char *hostname = memc->hosts[server_idx].hostname;
in_port_t port = memc->hosts[server_idx].port;
fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, host_index);
}
fclose(fp);
#endif
{
memcached_return_t rc= MEMCACHED_FAILURE;
memcached_st *memc_clone;
- memcached_server_instance_st instance;
memc_clone= memcached_clone(NULL, memc);
test_true(memc_clone);
// will not toggle protocol on an connection.
memcached_version(memc_clone);
- instance= memcached_server_instance_by_position(memc_clone, 0);
-
- if (instance->major_version >= 1 && instance->minor_version > 2)
+ if (libmemcached_util_version_check(memc_clone, 1, 2, 0))
{
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
{
memcached_return_t rc= MEMCACHED_FAILURE;
memcached_st *memc_clone;
- memcached_server_instance_st instance;
memc_clone= memcached_clone(NULL, memc);
test_true(memc_clone);
// will not toggle protocol on an connection.
memcached_version(memc_clone);
- instance= memcached_server_instance_by_position(memc_clone, 0);
-
- if (instance->major_version >= 1 && instance->minor_version > 2)
+ if (libmemcached_util_version_check(memc_clone, 1, 2, 0))
{
rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
test_true(rc == MEMCACHED_SUCCESS);
{
unsigned int set= 1;
- memcached_server_instance_st instance=
- memcached_server_instance_by_position(memc, 0);
-
- memcached_version(memc);
-
- if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
- || instance->minor_version > 2)
+ if (libmemcached_util_version_check(memc, 1, 2, 4))
{
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
|| instance->minor_version > 2)
+ {
return TEST_SUCCESS;
+ }
return TEST_SKIPPED;
}
test_true(memcached_pool_destroy(pool) == memc);
return TEST_SUCCESS;
}
+
+static test_return_t util_version_test(memcached_st *memc)
+{
+ bool if_successful;
+
+ if_successful= libmemcached_util_version_check(memc, 0, 0, 0);
+ test_true(if_successful == true);
+
+ if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
+ test_true(if_successful == false);
+
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, 0);
+
+ memcached_version(memc);
+
+ // We only use one binary when we test, so this should be just fine.
+ if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version, instance->minor_version);
+ test_true(if_successful == true);
+
+ if (instance->minor_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version, instance->minor_version -1);
+ else if (instance->micro_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version - 1, instance->minor_version);
+ else if (instance->major_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version -1, instance->micro_version, instance->minor_version);
+
+ test_true(if_successful == true);
+
+ if (instance->minor_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version, instance->minor_version +1);
+ else if (instance->micro_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version +1, instance->minor_version);
+ else if (instance->major_version > 0)
+ if_successful= libmemcached_util_version_check(memc, instance->major_version +1, instance->micro_version, instance->minor_version);
+
+ test_true(if_successful == false);
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t ping_test(memcached_st *memc)
+{
+ memcached_return_t rc;
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, 0);
+
+ // Test both the version that returns a code, and the one that does not.
+ test_true(libmemcached_util_ping(memcached_server_name(instance),
+ memcached_server_port(instance), NULL));
+
+ test_true(libmemcached_util_ping(memcached_server_name(instance),
+ memcached_server_port(instance), &rc));
+
+ test_true(rc == MEMCACHED_SUCCESS);
+
+ return TEST_SUCCESS;
+}
#endif
static test_return_t replication_set_test(memcached_st *memc)
return TEST_SUCCESS;
}
+/*
+ Test case adapted from John Gorman <johngorman2@gmail.com>
+
+ We are testing the error condition when we connect to a server via memcached_get()
+ but find that the server is not available.
+*/
+static test_return_t memcached_get_MEMCACHED_SOME_ERRORS(memcached_st *memc)
+{
+ (void)memc;
+ memcached_st *tl_memc_h;
+ memcached_server_st *servers;
+
+ const char *key= "MemcachedLives";
+ size_t len;
+ uint32_t flags;
+ memcached_return rc;
+ char *value;
+
+ // Create a handle.
+ tl_memc_h= memcached_create(NULL);
+ servers= memcached_servers_parse("localhost:9898"); // This server should not exist
+ memcached_server_push(tl_memc_h, servers);
+ memcached_server_list_free(servers);
+
+ // See if memcached is reachable.
+ value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc);
+
+ if (value)
+ {
+ free(value);
+ test_true(value); // Pointer won't be zero so this is fine.
+ }
+
+ test_true(len == 0);
+ test_true(rc == MEMCACHED_SOME_ERRORS);
+
+ return TEST_SUCCESS;
+}
+
+/*
+ We connect to a server which exists, but search for a key that does not exist.
+*/
+static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
+{
+ const char *key= "MemcachedKeyNotEXIST";
+ size_t len;
+ uint32_t flags;
+ memcached_return rc;
+ char *value;
+
+ // See if memcached is reachable.
+ value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
+
+ if (value)
+ {
+ free(value);
+ test_true(value); // Pointer won't be zero so this is fine.
+ }
+
+ test_true(len == 0);
+ test_true(rc == MEMCACHED_NOTFOUND);
+
+ return TEST_SUCCESS;
+}
+
+/*
+ Test case adapted from John Gorman <johngorman2@gmail.com>
+
+ We are testing the error condition when we connect to a server via memcached_get_by_key()
+ but find that the server is not available.
+*/
+static test_return_t memcached_get_by_key_MEMCACHED_SOME_ERRORS(memcached_st *memc)
+{
+ (void)memc;
+ memcached_st *tl_memc_h;
+ memcached_server_st *servers;
+
+ const char *key= "MemcachedLives";
+ size_t len;
+ uint32_t flags;
+ memcached_return rc;
+ char *value;
+
+ // Create a handle.
+ tl_memc_h= memcached_create(NULL);
+ servers= memcached_servers_parse("localhost:9898"); // This server should not exist
+ memcached_server_push(tl_memc_h, servers);
+ memcached_server_list_free(servers);
+
+ // See if memcached is reachable.
+ value= memcached_get_by_key(tl_memc_h, key, strlen(key), key, strlen(key), &len, &flags, &rc);
+
+ if (value)
+ {
+ free(value);
+ test_true(value); // Pointer won't be zero so this is fine.
+ }
+
+ test_true(len == 0);
+ test_true(rc == MEMCACHED_SOME_ERRORS);
+
+ return TEST_SUCCESS;
+}
+
+/*
+ We connect to a server which exists, but search for a key that does not exist.
+*/
+static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
+{
+ const char *key= "MemcachedKeyNotEXIST";
+ size_t len;
+ uint32_t flags;
+ memcached_return rc;
+ char *value;
+
+ // See if memcached is reachable.
+ value= memcached_get_by_key(memc, key, strlen(key), key, strlen(key), &len, &flags, &rc);
+
+ if (value)
+ {
+ free(value);
+ test_true(value); // Pointer won't be zero so this is fine.
+ }
+
+ test_true(len == 0);
+ test_true(rc == MEMCACHED_NOTFOUND);
+
+ return TEST_SUCCESS;
+}
+
static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
{
test_true(memc_clone != NULL);
test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
- memcached_server_instance_st instance=
- memcached_server_instance_by_position(memc_clone, 0);
- if (instance->major_version > 1 ||
- (instance->major_version == 1 &&
- instance->minor_version > 2))
+ if (libmemcached_util_version_check(memc_clone, 1, 1, 2))
{
/* Binary protocol doesn't support deferred delete */
memcached_st *bin_clone= memcached_clone(NULL, memc);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
+#ifdef __APPLE__
+ return TEST_SKIPPED; // My MAC can't handle this test
+#endif
+
/*
* I only want to hit _one_ server so I know the number of requests I'm
* sending in the pipeline.
size_t *key_length=calloc(max_keys, sizeof(size_t));
/* First add all of the items.. */
+ bool slept= false;
char blob[1024]= { 0 };
memcached_return rc;
for (size_t x= 0; x < max_keys; ++x)
keys[x]= strdup(k);
assert(keys[x] != NULL);
rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
- assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+#ifdef __APPLE__
+ if (rc == MEMCACHED_SERVER_MARKED_DEAD)
+ {
+ break; // We are out of business
+ }
+#endif
+ test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT); // MEMCACHED_TIMEOUT <-- only observed on OSX
+
+ if (rc == MEMCACHED_TIMEOUT && slept == false)
+ {
+ x++;
+ sleep(1);// We will try to sleep
+ slept= true;
+ }
+ else if (rc == MEMCACHED_TIMEOUT && slept == true)
+ {
+ // We failed to send everything.
+ break;
+ }
}
- /* Try to get all of them with a large multiget */
- size_t counter= 0;
- memcached_execute_function callbacks[1]= { [0]= &callback_counter };
- rc= memcached_mget_execute(memc, (const char**)keys, key_length,
- (size_t)max_keys, callbacks, &counter, 1);
+ if (rc != MEMCACHED_SERVER_MARKED_DEAD)
+ {
- assert(rc == MEMCACHED_SUCCESS);
- char* the_value= NULL;
- char the_key[MEMCACHED_MAX_KEY];
- size_t the_key_length;
- size_t the_value_length;
- uint32_t the_flags;
+ /* Try to get all of them with a large multiget */
+ size_t counter= 0;
+ memcached_execute_function callbacks[1]= { [0]= &callback_counter };
+ rc= memcached_mget_execute(memc, (const char**)keys, key_length,
+ (size_t)max_keys, callbacks, &counter, 1);
- do {
- the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
+ assert(rc == MEMCACHED_SUCCESS);
+ char* the_value= NULL;
+ char the_key[MEMCACHED_MAX_KEY];
+ size_t the_key_length;
+ size_t the_value_length;
+ uint32_t the_flags;
- if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
- {
- ++counter;
- free(the_value);
- }
+ do {
+ the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
+
+ if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
+ {
+ ++counter;
+ free(the_value);
+ }
- } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
+ } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
- assert(rc == MEMCACHED_END);
+ assert(rc == MEMCACHED_END);
- /* Verify that we got all of the items */
- assert(counter == max_keys);
+ /* Verify that we got all of the items */
+ assert(counter == max_keys);
+ }
/* Release all allocated resources */
for (size_t x= 0; x < max_keys; ++x)
return TEST_SUCCESS;
}
+static test_return_t regression_bug_583031(memcached_st *unused)
+{
+ (void)unused;
+
+ memcached_st *memc= memcached_create(NULL);
+ assert(memc);
+ memcached_server_add(memc, "10.2.3.4", 11211);
+
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
+
+ memcached_return_t rc;
+ size_t length;
+ uint32_t flags;
+
+ (void)memcached_get(memc, "dsf", 3, &length, &flags, &rc);
+
+ test_true(rc == MEMCACHED_TIMEOUT);
+
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
+
static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
{
fprintf(stderr, "Iteration #%u: ", it);
}
}
- return MEMCACHED_SUCCESS;
+ return TEST_SUCCESS;
}
/*
{"analyzer", 1, (test_callback_fn)analyzer_test},
#ifdef HAVE_LIBMEMCACHEDUTIL
{"connectionpool", 1, (test_callback_fn)connection_pool_test },
+ {"ping", 1, (test_callback_fn)ping_test },
+ {"util_version", 1, (test_callback_fn)util_version_test },
#endif
{"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
{"verbosity", 1, (test_callback_fn)test_verbosity},
{"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
{"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
{"lp:490486", 1, (test_callback_fn)regression_bug_490486 },
+ {"lp:583031", 1, (test_callback_fn)regression_bug_583031 },
{"lp:?", 1, (test_callback_fn)regression_bug_ },
{0, 0, (test_callback_fn)0}
};
{0, 0, (test_callback_fn)0}
};
+test_st error_conditions[] ={
+ {"memcached_get_MEMCACHED_SOME_ERRORS", 0, (test_callback_fn)memcached_get_MEMCACHED_SOME_ERRORS },
+ {"memcached_get_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND },
+ {"memcached_get_by_key_MEMCACHED_SOME_ERRORS", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_SOME_ERRORS },
+ {"memcached_get_by_key_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
+ {0, 0, (test_callback_fn)0}
+};
+
collection_st collection[] ={
#if 0
{"hash_sanity", 0, 0, hash_sanity},
{"regression", 0, 0, regression_tests},
{"behaviors", 0, 0, behavior_tests},
{"regression_binary_vs_block", (test_callback_fn)key_setup, (test_callback_fn)key_teardown, regression_binary_vs_block},
+ {"error_conditions", 0, 0, error_conditions},
{0, 0, 0, 0}
};