Upgraded drupal core with security updates
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Cache / BackendChainImplementationUnitTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Cache;
4
5 use Drupal\Core\Cache\BackendChain;
6 use Drupal\Core\Cache\Cache;
7 use Drupal\Core\Cache\MemoryBackend;
8 use Drupal\Tests\UnitTestCase;
9
10 /**
11  * Unit test of backend chain implementation specifics.
12  *
13  * @group Cache
14  */
15 class BackendChainImplementationUnitTest extends UnitTestCase {
16
17   /**
18    * Chain that will be heavily tested.
19    *
20    * @var \Drupal\Core\Cache\BackendChain
21    */
22   protected $chain;
23
24   /**
25    * First backend in the chain.
26    *
27    * @var \Drupal\Core\Cache\CacheBackendInterface
28    */
29   protected $firstBackend;
30
31   /**
32    * Second backend in the chain.
33    *
34    * @var \Drupal\Core\Cache\CacheBackendInterface
35    */
36   protected $secondBackend;
37
38   /**
39    * Third backend in the chain.
40    *
41    * @var \Drupal\Core\Cache\CacheBackendInterface
42    */
43   protected $thirdBackend;
44
45   protected function setUp() {
46     parent::setUp();
47
48     // Set up three memory backends to be used in the chain.
49     $this->firstBackend = new MemoryBackend();
50     $this->secondBackend = new MemoryBackend();
51     $this->thirdBackend = new MemoryBackend();
52
53     // Set an initial fixed dataset for all testing. The next three data
54     // collections will test two edge cases (last backend has the data, and
55     // first backend has the data) and will test a normal use case (middle
56     // backend has the data). We should have a complete unit test with those.
57     // Note that in all cases, when the same key is set on more than one
58     // backend, the values are voluntarily different, this ensures in which
59     // backend we actually fetched the key when doing get calls.
60
61     // Set a key present on all backends (for delete).
62     $this->firstBackend->set('t123', 1231);
63     $this->secondBackend->set('t123', 1232);
64     $this->thirdBackend->set('t123', 1233);
65
66     // Set a key present on the second and the third (for get), those two will
67     // be different, this will ensure from where we get the key.
68     $this->secondBackend->set('t23', 232);
69     $this->thirdBackend->set('t23', 233);
70
71     // Set a key on only the third, we will ensure propagation using this one.
72     $this->thirdBackend->set('t3', 33);
73
74     // Create the chain.
75     $this->chain = new BackendChain('foobarbaz');
76     $this->chain
77       ->appendBackend($this->firstBackend)
78       ->appendBackend($this->secondBackend)
79       ->appendBackend($this->thirdBackend);
80   }
81
82   /**
83    * Test the get feature.
84    */
85   public function testGet() {
86     $cached = $this->chain->get('t123');
87     $this->assertNotSame(FALSE, $cached, 'Got key that is on all backends');
88     $this->assertSame(1231, $cached->data, 'Got the key from the backend 1');
89
90     $cached = $this->chain->get('t23');
91     $this->assertNotSame(FALSE, $cached, 'Got key that is on backends 2 and 3');
92     $this->assertSame(232, $cached->data, 'Got the key from the backend 2');
93
94     $cached = $this->chain->get('t3');
95     $this->assertNotSame(FALSE, $cached, 'Got key that is on the backend 3');
96     $this->assertSame(33, $cached->data, 'Got the key from the backend 3');
97   }
98
99   /**
100    * Test the get multiple feature.
101    */
102   public function testGetMultiple() {
103     $cids = ['t123', 't23', 't3', 't4'];
104
105     $ret = $this->chain->getMultiple($cids);
106     $this->assertSame($ret['t123']->data, 1231, 'Got key 123 and value is from the first backend');
107     $this->assertSame($ret['t23']->data, 232, 'Got key 23 and value is from the second backend');
108     $this->assertSame($ret['t3']->data, 33, 'Got key 3 and value is from the third backend');
109     $this->assertFalse(array_key_exists('t4', $ret), "Didn't get the nonexistent key");
110
111     $this->assertFalse(in_array('t123', $cids), "Existing key 123 has been removed from &\$cids");
112     $this->assertFalse(in_array('t23', $cids), "Existing key 23 has been removed from &\$cids");
113     $this->assertFalse(in_array('t3', $cids), "Existing key 3 has been removed from &\$cids");
114     $this->assertTrue(in_array('t4', $cids), "Non existing key 4 is still in &\$cids");
115   }
116
117   /**
118    * Test that set will propagate.
119    */
120   public function testSet() {
121     $this->chain->set('test', 123);
122
123     $cached = $this->firstBackend->get('test');
124     $this->assertNotSame(FALSE, $cached, 'Test key is in the first backend');
125     $this->assertSame(123, $cached->data, 'Test key has the right value');
126
127     $cached = $this->secondBackend->get('test');
128     $this->assertNotSame(FALSE, $cached, 'Test key is in the second backend');
129     $this->assertSame(123, $cached->data, 'Test key has the right value');
130
131     $cached = $this->thirdBackend->get('test');
132     $this->assertNotSame(FALSE, $cached, 'Test key is in the third backend');
133     $this->assertSame(123, $cached->data, 'Test key has the right value');
134   }
135
136   /**
137    * Test that delete will propagate.
138    */
139   public function testDelete() {
140     $this->chain->set('test', 5);
141
142     $cached = $this->firstBackend->get('test');
143     $this->assertNotSame(FALSE, $cached, 'Test key has been added to the first backend');
144     $cached = $this->secondBackend->get('test');
145     $this->assertNotSame(FALSE, $cached, 'Test key has been added to the first backend');
146     $cached = $this->thirdBackend->get('test');
147     $this->assertNotSame(FALSE, $cached, 'Test key has been added to the first backend');
148
149     $this->chain->delete('test');
150
151     $cached = $this->firstBackend->get('test');
152     $this->assertSame(FALSE, $cached, 'Test key is removed from the first backend');
153     $cached = $this->secondBackend->get('test');
154     $this->assertSame(FALSE, $cached, 'Test key is removed from the second backend');
155     $cached = $this->thirdBackend->get('test');
156     $this->assertSame(FALSE, $cached, 'Test key is removed from the third backend');
157   }
158
159   /**
160    * Ensure get values propagation to previous backends.
161    */
162   public function testGetHasPropagated() {
163     $this->chain->get('t23');
164     $cached = $this->firstBackend->get('t23');
165     $this->assertNotSame(FALSE, $cached, 'Test 2 has been propagated to the first backend');
166
167     $this->chain->get('t3');
168     $cached = $this->firstBackend->get('t3');
169     $this->assertNotSame(FALSE, $cached, 'Test 3 has been propagated to the first backend');
170     $cached = $this->secondBackend->get('t3');
171     $this->assertNotSame(FALSE, $cached, 'Test 3 has been propagated to the second backend');
172   }
173
174   /**
175    * Ensure get multiple values propagation to previous backends.
176    */
177   public function testGetMultipleHasPropagated() {
178     $cids = ['t3', 't23'];
179     $this->chain->getMultiple($cids);
180
181     $cached = $this->firstBackend->get('t3');
182     $this->assertNotSame(FALSE, $cached, 'Test 3 has been propagated to the first backend');
183     $this->assertSame(33, $cached->data, 'And value has been kept');
184     $cached = $this->secondBackend->get('t3');
185     $this->assertNotSame(FALSE, $cached, 'Test 3 has been propagated to the second backend');
186     $this->assertSame(33, $cached->data, 'And value has been kept');
187
188     $cached = $this->firstBackend->get('t23');
189     $this->assertNotSame(FALSE, $cached, 'Test 2 has been propagated to the first backend');
190     $this->assertSame(232, $cached->data, 'And value has been kept');
191   }
192
193   /**
194    * Test that the delete all operation is propagated to all backends in the chain.
195    */
196   public function testDeleteAllPropagation() {
197     // Set both expiring and permanent keys.
198     $this->chain->set('test1', 1, Cache::PERMANENT);
199     $this->chain->set('test2', 3, time() + 1000);
200     $this->chain->deleteAll();
201
202     $this->assertFalse($this->firstBackend->get('test1'), 'First key has been deleted in first backend.');
203     $this->assertFalse($this->firstBackend->get('test2'), 'Second key has been deleted in first backend.');
204     $this->assertFalse($this->secondBackend->get('test1'), 'First key has been deleted in second backend.');
205     $this->assertFalse($this->secondBackend->get('test2'), 'Second key has been deleted in second backend.');
206     $this->assertFalse($this->thirdBackend->get('test1'), 'First key has been deleted in third backend.');
207     $this->assertFalse($this->thirdBackend->get('test2'), 'Second key has been deleted in third backend.');
208   }
209
210   /**
211    * Test that the delete tags operation is propagated to all backends
212    * in the chain.
213    */
214   public function testDeleteTagsPropagation() {
215     // Create two cache entries with the same tag and tag value.
216     $this->chain->set('test_cid_clear1', 'foo', Cache::PERMANENT, ['test_tag:2']);
217     $this->chain->set('test_cid_clear2', 'foo', Cache::PERMANENT, ['test_tag:2']);
218     $this->assertNotSame(FALSE, $this->firstBackend->get('test_cid_clear1')
219       && $this->firstBackend->get('test_cid_clear2')
220       && $this->secondBackend->get('test_cid_clear1')
221       && $this->secondBackend->get('test_cid_clear2')
222       && $this->thirdBackend->get('test_cid_clear1')
223       && $this->thirdBackend->get('test_cid_clear2'),
224       'Two cache items were created in all backends.');
225
226     // Invalidate test_tag of value 1. This should invalidate both entries.
227     $this->chain->invalidateTags(['test_tag:2']);
228     $this->assertSame(FALSE, $this->firstBackend->get('test_cid_clear1')
229       && $this->firstBackend->get('test_cid_clear2')
230       && $this->secondBackend->get('test_cid_clear1')
231       && $this->secondBackend->get('test_cid_clear2')
232       && $this->thirdBackend->get('test_cid_clear1')
233       && $this->thirdBackend->get('test_cid_clear2'),
234       'Two caches removed from all backends after clearing a cache tag.');
235
236     // Create two cache entries with the same tag and an array tag value.
237     $this->chain->set('test_cid_clear1', 'foo', Cache::PERMANENT, ['test_tag:1']);
238     $this->chain->set('test_cid_clear2', 'foo', Cache::PERMANENT, ['test_tag:1']);
239     $this->assertNotSame(FALSE, $this->firstBackend->get('test_cid_clear1')
240       && $this->firstBackend->get('test_cid_clear2')
241       && $this->secondBackend->get('test_cid_clear1')
242       && $this->secondBackend->get('test_cid_clear2')
243       && $this->thirdBackend->get('test_cid_clear1')
244       && $this->thirdBackend->get('test_cid_clear2'),
245       'Two cache items were created in all backends.');
246
247     // Invalidate test_tag of value 1. This should invalidate both entries.
248     $this->chain->invalidateTags(['test_tag:1']);
249     $this->assertSame(FALSE, $this->firstBackend->get('test_cid_clear1')
250       && $this->firstBackend->get('test_cid_clear2')
251       && $this->secondBackend->get('test_cid_clear1')
252       && $this->secondBackend->get('test_cid_clear2')
253       && $this->thirdBackend->get('test_cid_clear1')
254       && $this->thirdBackend->get('test_cid_clear2'),
255       'Two caches removed from all backends after clearing a cache tag.');
256
257     // Create three cache entries with a mix of tags and tag values.
258     $this->chain->set('test_cid_clear1', 'foo', Cache::PERMANENT, ['test_tag:1']);
259     $this->chain->set('test_cid_clear2', 'foo', Cache::PERMANENT, ['test_tag:2']);
260     $this->chain->set('test_cid_clear3', 'foo', Cache::PERMANENT, ['test_tag_foo:3']);
261     $this->assertNotSame(FALSE, $this->firstBackend->get('test_cid_clear1')
262       && $this->firstBackend->get('test_cid_clear2')
263       && $this->firstBackend->get('test_cid_clear3')
264       && $this->secondBackend->get('test_cid_clear1')
265       && $this->secondBackend->get('test_cid_clear2')
266       && $this->secondBackend->get('test_cid_clear3')
267       && $this->thirdBackend->get('test_cid_clear1')
268       && $this->thirdBackend->get('test_cid_clear2')
269       && $this->thirdBackend->get('test_cid_clear3'),
270       'Three cached items were created in all backends.');
271
272     $this->chain->invalidateTags(['test_tag_foo:3']);
273     $this->assertNotSame(FALSE, $this->firstBackend->get('test_cid_clear1')
274       && $this->firstBackend->get('test_cid_clear2')
275       && $this->secondBackend->get('test_cid_clear1')
276       && $this->secondBackend->get('test_cid_clear2')
277       && $this->thirdBackend->get('test_cid_clear1')
278       && $this->thirdBackend->get('test_cid_clear2'),
279       'Cached items not matching the tag were not cleared from any of the backends.');
280
281     $this->assertSame(FALSE, $this->firstBackend->get('test_cid_clear3')
282       && $this->secondBackend->get('test_cid_clear3')
283       && $this->thirdBackend->get('test_cid_clear3'),
284       'Cached item matching the tag was removed from all backends.');
285   }
286
287   /**
288    * Test that removing bin propagates to all backends.
289    */
290   public function testRemoveBin() {
291     $chain = new BackendChain('foo');
292     for ($i = 0; $i < 3; $i++) {
293       $backend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
294       $backend->expects($this->once())->method('removeBin');
295       $chain->appendBackend($backend);
296     }
297
298     $chain->removeBin();
299   }
300
301 }