static void test_blocking_connection_errors(void) { redisContext *c; test("Returns error when host cannot be resolved: "); c = redisConnect((char*)"idontexist.test", 6379); test_cond(c->err == REDIS_ERR_OTHER && (strcmp(c->errstr,"Name or service not known") == 0 || strcmp(c->errstr,"Can't resolve: idontexist.test") == 0 || strcmp(c->errstr,"nodename nor servname provided, or not known") == 0 || strcmp(c->errstr,"No address associated with hostname") == 0 || strcmp(c->errstr,"Temporary failure in name resolution") == 0 || strcmp(c->errstr,"hostname nor servname provided, or not known") == 0 || strcmp(c->errstr,"no address associated with name") == 0)); redisFree(c); test("Returns error when the port is not open: "); c = redisConnect((char*)"localhost", 1); test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr,"Connection refused") == 0); redisFree(c); test("Returns error when the unix socket path doesn't accept connections: "); c = redisConnectUnix((char*)"/tmp/idontexist.sock"); test_cond(c->err == REDIS_ERR_IO); /* Don't care about the message... */ redisFree(c); }
int main(void) { Landscape *l = landscape_create(2, 1, 1.0); landscape_set_height_at_node(l, 0, 0, 0.0); landscape_set_height_at_node(l, 0, 1, 0.0); landscape_set_height_at_node(l, 1, 0, 0.0); landscape_set_height_at_node(l, 1, 1, 0.0); Vector origin = { .x = 0.5, .y = 0.5, .z = 0.5 }; Vector orientation = { .x = 0, .y = 0, .z = 1 }; Vector direction = { .x = 1, .y = 0, .z = 0 }; Bounding b = { .origin = &origin, .previous_origin = &origin, .orientation = &orientation, .direction = &direction, .offset = { .x = 0, .y = 0, .z = 0 }, .bounding_type = bounding_box, .data = { .extent = { .x = 1, .y = 1, .z = 1 } } }; test_cond("Box landscape test 1.", bounding_intersects_with_landscape(l, &b)); origin.z = 1.5; test_cond("Box landscape test 2.", !bounding_intersects_with_landscape(l, &b)); b.bounding_type = bounding_sphere; b.data.radius = 3; test_cond("Sphere landscape test 1.", bounding_intersects_with_landscape(l, &b)); b.data.radius = 1; test_cond("Sphere landscape test 2.", !bounding_intersects_with_landscape(l, &b)); double speed = 0; Bounding composite_members[] = { { .origin = &origin, .previous_origin = &origin, .orientation = &orientation, .direction = &direction, .offset = { .x = 0, .y = 0, .z = 0 }, .speed = &speed, .bounding_type = bounding_box, .data = { .extent = { .x = 2, .y = 2, .z = 2 } } }, { .origin = &origin, .previous_origin = &origin, .orientation = &orientation, .direction = &direction, .offset = { .x = 0, .y = 0, .z = 1 }, .speed = &speed, .bounding_type = bounding_sphere, .data = { .radius = 1 } }
static void test_free_null(void) { void *redisCtx = NULL; void *reply = NULL; test("Don't fail when redisFree is passed a NULL value: "); redisFree(redisCtx); test_cond(redisCtx == NULL); test("Don't fail when freeReplyObject is passed a NULL value: "); freeReplyObject(reply); test_cond(reply == NULL); }
static void test_blocking_io_errors(struct config config) { redisContext *c; redisReply *reply; void *_reply; int major, minor; /* Connect to target given by config. */ c = connect(config); { /* Find out Redis version to determine the path for the next test */ const char *field = "redis_version:"; char *p, *eptr; reply = redisCommand(c,"INFO"); p = strstr(reply->str,field); major = strtol(p+strlen(field),&eptr,10); p = eptr+1; /* char next to the first "." */ minor = strtol(p,&eptr,10); freeReplyObject(reply); } test("Returns I/O error when the connection is lost: "); reply = redisCommand(c,"QUIT"); if (major > 2 || (major == 2 && minor > 0)) { /* > 2.0 returns OK on QUIT and read() should be issued once more * to know the descriptor is at EOF. */ test_cond(strcasecmp(reply->str,"OK") == 0 && redisGetReply(c,&_reply) == REDIS_ERR); freeReplyObject(reply); } else { test_cond(reply == NULL); } /* On 2.0, QUIT will cause the connection to be closed immediately and * the read(2) for the reply on QUIT will set the error to EOF. * On >2.0, QUIT will return with OK and another read(2) needed to be * issued to find out the socket was closed by the server. In both * conditions, the error will be set to EOF. */ assert(c->err == REDIS_ERR_EOF && strcmp(c->errstr,"Server closed the connection") == 0); redisFree(c); c = connect(config); test("Returns I/O error on socket timeout: "); struct timeval tv = { 0, 1000 }; assert(redisSetTimeout(c,tv) == REDIS_OK); test_cond(redisGetReply(c,&_reply) == REDIS_ERR && c->err == REDIS_ERR_IO && errno == EAGAIN); redisFree(c); }
int zoneParserTest(int argc, char *argv[]) { if (argc < 4) { fprintf(stderr, "need conf file\n"); exit(1); } test_cond("parse ttl 1", parsetime("2w3d3M2") == 17*(24*3600)+180 + 2); test_cond("parse ttl 2", parsetime("2002112") == 2002112); { char dot_origin[] = "google.com."; char domain[255] = "www.google.com."; abs2lenRelative(domain, dot_origin); test_cond("abs2lenRelative 1", strcmp(domain, "\3www") == 0); strcpy(domain, "aa.bb.google.com."); abs2lenRelative(domain, dot_origin); test_cond("abs2lenRelative 2", strcmp(domain, "\2aa\2bb") == 0); strcpy(domain, "google.com."); abs2lenRelative(domain, dot_origin); test_cond("abs2lenRelative 3", strcmp(domain, "@") == 0); } char *ss = readFile(argv[3]); char buf[1000]; int idx = 0; int err; char errstr[ERR_STR_LEN]; fprintf(stderr, "\n"); while ((err=readFullRecord(errstr, &ss, buf, 1000, &idx)) == OK_CODE) { fprintf(stderr, "l%d:%s \n", idx, buf); } fprintf(stderr, "\n"); zone *z; loadZoneFromFile(SOCKET_ID_HEAP, argv[3], &z); sds s = zoneToStr(z); printf("%s\n", s); sdsfree(s); // { // zone *z = zoneDictFetchVal(zd, "\7example\3com"); // sds s = zoneToStr(z); // LOG_DEBUG("%s", s); // sdsfree(s); // zoneDecRef(z); // } test_report(); return 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); }
int main(void) { { struct sdshdr *sh; sds x = sdsempty(); test_cond("sdsempty() should be strlen 0", strlen(x) == 0 && sdslen(x) == 0 && memcmp(x,"\0",1) == 0); sdsfree(x); x = sdsalloc(NULL, 2); test_cond("Create a NULL string with reserved space 2 bytes", sdslen(x) == 0 && sdsavail(x) == 2); sdsfree(x); } test_report() return 0; }
void test_post_mixed_param() { CURL_INIT_POST curl_easy_setopt(curl, CURLOPT_URL, "http://0.0.0.0:2000/multi/something/static/other"); res = curl_easy_perform(curl); if(CURLE_OK == res) { long status; res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); test_diag("Test multi param POST status"); test_cond(status == 200); test_diag("Test multi param POST content"); test_cond(strcmp(chunk.memory, "The params are something and other, the body is Username") == 0); } free(chunk.memory); curl_easy_cleanup(curl); }
void test_post_err_404() { CURL_INIT_POST curl_easy_setopt(curl, CURLOPT_URL, "http://0.0.0.0:2000/invalid"); res = curl_easy_perform(curl); if(CURLE_OK == res) { long status; res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); test_diag("Test POST error 404 status"); test_cond(status == 404); test_diag("Test POST error 404 content"); test_cond(strcmp(chunk.memory, "Error 404!") == 0); } free(chunk.memory); curl_easy_cleanup(curl); }
void test_status_simple() { CURL_INIT curl_easy_setopt(curl, CURLOPT_URL, "http://0.0.0.0:2000/coffe"); res = curl_easy_perform(curl); if(CURLE_OK == res) { long status; res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); test_diag("Test GET status"); test_cond(status == 418); test_diag("Test GET content"); test_cond(strcmp(chunk.memory, "Just a teapot!") == 0); } free(chunk.memory); curl_easy_cleanup(curl); }
void test_post_simple() { CURL_INIT_POST curl_easy_setopt(curl, CURLOPT_URL, "http://0.0.0.0:2000/simple"); res = curl_easy_perform(curl); if(CURLE_OK == res) { long status; res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); test_diag("Test simple POST status"); test_cond(status == 200); test_diag("Test simple POST content"); test_cond(strcmp(chunk.memory, "Hello Username!") == 0); } free(chunk.memory); curl_easy_cleanup(curl); }
//gcc --std=c99 -I. -o test -DHAVE_UNISTD_H -DISDK_XATTR_TEST_MAIN isdk_xattr.c sds.c zmalloc.c int main(void) { { int fd = open ("mytestfile", O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (fd != -1) close(fd); test_cond("touch('mytestfile')", fd != -1); sds path = sdsnew("mytestfile"), key = sdsnew("mydname"), value = sdsnew("hi world!"); test_cond("SetXattr(mytestfile, mydname, 'hi world!')", SetXattr(path, key, value)== 0); test_cond("IsXattrExists(mytestfile, mydname)", IsXattrExists(path, key)); test_cond("IsXattrExists(mytestfile, notexists)", !IsXattrExists(path, "notexists")); test_cond("IsXattrExists(nosuchmytestfile, notexists)", !IsXattrExists("nosuchmytestfile", "notexists")); sds result = GetXattr(path, key); test_cond("GetXattr(mytestfile, mydname)", result && sdslen(result) == 9 && memcmp(result, "hi world!\0", 10) == 0 ); sdsfree(path); sdsfree(key); sdsfree(value); if (result) sdsfree(result); remove("mytestfile"); } test_report(); return 0; }
int main(int c, char **v) { #ifdef RELEASE FILE *fs=fopen("/home/box/main.pid","w"); fprintf(fs,"%d",getpid()); fclose(fs); #endif test_cond(); test_barrier(); return 0; }
static void test_invalid_timeout_errors(struct config config) { redisContext *c; test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: "); config.tcp.timeout.tv_sec = 0; config.tcp.timeout.tv_usec = 10000001; c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout); test_cond(c->err == REDIS_ERR_IO); redisFree(c); test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: "); config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1; config.tcp.timeout.tv_usec = 0; c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout); test_cond(c->err == REDIS_ERR_IO); redisFree(c); }
static void test_append_formatted_commands(struct config config) { redisContext *c; redisReply *reply; char *cmd; int len; c = connect(config); test("Append format command: "); len = redisFormatCommand(&cmd, "SET foo bar"); test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK); assert(redisGetReply(c, (void*)&reply) == REDIS_OK); free(cmd); freeReplyObject(reply); disconnect(c, 0); }
int main () { #if TEST_PTH_THREADS if (!pth_init ()) abort (); #endif #if DO_TEST_COND printf ("Starting test_cond ..."); fflush (stdout); test_cond (); printf (" OK\n"); fflush (stdout); #endif #if DO_TEST_TIMEDCOND printf ("Starting test_timedcond ..."); fflush (stdout); test_timedcond (); printf (" OK\n"); fflush (stdout); #endif return 0; }
int main() { test_symbol(); test_integer(); test_cell(); test_list(); test_environment(); test_eval(); test_plus_integer(); test_begin(); test_string(); test_tokenize(); test_newlispobj(); test_expandreadmacro(); test_read_tokens(); test_macro(); test_equal(); test_cond(); return 0; }
static void test_reply_reader(void) { void *reader; void *reply; char *err; int ret; test("Error handling in reply parser: "); reader = redisReplyReaderCreate(); redisReplyReaderFeed(reader,(char*)"@foo\r\n",6); ret = redisReplyReaderGetReply(reader,NULL); err = redisReplyReaderGetError(reader); test_cond(ret == REDIS_ERR && strcasecmp(err,"Protocol error, got \"@\" as reply type byte") == 0); redisReplyReaderFree(reader); /* when the reply already contains multiple items, they must be free'd * on an error. valgrind will bark when this doesn't happen. */ test("Memory cleanup in reply parser: "); reader = redisReplyReaderCreate(); redisReplyReaderFeed(reader,(char*)"*2\r\n",4); redisReplyReaderFeed(reader,(char*)"$5\r\nhello\r\n",11); redisReplyReaderFeed(reader,(char*)"@foo\r\n",6); ret = redisReplyReaderGetReply(reader,NULL); err = redisReplyReaderGetError(reader); test_cond(ret == REDIS_ERR && strcasecmp(err,"Protocol error, got \"@\" as reply type byte") == 0); redisReplyReaderFree(reader); test("Set error on nested multi bulks with depth > 1: "); reader = redisReplyReaderCreate(); redisReplyReaderFeed(reader,(char*)"*1\r\n",4); redisReplyReaderFeed(reader,(char*)"*1\r\n",4); redisReplyReaderFeed(reader,(char*)"*1\r\n",4); ret = redisReplyReaderGetReply(reader,NULL); err = redisReplyReaderGetError(reader); test_cond(ret == REDIS_ERR && strncasecmp(err,"No support for",14) == 0); redisReplyReaderFree(reader); test("Works with NULL functions for reply: "); reader = redisReplyReaderCreate(); redisReplyReaderSetReplyObjectFunctions(reader,NULL); redisReplyReaderFeed(reader,(char*)"+OK\r\n",5); ret = redisReplyReaderGetReply(reader,&reply); test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); redisReplyReaderFree(reader); test("Works when a single newline (\\r\\n) covers two calls to feed: "); reader = redisReplyReaderCreate(); redisReplyReaderSetReplyObjectFunctions(reader,NULL); redisReplyReaderFeed(reader,(char*)"+OK\r",4); ret = redisReplyReaderGetReply(reader,&reply); assert(ret == REDIS_OK && reply == NULL); redisReplyReaderFeed(reader,(char*)"\n",1); ret = redisReplyReaderGetReply(reader,&reply); test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); redisReplyReaderFree(reader); test("Properly reset state after protocol error: "); reader = redisReplyReaderCreate(); redisReplyReaderSetReplyObjectFunctions(reader,NULL); redisReplyReaderFeed(reader,(char*)"x",1); ret = redisReplyReaderGetReply(reader,&reply); assert(ret == REDIS_ERR); ret = redisReplyReaderGetReply(reader,&reply); test_cond(ret == REDIS_OK && reply == NULL) }
int main(void) { { sds x = sdsnew("foo"), y; test_cond("Create a string and obtain the length", sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0) sdsfree(x); x = sdsnewlen("foo",2); test_cond("Create a string with specified length", sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0) x = sdscat(x,"bar"); test_cond("Strings concatenation", sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0); x = sdscpy(x,"a"); test_cond("sdscpy() against an originally longer string", sdslen(x) == 1 && memcmp(x,"a\0",2) == 0) x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk"); test_cond("sdscpy() against an originally shorter string", sdslen(x) == 33 && memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0) sdsfree(x); x = sdscatprintf(sdsempty(),"%d",123); test_cond("sdscatprintf() seems working in the base case", sdslen(x) == 3 && memcmp(x,"123\0",4) ==0) sdsfree(x); x = sdstrim(sdsnew("xxciaoyyy"),"xy"); test_cond("sdstrim() correctly trims characters", sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0) y = sdsrange(sdsdup(x),1,1); test_cond("sdsrange(...,1,1)", sdslen(y) == 1 && memcmp(y,"i\0",2) == 0) sdsfree(y); y = sdsrange(sdsdup(x),1,-1); test_cond("sdsrange(...,1,-1)", sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0) sdsfree(y); y = sdsrange(sdsdup(x),-2,-1); test_cond("sdsrange(...,-2,-1)", sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0) sdsfree(y); y = sdsrange(sdsdup(x),2,1); test_cond("sdsrange(...,2,1)", sdslen(y) == 0 && memcmp(y,"\0",1) == 0) sdsfree(y); y = sdsrange(sdsdup(x),1,100); test_cond("sdsrange(...,1,100)", sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0) sdsfree(y); y = sdsrange(sdsdup(x),100,100); test_cond("sdsrange(...,100,100)", sdslen(y) == 0 && memcmp(y,"\0",1) == 0) sdsfree(y); sdsfree(x); x = sdsnew("foo"); y = sdsnew("foa"); test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0) sdsfree(y); sdsfree(x); x = sdsnew("bar"); y = sdsnew("bar"); test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0) sdsfree(y); sdsfree(x); x = sdsnew("aar"); y = sdsnew("bar"); test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0) } test_report() }
static void test_blocking_connection(void) { redisContext *c; redisReply *reply; int major, minor; test("Returns error when host cannot be resolved: "); c = redisConnect((char*)"idontexist.local", 6379); test_cond(c->err == REDIS_ERR_OTHER && strcmp(c->errstr,"Can't resolve: idontexist.local") == 0); redisFree(c); test("Returns error when the port is not open: "); c = redisConnect((char*)"localhost", 56380); test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr,"Connection refused") == 0); redisFree(c); __connect(&c); test("Is able to deliver commands: "); reply = redisCommand(c,"PING"); test_cond(reply->type == REDIS_REPLY_STATUS && strcasecmp(reply->str,"pong") == 0) freeReplyObject(reply); /* Switch to DB 9 for testing, now that we know we can chat. */ reply = redisCommand(c,"SELECT 9"); freeReplyObject(reply); /* Make sure the DB is emtpy */ reply = redisCommand(c,"DBSIZE"); if (reply->type != REDIS_REPLY_INTEGER || reply->integer != 0) { printf("Database #9 is not empty, test can not continue\n"); exit(1); } freeReplyObject(reply); test("Is a able to send commands verbatim: "); reply = redisCommand(c,"SET foo bar"); test_cond (reply->type == REDIS_REPLY_STATUS && strcasecmp(reply->str,"ok") == 0) freeReplyObject(reply); test("%%s String interpolation works: "); reply = redisCommand(c,"SET %s %s","foo","hello world"); freeReplyObject(reply); reply = redisCommand(c,"GET foo"); test_cond(reply->type == REDIS_REPLY_STRING && strcmp(reply->str,"hello world") == 0); freeReplyObject(reply); test("%%b String interpolation works: "); reply = redisCommand(c,"SET %b %b","foo",3,"hello\x00world",11); freeReplyObject(reply); reply = redisCommand(c,"GET foo"); test_cond(reply->type == REDIS_REPLY_STRING && memcmp(reply->str,"hello\x00world",11) == 0) test("Binary reply length is correct: "); test_cond(reply->len == 11) freeReplyObject(reply); test("Can parse nil replies: "); reply = redisCommand(c,"GET nokey"); test_cond(reply->type == REDIS_REPLY_NIL) freeReplyObject(reply); /* test 7 */ test("Can parse integer replies: "); reply = redisCommand(c,"INCR mycounter"); test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1) freeReplyObject(reply); test("Can parse multi bulk replies: "); freeReplyObject(redisCommand(c,"LPUSH mylist foo")); freeReplyObject(redisCommand(c,"LPUSH mylist bar")); reply = redisCommand(c,"LRANGE mylist 0 -1"); test_cond(reply->type == REDIS_REPLY_ARRAY && reply->elements == 2 && !memcmp(reply->element[0]->str,"bar",3) && !memcmp(reply->element[1]->str,"foo",3)) freeReplyObject(reply); /* m/e with multi bulk reply *before* other reply. * specifically test ordering of reply items to parse. */ test("Can handle nested multi bulk replies: "); freeReplyObject(redisCommand(c,"MULTI")); freeReplyObject(redisCommand(c,"LRANGE mylist 0 -1")); freeReplyObject(redisCommand(c,"PING")); reply = (redisCommand(c,"EXEC")); test_cond(reply->type == REDIS_REPLY_ARRAY && reply->elements == 2 && reply->element[0]->type == REDIS_REPLY_ARRAY && reply->element[0]->elements == 2 && !memcmp(reply->element[0]->element[0]->str,"bar",3) && !memcmp(reply->element[0]->element[1]->str,"foo",3) && reply->element[1]->type == REDIS_REPLY_STATUS && strcasecmp(reply->element[1]->str,"pong") == 0); freeReplyObject(reply); { /* Find out Redis version to determine the path for the next test */ const char *field = "redis_version:"; char *p, *eptr; reply = redisCommand(c,"INFO"); p = strstr(reply->str,field); major = strtol(p+strlen(field),&eptr,10); p = eptr+1; /* char next to the first "." */ minor = strtol(p,&eptr,10); freeReplyObject(reply); } test("Returns I/O error when the connection is lost: "); reply = redisCommand(c,"QUIT"); if (major >= 2 && minor > 0) { /* > 2.0 returns OK on QUIT and read() should be issued once more * to know the descriptor is at EOF. */ test_cond(strcasecmp(reply->str,"OK") == 0 && redisGetReply(c,(void**)&reply) == REDIS_ERR); freeReplyObject(reply); } else { test_cond(reply == NULL); } /* On 2.0, QUIT will cause the connection to be closed immediately and * the read(2) for the reply on QUIT will set the error to EOF. * On >2.0, QUIT will return with OK and another read(2) needed to be * issued to find out the socket was closed by the server. In both * conditions, the error will be set to EOF. */ assert(c->err == REDIS_ERR_EOF && strcmp(c->errstr,"Server closed the connection") == 0); redisFree(c); __connect(&c); test("Returns I/O error on socket timeout: "); struct timeval tv = { 0, 1000 }; assert(redisSetTimeout(c,tv) == REDIS_OK); test_cond(redisGetReply(c,(void**)&reply) == REDIS_ERR && c->err == REDIS_ERR_IO && errno == EAGAIN); redisFree(c); /* Context should be connected */ __connect(&c); }
int main(void) { { sdshdr *sh; sds x = sdsnew("foo"), y; test_cond("Create a string and obtain the length", sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0) sdsfree(x); x = sdsnewlen("foo",2); test_cond("Create a string with specified length", sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0) x = sdscat(x,"bar"); test_cond("Strings concatenation", sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0); x = sdscpy(x,"a"); test_cond("sdscpy() against an originally longer string", sdslen(x) == 1 && memcmp(x,"a\0",2) == 0) x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk"); test_cond("sdscpy() against an originally shorter string", sdslen(x) == 33 && memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0) sdsfree(x); x = sdscatprintf(sdsempty(),"%d",123); test_cond("sdscatprintf() seems working in the base case", sdslen(x) == 3 && memcmp(x,"123\0",4) ==0) sdsfree(x); x = sdsnew("xxciaoyyy"); sdstrim(x,"xy"); test_cond("sdstrim() correctly trims characters", sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0) y = sdsdup(x); sdsrange(y,1,1); test_cond("sdsrange(...,1,1)", sdslen(y) == 1 && memcmp(y,"i\0",2) == 0) sdsfree(y); y = sdsdup(x); sdsrange(y,1,-1); test_cond("sdsrange(...,1,-1)", sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0) sdsfree(y); y = sdsdup(x); sdsrange(y,-2,-1); test_cond("sdsrange(...,-2,-1)", sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0) sdsfree(y); y = sdsdup(x); sdsrange(y,2,1); test_cond("sdsrange(...,2,1)", sdslen(y) == 0 && memcmp(y,"\0",1) == 0) sdsfree(y); y = sdsdup(x); sdsrange(y,1,100); test_cond("sdsrange(...,1,100)", sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0) sdsfree(y); y = sdsdup(x); sdsrange(y,100,100); test_cond("sdsrange(...,100,100)", sdslen(y) == 0 && memcmp(y,"\0",1) == 0) sdsfree(y); sdsfree(x); x = sdsnew("foo"); y = sdsnew("foa"); test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0) sdsfree(y); sdsfree(x); x = sdsnew("bar"); y = sdsnew("bar"); test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0) sdsfree(y); sdsfree(x); x = sdsnew("aar"); y = sdsnew("bar"); test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0) sdsfree(y); sdsfree(x); x = sdsnewlen("\a\n\0foo\r",7); y = sdscatrepr(sdsempty(),x,sdslen(x)); test_cond("sdscatrepr(...data...)", memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0) sdsfree(y); { size_t oldfree; sdsfree(x); x = sdsnew("0"); sh = sds_start(x); test_cond("sdsnew() free/len buffers", sh->len == 1 && sh->free == 0); x = sdsMakeRoomFor(x,1); sh = sds_start(x); test_cond("sdsMakeRoomFor()", sh->len == 1 && sh->free > 0); oldfree = sh->free; x[1] = '1'; sdsIncrLen(x,1); test_cond("sdsIncrLen() -- content", x[0] == '0' && x[1] == '1'); test_cond("sdsIncrLen() -- len", sh->len == 2); test_cond("sdsIncrLen() -- free", sh->free == oldfree-1); sdsfree(x); } x = sdsnew("0FoO1bar\n"); sdstolower(x); test_cond("sdstolower(...)", memcmp(x,"0foo1bar\n\0",10) == 0) sdsfree(x); x = sdsnew("0FoO1bar\n"); sdstoupper(x); test_cond("sdstoupper(...)", memcmp(x,"0FOO1BAR\n\0",10) == 0) sdsfree(x); } test_report() return 0; }
static void test_nonblocking_connection() { redisContext *c; int wdone = 0; test("Calls command callback when command is issued: "); c = __connect_nonblock(); redisSetCommandCallback(c,__test_callback,(void*)1); redisCommand(c,"PING"); test_cond(__test_callback_flags == 1); redisFree(c); test("Calls disconnect callback on redisDisconnect: "); c = __connect_nonblock(); redisSetDisconnectCallback(c,__test_callback,(void*)2); redisDisconnect(c); test_cond(__test_callback_flags == 2); redisFree(c); test("Calls disconnect callback and free callback on redisFree: "); c = __connect_nonblock(); redisSetDisconnectCallback(c,__test_callback,(void*)2); redisSetFreeCallback(c,__test_callback,(void*)4); redisFree(c); test_cond(__test_callback_flags == ((2 << 8) | 4)); test("redisBufferWrite against empty write buffer: "); c = __connect_nonblock(); test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1); redisFree(c); test("redisBufferWrite against not yet connected fd: "); c = __connect_nonblock(); redisCommand(c,"PING"); test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && strncmp(c->error,"write:",6) == 0); redisFree(c); test("redisBufferWrite against closed fd: "); c = __connect_nonblock(); redisCommand(c,"PING"); redisDisconnect(c); test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && strncmp(c->error,"write:",6) == 0); redisFree(c); test("Process callbacks in the right sequence: "); c = __connect_nonblock(); redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING"); redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING"); /* Write output buffer */ wdone = 0; while(!wdone) { usleep(500); redisBufferWrite(c,&wdone); } /* Read until at least one callback is executed (the 3 replies will * arrive in a single packet, causing all callbacks to be executed in * a single pass). */ while(__test_callback_flags == 0) { assert(redisBufferRead(c) == REDIS_OK); redisProcessCallbacks(c); } test_cond(__test_callback_flags == 0x010203); redisFree(c); test("redisDisconnect executes pending callbacks with NULL reply: "); c = __connect_nonblock(); redisSetDisconnectCallback(c,__test_callback,(void*)1); redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); redisDisconnect(c); test_cond(__test_callback_flags == 0x0201); redisFree(c); }
static void test_format_commands(void) { char *cmd; int len; test("Format command without interpolation: "); len = redisFormatCommand(&cmd,"SET foo bar"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); free(cmd); test("Format command with %%s string interpolation: "); len = redisFormatCommand(&cmd,"SET %s %s","foo","bar"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); free(cmd); test("Format command with %%s and an empty string: "); len = redisFormatCommand(&cmd,"SET %s %s","foo",""); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(0+2)); free(cmd); test("Format command with an empty string in between proper interpolations: "); len = redisFormatCommand(&cmd,"SET %s %s","","foo"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",len) == 0 && len == 4+4+(3+2)+4+(0+2)+4+(3+2)); free(cmd); test("Format command with %%b string interpolation: "); len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"b\0r",3); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); free(cmd); test("Format command with %%b and an empty string: "); len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"",0); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(0+2)); free(cmd); test("Format command with literal %%: "); len = redisFormatCommand(&cmd,"SET %% %%"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$1\r\n%\r\n$1\r\n%\r\n",len) == 0 && len == 4+4+(3+2)+4+(1+2)+4+(1+2)); free(cmd); test("Format command with printf-delegation (long long): "); len = redisFormatCommand(&cmd,"key:%08lld",1234ll); test_cond(strncmp(cmd,"*1\r\n$12\r\nkey:00001234\r\n",len) == 0 && len == 4+5+(12+2)); free(cmd); test("Format command with printf-delegation (float): "); len = redisFormatCommand(&cmd,"v:%06.1f",12.34f); test_cond(strncmp(cmd,"*1\r\n$8\r\nv:0012.3\r\n",len) == 0 && len == 4+4+(8+2)); free(cmd); test("Format command with printf-delegation and extra interpolation: "); len = redisFormatCommand(&cmd,"key:%d %b",1234,"foo",3); test_cond(strncmp(cmd,"*2\r\n$8\r\nkey:1234\r\n$3\r\nfoo\r\n",len) == 0 && len == 4+4+(8+2)+4+(3+2)); free(cmd); test("Format command with wrong printf format and extra interpolation: "); len = redisFormatCommand(&cmd,"key:%08p %b",1234,"foo",3); test_cond(strncmp(cmd,"*2\r\n$6\r\nkey:8p\r\n$3\r\nfoo\r\n",len) == 0 && len == 4+4+(6+2)+4+(3+2)); free(cmd); const char *argv[3]; argv[0] = "SET"; argv[1] = "foo\0xxx"; argv[2] = "bar"; size_t lens[3] = { 3, 7, 3 }; int argc = 3; test("Format command by passing argc/argv without lengths: "); len = redisFormatCommandArgv(&cmd,argc,argv,NULL); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); free(cmd); test("Format command by passing argc/argv with lengths: "); len = redisFormatCommandArgv(&cmd,argc,argv,lens); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(7+2)+4+(3+2)); free(cmd); }
static void test_blocking_connection(struct config config) { redisContext *c; redisReply *reply; c = connect(config); test("Is able to deliver commands: "); reply = redisCommand(c,"PING"); test_cond(reply->type == REDIS_REPLY_STATUS && strcasecmp(reply->str,"pong") == 0) freeReplyObject(reply); test("Is a able to send commands verbatim: "); reply = redisCommand(c,"SET foo bar"); test_cond (reply->type == REDIS_REPLY_STATUS && strcasecmp(reply->str,"ok") == 0) freeReplyObject(reply); test("%%s String interpolation works: "); reply = redisCommand(c,"SET %s %s","foo","hello world"); freeReplyObject(reply); reply = redisCommand(c,"GET foo"); test_cond(reply->type == REDIS_REPLY_STRING && strcmp(reply->str,"hello world") == 0); freeReplyObject(reply); test("%%b String interpolation works: "); reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11); freeReplyObject(reply); reply = redisCommand(c,"GET foo"); test_cond(reply->type == REDIS_REPLY_STRING && memcmp(reply->str,"hello\x00world",11) == 0) test("Binary reply length is correct: "); test_cond(reply->len == 11) freeReplyObject(reply); test("Can parse nil replies: "); reply = redisCommand(c,"GET nokey"); test_cond(reply->type == REDIS_REPLY_NIL) freeReplyObject(reply); /* test 7 */ test("Can parse integer replies: "); reply = redisCommand(c,"INCR mycounter"); test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1) freeReplyObject(reply); test("Can parse multi bulk replies: "); freeReplyObject(redisCommand(c,"LPUSH mylist foo")); freeReplyObject(redisCommand(c,"LPUSH mylist bar")); reply = redisCommand(c,"LRANGE mylist 0 -1"); test_cond(reply->type == REDIS_REPLY_ARRAY && reply->elements == 2 && !memcmp(reply->element[0]->str,"bar",3) && !memcmp(reply->element[1]->str,"foo",3)) freeReplyObject(reply); /* m/e with multi bulk reply *before* other reply. * specifically test ordering of reply items to parse. */ test("Can handle nested multi bulk replies: "); freeReplyObject(redisCommand(c,"MULTI")); freeReplyObject(redisCommand(c,"LRANGE mylist 0 -1")); freeReplyObject(redisCommand(c,"PING")); reply = (redisCommand(c,"EXEC")); test_cond(reply->type == REDIS_REPLY_ARRAY && reply->elements == 2 && reply->element[0]->type == REDIS_REPLY_ARRAY && reply->element[0]->elements == 2 && !memcmp(reply->element[0]->element[0]->str,"bar",3) && !memcmp(reply->element[0]->element[1]->str,"foo",3) && reply->element[1]->type == REDIS_REPLY_STATUS && strcasecmp(reply->element[1]->str,"pong") == 0); freeReplyObject(reply); disconnect(c, 0); }
static void test_reply_reader(void) { redisReader *reader; void *reply; int ret; int i; test("Error handling in reply parser: "); reader = redisReaderCreate(); redisReaderFeed(reader,(char*)"@foo\r\n",6); ret = redisReaderGetReply(reader,NULL); test_cond(ret == REDIS_ERR && strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0); redisReaderFree(reader); /* when the reply already contains multiple items, they must be free'd * on an error. valgrind will bark when this doesn't happen. */ test("Memory cleanup in reply parser: "); reader = redisReaderCreate(); redisReaderFeed(reader,(char*)"*2\r\n",4); redisReaderFeed(reader,(char*)"$5\r\nhello\r\n",11); redisReaderFeed(reader,(char*)"@foo\r\n",6); ret = redisReaderGetReply(reader,NULL); test_cond(ret == REDIS_ERR && strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0); redisReaderFree(reader); test("Set error on nested multi bulks with depth > 7: "); reader = redisReaderCreate(); for (i = 0; i < 9; i++) { redisReaderFeed(reader,(char*)"*1\r\n",4); } ret = redisReaderGetReply(reader,NULL); test_cond(ret == REDIS_ERR && strncasecmp(reader->errstr,"No support for",14) == 0); redisReaderFree(reader); test("Works with NULL functions for reply: "); reader = redisReaderCreate(); reader->fn = NULL; redisReaderFeed(reader,(char*)"+OK\r\n",5); ret = redisReaderGetReply(reader,&reply); test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); redisReaderFree(reader); test("Works when a single newline (\\r\\n) covers two calls to feed: "); reader = redisReaderCreate(); reader->fn = NULL; redisReaderFeed(reader,(char*)"+OK\r",4); ret = redisReaderGetReply(reader,&reply); assert(ret == REDIS_OK && reply == NULL); redisReaderFeed(reader,(char*)"\n",1); ret = redisReaderGetReply(reader,&reply); test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); redisReaderFree(reader); test("Don't reset state after protocol error: "); reader = redisReaderCreate(); reader->fn = NULL; redisReaderFeed(reader,(char*)"x",1); ret = redisReaderGetReply(reader,&reply); assert(ret == REDIS_ERR); ret = redisReaderGetReply(reader,&reply); test_cond(ret == REDIS_ERR && reply == NULL); redisReaderFree(reader); /* Regression test for issue #45 on GitHub. */ test("Don't do empty allocation for empty multi bulk: "); reader = redisReaderCreate(); redisReaderFeed(reader,(char*)"*0\r\n",4); ret = redisReaderGetReply(reader,&reply); test_cond(ret == REDIS_OK && ((redisReply*)reply)->type == REDIS_REPLY_ARRAY && ((redisReply*)reply)->elements == 0); freeReplyObject(reply); redisReaderFree(reader); }
static void test_format_commands(void) { char *cmd; int len; test("Format command without interpolation: "); len = redisFormatCommand(&cmd,"SET foo bar"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); free(cmd); test("Format command with %%s string interpolation: "); len = redisFormatCommand(&cmd,"SET %s %s","foo","bar"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); free(cmd); test("Format command with %%s and an empty string: "); len = redisFormatCommand(&cmd,"SET %s %s","foo",""); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(0+2)); free(cmd); test("Format command with an empty string in between proper interpolations: "); len = redisFormatCommand(&cmd,"SET %s %s","","foo"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",len) == 0 && len == 4+4+(3+2)+4+(0+2)+4+(3+2)); free(cmd); test("Format command with %%b string interpolation: "); len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); free(cmd); test("Format command with %%b and an empty string: "); len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(0+2)); free(cmd); test("Format command with literal %%: "); len = redisFormatCommand(&cmd,"SET %% %%"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$1\r\n%\r\n$1\r\n%\r\n",len) == 0 && len == 4+4+(3+2)+4+(1+2)+4+(1+2)); free(cmd); /* Vararg width depends on the type. These tests make sure that the * width is correctly determined using the format and subsequent varargs * can correctly be interpolated. */ #define INTEGER_WIDTH_TEST(fmt, type) do { \ type value = 123; \ test("Format command with printf-delegation (" #type "): "); \ len = redisFormatCommand(&cmd,"key:%08" fmt " str:%s", value, "hello"); \ test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:00000123\r\n$9\r\nstr:hello\r\n",len) == 0 && \ len == 4+5+(12+2)+4+(9+2)); \ free(cmd); \ } while(0) #define FLOAT_WIDTH_TEST(type) do { \ type value = 123.0; \ test("Format command with printf-delegation (" #type "): "); \ len = redisFormatCommand(&cmd,"key:%08.3f str:%s", value, "hello"); \ test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:0123.000\r\n$9\r\nstr:hello\r\n",len) == 0 && \ len == 4+5+(12+2)+4+(9+2)); \ free(cmd); \ } while(0) INTEGER_WIDTH_TEST("d", int); INTEGER_WIDTH_TEST("hhd", char); INTEGER_WIDTH_TEST("hd", short); INTEGER_WIDTH_TEST("ld", long); INTEGER_WIDTH_TEST("lld", long long); INTEGER_WIDTH_TEST("u", unsigned int); INTEGER_WIDTH_TEST("hhu", unsigned char); INTEGER_WIDTH_TEST("hu", unsigned short); INTEGER_WIDTH_TEST("lu", unsigned long); INTEGER_WIDTH_TEST("llu", unsigned long long); FLOAT_WIDTH_TEST(float); FLOAT_WIDTH_TEST(double); test("Format command with invalid printf format: "); len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3); test_cond(len == -1); const char *argv[3]; argv[0] = "SET"; argv[1] = "foo\0xxx"; argv[2] = "bar"; size_t lens[3] = { 3, 7, 3 }; int argc = 3; test("Format command by passing argc/argv without lengths: "); len = redisFormatCommandArgv(&cmd,argc,argv,NULL); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); free(cmd); test("Format command by passing argc/argv with lengths: "); len = redisFormatCommandArgv(&cmd,argc,argv,lens); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(7+2)+4+(3+2)); free(cmd); }
static int __init testredis_init(void) { int fd; int fails = 0; redisReply *reply; printk(KERN_INFO "testredis_init() called\n"); reply = redisConnect(&fd, SERVER_IP, SERVER_PORT); if (reply != NULL) { printk(KERN_INFO "Connection error: %s", reply->reply); return 1; } /* test 1 */ printk(KERN_INFO "\n#1 Is able to deliver commands: "); reply = redisCommand(fd, "PING"); test_cond(reply->type == REDIS_REPLY_STRING && strcasecmp(reply->reply, "pong") == 0) /* Switch to DB 9 for testing, now that we know we can chat. */ reply = redisCommand(fd, "SELECT 9"); freeReplyObject(reply); /* Make sure the DB is emtpy */ reply = redisCommand(fd, "DBSIZE"); if (reply->type != REDIS_REPLY_INTEGER || reply->integer != 0) { printk(KERN_INFO "Sorry DB 9 is not empty, test can not continue\n"); return 1; } else { printk(KERN_INFO "DB 9 is empty... test can continue\n"); } freeReplyObject(reply); /* test 2 */ printk(KERN_INFO "#2 Is a able to send commands verbatim: "); reply = redisCommand(fd, "SET foo bar"); test_cond(reply->type == REDIS_REPLY_STRING && strcasecmp(reply->reply, "ok") == 0) freeReplyObject(reply); /* test 3 */ printk(KERN_INFO "#3 %%s String interpolation works: "); reply = redisCommand(fd, "SET %s %s", "foo", "hello world"); freeReplyObject(reply); reply = redisCommand(fd, "GET foo"); test_cond(reply->type == REDIS_REPLY_STRING && strcmp(reply->reply, "hello world") == 0); freeReplyObject(reply); /* test 4 & 5 */ printk(KERN_INFO "#4 %%b String interpolation works: "); reply = redisCommand(fd, "SET %b %b", "foo", 3, "hello\x00world", 11); freeReplyObject(reply); reply = redisCommand(fd, "GET foo"); test_cond(reply->type == REDIS_REPLY_STRING && memcmp(reply->reply, "hello\x00world", 11) == 0) printk(KERN_INFO "#5 binary reply length is correct: "); test_cond(sdslen(reply->reply) == 11) freeReplyObject(reply); /* test 6 */ printk(KERN_INFO "#6 can parse nil replies: "); reply = redisCommand(fd,"GET nokey"); printk(KERN_INFO "Received %c %d\n", reply->type, reply->type); test_cond(reply->type == REDIS_REPLY_NIL) freeReplyObject(reply); /* test 7 */ printk(KERN_INFO "#7 can parse integer replies: "); reply = redisCommand(fd, "INCR mycounter"); test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1) freeReplyObject(reply); /* test 8 */ printk(KERN_INFO "#8 can parse multi bulk replies: "); freeReplyObject(redisCommand(fd, "LPUSH mylist foo")); freeReplyObject(redisCommand(fd, "LPUSH mylist bar")); reply = redisCommand(fd, "LRANGE mylist 0 -1"); test_cond(reply->type == REDIS_REPLY_ARRAY && reply->elements == 2 && !memcmp(reply->element[0]->reply, "bar", 3) && !memcmp(reply->element[1]->reply, "foo", 3)) freeReplyObject(reply); /* Clean DB 9 */ reply = redisCommand(fd, "FLUSHDB"); freeReplyObject(reply); if (fails == 0) { printk(KERN_INFO "ALL TESTS PASSED\n"); } else { printk(KERN_INFO "*** %d TESTS FAILED ***\n", fails); } return 0; }