X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=tests%2Ftest.c;h=27dd4419e39aa56b1a1e5d875100869f638e7c74;hb=d4dc795f136a3a652c5b13b4d818345c6080bceb;hp=60c6211a09e86a1dc20936abb99852647f4bb6d2;hpb=a6fa1b62336cfddaf0d9efb7f431490a7c2f3ac9;p=awesomized%2Flibmemcached diff --git a/tests/test.c b/tests/test.c index 60c6211a..27dd4419 100644 --- a/tests/test.c +++ b/tests/test.c @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include #include "../lib/common.h" @@ -37,6 +40,43 @@ void allocation_test(memcached_st *not_used) memcached_free(memc); } +void clone_test(memcached_st *memc) +{ + /* All null? */ + { + memcached_st *clone; + clone= memcached_clone(NULL, NULL); + assert(clone); + memcached_free(clone); + } + + /* Can we init from null? */ + { + memcached_st *clone; + clone= memcached_clone(NULL, memc); + assert(clone); + memcached_free(clone); + } + + /* Can we init from struct? */ + { + memcached_st declared_clone; + memcached_st *clone; + clone= memcached_clone(&declared_clone, NULL); + assert(clone); + memcached_free(clone); + } + + /* Can we init from struct? */ + { + memcached_st declared_clone; + memcached_st *clone; + clone= memcached_clone(&declared_clone, memc); + assert(clone); + memcached_free(clone); + } +} + void connection_test(memcached_st *memc) { memcached_return rc; @@ -344,6 +384,110 @@ void quit_test(memcached_st *memc) assert(rc == MEMCACHED_SUCCESS); } +void mget_result_test(memcached_st *memc) +{ + memcached_return rc; + char *keys[]= {"fudge", "son", "food"}; + size_t key_length[]= {5, 3, 4}; + unsigned int x; + + memcached_result_st results_obj; + memcached_result_st *results; + + results= memcached_result_create(memc, &results_obj); + assert(results); + assert(&results_obj == results); + + /* We need to empty the server before continueing test */ + rc= memcached_flush(memc, 0); + assert(rc == MEMCACHED_SUCCESS); + + rc= memcached_mget(memc, keys, key_length, 3); + assert(rc == MEMCACHED_SUCCESS); + + while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL) + { + assert(results); + } + while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL) + assert(!results); + assert(rc == MEMCACHED_NOTFOUND); + + for (x= 0; x < 3; x++) + { + rc= memcached_set(memc, keys[x], key_length[x], + keys[x], key_length[x], + (time_t)50, (uint16_t)9); + assert(rc == MEMCACHED_SUCCESS); + } + + rc= memcached_mget(memc, keys, key_length, 3); + assert(rc == MEMCACHED_SUCCESS); + + while ((results= memcached_fetch_result(memc, &results_obj, &rc))) + { + assert(results); + assert(&results_obj == results); + assert(rc == MEMCACHED_SUCCESS); + assert(memcached_result_key_length(results) == memcached_result_length(results)); + assert(!memcmp(memcached_result_key_value(results), + memcached_result_value(results), + memcached_result_length(results))); + } + + WATCHPOINT; + memcached_result_free(&results_obj); + WATCHPOINT; +} + +void mget_result_alloc_test(memcached_st *memc) +{ + memcached_return rc; + char *keys[]= {"fudge", "son", "food"}; + size_t key_length[]= {5, 3, 4}; + unsigned int x; + + memcached_result_st *results; + + /* We need to empty the server before continueing test */ + rc= memcached_flush(memc, 0); + assert(rc == MEMCACHED_SUCCESS); + + rc= memcached_mget(memc, keys, key_length, 3); + assert(rc == MEMCACHED_SUCCESS); + + while ((results= memcached_fetch_result(memc, NULL, &rc)) != NULL) + { + assert(results); + } + assert(!results); + assert(rc == MEMCACHED_NOTFOUND); + + for (x= 0; x < 3; x++) + { + rc= memcached_set(memc, keys[x], key_length[x], + keys[x], key_length[x], + (time_t)50, (uint16_t)9); + assert(rc == MEMCACHED_SUCCESS); + } + + rc= memcached_mget(memc, keys, key_length, 3); + assert(rc == MEMCACHED_SUCCESS); + + x= 0; + while ((results= memcached_fetch_result(memc, NULL, &rc))) + { + assert(results); + assert(rc == MEMCACHED_SUCCESS); + assert(memcached_result_key_length(results) == memcached_result_length(results)); + assert(!memcmp(memcached_result_key_value(results), + memcached_result_value(results), + memcached_result_length(results))); + memcached_result_free(results); + x++; + } +} + void mget_test(memcached_st *memc) { memcached_return rc; @@ -437,7 +581,7 @@ void get_stats(memcached_st *memc) free(list); } - free(stat); + memcached_stat_free(NULL, stat); } void add_host_test(memcached_st *memc) @@ -484,9 +628,10 @@ void behavior_test(memcached_st *memc) 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= MEMCACHED_HASH_MD5; + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &set); + value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH); + assert(value == MEMCACHED_HASH_MD5); set= 0; @@ -498,9 +643,15 @@ void behavior_test(memcached_st *memc) 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); + set= MEMCACHED_HASH_DEFAULT; + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &set); + value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH); + assert(value == MEMCACHED_HASH_DEFAULT); + + set= MEMCACHED_HASH_CRC; + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &set); + value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH); + assert(value == MEMCACHED_HASH_CRC); value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE); assert(value > 0); @@ -572,9 +723,11 @@ void user_supplied_bug2(memcached_st *memc) 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 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]; @@ -641,7 +794,7 @@ void user_supplied_bug3(memcached_st *memc) /* Turn this into a help function */ { - char *return_key; + char return_key[MEMCACHED_MAX_KEY]; size_t return_key_length; char *return_value; size_t return_value_length; @@ -661,29 +814,60 @@ void user_supplied_bug3(memcached_st *memc) free(keys); } +void 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); +} + +void result_alloc(memcached_st *memc) +{ + memcached_result_st *result; + + result= memcached_result_create(memc, NULL); + assert(result); + memcached_result_free(result); +} + +void 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); +} + void string_alloc_null(memcached_st *memc) { memcached_string_st *string; - string= memcached_string_create(memc, 0); + string= memcached_string_create(memc, NULL, 0); assert(string); - memcached_string_free(memc, string); + memcached_string_free(string); } void string_alloc_with_size(memcached_st *memc) { memcached_string_st *string; - string= memcached_string_create(memc, 1024); + string= memcached_string_create(memc, NULL, 1024); assert(string); - memcached_string_free(memc, string); + memcached_string_free(string); } void string_alloc_with_size_toobig(memcached_st *memc) { memcached_string_st *string; - string= memcached_string_create(memc, 1024*100000000000); + string= memcached_string_create(memc, NULL, INT64_MAX); assert(string == NULL); } @@ -696,16 +880,16 @@ void string_alloc_append(memcached_st *memc) /* Ring the bell! */ memset(buffer, 6, SMALL_STRING_LEN); - string= memcached_string_create(memc, 100); + string= memcached_string_create(memc, NULL, 100); assert(string); for (x= 0; x < 1024; x++) { memcached_return rc; - rc= memcached_string_append(memc, string, buffer, SMALL_STRING_LEN); + rc= memcached_string_append(string, buffer, SMALL_STRING_LEN); assert(rc == MEMCACHED_SUCCESS); } - memcached_string_free(memc, string); + memcached_string_free(string); } void string_alloc_append_toobig(memcached_st *memc) @@ -718,17 +902,17 @@ void string_alloc_append_toobig(memcached_st *memc) /* Ring the bell! */ memset(buffer, 6, SMALL_STRING_LEN); - string= memcached_string_create(memc, 100); + string= memcached_string_create(memc, NULL, 100); assert(string); for (x= 0; x < 1024; x++) { - rc= memcached_string_append(memc, string, buffer, SMALL_STRING_LEN); + rc= memcached_string_append(string, buffer, SMALL_STRING_LEN); assert(rc == MEMCACHED_SUCCESS); } - rc= memcached_string_append(memc, string, buffer, 1024*100000000000); + rc= memcached_string_append(string, buffer, INT64_MAX); assert(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE); - memcached_string_free(memc, string); + memcached_string_free(string); } void add_host_test1(memcached_st *memc) @@ -761,24 +945,121 @@ void add_host_test1(memcached_st *memc) 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_hash value= MEMCACHED_HASH_MD5; + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value); + + return MEMCACHED_SUCCESS; +} + +memcached_return pre_crc(memcached_st *memc) +{ + memcached_hash value= MEMCACHED_HASH_CRC; + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value); + + return MEMCACHED_SUCCESS; +} + +memcached_return pre_hash_fnv1_64(memcached_st *memc) +{ + memcached_hash value= MEMCACHED_HASH_FNV1_64; + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value); + + return MEMCACHED_SUCCESS; +} + +memcached_return pre_hash_fnv1a_64(memcached_st *memc) +{ + memcached_hash value= MEMCACHED_HASH_FNV1A_64; + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value); + + return MEMCACHED_SUCCESS; +} + +memcached_return pre_hash_fnv1_32(memcached_st *memc) +{ + memcached_hash value= MEMCACHED_HASH_FNV1_32; + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value); + + return MEMCACHED_SUCCESS; +} + +memcached_return pre_hash_fnv1a_32(memcached_st *memc) +{ + memcached_hash value= MEMCACHED_HASH_FNV1A_32; + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value); + + return MEMCACHED_SUCCESS; +} + +memcached_return pre_hash_ketama(memcached_st *memc) +{ + memcached_hash value= MEMCACHED_HASH_KETAMA; + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value); + + 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; +} + +memcached_return pre_nodelay(memcached_st *memc) +{ + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL); + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, NULL); + + return MEMCACHED_SUCCESS; +} + +typedef struct collection_st collection_st; typedef struct test_st test_st; struct test_st { - char *function_name; + char *name; unsigned int requires_flush; void (*function)(memcached_st *memc); }; +struct collection_st { + char *name; + memcached_return (*pre)(memcached_st *memc); + memcached_return (*post)(memcached_st *memc); + test_st *tests; +}; + int main(int argc, char *argv[]) { unsigned int x; char *server_list; - char *test_to_run= NULL; + char *collection_to_run= NULL; char *wildcard= NULL; memcached_server_st *servers; + if (argc > 1) - test_to_run= argv[1]; + collection_to_run= argv[1]; if (argc == 3) wildcard= argv[2]; @@ -807,6 +1088,7 @@ int main(int argc, char *argv[]) {"flush", 0, flush_test }, {"init", 0, init_test }, {"allocation", 0, allocation_test }, + {"clone_test", 0, clone_test }, {"error", 0, error_test }, {"set", 0, set_test }, {"set2", 0, set_test2 }, @@ -822,7 +1104,9 @@ int main(int argc, char *argv[]) {"increment", 0, increment_test }, {"decrement", 0, decrement_test }, {"quit", 0, quit_test }, - {"mget", 0, mget_test }, + {"mget", 1, mget_test }, + {"mget_result", 1, mget_result_test }, + {"mget_result_alloc", 1, mget_result_alloc_test }, {"get_stats", 0, get_stats }, {"add_host_test", 0, add_host_test }, {"get_stats_keys", 0, get_stats_keys }, @@ -831,6 +1115,7 @@ int main(int argc, char *argv[]) }; test_st string_tests[] ={ + {"string static with null", 0, string_static_null }, {"string alloc with null", 0, string_alloc_null }, {"string alloc with 1K", 0, string_alloc_with_size }, {"string alloc with malloc failure", 0, string_alloc_with_size_toobig }, @@ -839,134 +1124,57 @@ int main(int argc, char *argv[]) {0, 0, 0} }; + test_st result_tests[] ={ + {"result static", 0, result_static}, + {"result alloc", 0, result_alloc}, + {0, 0, 0} + }; + test_st user_tests[] ={ {"user_supplied_bug1", 0, user_supplied_bug1 }, {"user_supplied_bug2", 0, user_supplied_bug2 }, -// {"user_supplied_bug3", 0, user_supplied_bug3 }, + {"user_supplied_bug3", 0, user_supplied_bug3 }, {0, 0, 0} }; - if ((test_to_run && !strcmp(test_to_run, "block")) || !test_to_run) - { - fprintf(stderr, "\nBlock tests\n\n"); - for (x= 0; tests[x].function_name; x++) - { - if (wildcard) - if (strcmp(wildcard, tests[x].function_name)) - continue; - - memcached_st *memc; - memcached_return rc; - struct timeval start_time, end_time; - - memc= memcached_create(NULL); - assert(memc); - - if (tests[x].requires_flush) - memcached_flush(memc, 0); - - rc= memcached_server_push(memc, servers); - assert(rc == MEMCACHED_SUCCESS); - - unsigned int loop; - for (loop= 0; loop < memcached_server_list_count(servers); loop++) - { - assert(memc->hosts[loop].stack_responses == 0); - assert(memc->hosts[loop].fd == -1); - assert(memc->hosts[loop].cursor_active == 0); - } - fprintf(stderr, "Testing %s", tests[x].function_name); - gettimeofday(&start_time, NULL); - tests[x].function(memc); - gettimeofday(&end_time, NULL); - long int load_time= timedif(end_time, start_time); - fprintf(stderr, "\t\t\t\t\t %ld.%03ld [ ok ]\n", load_time / 1000, - load_time % 1000); - assert(memc); - memcached_free(memc); - } - } + collection_st collection[] ={ + {"block", 0, 0, tests}, + {"nonblock", pre_nonblock, 0, tests}, + {"nodelay", pre_nodelay, 0, tests}, + {"md5", pre_md5, 0, tests}, + {"crc", pre_crc, 0, tests}, + {"fnv1_64", pre_hash_fnv1_64, 0, tests}, + {"fnv1a_64", pre_hash_fnv1a_64, 0, tests}, + {"fnv1_32", pre_hash_fnv1_32, 0, tests}, + {"fnv1a_32", pre_hash_fnv1a_32, 0, tests}, + {"ketama", pre_hash_ketama, 0, tests}, + {"unix_socket", pre_unix_socket, 0, tests}, + {"unix_socket_nodelay", pre_nodelay, 0, tests}, + {"string", 0, 0, string_tests}, + {"result", 0, 0, result_tests}, + {"user", 0, 0, user_tests}, + {0, 0, 0, 0} + }; - if ((test_to_run && !strcmp(test_to_run, "nonblock")) || !test_to_run) + collection_st *next; + for (next= collection; next->name; next++) { - fprintf(stderr, "\nNonblock tests\n\n"); - for (x= 0; tests[x].function_name; x++) - { - if (wildcard) - if (strcmp(wildcard, tests[x].function_name)) - continue; - - memcached_st *memc; - memcached_return rc; - struct timeval start_time, end_time; + test_st *run; - memc= memcached_create(NULL); - assert(memc); + run= next->tests; - if (tests[x].requires_flush) - memcached_flush(memc, 0); - - rc= memcached_server_push(memc, servers); - assert(rc == MEMCACHED_SUCCESS); + if (collection_to_run && strcmp(collection_to_run, next->name)) + continue; - fprintf(stderr, "Testing %s", tests[x].function_name); - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL); - gettimeofday(&start_time, NULL); - tests[x].function(memc); - gettimeofday(&end_time, NULL); - long int load_time= timedif(end_time, start_time); - fprintf(stderr, "\t\t\t\t\t %ld.%03ld [ ok ]\n", load_time / 1000, - load_time % 1000); - assert(memc); - memcached_free(memc); - } - } + fprintf(stderr, "\n%s\n\n", next->name); - if ((test_to_run && !strcmp(test_to_run, "nodelay")) || !test_to_run) - { - fprintf(stderr, "\nTCP Nodelay tests\n\n"); - for (x= 0; tests[x].function_name; x++) + for (x= 0; run->name; run++) { - if (wildcard) - if (strcmp(wildcard, tests[x].function_name)) - continue; - - memcached_st *memc; - memcached_return rc; - struct timeval start_time, end_time; + if (wildcard && strcmp(wildcard, run->name)) + continue; - memc= memcached_create(NULL); - assert(memc); - - if (tests[x].requires_flush) - memcached_flush(memc, 0); - - rc= memcached_server_push(memc, servers); - assert(rc == MEMCACHED_SUCCESS); - - fprintf(stderr, "Testing %s", tests[x].function_name); - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL); - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, NULL); - gettimeofday(&start_time, NULL); - tests[x].function(memc); - gettimeofday(&end_time, NULL); - long int load_time= timedif(end_time, start_time); - fprintf(stderr, "\t\t\t\t\t %ld.%03ld [ ok ]\n", load_time / 1000, - load_time % 1000); - assert(memc); - memcached_free(memc); - } - } - - if ((test_to_run && !strcmp(test_to_run, "md5")) || !test_to_run) - { - fprintf(stderr, "\nMD5 Hashing\n\n"); - for (x= 0; tests[x].function_name; x++) - { - if (wildcard) - if (strcmp(wildcard, tests[x].function_name)) - continue; + fprintf(stderr, "Testing %s", run->name); memcached_st *memc; memcached_return rc; @@ -975,89 +1183,44 @@ int main(int argc, char *argv[]) memc= memcached_create(NULL); assert(memc); - if (tests[x].requires_flush) + if (run->requires_flush) memcached_flush(memc, 0); rc= memcached_server_push(memc, servers); assert(rc == MEMCACHED_SUCCESS); - fprintf(stderr, "Testing %s", tests[x].function_name); - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_MD5_HASHING, NULL); - gettimeofday(&start_time, NULL); - tests[x].function(memc); - gettimeofday(&end_time, NULL); - long int load_time= timedif(end_time, start_time); - fprintf(stderr, "\t\t\t\t\t %ld.%03ld [ ok ]\n", load_time / 1000, - load_time % 1000); - assert(memc); - memcached_free(memc); - } - } - - if ((test_to_run && !strcmp(test_to_run, "string")) || !test_to_run) - { - fprintf(stderr, "\nString tests (internal API)\n\n"); - for (x= 0; string_tests[x].function_name; x++) - { - if (wildcard) - if (strcmp(wildcard, string_tests[x].function_name)) - continue; - - memcached_st *memc; - memcached_return rc; - struct timeval start_time, end_time; - - memc= memcached_create(NULL); - assert(memc); - - if (tests[x].requires_flush) - memcached_flush(memc, 0); + unsigned int loop; + for (loop= 0; loop < memcached_server_list_count(servers); loop++) + { + assert(memc->hosts[loop].stack_responses == 0); + assert(memc->hosts[loop].fd == -1); + assert(memc->hosts[loop].cursor_active == 0); + } - rc= memcached_server_push(memc, servers); - assert(rc == MEMCACHED_SUCCESS); + if (next->pre) + { + memcached_return rc; + rc= next->pre(memc); + + if (rc != MEMCACHED_SUCCESS) + { + fprintf(stderr, "\t\t\t\t\t [ skipping ]\n"); + goto error; + } + } - fprintf(stderr, "Testing %s", string_tests[x].function_name); gettimeofday(&start_time, NULL); - string_tests[x].function(memc); + run->function(memc); gettimeofday(&end_time, NULL); long int load_time= timedif(end_time, start_time); fprintf(stderr, "\t\t\t\t\t %ld.%03ld [ ok ]\n", load_time / 1000, load_time % 1000); - assert(memc); - memcached_free(memc); - } - } - if ((test_to_run && !strcmp(test_to_run, "user")) || !test_to_run) - { - fprintf(stderr, "\nUser Supplied tests\n\n"); - for (x= 0; user_tests[x].function_name; x++) - { - if (wildcard) - if (strcmp(wildcard, user_tests[x].function_name)) - continue; + if (next->post) + (void)next->post(memc); - memcached_st *memc; - memcached_return rc; - struct timeval start_time, end_time; - - memc= memcached_create(NULL); - assert(memc); - - if (tests[x].requires_flush) - memcached_flush(memc, 0); - - rc= memcached_server_push(memc, servers); - assert(rc == MEMCACHED_SUCCESS); - - fprintf(stderr, "Testing %s", user_tests[x].function_name); - gettimeofday(&start_time, NULL); - user_tests[x].function(memc); - gettimeofday(&end_time, NULL); - long int load_time= timedif(end_time, start_time); - fprintf(stderr, "\t\t\t\t\t %ld.%03ld [ ok ]\n", load_time / 1000, - load_time % 1000); assert(memc); +error: memcached_free(memc); } }