Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bugfix for hgetall used with serializer.
Fixes issue #62.
Also started removing phpunit, it is such a pain to use.
  • Loading branch information
nicolasff committed Nov 3, 2011
1 parent ccc916d commit 27fc7c7
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 25 deletions.
19 changes: 13 additions & 6 deletions library.c
Expand Up @@ -14,6 +14,9 @@
#include "library.h"
#include <ext/standard/php_math.h>

#define UNSERIALIZE_ONLY_VALUES 0
#define UNSERIALIZE_ALL 1

extern zend_class_entry *redis_ce;
extern zend_class_entry *redis_exception_ce;
extern zend_class_entry *spl_ce_RuntimeException;
Expand Down Expand Up @@ -82,7 +85,7 @@ PHPAPI zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS,
array_init(z_tab);

redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAM_PASSTHRU,
redis_sock, z_tab, numElems, 1);
redis_sock, z_tab, numElems, 1, UNSERIALIZE_ALL);
return z_tab;
}

Expand Down Expand Up @@ -556,7 +559,7 @@ PHPAPI int redis_sock_read_multibulk_reply_zipped_with_flag(INTERNAL_FUNCTION_PA
array_init(z_multi_result); /* pre-allocate array for multi's results. */

redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAM_PASSTHRU,
redis_sock, z_multi_result, numElems, 1);
redis_sock, z_multi_result, numElems, 1, flag ? UNSERIALIZE_ALL : UNSERIALIZE_ONLY_VALUES);

array_zip_values_and_scores(redis_sock, z_multi_result, 0 TSRMLS_CC);

Expand Down Expand Up @@ -855,7 +858,7 @@ PHPAPI int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
array_init(z_multi_result); /* pre-allocate array for multi's results. */

redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAM_PASSTHRU,
redis_sock, z_multi_result, numElems, 1);
redis_sock, z_multi_result, numElems, 1, UNSERIALIZE_ALL);

IF_MULTI_OR_PIPELINE() {
add_next_index_zval(z_tab, z_multi_result);
Expand Down Expand Up @@ -896,7 +899,7 @@ PHPAPI int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, Red
array_init(z_multi_result); /* pre-allocate array for multi's results. */

redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAM_PASSTHRU,
redis_sock, z_multi_result, numElems, 0);
redis_sock, z_multi_result, numElems, 0, UNSERIALIZE_ALL);

IF_MULTI_OR_PIPELINE() {
add_next_index_zval(z_tab, z_multi_result);
Expand All @@ -910,7 +913,7 @@ PHPAPI int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, Red

PHPAPI int
redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zval *z_tab, int numElems, int unwrap_key)
zval *z_tab, int numElems, int unwrap_key, int unserialize_even_only)
{
char *response;
int response_len;
Expand All @@ -919,7 +922,11 @@ redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *re
response = redis_sock_read(redis_sock, &response_len TSRMLS_CC);
if(response != NULL) {
zval *z = NULL;
if(unwrap_key && redis_unserialize(redis_sock, response, response_len, &z TSRMLS_CC) == 1) {
int can_unserialize = unwrap_key;
if(unserialize_even_only == UNSERIALIZE_ONLY_VALUES && numElems % 2 == 0)
can_unserialize = 0;

if(can_unserialize && redis_unserialize(redis_sock, response, response_len, &z TSRMLS_CC) == 1) {
efree(response);
add_next_index_zval(z_tab, z);
} else {
Expand Down
2 changes: 1 addition & 1 deletion library.h
Expand Up @@ -21,7 +21,7 @@ PHPAPI zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS,
PHPAPI char *redis_sock_read_bulk_reply(RedisSock *redis_sock, int bytes TSRMLS_DC);
PHPAPI int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *_z_tab, void *ctx);
PHPAPI int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, int numElems, int unwrap_key);
PHPAPI int redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, int numElems, int unwrap_key, int unserialize_even_only);
PHPAPI int redis_sock_read_multibulk_reply_zipped(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_read_multibulk_reply_zipped_strings(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_read_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
Expand Down
90 changes: 72 additions & 18 deletions tests/TestRedis.php
@@ -1,14 +1,17 @@
<?php
require_once 'PHPUnit.php';

// phpunit is such a pain to install, we're going with pure-PHP here.

echo "Note: these tests might take up to a minute. Don't worry :-)\n";

class Redis_Test extends PHPUnit_TestCase
class Redis_Test
{
const HOST = '127.0.0.1';
const PORT = 6379;
const AUTH = NULL; //replace with a string to use Redis authentication

public static $errors = array();

/**
* @var Redis
*/
Expand All @@ -19,6 +22,31 @@ public function setUp()
$this->redis = $this->newInstance();
}

private function assertFalse($bool) {
$this->assertTrue(!$bool);
}

private function assertTrue($bool) {
if($bool)
return;

$bt = debug_backtrace(false);
$count = count($bt);
self::$errors []= sprintf("Assertion failed: %s:%d (%s)\n",
$bt[$count - 2]["file"], $bt[$count - 3]["line"], $bt[$count - 1]["function"]);
}

private function assertEquals($a, $b) {
if($a === $b)
return;

$bt = debug_backtrace(false);
$count = count($bt);
self::$errors []= sprintf("Assertion failed (%s !== %s): %s:%d (%s)\n",
print_r($a, true), print_r($b, true),
$bt[$count - 2]["file"], $bt[$count - 3]["line"], $bt[$count - 1]["function"]);
}

private function newInstance() {
$r = new Redis();
$r->connect(self::HOST, self::PORT);
Expand Down Expand Up @@ -333,22 +361,22 @@ public function testIncr()
$this->redis->set('key', 0);

$this->redis->incr('key');
$this->assertEquals(1, $this->redis->get('key'));
$this->assertEquals(1, (int)$this->redis->get('key'));

$this->redis->incr('key');
$this->assertEquals(2, $this->redis->get('key'));
$this->assertEquals(2, (int)$this->redis->get('key'));

$this->redis->incr('key', 3);
$this->assertEquals(5, $this->redis->get('key'));
$this->assertEquals(5, (int)$this->redis->get('key'));

$this->redis->incrBy('key', 3);
$this->assertEquals(8, $this->redis->get('key'));
$this->assertEquals(8, (int)$this->redis->get('key'));

$this->redis->incrBy('key', 1);
$this->assertEquals(9, $this->redis->get('key'));
$this->assertEquals(9, (int)$this->redis->get('key'));

$this->redis->incrBy('key', -1);
$this->assertEquals(8, $this->redis->get('key'));
$this->assertEquals(8, (int)$this->redis->get('key'));

$this->redis->delete('key');

Expand All @@ -367,25 +395,25 @@ public function testDecr()
$this->redis->set('key', 5);

$this->redis->decr('key');
$this->assertEquals(4, $this->redis->get('key'));
$this->assertEquals(4, (int)$this->redis->get('key'));

$this->redis->decr('key');
$this->assertEquals(3, $this->redis->get('key'));
$this->assertEquals(3, (int)$this->redis->get('key'));

$this->redis->decr('key', 2);
$this->assertEquals(1, $this->redis->get('key'));
$this->assertEquals(1, (int)$this->redis->get('key'));

$this->redis->decr('key', 2);
$this->assertEquals(-1, $this->redis->get('key'));
$this->assertEquals(-1, (int)$this->redis->get('key'));

$this->redis->decrBy('key', 2);
$this->assertEquals(-3, $this->redis->get('key'));
$this->assertEquals(-3, (int)$this->redis->get('key'));

$this->redis->decrBy('key', 1);
$this->assertEquals(-4, $this->redis->get('key'));
$this->assertEquals(-4, (int)$this->redis->get('key'));

$this->redis->decr('key', -10);
$this->assertEquals(6, $this->redis->get('key'));
$this->assertEquals(6, (int)$this->redis->get('key'));
}

public function testExists()
Expand Down Expand Up @@ -2766,16 +2794,42 @@ private function checkSerializer($mode) {
// keys
$this->assertTrue(is_array($this->redis->keys('*')));

// issue #62, hgetall
$this->redis->del('hash1');
$this->redis->hSet('hash1','data', 'test 1');
$this->redis->hSet('hash1','session_id', 'test 2');

$data = $this->redis->hGetAll('hash1');
$this->assertTrue($data['data'] === 'test 1');
$this->assertTrue($data['session_id'] === 'test 2');

// revert
$this->assertTrue($this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE) === TRUE); // set ok
$this->assertTrue($this->redis->getOption(Redis::OPT_SERIALIZER) === Redis::SERIALIZER_NONE); // get ok
}
}

$suite = new PHPUnit_TestSuite("Redis_Test");
$result = PHPUnit::run($suite);
$rc = new ReflectionClass("Redis_Test");
$methods = $rc->GetMethods(ReflectionMethod::IS_PUBLIC);

echo $result->toString();
foreach($methods as $m) {

$name = $m->name;
if(substr($name, 0, 4) !== 'test')
continue;

$count = count(Redis_Test::$errors);
$rt = new Redis_Test;
$rt->setUp();
$rt->$name();
echo ($count === count(Redis_Test::$errors)) ? "." : "F";
}
echo "\n";

if(empty(Redis_Test::$errors)) {
echo "All tests passed.\n";
exit(0);
}

echo implode('', Redis_Test::$errors);
?>

0 comments on commit 27fc7c7

Please sign in to comment.