Beispiel #1
0
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);
}
Beispiel #2
0
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 }
        }
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
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;
}
Beispiel #6
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);
}
Beispiel #7
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;
}
Beispiel #8
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);
}
Beispiel #9
0
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);
}
Beispiel #10
0
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);
}
Beispiel #11
0
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);
}
Beispiel #12
0
//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;
}
Beispiel #13
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;
}
Beispiel #14
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);
}
Beispiel #15
0
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);
}
Beispiel #16
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;
}
Beispiel #17
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;
}
Beispiel #18
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)
}
Beispiel #19
0
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()
}
Beispiel #20
0
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);
}
Beispiel #21
0
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;
}
Beispiel #22
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);
 }
Beispiel #23
0
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);
}
Beispiel #24
0
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);
}
Beispiel #25
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);
}
Beispiel #26
0
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);
}
Beispiel #27
0
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;
}