static void test_resp3_push_handler(redisContext *c) {
    redisPushFn *old = NULL;
    redisReply *reply;
    void *privdata;
    int n = 0;

    /* Switch to RESP3 and turn on client tracking */
    send_hello(c, 3);
    send_client_tracking(c, "ON");
    privdata = c->privdata;
    c->privdata = &n;

    reply = redisCommand(c, "GET key:0");
    assert(reply != NULL);
    freeReplyObject(reply);

    test("RESP3 PUSH messages are handled out of band by default: ");
    reply = redisCommand(c, "SET key:0 val:0");
    test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS);
    freeReplyObject(reply);

    assert((reply = redisCommand(c, "GET key:0")) != NULL);
    freeReplyObject(reply);

    old = redisSetPushCallback(c, push_handler);
    test("We can set a custom RESP3 PUSH handler: ");
    reply = redisCommand(c, "SET key:0 val:0");
    test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && n == 1);
    freeReplyObject(reply);

    /* Unset the push callback and generate an invalidate message making
     * sure it is not handled out of band. */
    test("With no handler, PUSH replies come in-band: ");
    redisSetPushCallback(c, NULL);
    assert((reply = redisCommand(c, "GET key:0")) != NULL);
    freeReplyObject(reply);
    assert((reply = redisCommand(c, "SET key:0 invalid")) != NULL);
    test_cond(reply->type == REDIS_REPLY_PUSH);
    freeReplyObject(reply);

    test("With no PUSH handler, no replies are lost: ");
    assert(redisGetReply(c, (void**)&reply) == REDIS_OK);
    test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS);
    freeReplyObject(reply);

    /* Return to the originally set PUSH handler */
    assert(old != NULL);
    redisSetPushCallback(c, old);

    /* Switch back to RESP2 and disable tracking */
    c->privdata = privdata;
    send_client_tracking(c, "OFF");
    send_hello(c, 2);
}
static void test_resp3_push_handler(redisContext *c) {
    redisPushFn *old = NULL;
    redisReply *reply;
    void *privdata;
    int n = 0;

     
    send_hello(c, 3);
    send_client_tracking(c, "ON");
    privdata = c->privdata;
    c->privdata = &n;

    reply = redisCommand(c, "GET key:0");
    assert(reply != NULL);
    freeReplyObject(reply);

    test("RESP3 PUSH messages are handled out of band by default: ");
    reply = redisCommand(c, "SET key:0 val:0");
    test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS);
    freeReplyObject(reply);

    assert((reply = redisCommand(c, "GET key:0")) != NULL);
    freeReplyObject(reply);

    old = redisSetPushCallback(c, push_handler);
    test("We can set a custom RESP3 PUSH handler: ");
    reply = redisCommand(c, "SET key:0 val:0");
    test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && n == 1);
    freeReplyObject(reply);

     
    test("With no handler, PUSH replies come in-band: ");
    redisSetPushCallback(c, NULL);
    assert((reply = redisCommand(c, "GET key:0")) != NULL);
    freeReplyObject(reply);
    assert((reply = redisCommand(c, "SET key:0 invalid")) != NULL);
    test_cond(reply->type == REDIS_REPLY_PUSH);
    freeReplyObject(reply);

    test("With no PUSH handler, no replies are lost: ");
    assert(redisGetReply(c, (void**)&reply) == REDIS_OK);
    test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS);
    freeReplyObject(reply);

     
    assert(old != NULL);
    redisSetPushCallback(c, old);

     
    c->privdata = privdata;
    send_client_tracking(c, "OFF");
    send_hello(c, 2);
}