3 namespace Drupal\KernelTests\Core\KeyValueStore;
5 use Drupal\Core\DependencyInjection\ContainerBuilder;
6 use Drupal\Core\KeyValueStore\KeyValueFactory;
9 * Tests the key-value database storage.
11 * @group KeyValueStore
13 class DatabaseStorageExpirableTest extends StorageTestBase {
20 public static $modules = ['system'];
22 protected function setUp() {
24 $this->factory = 'keyvalue.expirable';
25 $this->installSchema('system', ['key_value_expire']);
31 public function register(ContainerBuilder $container) {
32 parent::register($container);
34 $parameter[KeyValueFactory::DEFAULT_SETTING] = 'keyvalue.expirable.database';
35 $container->setParameter('factory.keyvalue.expirable', $parameter);
39 * Tests CRUD functionality with expiration.
41 public function testCRUDWithExpiration() {
42 $stores = $this->createStorage();
44 // Verify that an item can be stored with setWithExpire().
45 // Use a random expiration in each test.
46 $stores[0]->setWithExpire('foo', $this->objects[0], rand(500, 100000));
47 $this->assertIdenticalObject($this->objects[0], $stores[0]->get('foo'));
48 // Verify that the other collection is not affected.
49 $this->assertFalse($stores[1]->get('foo'));
51 // Verify that an item can be updated with setWithExpire().
52 $stores[0]->setWithExpire('foo', $this->objects[1], rand(500, 100000));
53 $this->assertIdenticalObject($this->objects[1], $stores[0]->get('foo'));
54 // Verify that the other collection is still not affected.
55 $this->assertFalse($stores[1]->get('foo'));
57 // Verify that the expirable data key is unique.
58 $stores[1]->setWithExpire('foo', $this->objects[2], rand(500, 100000));
59 $this->assertIdenticalObject($this->objects[1], $stores[0]->get('foo'));
60 $this->assertIdenticalObject($this->objects[2], $stores[1]->get('foo'));
62 // Verify that multiple items can be stored with setMultipleWithExpire().
64 'foo' => $this->objects[3],
65 'bar' => $this->objects[4],
67 $stores[0]->setMultipleWithExpire($values, rand(500, 100000));
68 $result = $stores[0]->getMultiple(['foo', 'bar']);
69 foreach ($values as $j => $value) {
70 $this->assertIdenticalObject($value, $result[$j]);
73 // Verify that the other collection was not affected.
74 $this->assertIdenticalObject($stores[1]->get('foo'), $this->objects[2]);
75 $this->assertFalse($stores[1]->get('bar'));
77 // Verify that all items in a collection can be retrieved.
78 // Ensure that an item with the same name exists in the other collection.
79 $stores[1]->set('foo', $this->objects[5]);
80 $result = $stores[0]->getAll();
81 // Not using assertIdentical(), since the order is not defined for getAll().
82 $this->assertEqual(count($result), count($values));
83 foreach ($result as $key => $value) {
84 $this->assertEqual($values[$key], $value);
86 // Verify that all items in the other collection are different.
87 $result = $stores[1]->getAll();
88 $this->assertEqual($result, ['foo' => $this->objects[5]]);
90 // Verify that multiple items can be deleted.
91 $stores[0]->deleteMultiple(array_keys($values));
92 $this->assertFalse($stores[0]->get('foo'));
93 $this->assertFalse($stores[0]->get('bar'));
94 $this->assertFalse($stores[0]->getMultiple(['foo', 'bar']));
95 // Verify that the item in the other collection still exists.
96 $this->assertIdenticalObject($this->objects[5], $stores[1]->get('foo'));
98 // Test that setWithExpireIfNotExists() succeeds only the first time.
99 $key = $this->randomMachineName();
100 for ($i = 0; $i <= 1; $i++) {
101 // setWithExpireIfNotExists() should be TRUE the first time (when $i is
102 // 0) and FALSE the second time (when $i is 1).
103 $this->assertEqual(!$i, $stores[0]->setWithExpireIfNotExists($key, $this->objects[$i], rand(500, 100000)));
104 $this->assertIdenticalObject($this->objects[0], $stores[0]->get($key));
105 // Verify that the other collection is not affected.
106 $this->assertFalse($stores[1]->get($key));
109 // Remove the item and try to set it again.
110 $stores[0]->delete($key);
111 $stores[0]->setWithExpireIfNotExists($key, $this->objects[1], rand(500, 100000));
112 // This time it should succeed.
113 $this->assertIdenticalObject($this->objects[1], $stores[0]->get($key));
114 // Verify that the other collection is still not affected.
115 $this->assertFalse($stores[1]->get($key));
120 * Tests data expiration.
122 public function testExpiration() {
123 $stores = $this->createStorage();
126 // Set an item to expire in the past and another without an expiration.
127 $stores[0]->setWithExpire('yesterday', 'all my troubles seemed so far away', -1 * $day);
128 $stores[0]->set('troubles', 'here to stay');
130 // Only the non-expired item should be returned.
131 $this->assertFalse($stores[0]->has('yesterday'));
132 $this->assertFalse($stores[0]->get('yesterday'));
133 $this->assertTrue($stores[0]->has('troubles'));
134 $this->assertIdentical($stores[0]->get('troubles'), 'here to stay');
135 $this->assertIdentical(count($stores[0]->getMultiple(['yesterday', 'troubles'])), 1);
137 // Store items set to expire in the past in various ways.
138 $stores[0]->setWithExpire($this->randomMachineName(), $this->objects[0], -7 * $day);
139 $stores[0]->setWithExpireIfNotExists($this->randomMachineName(), $this->objects[1], -5 * $day);
140 $stores[0]->setMultipleWithExpire(
142 $this->randomMachineName() => $this->objects[2],
143 $this->randomMachineName() => $this->objects[3],
147 $stores[0]->setWithExpireIfNotExists('yesterday', "you'd forgiven me", -1 * $day);
148 $stores[0]->setWithExpire('still', "'til we say we're sorry", 2 * $day);
150 // Ensure only non-expired items are retrieved.
151 $all = $stores[0]->getAll();
152 $this->assertIdentical(count($all), 2);
153 foreach (['troubles', 'still'] as $key) {
154 $this->assertTrue(!empty($all[$key]));