Redis-Cluster-Fast

 view release on metacpan or  search on metacpan

deps/hiredis-cluster/tests/ct_connection.c  view on Meta::CPAN

    redisClusterContext *cc2 = redisClusterContextInit();
    assert(cc2);
    redisClusterSetOptionAddNodes(cc2, CLUSTER_NODE_WITH_PASSWORD);
    redisClusterSetOptionPassword(cc2, CLUSTER_PASSWORD);
    ret = redisClusterConnect2(cc2);
    ASSERT_MSG(ret == REDIS_OK, cc2->errstr);

    // Set keys differently in clusters
    reply = redisClusterCommand(cc1, "SET key Hello1");
    CHECK_REPLY_OK(cc1, reply);
    freeReplyObject(reply);

    reply = redisClusterCommand(cc2, "SET key Hello2");
    CHECK_REPLY_OK(cc2, reply);
    freeReplyObject(reply);

    // Verify keys in clusters
    reply = redisClusterCommand(cc1, "GET key");
    CHECK_REPLY_STR(cc1, reply, "Hello1");
    freeReplyObject(reply);

    reply = redisClusterCommand(cc2, "GET key");
    CHECK_REPLY_STR(cc2, reply, "Hello2");
    freeReplyObject(reply);

    // Disconnect from first cluster
    redisClusterFree(cc1);

    // Verify that key is still accessible in connected cluster
    reply = redisClusterCommand(cc2, "GET key");
    CHECK_REPLY_STR(cc2, reply, "Hello2");
    freeReplyObject(reply);

    redisClusterFree(cc2);
}

/* Connect to a non-routable address which results in a connection timeout. */
void test_connect_timeout(void) {
    struct timeval timeout = {0, 200000};

    redisClusterContext *cc = redisClusterContextInit();
    assert(cc);

    /* Configure a non-routable IP address and a timeout */
    redisClusterSetOptionAddNodes(cc, "192.168.0.0:7000");
    redisClusterSetOptionConnectTimeout(cc, timeout);
    redisClusterSetConnectCallback(cc, connect_callback);

    int status = redisClusterConnect2(cc);
    assert(status == REDIS_ERR);
    assert(cc->err == REDIS_ERR_IO);
    assert(strcmp(cc->errstr, "Connection timed out") == 0);
    assert(connect_success_counter == 0);
    assert(connect_failure_counter == 1);
    reset_counters();

    redisClusterFree(cc);
}

/* Connect using a pre-configured command timeout */
void test_command_timeout(void) {
    struct timeval timeout = {0, 10000};

    redisClusterContext *cc = redisClusterContextInit();
    assert(cc);
    redisClusterSetOptionAddNodes(cc, CLUSTER_NODE);
    redisClusterSetOptionTimeout(cc, timeout);

    int status = redisClusterConnect2(cc);
    ASSERT_MSG(status == REDIS_OK, cc->errstr);

    redisClusterNodeIterator ni;
    redisClusterInitNodeIterator(&ni, cc);
    redisClusterNode *node = redisClusterNodeNext(&ni);
    assert(node);

    /* Simulate a command timeout */
    redisReply *reply;
    reply = redisClusterCommandToNode(cc, node, "DEBUG SLEEP 0.2");
    assert(reply == NULL);
    assert(cc->err == REDIS_ERR_IO);

    /* Make sure debug sleep is done before leaving testcase */
    for (int i = 0; i < 20; ++i) {
        reply = redisClusterCommandToNode(cc, node, "SET key1 Hello");
        if (reply && reply->type == REDIS_REPLY_STATUS)
            break;
    }
    CHECK_REPLY_OK(cc, reply);
    freeReplyObject(reply);

    redisClusterFree(cc);
}

/* Connect and configure a command timeout while connected. */
void test_command_timeout_set_while_connected(void) {
    struct timeval timeout = {0, 10000};

    redisClusterContext *cc = redisClusterContextInit();
    assert(cc);
    redisClusterSetOptionAddNodes(cc, CLUSTER_NODE);

    int status = redisClusterConnect2(cc);
    ASSERT_MSG(status == REDIS_OK, cc->errstr);

    redisClusterNodeIterator ni;
    redisClusterInitNodeIterator(&ni, cc);
    redisClusterNode *node = redisClusterNodeNext(&ni);
    assert(node);

    redisReply *reply;
    reply = redisClusterCommandToNode(cc, node, "DEBUG SLEEP 0.2");
    CHECK_REPLY_OK(cc, reply);
    freeReplyObject(reply);

    /* Set command timeout while connected */
    redisClusterSetOptionTimeout(cc, timeout);

    reply = redisClusterCommandToNode(cc, node, "DEBUG SLEEP 0.2");
    assert(reply == NULL);
    assert(cc->err == REDIS_ERR_IO);

    /* Make sure debug sleep is done before leaving testcase */
    for (int i = 0; i < 20; ++i) {
        reply = redisClusterCommandToNode(cc, node, "SET key1 Hello");
        if (reply && reply->type == REDIS_REPLY_STATUS)
            break;
    }
    CHECK_REPLY_OK(cc, reply);
    freeReplyObject(reply);

    redisClusterFree(cc);
}

//------------------------------------------------------------------------------
// Async API
//------------------------------------------------------------------------------
typedef struct ExpectedResult {
    int type;
    char *str;
    bool disconnect;
    bool noreply;
    char *errstr;
} ExpectedResult;

// Callback for Redis connects and disconnects
void callbackExpectOk(const redisAsyncContext *ac, int status) {
    UNUSED(ac);
    assert(status == REDIS_OK);
}

// Callback for async commands, verifies the redisReply
void commandCallback(redisClusterAsyncContext *cc, void *r, void *privdata) {
    redisReply *reply = (redisReply *)r;
    ExpectedResult *expect = (ExpectedResult *)privdata;
    if (expect->noreply) {

deps/hiredis-cluster/tests/ct_connection.c  view on Meta::CPAN


    // Set keys differently in clusters
    ExpectedResult r1 = {.type = REDIS_REPLY_STATUS, .str = "OK"};
    ret = redisClusterAsyncCommand(acc1, commandCallback, &r1, "SET key A");
    assert(ret == REDIS_OK);

    ExpectedResult r2 = {.type = REDIS_REPLY_STATUS, .str = "OK"};
    ret = redisClusterAsyncCommand(acc2, commandCallback, &r2, "SET key B");
    assert(ret == REDIS_OK);

    // Verify key in first cluster
    ExpectedResult r3 = {.type = REDIS_REPLY_STRING, .str = "A"};
    ret = redisClusterAsyncCommand(acc1, commandCallback, &r3, "GET key");
    assert(ret == REDIS_OK);

    // Verify key in second cluster and disconnect
    ExpectedResult r4 = {
        .type = REDIS_REPLY_STRING, .str = "B", .disconnect = true};
    ret = redisClusterAsyncCommand(acc2, commandCallback, &r4, "GET key");
    assert(ret == REDIS_OK);

    // Verify that key is still accessible in connected cluster
    ExpectedResult r5 = {
        .type = REDIS_REPLY_STRING, .str = "A", .disconnect = true};
    ret = redisClusterAsyncCommand(acc1, commandCallback, &r5, "GET key");
    assert(ret == REDIS_OK);

    event_base_dispatch(base);

    redisClusterAsyncFree(acc1);
    redisClusterAsyncFree(acc2);
    event_base_free(base);
}

/* Connect to a non-routable address which results in a connection timeout. */
void test_async_connect_timeout(void) {
    struct timeval timeout = {0, 200000};

    redisClusterAsyncContext *acc = redisClusterAsyncContextInit();
    assert(acc);

    /* Configure a non-routable IP address and a timeout */
    redisClusterSetOptionAddNodes(acc->cc, "192.168.0.0:7000");
    redisClusterSetOptionConnectTimeout(acc->cc, timeout);

    struct event_base *base = event_base_new();
    redisClusterLibeventAttach(acc, base);

    int status = redisClusterConnect2(acc->cc);
    assert(status == REDIS_ERR);
    assert(acc->cc->err == REDIS_ERR_IO);
    assert(strcmp(acc->cc->errstr, "Connection timed out") == 0);

    event_base_dispatch(base);

    redisClusterAsyncFree(acc);
    event_base_free(base);
}

/* Connect using a pre-configured command timeout */
void test_async_command_timeout(void) {
    struct timeval timeout = {0, 10000};

    redisClusterAsyncContext *acc = redisClusterAsyncContextInit();
    assert(acc);
    redisClusterSetOptionAddNodes(acc->cc, CLUSTER_NODE);
    redisClusterSetOptionTimeout(acc->cc, timeout);

    struct event_base *base = event_base_new();
    redisClusterLibeventAttach(acc, base);

    int status = redisClusterConnect2(acc->cc);
    assert(status == REDIS_OK);
    assert(acc->cc->err == 0);

    redisClusterNodeIterator ni;
    redisClusterInitNodeIterator(&ni, acc->cc);
    redisClusterNode *node = redisClusterNodeNext(&ni);
    assert(node);

    /* Simulate a command timeout and expect a timeout error */
    ExpectedResult r = {
        .noreply = true, .errstr = "Timeout", .disconnect = true};
    status = redisClusterAsyncCommandToNode(acc, node, commandCallback, &r,
                                            "DEBUG SLEEP 0.2");
    assert(status == REDIS_OK);

    event_base_dispatch(base);

    redisClusterAsyncFree(acc);
    event_base_free(base);
}

int main(void) {

    test_password_ok();
    test_password_wrong();
    test_password_missing();
    test_username_ok();
    test_username_disabled();
    test_multicluster();
    test_connect_timeout();
    test_command_timeout();
    test_command_timeout_set_while_connected();

    test_async_password_ok();
    test_async_password_wrong();
    test_async_password_missing();
    test_async_username_ok();
    test_async_multicluster();
    test_async_connect_timeout();
    test_async_command_timeout();

    return 0;
}



( run in 1.674 second using v1.01-cache-2.11-cpan-39bf76dae61 )