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