Proyectos de Subversion Moodle

Rev

Ir a la última revisión | | 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 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
}