See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace cachestore_redis; 18 19 use cache_definition; 20 use cache_store; 21 use cachestore_redis; 22 23 require_once (__DIR__.'/../../../tests/fixtures/stores.php'); 24 require_once (__DIR__.'/../lib.php'); 25 26 /** 27 * Redis cache test - compressor settings. 28 * 29 * If you wish to use these unit tests all you need to do is add the following definition to 30 * your config.php file. 31 * 32 * define('TEST_CACHESTORE_REDIS_TESTSERVERS', '127.0.0.1'); 33 * 34 * @package cachestore_redis 35 * @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net> 36 * @copyright 2018 Catalyst IT Australia {@link http://www.catalyst-au.net} 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class compressor_test extends \advanced_testcase { 40 41 /** 42 * Test set up 43 */ 44 public function setUp(): void { 45 if (!cachestore_redis::are_requirements_met() || !defined('TEST_CACHESTORE_REDIS_TESTSERVERS')) { 46 $this->markTestSkipped('Could not test cachestore_redis. Requirements are not met.'); 47 } 48 49 parent::setUp(); 50 } 51 52 /** 53 * Create a cachestore. 54 * 55 * @param int $compressor 56 * @param int $serializer 57 * @return cachestore_redis 58 */ 59 public function create_store($compressor, $serializer) { 60 /** @var cache_definition $definition */ 61 $definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_redis', 'phpunit_test'); 62 $config = cachestore_redis::unit_test_configuration(); 63 $config['compressor'] = $compressor; 64 $config['serializer'] = $serializer; 65 $store = new cachestore_redis('Test', $config); 66 $store->initialise($definition); 67 68 return $store; 69 } 70 71 /** 72 * It misses a value. 73 */ 74 public function test_it_can_miss_one() { 75 $store = $this->create_store(cachestore_redis::COMPRESSOR_PHP_GZIP, \Redis::SERIALIZER_PHP); 76 77 self::assertFalse($store->get('missme')); 78 } 79 80 /** 81 * It misses many values. 82 */ 83 public function test_it_can_miss_many() { 84 $store = $this->create_store(cachestore_redis::COMPRESSOR_PHP_GZIP, \Redis::SERIALIZER_PHP); 85 86 $expected = ['missme' => false, 'missmetoo' => false]; 87 $actual = $store->get_many(array_keys($expected)); 88 self::assertSame($expected, $actual); 89 } 90 91 /** 92 * It misses some values. 93 */ 94 public function test_it_can_miss_some() { 95 $store = $this->create_store(cachestore_redis::COMPRESSOR_PHP_GZIP, \Redis::SERIALIZER_PHP); 96 $store->set('iamhere', 'youfoundme'); 97 98 $expected = ['missme' => false, 'missmetoo' => false, 'iamhere' => 'youfoundme']; 99 $actual = $store->get_many(array_keys($expected)); 100 self::assertSame($expected, $actual); 101 } 102 103 /** 104 * A provider for test_works_with_different_types 105 * 106 * @return array 107 */ 108 public function provider_for_test_it_works_with_different_types() { 109 $object = new \stdClass(); 110 $object->field = 'value'; 111 112 return [ 113 ['string', 'Abc Def'], 114 ['string_empty', ''], 115 ['string_binary', gzencode('some binary data')], 116 ['int', 123], 117 ['int_zero', 0], 118 ['int_negative', -100], 119 ['int_huge', PHP_INT_MAX], 120 ['float', 3.14], 121 ['boolean_true', true], 122 // Boolean 'false' is not tested as it is not allowed in Moodle. 123 ['array', [1, 'b', 3.4]], 124 ['array_map', ['a' => 'b', 'c' => 'd']], 125 ['object_stdClass', $object], 126 ['null', null], 127 ]; 128 } 129 130 /** 131 * It works with different types. 132 * 133 * @dataProvider provider_for_test_it_works_with_different_types 134 * @param string $key 135 * @param mixed $value 136 */ 137 public function test_it_works_with_different_types($key, $value) { 138 $store = $this->create_store(cachestore_redis::COMPRESSOR_PHP_GZIP, \Redis::SERIALIZER_PHP); 139 $store->set($key, $value); 140 141 self::assertEquals($value, $store->get($key), "Failed set/get for: {$key}"); 142 } 143 144 /** 145 * Test it works with different types for many. 146 */ 147 public function test_it_works_with_different_types_for_many() { 148 $store = $this->create_store(cachestore_redis::COMPRESSOR_PHP_GZIP, \Redis::SERIALIZER_PHP); 149 150 $provider = $this->provider_for_test_it_works_with_different_types(); 151 $keys = []; 152 $values = []; 153 $expected = []; 154 foreach ($provider as $item) { 155 $keys[] = $item[0]; 156 $values[] = ['key' => $item[0], 'value' => $item[1]]; 157 $expected[$item[0]] = $item[1]; 158 } 159 $store->set_many($values); 160 $actual = $store->get_many($keys); 161 self::assertEquals($expected, $actual); 162 } 163 164 /** 165 * Provider for set/get combination tests. 166 * 167 * @return array 168 */ 169 public function provider_for_tests_setget() { 170 if (!cachestore_redis::are_requirements_met()) { 171 // Even though we skip all tests in this case, this provider can still show warnings about non-existing class. 172 return []; 173 } 174 175 $data = [ 176 ['none, none', 177 \Redis::SERIALIZER_NONE, cachestore_redis::COMPRESSOR_NONE, 178 'value1', 'value2'], 179 ['none, gzip', 180 \Redis::SERIALIZER_NONE, cachestore_redis::COMPRESSOR_PHP_GZIP, 181 gzencode('value1'), gzencode('value2')], 182 ['php, none', 183 \Redis::SERIALIZER_PHP, cachestore_redis::COMPRESSOR_NONE, 184 serialize('value1'), serialize('value2')], 185 ['php, gzip', 186 \Redis::SERIALIZER_PHP, cachestore_redis::COMPRESSOR_PHP_GZIP, 187 gzencode(serialize('value1')), gzencode(serialize('value2'))], 188 ]; 189 190 if (defined('Redis::SERIALIZER_IGBINARY')) { 191 $data[] = [ 192 'igbinary, none', 193 \Redis::SERIALIZER_IGBINARY, cachestore_redis::COMPRESSOR_NONE, 194 igbinary_serialize('value1'), igbinary_serialize('value2'), 195 ]; 196 $data[] = [ 197 'igbinary, gzip', 198 \Redis::SERIALIZER_IGBINARY, cachestore_redis::COMPRESSOR_PHP_GZIP, 199 gzencode(igbinary_serialize('value1')), gzencode(igbinary_serialize('value2')), 200 ]; 201 } 202 203 if (extension_loaded('zstd')) { 204 $data[] = [ 205 'none, zstd', 206 \Redis::SERIALIZER_NONE, cachestore_redis::COMPRESSOR_PHP_ZSTD, 207 zstd_compress('value1'), zstd_compress('value2'), 208 ]; 209 $data[] = [ 210 'php, zstd', 211 \Redis::SERIALIZER_PHP, cachestore_redis::COMPRESSOR_PHP_ZSTD, 212 zstd_compress(serialize('value1')), zstd_compress(serialize('value2')), 213 ]; 214 215 if (defined('\Redis::SERIALIZER_IGBINARY')) { 216 $data[] = [ 217 'igbinary, zstd', 218 \Redis::SERIALIZER_IGBINARY, cachestore_redis::COMPRESSOR_PHP_ZSTD, 219 zstd_compress(igbinary_serialize('value1')), zstd_compress(igbinary_serialize('value2')), 220 ]; 221 } 222 } 223 224 return $data; 225 } 226 227 /** 228 * Test we can use get and set with all combinations. 229 * 230 * @dataProvider provider_for_tests_setget 231 * @param string $name 232 * @param int $serializer 233 * @param int $compressor 234 * @param string $rawexpected1 235 * @param string $rawexpected2 236 */ 237 public function test_it_can_use_getset($name, $serializer, $compressor, $rawexpected1, $rawexpected2) { 238 // Create a connection with the desired serialisation. 239 $store = $this->create_store($compressor, $serializer); 240 $store->set('key', 'value1'); 241 242 // Disable compressor and serializer to check the actual stored value. 243 $rawstore = $this->create_store(cachestore_redis::COMPRESSOR_NONE, \Redis::SERIALIZER_NONE); 244 245 $data = $store->get('key'); 246 $rawdata = $rawstore->get('key'); 247 self::assertSame('value1', $data, "Invalid serialisation/unserialisation for: {$name}"); 248 self::assertSame($rawexpected1, $rawdata, "Invalid rawdata for: {$name}"); 249 } 250 251 /** 252 * Test we can use get and set many with all combinations. 253 * 254 * @dataProvider provider_for_tests_setget 255 * @param string $name 256 * @param int $serializer 257 * @param int $compressor 258 * @param string $rawexpected1 259 * @param string $rawexpected2 260 */ 261 public function test_it_can_use_getsetmany($name, $serializer, $compressor, $rawexpected1, $rawexpected2) { 262 $many = [ 263 ['key' => 'key1', 'value' => 'value1'], 264 ['key' => 'key2', 'value' => 'value2'], 265 ]; 266 $keys = ['key1', 'key2']; 267 $expectations = ['key1' => 'value1', 'key2' => 'value2']; 268 $rawexpectations = ['key1' => $rawexpected1, 'key2' => $rawexpected2]; 269 270 // Create a connection with the desired serialisation. 271 $store = $this->create_store($compressor, $serializer); 272 $store->set_many($many); 273 274 // Disable compressor and serializer to check the actual stored value. 275 $rawstore = $this->create_store(cachestore_redis::COMPRESSOR_NONE, \Redis::SERIALIZER_NONE); 276 277 $data = $store->get_many($keys); 278 $rawdata = $rawstore->get_many($keys); 279 foreach ($keys as $key) { 280 self::assertSame($expectations[$key], 281 $data[$key], 282 "Invalid serialisation/unserialisation for {$key} with serializer {$name}"); 283 self::assertSame($rawexpectations[$key], 284 $rawdata[$key], 285 "Invalid rawdata for {$key} with serializer {$name}"); 286 } 287 } 288 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body