+ memcached_stat_free(NULL, memc_stat);
+
+ return TEST_SUCCESS;
+}
+
+/* Count the objects */
+static memcached_return callback_dump_counter(memcached_st *ptr __attribute__((unused)),
+ const char *key __attribute__((unused)),
+ size_t key_length __attribute__((unused)),
+ void *context)
+{
+ uint32_t *counter= (uint32_t *)context;
+
+ *counter= *counter + 1;
+
+ return MEMCACHED_SUCCESS;
+}
+
+static test_return_t dump_test(memcached_st *memc)
+{
+ memcached_return rc;
+ uint32_t counter= 0;
+ memcached_dump_func callbacks[1];
+ test_return_t main_rc;
+
+ callbacks[0]= &callback_dump_counter;
+
+ /* No support for Binary protocol yet */
+ if (memc->flags & MEM_BINARY_PROTOCOL)
+ return TEST_SUCCESS;
+
+ main_rc= set_test3(memc);
+
+ assert (main_rc == TEST_SUCCESS);
+
+ rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ /* We may have more then 32 if our previous flush has not completed */
+ assert(counter >= 32);
+
+ return TEST_SUCCESS;
+}
+
+#ifdef HAVE_LIBMEMCACHEDUTIL
+static void* connection_release(void *arg) {
+ struct {
+ memcached_pool_st* pool;
+ memcached_st* mmc;
+ } *resource= arg;
+
+ usleep(250);
+ assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
+ return arg;
+}
+
+static test_return_t connection_pool_test(memcached_st *memc)
+{
+ memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
+ assert(pool != NULL);
+ memcached_st* mmc[10];
+ memcached_return rc;
+
+ for (int x= 0; x < 10; ++x) {
+ mmc[x]= memcached_pool_pop(pool, false, &rc);
+ assert(mmc[x] != NULL);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+
+ assert(memcached_pool_pop(pool, false, &rc) == NULL);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ pthread_t tid;
+ struct {
+ memcached_pool_st* pool;
+ memcached_st* mmc;
+ } item= { .pool = pool, .mmc = mmc[9] };
+ pthread_create(&tid, NULL, connection_release, &item);
+ mmc[9]= memcached_pool_pop(pool, true, &rc);
+ assert(rc == MEMCACHED_SUCCESS);
+ pthread_join(tid, NULL);
+ assert(mmc[9] == item.mmc);
+ const char *key= "key";
+ size_t keylen= strlen(key);
+
+ // verify that I can do ops with all connections
+ rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ for (unsigned int x= 0; x < 10; ++x) {
+ uint64_t number_value;
+ rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(number_value == (x+1));
+ }
+
+ // Release them..
+ for (int x= 0; x < 10; ++x)
+ assert(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
+
+
+ /* verify that I can set behaviors on the pool when I don't have all
+ * of the connections in the pool. It should however be enabled
+ * when I push the item into the pool
+ */
+ mmc[0]= memcached_pool_pop(pool, false, &rc);
+ assert(mmc[0] != NULL);
+
+ rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ mmc[1]= memcached_pool_pop(pool, false, &rc);
+ assert(mmc[1] != NULL);
+
+ assert(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
+ assert(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
+ assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
+
+ mmc[0]= memcached_pool_pop(pool, false, &rc);
+ assert(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
+ assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
+
+
+ assert(memcached_pool_destroy(pool) == memc);
+ return TEST_SUCCESS;
+}
+#endif
+
+static test_return_t replication_set_test(memcached_st *memc)
+{
+ memcached_return rc;
+ memcached_st *memc_clone= memcached_clone(NULL, memc);
+ memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
+
+ rc= memcached_set(memc, "bubba", 5, "0", 1, 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);
+
+ /*
+ ** "bubba" should now be stored on all of our servers. We don't have an
+ ** easy to use API to address each individual server, so I'll just iterate
+ ** through a bunch of "master keys" and I should most likely hit all of the
+ ** servers...
+ */
+ for (int x= 'a'; x <= 'z'; ++x)
+ {
+ char key[2]= { [0]= (char)x };
+ size_t len;
+ uint32_t flags;
+ char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
+ &len, &flags, &rc);
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(val != NULL);
+ free(val);
+ }
+
+ memcached_free(memc_clone);
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t replication_get_test(memcached_st *memc)
+{
+ memcached_return rc;
+
+ /*
+ * 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
+ */
+ for (uint32_t host= 0; host < memc->number_of_hosts; ++host)
+ {
+ memcached_st *memc_clone= memcached_clone(NULL, memc);
+ memc_clone->hosts[host].port= 0;
+
+ for (int x= 'a'; x <= 'z'; ++x)
+ {
+ char key[2]= { [0]= (char)x };
+ size_t len;
+ uint32_t flags;
+ char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
+ &len, &flags, &rc);
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(val != NULL);
+ free(val);
+ }
+
+ memcached_free(memc_clone);
+ }
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t replication_mget_test(memcached_st *memc)
+{
+ memcached_return rc;
+ memcached_st *memc_clone= memcached_clone(NULL, memc);
+ memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
+
+ const char *keys[]= { "bubba", "key1", "key2", "key3" };
+ size_t len[]= { 5, 4, 4, 4 };
+
+ for (int x=0; x< 4; ++x)
+ {
+ rc= memcached_set(memc, keys[x], len[x], "0", 1, 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);
+
+ /*
+ * 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
+ */
+ memcached_result_st result_obj;
+ for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
+ {
+ memcached_st *new_clone= memcached_clone(NULL, memc);
+ new_clone->hosts[host].port= 0;
+
+ for (int x= 'a'; x <= 'z'; ++x)
+ {
+ const char key[2]= { [0]= (const char)x };
+
+ rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
+ assert(results);
+
+ int hits= 0;
+ while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
+ {
+ hits++;
+ }
+ assert(hits == 4);
+ memcached_result_free(&result_obj);
+ }
+
+ memcached_free(new_clone);
+ }
+
+ memcached_free(memc_clone);
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t replication_delete_test(memcached_st *memc)
+{
+ memcached_return rc;
+ memcached_st *memc_clone= memcached_clone(NULL, memc);
+ /* Delete the items from all of the servers except 1 */
+ uint64_t repl= memcached_behavior_get(memc,
+ MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
+
+ const char *keys[]= { "bubba", "key1", "key2", "key3" };
+ size_t len[]= { 5, 4, 4, 4 };
+
+ for (int x=0; x< 4; ++x)
+ {
+ rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+
+ /*
+ * 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
+ */
+ uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
+ for (uint32_t x= 0; x < (repl + 1); ++x)
+ {
+ memc_clone->hosts[hash].port= 0;
+ if (++hash == memc_clone->number_of_hosts)
+ hash= 0;
+ }
+
+ memcached_result_st result_obj;
+ for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
+ {
+ for (int x= 'a'; x <= 'z'; ++x)
+ {
+ const char key[2]= { [0]= (const char)x };
+
+ rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
+ assert(results);
+
+ int hits= 0;
+ while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
+ {
+ ++hits;
+ }
+ assert(hits == 4);
+ memcached_result_free(&result_obj);
+ }
+ }
+ memcached_free(memc_clone);
+
+ return TEST_SUCCESS;
+}
+
+static void increment_request_id(uint16_t *id)
+{
+ (*id)++;
+ if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
+ *id= 0;
+}
+
+static uint16_t *get_udp_request_ids(memcached_st *memc)
+{
+ uint16_t *ids= malloc(sizeof(uint16_t) * memc->number_of_hosts);
+ assert(ids != NULL);
+ unsigned int x;
+
+ for (x= 0; x < memc->number_of_hosts; x++)
+ ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
+
+ return ids;
+}
+
+static test_return_t post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
+{
+ unsigned int x;
+ memcached_server_st *cur_server = memc->hosts;
+ uint16_t *cur_req_ids = get_udp_request_ids(memc);
+
+ for (x= 0; x < memc->number_of_hosts; x++)
+ {
+ assert(cur_server[x].cursor_active == 0);
+ assert(cur_req_ids[x] == expected_req_ids[x]);
+ }
+ free(expected_req_ids);
+ free(cur_req_ids);
+
+ return TEST_SUCCESS;
+}
+
+/*
+** There is a little bit of a hack here, instead of removing
+** the servers, I just set num host to 0 and them add then new udp servers
+**/
+static memcached_return init_udp(memcached_st *memc)
+{
+ memcached_version(memc);
+ /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
+ if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
+ || memc->hosts[0].micro_version < 6)
+ return MEMCACHED_FAILURE;
+
+ uint32_t num_hosts= memc->number_of_hosts;
+ unsigned int x= 0;
+ memcached_server_st servers[num_hosts];
+ memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
+ for (x= 0; x < num_hosts; x++)
+ memcached_server_free(&memc->hosts[x]);
+
+ memc->number_of_hosts= 0;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
+ for (x= 0; x < num_hosts; x++)
+ {
+ assert(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
+ assert(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
+ }
+
+ return MEMCACHED_SUCCESS;
+}
+
+static memcached_return binary_init_udp(memcached_st *memc)
+{
+ pre_binary(memc);
+ return init_udp(memc);
+}
+
+/* Make sure that I cant add a tcp server to a udp client */
+static test_return_t add_tcp_server_udp_client_test(memcached_st *memc)
+{
+ memcached_server_st server;
+ memcached_server_clone(&server, &memc->hosts[0]);
+ assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
+ assert(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
+ return TEST_SUCCESS;
+}
+
+/* Make sure that I cant add a udp server to a tcp client */
+static test_return_t add_udp_server_tcp_client_test(memcached_st *memc)
+{
+ memcached_server_st server;
+ memcached_server_clone(&server, &memc->hosts[0]);
+ assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
+
+ memcached_st tcp_client;
+ memcached_create(&tcp_client);
+ assert(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
+ return TEST_SUCCESS;
+}
+
+static test_return_t set_udp_behavior_test(memcached_st *memc)
+{
+
+ memcached_quit(memc);
+ memc->number_of_hosts= 0;
+ run_distribution(memc);
+ assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
+ assert(memc->flags & MEM_USE_UDP);
+ assert(memc->flags & MEM_NOREPLY);;
+
+ assert(memc->number_of_hosts == 0);
+
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
+ assert(!(memc->flags & MEM_USE_UDP));
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
+ assert(!(memc->flags & MEM_NOREPLY));
+ return TEST_SUCCESS;
+}
+
+static test_return_t udp_set_test(memcached_st *memc)
+{
+ unsigned int x= 0;
+ unsigned int num_iters= 1025; //request id rolls over at 1024
+ for (x= 0; x < num_iters;x++)
+ {
+ memcached_return rc;
+ const char *key= "foo";
+ const char *value= "when we sanitize";
+ uint16_t *expected_ids= get_udp_request_ids(memc);
+ unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
+ size_t init_offset= memc->hosts[server_key].write_buffer_offset;
+ rc= memcached_set(memc, key, strlen(key),
+ value, strlen(value),
+ (time_t)0, (uint32_t)0);
+ assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+ /** NB, the check below assumes that if new write_ptr is less than
+ * the original write_ptr that we have flushed. For large payloads, this
+ * maybe an invalid assumption, but for the small payload we have it is OK
+ */
+ if (rc == MEMCACHED_SUCCESS ||
+ memc->hosts[server_key].write_buffer_offset < init_offset)
+ increment_request_id(&expected_ids[server_key]);
+
+ if (rc == MEMCACHED_SUCCESS)
+ {
+ assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
+ }
+ else
+ {
+ assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
+ assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
+ }
+ assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
+ }
+ return TEST_SUCCESS;
+}
+
+static test_return_t udp_buffered_set_test(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
+ return udp_set_test(memc);
+}
+
+static test_return_t udp_set_too_big_test(memcached_st *memc)
+{
+ memcached_return rc;
+ const char *key= "bar";
+ char value[MAX_UDP_DATAGRAM_LENGTH];
+ uint16_t *expected_ids= get_udp_request_ids(memc);
+ rc= memcached_set(memc, key, strlen(key),
+ value, MAX_UDP_DATAGRAM_LENGTH,
+ (time_t)0, (uint32_t)0);
+ assert(rc == MEMCACHED_WRITE_FAILURE);
+ return post_udp_op_check(memc,expected_ids);
+}
+
+static test_return_t udp_delete_test(memcached_st *memc)
+{
+ unsigned int x= 0;
+ unsigned int num_iters= 1025; //request id rolls over at 1024
+ for (x= 0; x < num_iters;x++)
+ {
+ memcached_return rc;
+ const char *key= "foo";
+ uint16_t *expected_ids=get_udp_request_ids(memc);
+ unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
+ size_t init_offset= memc->hosts[server_key].write_buffer_offset;
+ rc= memcached_delete(memc, key, strlen(key), 0);
+ assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+ if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
+ increment_request_id(&expected_ids[server_key]);
+ if (rc == MEMCACHED_SUCCESS)
+ assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
+ else
+ {
+ assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
+ assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
+ }
+ assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
+ }
+ return TEST_SUCCESS;
+}
+
+static test_return_t udp_buffered_delete_test(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
+ return udp_delete_test(memc);
+}
+
+static test_return_t udp_verbosity_test(memcached_st *memc)
+{
+ memcached_return rc;
+ uint16_t *expected_ids= get_udp_request_ids(memc);
+ unsigned int x;
+ for (x= 0; x < memc->number_of_hosts;x++)
+ increment_request_id(&expected_ids[x]);
+
+ rc= memcached_verbosity(memc,3);
+ assert(rc == MEMCACHED_SUCCESS);
+ return post_udp_op_check(memc,expected_ids);
+}
+
+static test_return_t udp_quit_test(memcached_st *memc)
+{
+ uint16_t *expected_ids= get_udp_request_ids(memc);
+ memcached_quit(memc);
+ return post_udp_op_check(memc, expected_ids);
+}
+
+static test_return_t udp_flush_test(memcached_st *memc)
+{
+ memcached_return rc;
+ uint16_t *expected_ids= get_udp_request_ids(memc);
+ unsigned int x;
+ for (x= 0; x < memc->number_of_hosts;x++)
+ increment_request_id(&expected_ids[x]);
+
+ rc= memcached_flush(memc,0);
+ assert(rc == MEMCACHED_SUCCESS);
+ return post_udp_op_check(memc,expected_ids);
+}
+
+static test_return_t udp_incr_test(memcached_st *memc)
+{
+ memcached_return rc;
+ const char *key= "incr";
+ const char *value= "1";
+ rc= memcached_set(memc, key, strlen(key),
+ value, strlen(value),
+ (time_t)0, (uint32_t)0);
+
+ assert(rc == MEMCACHED_SUCCESS);
+ uint16_t *expected_ids= get_udp_request_ids(memc);
+ unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
+ increment_request_id(&expected_ids[server_key]);
+ uint64_t newvalue;
+ rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
+ assert(rc == MEMCACHED_SUCCESS);
+ return post_udp_op_check(memc, expected_ids);
+}
+
+static test_return_t udp_decr_test(memcached_st *memc)
+{
+ memcached_return rc;
+ const char *key= "decr";
+ const char *value= "1";
+ rc= memcached_set(memc, key, strlen(key),
+ value, strlen(value),
+ (time_t)0, (uint32_t)0);
+
+ assert(rc == MEMCACHED_SUCCESS);
+ uint16_t *expected_ids= get_udp_request_ids(memc);
+ unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
+ increment_request_id(&expected_ids[server_key]);
+ uint64_t newvalue;
+ rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
+ assert(rc == MEMCACHED_SUCCESS);
+ return post_udp_op_check(memc, expected_ids);
+}
+
+
+static test_return_t udp_stat_test(memcached_st *memc)
+{
+ memcached_stat_st * rv= NULL;
+ memcached_return rc;
+ char args[]= "";
+ uint16_t *expected_ids = get_udp_request_ids(memc);
+ rv = memcached_stat(memc, args, &rc);
+ free(rv);
+ assert(rc == MEMCACHED_NOT_SUPPORTED);
+ return post_udp_op_check(memc, expected_ids);
+}
+
+static test_return_t udp_version_test(memcached_st *memc)
+{
+ memcached_return rc;
+ uint16_t *expected_ids = get_udp_request_ids(memc);
+ rc = memcached_version(memc);
+ assert(rc == MEMCACHED_NOT_SUPPORTED);
+ return post_udp_op_check(memc, expected_ids);
+}
+
+static test_return_t udp_get_test(memcached_st *memc)
+{
+ memcached_return rc;
+ const char *key= "foo";
+ size_t vlen;
+ uint16_t *expected_ids = get_udp_request_ids(memc);
+ char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
+ assert(rc == MEMCACHED_NOT_SUPPORTED);
+ assert(val == NULL);
+ return post_udp_op_check(memc, expected_ids);
+}
+
+static test_return_t udp_mixed_io_test(memcached_st *memc)
+{
+ test_st current_op;
+ test_st mixed_io_ops [] ={
+ {"udp_set_test", 0, udp_set_test},
+ {"udp_set_too_big_test", 0, udp_set_too_big_test},
+ {"udp_delete_test", 0, udp_delete_test},
+ {"udp_verbosity_test", 0, udp_verbosity_test},
+ {"udp_quit_test", 0, udp_quit_test},
+ {"udp_flush_test", 0, udp_flush_test},
+ {"udp_incr_test", 0, udp_incr_test},
+ {"udp_decr_test", 0, udp_decr_test},
+ {"udp_version_test", 0, udp_version_test}
+ };
+ unsigned int x= 0;
+ for (x= 0; x < 500; x++)
+ {
+ current_op= mixed_io_ops[random() % 9];
+ assert(current_op.function(memc) == TEST_SUCCESS);
+ }
+ return TEST_SUCCESS;
+}
+
+static test_return_t hsieh_avaibility_test (memcached_st *memc)
+{
+ memcached_return expected_rc= MEMCACHED_FAILURE;
+#ifdef HAVE_HSIEH_HASH
+ expected_rc= MEMCACHED_SUCCESS;
+#endif
+ memcached_return rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
+ (uint64_t)MEMCACHED_HASH_HSIEH);
+ assert(rc == expected_rc);
+ return TEST_SUCCESS;
+}
+
+static const char *list[]=
+{
+ "apple",
+ "beat",
+ "carrot",
+ "daikon",
+ "eggplant",
+ "flower",
+ "green",
+ "hide",
+ "ick",
+ "jack",
+ "kick",
+ "lime",
+ "mushrooms",
+ "nectarine",
+ "orange",
+ "peach",
+ "quant",
+ "ripen",
+ "strawberry",
+ "tang",
+ "up",
+ "volumne",
+ "when",
+ "yellow",
+ "zip",
+ NULL
+};
+
+static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
+{
+ uint32_t x;
+ const char **ptr;
+ uint32_t values[]= { 3195025439U, 2556848621U, 3724893440U, 3332385401U,
+ 245758794U, 2550894432U, 121710495U, 3053817768U,
+ 1250994555U, 1862072655U, 2631955953U, 2951528551U,
+ 1451250070U, 2820856945U, 2060845566U, 3646985608U,
+ 2138080750U, 217675895U, 2230934345U, 1234361223U,
+ 3968582726U, 2455685270U, 1293568479U, 199067604U,
+ 2042482093U };
+
+
+ for (ptr= list, x= 0; *ptr; ptr++, x++)
+ {
+ uint32_t hash_val;
+
+ hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
+ assert(values[x] == hash_val);
+ }
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
+{
+ uint32_t x;
+ const char **ptr;
+ uint32_t values[]= { 10542U, 22009U, 14526U, 19510U, 19432U, 10199U, 20634U,
+ 9369U, 11511U, 10362U, 7893U, 31289U, 11313U, 9354U,
+ 7621U, 30628U, 15218U, 25967U, 2695U, 9380U,
+ 17300U, 28156U, 9192U, 20484U, 16925U };
+
+ for (ptr= list, x= 0; *ptr; ptr++, x++)
+ {
+ uint32_t hash_val;
+
+ hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
+ assert(values[x] == hash_val);
+ }
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
+{
+ uint32_t x;
+ const char **ptr;
+ uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U,
+ 1722477987U, 2991193800U, 4147007314U, 3633179701U,
+ 1805162104U, 3503289120U, 3395702895U, 3325073042U,
+ 2345265314U, 3340346032U, 2722964135U, 1173398992U,
+ 2815549194U, 2562818319U, 224996066U, 2680194749U,
+ 3035305390U, 246890365U, 2395624193U, 4145193337U,
+ 1801941682U };
+
+ for (ptr= list, x= 0; *ptr; ptr++, x++)
+ {
+ uint32_t hash_val;
+
+ hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
+ assert(values[x] == hash_val);
+ }
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
+{
+ uint32_t x;
+ const char **ptr;
+ uint32_t values[]= { 1488911807U, 2500855813U, 1510099634U, 1390325195U,
+ 3647689787U, 3241528582U, 1669328060U, 2604311949U,
+ 734810122U, 1516407546U, 560948863U, 1767346780U,
+ 561034892U, 4156330026U, 3716417003U, 3475297030U,
+ 1518272172U, 227211583U, 3938128828U, 126112909U,
+ 3043416448U, 3131561933U, 1328739897U, 2455664041U,
+ 2272238452U };
+
+ for (ptr= list, x= 0; *ptr; ptr++, x++)
+ {
+ uint32_t hash_val;
+
+ hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
+ assert(values[x] == hash_val);
+ }
+
+ return TEST_SUCCESS;
+}