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