-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
More tests with simulated Redis traffic (MOVED redirects, async API)
Add a test case for MOVED redirects and run simulated traffic tests with both the sync and the async API.
- Loading branch information
1 parent
0f2922a
commit abb920a
Showing
7 changed files
with
242 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* | ||
* This program connects to a cluster and then reads commands from stdin, such | ||
* as "SET foo bar", one per line and prints the results to stdout. | ||
* | ||
* The behaviour is the same as that of clusterclient.c, but the asynchronous | ||
* API of the library is used rather than the synchronous API. | ||
*/ | ||
|
||
#include "adapters/libevent.h" | ||
#include "hircluster.h" | ||
#include "test_utils.h" | ||
#include <assert.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
int num_running = 0; | ||
|
||
/* | ||
void printReply(redisReply *reply) { | ||
switch (reply->type) { | ||
case REDIS_REPLY_INTEGER: printf("%lld", reply->integer); break; | ||
case REDIS_REPLY_DOUBLE: printf("%s", reply->str); break; | ||
case REDIS_REPLY_ERROR: printf("-%s", reply->str); break; | ||
// TODO: Escape special chars in strings | ||
case REDIS_REPLY_STRING: printf("\"%s\"", reply->str); break; | ||
case REDIS_REPLY_ARRAY: | ||
printf("["); | ||
for (size_t i = 0; i < reply->elements; i++) { | ||
printReply(reply->element[i]); | ||
if (i < reply->elements - 1) | ||
printf(", "); | ||
} | ||
printf("]"); | ||
break; | ||
default: | ||
printf("UNKNOWN TYPE %d", reply->type); | ||
} | ||
} | ||
*/ | ||
|
||
void replyCallback(redisClusterAsyncContext *acc, void *r, void *privdata) { | ||
UNUSED(privdata); | ||
redisReply *reply = (redisReply *)r; | ||
ASSERT_MSG(reply != NULL, acc->errstr); | ||
|
||
/* printReply(reply); */ | ||
/* printf("\n"); */ | ||
printf("%s\n", reply->str); | ||
|
||
if (--num_running == 0) { | ||
// Disconnect after receiving all replies | ||
redisClusterAsyncDisconnect(acc); | ||
} | ||
} | ||
|
||
void connectCallback(const redisAsyncContext *ac, int status) { | ||
ASSERT_MSG(status == REDIS_OK, ac->errstr); | ||
// printf("Connected to %s:%d\n", ac->c.tcp.host, ac->c.tcp.port); | ||
} | ||
|
||
void disconnectCallback(const redisAsyncContext *ac, int status) { | ||
ASSERT_MSG(status == REDIS_OK, ac->errstr); | ||
// printf("Disconnected from %s:%d\n", ac->c.tcp.host, ac->c.tcp.port); | ||
} | ||
|
||
int main(int argc, char **argv) { | ||
if (argc <= 1) { | ||
fprintf(stderr, "Usage: clusterclient_async HOST:PORT\n"); | ||
exit(1); | ||
} | ||
const char *initnode = argv[1]; | ||
|
||
redisClusterAsyncContext *acc = redisClusterAsyncContextInit(); | ||
assert(acc); | ||
redisClusterAsyncSetConnectCallback(acc, connectCallback); | ||
redisClusterAsyncSetDisconnectCallback(acc, disconnectCallback); | ||
redisClusterSetOptionAddNodes(acc->cc, initnode); | ||
redisClusterSetOptionRouteUseSlots(acc->cc); | ||
redisClusterConnect2(acc->cc); | ||
if (acc->err) { | ||
printf("Connect error: %s\n", acc->errstr); | ||
exit(-1); | ||
} | ||
|
||
int status; | ||
struct event_base *base = event_base_new(); | ||
status = redisClusterLibeventAttach(acc, base); | ||
assert(status == REDIS_OK); | ||
|
||
// Forward commands from stdin to redis cluster | ||
char command[256]; | ||
|
||
// Make sure num_running doesn't reach 0 in replyCallback() before all | ||
// commands have been sent. | ||
num_running++; | ||
|
||
while (fgets(command, 256, stdin)) { | ||
size_t len = strlen(command); | ||
if (command[len - 1] == '\n') // Chop trailing line break | ||
command[len - 1] = '\0'; | ||
status = | ||
redisClusterAsyncCommand(acc, replyCallback, (char *)"ID", command); | ||
ASSERT_MSG(status == REDIS_OK, acc->errstr); | ||
num_running++; | ||
} | ||
num_running--; // all commands sent | ||
|
||
event_base_dispatch(base); | ||
|
||
redisClusterAsyncFree(acc); | ||
event_base_free(base); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#!/bin/sh | ||
|
||
# Usage: $0 /path/to/clusterclient-binary | ||
|
||
clientprog=${1:-./clusterclient} | ||
testname=moved-redirect-test | ||
|
||
# Sync processes waiting for CONT signals. | ||
perl -we 'use sigtrap "handler", sub{exit}, "CONT"; sleep 1; die "timeout"' & | ||
syncpid1=$!; | ||
perl -we 'use sigtrap "handler", sub{exit}, "CONT"; sleep 1; die "timeout"' & | ||
syncpid2=$!; | ||
|
||
# Start simulated redis node #1 | ||
timeout 5s ./simulated-redis.pl -p 7403 -d --sigcont $syncpid1 <<'EOF' & | ||
EXPECT CONNECT | ||
EXPECT ["CLUSTER", "SLOTS"] | ||
SEND [[0, 16383, ["127.0.0.1", 7403, "nodeid7403"]]] | ||
EXPECT CLOSE | ||
EXPECT CONNECT | ||
EXPECT ["GET", "foo"] | ||
SEND -MOVED 12182 127.0.0.1:7404 | ||
EXPECT CONNECT | ||
EXPECT ["CLUSTER", "SLOTS"] | ||
SEND [[0, 16383, ["127.0.0.1", 7404, "nodeid7404"]]] | ||
EXPECT CLOSE | ||
EXPECT CLOSE | ||
EOF | ||
server1=$! | ||
|
||
# Start simulated redis node #2 | ||
timeout 5s ./simulated-redis.pl -p 7404 -d --sigcont $syncpid2 <<'EOF' & | ||
EXPECT CONNECT | ||
EXPECT ["GET", "foo"] | ||
SEND "bar" | ||
EXPECT CLOSE | ||
EOF | ||
server2=$! | ||
|
||
# Wait until both nodes are ready to accept client connections | ||
wait $syncpid1 $syncpid2; | ||
|
||
# Run client | ||
echo 'GET foo' | timeout 3s "$clientprog" 127.0.0.1:7403 > "$testname.out" | ||
clientexit=$? | ||
|
||
# Wait for servers to exit | ||
wait $server1; server1exit=$? | ||
wait $server2; server2exit=$? | ||
|
||
# Check exit statuses | ||
if [ $server1exit -ne 0 ]; then | ||
echo "Simulated server #1 exited with status $server1exit" | ||
exit $server1exit | ||
fi | ||
if [ $server2exit -ne 0 ]; then | ||
echo "Simulated server #2 exited with status $server2exit" | ||
exit $server2exit | ||
fi | ||
if [ $clientexit -ne 0 ]; then | ||
echo "$clientprog exited with status $clientexit" | ||
exit $clientexit | ||
fi | ||
|
||
# Check the output from clusterclient | ||
echo 'bar' | cmp "$testname.out" - || exit 99 | ||
|
||
# Clean up | ||
rm "$testname.out" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters