Merge "Type hint against LinkTarget in WatchedItemStore"
[lhc/web/wiklou.git] / tests / phpunit / includes / libs / objectcache / MultiWriteBagOStuffTest.php
1 <?php
2
3 /**
4 * @group Database
5 */
6 class MultiWriteBagOStuffTest extends MediaWikiTestCase {
7 /** @var HashBagOStuff */
8 private $cache1;
9 /** @var HashBagOStuff */
10 private $cache2;
11 /** @var MultiWriteBagOStuff */
12 private $cache;
13
14 protected function setUp() {
15 parent::setUp();
16
17 $this->cache1 = new HashBagOStuff();
18 $this->cache2 = new HashBagOStuff();
19 $this->cache = new MultiWriteBagOStuff( [
20 'caches' => [ $this->cache1, $this->cache2 ],
21 'replication' => 'async',
22 'asyncHandler' => 'DeferredUpdates::addCallableUpdate'
23 ] );
24 }
25
26 /**
27 * @covers MultiWriteBagOStuff::set
28 * @covers MultiWriteBagOStuff::doWrite
29 */
30 public function testSetImmediate() {
31 $key = 'key';
32 $value = 'value';
33 $this->cache->set( $key, $value );
34
35 // Set in tier 1
36 $this->assertEquals( $value, $this->cache1->get( $key ), 'Written to tier 1' );
37 // Set in tier 2
38 $this->assertEquals( $value, $this->cache2->get( $key ), 'Written to tier 2' );
39 }
40
41 /**
42 * @covers MultiWriteBagOStuff
43 */
44 public function testSyncMerge() {
45 $key = 'keyA';
46 $value = 'value';
47 $func = function () use ( $value ) {
48 return $value;
49 };
50
51 // XXX: DeferredUpdates bound to transactions in CLI mode
52 $dbw = wfGetDB( DB_MASTER );
53 $dbw->begin();
54 $this->cache->merge( $key, $func );
55
56 // Set in tier 1
57 $this->assertEquals( $value, $this->cache1->get( $key ), 'Written to tier 1' );
58 // Not yet set in tier 2
59 $this->assertFalse( $this->cache2->get( $key ), 'Not written to tier 2' );
60
61 $dbw->commit();
62
63 // Set in tier 2
64 $this->assertEquals( $value, $this->cache2->get( $key ), 'Written to tier 2' );
65
66 $key = 'keyB';
67
68 $dbw->begin();
69 $this->cache->merge( $key, $func, 0, 1, BagOStuff::WRITE_SYNC );
70
71 // Set in tier 1
72 $this->assertEquals( $value, $this->cache1->get( $key ), 'Written to tier 1' );
73 // Also set in tier 2
74 $this->assertEquals( $value, $this->cache2->get( $key ), 'Written to tier 2' );
75
76 $dbw->commit();
77 }
78
79 /**
80 * @covers MultiWriteBagOStuff::set
81 */
82 public function testSetDelayed() {
83 $key = 'key';
84 $value = (object)[ 'v' => 'saved value' ];
85 $expectValue = clone $value;
86
87 // XXX: DeferredUpdates bound to transactions in CLI mode
88 $dbw = wfGetDB( DB_MASTER );
89 $dbw->begin();
90 $this->cache->set( $key, $value );
91
92 // Test that later changes to $value don't affect the saved value (e.g. T168040)
93 $value->v = 'other value';
94
95 // Set in tier 1
96 $this->assertEquals( $expectValue, $this->cache1->get( $key ), 'Written to tier 1' );
97 // Not yet set in tier 2
98 $this->assertFalse( $this->cache2->get( $key ), 'Not written to tier 2' );
99
100 $dbw->commit();
101
102 // Set in tier 2
103 $this->assertEquals( $expectValue, $this->cache2->get( $key ), 'Written to tier 2' );
104 }
105
106 /**
107 * @covers MultiWriteBagOStuff::makeKey
108 */
109 public function testMakeKey() {
110 if ( defined( 'HHVM_VERSION' ) ) {
111 $this->markTestSkipped( 'HHVM Reflection buggy' );
112 }
113
114 $cache1 = $this->getMockBuilder( HashBagOStuff::class )
115 ->setMethods( [ 'makeKey' ] )->getMock();
116 $cache1->expects( $this->once() )->method( 'makeKey' )
117 ->willReturn( 'special' );
118
119 $cache2 = $this->getMockBuilder( HashBagOStuff::class )
120 ->setMethods( [ 'makeKey' ] )->getMock();
121 $cache2->expects( $this->never() )->method( 'makeKey' );
122
123 $cache = new MultiWriteBagOStuff( [ 'caches' => [ $cache1, $cache2 ] ] );
124 $this->assertSame( 'special', $cache->makeKey( 'a', 'b' ) );
125 }
126
127 /**
128 * @covers MultiWriteBagOStuff::makeGlobalKey
129 */
130 public function testMakeGlobalKey() {
131 if ( defined( 'HHVM_VERSION' ) ) {
132 $this->markTestSkipped( 'HHVM Reflection buggy' );
133 }
134
135 $cache1 = $this->getMockBuilder( HashBagOStuff::class )
136 ->setMethods( [ 'makeGlobalKey' ] )->getMock();
137 $cache1->expects( $this->once() )->method( 'makeGlobalKey' )
138 ->willReturn( 'special' );
139
140 $cache2 = $this->getMockBuilder( HashBagOStuff::class )
141 ->setMethods( [ 'makeGlobalKey' ] )->getMock();
142 $cache2->expects( $this->never() )->method( 'makeGlobalKey' );
143
144 $cache = new MultiWriteBagOStuff( [ 'caches' => [ $cache1, $cache2 ] ] );
145
146 $this->assertSame( 'special', $cache->makeGlobalKey( 'a', 'b' ) );
147 }
148
149 /**
150 * @covers MultiWriteBagOStuff::add
151 */
152 public function testDuplicateStoreAdd() {
153 $bag = new HashBagOStuff();
154 $cache = new MultiWriteBagOStuff( [
155 'caches' => [ $bag, $bag ],
156 ] );
157
158 $this->assertTrue( $cache->add( 'key', 1, 30 ) );
159 }
160 }