Skip to content

Commit 08ecec9

Browse files
Unit test suite improvements and cluster failover test
* Added a test specifically for RedisCluster to test slave failover settings. * Added an option to specifically disable colorization, as well as a mechanism to determine if the output is being piped, such that we can turn colorization off in that case as well.
1 parent 97c9edc commit 08ecec9

File tree

5 files changed

+189
-15
lines changed

5 files changed

+189
-15
lines changed

tests/RedisArrayTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php
1+
<?php defined('PHPREDIS_TESTRUN') or die("Use TestRedis.php to run tests!\n");
22
require_once(dirname($_SERVER['PHP_SELF'])."/TestSuite.php");
33

44
define('REDIS_ARRAY_DATA_SIZE', 1000);

tests/RedisClusterTest.php

Lines changed: 154 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php
1+
<?php defined('PHPREDIS_TESTRUN') or die("Use TestRedis.php to run tests!\n");
22
require_once(dirname($_SERVER['PHP_SELF'])."/RedisTest.php");
33

44
/**
@@ -9,6 +9,20 @@
99
class Redis_Cluster_Test extends Redis_Test {
1010
private $_arr_node_map = Array();
1111

12+
private $_arr_redis_types = Array(
13+
Redis::REDIS_STRING,
14+
Redis::REDIS_SET,
15+
Redis::REDIS_LIST,
16+
Redis::REDIS_ZSET,
17+
Redis::REDIS_HASH
18+
);
19+
20+
private $_arr_failover_types = Array(
21+
RedisCluster::FAILOVER_NONE,
22+
RedisCluster::FAILOVER_ERROR,
23+
RedisCluster::FAILOVER_DISTRIBUTE
24+
);
25+
1226
/* Tests we'll skip all together in the context of RedisCluster. The
1327
* RedisCluster class doesn't implement specialized (non-redis) commands
1428
* such as sortAsc, or sortDesc and other commands such as SELECT are
@@ -216,16 +230,17 @@ public function testFailedTransactions() {
216230
$r = $this->newInstance(); // new instance, modifying `x'.
217231
$r->incr('x');
218232

233+
// This transaction should fail because the other client changed 'x'
219234
$ret = $this->redis->multi()->get('x')->exec();
220-
$this->assertTrue($ret === Array(FALSE)); // failed because another client changed our watched key between WATCH and EXEC.
221-
235+
$this->assertTrue($ret === Array(FALSE));
222236
// watch and unwatch
223237
$this->redis->watch('x');
224238
$r->incr('x'); // other instance
225239
$this->redis->unwatch('x'); // cancel transaction watch
226240

241+
// This should succeed as the watch has been cancelled
227242
$ret = $this->redis->multi()->get('x')->exec();
228-
$this->assertTrue($ret === array('44')); // succeeded since we've cancel the WATCH command.
243+
$this->assertTrue($ret === array('44'));
229244
}
230245

231246
/* RedisCluster::script() is a 'raw' command, which requires a key such that
@@ -281,5 +296,140 @@ public function testEvalSHA() {
281296
$this->assertTrue(1 === $this->redis->eval($scr,Array($str_key), 1));
282297
$this->assertTrue(1 === $this->redis->evalsha($sha,Array($str_key), 1));
283298
}
299+
300+
protected function genKeyName($i_key_idx, $i_type) {
301+
switch ($i_type) {
302+
case Redis::REDIS_STRING:
303+
return "string-$i_key_idx";
304+
case Redis::REDIS_SET:
305+
return "set-$i_key_idx";
306+
case Redis::REDIS_LIST:
307+
return "list-$i_key_idx";
308+
case Redis::REDIS_ZSET:
309+
return "zset-$i_key_idx";
310+
case Redis::REDIS_HASH:
311+
return "hash-$i_key_idx";
312+
default:
313+
return "unknown-$i_key_idx";
314+
}
315+
}
316+
317+
protected function setKeyVals($i_key_idx, $i_type, &$arr_ref) {
318+
$str_key = $this->genKeyName($i_key_idx, $i_type);
319+
320+
$this->redis->del($str_key);
321+
322+
switch ($i_type) {
323+
case Redis::REDIS_STRING:
324+
$value = "$str_key-value";
325+
$this->redis->set($str_key, $value);
326+
break;
327+
case Redis::REDIS_SET:
328+
$value = Array(
329+
$str_key . '-mem1', $str_key . '-mem2', $str_key . '-mem3',
330+
$str_key . '-mem4', $str_key . '-mem5', $str_key . '-mem6'
331+
);
332+
$arr_args = $value;
333+
array_unshift($arr_args, $str_key);
334+
call_user_func_array(Array($this->redis, 'sadd'), $arr_args);
335+
break;
336+
case Redis::REDIS_HASH:
337+
$value = Array(
338+
$str_key . '-mem1' => $str_key . '-val1',
339+
$str_key . '-mem2' => $str_key . '-val2',
340+
$str_key . '-mem3' => $str_key . '-val3'
341+
);
342+
$this->redis->hmset($str_key, $value);
343+
break;
344+
case Redis::REDIS_LIST:
345+
$value = Array(
346+
$str_key . '-ele1', $str_key . '-ele2', $str_key . '-ele3',
347+
$str_key . '-ele4', $str_key . '-ele5', $str_key . '-ele6'
348+
);
349+
$arr_args = $value;
350+
array_unshift($arr_args, $str_key);
351+
call_user_func_array(Array($this->redis, 'rpush'), $arr_args);
352+
break;
353+
case Redis::REDIS_ZSET:
354+
$i_score = 1;
355+
$value = Array(
356+
$str_key . '-mem1' => 1, $str_key . '-mem2' => 2,
357+
$str_key . '-mem3' => 3, $str_key . '-mem3' => 3
358+
);
359+
foreach ($value as $str_mem => $i_score) {
360+
$this->redis->zadd($str_key, $i_score, $str_mem);
361+
}
362+
break;
363+
}
364+
365+
/* Update our reference array so we can verify values */
366+
$arr_ref[$str_key] = $value;
367+
return $str_key;
368+
}
369+
370+
/* Verify that our ZSET values are identical */
371+
protected function checkZSetEquality($a, $b) {
372+
/* If the count is off, the array keys are different or the sums are
373+
* different, we know there is something off */
374+
$boo_diff = count($a) != count($b) ||
375+
count(array_diff(array_keys($a), array_keys($b))) != 0 ||
376+
array_sum($a) != array_sum($b);
377+
378+
if ($boo_diff) {
379+
$this->assertEquals($a,$b);
380+
return;
381+
}
382+
}
383+
384+
protected function checkKeyValue($str_key, $i_type, $value) {
385+
switch ($i_type) {
386+
case Redis::REDIS_STRING:
387+
$this->assertEquals($value, $this->redis->get($str_key));
388+
break;
389+
case Redis::REDIS_SET:
390+
$arr_r_values = $this->redis->sMembers($str_key);
391+
$arr_l_values = $value;
392+
sort($arr_r_values);
393+
sort($arr_l_values);
394+
$this->assertEquals($arr_r_values, $arr_l_values);
395+
break;
396+
case Redis::REDIS_LIST:
397+
$this->assertEquals($value, $this->redis->lrange($str_key,0,-1));
398+
break;
399+
case Redis::REDIS_HASH:
400+
$this->assertEquals($value, $this->redis->hgetall($str_key));
401+
break;
402+
case Redis::REDIS_ZSET:
403+
$this->checkZSetEquality($value, $this->redis->zrange($str_key,0,-1,true));
404+
break;
405+
default:
406+
throw new Exception("Unknown type " . $i_type);
407+
}
408+
}
409+
410+
/* Test automatic load distributor */
411+
public function testFailOver() {
412+
$arr_value_ref = Array();
413+
$arr_type_ref = Array();
414+
415+
/* Set a bunch of keys of various redis types*/
416+
for ($i = 0; $i < 200; $i++) {
417+
foreach ($this->_arr_redis_types as $i_type) {
418+
$str_key = $this->setKeyVals($i, $i_type, $arr_value_ref);
419+
$arr_type_ref[$str_key] = $i_type;
420+
}
421+
}
422+
423+
/* Iterate over failover options */
424+
foreach ($this->_arr_failover_types as $i_opt) {
425+
$this->redis->setOption(RedisCluster::OPT_SLAVE_FAILOVER, $i_opt);
426+
427+
foreach ($arr_value_ref as $str_key => $value) {
428+
$this->checkKeyValue($str_key, $arr_type_ref[$str_key], $value);
429+
}
430+
431+
break;
432+
}
433+
}
284434
}
285435
?>

tests/RedisTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php
1+
<?php defined('PHPREDIS_TESTRUN') or die("Use TestRedis.php to run tests!\n");
22

33
require_once(dirname($_SERVER['PHP_SELF'])."/TestSuite.php");
44

tests/TestRedis.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
<?php
1+
<?php define('PHPREDIS_TESTRUN', true);
2+
23
require_once(dirname($_SERVER['PHP_SELF'])."/TestSuite.php");
34
require_once(dirname($_SERVER['PHP_SELF'])."/RedisTest.php");
45
require_once(dirname($_SERVER['PHP_SELF'])."/RedisArrayTest.php");
56
require_once(dirname($_SERVER['PHP_SELF'])."/RedisClusterTest.php");
67

8+
/* Make sure errors go to stdout and are shown */
9+
error_reporting(E_ALL);
10+
ini_set( 'display_errors','1');
11+
712
/* Grab options */
8-
$arr_args = getopt('', Array('class:', 'test:'));
13+
$arr_args = getopt('', Array('class:', 'test:', 'nocolors'));
914

1015
/* Grab the test the user is trying to run */
1116
$arr_valid_classes = Array('redis', 'redisarray', 'rediscluster');
1217
$str_class = isset($arr_args['class']) ? strtolower($arr_args['class']) : 'redis';
18+
$boo_colorize = !isset($arr_args['nocolors']);
1319

1420
/* Get our test filter if provided one */
1521
$str_filter = isset($arr_args['test']) ? $arr_args['test'] : NULL;
@@ -20,6 +26,9 @@
2026
exit(1);
2127
}
2228

29+
/* Toggle colorization in our TestSuite class */
30+
TestSuite::flagColorization($boo_colorize);
31+
2332
/* Let the user know this can take a bit of time */
2433
echo "Note: these tests might take up to a minute. Don't worry :-)\n";
2534

tests/TestSuite.php

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
<?php
1+
<?php defined('PHPREDIS_TESTRUN') or die("Use TestRedis.php to run tests!\n");
22

33
// phpunit is such a pain to install, we're going with pure-PHP here.
44
class TestSuite {
5+
private static $_boo_colorize = false;
56

67
private static $BOLD_ON = "\033[1m";
78
private static $BOLD_OFF = "\033[0m";
@@ -18,19 +19,27 @@ class TestSuite {
1819
public static $warnings = array();
1920

2021
public static function make_bold($str_msg) {
21-
return self::$BOLD_ON . $str_msg . self::$BOLD_OFF;
22+
return self::$_boo_colorize
23+
? self::$BOLD_ON . $str_msg . self::$BOLD_OFF
24+
: $str_msg;
2225
}
2326

2427
public static function make_success($str_msg) {
25-
return self::$GREEN . $str_msg . self::$BOLD_OFF;
28+
return self::$_boo_colorize
29+
? self::$GREEN . $str_msg . self::$BOLD_OFF
30+
: $str_msg;
2631
}
2732

2833
public static function make_fail($str_msg) {
29-
return self::$RED . $str_msg . self::$BOLD_OFF;
34+
return self::$_boo_colorize
35+
? self::$RED . $str_msg . self::$BOLD_OFF
36+
: $str_msg;
3037
}
3138

3239
public static function make_warning($str_msg) {
33-
return self::$YELLOW . $str_msg . self::$BOLD_OFF;
40+
return self::$_boo_colorize
41+
? self::$YELLOW . $str_msg . self::$BOLD_OFF
42+
: $str_msg;
3443
}
3544

3645
protected function assertFalse($bool) {
@@ -74,7 +83,7 @@ protected function markTestSkipped($msg='') {
7483
throw new Exception($msg);
7584
}
7685

77-
private function getMaxTestLen($arr_methods, $str_limit) {
86+
private static function getMaxTestLen($arr_methods, $str_limit) {
7887
$i_result = 0;
7988

8089
$str_limit = strtolower($str_limit);
@@ -92,6 +101,12 @@ private function getMaxTestLen($arr_methods, $str_limit) {
92101
}
93102
return $i_result;
94103
}
104+
105+
/* Flag colorization */
106+
public static function flagColorization($boo_override) {
107+
self::$_boo_colorize = $boo_override && function_exists('posix_isatty') &&
108+
posix_isatty(STDOUT);
109+
}
95110

96111
public static function run($className, $str_limit = NULL) {
97112
/* Lowercase our limit arg if we're passed one */
@@ -142,7 +157,7 @@ public static function run($className, $str_limit = NULL) {
142157
echo "[" . $str_msg . "]\n";
143158
}
144159
echo "\n";
145-
echo implode('', $className::$warnings);
160+
echo implode('', $className::$warnings) . "\n";
146161

147162
if(empty($className::$errors)) {
148163
echo "All tests passed. \o/\n";

0 commit comments

Comments
 (0)