int max_keys= binary ? 20480 : 1;
- char **keys= calloc(max_keys, sizeof(char*));
- size_t *key_length=calloc(max_keys, sizeof(size_t));
+ char **keys= calloc((size_t)max_keys, sizeof(char*));
+ size_t *key_length=calloc((size_t)max_keys, sizeof(size_t));
/* First add all of the items.. */
char blob[1024] = {0};
for (int x= 0; x < max_keys; ++x)
{
char k[251];
- key_length[x]= snprintf(k, sizeof(k), "0200%u", x);
+ key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
keys[x]= strdup(k);
assert(keys[x] != NULL);
rc= memcached_add(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
/* Try to get all of them with a large multiget */
unsigned int counter= 0;
memcached_execute_function callbacks[1]= { [0]= &callback_counter };
- rc= memcached_mget_execute(memc, NULL, 0,
- (const char**)keys, key_length,
- max_keys, callbacks, &counter, 1);
+ rc= memcached_mget_execute(memc, (const char**)keys, key_length,
+ (size_t)max_keys, callbacks, &counter, 1);
if (binary)
{
assert(rc == MEMCACHED_END);
/* Verify that we got all of the items */
- assert(counter == max_keys);
+ assert(counter == (unsigned int)max_keys);
}
else
{
return TEST_SUCCESS;
}
+static test_return_t output_ketama_weighted_keys(memcached_st *trash)
+{
+ (void) trash;
+
+ memcached_return rc;
+ memcached_st *memc= memcached_create(NULL);
+ assert(memc);
+
+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
+ assert(value == 1);
+
+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
+ assert(value == MEMCACHED_HASH_MD5);
+
+ memcached_server_st *server_pool;
+ server_pool = memcached_servers_parse("10.0.1.1:11211,10.0.1.2:11211,10.0.1.3:11211,10.0.1.4:11211,10.0.1.5:11211,10.0.1.6:11211,10.0.1.7:11211,10.0.1.8:11211,192.168.1.1:11211,192.168.100.1:11211");
+ memcached_server_push(memc, server_pool);
+
+ FILE *fp;
+ if ((fp = fopen("ketama_keys.txt", "w")))
+ {
+ // noop
+ } else {
+ printf("cannot write to file ketama_keys.txt");
+ return TEST_FAILURE;
+ }
+
+ for (int x= 0; x < 10000; x++)
+ {
+ char key[10];
+ sprintf(key, "%d", x);
+
+ uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
+ char *hostname = memc->hosts[server_idx].hostname;
+ unsigned int port = memc->hosts[server_idx].port;
+ fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
+ }
+ fclose(fp);
+ memcached_server_list_free(server_pool);
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
+
+
static test_return_t result_static(memcached_st *memc)
{
memcached_result_st result;
return TEST_SUCCESS;
}
+static test_return_t regression_bug_447342(memcached_st *memc)
+{
+ if (memc->number_of_hosts < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
+ return TEST_SKIPPED;
+
+ memcached_return rc;
+
+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ const size_t max_keys= 100;
+ char **keys= calloc(max_keys, sizeof(char*));
+ size_t *key_length=calloc(max_keys, sizeof(size_t));
+
+ for (int x= 0; x < (int)max_keys; ++x)
+ {
+ char k[251];
+ key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
+ keys[x]= strdup(k);
+ assert(keys[x] != NULL);
+ rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+
+ /*
+ ** We are using the quiet commands to store the replicas, so we need
+ ** to ensure that all of them are processed before we can continue.
+ ** In the test we go directly from storing the object to trying to
+ ** receive the object from all of the different servers, so we
+ ** could end up in a race condition (the memcached server hasn't yet
+ ** processed the quiet command from the replication set when it process
+ ** the request from the other client (created by the clone)). As a
+ ** workaround for that we call memcached_quit to send the quit command
+ ** to the server and wait for the response ;-) If you use the test code
+ ** as an example for your own code, please note that you shouldn't need
+ ** to do this ;-)
+ */
+ memcached_quit(memc);
+
+ /* Verify that all messages are stored, and we didn't stuff too much
+ * into the servers
+ */
+ rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ unsigned int counter= 0;
+ memcached_execute_function callbacks[1]= { [0]= &callback_counter };
+ rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
+ /* Verify that we received all of the key/value pairs */
+ assert(counter == (unsigned int)max_keys);
+
+ memcached_quit(memc);
+ /*
+ * Don't do the following in your code. I am abusing the internal details
+ * within the library, and this is not a supported interface.
+ * This is to verify correct behavior in the library. Fake that two servers
+ * are dead..
+ */
+ unsigned int port0= memc->hosts[0].port;
+ unsigned int port2= memc->hosts[2].port;
+ memc->hosts[0].port= 0;
+ memc->hosts[2].port= 0;
+
+ rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ counter= 0;
+ rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
+ assert(counter == (unsigned int)max_keys);
+
+ /* restore the memc handle */
+ memc->hosts[0].port= port0;
+ memc->hosts[2].port= port2;
+
+ memcached_quit(memc);
+
+ /* Remove half of the objects */
+ for (int x= 0; x < (int)max_keys; ++x)
+ if (x & 1)
+ {
+ rc= memcached_delete(memc, keys[x], key_length[x], 0);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+
+ memcached_quit(memc);
+ memc->hosts[0].port= 0;
+ memc->hosts[2].port= 0;
+
+ /* now retry the command, this time we should have cache misses */
+ rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ counter= 0;
+ rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
+ assert(counter == (unsigned int)(max_keys >> 1));
+
+ /* Release allocated resources */
+ for (size_t x= 0; x < max_keys; ++x)
+ free(keys[x]);
+ free(keys);
+ free(key_length);
+
+ /* restore the memc handle */
+ memc->hosts[0].port= port0;
+ memc->hosts[2].port= port2;
+ return TEST_SUCCESS;
+}
+
/* Test memcached_server_get_last_disconnect
* For a working server set, shall be NULL
* For a set of non existing server, shall not be NULL
{"lp:434843 buffered", 1, regression_bug_434843_buffered },
{"lp:421108", 1, regression_bug_421108 },
{"lp:442914", 1, regression_bug_442914 },
+ {"lp:447342", 1, regression_bug_447342 },
{0, 0, 0}
};
test_st ketama_auto_eject_hosts[] ={
{"auto_eject_hosts", 1, auto_eject_hosts },
+ {"output_ketama_weighted_keys", 1, output_ketama_weighted_keys },
{0, 0, 0}
};