53d27c0afb201dbd87e56a53e16bd44afc159a62
[lhc/web/wiklou.git] / tests / phpunit / includes / libs / objectcache / HashBagOStuffTest.php
1 <?php
2
3 use Wikimedia\TestingAccessWrapper;
4
5 /**
6 * @group BagOStuff
7 */
8 class HashBagOStuffTest extends PHPUnit_Framework_TestCase {
9
10 /**
11 * @covers HashBagOStuff::__construct
12 */
13 public function testConstruct() {
14 $this->assertInstanceOf(
15 HashBagOStuff::class,
16 new HashBagOStuff()
17 );
18 }
19
20 /**
21 * @covers HashBagOStuff::__construct
22 * @expectedException InvalidArgumentException
23 */
24 public function testConstructBadZero() {
25 $cache = new HashBagOStuff( [ 'maxKeys' => 0 ] );
26 }
27
28 /**
29 * @covers HashBagOStuff::__construct
30 * @expectedException InvalidArgumentException
31 */
32 public function testConstructBadNeg() {
33 $cache = new HashBagOStuff( [ 'maxKeys' => -1 ] );
34 }
35
36 /**
37 * @covers HashBagOStuff::__construct
38 * @expectedException InvalidArgumentException
39 */
40 public function testConstructBadType() {
41 $cache = new HashBagOStuff( [ 'maxKeys' => 'x' ] );
42 }
43
44 /**
45 * @covers HashBagOStuff::delete
46 */
47 public function testDelete() {
48 $cache = new HashBagOStuff();
49 for ( $i = 0; $i < 10; $i++ ) {
50 $cache->set( "key$i", 1 );
51 $this->assertEquals( 1, $cache->get( "key$i" ) );
52 $cache->delete( "key$i" );
53 $this->assertEquals( false, $cache->get( "key$i" ) );
54 }
55 }
56
57 /**
58 * @covers HashBagOStuff::clear
59 */
60 public function testClear() {
61 $cache = new HashBagOStuff();
62 for ( $i = 0; $i < 10; $i++ ) {
63 $cache->set( "key$i", 1 );
64 $this->assertEquals( 1, $cache->get( "key$i" ) );
65 }
66 $cache->clear();
67 for ( $i = 0; $i < 10; $i++ ) {
68 $this->assertEquals( false, $cache->get( "key$i" ) );
69 }
70 }
71
72 /**
73 * @covers HashBagOStuff::doGet
74 * @covers HashBagOStuff::expire
75 */
76 public function testExpire() {
77 $cache = new HashBagOStuff();
78 $cacheInternal = TestingAccessWrapper::newFromObject( $cache );
79 $cache->set( 'foo', 1 );
80 $cache->set( 'bar', 1, 10 );
81 $cache->set( 'baz', 1, -10 );
82
83 $this->assertEquals( 0, $cacheInternal->bag['foo'][$cache::KEY_EXP], 'Indefinite' );
84 // 2 seconds tolerance
85 $this->assertEquals( time() + 10, $cacheInternal->bag['bar'][$cache::KEY_EXP], 'Future', 2 );
86 $this->assertEquals( time() - 10, $cacheInternal->bag['baz'][$cache::KEY_EXP], 'Past', 2 );
87
88 $this->assertEquals( 1, $cache->get( 'bar' ), 'Key not expired' );
89 $this->assertEquals( false, $cache->get( 'baz' ), 'Key expired' );
90 }
91
92 /**
93 * Ensure maxKeys eviction prefers keeping new keys.
94 *
95 * @covers HashBagOStuff::set
96 */
97 public function testEvictionAdd() {
98 $cache = new HashBagOStuff( [ 'maxKeys' => 10 ] );
99 for ( $i = 0; $i < 10; $i++ ) {
100 $cache->set( "key$i", 1 );
101 $this->assertEquals( 1, $cache->get( "key$i" ) );
102 }
103 for ( $i = 10; $i < 20; $i++ ) {
104 $cache->set( "key$i", 1 );
105 $this->assertEquals( 1, $cache->get( "key$i" ) );
106 $this->assertEquals( false, $cache->get( "key" . ( $i - 10 ) ) );
107 }
108 }
109
110 /**
111 * Ensure maxKeys eviction prefers recently set keys
112 * even if the keys pre-exist.
113 *
114 * @covers HashBagOStuff::set
115 */
116 public function testEvictionSet() {
117 $cache = new HashBagOStuff( [ 'maxKeys' => 3 ] );
118
119 foreach ( [ 'foo', 'bar', 'baz' ] as $key ) {
120 $cache->set( $key, 1 );
121 }
122
123 // Set existing key
124 $cache->set( 'foo', 1 );
125
126 // Add a 4th key (beyond the allowed maximum)
127 $cache->set( 'quux', 1 );
128
129 // Foo's life should have been extended over Bar
130 foreach ( [ 'foo', 'baz', 'quux' ] as $key ) {
131 $this->assertEquals( 1, $cache->get( $key ), "Kept $key" );
132 }
133 $this->assertEquals( false, $cache->get( 'bar' ), 'Evicted bar' );
134 }
135
136 /**
137 * Ensure maxKeys eviction prefers recently retrieved keys (LRU).
138 *
139 * @covers HashBagOStuff::doGet
140 * @covers HashBagOStuff::hasKey
141 */
142 public function testEvictionGet() {
143 $cache = new HashBagOStuff( [ 'maxKeys' => 3 ] );
144
145 foreach ( [ 'foo', 'bar', 'baz' ] as $key ) {
146 $cache->set( $key, 1 );
147 }
148
149 // Get existing key
150 $cache->get( 'foo', 1 );
151
152 // Add a 4th key (beyond the allowed maximum)
153 $cache->set( 'quux', 1 );
154
155 // Foo's life should have been extended over Bar
156 foreach ( [ 'foo', 'baz', 'quux' ] as $key ) {
157 $this->assertEquals( 1, $cache->get( $key ), "Kept $key" );
158 }
159 $this->assertEquals( false, $cache->get( 'bar' ), 'Evicted bar' );
160 }
161 }