summaryrefslogtreecommitdiff
path: root/test.c
diff options
context:
space:
mode:
authorJan-Erik Rediger <janerik@fnordig.de>2015-04-16 19:28:12 +0200
committerJan-Erik Rediger <janerik@fnordig.de>2015-04-16 21:00:30 +0200
commitd9e0b0f6abfbb8918f73607bdfcc707d0df3fd41 (patch)
tree18a642cfca4697e0349767238ddf6d6ff368ea38 /test.c
parentb872919463fbc04c3a8fde113cb9ae89dfcb3859 (diff)
Implement a reconnect method for the client context
Originally implemented by @abedra as part of #306. In case a write or read times out, we force an error state, because we can't guarantuee that the next read will get the right data. Instead we need to reconnect to have a clean-state connection, which is now easily possible with this method.
Diffstat (limited to 'test.c')
-rw-r--r--test.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/test.c b/test.c
index c1575b1..8fde554 100644
--- a/test.c
+++ b/test.c
@@ -11,6 +11,7 @@
#include <limits.h>
#include "hiredis.h"
+#include "net.h"
enum connection_type {
CONN_TCP,
@@ -443,6 +444,52 @@ static void test_blocking_connection(struct config config) {
disconnect(c, 0);
}
+static void test_blocking_connection_timeouts(struct config config) {
+ redisContext *c;
+ redisReply *reply;
+ ssize_t s;
+ const char *cmd = "DEBUG SLEEP 3\r\n";
+ struct timeval tv;
+
+ c = connect(config);
+ test("Successfully completes a command when the timeout is not exceeded: ");
+ reply = redisCommand(c,"SET foo fast");
+ freeReplyObject(reply);
+ tv.tv_sec = 0;
+ tv.tv_usec = 10000;
+ redisSetTimeout(c, tv);
+ reply = redisCommand(c, "GET foo");
+ test_cond(reply != NULL && reply->type == REDIS_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0);
+ freeReplyObject(reply);
+ disconnect(c, 0);
+
+ c = connect(config);
+ test("Does not return a reply when the command times out: ");
+ s = write(c->fd, cmd, strlen(cmd));
+ tv.tv_sec = 0;
+ tv.tv_usec = 10000;
+ redisSetTimeout(c, tv);
+ reply = redisCommand(c, "GET foo");
+ test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Resource temporarily unavailable") == 0);
+ freeReplyObject(reply);
+
+ test("Reconnect properly reconnects after a timeout: ");
+ redisReconnect(c);
+ reply = redisCommand(c, "PING");
+ test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
+ freeReplyObject(reply);
+
+ test("Reconnect properly uses owned parameters: ");
+ config.tcp.host = "foo";
+ config.unix.path = "foo";
+ redisReconnect(c);
+ reply = redisCommand(c, "PING");
+ test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
+ freeReplyObject(reply);
+
+ disconnect(c, 0);
+}
+
static void test_blocking_io_errors(struct config config) {
redisContext *c;
redisReply *reply;
@@ -729,6 +776,7 @@ int main(int argc, char **argv) {
printf("\nTesting against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port);
cfg.type = CONN_TCP;
test_blocking_connection(cfg);
+ test_blocking_connection_timeouts(cfg);
test_blocking_io_errors(cfg);
test_invalid_timeout_errors(cfg);
test_append_formatted_commands(cfg);
@@ -737,6 +785,7 @@ int main(int argc, char **argv) {
printf("\nTesting against Unix socket connection (%s):\n", cfg.unix.path);
cfg.type = CONN_UNIX;
test_blocking_connection(cfg);
+ test_blocking_connection_timeouts(cfg);
test_blocking_io_errors(cfg);
if (throughput) test_throughput(cfg);