Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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 cachestore_redis;
1441 ariadna 20
use core_cache\definition;
21
use core_cache\store;
1 efrain 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
 */
1441 ariadna 39
final class compressor_test extends \advanced_testcase {
40
    /** @var null|\cachestore_redis */
41
    protected ?cachestore_redis $store = null;
1 efrain 42
 
1441 ariadna 43
    #[\Override]
1 efrain 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
 
1441 ariadna 52
    #[\Override]
53
    protected function tearDown(): void {
54
        parent::tearDown();
55
 
56
        if ($this->store !== null) {
57
            $this->store->purge();
58
            $this->store = null;
59
        }
60
    }
61
 
1 efrain 62
    /**
63
     * Create a cachestore.
64
     *
65
     * @param int $compressor
66
     * @param int $serializer
67
     * @return cachestore_redis
68
     */
69
    public function create_store($compressor, $serializer) {
1441 ariadna 70
        /** @var definition $definition */
71
        $definition = definition::load_adhoc(store::MODE_APPLICATION, 'cachestore_redis', 'phpunit_test');
1 efrain 72
        $config = cachestore_redis::unit_test_configuration();
73
        $config['compressor'] = $compressor;
74
        $config['serializer'] = $serializer;
75
        $store = new cachestore_redis('Test', $config);
76
        $store->initialise($definition);
1441 ariadna 77
        $this->store = $store;
1 efrain 78
 
79
        return $store;
80
    }
81
 
82
    /**
83
     * It misses a value.
84
     */
11 efrain 85
    public function test_it_can_miss_one(): void {
1 efrain 86
        $store = $this->create_store(cachestore_redis::COMPRESSOR_PHP_GZIP, \Redis::SERIALIZER_PHP);
87
 
88
        self::assertFalse($store->get('missme'));
89
    }
90
 
91
    /**
92
     * It misses many values.
93
     */
11 efrain 94
    public function test_it_can_miss_many(): void {
1 efrain 95
        $store = $this->create_store(cachestore_redis::COMPRESSOR_PHP_GZIP, \Redis::SERIALIZER_PHP);
96
 
97
        $expected = ['missme' => false, 'missmetoo' => false];
98
        $actual = $store->get_many(array_keys($expected));
99
        self::assertSame($expected, $actual);
100
    }
101
 
102
    /**
103
     * It misses some values.
104
     */
11 efrain 105
    public function test_it_can_miss_some(): void {
1 efrain 106
        $store = $this->create_store(cachestore_redis::COMPRESSOR_PHP_GZIP, \Redis::SERIALIZER_PHP);
107
        $store->set('iamhere', 'youfoundme');
108
 
109
        $expected = ['missme' => false, 'missmetoo' => false, 'iamhere' => 'youfoundme'];
110
        $actual = $store->get_many(array_keys($expected));
111
        self::assertSame($expected, $actual);
112
    }
113
 
114
    /**
115
     * A provider for test_works_with_different_types
116
     *
117
     * @return array
118
     */
1441 ariadna 119
    public static function provider_for_test_it_works_with_different_types(): array {
1 efrain 120
        $object = new \stdClass();
121
        $object->field = 'value';
122
 
123
        return [
124
            ['string', 'Abc Def'],
125
            ['string_empty', ''],
126
            ['string_binary', gzencode('some binary data')],
127
            ['int', 123],
128
            ['int_zero', 0],
129
            ['int_negative', -100],
130
            ['int_huge', PHP_INT_MAX],
131
            ['float', 3.14],
132
            ['boolean_true', true],
133
            // Boolean 'false' is not tested as it is not allowed in Moodle.
134
            ['array', [1, 'b', 3.4]],
135
            ['array_map', ['a' => 'b', 'c' => 'd']],
136
            ['object_stdClass', $object],
137
            ['null', null],
138
        ];
139
    }
140
 
141
    /**
142
     * It works with different types.
143
     *
144
     * @dataProvider provider_for_test_it_works_with_different_types
145
     * @param string $key
146
     * @param mixed $value
147
     */
11 efrain 148
    public function test_it_works_with_different_types($key, $value): void {
1 efrain 149
        $store = $this->create_store(cachestore_redis::COMPRESSOR_PHP_GZIP, \Redis::SERIALIZER_PHP);
150
        $store->set($key, $value);
151
 
152
        self::assertEquals($value, $store->get($key), "Failed set/get for: {$key}");
153
    }
154
 
155
    /**
156
     * Test it works with different types for many.
157
     */
11 efrain 158
    public function test_it_works_with_different_types_for_many(): void {
1 efrain 159
        $store = $this->create_store(cachestore_redis::COMPRESSOR_PHP_GZIP, \Redis::SERIALIZER_PHP);
160
 
1441 ariadna 161
        $provider = self::provider_for_test_it_works_with_different_types();
1 efrain 162
        $keys = [];
163
        $values = [];
164
        $expected = [];
165
        foreach ($provider as $item) {
166
            $keys[] = $item[0];
167
            $values[] = ['key' => $item[0], 'value' => $item[1]];
168
            $expected[$item[0]] = $item[1];
169
        }
170
        $store->set_many($values);
171
        $actual = $store->get_many($keys);
172
        self::assertEquals($expected, $actual);
173
    }
174
 
175
    /**
176
     * Provider for set/get combination tests.
177
     *
178
     * @return array
179
     */
1441 ariadna 180
    public static function provider_for_tests_setget(): array {
1 efrain 181
        $data = [
182
            ['none, none',
183
                \Redis::SERIALIZER_NONE, cachestore_redis::COMPRESSOR_NONE,
184
                'value1', 'value2'],
185
            ['none, gzip',
186
                \Redis::SERIALIZER_NONE, cachestore_redis::COMPRESSOR_PHP_GZIP,
187
                gzencode('value1'), gzencode('value2')],
188
            ['php, none',
189
                \Redis::SERIALIZER_PHP, cachestore_redis::COMPRESSOR_NONE,
190
                serialize('value1'), serialize('value2')],
191
            ['php, gzip',
192
                \Redis::SERIALIZER_PHP, cachestore_redis::COMPRESSOR_PHP_GZIP,
193
                gzencode(serialize('value1')), gzencode(serialize('value2'))],
194
        ];
195
 
196
        if (defined('Redis::SERIALIZER_IGBINARY')) {
197
            $data[] = [
198
                'igbinary, none',
199
                    \Redis::SERIALIZER_IGBINARY, cachestore_redis::COMPRESSOR_NONE,
200
                    igbinary_serialize('value1'), igbinary_serialize('value2'),
201
            ];
202
            $data[] = [
203
                'igbinary, gzip',
204
                    \Redis::SERIALIZER_IGBINARY, cachestore_redis::COMPRESSOR_PHP_GZIP,
205
                    gzencode(igbinary_serialize('value1')), gzencode(igbinary_serialize('value2')),
206
            ];
207
        }
208
 
209
        if (extension_loaded('zstd')) {
210
            $data[] = [
211
                'none, zstd',
212
                \Redis::SERIALIZER_NONE, cachestore_redis::COMPRESSOR_PHP_ZSTD,
213
                zstd_compress('value1'), zstd_compress('value2'),
214
            ];
215
            $data[] = [
216
                'php, zstd',
217
                \Redis::SERIALIZER_PHP, cachestore_redis::COMPRESSOR_PHP_ZSTD,
218
                zstd_compress(serialize('value1')), zstd_compress(serialize('value2')),
219
            ];
220
 
221
            if (defined('\Redis::SERIALIZER_IGBINARY')) {
222
                $data[] = [
223
                    'igbinary, zstd',
224
                    \Redis::SERIALIZER_IGBINARY, cachestore_redis::COMPRESSOR_PHP_ZSTD,
225
                    zstd_compress(igbinary_serialize('value1')), zstd_compress(igbinary_serialize('value2')),
226
                ];
227
            }
228
        }
229
 
230
        return $data;
231
    }
232
 
233
    /**
234
     * Test we can use get and set with all combinations.
235
     *
236
     * @dataProvider provider_for_tests_setget
1441 ariadna 237
     * @requires extension Redis
1 efrain 238
     * @param string $name
239
     * @param int $serializer
240
     * @param int $compressor
241
     * @param string $rawexpected1
242
     * @param string $rawexpected2
243
     */
11 efrain 244
    public function test_it_can_use_getset($name, $serializer, $compressor, $rawexpected1, $rawexpected2): void {
1 efrain 245
        // Create a connection with the desired serialisation.
246
        $store = $this->create_store($compressor, $serializer);
247
        $store->set('key', 'value1');
248
 
249
        // Disable compressor and serializer to check the actual stored value.
250
        $rawstore = $this->create_store(cachestore_redis::COMPRESSOR_NONE, \Redis::SERIALIZER_NONE);
251
 
252
        $data = $store->get('key');
253
        $rawdata = $rawstore->get('key');
254
        self::assertSame('value1', $data, "Invalid serialisation/unserialisation for: {$name}");
255
        self::assertSame($rawexpected1, $rawdata, "Invalid rawdata for: {$name}");
256
    }
257
 
258
    /**
259
     * Test we can use get and set many with all combinations.
260
     *
261
     * @dataProvider provider_for_tests_setget
1441 ariadna 262
     * @requires extension Redis
1 efrain 263
     * @param string $name
264
     * @param int $serializer
265
     * @param int $compressor
266
     * @param string $rawexpected1
267
     * @param string $rawexpected2
268
     */
11 efrain 269
    public function test_it_can_use_getsetmany($name, $serializer, $compressor, $rawexpected1, $rawexpected2): void {
1 efrain 270
        $many = [
271
            ['key' => 'key1', 'value' => 'value1'],
272
            ['key' => 'key2', 'value' => 'value2'],
273
        ];
274
        $keys = ['key1', 'key2'];
275
        $expectations = ['key1' => 'value1', 'key2' => 'value2'];
276
        $rawexpectations = ['key1' => $rawexpected1, 'key2' => $rawexpected2];
277
 
278
        // Create a connection with the desired serialisation.
279
        $store = $this->create_store($compressor, $serializer);
280
        $store->set_many($many);
281
 
282
        // Disable compressor and serializer to check the actual stored value.
283
        $rawstore = $this->create_store(cachestore_redis::COMPRESSOR_NONE, \Redis::SERIALIZER_NONE);
284
 
285
        $data = $store->get_many($keys);
286
        $rawdata = $rawstore->get_many($keys);
287
        foreach ($keys as $key) {
288
            self::assertSame($expectations[$key],
289
                             $data[$key],
290
                             "Invalid serialisation/unserialisation for {$key} with serializer {$name}");
291
            self::assertSame($rawexpectations[$key],
292
                             $rawdata[$key],
293
                             "Invalid rawdata for {$key} with serializer {$name}");
294
        }
295
    }
296
}