MediaWiki
REL1_24
|
00001 <?php 00007 class BagOStuffTest extends MediaWikiTestCase { 00008 private $cache; 00009 00010 protected function setUp() { 00011 parent::setUp(); 00012 00013 // type defined through parameter 00014 if ( $this->getCliArg( 'use-bagostuff' ) ) { 00015 $name = $this->getCliArg( 'use-bagostuff' ); 00016 00017 $this->cache = ObjectCache::newFromId( $name ); 00018 } else { 00019 // no type defined - use simple hash 00020 $this->cache = new HashBagOStuff; 00021 } 00022 00023 $this->cache->delete( wfMemcKey( 'test' ) ); 00024 } 00025 00026 public function testMerge() { 00027 $key = wfMemcKey( 'test' ); 00028 00029 $usleep = 0; 00030 00040 $callback = function ( BagOStuff $cache, $key, $existingValue ) use ( &$usleep ) { 00041 // let's pretend this is an expensive callback to test concurrent merge attempts 00042 usleep( $usleep ); 00043 00044 if ( $existingValue === false ) { 00045 return 'merged'; 00046 } 00047 00048 return $existingValue . 'merged'; 00049 }; 00050 00051 // merge on non-existing value 00052 $merged = $this->cache->merge( $key, $callback, 0 ); 00053 $this->assertTrue( $merged ); 00054 $this->assertEquals( $this->cache->get( $key ), 'merged' ); 00055 00056 // merge on existing value 00057 $merged = $this->cache->merge( $key, $callback, 0 ); 00058 $this->assertTrue( $merged ); 00059 $this->assertEquals( $this->cache->get( $key ), 'mergedmerged' ); 00060 00061 /* 00062 * Test concurrent merges by forking this process, if: 00063 * - not manually called with --use-bagostuff 00064 * - pcntl_fork is supported by the system 00065 * - cache type will correctly support calls over forks 00066 */ 00067 $fork = (bool)$this->getCliArg( 'use-bagostuff' ); 00068 $fork &= function_exists( 'pcntl_fork' ); 00069 $fork &= !$this->cache instanceof HashBagOStuff; 00070 $fork &= !$this->cache instanceof EmptyBagOStuff; 00071 $fork &= !$this->cache instanceof MultiWriteBagOStuff; 00072 if ( $fork ) { 00073 // callback should take awhile now so that we can test concurrent merge attempts 00074 $pid = pcntl_fork(); 00075 if ( $pid == -1 ) { 00076 // can't fork, ignore this test... 00077 } elseif ( $pid ) { 00078 // wait a little, making sure that the child process is calling merge 00079 usleep( 3000 ); 00080 00081 // attempt a merge - this should fail 00082 $merged = $this->cache->merge( $key, $callback, 0, 1 ); 00083 00084 // merge has failed because child process was merging (and we only attempted once) 00085 $this->assertFalse( $merged ); 00086 00087 // make sure the child's merge is completed and verify 00088 usleep( 3000 ); 00089 $this->assertEquals( $this->cache->get( $key ), 'mergedmergedmerged' ); 00090 } else { 00091 $this->cache->merge( $key, $callback, 0, 1 ); 00092 00093 // Note: I'm not even going to check if the merge worked, I'll 00094 // compare values in the parent process to test if this merge worked. 00095 // I'm just going to exit this child process, since I don't want the 00096 // child to output any test results (would be rather confusing to 00097 // have test output twice) 00098 exit; 00099 } 00100 } 00101 } 00102 00103 public function testAdd() { 00104 $key = wfMemcKey( 'test' ); 00105 $this->assertTrue( $this->cache->add( $key, 'test' ) ); 00106 } 00107 00108 public function testGet() { 00109 $value = array( 'this' => 'is', 'a' => 'test' ); 00110 00111 $key = wfMemcKey( 'test' ); 00112 $this->cache->add( $key, $value ); 00113 $this->assertEquals( $this->cache->get( $key ), $value ); 00114 } 00115 00119 public function testIncr() { 00120 $key = wfMemcKey( 'test' ); 00121 $this->cache->add( $key, 0 ); 00122 $this->cache->incr( $key ); 00123 $expectedValue = 1; 00124 $actualValue = $this->cache->get( $key ); 00125 $this->assertEquals( $expectedValue, $actualValue, 'Value should be 1 after incrementing' ); 00126 } 00127 00128 public function testGetMulti() { 00129 $value1 = array( 'this' => 'is', 'a' => 'test' ); 00130 $value2 = array( 'this' => 'is', 'another' => 'test' ); 00131 00132 $key1 = wfMemcKey( 'test1' ); 00133 $key2 = wfMemcKey( 'test2' ); 00134 00135 $this->cache->add( $key1, $value1 ); 00136 $this->cache->add( $key2, $value2 ); 00137 00138 $this->assertEquals( 00139 $this->cache->getMulti( array( $key1, $key2 ) ), 00140 array( $key1 => $value1, $key2 => $value2 ) 00141 ); 00142 00143 // cleanup 00144 $this->cache->delete( $key1 ); 00145 $this->cache->delete( $key2 ); 00146 } 00147 }