+void get_stats(memcached_st *memc)
+{
+ unsigned int x;
+ char **list;
+ char **ptr;
+ memcached_return rc;
+ memcached_stat_st *stat;
+
+ stat= memcached_stat(memc, NULL, &rc);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(stat);
+
+ for (x= 0; x < memcached_server_count(memc); x++)
+ {
+ list= memcached_stat_get_keys(memc, &stat[x], &rc);
+ assert(rc == MEMCACHED_SUCCESS);
+ for (ptr= list; *ptr; ptr++)
+ printf("Found key %s\n", *ptr);
+
+ free(list);
+ }
+
+ free(stat);
+}
+
+void add_host_test(memcached_st *memc)
+{
+ unsigned int x;
+ memcached_server_st *servers;
+ memcached_return rc;
+ char servername[]= "0.example.com";
+
+ 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);
+}
+
+/* We don't test the behavior itself, we test the switches */
+void behavior_test(memcached_st *memc)
+{
+ unsigned long long value;
+ unsigned int set= 1;
+
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &set);
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
+ assert(value == 1);
+
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &set);
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
+ assert(value == 1);
+
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_MD5_HASHING, &set);
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_MD5_HASHING);
+ assert(value == 1);
+
+ set= 0;
+
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &set);
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
+ assert(value == 0);
+
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &set);
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
+ assert(value == 0);
+
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_MD5_HASHING, &set);
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_MD5_HASHING);
+ assert(value == 0);
+
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
+ assert(value > 0);
+
+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
+ assert(value > 0);
+}
+
+/* Test case provided by Cal Haldenbrand */
+void user_supplied_bug1(memcached_st *memc)
+{
+ unsigned int setter= 1;
+ unsigned int x;
+
+ unsigned long long total= 0;
+ int size= 0;
+ char key[10];
+ char randomstuff[6 * 1024];
+ memcached_return rc;
+
+ memset(randomstuff, 0, 6 * 1024);
+
+ /* We just keep looking at the same values over and over */
+ srandom(10);
+
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &setter);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &setter);
+
+
+ /* add key */
+ for (x= 0 ; total < 20 * 1024576 ; x++ )
+ {
+ unsigned int j= 0;
+
+ size= (rand() % ( 5 * 1024 ) ) + 400;
+ memset(randomstuff, 0, 6 * 1024);
+ assert(size < 6 * 1024); /* Being safe here */
+
+ for (j= 0 ; j < size ;j++)
+ randomstuff[j] = (char) (rand() % 26) + 97;
+
+ total += size;
+ sprintf(key, "%d", x);
+ rc = memcached_set(memc, key, strlen(key),
+ randomstuff, strlen(randomstuff), 10, 0);
+ /* If we fail, lets try again */
+ if (rc != MEMCACHED_SUCCESS)
+ rc = memcached_set(memc, key, strlen(key),
+ randomstuff, strlen(randomstuff), 10, 0);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+}
+
+/* Test case provided by Cal Haldenbrand */
+void user_supplied_bug2(memcached_st *memc)
+{
+ int errors;
+ unsigned int setter;
+ unsigned int x;
+ unsigned long long total;
+
+ setter= 1;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &setter);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &setter);
+#ifdef NOT_YET
+ setter = 20 * 1024576;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, &setter);
+ setter = 20 * 1024576;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, &setter);
+ getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
+ getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
+
+ for (x= 0, errors= 0, total= 0 ; total < 20 * 1024576 ; x++)
+#endif
+
+ for (x= 0, errors= 0, total= 0 ; total < 24576 ; x++)
+ {
+ memcached_return rc= MEMCACHED_SUCCESS;
+ char buffer[SMALL_STRING_LEN];
+ uint16_t flags= 0;
+ size_t val_len= 0;
+ char *getval;
+
+ memset(buffer, 0, SMALL_STRING_LEN);
+
+ snprintf(buffer, SMALL_STRING_LEN, "%u", x);
+ getval= memcached_get(memc, buffer, strlen(buffer),
+ &val_len, &flags, &rc);
+ if (rc != MEMCACHED_SUCCESS)
+ {
+ if (rc == MEMCACHED_NOTFOUND)
+ errors++;
+ else
+ assert(0);
+
+ continue;
+ }
+ total+= val_len;
+ errors= 0;
+ free(getval);
+ }
+}
+
+/* Do a large mget() over all the keys we think exist */
+#define KEY_COUNT 3000 // * 1024576
+void user_supplied_bug3(memcached_st *memc)
+{
+ memcached_return rc;
+ unsigned int setter;
+ unsigned int x;
+ char **keys;
+ size_t key_lengths[KEY_COUNT];
+
+ setter= 1;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &setter);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &setter);
+#ifdef NOT_YET
+ setter = 20 * 1024576;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, &setter);
+ setter = 20 * 1024576;
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, &setter);
+ getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
+ getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
+#endif
+
+ keys= (char **)malloc(sizeof(char *) * KEY_COUNT);
+ assert(keys);
+ memset(keys, 0, (sizeof(char *) * KEY_COUNT));
+ for (x= 0; x < KEY_COUNT; x++)
+ {
+ char buffer[30];
+
+ snprintf(buffer, 30, "%u", x);
+ keys[x]= strdup(buffer);
+ key_lengths[x]= strlen(keys[x]);
+ }
+
+ rc= memcached_mget(memc, keys, key_lengths, KEY_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;
+ uint16_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);
+ }
+ }
+
+ for (x= 0; x < KEY_COUNT; x++)
+ free(keys[x]);
+ free(keys);
+}
+
+void string_alloc_null(memcached_st *memc)
+{
+ memcached_string_st *string;
+
+ string= memcached_string_create(memc, 0);
+ assert(string);
+ memcached_string_free(memc, string);
+}
+
+void string_alloc_with_size(memcached_st *memc)
+{
+ memcached_string_st *string;
+
+ string= memcached_string_create(memc, 1024);
+ assert(string);
+ memcached_string_free(memc, string);
+}
+
+void string_alloc_with_size_toobig(memcached_st *memc)
+{
+ memcached_string_st *string;
+
+ string= memcached_string_create(memc, INT64_MAX);
+ assert(string == NULL);
+}
+
+void 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, 100);
+ assert(string);
+
+ for (x= 0; x < 1024; x++)
+ {
+ memcached_return rc;
+ rc= memcached_string_append(memc, string, buffer, SMALL_STRING_LEN);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+ memcached_string_free(memc, string);
+}
+
+void 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, 100);
+ assert(string);
+
+ for (x= 0; x < 1024; x++)
+ {
+ rc= memcached_string_append(memc, string, buffer, SMALL_STRING_LEN);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+ rc= memcached_string_append(memc, string, buffer, INT64_MAX);
+ assert(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
+ memcached_string_free(memc, string);
+}
+
+void 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);
+}
+
+memcached_return pre_nonblock(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_md5(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_MD5_HASHING, NULL);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_crc(memcached_st *memc)
+{
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CRC_HASHING, NULL);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_unix_socket(memcached_st *memc)
+{
+ memcached_return rc;
+ struct stat buf;
+
+ memcached_server_list_free(memc->hosts);
+ memc->hosts= NULL;
+ memc->number_of_hosts= 0;
+
+ if (stat("/tmp/memcached.socket", &buf))
+ return MEMCACHED_FAILURE;
+
+ rc= memcached_server_add_unix_socket(memc, "/tmp/memcached.socket");
+
+ return rc;