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