Merge "rdbms: avoid LoadBalancer::getConnection waste when using $groups"
[lhc/web/wiklou.git] / tests / phpunit / includes / libs / objectcache / CachedBagOStuffTest.php
1 <?php
2
3 use Wikimedia\TestingAccessWrapper;
4
5 /**
6 * @group BagOStuff
7 */
8 class CachedBagOStuffTest extends PHPUnit\Framework\TestCase {
9
10 use MediaWikiCoversValidator;
11
12 /**
13 * @covers CachedBagOStuff::__construct
14 * @covers CachedBagOStuff::get
15 */
16 public function testGetFromBackend() {
17 $backend = new HashBagOStuff;
18 $cache = new CachedBagOStuff( $backend );
19
20 $backend->set( 'foo', 'bar' );
21 $this->assertEquals( 'bar', $cache->get( 'foo' ) );
22
23 $backend->set( 'foo', 'baz' );
24 $this->assertEquals( 'bar', $cache->get( 'foo' ), 'cached' );
25 }
26
27 /**
28 * @covers CachedBagOStuff::set
29 * @covers CachedBagOStuff::delete
30 */
31 public function testSetAndDelete() {
32 $backend = new HashBagOStuff;
33 $cache = new CachedBagOStuff( $backend );
34
35 for ( $i = 0; $i < 10; $i++ ) {
36 $cache->set( "key$i", 1 );
37 $this->assertEquals( 1, $cache->get( "key$i" ) );
38 $this->assertEquals( 1, $backend->get( "key$i" ) );
39
40 $cache->delete( "key$i" );
41 $this->assertEquals( false, $cache->get( "key$i" ) );
42 $this->assertEquals( false, $backend->get( "key$i" ) );
43 }
44 }
45
46 /**
47 * @covers CachedBagOStuff::set
48 * @covers CachedBagOStuff::delete
49 */
50 public function testWriteCacheOnly() {
51 $backend = new HashBagOStuff;
52 $cache = new CachedBagOStuff( $backend );
53
54 $cache->set( 'foo', 'bar', 0, CachedBagOStuff::WRITE_CACHE_ONLY );
55 $this->assertEquals( 'bar', $cache->get( 'foo' ) );
56 $this->assertFalse( $backend->get( 'foo' ) );
57
58 $cache->set( 'foo', 'old' );
59 $this->assertEquals( 'old', $cache->get( 'foo' ) );
60 $this->assertEquals( 'old', $backend->get( 'foo' ) );
61
62 $cache->set( 'foo', 'new', 0, CachedBagOStuff::WRITE_CACHE_ONLY );
63 $this->assertEquals( 'new', $cache->get( 'foo' ) );
64 $this->assertEquals( 'old', $backend->get( 'foo' ) );
65
66 $cache->delete( 'foo', CachedBagOStuff::WRITE_CACHE_ONLY );
67 $this->assertEquals( 'old', $cache->get( 'foo' ) ); // Reloaded from backend
68 }
69
70 /**
71 * @covers CachedBagOStuff::get
72 */
73 public function testCacheBackendMisses() {
74 $backend = new HashBagOStuff;
75 $cache = new CachedBagOStuff( $backend );
76
77 // First hit primes the cache with miss from the backend
78 $this->assertEquals( false, $cache->get( 'foo' ) );
79
80 // Change the value in the backend
81 $backend->set( 'foo', true );
82
83 // Second hit returns the cached miss
84 $this->assertEquals( false, $cache->get( 'foo' ) );
85
86 // But a fresh value is read from the backend
87 $backend->set( 'bar', true );
88 $this->assertEquals( true, $cache->get( 'bar' ) );
89 }
90
91 /**
92 * @covers CachedBagOStuff::setDebug
93 */
94 public function testSetDebug() {
95 $backend = new HashBagOStuff();
96 $cache = new CachedBagOStuff( $backend );
97 // Access private property 'debugMode'
98 $backend = TestingAccessWrapper::newFromObject( $backend );
99 $cache = TestingAccessWrapper::newFromObject( $cache );
100 $this->assertFalse( $backend->debugMode );
101 $this->assertFalse( $cache->debugMode );
102
103 $cache->setDebug( true );
104 // Should have set both
105 $this->assertTrue( $backend->debugMode, 'sets backend' );
106 $this->assertTrue( $cache->debugMode, 'sets self' );
107 }
108
109 /**
110 * @covers CachedBagOStuff::deleteObjectsExpiringBefore
111 */
112 public function testExpire() {
113 $backend = $this->getMockBuilder( HashBagOStuff::class )
114 ->setMethods( [ 'deleteObjectsExpiringBefore' ] )
115 ->getMock();
116 $backend->expects( $this->once() )
117 ->method( 'deleteObjectsExpiringBefore' )
118 ->willReturn( false );
119
120 $cache = new CachedBagOStuff( $backend );
121 $cache->deleteObjectsExpiringBefore( '20110401000000' );
122 }
123
124 /**
125 * @covers CachedBagOStuff::makeKey
126 */
127 public function testMakeKey() {
128 $backend = $this->getMockBuilder( HashBagOStuff::class )
129 ->setMethods( [ 'makeKey' ] )
130 ->getMock();
131 $backend->method( 'makeKey' )
132 ->willReturn( 'special/logic' );
133
134 // CachedBagOStuff wraps any backend with a process cache
135 // using HashBagOStuff. Hash has no special key limitations,
136 // but backends often do. Make sure it uses the backend's
137 // makeKey() logic, not the one inherited from HashBagOStuff
138 $cache = new CachedBagOStuff( $backend );
139
140 $this->assertEquals( 'special/logic', $backend->makeKey( 'special', 'logic' ) );
141 $this->assertEquals( 'special/logic', $cache->makeKey( 'special', 'logic' ) );
142 }
143
144 /**
145 * @covers CachedBagOStuff::makeGlobalKey
146 */
147 public function testMakeGlobalKey() {
148 $backend = $this->getMockBuilder( HashBagOStuff::class )
149 ->setMethods( [ 'makeGlobalKey' ] )
150 ->getMock();
151 $backend->method( 'makeGlobalKey' )
152 ->willReturn( 'special/logic' );
153
154 $cache = new CachedBagOStuff( $backend );
155
156 $this->assertEquals( 'special/logic', $backend->makeGlobalKey( 'special', 'logic' ) );
157 $this->assertEquals( 'special/logic', $cache->makeGlobalKey( 'special', 'logic' ) );
158 }
159 }