+ key_length[0]= strlen("UDATA:edevil@sapo.pt");
+ key_length[1]= strlen("fudge&*@#");
+ key_length[2]= strlen("for^#@&$not");
+
+
+ for (x= 0; x < 3; x++)
+ {
+ rc= memcached_set(memc, keys[x], key_length[x],
+ keys[x], key_length[x],
+ (time_t)50, (uint32_t)9);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+
+ rc= memcached_mget(memc, keys, key_length, 3);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ /* We need to empty the server before continueing test */
+ while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
+ &return_value_length, &flags, &rc)) != NULL)
+ {
+ assert(return_value);
+ free(return_value);
+ count++;
+ }
+ assert(count == 3);
+
+ return 0;
+}
+
+/* We are testing with aggressive timeout to get failures */
+uint8_t user_supplied_bug10(memcached_st *memc)
+{
+ char *key= "foo";
+ char *value;
+ size_t value_length= 512;
+ unsigned int x;
+ int key_len= 3;
+ memcached_return rc;
+ unsigned int set= 1;
+ memcached_st *mclone= memcached_clone(NULL, memc);
+ int32_t timeout;
+
+ memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
+ memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
+ timeout= 2;
+ memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
+
+ value = (char*)malloc(value_length * sizeof(char));
+
+ for (x= 0; x < value_length; x++)
+ value[x]= (char) (x % 127);
+
+ for (x= 1; x <= 100000; ++x)
+ {
+ rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
+
+ assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_BUFFERED);
+
+ if (rc == MEMCACHED_WRITE_FAILURE)
+ x--;
+ }
+
+ free(value);
+ memcached_free(mclone);
+
+ return 0;
+}
+
+/*
+ We are looking failures in the async protocol
+*/
+uint8_t user_supplied_bug11(memcached_st *memc)
+{
+ char *key= "foo";
+ char *value;
+ size_t value_length= 512;
+ unsigned int x;
+ int key_len= 3;
+ memcached_return rc;
+ unsigned int set= 1;
+ int32_t timeout;
+ memcached_st *mclone= memcached_clone(NULL, memc);
+
+ memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
+ memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
+ timeout= -1;
+ memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
+
+ timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
+
+ assert(timeout == -1);
+
+ value = (char*)malloc(value_length * sizeof(char));
+
+ for (x= 0; x < value_length; x++)
+ value[x]= (char) (x % 127);
+
+ for (x= 1; x <= 100000; ++x)
+ {
+ rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
+ }
+
+ free(value);
+ memcached_free(mclone);
+
+ return 0;
+}
+
+/*
+ Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
+*/
+uint8_t user_supplied_bug12(memcached_st *memc)
+{
+ memcached_return rc;
+ uint32_t flags;
+ size_t value_length;
+ char *value;
+ uint64_t number_value;
+
+ value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
+ &value_length, &flags, &rc);
+ assert(value == NULL);
+ assert(rc == MEMCACHED_NOTFOUND);
+
+ rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
+ 1, &number_value);
+
+ assert(value == NULL);
+ assert(rc == MEMCACHED_NOTFOUND);
+
+ rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
+
+ value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
+ &value_length, &flags, &rc);
+ assert(value);
+ assert(rc == MEMCACHED_SUCCESS);
+ free(value);
+
+ rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
+ 1, &number_value);
+ assert(number_value == 2);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ return 0;
+}
+
+/*
+ Bug found where command total one more than MEMCACHED_MAX_BUFFER
+ set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
+ */
+uint8_t user_supplied_bug13(memcached_st *memc)
+{
+ char key[] = "key34567890";
+ char *overflow;
+ memcached_return rc;
+ size_t overflowSize;
+
+ char commandFirst[]= "set key34567890 0 0 ";
+ char commandLast[] = " \r\n"; /* first line of command sent to server */
+ size_t commandLength;
+ size_t testSize;
+
+ commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
+
+ overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
+
+ for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
+ {
+ overflow= malloc(testSize);
+ assert(overflow != NULL);
+
+ memset(overflow, 'x', testSize);
+ rc= memcached_set(memc, key, strlen(key),
+ overflow, testSize, 0, 0);
+ assert(rc == MEMCACHED_SUCCESS);
+ free(overflow);
+ }
+
+ return 0;
+}
+
+
+/*
+ Test values of many different sizes
+ Bug found where command total one more than MEMCACHED_MAX_BUFFER
+ set key34567890 0 0 8169 \r\n
+ is sent followed by buffer of size 8169, followed by 8169
+ */
+uint8_t user_supplied_bug14(memcached_st *memc)
+{
+ int setter= 1;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
+ memcached_return rc;
+ char *key= "foo";
+ char *value;
+ size_t value_length= 18000;
+ char *string;
+ size_t string_length;
+ uint32_t flags;
+ unsigned int x;
+ size_t current_length;
+
+ value = (char*)malloc(value_length);
+ assert(value);
+
+ for (x= 0; x < value_length; x++)
+ value[x] = (char) (x % 127);
+
+ for (current_length= 0; current_length < value_length; current_length++)
+ {
+ rc= memcached_set(memc, key, strlen(key),
+ value, current_length,
+ (time_t)0, (uint32_t)0);
+ assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+
+ string= memcached_get(memc, key, strlen(key),
+ &string_length, &flags, &rc);
+
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(string);
+ assert(string_length == current_length);
+ assert(!memcmp(string, value, string_length));
+
+ free(string);
+ }
+
+ free(value);
+
+ return 0;
+}
+
+/*
+ Look for zero length value problems
+ */
+uint8_t user_supplied_bug15(memcached_st *memc)
+{
+ uint32_t x;
+ memcached_return rc;
+ char *key= "mykey";
+ char *value;
+ size_t length;
+ uint32_t flags;
+
+ for (x= 0; x < 2; x++)
+ {
+ rc= memcached_set(memc, key, strlen(key),
+ NULL, 0,
+ (time_t)0, (uint32_t)0);
+
+ assert(rc == MEMCACHED_SUCCESS);
+
+ value= memcached_get(memc, key, strlen(key),
+ &length, &flags, &rc);
+
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(value == NULL);
+ assert(length == 0);
+ assert(flags == 0);
+
+ value= memcached_get(memc, key, strlen(key),
+ &length, &flags, &rc);
+
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(value == NULL);
+ assert(length == 0);
+ assert(flags == 0);
+ }
+
+ return 0;
+}
+
+uint8_t result_static(memcached_st *memc)
+{
+ memcached_result_st result;
+ memcached_result_st *result_ptr;
+
+ result_ptr= memcached_result_create(memc, &result);
+ assert(result.is_allocated == MEMCACHED_NOT_ALLOCATED);
+ assert(result_ptr);
+ memcached_result_free(&result);
+
+ return 0;
+}
+
+uint8_t result_alloc(memcached_st *memc)
+{
+ memcached_result_st *result;
+
+ result= memcached_result_create(memc, NULL);
+ assert(result);
+ memcached_result_free(result);
+
+ return 0;
+}
+
+uint8_t string_static_null(memcached_st *memc)
+{
+ memcached_string_st string;
+ memcached_string_st *string_ptr;
+
+ string_ptr= memcached_string_create(memc, &string, 0);
+ assert(string.is_allocated == MEMCACHED_NOT_ALLOCATED);
+ assert(string_ptr);
+ memcached_string_free(&string);
+
+ return 0;
+}
+
+uint8_t string_alloc_null(memcached_st *memc)
+{
+ memcached_string_st *string;
+
+ string= memcached_string_create(memc, NULL, 0);
+ assert(string);
+ memcached_string_free(string);
+
+ return 0;
+}
+
+uint8_t string_alloc_with_size(memcached_st *memc)
+{
+ memcached_string_st *string;
+
+ string= memcached_string_create(memc, NULL, 1024);
+ assert(string);
+ memcached_string_free(string);
+
+ return 0;
+}
+
+uint8_t string_alloc_with_size_toobig(memcached_st *memc)
+{
+ memcached_string_st *string;
+
+ string= memcached_string_create(memc, NULL, INT64_MAX);
+ assert(string == NULL);
+
+ return 0;
+}
+
+uint8_t string_alloc_append(memcached_st *memc)
+{
+ unsigned int x;
+ char buffer[SMALL_STRING_LEN];
+ memcached_string_st *string;
+
+ /* Ring the bell! */
+ memset(buffer, 6, SMALL_STRING_LEN);
+
+ string= memcached_string_create(memc, NULL, 100);
+ assert(string);
+
+ for (x= 0; x < 1024; x++)
+ {
+ memcached_return rc;
+ rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+ memcached_string_free(string);
+
+ return 0;
+}
+
+uint8_t string_alloc_append_toobig(memcached_st *memc)
+{
+ memcached_return rc;
+ unsigned int x;
+ char buffer[SMALL_STRING_LEN];
+ memcached_string_st *string;
+
+ /* Ring the bell! */
+ memset(buffer, 6, SMALL_STRING_LEN);
+
+ string= memcached_string_create(memc, NULL, 100);
+ assert(string);
+
+ for (x= 0; x < 1024; x++)
+ {
+ rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+ rc= memcached_string_append(string, buffer, INT64_MAX);
+ assert(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
+ memcached_string_free(string);
+
+ return 0;
+}
+
+uint8_t cleanup_pairs(memcached_st *memc)
+{
+ pairs_free(global_pairs);
+
+ return 0;
+}
+
+uint8_t generate_pairs(memcached_st *memc)
+{
+ unsigned long long x;
+ global_pairs= pairs_generate(GLOBAL_COUNT, 400);
+ global_count= GLOBAL_COUNT;
+
+ for (x= 0; x < global_count; x++)
+ {
+ global_keys[x]= global_pairs[x].key;
+ global_keys_length[x]= global_pairs[x].key_length;
+ }
+
+ return 0;
+}
+
+uint8_t generate_large_pairs(memcached_st *memc)
+{
+ unsigned long long x;
+ global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
+ global_count= GLOBAL2_COUNT;
+
+ for (x= 0; x < global_count; x++)
+ {
+ global_keys[x]= global_pairs[x].key;
+ global_keys_length[x]= global_pairs[x].key_length;
+ }
+
+ return 0;
+}
+
+uint8_t generate_data(memcached_st *memc)
+{
+ execute_set(memc, global_pairs, global_count);
+
+ return 0;
+}
+
+uint8_t generate_buffer_data(memcached_st *memc)
+{
+ int latch= 0;
+
+ latch= 1;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
+ generate_data(memc);
+
+ return 0;
+}
+
+uint8_t get_read(memcached_st *memc)
+{
+ unsigned int x;
+ memcached_return rc;
+
+ {
+ char *return_value;
+ size_t return_value_length;
+ uint32_t flags;
+
+ for (x= 0; x < global_count; x++)
+ {
+ return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
+ &return_value_length, &flags, &rc);
+ /*
+ assert(return_value);
+ assert(rc == MEMCACHED_SUCCESS);
+ */
+ if (rc == MEMCACHED_SUCCESS && return_value)
+ free(return_value);
+ }
+ }
+
+ return 0;
+}
+
+uint8_t mget_read(memcached_st *memc)
+{
+ memcached_return rc;
+
+ rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
+ assert(rc == MEMCACHED_SUCCESS);
+ /* Turn this into a help function */
+ {
+ char return_key[MEMCACHED_MAX_KEY];
+ size_t return_key_length;
+ char *return_value;
+ size_t return_value_length;
+ uint32_t flags;
+
+ while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
+ &return_value_length, &flags, &rc)))
+ {
+ assert(return_value);
+ assert(rc == MEMCACHED_SUCCESS);
+ free(return_value);
+ }
+ }
+
+ return 0;
+}
+
+uint8_t mget_read_result(memcached_st *memc)
+{
+ memcached_return rc;
+
+ rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
+ assert(rc == MEMCACHED_SUCCESS);
+ /* Turn this into a help function */
+ {
+ memcached_result_st results_obj;
+ memcached_result_st *results;
+
+ results= memcached_result_create(memc, &results_obj);
+
+ while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
+ {
+ assert(results);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+
+ memcached_result_free(&results_obj);
+ }
+
+ return 0;
+}
+
+uint8_t mget_read_function(memcached_st *memc)
+{
+ memcached_return rc;
+ unsigned int counter;
+ unsigned int (*callbacks[1])(memcached_st *, memcached_result_st *, void *);
+
+ rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ callbacks[0]= &callback_counter;
+ counter= 0;
+ rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
+
+ return 0;
+}
+
+uint8_t delete_generate(memcached_st *memc)
+{
+ unsigned int x;
+
+ for (x= 0; x < global_count; x++)
+ {
+ (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
+ }
+
+ return 0;
+}
+
+uint8_t delete_buffer_generate(memcached_st *memc)
+{
+ int latch= 0;
+ unsigned int x;
+
+ latch= 1;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
+
+ for (x= 0; x < global_count; x++)
+ {
+ (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
+ }
+
+ return 0;
+}
+
+uint8_t free_data(memcached_st *memc)
+{
+ pairs_free(global_pairs);
+
+ return 0;
+}
+
+uint8_t add_host_test1(memcached_st *memc)
+{
+ unsigned int x;
+ memcached_return rc;
+ char servername[]= "0.example.com";
+ memcached_server_st *servers;
+
+ servers= memcached_server_list_append(NULL, servername, 400, &rc);
+ assert(servers);
+ assert(1 == memcached_server_list_count(servers));
+
+ for (x= 2; x < 20; x++)
+ {
+ char buffer[SMALL_STRING_LEN];
+
+ snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
+ servers= memcached_server_list_append(servers, buffer, 401,
+ &rc);
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(x == memcached_server_list_count(servers));
+ }
+
+ rc= memcached_server_push(memc, servers);
+ assert(rc == MEMCACHED_SUCCESS);
+ rc= memcached_server_push(memc, servers);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ memcached_server_list_free(servers);
+
+ return 0;
+}
+
+memcached_return pre_nonblock(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_murmur(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_md5(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_crc(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_hsieh(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_hash_fnv1_64(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_64);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_hash_fnv1a_64(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_hash_fnv1_32(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_hash_fnv1a_32(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_hash_ketama(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_KETAMA);
+
+ return MEMCACHED_SUCCESS;
+}
+
+void my_free(memcached_st *ptr, void *mem)
+{
+ free(mem);
+}
+
+void *my_malloc(memcached_st *ptr, const size_t size)
+{
+ return malloc(size);
+}
+
+void *my_realloc(memcached_st *ptr, void *mem, const size_t size)
+{
+ return realloc(mem, size);
+}
+
+memcached_return set_memory_alloc(memcached_st *memc)
+{
+ {
+ memcached_malloc_function test_ptr;
+ memcached_return rc;
+
+ rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &my_malloc);
+ assert(rc == MEMCACHED_SUCCESS);
+ test_ptr= (memcached_malloc_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(test_ptr == my_malloc);
+ }
+
+ {
+ memcached_realloc_function test_ptr;
+ memcached_return rc;
+
+ rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &my_realloc);
+ assert(rc == MEMCACHED_SUCCESS);
+ test_ptr= (memcached_realloc_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(test_ptr == my_realloc);
+ }
+
+ {
+ memcached_free_function test_ptr;
+ memcached_return rc;
+
+ rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, my_free);
+ assert(rc == MEMCACHED_SUCCESS);
+ test_ptr= (memcached_free_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(test_ptr == my_free);
+ }
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return enable_consistent(memcached_st *memc)
+{
+ memcached_server_distribution value= MEMCACHED_DISTRIBUTION_CONSISTENT;
+ memcached_hash hash;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
+ pre_hsieh(memc);
+
+ value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
+ assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
+
+ hash= (memcached_hash)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
+ assert(hash == MEMCACHED_HASH_HSIEH);
+
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return enable_cas(memcached_st *memc)
+{
+ unsigned int set= 1;
+
+ memcached_version(memc);
+
+ if (memc->hosts[0].major_version >= 1 &&
+ memc->hosts[0].minor_version >= 2 &&
+ memc->hosts[0].micro_version >= 4)
+ {
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
+
+ return MEMCACHED_SUCCESS;
+ }
+
+ return MEMCACHED_FAILURE;
+}
+
+memcached_return check_for_1_2_3(memcached_st *memc)
+{
+ memcached_version(memc);
+
+ if (memc->hosts[0].major_version >= 1 &&
+ memc->hosts[0].minor_version >= 2 &&
+ memc->hosts[0].micro_version >= 4)
+ return MEMCACHED_SUCCESS;
+
+ return MEMCACHED_FAILURE;
+}