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