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