e675975c2ec235e33a0f72411b74ff20b93add26
[m6w6/libmemcached] / tests / mem_functions.c
1 /* libMemcached Functions Test
2 * Copyright (C) 2006-2009 Brian Aker
3 * All rights reserved.
4 *
5 * Use and distribution licensed under the BSD license. See
6 * the COPYING file in the parent directory for full text.
7 */
8
9 /*
10 Sample test application.
11 */
12
13 #include "config.h"
14
15 #include <assert.h>
16 #include <stdio.h>
17 #include <stdint.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/time.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <signal.h>
24 #include <unistd.h>
25 #include <time.h>
26
27 #include "libmemcached/common.h"
28
29 #include <libtest/server.h>
30
31 #include "clients/generator.h"
32 #include "clients/execute.h"
33
34 #define SMALL_STRING_LEN 1024
35
36 #include <libtest/test.h>
37 #include "tests/parser.h"
38 #include "tests/string.h"
39 #include "tests/replication.h"
40 #include "tests/basic.h"
41 #include "tests/error_conditions.h"
42 #include "tests/print.h"
43
44
45 #ifdef HAVE_LIBMEMCACHEDUTIL
46 #include <pthread.h>
47 #include "libmemcached/memcached_util.h"
48 #endif
49
50 #include "hash_results.h"
51
52 #define GLOBAL_COUNT 10000
53 #define GLOBAL2_COUNT 100
54 #define SERVERS_TO_CREATE 5
55 static uint32_t global_count;
56
57 static pairs_st *global_pairs;
58 static const char *global_keys[GLOBAL_COUNT];
59 static size_t global_keys_length[GLOBAL_COUNT];
60
61 // Prototype
62 static test_return_t pre_binary(memcached_st *memc);
63
64
65 static test_return_t init_test(memcached_st *not_used)
66 {
67 memcached_st memc;
68 (void)not_used;
69
70 (void)memcached_create(&memc);
71 memcached_free(&memc);
72
73 return TEST_SUCCESS;
74 }
75
76 static test_return_t server_list_null_test(memcached_st *ptr)
77 {
78 memcached_server_st *server_list;
79 memcached_return_t rc;
80 (void)ptr;
81
82 server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, NULL);
83 test_true(server_list == NULL);
84
85 server_list= memcached_server_list_append_with_weight(NULL, "localhost", 0, 0, NULL);
86 test_true(server_list == NULL);
87
88 server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, &rc);
89 test_true(server_list == NULL);
90
91 return TEST_SUCCESS;
92 }
93
94 #define TEST_PORT_COUNT 7
95 in_port_t test_ports[TEST_PORT_COUNT];
96
97 static memcached_return_t server_display_function(const memcached_st *ptr,
98 const memcached_server_st *server,
99 void *context)
100 {
101 /* Do Nothing */
102 size_t bigger= *((size_t *)(context));
103 (void)ptr;
104 assert(bigger <= memcached_server_port(server));
105 *((size_t *)(context))= memcached_server_port(server);
106
107 return MEMCACHED_SUCCESS;
108 }
109
110 static memcached_return_t dump_server_information(const memcached_st *ptr,
111 const memcached_server_st *instance,
112 void *context)
113 {
114 /* Do Nothing */
115 FILE *stream= (FILE *)context;
116 (void)ptr;
117
118 fprintf(stream, "Memcached Server: %s %u Version %u.%u.%u\n",
119 memcached_server_name(instance),
120 memcached_server_port(instance),
121 instance->major_version,
122 instance->minor_version,
123 instance->micro_version);
124
125 return MEMCACHED_SUCCESS;
126 }
127
128 static test_return_t server_sort_test(memcached_st *ptr)
129 {
130 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
131
132 memcached_return_t rc;
133 memcached_server_fn callbacks[1];
134 memcached_st *local_memc;
135 (void)ptr;
136
137 local_memc= memcached_create(NULL);
138 test_true(local_memc);
139 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
140
141 for (size_t x= 0; x < TEST_PORT_COUNT; x++)
142 {
143 test_ports[x]= (in_port_t)random() % 64000;
144 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
145 test_true(memcached_server_count(local_memc) == x + 1);
146 #if 0 // Rewrite
147 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
148 #endif
149 test_true(rc == MEMCACHED_SUCCESS);
150 }
151
152 callbacks[0]= server_display_function;
153 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
154
155
156 memcached_free(local_memc);
157
158 return TEST_SUCCESS;
159 }
160
161 static test_return_t server_sort2_test(memcached_st *ptr)
162 {
163 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
164 memcached_return_t rc;
165 memcached_server_fn callbacks[1];
166 memcached_st *local_memc;
167 memcached_server_instance_st instance;
168 (void)ptr;
169
170 local_memc= memcached_create(NULL);
171 test_true(local_memc);
172 rc= memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
173 test_true(rc == MEMCACHED_SUCCESS);
174
175 rc= memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43043, 0);
176 test_true(rc == MEMCACHED_SUCCESS);
177 instance= memcached_server_instance_by_position(local_memc, 0);
178 test_true(memcached_server_port(instance) == 43043);
179
180 rc= memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43042, 0);
181 test_true(rc == MEMCACHED_SUCCESS);
182
183 instance= memcached_server_instance_by_position(local_memc, 0);
184 test_true(memcached_server_port(instance) == 43042);
185
186 instance= memcached_server_instance_by_position(local_memc, 1);
187 test_true(memcached_server_port(instance) == 43043);
188
189 callbacks[0]= server_display_function;
190 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
191
192
193 memcached_free(local_memc);
194
195 return TEST_SUCCESS;
196 }
197
198 static test_return_t memcached_server_remove_test(memcached_st *ptr)
199 {
200 memcached_return_t rc;
201 memcached_st local_memc;
202 memcached_st *memc;
203 memcached_server_st *servers;
204 memcached_server_fn callbacks[1];
205
206 const char *server_string= "localhost:4444, localhost:4445, localhost:4446, localhost:4447, localhost, memcache1.memcache.bk.sapo.pt:11211, memcache1.memcache.bk.sapo.pt:11212, memcache1.memcache.bk.sapo.pt:11213, memcache1.memcache.bk.sapo.pt:11214, memcache2.memcache.bk.sapo.pt:11211, memcache2.memcache.bk.sapo.pt:11212, memcache2.memcache.bk.sapo.pt:11213, memcache2.memcache.bk.sapo.pt:11214";
207 (void)ptr;
208
209 memc= memcached_create(&local_memc);
210
211 servers= memcached_servers_parse(server_string);
212
213 rc= memcached_server_push(memc, servers);
214 memcached_server_list_free(servers);
215
216 callbacks[0]= server_print_callback;
217 memcached_server_cursor(memc, callbacks, NULL, 1);
218
219 memcached_free(memc);
220
221 return TEST_SUCCESS;
222 }
223
224 static memcached_return_t server_display_unsort_function(const memcached_st *ptr,
225 const memcached_server_st *server,
226 void *context)
227 {
228 /* Do Nothing */
229 uint32_t x= *((uint32_t *)(context));
230 (void)ptr;
231
232 assert(test_ports[x] == server->port);
233 *((uint32_t *)(context))= ++x;
234
235 return MEMCACHED_SUCCESS;
236 }
237
238 static test_return_t server_unsort_test(memcached_st *ptr)
239 {
240 size_t counter= 0; /* Prime the value for the test_true in server_display_function */
241 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
242 memcached_return_t rc;
243 memcached_server_fn callbacks[1];
244 memcached_st *local_memc;
245 (void)ptr;
246
247 local_memc= memcached_create(NULL);
248 test_true(local_memc);
249
250 for (size_t x= 0; x < TEST_PORT_COUNT; x++)
251 {
252 test_ports[x]= (in_port_t)(random() % 64000);
253 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
254 test_true(memcached_server_count(local_memc) == x+1);
255 #if 0 // Rewrite
256 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
257 #endif
258 test_true(rc == MEMCACHED_SUCCESS);
259 }
260
261 callbacks[0]= server_display_unsort_function;
262 memcached_server_cursor(local_memc, callbacks, (void *)&counter, 1);
263
264 /* Now we sort old data! */
265 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
266 callbacks[0]= server_display_function;
267 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
268
269
270 memcached_free(local_memc);
271
272 return TEST_SUCCESS;
273 }
274
275 static test_return_t allocation_test(memcached_st *not_used)
276 {
277 (void)not_used;
278 memcached_st *memc;
279 memc= memcached_create(NULL);
280 test_true(memc);
281 memcached_free(memc);
282
283 return TEST_SUCCESS;
284 }
285
286 static test_return_t clone_test(memcached_st *memc)
287 {
288 /* All null? */
289 {
290 memcached_st *memc_clone;
291 memc_clone= memcached_clone(NULL, NULL);
292 test_true(memc_clone);
293 memcached_free(memc_clone);
294 }
295
296 /* Can we init from null? */
297 {
298 memcached_st *memc_clone;
299 memc_clone= memcached_clone(NULL, memc);
300 test_true(memc_clone);
301
302 { // Test allocators
303 test_true(memc_clone->allocators.free == memc->allocators.free);
304 test_true(memc_clone->allocators.malloc == memc->allocators.malloc);
305 test_true(memc_clone->allocators.realloc == memc->allocators.realloc);
306 test_true(memc_clone->allocators.calloc == memc->allocators.calloc);
307 }
308
309 test_true(memc_clone->connect_timeout == memc->connect_timeout);
310 test_true(memc_clone->delete_trigger == memc->delete_trigger);
311 test_true(memc_clone->distribution == memc->distribution);
312 { // Test all of the flags
313 test_true(memc_clone->flags.no_block == memc->flags.no_block);
314 test_true(memc_clone->flags.tcp_nodelay == memc->flags.tcp_nodelay);
315 test_true(memc_clone->flags.reuse_memory == memc->flags.reuse_memory);
316 test_true(memc_clone->flags.use_cache_lookups == memc->flags.use_cache_lookups);
317 test_true(memc_clone->flags.support_cas == memc->flags.support_cas);
318 test_true(memc_clone->flags.buffer_requests == memc->flags.buffer_requests);
319 test_true(memc_clone->flags.use_sort_hosts == memc->flags.use_sort_hosts);
320 test_true(memc_clone->flags.verify_key == memc->flags.verify_key);
321 test_true(memc_clone->flags.ketama_weighted == memc->flags.ketama_weighted);
322 test_true(memc_clone->flags.binary_protocol == memc->flags.binary_protocol);
323 test_true(memc_clone->flags.hash_with_prefix_key == memc->flags.hash_with_prefix_key);
324 test_true(memc_clone->flags.no_reply == memc->flags.no_reply);
325 test_true(memc_clone->flags.use_udp == memc->flags.use_udp);
326 test_true(memc_clone->flags.auto_eject_hosts == memc->flags.auto_eject_hosts);
327 test_true(memc_clone->flags.randomize_replica_read == memc->flags.randomize_replica_read);
328 }
329 test_true(memc_clone->get_key_failure == memc->get_key_failure);
330 test_true(hashkit_compare(&memc_clone->hashkit, &memc->hashkit));
331 test_true(hashkit_compare(&memc_clone->distribution_hashkit, &memc->distribution_hashkit));
332 test_true(memc_clone->io_bytes_watermark == memc->io_bytes_watermark);
333 test_true(memc_clone->io_msg_watermark == memc->io_msg_watermark);
334 test_true(memc_clone->io_key_prefetch == memc->io_key_prefetch);
335 test_true(memc_clone->on_cleanup == memc->on_cleanup);
336 test_true(memc_clone->on_clone == memc->on_clone);
337 test_true(memc_clone->poll_timeout == memc->poll_timeout);
338 test_true(memc_clone->rcv_timeout == memc->rcv_timeout);
339 test_true(memc_clone->recv_size == memc->recv_size);
340 test_true(memc_clone->retry_timeout == memc->retry_timeout);
341 test_true(memc_clone->send_size == memc->send_size);
342 test_true(memc_clone->server_failure_limit == memc->server_failure_limit);
343 test_true(memc_clone->snd_timeout == memc->snd_timeout);
344 test_true(memc_clone->user_data == memc->user_data);
345
346 memcached_free(memc_clone);
347 }
348
349 /* Can we init from struct? */
350 {
351 memcached_st declared_clone;
352 memcached_st *memc_clone;
353 memset(&declared_clone, 0 , sizeof(memcached_st));
354 memc_clone= memcached_clone(&declared_clone, NULL);
355 test_true(memc_clone);
356 memcached_free(memc_clone);
357 }
358
359 /* Can we init from struct? */
360 {
361 memcached_st declared_clone;
362 memcached_st *memc_clone;
363 memset(&declared_clone, 0 , sizeof(memcached_st));
364 memc_clone= memcached_clone(&declared_clone, memc);
365 test_true(memc_clone);
366 memcached_free(memc_clone);
367 }
368
369 return TEST_SUCCESS;
370 }
371
372 static test_return_t userdata_test(memcached_st *memc)
373 {
374 void* foo= NULL;
375 test_true(memcached_set_user_data(memc, foo) == NULL);
376 test_true(memcached_get_user_data(memc) == foo);
377 test_true(memcached_set_user_data(memc, NULL) == foo);
378
379 return TEST_SUCCESS;
380 }
381
382 static test_return_t connection_test(memcached_st *memc)
383 {
384 memcached_return_t rc;
385
386 rc= memcached_server_add_with_weight(memc, "localhost", 0, 0);
387 test_true(rc == MEMCACHED_SUCCESS);
388
389 return TEST_SUCCESS;
390 }
391
392 static test_return_t error_test(memcached_st *memc)
393 {
394 memcached_return_t rc;
395 uint32_t values[] = { 851992627U, 2337886783U, 3196981036U, 4001849190U,
396 982370485U, 1263635348U, 4242906218U, 3829656100U,
397 1891735253U, 334139633U, 2257084983U, 3088286104U,
398 13199785U, 2542027183U, 1097051614U, 199566778U,
399 2748246961U, 2465192557U, 1664094137U, 2405439045U,
400 1842224848U, 692413798U, 3479807801U, 919913813U,
401 4269430871U, 610793021U, 527273862U, 1437122909U,
402 2300930706U, 2943759320U, 674306647U, 2400528935U,
403 54481931U, 4186304426U, 1741088401U, 2979625118U,
404 4159057246U, 3425930182U, 2593724503U, 1868899624U,
405 1769812374U, 2302537950U, 1110330676U, 3365377466U,
406 1336171666U, 3365377466U };
407
408 // You have updated the memcache_error messages but not updated docs/tests.
409 for (rc= MEMCACHED_SUCCESS; rc < MEMCACHED_MAXIMUM_RETURN; rc++)
410 {
411 uint32_t hash_val;
412 const char *msg= memcached_strerror(memc, rc);
413 hash_val= memcached_generate_hash_value(msg, strlen(msg),
414 MEMCACHED_HASH_JENKINS);
415 if (values[rc] != hash_val)
416 {
417 fprintf(stderr, "\n\nYou have updated memcached_return_t without updating the error_test\n");
418 fprintf(stderr, "%u, %s, (%u)\n\n", (uint32_t)rc, memcached_strerror(memc, rc), hash_val);
419 }
420 test_true(values[rc] == hash_val);
421 }
422 test_true(MEMCACHED_MAXIMUM_RETURN == 45);
423
424 return TEST_SUCCESS;
425 }
426
427 static test_return_t set_test(memcached_st *memc)
428 {
429 memcached_return_t rc;
430 const char *key= "foo";
431 const char *value= "when we sanitize";
432
433 rc= memcached_set(memc, key, strlen(key),
434 value, strlen(value),
435 (time_t)0, (uint32_t)0);
436 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
437
438 return TEST_SUCCESS;
439 }
440
441 static test_return_t append_test(memcached_st *memc)
442 {
443 memcached_return_t rc;
444 const char *key= "fig";
445 const char *in_value= "we";
446 char *out_value= NULL;
447 size_t value_length;
448 uint32_t flags;
449
450 rc= memcached_flush(memc, 0);
451 test_true(rc == MEMCACHED_SUCCESS);
452
453 rc= memcached_set(memc, key, strlen(key),
454 in_value, strlen(in_value),
455 (time_t)0, (uint32_t)0);
456 test_true(rc == MEMCACHED_SUCCESS);
457
458 rc= memcached_append(memc, key, strlen(key),
459 " the", strlen(" the"),
460 (time_t)0, (uint32_t)0);
461 test_true(rc == MEMCACHED_SUCCESS);
462
463 rc= memcached_append(memc, key, strlen(key),
464 " people", strlen(" people"),
465 (time_t)0, (uint32_t)0);
466 test_true(rc == MEMCACHED_SUCCESS);
467
468 out_value= memcached_get(memc, key, strlen(key),
469 &value_length, &flags, &rc);
470 test_true(!memcmp(out_value, "we the people", strlen("we the people")));
471 test_true(strlen("we the people") == value_length);
472 test_true(rc == MEMCACHED_SUCCESS);
473 free(out_value);
474
475 return TEST_SUCCESS;
476 }
477
478 static test_return_t append_binary_test(memcached_st *memc)
479 {
480 memcached_return_t rc;
481 const char *key= "numbers";
482 uint32_t store_list[] = { 23, 56, 499, 98, 32847, 0 };
483 uint32_t *value;
484 size_t value_length;
485 uint32_t flags;
486 uint32_t x;
487
488 rc= memcached_flush(memc, 0);
489 test_true(rc == MEMCACHED_SUCCESS);
490
491 rc= memcached_set(memc,
492 key, strlen(key),
493 NULL, 0,
494 (time_t)0, (uint32_t)0);
495 test_true(rc == MEMCACHED_SUCCESS);
496
497 for (x= 0; store_list[x] ; x++)
498 {
499 rc= memcached_append(memc,
500 key, strlen(key),
501 (char *)&store_list[x], sizeof(uint32_t),
502 (time_t)0, (uint32_t)0);
503 test_true(rc == MEMCACHED_SUCCESS);
504 }
505
506 value= (uint32_t *)memcached_get(memc, key, strlen(key),
507 &value_length, &flags, &rc);
508 test_true((value_length == (sizeof(uint32_t) * x)));
509 test_true(rc == MEMCACHED_SUCCESS);
510
511 for (uint32_t counter= x, *ptr= value; counter; counter--)
512 {
513 test_true(*ptr == store_list[x - counter]);
514 ptr++;
515 }
516 free(value);
517
518 return TEST_SUCCESS;
519 }
520
521 static test_return_t cas2_test(memcached_st *memc)
522 {
523 memcached_return_t rc;
524 const char *keys[]= {"fudge", "son", "food"};
525 size_t key_length[]= {5, 3, 4};
526 const char *value= "we the people";
527 size_t value_length= strlen("we the people");
528 unsigned int x;
529 memcached_result_st results_obj;
530 memcached_result_st *results;
531 unsigned int set= 1;
532
533 rc= memcached_flush(memc, 0);
534 test_true(rc == MEMCACHED_SUCCESS);
535
536 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
537
538 for (x= 0; x < 3; x++)
539 {
540 rc= memcached_set(memc, keys[x], key_length[x],
541 keys[x], key_length[x],
542 (time_t)50, (uint32_t)9);
543 test_true(rc == MEMCACHED_SUCCESS);
544 }
545
546 rc= memcached_mget(memc, keys, key_length, 3);
547
548 results= memcached_result_create(memc, &results_obj);
549
550 results= memcached_fetch_result(memc, &results_obj, &rc);
551 test_true(results);
552 test_true(results->item_cas);
553 test_true(rc == MEMCACHED_SUCCESS);
554 test_true(memcached_result_cas(results));
555
556 test_true(!memcmp(value, "we the people", strlen("we the people")));
557 test_true(strlen("we the people") == value_length);
558 test_true(rc == MEMCACHED_SUCCESS);
559
560 memcached_result_free(&results_obj);
561
562 return TEST_SUCCESS;
563 }
564
565 static test_return_t cas_test(memcached_st *memc)
566 {
567 memcached_return_t rc;
568 const char *key= "fun";
569 size_t key_length= strlen(key);
570 const char *value= "we the people";
571 const char* keys[2] = { key, NULL };
572 size_t keylengths[2] = { strlen(key), 0 };
573 size_t value_length= strlen(value);
574 const char *value2= "change the value";
575 size_t value2_length= strlen(value2);
576
577 memcached_result_st results_obj;
578 memcached_result_st *results;
579 unsigned int set= 1;
580
581 rc= memcached_flush(memc, 0);
582 test_true(rc == MEMCACHED_SUCCESS);
583
584 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
585
586 rc= memcached_set(memc, key, strlen(key),
587 value, strlen(value),
588 (time_t)0, (uint32_t)0);
589 test_true(rc == MEMCACHED_SUCCESS);
590
591 rc= memcached_mget(memc, keys, keylengths, 1);
592
593 results= memcached_result_create(memc, &results_obj);
594
595 results= memcached_fetch_result(memc, &results_obj, &rc);
596 test_true(results);
597 test_true(rc == MEMCACHED_SUCCESS);
598 test_true(memcached_result_cas(results));
599 test_true(!memcmp(value, memcached_result_value(results), value_length));
600 test_true(strlen(memcached_result_value(results)) == value_length);
601 test_true(rc == MEMCACHED_SUCCESS);
602 uint64_t cas = memcached_result_cas(results);
603
604 #if 0
605 results= memcached_fetch_result(memc, &results_obj, &rc);
606 test_true(rc == MEMCACHED_END);
607 test_true(results == NULL);
608 #endif
609
610 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
611 test_true(rc == MEMCACHED_SUCCESS);
612
613 /*
614 * The item will have a new cas value, so try to set it again with the old
615 * value. This should fail!
616 */
617 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
618 test_true(rc == MEMCACHED_DATA_EXISTS);
619
620 memcached_result_free(&results_obj);
621
622 return TEST_SUCCESS;
623 }
624
625 static test_return_t prepend_test(memcached_st *memc)
626 {
627 memcached_return_t rc;
628 const char *key= "fig";
629 const char *value= "people";
630 char *out_value= NULL;
631 size_t value_length;
632 uint32_t flags;
633
634 rc= memcached_flush(memc, 0);
635 test_true(rc == MEMCACHED_SUCCESS);
636
637 rc= memcached_set(memc, key, strlen(key),
638 value, strlen(value),
639 (time_t)0, (uint32_t)0);
640 test_true(rc == MEMCACHED_SUCCESS);
641
642 rc= memcached_prepend(memc, key, strlen(key),
643 "the ", strlen("the "),
644 (time_t)0, (uint32_t)0);
645 test_true(rc == MEMCACHED_SUCCESS);
646
647 rc= memcached_prepend(memc, key, strlen(key),
648 "we ", strlen("we "),
649 (time_t)0, (uint32_t)0);
650 test_true(rc == MEMCACHED_SUCCESS);
651
652 out_value= memcached_get(memc, key, strlen(key),
653 &value_length, &flags, &rc);
654 test_true(!memcmp(out_value, "we the people", strlen("we the people")));
655 test_true(strlen("we the people") == value_length);
656 test_true(rc == MEMCACHED_SUCCESS);
657 free(out_value);
658
659 return TEST_SUCCESS;
660 }
661
662 /*
663 Set the value, then quit to make sure it is flushed.
664 Come back in and test that add fails.
665 */
666 static test_return_t add_test(memcached_st *memc)
667 {
668 memcached_return_t rc;
669 const char *key= "foo";
670 const char *value= "when we sanitize";
671 unsigned long long setting_value;
672
673 setting_value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
674
675 rc= memcached_set(memc, key, strlen(key),
676 value, strlen(value),
677 (time_t)0, (uint32_t)0);
678 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
679 memcached_quit(memc);
680 rc= memcached_add(memc, key, strlen(key),
681 value, strlen(value),
682 (time_t)0, (uint32_t)0);
683
684 /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */
685 if (setting_value)
686 {
687 test_true(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_STORED);
688 }
689 else
690 {
691 test_true(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_DATA_EXISTS);
692 }
693
694 return TEST_SUCCESS;
695 }
696
697 /*
698 ** There was a problem of leaking filedescriptors in the initial release
699 ** of MacOSX 10.5. This test case triggers the problem. On some Solaris
700 ** systems it seems that the kernel is slow on reclaiming the resources
701 ** because the connects starts to time out (the test doesn't do much
702 ** anyway, so just loop 10 iterations)
703 */
704 static test_return_t add_wrapper(memcached_st *memc)
705 {
706 unsigned int max= 10000;
707 #ifdef __sun
708 max= 10;
709 #endif
710 #ifdef __APPLE__
711 max= 10;
712 #endif
713
714 for (uint32_t x= 0; x < max; x++)
715 add_test(memc);
716
717 return TEST_SUCCESS;
718 }
719
720 static test_return_t replace_test(memcached_st *memc)
721 {
722 memcached_return_t rc;
723 const char *key= "foo";
724 const char *value= "when we sanitize";
725 const char *original= "first we insert some data";
726
727 rc= memcached_set(memc, key, strlen(key),
728 original, strlen(original),
729 (time_t)0, (uint32_t)0);
730 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
731
732 rc= memcached_replace(memc, key, strlen(key),
733 value, strlen(value),
734 (time_t)0, (uint32_t)0);
735 test_true(rc == MEMCACHED_SUCCESS);
736
737 return TEST_SUCCESS;
738 }
739
740 static test_return_t delete_test(memcached_st *memc)
741 {
742 memcached_return_t rc;
743 const char *key= "foo";
744 const char *value= "when we sanitize";
745
746 rc= memcached_set(memc, key, strlen(key),
747 value, strlen(value),
748 (time_t)0, (uint32_t)0);
749 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
750
751 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
752 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
753
754 return TEST_SUCCESS;
755 }
756
757 static test_return_t flush_test(memcached_st *memc)
758 {
759 memcached_return_t rc;
760
761 rc= memcached_flush(memc, 0);
762 test_true(rc == MEMCACHED_SUCCESS);
763
764 return TEST_SUCCESS;
765 }
766
767 static memcached_return_t server_function(const memcached_st *ptr,
768 const memcached_server_st *server,
769 void *context)
770 {
771 (void)ptr; (void)server; (void)context;
772 /* Do Nothing */
773
774 return MEMCACHED_SUCCESS;
775 }
776
777 static test_return_t memcached_server_cursor_test(memcached_st *memc)
778 {
779 char context[10];
780 strncpy(context, "foo bad", sizeof(context));
781 memcached_server_fn callbacks[1];
782
783 callbacks[0]= server_function;
784 memcached_server_cursor(memc, callbacks, context, 1);
785 return TEST_SUCCESS;
786 }
787
788 static test_return_t bad_key_test(memcached_st *memc)
789 {
790 memcached_return_t rc;
791 const char *key= "foo bad";
792 char *string;
793 size_t string_length;
794 uint32_t flags;
795 memcached_st *memc_clone;
796 unsigned int set= 1;
797 size_t max_keylen= 0xffff;
798
799 // Just skip if we are in binary mode.
800 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL))
801 return TEST_SKIPPED;
802
803 memc_clone= memcached_clone(NULL, memc);
804 test_true(memc_clone);
805
806 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
807 test_true(rc == MEMCACHED_SUCCESS);
808
809 /* All keys are valid in the binary protocol (except for length) */
810 if (memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 0)
811 {
812 string= memcached_get(memc_clone, key, strlen(key),
813 &string_length, &flags, &rc);
814 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
815 test_true(string_length == 0);
816 test_true(!string);
817
818 set= 0;
819 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
820 test_true(rc == MEMCACHED_SUCCESS);
821 string= memcached_get(memc_clone, key, strlen(key),
822 &string_length, &flags, &rc);
823 test_true(rc == MEMCACHED_NOTFOUND);
824 test_true(string_length == 0);
825 test_true(!string);
826
827 /* Test multi key for bad keys */
828 const char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
829 size_t key_lengths[] = { 7, 7, 7 };
830 set= 1;
831 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
832 test_true(rc == MEMCACHED_SUCCESS);
833
834 rc= memcached_mget(memc_clone, keys, key_lengths, 3);
835 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
836
837 rc= memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1);
838 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
839
840 max_keylen= 250;
841
842 /* The following test should be moved to the end of this function when the
843 memcached server is updated to allow max size length of the keys in the
844 binary protocol
845 */
846 rc= memcached_callback_set(memc_clone, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
847 test_true(rc == MEMCACHED_SUCCESS);
848
849 char *longkey= (char *)malloc(max_keylen + 1);
850 if (longkey != NULL)
851 {
852 memset(longkey, 'a', max_keylen + 1);
853 string= memcached_get(memc_clone, longkey, max_keylen,
854 &string_length, &flags, &rc);
855 test_true(rc == MEMCACHED_NOTFOUND);
856 test_true(string_length == 0);
857 test_true(!string);
858
859 string= memcached_get(memc_clone, longkey, max_keylen + 1,
860 &string_length, &flags, &rc);
861 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
862 test_true(string_length == 0);
863 test_true(!string);
864
865 free(longkey);
866 }
867 }
868
869 /* Make sure zero length keys are marked as bad */
870 set= 1;
871 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
872 test_true(rc == MEMCACHED_SUCCESS);
873 string= memcached_get(memc_clone, key, 0,
874 &string_length, &flags, &rc);
875 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
876 test_true(string_length == 0);
877 test_true(!string);
878
879 memcached_free(memc_clone);
880
881 return TEST_SUCCESS;
882 }
883
884 #define READ_THROUGH_VALUE "set for me"
885 static memcached_return_t read_through_trigger(memcached_st *memc,
886 char *key,
887 size_t key_length,
888 memcached_result_st *result)
889 {
890 (void)memc;(void)key;(void)key_length;
891 return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE));
892 }
893
894 static test_return_t read_through(memcached_st *memc)
895 {
896 memcached_return_t rc;
897 const char *key= "foo";
898 char *string;
899 size_t string_length;
900 uint32_t flags;
901 memcached_trigger_key_fn cb= (memcached_trigger_key_fn)read_through_trigger;
902
903 string= memcached_get(memc, key, strlen(key),
904 &string_length, &flags, &rc);
905
906 test_true(rc == MEMCACHED_NOTFOUND);
907 test_false(string_length);
908 test_false(string);
909
910 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE,
911 *(void **)&cb);
912 test_true(rc == MEMCACHED_SUCCESS);
913
914 string= memcached_get(memc, key, strlen(key),
915 &string_length, &flags, &rc);
916
917 test_true(rc == MEMCACHED_SUCCESS);
918 test_true(string_length == strlen(READ_THROUGH_VALUE));
919 test_strcmp(READ_THROUGH_VALUE, string);
920 free(string);
921
922 string= memcached_get(memc, key, strlen(key),
923 &string_length, &flags, &rc);
924
925 test_true(rc == MEMCACHED_SUCCESS);
926 test_true(string_length == strlen(READ_THROUGH_VALUE));
927 test_true(!strcmp(READ_THROUGH_VALUE, string));
928 free(string);
929
930 return TEST_SUCCESS;
931 }
932
933 static memcached_return_t delete_trigger(memcached_st *ptr,
934 const char *key,
935 size_t key_length)
936 {
937 (void)ptr;(void)key_length;
938 assert(key);
939
940 return MEMCACHED_SUCCESS;
941 }
942
943 static test_return_t delete_through(memcached_st *memc)
944 {
945 memcached_trigger_delete_key_fn callback;
946 memcached_return_t rc;
947
948 callback= (memcached_trigger_delete_key_fn)delete_trigger;
949
950 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, *(void**)&callback);
951 test_true(rc == MEMCACHED_SUCCESS);
952
953 return TEST_SUCCESS;
954 }
955
956 static test_return_t get_test(memcached_st *memc)
957 {
958 memcached_return_t rc;
959 const char *key= "foo";
960 char *string;
961 size_t string_length;
962 uint32_t flags;
963
964 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
965 test_true(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND);
966
967 string= memcached_get(memc, key, strlen(key),
968 &string_length, &flags, &rc);
969
970 test_true(rc == MEMCACHED_NOTFOUND);
971 test_false(string_length);
972 test_false(string);
973
974 return TEST_SUCCESS;
975 }
976
977 static test_return_t get_test2(memcached_st *memc)
978 {
979 memcached_return_t rc;
980 const char *key= "foo";
981 const char *value= "when we sanitize";
982 char *string;
983 size_t string_length;
984 uint32_t flags;
985
986 rc= memcached_set(memc, key, strlen(key),
987 value, strlen(value),
988 (time_t)0, (uint32_t)0);
989 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
990
991 string= memcached_get(memc, key, strlen(key),
992 &string_length, &flags, &rc);
993
994 test_true(string);
995 test_true(rc == MEMCACHED_SUCCESS);
996 test_true(string_length == strlen(value));
997 test_true(!memcmp(string, value, string_length));
998
999 free(string);
1000
1001 return TEST_SUCCESS;
1002 }
1003
1004 static test_return_t set_test2(memcached_st *memc)
1005 {
1006 memcached_return_t rc;
1007 const char *key= "foo";
1008 const char *value= "train in the brain";
1009 size_t value_length= strlen(value);
1010 unsigned int x;
1011
1012 for (x= 0; x < 10; x++)
1013 {
1014 rc= memcached_set(memc, key, strlen(key),
1015 value, value_length,
1016 (time_t)0, (uint32_t)0);
1017 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1018 }
1019
1020 return TEST_SUCCESS;
1021 }
1022
1023 static test_return_t set_test3(memcached_st *memc)
1024 {
1025 memcached_return_t rc;
1026 char *value;
1027 size_t value_length= 8191;
1028 unsigned int x;
1029
1030 value = (char*)malloc(value_length);
1031 test_true(value);
1032
1033 for (x= 0; x < value_length; x++)
1034 value[x] = (char) (x % 127);
1035
1036 /* The dump test relies on there being at least 32 items in memcached */
1037 for (x= 0; x < 32; x++)
1038 {
1039 char key[16];
1040
1041 snprintf(key, sizeof(key), "foo%u", x);
1042
1043 rc= memcached_set(memc, key, strlen(key),
1044 value, value_length,
1045 (time_t)0, (uint32_t)0);
1046 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1047 }
1048
1049 free(value);
1050
1051 return TEST_SUCCESS;
1052 }
1053
1054 static test_return_t get_test3(memcached_st *memc)
1055 {
1056 memcached_return_t rc;
1057 const char *key= "foo";
1058 char *value;
1059 size_t value_length= 8191;
1060 char *string;
1061 size_t string_length;
1062 uint32_t flags;
1063 uint32_t x;
1064
1065 value = (char*)malloc(value_length);
1066 test_true(value);
1067
1068 for (x= 0; x < value_length; x++)
1069 value[x] = (char) (x % 127);
1070
1071 rc= memcached_set(memc, key, strlen(key),
1072 value, value_length,
1073 (time_t)0, (uint32_t)0);
1074 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1075
1076 string= memcached_get(memc, key, strlen(key),
1077 &string_length, &flags, &rc);
1078
1079 test_true(rc == MEMCACHED_SUCCESS);
1080 test_true(string);
1081 test_true(string_length == value_length);
1082 test_true(!memcmp(string, value, string_length));
1083
1084 free(string);
1085 free(value);
1086
1087 return TEST_SUCCESS;
1088 }
1089
1090 static test_return_t get_test4(memcached_st *memc)
1091 {
1092 memcached_return_t rc;
1093 const char *key= "foo";
1094 char *value;
1095 size_t value_length= 8191;
1096 char *string;
1097 size_t string_length;
1098 uint32_t flags;
1099 uint32_t x;
1100
1101 value = (char*)malloc(value_length);
1102 test_true(value);
1103
1104 for (x= 0; x < value_length; x++)
1105 value[x] = (char) (x % 127);
1106
1107 rc= memcached_set(memc, key, strlen(key),
1108 value, value_length,
1109 (time_t)0, (uint32_t)0);
1110 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1111
1112 for (x= 0; x < 10; x++)
1113 {
1114 string= memcached_get(memc, key, strlen(key),
1115 &string_length, &flags, &rc);
1116
1117 test_true(rc == MEMCACHED_SUCCESS);
1118 test_true(string);
1119 test_true(string_length == value_length);
1120 test_true(!memcmp(string, value, string_length));
1121 free(string);
1122 }
1123
1124 free(value);
1125
1126 return TEST_SUCCESS;
1127 }
1128
1129 /*
1130 * This test verifies that memcached_read_one_response doesn't try to
1131 * dereference a NIL-pointer if you issue a multi-get and don't read out all
1132 * responses before you execute a storage command.
1133 */
1134 static test_return_t get_test5(memcached_st *memc)
1135 {
1136 /*
1137 ** Request the same key twice, to ensure that we hash to the same server
1138 ** (so that we have multiple response values queued up) ;-)
1139 */
1140 const char *keys[]= { "key", "key" };
1141 size_t lengths[]= { 3, 3 };
1142 uint32_t flags;
1143 size_t rlen;
1144
1145 memcached_return_t rc= memcached_set(memc, keys[0], lengths[0],
1146 keys[0], lengths[0], 0, 0);
1147 test_true(rc == MEMCACHED_SUCCESS);
1148 rc= memcached_mget(memc, keys, lengths, 2);
1149
1150 memcached_result_st results_obj;
1151 memcached_result_st *results;
1152 results=memcached_result_create(memc, &results_obj);
1153 test_true(results);
1154 results=memcached_fetch_result(memc, &results_obj, &rc);
1155 test_true(results);
1156 memcached_result_free(&results_obj);
1157
1158 /* Don't read out the second result, but issue a set instead.. */
1159 rc= memcached_set(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0);
1160 test_true(rc == MEMCACHED_SUCCESS);
1161
1162 char *val= memcached_get_by_key(memc, keys[0], lengths[0], "yek", 3,
1163 &rlen, &flags, &rc);
1164 test_true(val == NULL);
1165 test_true(rc == MEMCACHED_NOTFOUND);
1166 val= memcached_get(memc, keys[0], lengths[0], &rlen, &flags, &rc);
1167 test_true(val != NULL);
1168 test_true(rc == MEMCACHED_SUCCESS);
1169 free(val);
1170
1171 return TEST_SUCCESS;
1172 }
1173
1174 static test_return_t mget_end(memcached_st *memc)
1175 {
1176 const char *keys[]= { "foo", "foo2" };
1177 size_t lengths[]= { 3, 4 };
1178 const char *values[]= { "fjord", "41" };
1179
1180 memcached_return_t rc;
1181
1182 // Set foo and foo2
1183 for (int i= 0; i < 2; i++)
1184 {
1185 rc= memcached_set(memc, keys[i], lengths[i], values[i], strlen(values[i]),
1186 (time_t)0, (uint32_t)0);
1187 test_true(rc == MEMCACHED_SUCCESS);
1188 }
1189
1190 char *string;
1191 size_t string_length;
1192 uint32_t flags;
1193
1194 // retrieve both via mget
1195 rc= memcached_mget(memc, keys, lengths, 2);
1196 test_true(rc == MEMCACHED_SUCCESS);
1197
1198 char key[MEMCACHED_MAX_KEY];
1199 size_t key_length;
1200
1201 // this should get both
1202 for (int i = 0; i < 2; i++)
1203 {
1204 string= memcached_fetch(memc, key, &key_length, &string_length,
1205 &flags, &rc);
1206 test_true(rc == MEMCACHED_SUCCESS);
1207 int val = 0;
1208 if (key_length == 4)
1209 val= 1;
1210 test_true(string_length == strlen(values[val]));
1211 test_true(strncmp(values[val], string, string_length) == 0);
1212 free(string);
1213 }
1214
1215 // this should indicate end
1216 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1217 test_true(rc == MEMCACHED_END);
1218
1219 // now get just one
1220 rc= memcached_mget(memc, keys, lengths, 1);
1221 test_true(rc == MEMCACHED_SUCCESS);
1222
1223 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1224 test_true(key_length == lengths[0]);
1225 test_true(strncmp(keys[0], key, key_length) == 0);
1226 test_true(string_length == strlen(values[0]));
1227 test_true(strncmp(values[0], string, string_length) == 0);
1228 test_true(rc == MEMCACHED_SUCCESS);
1229 free(string);
1230
1231 // this should indicate end
1232 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1233 test_true(rc == MEMCACHED_END);
1234
1235 return TEST_SUCCESS;
1236 }
1237
1238 /* Do not copy the style of this code, I just access hosts to testthis function */
1239 static test_return_t stats_servername_test(memcached_st *memc)
1240 {
1241 memcached_return_t rc;
1242 memcached_stat_st memc_stat;
1243 memcached_server_instance_st instance=
1244 memcached_server_instance_by_position(memc, 0);
1245
1246 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
1247 if (memcached_get_sasl_callbacks(memc) != NULL)
1248 return TEST_SKIPPED;
1249 #endif
1250 rc= memcached_stat_servername(&memc_stat, NULL,
1251 memcached_server_name(instance),
1252 memcached_server_port(instance));
1253
1254 return TEST_SUCCESS;
1255 }
1256
1257 static test_return_t increment_test(memcached_st *memc)
1258 {
1259 uint64_t new_number;
1260 memcached_return_t rc;
1261 const char *key= "number";
1262 const char *value= "0";
1263
1264 rc= memcached_set(memc, key, strlen(key),
1265 value, strlen(value),
1266 (time_t)0, (uint32_t)0);
1267 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1268
1269 rc= memcached_increment(memc, key, strlen(key),
1270 1, &new_number);
1271 test_true(rc == MEMCACHED_SUCCESS);
1272 test_true(new_number == 1);
1273
1274 rc= memcached_increment(memc, key, strlen(key),
1275 1, &new_number);
1276 test_true(rc == MEMCACHED_SUCCESS);
1277 test_true(new_number == 2);
1278
1279 return TEST_SUCCESS;
1280 }
1281
1282 static test_return_t increment_with_initial_test(memcached_st *memc)
1283 {
1284 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1285 {
1286 uint64_t new_number;
1287 memcached_return_t rc;
1288 const char *key= "number";
1289 uint64_t initial= 0;
1290
1291 rc= memcached_increment_with_initial(memc, key, strlen(key),
1292 1, initial, 0, &new_number);
1293 test_true(rc == MEMCACHED_SUCCESS);
1294 test_true(new_number == initial);
1295
1296 rc= memcached_increment_with_initial(memc, key, strlen(key),
1297 1, initial, 0, &new_number);
1298 test_true(rc == MEMCACHED_SUCCESS);
1299 test_true(new_number == (initial + 1));
1300 }
1301 return TEST_SUCCESS;
1302 }
1303
1304 static test_return_t decrement_test(memcached_st *memc)
1305 {
1306 uint64_t new_number;
1307 memcached_return_t rc;
1308 const char *key= "number";
1309 const char *value= "3";
1310
1311 rc= memcached_set(memc, key, strlen(key),
1312 value, strlen(value),
1313 (time_t)0, (uint32_t)0);
1314 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1315
1316 rc= memcached_decrement(memc, key, strlen(key),
1317 1, &new_number);
1318 test_true(rc == MEMCACHED_SUCCESS);
1319 test_true(new_number == 2);
1320
1321 rc= memcached_decrement(memc, key, strlen(key),
1322 1, &new_number);
1323 test_true(rc == MEMCACHED_SUCCESS);
1324 test_true(new_number == 1);
1325
1326 return TEST_SUCCESS;
1327 }
1328
1329 static test_return_t decrement_with_initial_test(memcached_st *memc)
1330 {
1331 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1332 {
1333 uint64_t new_number;
1334 memcached_return_t rc;
1335 const char *key= "number";
1336 uint64_t initial= 3;
1337
1338 rc= memcached_decrement_with_initial(memc, key, strlen(key),
1339 1, initial, 0, &new_number);
1340 test_true(rc == MEMCACHED_SUCCESS);
1341 test_true(new_number == initial);
1342
1343 rc= memcached_decrement_with_initial(memc, key, strlen(key),
1344 1, initial, 0, &new_number);
1345 test_true(rc == MEMCACHED_SUCCESS);
1346 test_true(new_number == (initial - 1));
1347 }
1348 return TEST_SUCCESS;
1349 }
1350
1351 static test_return_t increment_by_key_test(memcached_st *memc)
1352 {
1353 uint64_t new_number;
1354 memcached_return_t rc;
1355 const char *master_key= "foo";
1356 const char *key= "number";
1357 const char *value= "0";
1358
1359 rc= memcached_set_by_key(memc, master_key, strlen(master_key),
1360 key, strlen(key),
1361 value, strlen(value),
1362 (time_t)0, (uint32_t)0);
1363 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1364
1365 rc= memcached_increment_by_key(memc, master_key, strlen(master_key), key, strlen(key),
1366 1, &new_number);
1367 test_true(rc == MEMCACHED_SUCCESS);
1368 test_true(new_number == 1);
1369
1370 rc= memcached_increment_by_key(memc, master_key, strlen(master_key), key, strlen(key),
1371 1, &new_number);
1372 test_true(rc == MEMCACHED_SUCCESS);
1373 test_true(new_number == 2);
1374
1375 return TEST_SUCCESS;
1376 }
1377
1378 static test_return_t increment_with_initial_by_key_test(memcached_st *memc)
1379 {
1380 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1381 {
1382 uint64_t new_number;
1383 memcached_return_t rc;
1384 const char *master_key= "foo";
1385 const char *key= "number";
1386 uint64_t initial= 0;
1387
1388 rc= memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1389 key, strlen(key),
1390 1, initial, 0, &new_number);
1391 test_true(rc == MEMCACHED_SUCCESS);
1392 test_true(new_number == initial);
1393
1394 rc= memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1395 key, strlen(key),
1396 1, initial, 0, &new_number);
1397 test_true(rc == MEMCACHED_SUCCESS);
1398 test_true(new_number == (initial + 1));
1399 }
1400 return TEST_SUCCESS;
1401 }
1402
1403 static test_return_t decrement_by_key_test(memcached_st *memc)
1404 {
1405 uint64_t new_number;
1406 memcached_return_t rc;
1407 const char *master_key= "foo";
1408 const char *key= "number";
1409 const char *value= "3";
1410
1411 rc= memcached_set_by_key(memc, master_key, strlen(master_key),
1412 key, strlen(key),
1413 value, strlen(value),
1414 (time_t)0, (uint32_t)0);
1415 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1416
1417 rc= memcached_decrement_by_key(memc, master_key, strlen(master_key),
1418 key, strlen(key),
1419 1, &new_number);
1420 test_true(rc == MEMCACHED_SUCCESS);
1421 test_true(new_number == 2);
1422
1423 rc= memcached_decrement_by_key(memc, master_key, strlen(master_key),
1424 key, strlen(key),
1425 1, &new_number);
1426 test_true(rc == MEMCACHED_SUCCESS);
1427 test_true(new_number == 1);
1428
1429 return TEST_SUCCESS;
1430 }
1431
1432 static test_return_t decrement_with_initial_by_key_test(memcached_st *memc)
1433 {
1434 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1435 {
1436 uint64_t new_number;
1437 memcached_return_t rc;
1438 const char *master_key= "foo";
1439 const char *key= "number";
1440 uint64_t initial= 3;
1441
1442 rc= memcached_decrement_with_initial_by_key(memc, master_key, strlen(master_key),
1443 key, strlen(key),
1444 1, initial, 0, &new_number);
1445 test_true(rc == MEMCACHED_SUCCESS);
1446 test_true(new_number == initial);
1447
1448 rc= memcached_decrement_with_initial_by_key(memc, master_key, strlen(master_key),
1449 key, strlen(key),
1450 1, initial, 0, &new_number);
1451 test_true(rc == MEMCACHED_SUCCESS);
1452 test_true(new_number == (initial - 1));
1453 }
1454 return TEST_SUCCESS;
1455 }
1456
1457 static test_return_t quit_test(memcached_st *memc)
1458 {
1459 memcached_return_t rc;
1460 const char *key= "fudge";
1461 const char *value= "sanford and sun";
1462
1463 rc= memcached_set(memc, key, strlen(key),
1464 value, strlen(value),
1465 (time_t)10, (uint32_t)3);
1466 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1467 memcached_quit(memc);
1468
1469 rc= memcached_set(memc, key, strlen(key),
1470 value, strlen(value),
1471 (time_t)50, (uint32_t)9);
1472 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1473
1474 return TEST_SUCCESS;
1475 }
1476
1477 static test_return_t mget_result_test(memcached_st *memc)
1478 {
1479 memcached_return_t rc;
1480 const char *keys[]= {"fudge", "son", "food"};
1481 size_t key_length[]= {5, 3, 4};
1482 unsigned int x;
1483
1484 memcached_result_st results_obj;
1485 memcached_result_st *results;
1486
1487 results= memcached_result_create(memc, &results_obj);
1488 test_true(results);
1489 test_true(&results_obj == results);
1490
1491 /* We need to empty the server before continueing test */
1492 rc= memcached_flush(memc, 0);
1493 test_true(rc == MEMCACHED_SUCCESS);
1494
1495 rc= memcached_mget(memc, keys, key_length, 3);
1496 test_true(rc == MEMCACHED_SUCCESS);
1497
1498 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1499 {
1500 test_true(results);
1501 }
1502
1503 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1504 test_true(!results);
1505 test_true(rc == MEMCACHED_END);
1506
1507 for (x= 0; x < 3; x++)
1508 {
1509 rc= memcached_set(memc, keys[x], key_length[x],
1510 keys[x], key_length[x],
1511 (time_t)50, (uint32_t)9);
1512 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1513 }
1514
1515 rc= memcached_mget(memc, keys, key_length, 3);
1516 test_true(rc == MEMCACHED_SUCCESS);
1517
1518 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1519 {
1520 test_true(results);
1521 test_true(&results_obj == results);
1522 test_true(rc == MEMCACHED_SUCCESS);
1523 test_true(memcached_result_key_length(results) == memcached_result_length(results));
1524 test_true(!memcmp(memcached_result_key_value(results),
1525 memcached_result_value(results),
1526 memcached_result_length(results)));
1527 }
1528
1529 memcached_result_free(&results_obj);
1530
1531 return TEST_SUCCESS;
1532 }
1533
1534 static test_return_t mget_result_alloc_test(memcached_st *memc)
1535 {
1536 memcached_return_t rc;
1537 const char *keys[]= {"fudge", "son", "food"};
1538 size_t key_length[]= {5, 3, 4};
1539 unsigned int x;
1540
1541 memcached_result_st *results;
1542
1543 /* We need to empty the server before continueing test */
1544 rc= memcached_flush(memc, 0);
1545 test_true(rc == MEMCACHED_SUCCESS);
1546
1547 rc= memcached_mget(memc, keys, key_length, 3);
1548 test_true(rc == MEMCACHED_SUCCESS);
1549
1550 while ((results= memcached_fetch_result(memc, NULL, &rc)) != NULL)
1551 {
1552 test_true(results);
1553 }
1554 test_true(!results);
1555 test_true(rc == MEMCACHED_END);
1556
1557 for (x= 0; x < 3; x++)
1558 {
1559 rc= memcached_set(memc, keys[x], key_length[x],
1560 keys[x], key_length[x],
1561 (time_t)50, (uint32_t)9);
1562 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1563 }
1564
1565 rc= memcached_mget(memc, keys, key_length, 3);
1566 test_true(rc == MEMCACHED_SUCCESS);
1567
1568 x= 0;
1569 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1570 {
1571 test_true(results);
1572 test_true(rc == MEMCACHED_SUCCESS);
1573 test_true(memcached_result_key_length(results) == memcached_result_length(results));
1574 test_true(!memcmp(memcached_result_key_value(results),
1575 memcached_result_value(results),
1576 memcached_result_length(results)));
1577 memcached_result_free(results);
1578 x++;
1579 }
1580
1581 return TEST_SUCCESS;
1582 }
1583
1584 /* Count the results */
1585 static memcached_return_t callback_counter(const memcached_st *ptr,
1586 memcached_result_st *result,
1587 void *context)
1588 {
1589 (void)ptr; (void)result;
1590 size_t *counter= (size_t *)context;
1591
1592 *counter= *counter + 1;
1593
1594 return MEMCACHED_SUCCESS;
1595 }
1596
1597 static test_return_t mget_result_function(memcached_st *memc)
1598 {
1599 memcached_return_t rc;
1600 const char *keys[]= {"fudge", "son", "food"};
1601 size_t key_length[]= {5, 3, 4};
1602 unsigned int x;
1603 size_t counter;
1604 memcached_execute_fn callbacks[1];
1605
1606 /* We need to empty the server before continueing test */
1607 rc= memcached_flush(memc, 0);
1608 for (x= 0; x < 3; x++)
1609 {
1610 rc= memcached_set(memc, keys[x], key_length[x],
1611 keys[x], key_length[x],
1612 (time_t)50, (uint32_t)9);
1613 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1614 }
1615
1616 rc= memcached_mget(memc, keys, key_length, 3);
1617 test_true(rc == MEMCACHED_SUCCESS);
1618
1619 callbacks[0]= &callback_counter;
1620 counter= 0;
1621 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
1622
1623 test_true(counter == 3);
1624
1625 return TEST_SUCCESS;
1626 }
1627
1628 static test_return_t mget_test(memcached_st *memc)
1629 {
1630 memcached_return_t rc;
1631 const char *keys[]= {"fudge", "son", "food"};
1632 size_t key_length[]= {5, 3, 4};
1633 unsigned int x;
1634 uint32_t flags;
1635
1636 char return_key[MEMCACHED_MAX_KEY];
1637 size_t return_key_length;
1638 char *return_value;
1639 size_t return_value_length;
1640
1641 /* We need to empty the server before continueing test */
1642 rc= memcached_flush(memc, 0);
1643 test_true(rc == MEMCACHED_SUCCESS);
1644
1645 rc= memcached_mget(memc, keys, key_length, 3);
1646 test_true(rc == MEMCACHED_SUCCESS);
1647
1648 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1649 &return_value_length, &flags, &rc)) != NULL)
1650 {
1651 test_true(return_value);
1652 }
1653 test_true(!return_value);
1654 test_true(return_value_length == 0);
1655 test_true(rc == MEMCACHED_END);
1656
1657 for (x= 0; x < 3; x++)
1658 {
1659 rc= memcached_set(memc, keys[x], key_length[x],
1660 keys[x], key_length[x],
1661 (time_t)50, (uint32_t)9);
1662 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1663 }
1664
1665 rc= memcached_mget(memc, keys, key_length, 3);
1666 test_true(rc == MEMCACHED_SUCCESS);
1667
1668 x= 0;
1669 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1670 &return_value_length, &flags, &rc)))
1671 {
1672 test_true(return_value);
1673 test_true(rc == MEMCACHED_SUCCESS);
1674 test_true(return_key_length == return_value_length);
1675 test_true(!memcmp(return_value, return_key, return_value_length));
1676 free(return_value);
1677 x++;
1678 }
1679
1680 return TEST_SUCCESS;
1681 }
1682
1683 static test_return_t mget_execute(memcached_st *memc)
1684 {
1685 bool binary= false;
1686
1687 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1688 binary= true;
1689
1690 /*
1691 * I only want to hit _one_ server so I know the number of requests I'm
1692 * sending in the pipeline.
1693 */
1694 uint32_t number_of_hosts= memc->number_of_hosts;
1695 memc->number_of_hosts= 1;
1696
1697 size_t max_keys= 20480;
1698
1699
1700 char **keys= calloc(max_keys, sizeof(char*));
1701 size_t *key_length=calloc(max_keys, sizeof(size_t));
1702
1703 /* First add all of the items.. */
1704 char blob[1024] = {0};
1705 memcached_return_t rc;
1706
1707 for (size_t x= 0; x < max_keys; ++x)
1708 {
1709 char k[251];
1710
1711 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
1712 keys[x]= strdup(k);
1713 test_true(keys[x] != NULL);
1714 rc= memcached_add(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
1715 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1716 }
1717
1718 /* Try to get all of them with a large multiget */
1719 size_t counter= 0;
1720 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
1721 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
1722 max_keys, callbacks, &counter, 1);
1723
1724 if (rc == MEMCACHED_SUCCESS)
1725 {
1726 test_true(binary);
1727 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
1728 test_true(rc == MEMCACHED_END);
1729
1730 /* Verify that we got all of the items */
1731 test_true(counter == max_keys);
1732 }
1733 else if (rc == MEMCACHED_NOT_SUPPORTED)
1734 {
1735 test_true(counter == 0);
1736 }
1737 else
1738 {
1739 test_fail("note: this test functions differently when in binary mode");
1740 }
1741
1742 /* Release all allocated resources */
1743 for (size_t x= 0; x < max_keys; ++x)
1744 {
1745 free(keys[x]);
1746 }
1747 free(keys);
1748 free(key_length);
1749
1750 memc->number_of_hosts= number_of_hosts;
1751 return TEST_SUCCESS;
1752 }
1753
1754 #define REGRESSION_BINARY_VS_BLOCK_COUNT 20480
1755
1756 static test_return_t key_setup(memcached_st *memc)
1757 {
1758 (void)memc;
1759
1760 if (pre_binary(memc) != TEST_SUCCESS)
1761 return TEST_SKIPPED;
1762
1763 global_pairs= pairs_generate(REGRESSION_BINARY_VS_BLOCK_COUNT, 0);
1764
1765 return TEST_SUCCESS;
1766 }
1767
1768 static test_return_t key_teardown(memcached_st *memc)
1769 {
1770 (void)memc;
1771 pairs_free(global_pairs);
1772
1773 return TEST_SUCCESS;
1774 }
1775
1776 static test_return_t block_add_regression(memcached_st *memc)
1777 {
1778 /* First add all of the items.. */
1779 for (size_t x= 0; x < REGRESSION_BINARY_VS_BLOCK_COUNT; ++x)
1780 {
1781 memcached_return_t rc;
1782 char blob[1024] = {0};
1783
1784 rc= memcached_add_by_key(memc, "bob", 3, global_pairs[x].key, global_pairs[x].key_length, blob, sizeof(blob), 0, 0);
1785 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1786 }
1787
1788 return TEST_SUCCESS;
1789 }
1790
1791 static test_return_t binary_add_regression(memcached_st *memc)
1792 {
1793 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
1794 test_return_t rc= block_add_regression(memc);
1795 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 0);
1796 return rc;
1797 }
1798
1799 static test_return_t get_stats_keys(memcached_st *memc)
1800 {
1801 char **stat_list;
1802 char **ptr;
1803 memcached_stat_st memc_stat;
1804 memcached_return_t rc;
1805
1806 stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc);
1807 test_true(rc == MEMCACHED_SUCCESS);
1808 for (ptr= stat_list; *ptr; ptr++)
1809 test_true(*ptr);
1810
1811 free(stat_list);
1812
1813 return TEST_SUCCESS;
1814 }
1815
1816 static test_return_t version_string_test(memcached_st *memc)
1817 {
1818 const char *version_string;
1819 (void)memc;
1820
1821 version_string= memcached_lib_version();
1822
1823 test_true(!strcmp(version_string, LIBMEMCACHED_VERSION_STRING));
1824
1825 return TEST_SUCCESS;
1826 }
1827
1828 static test_return_t get_stats(memcached_st *memc)
1829 {
1830 char **stat_list;
1831 char **ptr;
1832 memcached_return_t rc;
1833 memcached_stat_st *memc_stat;
1834
1835 memc_stat= memcached_stat(memc, NULL, &rc);
1836 test_true(rc == MEMCACHED_SUCCESS);
1837
1838 test_true(rc == MEMCACHED_SUCCESS);
1839 test_true(memc_stat);
1840
1841 for (uint32_t x= 0; x < memcached_server_count(memc); x++)
1842 {
1843 stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
1844 test_true(rc == MEMCACHED_SUCCESS);
1845 for (ptr= stat_list; *ptr; ptr++);
1846
1847 free(stat_list);
1848 }
1849
1850 memcached_stat_free(NULL, memc_stat);
1851
1852 return TEST_SUCCESS;
1853 }
1854
1855 static test_return_t add_host_test(memcached_st *memc)
1856 {
1857 unsigned int x;
1858 memcached_server_st *servers;
1859 memcached_return_t rc;
1860 char servername[]= "0.example.com";
1861
1862 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1863 test_true(servers);
1864 test_true(1 == memcached_server_list_count(servers));
1865
1866 for (x= 2; x < 20; x++)
1867 {
1868 char buffer[SMALL_STRING_LEN];
1869
1870 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1871 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1872 &rc);
1873 test_true(rc == MEMCACHED_SUCCESS);
1874 test_true(x == memcached_server_list_count(servers));
1875 }
1876
1877 rc= memcached_server_push(memc, servers);
1878 test_true(rc == MEMCACHED_SUCCESS);
1879 rc= memcached_server_push(memc, servers);
1880 test_true(rc == MEMCACHED_SUCCESS);
1881
1882 memcached_server_list_free(servers);
1883
1884 return TEST_SUCCESS;
1885 }
1886
1887 static memcached_return_t clone_test_callback(memcached_st *parent, memcached_st *memc_clone)
1888 {
1889 (void)parent;(void)memc_clone;
1890 return MEMCACHED_SUCCESS;
1891 }
1892
1893 static memcached_return_t cleanup_test_callback(memcached_st *ptr)
1894 {
1895 (void)ptr;
1896 return MEMCACHED_SUCCESS;
1897 }
1898
1899 static test_return_t callback_test(memcached_st *memc)
1900 {
1901 /* Test User Data */
1902 {
1903 int x= 5;
1904 int *test_ptr;
1905 memcached_return_t rc;
1906
1907 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x);
1908 test_true(rc == MEMCACHED_SUCCESS);
1909 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1910 test_true(*test_ptr == x);
1911 }
1912
1913 /* Test Clone Callback */
1914 {
1915 memcached_clone_fn clone_cb= (memcached_clone_fn)clone_test_callback;
1916 void *clone_cb_ptr= *(void **)&clone_cb;
1917 void *temp_function= NULL;
1918 memcached_return_t rc;
1919
1920 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION,
1921 clone_cb_ptr);
1922 test_true(rc == MEMCACHED_SUCCESS);
1923 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1924 test_true(temp_function == clone_cb_ptr);
1925 }
1926
1927 /* Test Cleanup Callback */
1928 {
1929 memcached_cleanup_fn cleanup_cb=
1930 (memcached_cleanup_fn)cleanup_test_callback;
1931 void *cleanup_cb_ptr= *(void **)&cleanup_cb;
1932 void *temp_function= NULL;
1933 memcached_return_t rc;
1934
1935 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION,
1936 cleanup_cb_ptr);
1937 test_true(rc == MEMCACHED_SUCCESS);
1938 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1939 test_true(temp_function == cleanup_cb_ptr);
1940 }
1941
1942 return TEST_SUCCESS;
1943 }
1944
1945 /* We don't test the behavior itself, we test the switches */
1946 static test_return_t behavior_test(memcached_st *memc)
1947 {
1948 uint64_t value;
1949 uint32_t set= 1;
1950
1951 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1952 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1953 test_true(value == 1);
1954
1955 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1956 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1957 test_true(value == 1);
1958
1959 set= MEMCACHED_HASH_MD5;
1960 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1961 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1962 test_true(value == MEMCACHED_HASH_MD5);
1963
1964 set= 0;
1965
1966 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1967 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1968 test_true(value == 0);
1969
1970 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1971 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1972 test_true(value == 0);
1973
1974 set= MEMCACHED_HASH_DEFAULT;
1975 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1976 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1977 test_true(value == MEMCACHED_HASH_DEFAULT);
1978
1979 set= MEMCACHED_HASH_CRC;
1980 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1981 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1982 test_true(value == MEMCACHED_HASH_CRC);
1983
1984 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1985 test_true(value > 0);
1986
1987 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1988 test_true(value > 0);
1989
1990 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
1991 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value + 1);
1992 test_true((value + 1) == memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
1993
1994 return TEST_SUCCESS;
1995 }
1996
1997 static test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
1998 {
1999 memcached_return_t rc;
2000 bool set= true;
2001 bool value;
2002
2003 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
2004 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2005
2006 value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
2007
2008 if (rc == MEMCACHED_SUCCESS)
2009 {
2010 test_true((bool)value == set);
2011 }
2012 else
2013 {
2014 test_false((bool)value == set);
2015 }
2016
2017 return TEST_SUCCESS;
2018 }
2019
2020
2021 static test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test(memcached_st *memc)
2022 {
2023 memcached_return_t rc;
2024 bool set= true;
2025 bool value;
2026
2027 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, set);
2028 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2029
2030 value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE);
2031
2032 if (rc == MEMCACHED_SUCCESS)
2033 {
2034 test_true((bool)value == set);
2035 }
2036 else
2037 {
2038 test_false((bool)value == set);
2039 }
2040
2041 return TEST_SUCCESS;
2042 }
2043
2044
2045 static test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc)
2046 {
2047 memcached_return_t rc;
2048 bool set= true;
2049 bool value;
2050
2051 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE, set);
2052 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2053
2054 value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE);
2055
2056 if (rc == MEMCACHED_SUCCESS)
2057 {
2058 test_true((bool)value == set);
2059 }
2060 else
2061 {
2062 test_false((bool)value == set);
2063 }
2064
2065 return TEST_SUCCESS;
2066 }
2067
2068 static test_return_t fetch_all_results(memcached_st *memc, size_t *keys_returned)
2069 {
2070 memcached_return_t rc= MEMCACHED_SUCCESS;
2071 char return_key[MEMCACHED_MAX_KEY];
2072 size_t return_key_length;
2073 char *return_value;
2074 size_t return_value_length;
2075 uint32_t flags;
2076
2077 *keys_returned= 0;
2078
2079 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2080 &return_value_length, &flags, &rc)))
2081 {
2082 test_true(return_value);
2083 test_true(rc == MEMCACHED_SUCCESS);
2084 free(return_value);
2085 *keys_returned= *keys_returned +1;
2086 }
2087
2088 test_true_got(rc == MEMCACHED_END || rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
2089
2090 return TEST_SUCCESS;
2091 }
2092
2093 /* Test case provided by Cal Haldenbrand */
2094 static test_return_t user_supplied_bug1(memcached_st *memc)
2095 {
2096 unsigned int setter= 1;
2097
2098 unsigned long long total= 0;
2099 uint32_t size= 0;
2100 char key[10];
2101 char randomstuff[6 * 1024];
2102 memcached_return_t rc;
2103
2104 memset(randomstuff, 0, 6 * 1024);
2105
2106 /* We just keep looking at the same values over and over */
2107 srandom(10);
2108
2109 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2110 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2111
2112
2113 /* add key */
2114 for (uint32_t x= 0 ; total < 20 * 1024576 ; x++ )
2115 {
2116 unsigned int j= 0;
2117
2118 size= (uint32_t)(rand() % ( 5 * 1024 ) ) + 400;
2119 memset(randomstuff, 0, 6 * 1024);
2120 test_true(size < 6 * 1024); /* Being safe here */
2121
2122 for (j= 0 ; j < size ;j++)
2123 randomstuff[j] = (signed char) ((rand() % 26) + 97);
2124
2125 total += size;
2126 snprintf(key, sizeof(key), "%u", x);
2127 rc = memcached_set(memc, key, strlen(key),
2128 randomstuff, strlen(randomstuff), 10, 0);
2129 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2130 /* If we fail, lets try again */
2131 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
2132 rc = memcached_set(memc, key, strlen(key),
2133 randomstuff, strlen(randomstuff), 10, 0);
2134 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2135 }
2136
2137 return TEST_SUCCESS;
2138 }
2139
2140 /* Test case provided by Cal Haldenbrand */
2141 static test_return_t user_supplied_bug2(memcached_st *memc)
2142 {
2143 unsigned int setter;
2144 size_t total= 0;
2145
2146 setter= 1;
2147 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2148 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2149 #ifdef NOT_YET
2150 setter = 20 * 1024576;
2151 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2152 setter = 20 * 1024576;
2153 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2154 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2155 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2156
2157 for (x= 0, errors= 0; total < 20 * 1024576 ; x++)
2158 #endif
2159
2160 for (uint32_t x= 0, errors= 0; total < 24576 ; x++)
2161 {
2162 memcached_return_t rc= MEMCACHED_SUCCESS;
2163 char buffer[SMALL_STRING_LEN];
2164 uint32_t flags= 0;
2165 size_t val_len= 0;
2166 char *getval;
2167
2168 memset(buffer, 0, SMALL_STRING_LEN);
2169
2170 snprintf(buffer, sizeof(buffer), "%u", x);
2171 getval= memcached_get(memc, buffer, strlen(buffer),
2172 &val_len, &flags, &rc);
2173 if (rc != MEMCACHED_SUCCESS)
2174 {
2175 if (rc == MEMCACHED_NOTFOUND)
2176 errors++;
2177 else
2178 {
2179 test_true(rc);
2180 }
2181
2182 continue;
2183 }
2184 total+= val_len;
2185 errors= 0;
2186 free(getval);
2187 }
2188
2189 return TEST_SUCCESS;
2190 }
2191
2192 /* Do a large mget() over all the keys we think exist */
2193 #define KEY_COUNT 3000 // * 1024576
2194 static test_return_t user_supplied_bug3(memcached_st *memc)
2195 {
2196 memcached_return_t rc;
2197 unsigned int setter;
2198 unsigned int x;
2199 char **keys;
2200 size_t key_lengths[KEY_COUNT];
2201
2202 setter= 1;
2203 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2204 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2205 #ifdef NOT_YET
2206 setter = 20 * 1024576;
2207 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2208 setter = 20 * 1024576;
2209 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2210 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2211 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2212 #endif
2213
2214 keys= calloc(KEY_COUNT, sizeof(char *));
2215 test_true(keys);
2216 for (x= 0; x < KEY_COUNT; x++)
2217 {
2218 char buffer[30];
2219
2220 snprintf(buffer, 30, "%u", x);
2221 keys[x]= strdup(buffer);
2222 key_lengths[x]= strlen(keys[x]);
2223 }
2224
2225 rc= memcached_mget(memc, (const char **)keys, key_lengths, KEY_COUNT);
2226 test_true(rc == MEMCACHED_SUCCESS);
2227
2228 size_t keys_returned;
2229 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
2230
2231 for (x= 0; x < KEY_COUNT; x++)
2232 free(keys[x]);
2233 free(keys);
2234
2235 return TEST_SUCCESS;
2236 }
2237
2238 /* Make sure we behave properly if server list has no values */
2239 static test_return_t user_supplied_bug4(memcached_st *memc)
2240 {
2241 memcached_return_t rc;
2242 const char *keys[]= {"fudge", "son", "food"};
2243 size_t key_length[]= {5, 3, 4};
2244 unsigned int x;
2245 uint32_t flags;
2246 char return_key[MEMCACHED_MAX_KEY];
2247 size_t return_key_length;
2248 char *return_value;
2249 size_t return_value_length;
2250
2251 /* Here we free everything before running a bunch of mget tests */
2252 memcached_servers_reset(memc);
2253
2254
2255 /* We need to empty the server before continueing test */
2256 rc= memcached_flush(memc, 0);
2257 test_true(rc == MEMCACHED_NO_SERVERS);
2258
2259 rc= memcached_mget(memc, keys, key_length, 3);
2260 test_true(rc == MEMCACHED_NO_SERVERS);
2261
2262 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2263 &return_value_length, &flags, &rc)) != NULL)
2264 {
2265 test_true(return_value);
2266 }
2267 test_true(!return_value);
2268 test_true(return_value_length == 0);
2269 test_true(rc == MEMCACHED_NO_SERVERS);
2270
2271 for (x= 0; x < 3; x++)
2272 {
2273 rc= memcached_set(memc, keys[x], key_length[x],
2274 keys[x], key_length[x],
2275 (time_t)50, (uint32_t)9);
2276 test_true(rc == MEMCACHED_NO_SERVERS);
2277 }
2278
2279 rc= memcached_mget(memc, keys, key_length, 3);
2280 test_true(rc == MEMCACHED_NO_SERVERS);
2281
2282 x= 0;
2283 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2284 &return_value_length, &flags, &rc)))
2285 {
2286 test_true(return_value);
2287 test_true(rc == MEMCACHED_SUCCESS);
2288 test_true(return_key_length == return_value_length);
2289 test_true(!memcmp(return_value, return_key, return_value_length));
2290 free(return_value);
2291 x++;
2292 }
2293
2294 return TEST_SUCCESS;
2295 }
2296
2297 #define VALUE_SIZE_BUG5 1048064
2298 static test_return_t user_supplied_bug5(memcached_st *memc)
2299 {
2300 memcached_return_t rc;
2301 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2302 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2303 char return_key[MEMCACHED_MAX_KEY];
2304 size_t return_key_length;
2305 char *value;
2306 size_t value_length;
2307 uint32_t flags;
2308 unsigned int count;
2309 unsigned int x;
2310 char insert_data[VALUE_SIZE_BUG5];
2311
2312 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2313 insert_data[x]= (signed char)rand();
2314
2315 memcached_flush(memc, 0);
2316 value= memcached_get(memc, keys[0], key_length[0],
2317 &value_length, &flags, &rc);
2318 test_true(value == NULL);
2319 rc= memcached_mget(memc, keys, key_length, 4);
2320
2321 count= 0;
2322 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2323 &value_length, &flags, &rc)))
2324 count++;
2325 test_true(count == 0);
2326
2327 for (x= 0; x < 4; x++)
2328 {
2329 rc= memcached_set(memc, keys[x], key_length[x],
2330 insert_data, VALUE_SIZE_BUG5,
2331 (time_t)0, (uint32_t)0);
2332 test_true(rc == MEMCACHED_SUCCESS);
2333 }
2334
2335 for (x= 0; x < 10; x++)
2336 {
2337 value= memcached_get(memc, keys[0], key_length[0],
2338 &value_length, &flags, &rc);
2339 test_true(value);
2340 free(value);
2341
2342 rc= memcached_mget(memc, keys, key_length, 4);
2343 count= 0;
2344 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2345 &value_length, &flags, &rc)))
2346 {
2347 count++;
2348 free(value);
2349 }
2350 test_true(count == 4);
2351 }
2352
2353 return TEST_SUCCESS;
2354 }
2355
2356 static test_return_t user_supplied_bug6(memcached_st *memc)
2357 {
2358 memcached_return_t rc;
2359 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2360 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2361 char return_key[MEMCACHED_MAX_KEY];
2362 size_t return_key_length;
2363 char *value;
2364 size_t value_length;
2365 uint32_t flags;
2366 unsigned int count;
2367 unsigned int x;
2368 char insert_data[VALUE_SIZE_BUG5];
2369
2370 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2371 insert_data[x]= (signed char)rand();
2372
2373 memcached_flush(memc, 0);
2374 value= memcached_get(memc, keys[0], key_length[0],
2375 &value_length, &flags, &rc);
2376 test_true(value == NULL);
2377 test_true(rc == MEMCACHED_NOTFOUND);
2378 rc= memcached_mget(memc, keys, key_length, 4);
2379 test_true(rc == MEMCACHED_SUCCESS);
2380
2381 count= 0;
2382 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2383 &value_length, &flags, &rc)))
2384 count++;
2385 test_true(count == 0);
2386 test_true(rc == MEMCACHED_END);
2387
2388 for (x= 0; x < 4; x++)
2389 {
2390 rc= memcached_set(memc, keys[x], key_length[x],
2391 insert_data, VALUE_SIZE_BUG5,
2392 (time_t)0, (uint32_t)0);
2393 test_true(rc == MEMCACHED_SUCCESS);
2394 }
2395
2396 for (x= 0; x < 2; x++)
2397 {
2398 value= memcached_get(memc, keys[0], key_length[0],
2399 &value_length, &flags, &rc);
2400 test_true(value);
2401 free(value);
2402
2403 rc= memcached_mget(memc, keys, key_length, 4);
2404 test_true(rc == MEMCACHED_SUCCESS);
2405 count= 3;
2406 /* We test for purge of partial complete fetches */
2407 for (count= 3; count; count--)
2408 {
2409 value= memcached_fetch(memc, return_key, &return_key_length,
2410 &value_length, &flags, &rc);
2411 test_true(rc == MEMCACHED_SUCCESS);
2412 test_true(!(memcmp(value, insert_data, value_length)));
2413 test_true(value_length);
2414 free(value);
2415 }
2416 }
2417
2418 return TEST_SUCCESS;
2419 }
2420
2421 static test_return_t user_supplied_bug8(memcached_st *memc)
2422 {
2423 memcached_return_t rc;
2424 memcached_st *mine;
2425 memcached_st *memc_clone;
2426
2427 memcached_server_st *servers;
2428 const char *server_list= "memcache1.memcache.bk.sapo.pt:11211, memcache1.memcache.bk.sapo.pt:11212, memcache1.memcache.bk.sapo.pt:11213, memcache1.memcache.bk.sapo.pt:11214, memcache2.memcache.bk.sapo.pt:11211, memcache2.memcache.bk.sapo.pt:11212, memcache2.memcache.bk.sapo.pt:11213, memcache2.memcache.bk.sapo.pt:11214";
2429
2430 (void)memc;
2431 servers= memcached_servers_parse(server_list);
2432 test_true(servers);
2433
2434 mine= memcached_create(NULL);
2435 rc= memcached_server_push(mine, servers);
2436 test_true(rc == MEMCACHED_SUCCESS);
2437 memcached_server_list_free(servers);
2438
2439 test_true(mine);
2440 memc_clone= memcached_clone(NULL, mine);
2441
2442 memcached_quit(mine);
2443 memcached_quit(memc_clone);
2444
2445
2446 memcached_free(mine);
2447 memcached_free(memc_clone);
2448
2449 return TEST_SUCCESS;
2450 }
2451
2452 /* Test flag store/retrieve */
2453 static test_return_t user_supplied_bug7(memcached_st *memc)
2454 {
2455 memcached_return_t rc;
2456 const char *keys= "036790384900";
2457 size_t key_length= strlen(keys);
2458 char return_key[MEMCACHED_MAX_KEY];
2459 size_t return_key_length;
2460 char *value;
2461 size_t value_length;
2462 uint32_t flags;
2463 unsigned int x;
2464 char insert_data[VALUE_SIZE_BUG5];
2465
2466 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2467 insert_data[x]= (signed char)rand();
2468
2469 memcached_flush(memc, 0);
2470
2471 flags= 245;
2472 rc= memcached_set(memc, keys, key_length,
2473 insert_data, VALUE_SIZE_BUG5,
2474 (time_t)0, flags);
2475 test_true(rc == MEMCACHED_SUCCESS);
2476
2477 flags= 0;
2478 value= memcached_get(memc, keys, key_length,
2479 &value_length, &flags, &rc);
2480 test_true(flags == 245);
2481 test_true(value);
2482 free(value);
2483
2484 rc= memcached_mget(memc, &keys, &key_length, 1);
2485
2486 flags= 0;
2487 value= memcached_fetch(memc, return_key, &return_key_length,
2488 &value_length, &flags, &rc);
2489 test_true(flags == 245);
2490 test_true(value);
2491 free(value);
2492
2493
2494 return TEST_SUCCESS;
2495 }
2496
2497 static test_return_t user_supplied_bug9(memcached_st *memc)
2498 {
2499 memcached_return_t rc;
2500 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2501 size_t key_length[3];
2502 unsigned int x;
2503 uint32_t flags;
2504 unsigned count= 0;
2505
2506 char return_key[MEMCACHED_MAX_KEY];
2507 size_t return_key_length;
2508 char *return_value;
2509 size_t return_value_length;
2510
2511
2512 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2513 key_length[1]= strlen("fudge&*@#");
2514 key_length[2]= strlen("for^#@&$not");
2515
2516
2517 for (x= 0; x < 3; x++)
2518 {
2519 rc= memcached_set(memc, keys[x], key_length[x],
2520 keys[x], key_length[x],
2521 (time_t)50, (uint32_t)9);
2522 test_true(rc == MEMCACHED_SUCCESS);
2523 }
2524
2525 rc= memcached_mget(memc, keys, key_length, 3);
2526 test_true(rc == MEMCACHED_SUCCESS);
2527
2528 /* We need to empty the server before continueing test */
2529 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2530 &return_value_length, &flags, &rc)) != NULL)
2531 {
2532 test_true(return_value);
2533 free(return_value);
2534 count++;
2535 }
2536 test_true(count == 3);
2537
2538 return TEST_SUCCESS;
2539 }
2540
2541 /* We are testing with aggressive timeout to get failures */
2542 static test_return_t user_supplied_bug10(memcached_st *memc)
2543 {
2544 const char *key= "foo";
2545 char *value;
2546 size_t value_length= 512;
2547 unsigned int x;
2548 size_t key_len= 3;
2549 memcached_return_t rc;
2550 unsigned int set= 1;
2551 memcached_st *mclone= memcached_clone(NULL, memc);
2552 int32_t timeout;
2553
2554 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2555 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2556 timeout= 2;
2557 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2558 (uint64_t)timeout);
2559
2560 value = (char*)malloc(value_length * sizeof(char));
2561
2562 for (x= 0; x < value_length; x++)
2563 value[x]= (char) (x % 127);
2564
2565 for (x= 1; x <= 100000; ++x)
2566 {
2567 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2568
2569 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE ||
2570 rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT);
2571
2572 if (rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_TIMEOUT)
2573 x--;
2574 }
2575
2576 free(value);
2577 memcached_free(mclone);
2578
2579 return TEST_SUCCESS;
2580 }
2581
2582 /*
2583 We are looking failures in the async protocol
2584 */
2585 static test_return_t user_supplied_bug11(memcached_st *memc)
2586 {
2587 const char *key= "foo";
2588 char *value;
2589 size_t value_length= 512;
2590 unsigned int x;
2591 size_t key_len= 3;
2592 memcached_return_t rc;
2593 unsigned int set= 1;
2594 int32_t timeout;
2595 memcached_st *mclone= memcached_clone(NULL, memc);
2596
2597 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2598 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2599 timeout= -1;
2600 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2601 (size_t)timeout);
2602
2603 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2604
2605 test_true(timeout == -1);
2606
2607 value = (char*)malloc(value_length * sizeof(char));
2608
2609 for (x= 0; x < value_length; x++)
2610 value[x]= (char) (x % 127);
2611
2612 for (x= 1; x <= 100000; ++x)
2613 {
2614 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2615 }
2616
2617 free(value);
2618 memcached_free(mclone);
2619
2620 return TEST_SUCCESS;
2621 }
2622
2623 /*
2624 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2625 */
2626 static test_return_t user_supplied_bug12(memcached_st *memc)
2627 {
2628 memcached_return_t rc;
2629 uint32_t flags;
2630 size_t value_length;
2631 char *value;
2632 uint64_t number_value;
2633
2634 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2635 &value_length, &flags, &rc);
2636 test_true(value == NULL);
2637 test_true(rc == MEMCACHED_NOTFOUND);
2638
2639 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2640 1, &number_value);
2641
2642 test_true(value == NULL);
2643 /* The binary protocol will set the key if it doesn't exist */
2644 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2645 {
2646 test_true(rc == MEMCACHED_SUCCESS);
2647 }
2648 else
2649 {
2650 test_true(rc == MEMCACHED_NOTFOUND);
2651 }
2652
2653 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2654
2655 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2656 &value_length, &flags, &rc);
2657 test_true(value);
2658 test_true(rc == MEMCACHED_SUCCESS);
2659 free(value);
2660
2661 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2662 1, &number_value);
2663 test_true(number_value == 2);
2664 test_true(rc == MEMCACHED_SUCCESS);
2665
2666 return TEST_SUCCESS;
2667 }
2668
2669 /*
2670 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2671 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2672 */
2673 static test_return_t user_supplied_bug13(memcached_st *memc)
2674 {
2675 char key[] = "key34567890";
2676 char *overflow;
2677 memcached_return_t rc;
2678 size_t overflowSize;
2679
2680 char commandFirst[]= "set key34567890 0 0 ";
2681 char commandLast[] = " \r\n"; /* first line of command sent to server */
2682 size_t commandLength;
2683 size_t testSize;
2684
2685 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2686
2687 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2688
2689 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2690 {
2691 overflow= malloc(testSize);
2692 test_true(overflow != NULL);
2693
2694 memset(overflow, 'x', testSize);
2695 rc= memcached_set(memc, key, strlen(key),
2696 overflow, testSize, 0, 0);
2697 test_true(rc == MEMCACHED_SUCCESS);
2698 free(overflow);
2699 }
2700
2701 return TEST_SUCCESS;
2702 }
2703
2704
2705 /*
2706 Test values of many different sizes
2707 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2708 set key34567890 0 0 8169 \r\n
2709 is sent followed by buffer of size 8169, followed by 8169
2710 */
2711 static test_return_t user_supplied_bug14(memcached_st *memc)
2712 {
2713 size_t setter= 1;
2714 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2715 memcached_return_t rc;
2716 const char *key= "foo";
2717 char *value;
2718 size_t value_length= 18000;
2719 char *string;
2720 size_t string_length;
2721 uint32_t flags;
2722 unsigned int x;
2723 size_t current_length;
2724
2725 value = (char*)malloc(value_length);
2726 test_true(value);
2727
2728 for (x= 0; x < value_length; x++)
2729 value[x] = (char) (x % 127);
2730
2731 for (current_length= 0; current_length < value_length; current_length++)
2732 {
2733 rc= memcached_set(memc, key, strlen(key),
2734 value, current_length,
2735 (time_t)0, (uint32_t)0);
2736 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2737
2738 string= memcached_get(memc, key, strlen(key),
2739 &string_length, &flags, &rc);
2740
2741 test_true(rc == MEMCACHED_SUCCESS);
2742 test_true(string_length == current_length);
2743 test_true(!memcmp(string, value, string_length));
2744
2745 free(string);
2746 }
2747
2748 free(value);
2749
2750 return TEST_SUCCESS;
2751 }
2752
2753 /*
2754 Look for zero length value problems
2755 */
2756 static test_return_t user_supplied_bug15(memcached_st *memc)
2757 {
2758 uint32_t x;
2759 memcached_return_t rc;
2760 const char *key= "mykey";
2761 char *value;
2762 size_t length;
2763 uint32_t flags;
2764
2765 for (x= 0; x < 2; x++)
2766 {
2767 rc= memcached_set(memc, key, strlen(key),
2768 NULL, 0,
2769 (time_t)0, (uint32_t)0);
2770
2771 test_true(rc == MEMCACHED_SUCCESS);
2772
2773 value= memcached_get(memc, key, strlen(key),
2774 &length, &flags, &rc);
2775
2776 test_true(rc == MEMCACHED_SUCCESS);
2777 test_true(value == NULL);
2778 test_true(length == 0);
2779 test_true(flags == 0);
2780
2781 value= memcached_get(memc, key, strlen(key),
2782 &length, &flags, &rc);
2783
2784 test_true(rc == MEMCACHED_SUCCESS);
2785 test_true(value == NULL);
2786 test_true(length == 0);
2787 test_true(flags == 0);
2788 }
2789
2790 return TEST_SUCCESS;
2791 }
2792
2793 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2794 static test_return_t user_supplied_bug16(memcached_st *memc)
2795 {
2796 memcached_return_t rc;
2797 const char *key= "mykey";
2798 char *value;
2799 size_t length;
2800 uint32_t flags;
2801
2802 rc= memcached_set(memc, key, strlen(key),
2803 NULL, 0,
2804 (time_t)0, UINT32_MAX);
2805
2806 test_true(rc == MEMCACHED_SUCCESS);
2807
2808 value= memcached_get(memc, key, strlen(key),
2809 &length, &flags, &rc);
2810
2811 test_true(rc == MEMCACHED_SUCCESS);
2812 test_true(value == NULL);
2813 test_true(length == 0);
2814 test_true(flags == UINT32_MAX);
2815
2816 return TEST_SUCCESS;
2817 }
2818
2819 #if !defined(__sun) && !defined(__OpenBSD__)
2820 /* Check the validity of chinese key*/
2821 static test_return_t user_supplied_bug17(memcached_st *memc)
2822 {
2823 memcached_return_t rc;
2824 const char *key= "豆瓣";
2825 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2826 char *value2;
2827 size_t length;
2828 uint32_t flags;
2829
2830 rc= memcached_set(memc, key, strlen(key),
2831 value, strlen(value),
2832 (time_t)0, 0);
2833
2834 test_true(rc == MEMCACHED_SUCCESS);
2835
2836 value2= memcached_get(memc, key, strlen(key),
2837 &length, &flags, &rc);
2838
2839 test_true(length==strlen(value));
2840 test_true(rc == MEMCACHED_SUCCESS);
2841 test_true(memcmp(value, value2, length)==0);
2842 free(value2);
2843
2844 return TEST_SUCCESS;
2845 }
2846 #endif
2847
2848 /*
2849 From Andrei on IRC
2850 */
2851
2852 static test_return_t user_supplied_bug19(memcached_st *not_used)
2853 {
2854 memcached_st *memc;
2855 const memcached_server_st *server;
2856 memcached_return_t res;
2857
2858 (void)not_used;
2859
2860 memc= memcached_create(NULL);
2861 memcached_server_add_with_weight(memc, "localhost", 11311, 100);
2862 memcached_server_add_with_weight(memc, "localhost", 11312, 100);
2863
2864 server= memcached_server_by_key(memc, "a", 1, &res);
2865
2866 memcached_free(memc);
2867
2868 return TEST_SUCCESS;
2869 }
2870
2871 /* CAS test from Andei */
2872 static test_return_t user_supplied_bug20(memcached_st *memc)
2873 {
2874 memcached_return_t status;
2875 memcached_result_st *result, result_obj;
2876 const char *key = "abc";
2877 size_t key_len = strlen("abc");
2878 const char *value = "foobar";
2879 size_t value_len = strlen(value);
2880
2881 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2882
2883 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2884 test_true(status == MEMCACHED_SUCCESS);
2885
2886 status = memcached_mget(memc, &key, &key_len, 1);
2887 test_true(status == MEMCACHED_SUCCESS);
2888
2889 result= memcached_result_create(memc, &result_obj);
2890 test_true(result);
2891
2892 memcached_result_create(memc, &result_obj);
2893 result= memcached_fetch_result(memc, &result_obj, &status);
2894
2895 test_true(result);
2896 test_true(status == MEMCACHED_SUCCESS);
2897
2898 memcached_result_free(result);
2899
2900 return TEST_SUCCESS;
2901 }
2902
2903 #include "ketama_test_cases.h"
2904 static test_return_t user_supplied_bug18(memcached_st *trash)
2905 {
2906 memcached_return_t rc;
2907 uint64_t value;
2908 int x;
2909 memcached_server_st *server_pool;
2910 memcached_st *memc;
2911
2912 (void)trash;
2913
2914 memc= memcached_create(NULL);
2915 test_true(memc);
2916
2917 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2918 test_true(rc == MEMCACHED_SUCCESS);
2919
2920 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2921 test_true(value == 1);
2922
2923 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2924 test_true(rc == MEMCACHED_SUCCESS);
2925
2926 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2927 test_true(value == MEMCACHED_HASH_MD5);
2928
2929 server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
2930 memcached_server_push(memc, server_pool);
2931
2932 /* verify that the server list was parsed okay. */
2933 test_true(memcached_server_count(memc) == 8);
2934 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2935 test_true(server_pool[0].port == 11211);
2936 test_true(server_pool[0].weight == 600);
2937 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2938 test_true(server_pool[2].port == 11211);
2939 test_true(server_pool[2].weight == 200);
2940 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2941 test_true(server_pool[7].port == 11211);
2942 test_true(server_pool[7].weight == 100);
2943
2944 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2945 * us test the boundary wraparound.
2946 */
2947 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
2948
2949 /* verify the standard ketama set. */
2950 for (x= 0; x < 99; x++)
2951 {
2952 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2953
2954 memcached_server_instance_st instance=
2955 memcached_server_instance_by_position(memc, server_idx);
2956
2957 const char *hostname = memcached_server_name(instance);
2958 test_strcmp(hostname, ketama_test_cases[x].server);
2959 }
2960
2961 memcached_server_list_free(server_pool);
2962 memcached_free(memc);
2963
2964 return TEST_SUCCESS;
2965 }
2966
2967 /* Large mget() of missing keys with binary proto
2968 *
2969 * If many binary quiet commands (such as getq's in an mget) fill the output
2970 * buffer and the server chooses not to respond, memcached_flush hangs. See
2971 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2972 */
2973
2974 /* sighandler_t function that always asserts false */
2975 static void fail(int unused)
2976 {
2977 (void)unused;
2978 assert(0);
2979 }
2980
2981
2982 static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2983 {
2984 #ifdef WIN32
2985 (void)memc;
2986 (void)key_count;
2987 return TEST_SKIPPED;
2988 #else
2989 memcached_return_t rc;
2990 unsigned int x;
2991 char **keys;
2992 size_t* key_lengths;
2993 void (*oldalarm)(int);
2994 memcached_st *memc_clone;
2995
2996 memc_clone= memcached_clone(NULL, memc);
2997 test_true(memc_clone);
2998
2999 /* only binproto uses getq for mget */
3000 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3001
3002 /* empty the cache to ensure misses (hence non-responses) */
3003 rc= memcached_flush(memc_clone, 0);
3004 test_true(rc == MEMCACHED_SUCCESS);
3005
3006 key_lengths= calloc(key_count, sizeof(size_t));
3007 keys= calloc(key_count, sizeof(char *));
3008 test_true(keys);
3009 for (x= 0; x < key_count; x++)
3010 {
3011 char buffer[30];
3012
3013 snprintf(buffer, 30, "%u", x);
3014 keys[x]= strdup(buffer);
3015 key_lengths[x]= strlen(keys[x]);
3016 }
3017
3018 oldalarm= signal(SIGALRM, fail);
3019 alarm(5);
3020
3021 rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
3022 test_true(rc == MEMCACHED_SUCCESS);
3023
3024 alarm(0);
3025 signal(SIGALRM, oldalarm);
3026
3027 size_t keys_returned;
3028 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
3029
3030 for (x= 0; x < key_count; x++)
3031 free(keys[x]);
3032 free(keys);
3033 free(key_lengths);
3034
3035 memcached_free(memc_clone);
3036
3037 return TEST_SUCCESS;
3038 #endif
3039 }
3040
3041 static test_return_t user_supplied_bug21(memcached_st *memc)
3042 {
3043 test_return_t test_rc;
3044 test_rc= pre_binary(memc);
3045
3046 if (test_rc != TEST_SUCCESS)
3047 return test_rc;
3048
3049 test_return_t rc;
3050
3051 /* should work as of r580 */
3052 rc= _user_supplied_bug21(memc, 10);
3053 test_true(rc == TEST_SUCCESS);
3054
3055 /* should fail as of r580 */
3056 rc= _user_supplied_bug21(memc, 1000);
3057 test_true(rc == TEST_SUCCESS);
3058
3059 return TEST_SUCCESS;
3060 }
3061
3062 static test_return_t auto_eject_hosts(memcached_st *trash)
3063 {
3064 (void) trash;
3065 memcached_server_instance_st instance;
3066
3067 memcached_return_t rc;
3068 memcached_st *memc= memcached_create(NULL);
3069 test_true(memc);
3070
3071 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3072 test_true(rc == MEMCACHED_SUCCESS);
3073
3074 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3075 test_true(value == 1);
3076
3077 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3078 test_true(rc == MEMCACHED_SUCCESS);
3079
3080 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3081 test_true(value == MEMCACHED_HASH_MD5);
3082
3083 /* server should be removed when in delay */
3084 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
3085 test_true(rc == MEMCACHED_SUCCESS);
3086
3087 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
3088 test_true(value == 1);
3089
3090 memcached_server_st *server_pool;
3091 server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
3092 memcached_server_push(memc, server_pool);
3093
3094 /* verify that the server list was parsed okay. */
3095 test_true(memcached_server_count(memc) == 8);
3096 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
3097 test_true(server_pool[0].port == 11211);
3098 test_true(server_pool[0].weight == 600);
3099 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
3100 test_true(server_pool[2].port == 11211);
3101 test_true(server_pool[2].weight == 200);
3102 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
3103 test_true(server_pool[7].port == 11211);
3104 test_true(server_pool[7].weight == 100);
3105
3106 instance= memcached_server_instance_by_position(memc, 2);
3107 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) + 15;
3108 memc->ketama.next_distribution_rebuild= time(NULL) - 1;
3109
3110 /*
3111 This would not work if there were only two hosts.
3112 */
3113 for (size_t x= 0; x < 99; x++)
3114 {
3115 memcached_autoeject(memc);
3116 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
3117 test_true(server_idx != 2);
3118 }
3119
3120 /* and re-added when it's back. */
3121 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) - 1;
3122 memc->ketama.next_distribution_rebuild= time(NULL) - 1;
3123 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
3124 memc->distribution);
3125 for (size_t x= 0; x < 99; x++)
3126 {
3127 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
3128 // We re-use instance from above.
3129 instance=
3130 memcached_server_instance_by_position(memc, server_idx);
3131 const char *hostname = memcached_server_name(instance);
3132 test_true(strcmp(hostname, ketama_test_cases[x].server) == 0);
3133 }
3134
3135 memcached_server_list_free(server_pool);
3136 memcached_free(memc);
3137
3138 return TEST_SUCCESS;
3139 }
3140
3141 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
3142 {
3143 (void) trash;
3144
3145 memcached_return_t rc;
3146 memcached_st *memc= memcached_create(NULL);
3147 test_true(memc);
3148
3149
3150 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3151 test_true(rc == MEMCACHED_SUCCESS);
3152
3153 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3154 test_true(value == 1);
3155
3156 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3157 test_true(rc == MEMCACHED_SUCCESS);
3158
3159 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3160 test_true(value == MEMCACHED_HASH_MD5);
3161
3162
3163 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
3164
3165 memcached_server_st *server_pool;
3166 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");
3167 memcached_server_push(memc, server_pool);
3168
3169 // @todo this needs to be refactored to actually test something.
3170 #if 0
3171 FILE *fp;
3172 if ((fp = fopen("ketama_keys.txt", "w")))
3173 {
3174 // noop
3175 } else {
3176 printf("cannot write to file ketama_keys.txt");
3177 return TEST_FAILURE;
3178 }
3179
3180 for (int x= 0; x < 10000; x++)
3181 {
3182 char key[10];
3183 snprintf(key, sizeof(key), "%d", x);
3184
3185 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
3186 char *hostname = memc->hosts[server_idx].hostname;
3187 in_port_t port = memc->hosts[server_idx].port;
3188 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
3189 memcached_server_instance_st instance=
3190 memcached_server_instance_by_position(memc, host_index);
3191 }
3192 fclose(fp);
3193 #endif
3194 memcached_server_list_free(server_pool);
3195 memcached_free(memc);
3196
3197 return TEST_SUCCESS;
3198 }
3199
3200
3201 static test_return_t result_static(memcached_st *memc)
3202 {
3203 memcached_result_st result;
3204 memcached_result_st *result_ptr;
3205
3206 result_ptr= memcached_result_create(memc, &result);
3207 test_true(result.options.is_allocated == false);
3208 test_true(memcached_is_initialized(&result) == true);
3209 test_true(result_ptr);
3210 test_true(result_ptr == &result);
3211
3212 memcached_result_free(&result);
3213
3214 test_true(result.options.is_allocated == false);
3215 test_true(memcached_is_initialized(&result) == false);
3216
3217 return TEST_SUCCESS;
3218 }
3219
3220 static test_return_t result_alloc(memcached_st *memc)
3221 {
3222 memcached_result_st *result_ptr;
3223
3224 result_ptr= memcached_result_create(memc, NULL);
3225 test_true(result_ptr);
3226 test_true(result_ptr->options.is_allocated == true);
3227 test_true(memcached_is_initialized(result_ptr) == true);
3228 memcached_result_free(result_ptr);
3229
3230 return TEST_SUCCESS;
3231 }
3232
3233 static test_return_t cleanup_pairs(memcached_st *memc)
3234 {
3235 (void)memc;
3236 pairs_free(global_pairs);
3237
3238 return TEST_SUCCESS;
3239 }
3240
3241 static test_return_t generate_pairs(memcached_st *memc)
3242 {
3243 (void)memc;
3244 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3245 global_count= GLOBAL_COUNT;
3246
3247 for (size_t x= 0; x < global_count; x++)
3248 {
3249 global_keys[x]= global_pairs[x].key;
3250 global_keys_length[x]= global_pairs[x].key_length;
3251 }
3252
3253 return TEST_SUCCESS;
3254 }
3255
3256 static test_return_t generate_large_pairs(memcached_st *memc)
3257 {
3258 (void)memc;
3259 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3260 global_count= GLOBAL2_COUNT;
3261
3262 for (size_t x= 0; x < global_count; x++)
3263 {
3264 global_keys[x]= global_pairs[x].key;
3265 global_keys_length[x]= global_pairs[x].key_length;
3266 }
3267
3268 return TEST_SUCCESS;
3269 }
3270
3271 static test_return_t generate_data(memcached_st *memc)
3272 {
3273 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3274
3275 test_true(check_execute == global_count);
3276
3277 return TEST_SUCCESS;
3278 }
3279
3280 static test_return_t generate_data_with_stats(memcached_st *memc)
3281 {
3282 memcached_stat_st *stat_p;
3283 memcached_return_t rc;
3284 uint32_t host_index= 0;
3285 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3286
3287 test_true(check_execute == global_count);
3288
3289 //TODO: hosts used size stats
3290 stat_p= memcached_stat(memc, NULL, &rc);
3291 test_true(stat_p);
3292
3293 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3294 {
3295 /* This test was changes so that "make test" would work properlly */
3296 #ifdef DEBUG
3297 memcached_server_instance_st instance=
3298 memcached_server_instance_by_position(memc, host_index);
3299
3300 printf("\nserver %u|%s|%u bytes: %llu\n", host_index, instance->hostname, instance->port, (unsigned long long)(stat_p + host_index)->bytes);
3301 #endif
3302 test_true((unsigned long long)(stat_p + host_index)->bytes);
3303 }
3304
3305 memcached_stat_free(NULL, stat_p);
3306
3307 return TEST_SUCCESS;
3308 }
3309 static test_return_t generate_buffer_data(memcached_st *memc)
3310 {
3311 size_t latch= 0;
3312
3313 latch= 1;
3314 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3315 generate_data(memc);
3316
3317 return TEST_SUCCESS;
3318 }
3319
3320 static test_return_t get_read_count(memcached_st *memc)
3321 {
3322 memcached_return_t rc;
3323 memcached_st *memc_clone;
3324
3325 memc_clone= memcached_clone(NULL, memc);
3326 test_true(memc_clone);
3327
3328 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3329
3330 {
3331 char *return_value;
3332 size_t return_value_length;
3333 uint32_t flags;
3334 uint32_t count;
3335
3336 for (size_t x= count= 0; x < global_count; x++)
3337 {
3338 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3339 &return_value_length, &flags, &rc);
3340 if (rc == MEMCACHED_SUCCESS)
3341 {
3342 count++;
3343 if (return_value)
3344 free(return_value);
3345 }
3346 }
3347 }
3348
3349 memcached_free(memc_clone);
3350
3351 return TEST_SUCCESS;
3352 }
3353
3354 static test_return_t get_read(memcached_st *memc)
3355 {
3356 memcached_return_t rc;
3357
3358 {
3359 char *return_value;
3360 size_t return_value_length;
3361 uint32_t flags;
3362
3363 for (size_t x= 0; x < global_count; x++)
3364 {
3365 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3366 &return_value_length, &flags, &rc);
3367 /*
3368 test_true(return_value);
3369 test_true(rc == MEMCACHED_SUCCESS);
3370 */
3371 if (rc == MEMCACHED_SUCCESS && return_value)
3372 free(return_value);
3373 }
3374 }
3375
3376 return TEST_SUCCESS;
3377 }
3378
3379 static test_return_t mget_read(memcached_st *memc)
3380 {
3381 memcached_return_t rc;
3382
3383 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3384 return TEST_SKIPPED;
3385
3386 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3387
3388 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3389
3390 // Go fetch the keys and test to see if all of them were returned
3391 {
3392 size_t keys_returned;
3393 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
3394 char buffer[30];
3395 snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)keys_returned);
3396 test_true_got(global_count == keys_returned, buffer);
3397 }
3398
3399
3400 return TEST_SUCCESS;
3401 }
3402
3403 static test_return_t mget_read_result(memcached_st *memc)
3404 {
3405 memcached_return_t rc;
3406
3407 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3408 return TEST_SKIPPED;
3409
3410 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3411
3412 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3413
3414 /* Turn this into a help function */
3415 {
3416 memcached_result_st results_obj;
3417 memcached_result_st *results;
3418
3419 results= memcached_result_create(memc, &results_obj);
3420
3421 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3422 {
3423 test_true(results);
3424 test_true(rc == MEMCACHED_SUCCESS);
3425 }
3426
3427 memcached_result_free(&results_obj);
3428 }
3429
3430 return TEST_SUCCESS;
3431 }
3432
3433 static test_return_t mget_read_function(memcached_st *memc)
3434 {
3435 memcached_return_t rc;
3436 size_t counter;
3437 memcached_execute_fn callbacks[1];
3438
3439 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3440 return TEST_SKIPPED;
3441
3442 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3443
3444 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3445
3446 callbacks[0]= &callback_counter;
3447 counter= 0;
3448 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3449
3450 return TEST_SUCCESS;
3451 }
3452
3453 static test_return_t delete_generate(memcached_st *memc)
3454 {
3455 for (size_t x= 0; x < global_count; x++)
3456 {
3457 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3458 }
3459
3460 return TEST_SUCCESS;
3461 }
3462
3463 static test_return_t delete_buffer_generate(memcached_st *memc)
3464 {
3465 uint64_t latch= 0;
3466
3467 latch= 1;
3468 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3469
3470 for (size_t x= 0; x < global_count; x++)
3471 {
3472 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3473 }
3474
3475 return TEST_SUCCESS;
3476 }
3477
3478 static test_return_t add_host_test1(memcached_st *memc)
3479 {
3480 memcached_return_t rc;
3481 char servername[]= "0.example.com";
3482 memcached_server_st *servers;
3483
3484 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3485 test_true(servers);
3486 test_true(1 == memcached_server_list_count(servers));
3487
3488 for (size_t x= 2; x < 20; x++)
3489 {
3490 char buffer[SMALL_STRING_LEN];
3491
3492 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
3493 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3494 &rc);
3495 test_true(rc == MEMCACHED_SUCCESS);
3496 test_true(x == memcached_server_list_count(servers));
3497 }
3498
3499 rc= memcached_server_push(memc, servers);
3500 test_true(rc == MEMCACHED_SUCCESS);
3501 rc= memcached_server_push(memc, servers);
3502 test_true(rc == MEMCACHED_SUCCESS);
3503
3504 memcached_server_list_free(servers);
3505
3506 return TEST_SUCCESS;
3507 }
3508
3509 static test_return_t pre_nonblock(memcached_st *memc)
3510 {
3511 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3512
3513 return TEST_SUCCESS;
3514 }
3515
3516 static test_return_t pre_cork(memcached_st *memc)
3517 {
3518 memcached_return_t rc;
3519 bool set= true;
3520
3521 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
3522
3523 #ifdef __APPLE__
3524 return TEST_SKIPPED;
3525 #endif
3526
3527 if (rc == MEMCACHED_SUCCESS)
3528 return TEST_SUCCESS;
3529
3530 return TEST_SKIPPED;
3531 }
3532
3533 static test_return_t pre_cork_and_nonblock(memcached_st *memc)
3534 {
3535 test_return_t rc;
3536
3537 rc= pre_cork(memc);
3538
3539 #ifdef __APPLE__
3540 return TEST_SKIPPED;
3541 #endif
3542
3543 if (rc != TEST_SUCCESS)
3544 return rc;
3545
3546 return pre_nonblock(memc);
3547 }
3548
3549 static test_return_t pre_nonblock_binary(memcached_st *memc)
3550 {
3551 memcached_return_t rc= MEMCACHED_FAILURE;
3552 memcached_st *memc_clone;
3553
3554 memc_clone= memcached_clone(NULL, memc);
3555 test_true(memc_clone);
3556 // The memcached_version needs to be done on a clone, because the server
3557 // will not toggle protocol on an connection.
3558 memcached_version(memc_clone);
3559
3560 if (libmemcached_util_version_check(memc_clone, 1, 4, 4))
3561 {
3562 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3563 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3564 test_true(rc == MEMCACHED_SUCCESS);
3565 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3566 }
3567 else
3568 {
3569 return TEST_SKIPPED;
3570 }
3571
3572 memcached_free(memc_clone);
3573
3574 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3575 }
3576
3577 static test_return_t pre_murmur(memcached_st *memc)
3578 {
3579 #ifdef HAVE_MURMUR_HASH
3580 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3581 return TEST_SUCCESS;
3582 #else
3583 (void) memc;
3584 return TEST_SKIPPED;
3585 #endif
3586 }
3587
3588 static test_return_t pre_jenkins(memcached_st *memc)
3589 {
3590 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3591
3592 return TEST_SUCCESS;
3593 }
3594
3595
3596 static test_return_t pre_md5(memcached_st *memc)
3597 {
3598 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3599
3600 return TEST_SUCCESS;
3601 }
3602
3603 static test_return_t pre_crc(memcached_st *memc)
3604 {
3605 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3606
3607 return TEST_SUCCESS;
3608 }
3609
3610 static test_return_t pre_hsieh(memcached_st *memc)
3611 {
3612 #ifdef HAVE_HSIEH_HASH
3613 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3614 return TEST_SUCCESS;
3615 #else
3616 (void) memc;
3617 return TEST_SKIPPED;
3618 #endif
3619 }
3620
3621 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3622 {
3623 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3624
3625 return TEST_SUCCESS;
3626 }
3627
3628 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3629 {
3630 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3631
3632 return TEST_SUCCESS;
3633 }
3634
3635 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3636 {
3637 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3638
3639 return TEST_SUCCESS;
3640 }
3641
3642 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3643 {
3644 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3645
3646 return TEST_SUCCESS;
3647 }
3648
3649 static test_return_t pre_behavior_ketama(memcached_st *memc)
3650 {
3651 memcached_return_t rc;
3652 uint64_t value;
3653
3654 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3655 test_true(rc == MEMCACHED_SUCCESS);
3656
3657 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3658 test_true(value == 1);
3659
3660 return TEST_SUCCESS;
3661 }
3662
3663 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3664 {
3665 memcached_return_t rc;
3666 uint64_t value;
3667
3668 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3669 test_true(rc == MEMCACHED_SUCCESS);
3670
3671 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3672 test_true(value == 1);
3673
3674 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3675 test_true(rc == MEMCACHED_SUCCESS);
3676
3677 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3678 test_true(value == MEMCACHED_HASH_MD5);
3679
3680 return TEST_SUCCESS;
3681 }
3682
3683 /**
3684 @note This should be testing to see if the server really supports the binary protocol.
3685 */
3686 static test_return_t pre_binary(memcached_st *memc)
3687 {
3688 memcached_return_t rc= MEMCACHED_FAILURE;
3689
3690 if (libmemcached_util_version_check(memc, 1, 4, 4))
3691 {
3692 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3693 test_true(rc == MEMCACHED_SUCCESS);
3694 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3695 }
3696
3697 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3698 }
3699
3700 static test_return_t pre_sasl(memcached_st *memc)
3701 {
3702 memcached_return_t rc= MEMCACHED_FAILURE;
3703
3704 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
3705 const char *server= getenv("LIBMEMCACHED_TEST_SASL_SERVER");
3706 const char *user= getenv("LIBMEMCACHED_TEST_SASL_USERNAME");
3707 const char *pass= getenv("LIBMEMCACHED_TEST_SASL_PASSWORD");
3708
3709 if (server != NULL && user != NULL && pass != NULL)
3710 {
3711 memcached_server_st *servers= memcached_servers_parse(server);
3712 test_true(servers != NULL);
3713 memcached_servers_reset(memc);
3714 test_true(memcached_server_push(memc, servers) == MEMCACHED_SUCCESS);
3715 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3716 rc= memcached_set_sasl_auth_data(memc, user, pass);
3717 test_true(rc == MEMCACHED_SUCCESS);
3718 }
3719 #else
3720 (void)memc;
3721 #endif
3722
3723 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3724 }
3725
3726 static test_return_t pre_replication(memcached_st *memc)
3727 {
3728 test_return_t test_rc;
3729 test_rc= pre_binary(memc);
3730
3731 if (test_rc != TEST_SUCCESS)
3732 return test_rc;
3733
3734 /*
3735 * Make sure that we store the item on all servers
3736 * (master + replicas == number of servers)
3737 */
3738 memcached_return_t rc;
3739 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3740 memcached_server_count(memc) - 1);
3741 test_true(rc == MEMCACHED_SUCCESS);
3742 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memcached_server_count(memc) - 1);
3743
3744 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3745 }
3746
3747
3748 static test_return_t pre_replication_noblock(memcached_st *memc)
3749 {
3750 test_return_t rc;
3751
3752 rc= pre_replication(memc);
3753 if (rc != TEST_SUCCESS)
3754 return rc;
3755
3756 rc= pre_nonblock(memc);
3757
3758 return rc;
3759 }
3760
3761
3762 static void my_free(const memcached_st *ptr, void *mem, void *context)
3763 {
3764 (void)context;
3765 (void)ptr;
3766 #ifdef HARD_MALLOC_TESTS
3767 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3768 free(real_ptr);
3769 #else
3770 free(mem);
3771 #endif
3772 }
3773
3774
3775 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
3776 {
3777 (void)context;
3778 (void)ptr;
3779 #ifdef HARD_MALLOC_TESTS
3780 void *ret= malloc(size + 8);
3781 if (ret != NULL)
3782 {
3783 ret= (void*)((caddr_t)ret + 8);
3784 }
3785 #else
3786 void *ret= malloc(size);
3787 #endif
3788
3789 if (ret != NULL)
3790 {
3791 memset(ret, 0xff, size);
3792 }
3793
3794 return ret;
3795 }
3796
3797
3798 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *context)
3799 {
3800 (void)context;
3801 #ifdef HARD_MALLOC_TESTS
3802 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3803 void *nmem= realloc(real_ptr, size + 8);
3804
3805 void *ret= NULL;
3806 if (nmem != NULL)
3807 {
3808 ret= (void*)((caddr_t)nmem + 8);
3809 }
3810
3811 return ret;
3812 #else
3813 (void)ptr;
3814 return realloc(mem, size);
3815 #endif
3816 }
3817
3818
3819 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *context)
3820 {
3821 (void)context;
3822 #ifdef HARD_MALLOC_TESTS
3823 void *mem= my_malloc(ptr, nelem * size);
3824 if (mem)
3825 {
3826 memset(mem, 0, nelem * size);
3827 }
3828
3829 return mem;
3830 #else
3831 (void)ptr;
3832 return calloc(nelem, size);
3833 #endif
3834 }
3835
3836
3837 static test_return_t set_prefix(memcached_st *memc)
3838 {
3839 memcached_return_t rc;
3840 const char *key= "mine";
3841 char *value;
3842
3843 /* Make sure be default none exists */
3844 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3845 test_true(rc == MEMCACHED_FAILURE);
3846
3847 /* Test a clean set */
3848 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3849 test_true_got(rc == MEMCACHED_SUCCESS, memcached_last_error_message(memc));
3850
3851 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3852 test_true(value);
3853 test_true(memcmp(value, key, 4) == 0);
3854 test_true(rc == MEMCACHED_SUCCESS);
3855
3856 /* Test that we can turn it off */
3857 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3858 test_true(rc == MEMCACHED_SUCCESS);
3859
3860 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3861 test_false(value);
3862 test_true(rc == MEMCACHED_FAILURE);
3863
3864 /* Now setup for main test */
3865 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3866 test_true(rc == MEMCACHED_SUCCESS);
3867
3868 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3869 test_true(value);
3870 test_true(rc == MEMCACHED_SUCCESS);
3871 test_true(memcmp(value, key, 4) == 0);
3872
3873 /* Set to Zero, and then Set to something too large */
3874 {
3875 char long_key[255];
3876 memset(long_key, 0, 255);
3877
3878 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3879 test_true(rc == MEMCACHED_SUCCESS);
3880
3881 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3882 test_false(value);
3883 test_true(rc == MEMCACHED_FAILURE);
3884 test_true(value == NULL);
3885
3886 /* Test a long key for failure */
3887 /* TODO, extend test to determine based on setting, what result should be */
3888 strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key));
3889 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3890 //test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3891 test_true(rc == MEMCACHED_SUCCESS);
3892
3893 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3894 strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key));
3895 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3896 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3897
3898 /* Test for a bad prefix, but with a short key */
3899 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3900 test_true(rc == MEMCACHED_SUCCESS);
3901
3902 strncpy(long_key, "dog cat", sizeof(long_key));
3903 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3904 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3905 }
3906
3907 return TEST_SUCCESS;
3908 }
3909
3910
3911 #ifdef MEMCACHED_ENABLE_DEPRECATED
3912 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3913 {
3914 void *test_ptr= NULL;
3915 void *cb_ptr= NULL;
3916 {
3917 memcached_malloc_fn malloc_cb=
3918 (memcached_malloc_fn)my_malloc;
3919 cb_ptr= *(void **)&malloc_cb;
3920 memcached_return_t rc;
3921
3922 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3923 test_true(rc == MEMCACHED_SUCCESS);
3924 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3925 test_true(rc == MEMCACHED_SUCCESS);
3926 test_true(test_ptr == cb_ptr);
3927 }
3928
3929 {
3930 memcached_realloc_fn realloc_cb=
3931 (memcached_realloc_fn)my_realloc;
3932 cb_ptr= *(void **)&realloc_cb;
3933 memcached_return_t rc;
3934
3935 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3936 test_true(rc == MEMCACHED_SUCCESS);
3937 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3938 test_true(rc == MEMCACHED_SUCCESS);
3939 test_true(test_ptr == cb_ptr);
3940 }
3941
3942 {
3943 memcached_free_fn free_cb=
3944 (memcached_free_fn)my_free;
3945 cb_ptr= *(void **)&free_cb;
3946 memcached_return_t rc;
3947
3948 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3949 test_true(rc == MEMCACHED_SUCCESS);
3950 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3951 test_true(rc == MEMCACHED_SUCCESS);
3952 test_true(test_ptr == cb_ptr);
3953 }
3954
3955 return TEST_SUCCESS;
3956 }
3957 #endif
3958
3959
3960 static test_return_t set_memory_alloc(memcached_st *memc)
3961 {
3962 memcached_return_t rc;
3963 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3964 my_realloc, my_calloc, NULL);
3965 test_true(rc == MEMCACHED_FAILURE);
3966
3967 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3968 my_realloc, my_calloc, NULL);
3969
3970 memcached_malloc_fn mem_malloc;
3971 memcached_free_fn mem_free;
3972 memcached_realloc_fn mem_realloc;
3973 memcached_calloc_fn mem_calloc;
3974 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3975 &mem_realloc, &mem_calloc);
3976
3977 test_true(mem_malloc == my_malloc);
3978 test_true(mem_realloc == my_realloc);
3979 test_true(mem_calloc == my_calloc);
3980 test_true(mem_free == my_free);
3981
3982 return TEST_SUCCESS;
3983 }
3984
3985 static test_return_t enable_consistent_crc(memcached_st *memc)
3986 {
3987 test_return_t rc;
3988 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3989 memcached_hash_t hash;
3990 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3991 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3992 return rc;
3993
3994 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3995 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3996
3997 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3998
3999 if (hash != MEMCACHED_HASH_CRC)
4000 return TEST_SKIPPED;
4001
4002 return TEST_SUCCESS;
4003 }
4004
4005 static test_return_t enable_consistent_hsieh(memcached_st *memc)
4006 {
4007 test_return_t rc;
4008 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4009 memcached_hash_t hash;
4010 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4011 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
4012 return rc;
4013
4014 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4015 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4016
4017 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4018
4019 if (hash != MEMCACHED_HASH_HSIEH)
4020 return TEST_SKIPPED;
4021
4022
4023 return TEST_SUCCESS;
4024 }
4025
4026 static test_return_t enable_cas(memcached_st *memc)
4027 {
4028 unsigned int set= 1;
4029
4030 if (libmemcached_util_version_check(memc, 1, 2, 4))
4031 {
4032 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
4033
4034 return TEST_SUCCESS;
4035 }
4036
4037 return TEST_SKIPPED;
4038 }
4039
4040 static test_return_t check_for_1_2_3(memcached_st *memc)
4041 {
4042 memcached_version(memc);
4043
4044 memcached_server_instance_st instance=
4045 memcached_server_instance_by_position(memc, 0);
4046
4047 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
4048 || instance->minor_version > 2)
4049 {
4050 return TEST_SUCCESS;
4051 }
4052
4053 return TEST_SKIPPED;
4054 }
4055
4056 static test_return_t pre_unix_socket(memcached_st *memc)
4057 {
4058 memcached_return_t rc;
4059 struct stat buf;
4060
4061 memcached_servers_reset(memc);
4062
4063 if (stat("/tmp/memcached.socket", &buf))
4064 return TEST_SKIPPED;
4065
4066 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
4067
4068 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
4069 }
4070
4071 static test_return_t pre_nodelay(memcached_st *memc)
4072 {
4073 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
4074 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
4075
4076 return TEST_SUCCESS;
4077 }
4078
4079 static test_return_t pre_settimer(memcached_st *memc)
4080 {
4081 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4082 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4083
4084 return TEST_SUCCESS;
4085 }
4086
4087 static test_return_t poll_timeout(memcached_st *memc)
4088 {
4089 size_t timeout;
4090
4091 timeout= 100;
4092
4093 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
4094
4095 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
4096
4097 test_true(timeout == 100);
4098
4099 return TEST_SUCCESS;
4100 }
4101
4102 static test_return_t noreply_test(memcached_st *memc)
4103 {
4104 memcached_return_t ret;
4105 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
4106 test_true(ret == MEMCACHED_SUCCESS);
4107 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4108 test_true(ret == MEMCACHED_SUCCESS);
4109 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
4110 test_true(ret == MEMCACHED_SUCCESS);
4111 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
4112 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
4113 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
4114
4115 for (int count=0; count < 5; ++count)
4116 {
4117 for (size_t x= 0; x < 100; ++x)
4118 {
4119 char key[10];
4120 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4121 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4122
4123 size_t len= (size_t)check_length;
4124
4125 switch (count)
4126 {
4127 case 0:
4128 ret= memcached_add(memc, key, len, key, len, 0, 0);
4129 break;
4130 case 1:
4131 ret= memcached_replace(memc, key, len, key, len, 0, 0);
4132 break;
4133 case 2:
4134 ret= memcached_set(memc, key, len, key, len, 0, 0);
4135 break;
4136 case 3:
4137 ret= memcached_append(memc, key, len, key, len, 0, 0);
4138 break;
4139 case 4:
4140 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
4141 break;
4142 default:
4143 test_true(count);
4144 break;
4145 }
4146 test_true(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
4147 }
4148
4149 /*
4150 ** NOTE: Don't ever do this in your code! this is not a supported use of the
4151 ** API and is _ONLY_ done this way to verify that the library works the
4152 ** way it is supposed to do!!!!
4153 */
4154 int no_msg=0;
4155 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
4156 {
4157 memcached_server_instance_st instance=
4158 memcached_server_instance_by_position(memc, x);
4159 no_msg+=(int)(instance->cursor_active);
4160 }
4161
4162 test_true(no_msg == 0);
4163 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4164
4165 /*
4166 ** Now validate that all items was set properly!
4167 */
4168 for (size_t x= 0; x < 100; ++x)
4169 {
4170 char key[10];
4171
4172 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4173
4174 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4175
4176 size_t len= (size_t)check_length;
4177 size_t length;
4178 uint32_t flags;
4179 char* value=memcached_get(memc, key, strlen(key),
4180 &length, &flags, &ret);
4181 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4182 switch (count)
4183 {
4184 case 0: /* FALLTHROUGH */
4185 case 1: /* FALLTHROUGH */
4186 case 2:
4187 test_true(strncmp(value, key, len) == 0);
4188 test_true(len == length);
4189 break;
4190 case 3:
4191 test_true(length == len * 2);
4192 break;
4193 case 4:
4194 test_true(length == len * 3);
4195 break;
4196 default:
4197 test_true(count);
4198 break;
4199 }
4200 free(value);
4201 }
4202 }
4203
4204 /* Try setting an illegal cas value (should not return an error to
4205 * the caller (because we don't expect a return message from the server)
4206 */
4207 const char* keys[]= {"0"};
4208 size_t lengths[]= {1};
4209 size_t length;
4210 uint32_t flags;
4211 memcached_result_st results_obj;
4212 memcached_result_st *results;
4213 ret= memcached_mget(memc, keys, lengths, 1);
4214 test_true(ret == MEMCACHED_SUCCESS);
4215
4216 results= memcached_result_create(memc, &results_obj);
4217 test_true(results);
4218 results= memcached_fetch_result(memc, &results_obj, &ret);
4219 test_true(results);
4220 test_true(ret == MEMCACHED_SUCCESS);
4221 uint64_t cas= memcached_result_cas(results);
4222 memcached_result_free(&results_obj);
4223
4224 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4225 test_true(ret == MEMCACHED_SUCCESS);
4226
4227 /*
4228 * The item will have a new cas value, so try to set it again with the old
4229 * value. This should fail!
4230 */
4231 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4232 test_true(ret == MEMCACHED_SUCCESS);
4233 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4234 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4235 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4236 free(value);
4237
4238 return TEST_SUCCESS;
4239 }
4240
4241 static test_return_t analyzer_test(memcached_st *memc)
4242 {
4243 memcached_return_t rc;
4244 memcached_stat_st *memc_stat;
4245 memcached_analysis_st *report;
4246
4247 memc_stat= memcached_stat(memc, NULL, &rc);
4248 test_true(rc == MEMCACHED_SUCCESS);
4249 test_true(memc_stat);
4250
4251 report= memcached_analyze(memc, memc_stat, &rc);
4252 test_true(rc == MEMCACHED_SUCCESS);
4253 test_true(report);
4254
4255 free(report);
4256 memcached_stat_free(NULL, memc_stat);
4257
4258 return TEST_SUCCESS;
4259 }
4260
4261 /* Count the objects */
4262 static memcached_return_t callback_dump_counter(const memcached_st *ptr,
4263 const char *key,
4264 size_t key_length,
4265 void *context)
4266 {
4267 (void)ptr; (void)key; (void)key_length;
4268 size_t *counter= (size_t *)context;
4269
4270 *counter= *counter + 1;
4271
4272 return MEMCACHED_SUCCESS;
4273 }
4274
4275 static test_return_t dump_test(memcached_st *memc)
4276 {
4277 memcached_return_t rc;
4278 size_t counter= 0;
4279 memcached_dump_fn callbacks[1];
4280 test_return_t main_rc;
4281
4282 callbacks[0]= &callback_dump_counter;
4283
4284 /* No support for Binary protocol yet */
4285 if (memc->flags.binary_protocol)
4286 return TEST_SUCCESS;
4287
4288 main_rc= set_test3(memc);
4289
4290 test_true (main_rc == TEST_SUCCESS);
4291
4292 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
4293 test_true(rc == MEMCACHED_SUCCESS);
4294
4295 /* We may have more then 32 if our previous flush has not completed */
4296 test_true(counter >= 32);
4297
4298 return TEST_SUCCESS;
4299 }
4300
4301 #ifdef HAVE_LIBMEMCACHEDUTIL
4302 static void* connection_release(void *arg)
4303 {
4304 struct {
4305 memcached_pool_st* pool;
4306 memcached_st* mmc;
4307 } *resource= arg;
4308
4309 usleep(250);
4310 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
4311 return arg;
4312 }
4313
4314 #define POOL_SIZE 10
4315 static test_return_t connection_pool_test(memcached_st *memc)
4316 {
4317 memcached_pool_st* pool= memcached_pool_create(memc, 5, POOL_SIZE);
4318 test_true(pool != NULL);
4319 memcached_st *mmc[POOL_SIZE];
4320 memcached_return_t rc;
4321
4322 for (size_t x= 0; x < POOL_SIZE; ++x)
4323 {
4324 mmc[x]= memcached_pool_pop(pool, false, &rc);
4325 test_true(mmc[x] != NULL);
4326 test_true(rc == MEMCACHED_SUCCESS);
4327 }
4328
4329 test_true(memcached_pool_pop(pool, false, &rc) == NULL);
4330 test_true(rc == MEMCACHED_SUCCESS);
4331
4332 pthread_t tid;
4333 struct {
4334 memcached_pool_st* pool;
4335 memcached_st* mmc;
4336 } item= { .pool = pool, .mmc = mmc[9] };
4337 pthread_create(&tid, NULL, connection_release, &item);
4338 mmc[9]= memcached_pool_pop(pool, true, &rc);
4339 test_true(rc == MEMCACHED_SUCCESS);
4340 pthread_join(tid, NULL);
4341 test_true(mmc[9] == item.mmc);
4342 const char *key= "key";
4343 size_t keylen= strlen(key);
4344
4345 // verify that I can do ops with all connections
4346 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
4347 test_true(rc == MEMCACHED_SUCCESS);
4348
4349 for (size_t x= 0; x < POOL_SIZE; ++x)
4350 {
4351 uint64_t number_value;
4352 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
4353 test_true(rc == MEMCACHED_SUCCESS);
4354 test_true(number_value == (x+1));
4355 }
4356
4357 // Release them..
4358 for (size_t x= 0; x < POOL_SIZE; ++x)
4359 {
4360 test_true(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
4361 }
4362
4363
4364 /* verify that I can set behaviors on the pool when I don't have all
4365 * of the connections in the pool. It should however be enabled
4366 * when I push the item into the pool
4367 */
4368 mmc[0]= memcached_pool_pop(pool, false, &rc);
4369 test_true(mmc[0] != NULL);
4370
4371 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4372 test_true(rc == MEMCACHED_SUCCESS);
4373
4374 mmc[1]= memcached_pool_pop(pool, false, &rc);
4375 test_true(mmc[1] != NULL);
4376
4377 test_true(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4378 test_true(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
4379 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4380
4381 mmc[0]= memcached_pool_pop(pool, false, &rc);
4382 test_true(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4383 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4384
4385 test_true(memcached_pool_destroy(pool) == memc);
4386
4387 return TEST_SUCCESS;
4388 }
4389
4390 static test_return_t util_version_test(memcached_st *memc)
4391 {
4392 bool if_successful;
4393
4394 if_successful= libmemcached_util_version_check(memc, 0, 0, 0);
4395 test_true(if_successful == true);
4396
4397 if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
4398
4399 // We expect failure
4400 if (if_successful)
4401 {
4402 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4403 fprintf(stderr, "\nDumping Server Information\n\n");
4404 memcached_server_fn callbacks[1];
4405
4406 callbacks[0]= dump_server_information;
4407 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
4408 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4409 }
4410 test_true(if_successful == false);
4411
4412 memcached_server_instance_st instance=
4413 memcached_server_instance_by_position(memc, 0);
4414
4415 memcached_version(memc);
4416
4417 // We only use one binary when we test, so this should be just fine.
4418 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
4419 test_true(if_successful == true);
4420
4421 if (instance->micro_version > 0)
4422 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
4423 else if (instance->minor_version > 0)
4424 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
4425 else if (instance->major_version > 0)
4426 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
4427
4428 test_true(if_successful == true);
4429
4430 if (instance->micro_version > 0)
4431 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
4432 else if (instance->minor_version > 0)
4433 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
4434 else if (instance->major_version > 0)
4435 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
4436
4437 test_true(if_successful == false);
4438
4439 return TEST_SUCCESS;
4440 }
4441
4442 static test_return_t ping_test(memcached_st *memc)
4443 {
4444 memcached_return_t rc;
4445 memcached_server_instance_st instance=
4446 memcached_server_instance_by_position(memc, 0);
4447
4448 // Test both the version that returns a code, and the one that does not.
4449 test_true(libmemcached_util_ping(memcached_server_name(instance),
4450 memcached_server_port(instance), NULL));
4451
4452 test_true(libmemcached_util_ping(memcached_server_name(instance),
4453 memcached_server_port(instance), &rc));
4454
4455 test_true(rc == MEMCACHED_SUCCESS);
4456
4457 return TEST_SUCCESS;
4458 }
4459 #endif
4460
4461
4462 #if 0
4463 static test_return_t hash_sanity_test (memcached_st *memc)
4464 {
4465 (void)memc;
4466
4467 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4468 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4469 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4470 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4471 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4472 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4473 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4474 #ifdef HAVE_HSIEH_HASH
4475 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4476 #endif
4477 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4478 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4479 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4480
4481 return TEST_SUCCESS;
4482 }
4483 #endif
4484
4485 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4486 {
4487 memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS;
4488 #ifdef HAVE_HSIEH_HASH
4489 expected_rc= MEMCACHED_SUCCESS;
4490 #endif
4491 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4492 (uint64_t)MEMCACHED_HASH_HSIEH);
4493 test_true(rc == expected_rc);
4494
4495 return TEST_SUCCESS;
4496 }
4497
4498 static test_return_t murmur_avaibility_test (memcached_st *memc)
4499 {
4500 memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS;
4501 #ifdef HAVE_MURMUR_HASH
4502 expected_rc= MEMCACHED_SUCCESS;
4503 #endif
4504 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4505 (uint64_t)MEMCACHED_HASH_MURMUR);
4506 test_true(rc == expected_rc);
4507
4508 return TEST_SUCCESS;
4509 }
4510
4511 static test_return_t one_at_a_time_run (memcached_st *memc)
4512 {
4513 uint32_t x;
4514 const char **ptr;
4515 (void)memc;
4516
4517 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4518 {
4519 uint32_t hash_val;
4520
4521 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT);
4522 test_true(one_at_a_time_values[x] == hash_val);
4523 }
4524
4525 return TEST_SUCCESS;
4526 }
4527
4528 static test_return_t md5_run (memcached_st *memc)
4529 {
4530 uint32_t x;
4531 const char **ptr;
4532 (void)memc;
4533
4534 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4535 {
4536 uint32_t hash_val;
4537
4538 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4539 test_true(md5_values[x] == hash_val);
4540 }
4541
4542 return TEST_SUCCESS;
4543 }
4544
4545 static test_return_t crc_run (memcached_st *memc)
4546 {
4547 uint32_t x;
4548 const char **ptr;
4549 (void)memc;
4550
4551 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4552 {
4553 uint32_t hash_val;
4554
4555 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4556 test_true(crc_values[x] == hash_val);
4557 }
4558
4559 return TEST_SUCCESS;
4560 }
4561
4562 static test_return_t fnv1_64_run (memcached_st *memc)
4563 {
4564 uint32_t x;
4565 const char **ptr;
4566 (void)memc;
4567
4568 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4569 {
4570 uint32_t hash_val;
4571
4572 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4573 test_true(fnv1_64_values[x] == hash_val);
4574 }
4575
4576 return TEST_SUCCESS;
4577 }
4578
4579 static test_return_t fnv1a_64_run (memcached_st *memc)
4580 {
4581 uint32_t x;
4582 const char **ptr;
4583 (void)memc;
4584
4585 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4586 {
4587 uint32_t hash_val;
4588
4589 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4590 test_true(fnv1a_64_values[x] == hash_val);
4591 }
4592
4593 return TEST_SUCCESS;
4594 }
4595
4596 static test_return_t fnv1_32_run (memcached_st *memc)
4597 {
4598 uint32_t x;
4599 const char **ptr;
4600 (void)memc;
4601
4602 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4603 {
4604 uint32_t hash_val;
4605
4606 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4607 test_true(fnv1_32_values[x] == hash_val);
4608 }
4609
4610 return TEST_SUCCESS;
4611 }
4612
4613 static test_return_t fnv1a_32_run (memcached_st *memc)
4614 {
4615 uint32_t x;
4616 const char **ptr;
4617 (void)memc;
4618
4619 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4620 {
4621 uint32_t hash_val;
4622
4623 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4624 test_true(fnv1a_32_values[x] == hash_val);
4625 }
4626
4627 return TEST_SUCCESS;
4628 }
4629
4630 static test_return_t hsieh_run (memcached_st *memc)
4631 {
4632 uint32_t x;
4633 const char **ptr;
4634 (void)memc;
4635
4636 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4637 {
4638 uint32_t hash_val;
4639
4640 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4641 test_true(hsieh_values[x] == hash_val);
4642 }
4643
4644 return TEST_SUCCESS;
4645 }
4646
4647 static test_return_t murmur_run (memcached_st *memc)
4648 {
4649 #ifdef WORDS_BIGENDIAN
4650 (void)murmur_values;
4651 return TEST_SKIPPED;
4652 #else
4653 uint32_t x;
4654 const char **ptr;
4655 (void)memc;
4656
4657 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4658 {
4659 uint32_t hash_val;
4660
4661 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4662 test_true(murmur_values[x] == hash_val);
4663 }
4664
4665 return TEST_SUCCESS;
4666 #endif
4667 }
4668
4669 static test_return_t jenkins_run (memcached_st *memc)
4670 {
4671 uint32_t x;
4672 const char **ptr;
4673 (void)memc;
4674
4675 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4676 {
4677 uint32_t hash_val;
4678
4679 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4680 test_true(jenkins_values[x] == hash_val);
4681 }
4682
4683 return TEST_SUCCESS;
4684 }
4685
4686 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *context)
4687 {
4688 (void)context;
4689 return libhashkit_md5(string, string_length);
4690 }
4691
4692 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *context)
4693 {
4694 (void)context;
4695 return libhashkit_crc32(string, string_length);
4696 }
4697
4698 static test_return_t memcached_get_hashkit_test (memcached_st *memc)
4699 {
4700 uint32_t x;
4701 const char **ptr;
4702 const hashkit_st *kit;
4703 hashkit_st new_kit;
4704 hashkit_return_t hash_rc;
4705
4706 uint32_t md5_hosts[]= {4U, 1U, 0U, 1U, 4U, 2U, 0U, 3U, 0U, 0U, 3U, 1U, 0U, 0U, 1U, 3U, 0U, 0U, 0U, 3U, 1U, 0U, 4U, 4U, 3U};
4707 uint32_t crc_hosts[]= {2U, 4U, 1U, 0U, 2U, 4U, 4U, 4U, 1U, 2U, 3U, 4U, 3U, 4U, 1U, 3U, 3U, 2U, 0U, 0U, 0U, 1U, 2U, 4U, 0U};
4708
4709 kit= memcached_get_hashkit(memc);
4710
4711 hashkit_clone(&new_kit, kit);
4712 hash_rc= hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL);
4713 test_true(hash_rc == HASHKIT_SUCCESS);
4714
4715 memcached_set_hashkit(memc, &new_kit);
4716
4717 /*
4718 Verify Setting the hash.
4719 */
4720 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4721 {
4722 uint32_t hash_val;
4723
4724 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4725 test_true(md5_values[x] == hash_val);
4726 }
4727
4728
4729 /*
4730 Now check memcached_st.
4731 */
4732 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4733 {
4734 uint32_t hash_val;
4735
4736 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4737 test_true(md5_hosts[x] == hash_val);
4738 }
4739
4740 hash_rc= hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL);
4741 test_true(hash_rc == HASHKIT_SUCCESS);
4742
4743 memcached_set_hashkit(memc, &new_kit);
4744
4745 /*
4746 Verify Setting the hash.
4747 */
4748 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4749 {
4750 uint32_t hash_val;
4751
4752 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4753 test_true(crc_values[x] == hash_val);
4754 }
4755
4756 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4757 {
4758 uint32_t hash_val;
4759
4760 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4761 test_true(crc_hosts[x] == hash_val);
4762 }
4763
4764 return TEST_SUCCESS;
4765 }
4766
4767 /*
4768 Test case adapted from John Gorman <johngorman2@gmail.com>
4769
4770 We are testing the error condition when we connect to a server via memcached_get()
4771 but find that the server is not available.
4772 */
4773 static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc)
4774 {
4775 (void)memc;
4776 memcached_st *tl_memc_h;
4777 memcached_server_st *servers;
4778
4779 const char *key= "MemcachedLives";
4780 size_t len;
4781 uint32_t flags;
4782 memcached_return rc;
4783 char *value;
4784
4785 // Create a handle.
4786 tl_memc_h= memcached_create(NULL);
4787 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4788 memcached_server_push(tl_memc_h, servers);
4789 memcached_server_list_free(servers);
4790
4791 // See if memcached is reachable.
4792 value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc);
4793
4794 test_false(value);
4795 test_true(len == 0);
4796 test_false(rc == MEMCACHED_SUCCESS);
4797
4798 memcached_free(tl_memc_h);
4799
4800 return TEST_SUCCESS;
4801 }
4802
4803 /*
4804 We connect to a server which exists, but search for a key that does not exist.
4805 */
4806 static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
4807 {
4808 const char *key= "MemcachedKeyNotEXIST";
4809 size_t len;
4810 uint32_t flags;
4811 memcached_return rc;
4812 char *value;
4813
4814 // See if memcached is reachable.
4815 value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
4816
4817 test_false(value);
4818 test_true(len == 0);
4819 test_true(rc == MEMCACHED_NOTFOUND);
4820
4821 return TEST_SUCCESS;
4822 }
4823
4824 /*
4825 Test case adapted from John Gorman <johngorman2@gmail.com>
4826
4827 We are testing the error condition when we connect to a server via memcached_get_by_key()
4828 but find that the server is not available.
4829 */
4830 static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc)
4831 {
4832 (void)memc;
4833 memcached_st *tl_memc_h;
4834 memcached_server_st *servers;
4835
4836 const char *key= "MemcachedLives";
4837 size_t len;
4838 uint32_t flags;
4839 memcached_return rc;
4840 char *value;
4841
4842 // Create a handle.
4843 tl_memc_h= memcached_create(NULL);
4844 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4845 memcached_server_push(tl_memc_h, servers);
4846 memcached_server_list_free(servers);
4847
4848 // See if memcached is reachable.
4849 value= memcached_get_by_key(tl_memc_h, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4850
4851 test_false(value);
4852 test_true(len == 0);
4853 test_false(rc == MEMCACHED_SUCCESS);
4854
4855 memcached_free(tl_memc_h);
4856
4857 return TEST_SUCCESS;
4858 }
4859
4860 /*
4861 We connect to a server which exists, but search for a key that does not exist.
4862 */
4863 static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
4864 {
4865 const char *key= "MemcachedKeyNotEXIST";
4866 size_t len;
4867 uint32_t flags;
4868 memcached_return rc;
4869 char *value;
4870
4871 // See if memcached is reachable.
4872 value= memcached_get_by_key(memc, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4873
4874 test_false(value);
4875 test_true(len == 0);
4876 test_true(rc == MEMCACHED_NOTFOUND);
4877
4878 return TEST_SUCCESS;
4879 }
4880
4881
4882 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
4883 {
4884 memcached_return_t rc;
4885 uint64_t value;
4886 int x;
4887 memcached_server_st *server_pool;
4888 memcached_st *memc;
4889
4890 (void)trash;
4891
4892 memc= memcached_create(NULL);
4893 test_true(memc);
4894
4895 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4896 test_true(rc == MEMCACHED_SUCCESS);
4897
4898 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4899 test_true(value == 1);
4900
4901 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
4902 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
4903
4904
4905 server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
4906 memcached_server_push(memc, server_pool);
4907
4908 /* verify that the server list was parsed okay. */
4909 test_true(memcached_server_count(memc) == 8);
4910 test_strcmp(server_pool[0].hostname, "10.0.1.1");
4911 test_true(server_pool[0].port == 11211);
4912 test_true(server_pool[0].weight == 600);
4913 test_strcmp(server_pool[2].hostname, "10.0.1.3");
4914 test_true(server_pool[2].port == 11211);
4915 test_true(server_pool[2].weight == 200);
4916 test_strcmp(server_pool[7].hostname, "10.0.1.8");
4917 test_true(server_pool[7].port == 11211);
4918 test_true(server_pool[7].weight == 100);
4919
4920 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4921 * us test the boundary wraparound.
4922 */
4923 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
4924
4925 /* verify the standard ketama set. */
4926 for (x= 0; x < 99; x++)
4927 {
4928 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
4929 memcached_server_instance_st instance=
4930 memcached_server_instance_by_position(memc, server_idx);
4931 const char *hostname = memcached_server_name(instance);
4932
4933 test_strcmp(hostname, ketama_test_cases[x].server);
4934 }
4935
4936 memcached_server_list_free(server_pool);
4937 memcached_free(memc);
4938
4939 return TEST_SUCCESS;
4940 }
4941
4942 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
4943 {
4944 memcached_return_t rc;
4945 uint64_t value;
4946 memcached_server_st *server_pool;
4947 memcached_st *memc;
4948
4949 (void)trash;
4950
4951 memc= memcached_create(NULL);
4952 test_true(memc);
4953
4954 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4955 test_true(rc == MEMCACHED_SUCCESS);
4956
4957 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4958 test_true(value == 1);
4959
4960 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
4961 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
4962
4963 server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
4964 memcached_server_push(memc, server_pool);
4965
4966 /* verify that the server list was parsed okay. */
4967 test_true(memcached_server_count(memc) == 8);
4968 test_strcmp(server_pool[0].hostname, "10.0.1.1");
4969 test_true(server_pool[0].port == 11211);
4970 test_true(server_pool[0].weight == 600);
4971 test_strcmp(server_pool[2].hostname, "10.0.1.3");
4972 test_true(server_pool[2].port == 11211);
4973 test_true(server_pool[2].weight == 200);
4974 test_strcmp(server_pool[7].hostname, "10.0.1.8");
4975 test_true(server_pool[7].port == 11211);
4976 test_true(server_pool[7].weight == 100);
4977
4978 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4979 * us test the boundary wraparound.
4980 */
4981 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
4982
4983 /* verify the standard ketama set. */
4984 for (uint32_t x= 0; x < 99; x++)
4985 {
4986 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
4987
4988 memcached_server_instance_st instance=
4989 memcached_server_instance_by_position(memc, server_idx);
4990
4991 const char *hostname= memcached_server_name(instance);
4992
4993 test_strcmp(hostname, ketama_test_cases_spy[x].server);
4994 }
4995
4996 memcached_server_list_free(server_pool);
4997 memcached_free(memc);
4998
4999 return TEST_SUCCESS;
5000 }
5001
5002 static test_return_t regression_bug_434484(memcached_st *memc)
5003 {
5004 test_return_t test_rc;
5005 test_rc= pre_binary(memc);
5006
5007 if (test_rc != TEST_SUCCESS)
5008 return test_rc;
5009
5010 memcached_return_t ret;
5011 const char *key= "regression_bug_434484";
5012 size_t keylen= strlen(key);
5013
5014 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5015 test_true(ret == MEMCACHED_NOTSTORED);
5016
5017 size_t size= 2048 * 1024;
5018 void *data= calloc(1, size);
5019 test_true(data != NULL);
5020 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5021 test_true(ret == MEMCACHED_E2BIG);
5022 free(data);
5023
5024 return TEST_SUCCESS;
5025 }
5026
5027 static test_return_t regression_bug_434843(memcached_st *memc)
5028 {
5029 test_return_t test_rc;
5030 test_rc= pre_binary(memc);
5031
5032 if (test_rc != TEST_SUCCESS)
5033 return test_rc;
5034
5035 memcached_return_t rc;
5036 size_t counter= 0;
5037 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5038
5039 /*
5040 * I only want to hit only _one_ server so I know the number of requests I'm
5041 * sending in the pipleine to the server. Let's try to do a multiget of
5042 * 1024 (that should satisfy most users don't you think?). Future versions
5043 * will include a mget_execute function call if you need a higher number.
5044 */
5045 uint32_t number_of_hosts= memcached_server_count(memc);
5046 memc->number_of_hosts= 1;
5047 const size_t max_keys= 1024;
5048 char **keys= calloc(max_keys, sizeof(char*));
5049 size_t *key_length=calloc(max_keys, sizeof(size_t));
5050
5051 for (size_t x= 0; x < max_keys; ++x)
5052 {
5053 char k[251];
5054
5055 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5056 keys[x]= strdup(k);
5057 test_true(keys[x] != NULL);
5058 }
5059
5060 /*
5061 * Run two times.. the first time we should have 100% cache miss,
5062 * and the second time we should have 100% cache hits
5063 */
5064 for (size_t y= 0; y < 2; y++)
5065 {
5066 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5067 test_true(rc == MEMCACHED_SUCCESS);
5068 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5069
5070 if (y == 0)
5071 {
5072 /* The first iteration should give me a 100% cache miss. verify that*/
5073 char blob[1024]= { 0 };
5074
5075 test_true(counter == 0);
5076
5077 for (size_t x= 0; x < max_keys; ++x)
5078 {
5079 rc= memcached_add(memc, keys[x], key_length[x],
5080 blob, sizeof(blob), 0, 0);
5081 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5082 }
5083 }
5084 else
5085 {
5086 /* Verify that we received all of the key/value pairs */
5087 test_true(counter == max_keys);
5088 }
5089 }
5090
5091 /* Release allocated resources */
5092 for (size_t x= 0; x < max_keys; ++x)
5093 {
5094 free(keys[x]);
5095 }
5096 free(keys);
5097 free(key_length);
5098
5099 memc->number_of_hosts= number_of_hosts;
5100
5101 return TEST_SUCCESS;
5102 }
5103
5104 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5105 {
5106 memcached_return_t rc;
5107 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5108 test_true(rc == MEMCACHED_SUCCESS);
5109
5110 return regression_bug_434843(memc);
5111 }
5112
5113 static test_return_t regression_bug_421108(memcached_st *memc)
5114 {
5115 memcached_return_t rc;
5116 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5117 test_true(rc == MEMCACHED_SUCCESS);
5118
5119 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5120 test_true(rc == MEMCACHED_SUCCESS);
5121 test_true(bytes != NULL);
5122 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5123 "bytes_read", &rc);
5124 test_true(rc == MEMCACHED_SUCCESS);
5125 test_true(bytes_read != NULL);
5126
5127 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5128 "bytes_written", &rc);
5129 test_true(rc == MEMCACHED_SUCCESS);
5130 test_true(bytes_written != NULL);
5131
5132 test_true(strcmp(bytes, bytes_read) != 0);
5133 test_true(strcmp(bytes, bytes_written) != 0);
5134
5135 /* Release allocated resources */
5136 free(bytes);
5137 free(bytes_read);
5138 free(bytes_written);
5139 memcached_stat_free(NULL, memc_stat);
5140
5141 return TEST_SUCCESS;
5142 }
5143
5144 /*
5145 * The test case isn't obvious so I should probably document why
5146 * it works the way it does. Bug 442914 was caused by a bug
5147 * in the logic in memcached_purge (it did not handle the case
5148 * where the number of bytes sent was equal to the watermark).
5149 * In this test case, create messages so that we hit that case
5150 * and then disable noreply mode and issue a new command to
5151 * verify that it isn't stuck. If we change the format for the
5152 * delete command or the watermarks, we need to update this
5153 * test....
5154 */
5155 static test_return_t regression_bug_442914(memcached_st *memc)
5156 {
5157 memcached_return_t rc;
5158 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5159 test_true(rc == MEMCACHED_SUCCESS);
5160 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5161
5162 uint32_t number_of_hosts= memcached_server_count(memc);
5163 memc->number_of_hosts= 1;
5164
5165 char k[250];
5166 size_t len;
5167
5168 for (uint32_t x= 0; x < 250; ++x)
5169 {
5170 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5171 rc= memcached_delete(memc, k, len, 0);
5172 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5173 }
5174
5175 (void)snprintf(k, sizeof(k), "%037u", 251U);
5176 len= strlen(k);
5177
5178 rc= memcached_delete(memc, k, len, 0);
5179 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5180
5181 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5182 test_true(rc == MEMCACHED_SUCCESS);
5183 rc= memcached_delete(memc, k, len, 0);
5184 test_true(rc == MEMCACHED_NOTFOUND);
5185
5186 memc->number_of_hosts= number_of_hosts;
5187
5188 return TEST_SUCCESS;
5189 }
5190
5191 static test_return_t regression_bug_447342(memcached_st *memc)
5192 {
5193 memcached_server_instance_st instance_one;
5194 memcached_server_instance_st instance_two;
5195
5196 if (memcached_server_count(memc) < 3 || pre_replication(memc) != TEST_SUCCESS)
5197 return TEST_SKIPPED;
5198
5199 memcached_return_t rc;
5200
5201 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5202 test_true(rc == MEMCACHED_SUCCESS);
5203
5204 const size_t max_keys= 100;
5205 char **keys= calloc(max_keys, sizeof(char*));
5206 size_t *key_length= calloc(max_keys, sizeof(size_t));
5207
5208 for (size_t x= 0; x < max_keys; ++x)
5209 {
5210 char k[251];
5211
5212 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5213 keys[x]= strdup(k);
5214 test_true(keys[x] != NULL);
5215 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5216 test_true(rc == MEMCACHED_SUCCESS);
5217 }
5218
5219 /*
5220 ** We are using the quiet commands to store the replicas, so we need
5221 ** to ensure that all of them are processed before we can continue.
5222 ** In the test we go directly from storing the object to trying to
5223 ** receive the object from all of the different servers, so we
5224 ** could end up in a race condition (the memcached server hasn't yet
5225 ** processed the quiet command from the replication set when it process
5226 ** the request from the other client (created by the clone)). As a
5227 ** workaround for that we call memcached_quit to send the quit command
5228 ** to the server and wait for the response ;-) If you use the test code
5229 ** as an example for your own code, please note that you shouldn't need
5230 ** to do this ;-)
5231 */
5232 memcached_quit(memc);
5233
5234 /* Verify that all messages are stored, and we didn't stuff too much
5235 * into the servers
5236 */
5237 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5238 test_true(rc == MEMCACHED_SUCCESS);
5239
5240 size_t counter= 0;
5241 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5242 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5243 /* Verify that we received all of the key/value pairs */
5244 test_true(counter == max_keys);
5245
5246 memcached_quit(memc);
5247 /*
5248 * Don't do the following in your code. I am abusing the internal details
5249 * within the library, and this is not a supported interface.
5250 * This is to verify correct behavior in the library. Fake that two servers
5251 * are dead..
5252 */
5253 instance_one= memcached_server_instance_by_position(memc, 0);
5254 instance_two= memcached_server_instance_by_position(memc, 2);
5255 in_port_t port0= instance_one->port;
5256 in_port_t port2= instance_two->port;
5257
5258 ((memcached_server_write_instance_st)instance_one)->port= 0;
5259 ((memcached_server_write_instance_st)instance_two)->port= 0;
5260
5261 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5262 test_true(rc == MEMCACHED_SUCCESS);
5263
5264 counter= 0;
5265 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5266 test_true(counter == (unsigned int)max_keys);
5267
5268 /* restore the memc handle */
5269 ((memcached_server_write_instance_st)instance_one)->port= port0;
5270 ((memcached_server_write_instance_st)instance_two)->port= port2;
5271
5272 memcached_quit(memc);
5273
5274 /* Remove half of the objects */
5275 for (size_t x= 0; x < max_keys; ++x)
5276 {
5277 if (x & 1)
5278 {
5279 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5280 test_true(rc == MEMCACHED_SUCCESS);
5281 }
5282 }
5283
5284 memcached_quit(memc);
5285 ((memcached_server_write_instance_st)instance_one)->port= 0;
5286 ((memcached_server_write_instance_st)instance_two)->port= 0;
5287
5288 /* now retry the command, this time we should have cache misses */
5289 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5290 test_true(rc == MEMCACHED_SUCCESS);
5291
5292 counter= 0;
5293 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5294 test_true(counter == (unsigned int)(max_keys >> 1));
5295
5296 /* Release allocated resources */
5297 for (size_t x= 0; x < max_keys; ++x)
5298 {
5299 free(keys[x]);
5300 }
5301 free(keys);
5302 free(key_length);
5303
5304 /* restore the memc handle */
5305 ((memcached_server_write_instance_st)instance_one)->port= port0;
5306 ((memcached_server_write_instance_st)instance_two)->port= port2;
5307
5308 return TEST_SUCCESS;
5309 }
5310
5311 static test_return_t regression_bug_463297(memcached_st *memc)
5312 {
5313 memcached_st *memc_clone= memcached_clone(NULL, memc);
5314 test_true(memc_clone != NULL);
5315 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5316
5317 memcached_server_instance_st instance=
5318 memcached_server_instance_by_position(memc_clone, 0);
5319
5320 if (instance->major_version > 1 ||
5321 (instance->major_version == 1 &&
5322 instance->minor_version > 2))
5323 {
5324 /* Binary protocol doesn't support deferred delete */
5325 memcached_st *bin_clone= memcached_clone(NULL, memc);
5326 test_true(bin_clone != NULL);
5327 test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5328 test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5329 memcached_free(bin_clone);
5330
5331 memcached_quit(memc_clone);
5332
5333 /* If we know the server version, deferred delete should fail
5334 * with invalid arguments */
5335 test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5336
5337 /* If we don't know the server version, we should get a protocol error */
5338 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5339
5340 /* but there is a bug in some of the memcached servers (1.4) that treats
5341 * the counter as noreply so it doesn't send the proper error message
5342 */
5343 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5344
5345 /* And buffered mode should be disabled and we should get protocol error */
5346 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5347 rc= memcached_delete(memc, "foo", 3, 1);
5348 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5349
5350 /* Same goes for noreply... */
5351 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5352 rc= memcached_delete(memc, "foo", 3, 1);
5353 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5354
5355 /* but a normal request should go through (and be buffered) */
5356 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5357 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5358
5359 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5360 /* unbuffered noreply should be success */
5361 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5362 /* unbuffered with reply should be not found... */
5363 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5364 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5365 }
5366
5367 memcached_free(memc_clone);
5368 return TEST_SUCCESS;
5369 }
5370
5371
5372 /* Test memcached_server_get_last_disconnect
5373 * For a working server set, shall be NULL
5374 * For a set of non existing server, shall not be NULL
5375 */
5376 static test_return_t test_get_last_disconnect(memcached_st *memc)
5377 {
5378 memcached_return_t rc;
5379 memcached_server_instance_st disconnected_server;
5380
5381 /* With the working set of server */
5382 const char *key= "marmotte";
5383 const char *value= "milka";
5384
5385 memcached_reset_last_disconnected_server(memc);
5386 rc= memcached_set(memc, key, strlen(key),
5387 value, strlen(value),
5388 (time_t)0, (uint32_t)0);
5389 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5390
5391 disconnected_server = memcached_server_get_last_disconnect(memc);
5392 test_true(disconnected_server == NULL);
5393
5394 /* With a non existing server */
5395 memcached_st *mine;
5396 memcached_server_st *servers;
5397
5398 const char *server_list= "localhost:9";
5399
5400 servers= memcached_servers_parse(server_list);
5401 test_true(servers);
5402 mine= memcached_create(NULL);
5403 rc= memcached_server_push(mine, servers);
5404 test_true(rc == MEMCACHED_SUCCESS);
5405 memcached_server_list_free(servers);
5406 test_true(mine);
5407
5408 rc= memcached_set(mine, key, strlen(key),
5409 value, strlen(value),
5410 (time_t)0, (uint32_t)0);
5411 test_true(rc != MEMCACHED_SUCCESS);
5412
5413 disconnected_server= memcached_server_get_last_disconnect(mine);
5414 if (disconnected_server == NULL)
5415 {
5416 fprintf(stderr, "RC %s\n", memcached_strerror(mine, rc));
5417 abort();
5418 }
5419 test_true(disconnected_server != NULL);
5420 test_true(memcached_server_port(disconnected_server)== 9);
5421 test_true(strncmp(memcached_server_name(disconnected_server),"localhost",9) == 0);
5422
5423 memcached_quit(mine);
5424 memcached_free(mine);
5425
5426 return TEST_SUCCESS;
5427 }
5428
5429 static test_return_t test_verbosity(memcached_st *memc)
5430 {
5431 memcached_verbosity(memc, 3);
5432
5433 return TEST_SUCCESS;
5434 }
5435
5436 static test_return_t test_server_failure(memcached_st *memc)
5437 {
5438 memcached_st *local_memc;
5439 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
5440
5441 local_memc= memcached_create(NULL);
5442
5443 memcached_server_add(local_memc, memcached_server_name(instance), memcached_server_port(instance));
5444 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2);
5445
5446 uint32_t server_count= memcached_server_count(local_memc);
5447
5448 test_true(server_count == 1);
5449
5450 // Disable the server
5451 instance= memcached_server_instance_by_position(local_memc, 0);
5452 ((memcached_server_write_instance_st)instance)->server_failure_counter= 2;
5453
5454 memcached_return_t rc;
5455 rc= memcached_set(local_memc, "foo", strlen("foo"),
5456 NULL, 0,
5457 (time_t)0, (uint32_t)0);
5458 test_true(rc == MEMCACHED_SERVER_MARKED_DEAD);
5459
5460 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5461 rc= memcached_set(local_memc, "foo", strlen("foo"),
5462 NULL, 0,
5463 (time_t)0, (uint32_t)0);
5464 test_true(rc == MEMCACHED_SUCCESS);
5465
5466
5467 memcached_free(local_memc);
5468
5469 return TEST_SUCCESS;
5470 }
5471
5472 static test_return_t test_cull_servers(memcached_st *memc)
5473 {
5474 uint32_t count = memcached_server_count(memc);
5475
5476 // Do not do this in your code, it is not supported.
5477 memc->servers[1].state.is_dead= true;
5478 memc->state.is_time_for_rebuild= true;
5479
5480 uint32_t new_count= memcached_server_count(memc);
5481 test_true(count == new_count);
5482
5483 #if 0
5484 test_true(count == new_count + 1 );
5485 #endif
5486
5487 return TEST_SUCCESS;
5488 }
5489
5490
5491 static memcached_return_t stat_printer(memcached_server_instance_st server,
5492 const char *key, size_t key_length,
5493 const char *value, size_t value_length,
5494 void *context)
5495 {
5496 (void)server;
5497 (void)context;
5498 (void)key;
5499 (void)key_length;
5500 (void)value;
5501 (void)value_length;
5502
5503 return MEMCACHED_SUCCESS;
5504 }
5505
5506 static test_return_t memcached_stat_execute_test(memcached_st *memc)
5507 {
5508 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
5509 test_true(rc == MEMCACHED_SUCCESS);
5510
5511 rc= memcached_stat_execute(memc, "slabs", stat_printer, NULL);
5512 test_true(rc == MEMCACHED_SUCCESS);
5513
5514 rc= memcached_stat_execute(memc, "items", stat_printer, NULL);
5515 test_true(rc == MEMCACHED_SUCCESS);
5516
5517 rc= memcached_stat_execute(memc, "sizes", stat_printer, NULL);
5518 test_true(rc == MEMCACHED_SUCCESS);
5519
5520 return TEST_SUCCESS;
5521 }
5522
5523 /*
5524 * This test ensures that the failure counter isn't incremented during
5525 * normal termination of the memcached instance.
5526 */
5527 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5528 {
5529 memcached_return_t rc;
5530 memcached_server_instance_st instance;
5531
5532 /* Set value to force connection to the server */
5533 const char *key= "marmotte";
5534 const char *value= "milka";
5535
5536 /*
5537 * Please note that I'm abusing the internal structures in libmemcached
5538 * in a non-portable way and you shouldn't be doing this. I'm only
5539 * doing this in order to verify that the library works the way it should
5540 */
5541 uint32_t number_of_hosts= memcached_server_count(memc);
5542 memc->number_of_hosts= 1;
5543
5544 /* Ensure that we are connected to the server by setting a value */
5545 rc= memcached_set(memc, key, strlen(key),
5546 value, strlen(value),
5547 (time_t)0, (uint32_t)0);
5548 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5549
5550
5551 instance= memcached_server_instance_by_position(memc, 0);
5552 /* The test is to see that the memcached_quit doesn't increase the
5553 * the server failure conter, so let's ensure that it is zero
5554 * before sending quit
5555 */
5556 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5557
5558 memcached_quit(memc);
5559
5560 /* Verify that it memcached_quit didn't increment the failure counter
5561 * Please note that this isn't bullet proof, because an error could
5562 * occur...
5563 */
5564 test_true(instance->server_failure_counter == 0);
5565
5566 /* restore the instance */
5567 memc->number_of_hosts= number_of_hosts;
5568
5569 return TEST_SUCCESS;
5570 }
5571
5572 /*
5573 * This tests ensures expected disconnections (for some behavior changes
5574 * for instance) do not wrongly increase failure counter
5575 */
5576 static test_return_t wrong_failure_counter_two_test(memcached_st *memc)
5577 {
5578 memcached_return rc;
5579
5580 memcached_st *memc_clone;
5581 memc_clone= memcached_clone(NULL, memc);
5582 test_true(memc_clone);
5583
5584 /* Set value to force connection to the server */
5585 const char *key= "marmotte";
5586 const char *value= "milka";
5587 char *string = NULL;
5588 size_t string_length;
5589 uint32_t flags;
5590
5591 rc= memcached_set(memc_clone, key, strlen(key),
5592 value, strlen(value),
5593 (time_t)0, (uint32_t)0);
5594 test_true_got(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
5595
5596
5597 /* put failure limit to 1 */
5598 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5599 assert(rc == MEMCACHED_SUCCESS);
5600
5601 /* Put a retry timeout to effectively activate failure_limit effect */
5602 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1);
5603 assert(rc == MEMCACHED_SUCCESS);
5604
5605 /* change behavior that triggers memcached_quit()*/
5606 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5607 assert(rc == MEMCACHED_SUCCESS);
5608
5609
5610 /* Check if we still are connected */
5611 string= memcached_get(memc_clone, key, strlen(key),
5612 &string_length, &flags, &rc);
5613
5614 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
5615 test_true(string);
5616 free(string);
5617 memcached_free(memc_clone);
5618
5619 return TEST_SUCCESS;
5620 }
5621
5622
5623
5624
5625 /*
5626 * Test that ensures mget_execute does not end into recursive calls that finally fails
5627 */
5628 static test_return_t regression_bug_490486(memcached_st *memc)
5629 {
5630 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5631 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
5632 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5633 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5634 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5635
5636 #ifdef __APPLE__
5637 return TEST_SKIPPED; // My MAC can't handle this test
5638 #endif
5639
5640 /*
5641 * I only want to hit _one_ server so I know the number of requests I'm
5642 * sending in the pipeline.
5643 */
5644 uint32_t number_of_hosts= memc->number_of_hosts;
5645 memc->number_of_hosts= 1;
5646 size_t max_keys= 20480;
5647
5648
5649 char **keys= calloc(max_keys, sizeof(char*));
5650 size_t *key_length=calloc(max_keys, sizeof(size_t));
5651
5652 /* First add all of the items.. */
5653 bool slept= false;
5654 char blob[1024]= { 0 };
5655 memcached_return rc;
5656 for (size_t x= 0; x < max_keys; ++x)
5657 {
5658 char k[251];
5659 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5660 keys[x]= strdup(k);
5661 assert(keys[x] != NULL);
5662 rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5663 #ifdef __APPLE__
5664 if (rc == MEMCACHED_SERVER_MARKED_DEAD)
5665 {
5666 break; // We are out of business
5667 }
5668 #endif
5669 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT); // MEMCACHED_TIMEOUT <-- only observed on OSX
5670
5671 if (rc == MEMCACHED_TIMEOUT && slept == false)
5672 {
5673 x++;
5674 sleep(1);// We will try to sleep
5675 slept= true;
5676 }
5677 else if (rc == MEMCACHED_TIMEOUT && slept == true)
5678 {
5679 // We failed to send everything.
5680 break;
5681 }
5682 }
5683
5684 if (rc != MEMCACHED_SERVER_MARKED_DEAD)
5685 {
5686
5687 /* Try to get all of them with a large multiget */
5688 size_t counter= 0;
5689 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
5690 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
5691 (size_t)max_keys, callbacks, &counter, 1);
5692
5693 assert(rc == MEMCACHED_SUCCESS);
5694 char* the_value= NULL;
5695 char the_key[MEMCACHED_MAX_KEY];
5696 size_t the_key_length;
5697 size_t the_value_length;
5698 uint32_t the_flags;
5699
5700 do {
5701 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
5702
5703 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
5704 {
5705 ++counter;
5706 free(the_value);
5707 }
5708
5709 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
5710
5711
5712 assert(rc == MEMCACHED_END);
5713
5714 /* Verify that we got all of the items */
5715 assert(counter == max_keys);
5716 }
5717
5718 /* Release all allocated resources */
5719 for (size_t x= 0; x < max_keys; ++x)
5720 {
5721 free(keys[x]);
5722 }
5723 free(keys);
5724 free(key_length);
5725
5726 memc->number_of_hosts= number_of_hosts;
5727
5728 return TEST_SUCCESS;
5729 }
5730
5731 static test_return_t regression_bug_583031(memcached_st *unused)
5732 {
5733 (void)unused;
5734
5735 memcached_st *memc= memcached_create(NULL);
5736 assert(memc);
5737 memcached_server_add(memc, "10.2.3.4", 11211);
5738
5739 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
5740 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
5741 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
5742 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
5743 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5744 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
5745
5746 memcached_return_t rc;
5747 size_t length;
5748 uint32_t flags;
5749
5750 (void)memcached_get(memc, "dsf", 3, &length, &flags, &rc);
5751
5752 test_true_got(rc == MEMCACHED_TIMEOUT, memcached_strerror(NULL, rc));
5753
5754 memcached_free(memc);
5755
5756 return TEST_SUCCESS;
5757 }
5758
5759 // Look for memory leak
5760 static test_return_t regression_bug_728286(memcached_st *unused)
5761 {
5762 (void)unused;
5763 memcached_server_st *servers = memcached_servers_parse("1.2.3.4:99");
5764 memcached_server_free(servers);
5765
5766 return TEST_SUCCESS;
5767 }
5768
5769 static test_return_t regression_bug_581030(memcached_st *unused)
5770 {
5771 (void)unused;
5772
5773 #ifndef DEBUG
5774 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
5775 test_false(local_stat);
5776
5777 memcached_stat_free(NULL, NULL);
5778 #endif
5779
5780 return TEST_SUCCESS;
5781 }
5782
5783 static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
5784 {
5785 fprintf(stderr, "Iteration #%u: ", it);
5786
5787 if(error == MEMCACHED_ERRNO)
5788 {
5789 fprintf(stderr, "system error %d from %s: %s\n",
5790 errno, what, strerror(errno));
5791 }
5792 else
5793 {
5794 fprintf(stderr, "error %d from %s: %s\n", error, what,
5795 memcached_strerror(mc, error));
5796 }
5797 }
5798
5799 #define TEST_CONSTANT_CREATION 200
5800
5801 static test_return_t regression_bug_(memcached_st *memc)
5802 {
5803 const char *remote_server;
5804 (void)memc;
5805
5806 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
5807 {
5808 return TEST_SKIPPED;
5809 }
5810
5811 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
5812 {
5813 memcached_st* mc= memcached_create(NULL);
5814 memcached_return rc;
5815
5816 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5817 if (rc != MEMCACHED_SUCCESS)
5818 {
5819 memcached_die(mc, rc, "memcached_behavior_set", x);
5820 }
5821
5822 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
5823 if (rc != MEMCACHED_SUCCESS)
5824 {
5825 memcached_die(mc, rc, "memcached_behavior_set", x);
5826 }
5827
5828 rc= memcached_server_add(mc, remote_server, 0);
5829 if (rc != MEMCACHED_SUCCESS)
5830 {
5831 memcached_die(mc, rc, "memcached_server_add", x);
5832 }
5833
5834 const char *set_key= "akey";
5835 const size_t set_key_len= strlen(set_key);
5836 const char *set_value= "a value";
5837 const size_t set_value_len= strlen(set_value);
5838
5839 if (rc == MEMCACHED_SUCCESS)
5840 {
5841 if (x > 0)
5842 {
5843 size_t get_value_len;
5844 char *get_value;
5845 uint32_t get_value_flags;
5846
5847 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
5848 &get_value_flags, &rc);
5849 if (rc != MEMCACHED_SUCCESS)
5850 {
5851 memcached_die(mc, rc, "memcached_get", x);
5852 }
5853 else
5854 {
5855
5856 if (x != 0 &&
5857 (get_value_len != set_value_len
5858 || 0!=strncmp(get_value, set_value, get_value_len)))
5859 {
5860 fprintf(stderr, "Values don't match?\n");
5861 rc= MEMCACHED_FAILURE;
5862 }
5863 free(get_value);
5864 }
5865 }
5866
5867 rc= memcached_set(mc,
5868 set_key, set_key_len,
5869 set_value, set_value_len,
5870 0, /* time */
5871 0 /* flags */
5872 );
5873 if (rc != MEMCACHED_SUCCESS)
5874 {
5875 memcached_die(mc, rc, "memcached_set", x);
5876 }
5877 }
5878
5879 memcached_quit(mc);
5880 memcached_free(mc);
5881
5882 if (rc != MEMCACHED_SUCCESS)
5883 {
5884 break;
5885 }
5886 }
5887
5888 return TEST_SUCCESS;
5889 }
5890
5891 /*
5892 * Test that the sasl authentication works. We cannot use the default
5893 * pool of servers, because that would require that all servers we want
5894 * to test supports SASL authentication, and that they use the default
5895 * creds.
5896 */
5897 static test_return_t sasl_auth_test(memcached_st *memc)
5898 {
5899 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
5900 memcached_return_t rc;
5901
5902 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
5903 test_true(rc == MEMCACHED_SUCCESS);
5904 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_SUCCESS);
5905 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_SUCCESS);
5906 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_FAILURE);
5907 test_true((rc= memcached_destroy_sasl_auth_data(NULL)) == MEMCACHED_FAILURE);
5908 memcached_quit(memc);
5909
5910 rc= memcached_set_sasl_auth_data(memc,
5911 getenv("LIBMEMCACHED_TEST_SASL_USERNAME"),
5912 getenv("LIBMEMCACHED_TEST_SASL_SERVER"));
5913 test_true(rc == MEMCACHED_SUCCESS);
5914
5915 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
5916 test_true(rc == MEMCACHED_AUTH_FAILURE);
5917 test_true(memcached_destroy_sasl_auth_data(memc) == MEMCACHED_SUCCESS);
5918
5919 memcached_quit(memc);
5920 return TEST_SUCCESS;
5921 #else
5922 (void)memc;
5923 return TEST_FAILURE;
5924 #endif
5925 }
5926
5927 /* Clean the server before beginning testing */
5928 test_st tests[] ={
5929 {"util_version", 1, (test_callback_fn)util_version_test },
5930 {"flush", 0, (test_callback_fn)flush_test },
5931 {"init", 0, (test_callback_fn)init_test },
5932 {"allocation", 0, (test_callback_fn)allocation_test },
5933 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
5934 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
5935 {"server_sort", 0, (test_callback_fn)server_sort_test},
5936 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
5937 {"memcached_server_remove", 0, (test_callback_fn)memcached_server_remove_test},
5938 {"clone_test", 0, (test_callback_fn)clone_test },
5939 {"connection_test", 0, (test_callback_fn)connection_test},
5940 {"callback_test", 0, (test_callback_fn)callback_test},
5941 {"userdata_test", 0, (test_callback_fn)userdata_test},
5942 {"error", 0, (test_callback_fn)error_test },
5943 {"set", 0, (test_callback_fn)set_test },
5944 {"set2", 0, (test_callback_fn)set_test2 },
5945 {"set3", 0, (test_callback_fn)set_test3 },
5946 {"dump", 1, (test_callback_fn)dump_test},
5947 {"add", 1, (test_callback_fn)add_test },
5948 {"replace", 1, (test_callback_fn)replace_test },
5949 {"delete", 1, (test_callback_fn)delete_test },
5950 {"get", 1, (test_callback_fn)get_test },
5951 {"get2", 0, (test_callback_fn)get_test2 },
5952 {"get3", 0, (test_callback_fn)get_test3 },
5953 {"get4", 0, (test_callback_fn)get_test4 },
5954 {"partial mget", 0, (test_callback_fn)get_test5 },
5955 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
5956 {"increment", 0, (test_callback_fn)increment_test },
5957 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
5958 {"decrement", 0, (test_callback_fn)decrement_test },
5959 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
5960 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
5961 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
5962 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
5963 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
5964 {"quit", 0, (test_callback_fn)quit_test },
5965 {"mget", 1, (test_callback_fn)mget_test },
5966 {"mget_result", 1, (test_callback_fn)mget_result_test },
5967 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
5968 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
5969 {"mget_execute", 1, (test_callback_fn)mget_execute },
5970 {"mget_end", 0, (test_callback_fn)mget_end },
5971 {"get_stats", 0, (test_callback_fn)get_stats },
5972 {"add_host_test", 0, (test_callback_fn)add_host_test },
5973 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
5974 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
5975 {"version_string_test", 0, (test_callback_fn)version_string_test},
5976 {"bad_key", 1, (test_callback_fn)bad_key_test },
5977 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
5978 {"read_through", 1, (test_callback_fn)read_through },
5979 {"delete_through", 1, (test_callback_fn)delete_through },
5980 {"noreply", 1, (test_callback_fn)noreply_test},
5981 {"analyzer", 1, (test_callback_fn)analyzer_test},
5982 #ifdef HAVE_LIBMEMCACHEDUTIL
5983 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
5984 {"ping", 1, (test_callback_fn)ping_test },
5985 #endif
5986 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
5987 {"verbosity", 1, (test_callback_fn)test_verbosity},
5988 {"test_server_failure", 1, (test_callback_fn)test_server_failure},
5989 {"cull_servers", 1, (test_callback_fn)test_cull_servers},
5990 {"memcached_stat_execute", 1, (test_callback_fn)memcached_stat_execute_test},
5991 {0, 0, 0}
5992 };
5993
5994 test_st behavior_tests[] ={
5995 {"behavior_test", 0, (test_callback_fn)behavior_test},
5996 {"MEMCACHED_BEHAVIOR_CORK", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_CORK_test},
5997 {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
5998 {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
5999 {0, 0, 0}
6000 };
6001
6002 test_st basic_tests[] ={
6003 {"init", 1, (test_callback_fn)basic_init_test},
6004 {"clone", 1, (test_callback_fn)basic_clone_test},
6005 {"reset", 1, (test_callback_fn)basic_reset_stack_test},
6006 {"reset heap", 1, (test_callback_fn)basic_reset_heap_test},
6007 {"reset stack clone", 1, (test_callback_fn)basic_reset_stack_clone_test},
6008 {"reset heap clone", 1, (test_callback_fn)basic_reset_heap_clone_test},
6009 {0, 0, 0}
6010 };
6011
6012 test_st regression_binary_vs_block[] ={
6013 {"block add", 1, (test_callback_fn)block_add_regression},
6014 {"binary add", 1, (test_callback_fn)binary_add_regression},
6015 {0, 0, 0}
6016 };
6017
6018 test_st async_tests[] ={
6019 {"add", 1, (test_callback_fn)add_wrapper },
6020 {0, 0, 0}
6021 };
6022
6023 test_st string_tests[] ={
6024 {"string static with null", 0, (test_callback_fn)string_static_null },
6025 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
6026 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
6027 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
6028 {"string append", 0, (test_callback_fn)string_alloc_append },
6029 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
6030 {"string_alloc_append_multiple", 0, (test_callback_fn)string_alloc_append_multiple },
6031 {0, 0, (test_callback_fn)0}
6032 };
6033
6034 test_st result_tests[] ={
6035 {"result static", 0, (test_callback_fn)result_static},
6036 {"result alloc", 0, (test_callback_fn)result_alloc},
6037 {0, 0, (test_callback_fn)0}
6038 };
6039
6040 test_st version_1_2_3[] ={
6041 {"append", 0, (test_callback_fn)append_test },
6042 {"prepend", 0, (test_callback_fn)prepend_test },
6043 {"cas", 0, (test_callback_fn)cas_test },
6044 {"cas2", 0, (test_callback_fn)cas2_test },
6045 {"append_binary", 0, (test_callback_fn)append_binary_test },
6046 {0, 0, (test_callback_fn)0}
6047 };
6048
6049 test_st user_tests[] ={
6050 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
6051 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
6052 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
6053 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
6054 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
6055 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
6056 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
6057 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
6058 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
6059 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
6060 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
6061 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
6062 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
6063 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
6064 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
6065 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
6066 #if !defined(__sun) && !defined(__OpenBSD__)
6067 /*
6068 ** It seems to be something weird with the character sets..
6069 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
6070 ** guess I need to find out how this is supposed to work.. Perhaps I need
6071 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
6072 ** so just disable the code for now...).
6073 */
6074 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
6075 #endif
6076 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
6077 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
6078 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
6079 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
6080 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
6081 {"wrong_failure_counter_two_test", 1, (test_callback_fn)wrong_failure_counter_two_test},
6082 {0, 0, (test_callback_fn)0}
6083 };
6084
6085 test_st replication_tests[]= {
6086 {"set", 1, (test_callback_fn)replication_set_test },
6087 {"get", 0, (test_callback_fn)replication_get_test },
6088 {"mget", 0, (test_callback_fn)replication_mget_test },
6089 {"delete", 0, (test_callback_fn)replication_delete_test },
6090 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
6091 {0, 0, (test_callback_fn)0}
6092 };
6093
6094 /*
6095 * The following test suite is used to verify that we don't introduce
6096 * regression bugs. If you want more information about the bug / test,
6097 * you should look in the bug report at
6098 * http://bugs.launchpad.net/libmemcached
6099 */
6100 test_st regression_tests[]= {
6101 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
6102 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
6103 {"lp:434843-buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
6104 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
6105 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
6106 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
6107 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
6108 {"lp:490486", 1, (test_callback_fn)regression_bug_490486 },
6109 {"lp:583031", 1, (test_callback_fn)regression_bug_583031 },
6110 {"lp:?", 1, (test_callback_fn)regression_bug_ },
6111 {"lp:728286", 1, (test_callback_fn)regression_bug_728286 },
6112 {"lp:581030", 1, (test_callback_fn)regression_bug_581030 },
6113 {0, 0, (test_callback_fn)0}
6114 };
6115
6116 test_st sasl_auth_tests[]= {
6117 {"sasl_auth", 1, (test_callback_fn)sasl_auth_test },
6118 {0, 0, (test_callback_fn)0}
6119 };
6120
6121 test_st ketama_compatibility[]= {
6122 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
6123 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
6124 {0, 0, (test_callback_fn)0}
6125 };
6126
6127 test_st generate_tests[] ={
6128 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6129 {"generate_data", 1, (test_callback_fn)generate_data },
6130 {"get_read", 0, (test_callback_fn)get_read },
6131 {"delete_generate", 0, (test_callback_fn)delete_generate },
6132 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
6133 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
6134 {"generate_data", 1, (test_callback_fn)generate_data },
6135 {"mget_read", 0, (test_callback_fn)mget_read },
6136 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
6137 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
6138 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6139 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
6140 {"generate_data", 1, (test_callback_fn)generate_data },
6141 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
6142 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6143 {0, 0, (test_callback_fn)0}
6144 };
6145
6146 test_st consistent_tests[] ={
6147 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6148 {"generate_data", 1, (test_callback_fn)generate_data },
6149 {"get_read", 0, (test_callback_fn)get_read_count },
6150 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6151 {0, 0, (test_callback_fn)0}
6152 };
6153
6154 test_st consistent_weighted_tests[] ={
6155 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6156 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
6157 {"get_read", 0, (test_callback_fn)get_read_count },
6158 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6159 {0, 0, (test_callback_fn)0}
6160 };
6161
6162 test_st hsieh_availability[] ={
6163 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
6164 {0, 0, (test_callback_fn)0}
6165 };
6166
6167 test_st murmur_availability[] ={
6168 {"murmur_avaibility_test", 0, (test_callback_fn)murmur_avaibility_test},
6169 {0, 0, (test_callback_fn)0}
6170 };
6171
6172 #if 0
6173 test_st hash_sanity[] ={
6174 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
6175 {0, 0, (test_callback_fn)0}
6176 };
6177 #endif
6178
6179 test_st ketama_auto_eject_hosts[] ={
6180 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
6181 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
6182 {0, 0, (test_callback_fn)0}
6183 };
6184
6185 test_st hash_tests[] ={
6186 {"one_at_a_time_run", 0, (test_callback_fn)one_at_a_time_run },
6187 {"md5", 0, (test_callback_fn)md5_run },
6188 {"crc", 0, (test_callback_fn)crc_run },
6189 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
6190 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
6191 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
6192 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
6193 {"hsieh", 0, (test_callback_fn)hsieh_run },
6194 {"murmur", 0, (test_callback_fn)murmur_run },
6195 {"jenkis", 0, (test_callback_fn)jenkins_run },
6196 {"memcached_get_hashkit", 0, (test_callback_fn)memcached_get_hashkit_test },
6197 {0, 0, (test_callback_fn)0}
6198 };
6199
6200 test_st error_conditions[] ={
6201 {"memcached_get(MEMCACHED_ERRNO)", 0, (test_callback_fn)memcached_get_MEMCACHED_ERRNO },
6202 {"memcached_get(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND },
6203 {"memcached_get_by_key(MEMCACHED_ERRNO)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_ERRNO },
6204 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
6205 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
6206 {"memcached_increment(MEMCACHED_NO_SERVERS)", 0, (test_callback_fn)memcached_increment_MEMCACHED_NO_SERVERS },
6207 {0, 0, (test_callback_fn)0}
6208 };
6209
6210
6211 test_st parser_tests[] ={
6212 {"behavior", 0, (test_callback_fn)behavior_parser_test },
6213 {"boolean_options", 0, (test_callback_fn)parser_boolean_options_test },
6214 {"configure_file", 0, (test_callback_fn)memcached_create_with_options_with_filename },
6215 {"distribtions", 0, (test_callback_fn)parser_distribution_test },
6216 {"hash", 0, (test_callback_fn)parser_hash_test },
6217 {"libmemcached_check_configuration", 0, (test_callback_fn)libmemcached_check_configuration_test },
6218 {"libmemcached_check_configuration_with_filename", 0, (test_callback_fn)libmemcached_check_configuration_with_filename_test },
6219 {"memcached_parse_configure_file", 0, (test_callback_fn)memcached_parse_configure_file_test },
6220 {"number_options", 0, (test_callback_fn)parser_number_options_test },
6221 {"randomly generated options", 0, (test_callback_fn)random_statement_build_test },
6222 {"prefix_key", 0, (test_callback_fn)parser_key_prefix_test },
6223 {"server", 0, (test_callback_fn)server_test },
6224 {"servers", 0, (test_callback_fn)servers_test },
6225 {0, 0, (test_callback_fn)0}
6226 };
6227
6228 collection_st collection[] ={
6229 #if 0
6230 {"hash_sanity", 0, 0, hash_sanity},
6231 #endif
6232 {"basic", 0, 0, basic_tests},
6233 {"hsieh_availability", 0, 0, hsieh_availability},
6234 {"murmur_availability", 0, 0, murmur_availability},
6235 {"block", 0, 0, tests},
6236 {"binary", (test_callback_fn)pre_binary, 0, tests},
6237 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
6238 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6239 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
6240 {"md5", (test_callback_fn)pre_md5, 0, tests},
6241 {"crc", (test_callback_fn)pre_crc, 0, tests},
6242 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
6243 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
6244 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
6245 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
6246 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
6247 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
6248 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
6249 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
6250 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
6251 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6252 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
6253 {"gets", (test_callback_fn)enable_cas, 0, tests},
6254 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
6255 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
6256 #ifdef MEMCACHED_ENABLE_DEPRECATED
6257 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
6258 #endif
6259 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
6260 {"prefix", (test_callback_fn)set_prefix, 0, tests},
6261 {"sasl_auth", (test_callback_fn)pre_sasl, 0, sasl_auth_tests },
6262 {"sasl", (test_callback_fn)pre_sasl, 0, tests },
6263 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
6264 {"string", 0, 0, string_tests},
6265 {"result", 0, 0, result_tests},
6266 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
6267 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
6268 {"user", 0, 0, user_tests},
6269 {"generate", 0, 0, generate_tests},
6270 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
6271 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
6272 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
6273 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
6274 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
6275 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
6276 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
6277 // Too slow
6278 {"generate_corked", (test_callback_fn)pre_cork, 0, generate_tests},
6279 {"generate_corked_and_nonblock", (test_callback_fn)pre_cork_and_nonblock, 0, generate_tests},
6280 {"consistent_not", 0, 0, consistent_tests},
6281 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
6282 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
6283 {"ketama_compat", 0, 0, ketama_compatibility},
6284 {"test_hashes", 0, 0, hash_tests},
6285 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
6286 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
6287 {"regression", 0, 0, regression_tests},
6288 {"behaviors", 0, 0, behavior_tests},
6289 {"regression_binary_vs_block", (test_callback_fn)key_setup, (test_callback_fn)key_teardown, regression_binary_vs_block},
6290 {"error_conditions", 0, 0, error_conditions},
6291 {"parser", 0, 0, parser_tests},
6292 {0, 0, 0, 0}
6293 };
6294
6295 #define SERVERS_TO_CREATE 5
6296
6297 #include "libmemcached_world.h"
6298
6299 void get_world(world_st *world)
6300 {
6301 world->collections= collection;
6302
6303 world->create= (test_callback_create_fn)world_create;
6304 world->destroy= (test_callback_fn)world_destroy;
6305
6306 world->test.startup= (test_callback_fn)world_test_startup;
6307 world->test.flush= (test_callback_fn)world_flush;
6308 world->test.pre_run= (test_callback_fn)world_pre_run;
6309 world->test.post_run= (test_callback_fn)world_post_run;
6310 world->test.on_error= (test_callback_error_fn)world_on_error;
6311
6312 world->collection.startup= (test_callback_fn)world_container_startup;
6313 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
6314
6315 world->runner= &defualt_libmemcached_runner;
6316 }