Files
phpredis/tests/TestRedis.php
michael-grunder 7b36957682 Various memory related fixes for php7
The php7 api has substantial changes in the way one goes about
interacting with the zval type (php's internal structure for dealing
with dynamically typed variables).

Most notably, most everything is dereferenced by one pointer.  So,
where you once used zval** you typically use zval*, and where you
used zval* you now just use a zval struct on the stack.

In addition, the api changed in how you return a string.  Previously
you had the option of whether or not to "duplicate" the memory returned
(or in other words, pass ownership of the pointer to PHP or not).

Because phpredis sometimes buffers commands to the server (say in the
case of a pipeline, or a MULTI/EXEC) transaction, we had several stack
violations and/or memory corruption which resulted from keeping track
of the address of a stack allocated structure, which was accessed at
a later date (sometimes causing segmentation faults, bus errors, etc).

Also, there were a few places where this pattern was being used:

zval **ptr = emalloc(sizeof(zval*) * count);
/* stuff */
ZVAL_STRING(ptr[0], "hello world");

Given that ZVAL_STRING() thinks it's writing to an allocated structure
it would cause various random issues (because we were blowing through
the data segment and writing into the code section).

This commit (so far) fixes all of the segmentation faults and memory
errors but there are still leaks (specifically in RedisArray) that need
to be solved.

Addresses #727
2016-01-25 12:55:41 -08:00

57 lines
2.1 KiB
PHP

<?php define('PHPREDIS_TESTRUN', true);
require_once(dirname($_SERVER['PHP_SELF'])."/TestSuite.php");
require_once(dirname($_SERVER['PHP_SELF'])."/RedisTest.php");
require_once(dirname($_SERVER['PHP_SELF'])."/RedisArrayTest.php");
require_once(dirname($_SERVER['PHP_SELF'])."/RedisClusterTest.php");
/* Make sure errors go to stdout and are shown */
error_reporting(E_ALL);
ini_set( 'display_errors','1');
/* Grab options */
$arr_args = getopt('', Array('class:', 'test:', 'nocolors'));
/* Grab the test the user is trying to run */
$arr_valid_classes = Array('redis', 'redisarray', 'rediscluster');
$str_class = isset($arr_args['class']) ? strtolower($arr_args['class']) : 'redis';
$boo_colorize = !isset($arr_args['nocolors']);
/* Get our test filter if provided one */
$str_filter = isset($arr_args['test']) ? $arr_args['test'] : NULL;
/* Validate the class is known */
if (!in_array($str_class, $arr_valid_classes)) {
echo "Error: Valid test classes are Redis, RedisArray, and RedisCluster!\n";
exit(1);
}
/* Toggle colorization in our TestSuite class */
TestSuite::flagColorization($boo_colorize);
/* Let the user know this can take a bit of time */
echo "Note: these tests might take up to a minute. Don't worry :-)\n";
/* Depending on the classes being tested, run our tests on it */
echo "Testing class ";
if ($str_class == 'redis') {
echo TestSuite::make_bold("Redis") . "\n";
exit(TestSuite::run("Redis_Test", $str_filter));
} else if ($str_class == 'redisarray') {
echo TestSuite::make_bold("RedisArray") . "\n";
global $useIndex;
foreach(array(false) as $useIndex) {
echo "\n".($useIndex?"WITH":"WITHOUT"). " per-node index:\n";
run_tests('Redis_Array_Test', $str_filter);
run_tests('Redis_Rehashing_Test', $str_filter);
run_tests('Redis_Auto_Rehashing_Test', $str_filter);
// run_tests('Redis_Multi_Exec_Test', $str_filter);
run_tests('Redis_Distributor_Test', $str_filter);
}
} else {
echo TestSuite::make_bold("RedisCluster") . "\n";
exit(TestSuite::run("Redis_Cluster_Test", $str_filter));
}
?>