Small cleanup for for() to array.
[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 (int 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 (int 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 printf("\nserver %u|%s|%u bytes: %llu\n", host_index, (memc->hosts)[host_index].hostname, (memc->hosts)[host_index].port, (unsigned long long)(stat_p + host_index)->bytes);
3182 #endif
3183 test_truth((unsigned long long)(stat_p + host_index)->bytes);
3184 }
3185
3186 memcached_stat_free(NULL, stat_p);
3187
3188 return TEST_SUCCESS;
3189 }
3190 static test_return_t generate_buffer_data(memcached_st *memc)
3191 {
3192 size_t latch= 0;
3193
3194 latch= 1;
3195 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3196 generate_data(memc);
3197
3198 return TEST_SUCCESS;
3199 }
3200
3201 static test_return_t get_read_count(memcached_st *memc)
3202 {
3203 memcached_return_t rc;
3204 memcached_st *memc_clone;
3205
3206 memc_clone= memcached_clone(NULL, memc);
3207 test_truth(memc_clone);
3208
3209 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3210
3211 {
3212 char *return_value;
3213 size_t return_value_length;
3214 uint32_t flags;
3215 uint32_t count;
3216
3217 for (size_t x= count= 0; x < global_count; x++)
3218 {
3219 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3220 &return_value_length, &flags, &rc);
3221 if (rc == MEMCACHED_SUCCESS)
3222 {
3223 count++;
3224 if (return_value)
3225 free(return_value);
3226 }
3227 }
3228 }
3229
3230 memcached_free(memc_clone);
3231
3232 return TEST_SUCCESS;
3233 }
3234
3235 static test_return_t get_read(memcached_st *memc)
3236 {
3237 memcached_return_t rc;
3238
3239 {
3240 char *return_value;
3241 size_t return_value_length;
3242 uint32_t flags;
3243
3244 for (size_t x= 0; x < global_count; x++)
3245 {
3246 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3247 &return_value_length, &flags, &rc);
3248 /*
3249 test_truth(return_value);
3250 test_truth(rc == MEMCACHED_SUCCESS);
3251 */
3252 if (rc == MEMCACHED_SUCCESS && return_value)
3253 free(return_value);
3254 }
3255 }
3256
3257 return TEST_SUCCESS;
3258 }
3259
3260 static test_return_t mget_read(memcached_st *memc)
3261 {
3262 memcached_return_t rc;
3263
3264 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3265 test_truth(rc == MEMCACHED_SUCCESS);
3266 test_truth(fetch_all_results(memc) == TEST_SUCCESS);
3267
3268 return TEST_SUCCESS;
3269 }
3270
3271 static test_return_t mget_read_result(memcached_st *memc)
3272 {
3273 memcached_return_t rc;
3274
3275 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3276 test_truth(rc == MEMCACHED_SUCCESS);
3277 /* Turn this into a help function */
3278 {
3279 memcached_result_st results_obj;
3280 memcached_result_st *results;
3281
3282 results= memcached_result_create(memc, &results_obj);
3283
3284 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3285 {
3286 test_truth(results);
3287 test_truth(rc == MEMCACHED_SUCCESS);
3288 }
3289
3290 memcached_result_free(&results_obj);
3291 }
3292
3293 return TEST_SUCCESS;
3294 }
3295
3296 static test_return_t mget_read_function(memcached_st *memc)
3297 {
3298 memcached_return_t rc;
3299 size_t counter;
3300 memcached_execute_fn callbacks[1];
3301
3302 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3303 test_truth(rc == MEMCACHED_SUCCESS);
3304
3305 callbacks[0]= &callback_counter;
3306 counter= 0;
3307 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3308
3309 return TEST_SUCCESS;
3310 }
3311
3312 static test_return_t delete_generate(memcached_st *memc)
3313 {
3314 for (size_t x= 0; x < global_count; x++)
3315 {
3316 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3317 }
3318
3319 return TEST_SUCCESS;
3320 }
3321
3322 static test_return_t delete_buffer_generate(memcached_st *memc)
3323 {
3324 uint64_t latch= 0;
3325
3326 latch= 1;
3327 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3328
3329 for (size_t x= 0; x < global_count; x++)
3330 {
3331 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3332 }
3333
3334 return TEST_SUCCESS;
3335 }
3336
3337 static test_return_t add_host_test1(memcached_st *memc)
3338 {
3339 memcached_return_t rc;
3340 char servername[]= "0.example.com";
3341 memcached_server_st *servers;
3342
3343 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3344 test_truth(servers);
3345 test_truth(1 == memcached_server_list_count(servers));
3346
3347 for (size_t x= 2; x < 20; x++)
3348 {
3349 char buffer[SMALL_STRING_LEN];
3350
3351 snprintf(buffer, SMALL_STRING_LEN, "%zu.example.com", 400+x);
3352 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3353 &rc);
3354 test_truth(rc == MEMCACHED_SUCCESS);
3355 test_truth(x == memcached_server_list_count(servers));
3356 }
3357
3358 rc= memcached_server_push(memc, servers);
3359 test_truth(rc == MEMCACHED_SUCCESS);
3360 rc= memcached_server_push(memc, servers);
3361 test_truth(rc == MEMCACHED_SUCCESS);
3362
3363 memcached_server_list_free(servers);
3364
3365 return TEST_SUCCESS;
3366 }
3367
3368 static test_return_t pre_nonblock(memcached_st *memc)
3369 {
3370 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3371
3372 return TEST_SUCCESS;
3373 }
3374
3375 static test_return_t pre_nonblock_binary(memcached_st *memc)
3376 {
3377 memcached_return_t rc= MEMCACHED_FAILURE;
3378 memcached_st *memc_clone;
3379 memcached_server_instance_st *instance;
3380
3381 memc_clone= memcached_clone(NULL, memc);
3382 test_truth(memc_clone);
3383 // The memcached_version needs to be done on a clone, because the server
3384 // will not toggle protocol on an connection.
3385 memcached_version(memc_clone);
3386
3387 instance= memcached_server_instance_fetch(memc_clone, 0);
3388
3389 if (instance->major_version >= 1 && instance->minor_version > 2)
3390 {
3391 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3392 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3393 test_truth(rc == MEMCACHED_SUCCESS);
3394 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3395 }
3396 else
3397 {
3398 return TEST_SKIPPED;
3399 }
3400
3401 memcached_free(memc_clone);
3402
3403 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3404 }
3405
3406 static test_return_t pre_murmur(memcached_st *memc)
3407 {
3408 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3409
3410 return TEST_SUCCESS;
3411 }
3412
3413 static test_return_t pre_jenkins(memcached_st *memc)
3414 {
3415 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3416
3417 return TEST_SUCCESS;
3418 }
3419
3420
3421 static test_return_t pre_md5(memcached_st *memc)
3422 {
3423 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3424
3425 return TEST_SUCCESS;
3426 }
3427
3428 static test_return_t pre_crc(memcached_st *memc)
3429 {
3430 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3431
3432 return TEST_SUCCESS;
3433 }
3434
3435 static test_return_t pre_hsieh(memcached_st *memc)
3436 {
3437 #ifdef HAVE_HSIEH_HASH
3438 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3439 return TEST_SUCCESS;
3440 #else
3441 (void) memc;
3442 return TEST_SKIPPED;
3443 #endif
3444 }
3445
3446 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3447 {
3448 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3449
3450 return TEST_SUCCESS;
3451 }
3452
3453 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3454 {
3455 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3456
3457 return TEST_SUCCESS;
3458 }
3459
3460 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3461 {
3462 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3463
3464 return TEST_SUCCESS;
3465 }
3466
3467 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3468 {
3469 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3470
3471 return TEST_SUCCESS;
3472 }
3473
3474 static test_return_t pre_behavior_ketama(memcached_st *memc)
3475 {
3476 memcached_return_t rc;
3477 uint64_t value;
3478
3479 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3480 test_truth(rc == MEMCACHED_SUCCESS);
3481
3482 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3483 test_truth(value == 1);
3484
3485 return TEST_SUCCESS;
3486 }
3487
3488 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3489 {
3490 memcached_return_t rc;
3491 uint64_t value;
3492
3493 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3494 test_truth(rc == MEMCACHED_SUCCESS);
3495
3496 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3497 test_truth(value == 1);
3498
3499 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3500 test_truth(rc == MEMCACHED_SUCCESS);
3501
3502 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3503 test_truth(value == MEMCACHED_HASH_MD5);
3504
3505 return TEST_SUCCESS;
3506 }
3507
3508 /**
3509 @note This should be testing to see if the server really supports the binary protocol.
3510 */
3511 static test_return_t pre_binary(memcached_st *memc)
3512 {
3513 memcached_return_t rc= MEMCACHED_FAILURE;
3514 memcached_st *memc_clone;
3515 memcached_server_instance_st *instance;
3516
3517 memc_clone= memcached_clone(NULL, memc);
3518 test_truth(memc_clone);
3519 // The memcached_version needs to be done on a clone, because the server
3520 // will not toggle protocol on an connection.
3521 memcached_version(memc_clone);
3522
3523 instance= memcached_server_instance_fetch(memc_clone, 0);
3524
3525 if (instance->major_version >= 1 && instance->minor_version > 2)
3526 {
3527 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3528 test_truth(rc == MEMCACHED_SUCCESS);
3529 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3530 }
3531
3532 memcached_free(memc_clone);
3533
3534 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3535 }
3536
3537
3538 static test_return_t pre_replication(memcached_st *memc)
3539 {
3540 test_return_t test_rc;
3541 test_rc= pre_binary(memc);
3542
3543 if (test_rc != TEST_SUCCESS)
3544 return test_rc;
3545
3546 /*
3547 * Make sure that we store the item on all servers
3548 * (master + replicas == number of servers)
3549 */
3550 memcached_return_t rc;
3551 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3552 memcached_server_count(memc) - 1);
3553 test_truth(rc == MEMCACHED_SUCCESS);
3554 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memcached_server_count(memc) - 1);
3555
3556 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3557 }
3558
3559
3560 static test_return_t pre_replication_noblock(memcached_st *memc)
3561 {
3562 test_return_t rc;
3563
3564 rc= pre_replication(memc);
3565 if (rc != TEST_SUCCESS)
3566 return rc;
3567
3568 rc= pre_nonblock(memc);
3569
3570 return rc;
3571 }
3572
3573
3574 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3575 {
3576 #ifdef HARD_MALLOC_TESTS
3577 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3578 free(real_ptr);
3579 #else
3580 free(mem);
3581 #endif
3582 }
3583
3584
3585 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3586 {
3587 #ifdef HARD_MALLOC_TESTS
3588 void *ret= malloc(size + 8);
3589 if (ret != NULL)
3590 {
3591 ret= (void*)((caddr_t)ret + 8);
3592 }
3593 #else
3594 void *ret= malloc(size);
3595 #endif
3596
3597 if (ret != NULL)
3598 {
3599 memset(ret, 0xff, size);
3600 }
3601
3602 return ret;
3603 }
3604
3605
3606 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3607 {
3608 #ifdef HARD_MALLOC_TESTS
3609 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3610 void *nmem= realloc(real_ptr, size + 8);
3611
3612 void *ret= NULL;
3613 if (nmem != NULL)
3614 {
3615 ret= (void*)((caddr_t)nmem + 8);
3616 }
3617
3618 return ret;
3619 #else
3620 return realloc(mem, size);
3621 #endif
3622 }
3623
3624
3625 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3626 {
3627 #ifdef HARD_MALLOC_TESTS
3628 void *mem= my_malloc(ptr, nelem * size);
3629 if (mem)
3630 {
3631 memset(mem, 0, nelem * size);
3632 }
3633
3634 return mem;
3635 #else
3636 return calloc(nelem, size);
3637 #endif
3638 }
3639
3640
3641 static test_return_t set_prefix(memcached_st *memc)
3642 {
3643 memcached_return_t rc;
3644 const char *key= "mine";
3645 char *value;
3646
3647 /* Make sure be default none exists */
3648 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3649 test_truth(rc == MEMCACHED_FAILURE);
3650
3651 /* Test a clean set */
3652 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3653 test_truth(rc == MEMCACHED_SUCCESS);
3654
3655 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3656 test_truth(memcmp(value, key, 4) == 0);
3657 test_truth(rc == MEMCACHED_SUCCESS);
3658
3659 /* Test that we can turn it off */
3660 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3661 test_truth(rc == MEMCACHED_SUCCESS);
3662
3663 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3664 test_truth(rc == MEMCACHED_FAILURE);
3665
3666 /* Now setup for main test */
3667 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3668 test_truth(rc == MEMCACHED_SUCCESS);
3669
3670 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3671 test_truth(rc == MEMCACHED_SUCCESS);
3672 test_truth(memcmp(value, key, 4) == 0);
3673
3674 /* Set to Zero, and then Set to something too large */
3675 {
3676 char long_key[255];
3677 memset(long_key, 0, 255);
3678
3679 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3680 test_truth(rc == MEMCACHED_SUCCESS);
3681
3682 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3683 test_truth(rc == MEMCACHED_FAILURE);
3684 test_truth(value == NULL);
3685
3686 /* Test a long key for failure */
3687 /* TODO, extend test to determine based on setting, what result should be */
3688 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3689 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3690 //test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3691 test_truth(rc == MEMCACHED_SUCCESS);
3692
3693 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3694 strcpy(long_key, "This is more then the allotted number of characters");
3695 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3696 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3697
3698 /* Test for a bad prefix, but with a short key */
3699 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3700 test_truth(rc == MEMCACHED_SUCCESS);
3701
3702 strcpy(long_key, "dog cat");
3703 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3704 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3705 }
3706
3707 return TEST_SUCCESS;
3708 }
3709
3710
3711 #ifdef MEMCACHED_ENABLE_DEPRECATED
3712 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3713 {
3714 void *test_ptr= NULL;
3715 void *cb_ptr= NULL;
3716 {
3717 memcached_malloc_fn malloc_cb=
3718 (memcached_malloc_fn)my_malloc;
3719 cb_ptr= *(void **)&malloc_cb;
3720 memcached_return_t rc;
3721
3722 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3723 test_truth(rc == MEMCACHED_SUCCESS);
3724 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3725 test_truth(rc == MEMCACHED_SUCCESS);
3726 test_truth(test_ptr == cb_ptr);
3727 }
3728
3729 {
3730 memcached_realloc_fn realloc_cb=
3731 (memcached_realloc_fn)my_realloc;
3732 cb_ptr= *(void **)&realloc_cb;
3733 memcached_return_t rc;
3734
3735 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3736 test_truth(rc == MEMCACHED_SUCCESS);
3737 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3738 test_truth(rc == MEMCACHED_SUCCESS);
3739 test_truth(test_ptr == cb_ptr);
3740 }
3741
3742 {
3743 memcached_free_fn free_cb=
3744 (memcached_free_fn)my_free;
3745 cb_ptr= *(void **)&free_cb;
3746 memcached_return_t rc;
3747
3748 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3749 test_truth(rc == MEMCACHED_SUCCESS);
3750 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3751 test_truth(rc == MEMCACHED_SUCCESS);
3752 test_truth(test_ptr == cb_ptr);
3753 }
3754
3755 return TEST_SUCCESS;
3756 }
3757 #endif
3758
3759
3760 static test_return_t set_memory_alloc(memcached_st *memc)
3761 {
3762 memcached_return_t rc;
3763 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3764 my_realloc, my_calloc);
3765 test_truth(rc == MEMCACHED_FAILURE);
3766
3767 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3768 my_realloc, my_calloc);
3769
3770 memcached_malloc_fn mem_malloc;
3771 memcached_free_fn mem_free;
3772 memcached_realloc_fn mem_realloc;
3773 memcached_calloc_fn mem_calloc;
3774 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3775 &mem_realloc, &mem_calloc);
3776
3777 test_truth(mem_malloc == my_malloc);
3778 test_truth(mem_realloc == my_realloc);
3779 test_truth(mem_calloc == my_calloc);
3780 test_truth(mem_free == my_free);
3781
3782 return TEST_SUCCESS;
3783 }
3784
3785 static test_return_t enable_consistent_crc(memcached_st *memc)
3786 {
3787 test_return_t rc;
3788 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3789 memcached_hash_t hash;
3790 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3791 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3792 return rc;
3793
3794 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3795 test_truth(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3796
3797 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3798
3799 if (hash != MEMCACHED_HASH_CRC)
3800 return TEST_SKIPPED;
3801
3802 return TEST_SUCCESS;
3803 }
3804
3805 static test_return_t enable_consistent_hsieh(memcached_st *memc)
3806 {
3807 test_return_t rc;
3808 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3809 memcached_hash_t hash;
3810 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3811 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3812 return rc;
3813
3814 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3815 test_truth(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3816
3817 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3818
3819 if (hash != MEMCACHED_HASH_HSIEH)
3820 return TEST_SKIPPED;
3821
3822
3823 return TEST_SUCCESS;
3824 }
3825
3826 static test_return_t enable_cas(memcached_st *memc)
3827 {
3828 unsigned int set= 1;
3829
3830 memcached_server_instance_st *instance=
3831 memcached_server_instance_fetch(memc, 0);
3832
3833 memcached_version(memc);
3834
3835 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3836 || instance->minor_version > 2)
3837 {
3838 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3839
3840 return TEST_SUCCESS;
3841 }
3842
3843 return TEST_SKIPPED;
3844 }
3845
3846 static test_return_t check_for_1_2_3(memcached_st *memc)
3847 {
3848 memcached_version(memc);
3849 memcached_server_instance_st *instance=
3850 memcached_server_instance_fetch(memc, 0);
3851
3852 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3853 || instance->minor_version > 2)
3854 return TEST_SUCCESS;
3855
3856 return TEST_SKIPPED;
3857 }
3858
3859 static test_return_t pre_unix_socket(memcached_st *memc)
3860 {
3861 memcached_return_t rc;
3862 struct stat buf;
3863
3864 memcached_servers_reset(memc);
3865
3866 if (stat("/tmp/memcached.socket", &buf))
3867 return TEST_SKIPPED;
3868
3869 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3870
3871 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
3872 }
3873
3874 static test_return_t pre_nodelay(memcached_st *memc)
3875 {
3876 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3877 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3878
3879 return TEST_SUCCESS;
3880 }
3881
3882 static test_return_t pre_settimer(memcached_st *memc)
3883 {
3884 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3885 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3886
3887 return TEST_SUCCESS;
3888 }
3889
3890 static test_return_t poll_timeout(memcached_st *memc)
3891 {
3892 size_t timeout;
3893
3894 timeout= 100;
3895
3896 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3897
3898 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3899
3900 test_truth(timeout == 100);
3901
3902 return TEST_SUCCESS;
3903 }
3904
3905 static test_return_t noreply_test(memcached_st *memc)
3906 {
3907 memcached_return_t ret;
3908 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3909 test_truth(ret == MEMCACHED_SUCCESS);
3910 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3911 test_truth(ret == MEMCACHED_SUCCESS);
3912 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3913 test_truth(ret == MEMCACHED_SUCCESS);
3914 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3915 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3916 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3917
3918 for (int count=0; count < 5; ++count)
3919 {
3920 for (size_t x= 0; x < 100; ++x)
3921 {
3922 char key[10];
3923 size_t len= (size_t)sprintf(key, "%zu", x);
3924 switch (count)
3925 {
3926 case 0:
3927 ret= memcached_add(memc, key, len, key, len, 0, 0);
3928 break;
3929 case 1:
3930 ret= memcached_replace(memc, key, len, key, len, 0, 0);
3931 break;
3932 case 2:
3933 ret= memcached_set(memc, key, len, key, len, 0, 0);
3934 break;
3935 case 3:
3936 ret= memcached_append(memc, key, len, key, len, 0, 0);
3937 break;
3938 case 4:
3939 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
3940 break;
3941 default:
3942 test_truth(count);
3943 break;
3944 }
3945 test_truth(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3946 }
3947
3948 /*
3949 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3950 ** API and is _ONLY_ done this way to verify that the library works the
3951 ** way it is supposed to do!!!!
3952 */
3953 int no_msg=0;
3954 for (size_t x= 0; x < memcached_server_count(memc); ++x)
3955 {
3956 memcached_server_instance_st *instance=
3957 memcached_server_instance_fetch(memc, x);
3958 no_msg+=(int)(instance->cursor_active);
3959 }
3960
3961 test_truth(no_msg == 0);
3962 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3963
3964 /*
3965 ** Now validate that all items was set properly!
3966 */
3967 for (size_t x= 0; x < 100; ++x)
3968 {
3969 char key[10];
3970
3971 size_t len= (size_t)sprintf(key, "%zu", x);
3972 size_t length;
3973 uint32_t flags;
3974 char* value=memcached_get(memc, key, strlen(key),
3975 &length, &flags, &ret);
3976 test_truth(ret == MEMCACHED_SUCCESS && value != NULL);
3977 switch (count)
3978 {
3979 case 0: /* FALLTHROUGH */
3980 case 1: /* FALLTHROUGH */
3981 case 2:
3982 test_truth(strncmp(value, key, len) == 0);
3983 test_truth(len == length);
3984 break;
3985 case 3:
3986 test_truth(length == len * 2);
3987 break;
3988 case 4:
3989 test_truth(length == len * 3);
3990 break;
3991 default:
3992 test_truth(count);
3993 break;
3994 }
3995 free(value);
3996 }
3997 }
3998
3999 /* Try setting an illegal cas value (should not return an error to
4000 * the caller (because we don't expect a return message from the server)
4001 */
4002 const char* keys[]= {"0"};
4003 size_t lengths[]= {1};
4004 size_t length;
4005 uint32_t flags;
4006 memcached_result_st results_obj;
4007 memcached_result_st *results;
4008 ret= memcached_mget(memc, keys, lengths, 1);
4009 test_truth(ret == MEMCACHED_SUCCESS);
4010
4011 results= memcached_result_create(memc, &results_obj);
4012 test_truth(results);
4013 results= memcached_fetch_result(memc, &results_obj, &ret);
4014 test_truth(results);
4015 test_truth(ret == MEMCACHED_SUCCESS);
4016 uint64_t cas= memcached_result_cas(results);
4017 memcached_result_free(&results_obj);
4018
4019 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4020 test_truth(ret == MEMCACHED_SUCCESS);
4021
4022 /*
4023 * The item will have a new cas value, so try to set it again with the old
4024 * value. This should fail!
4025 */
4026 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4027 test_truth(ret == MEMCACHED_SUCCESS);
4028 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4029 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4030 test_truth(ret == MEMCACHED_SUCCESS && value != NULL);
4031 free(value);
4032
4033 return TEST_SUCCESS;
4034 }
4035
4036 static test_return_t analyzer_test(memcached_st *memc)
4037 {
4038 memcached_return_t rc;
4039 memcached_stat_st *memc_stat;
4040 memcached_analysis_st *report;
4041
4042 memc_stat= memcached_stat(memc, NULL, &rc);
4043 test_truth(rc == MEMCACHED_SUCCESS);
4044 test_truth(memc_stat);
4045
4046 report= memcached_analyze(memc, memc_stat, &rc);
4047 test_truth(rc == MEMCACHED_SUCCESS);
4048 test_truth(report);
4049
4050 free(report);
4051 memcached_stat_free(NULL, memc_stat);
4052
4053 return TEST_SUCCESS;
4054 }
4055
4056 /* Count the objects */
4057 static memcached_return_t callback_dump_counter(memcached_st *ptr __attribute__((unused)),
4058 const char *key __attribute__((unused)),
4059 size_t key_length __attribute__((unused)),
4060 void *context)
4061 {
4062 size_t *counter= (size_t *)context;
4063
4064 *counter= *counter + 1;
4065
4066 return MEMCACHED_SUCCESS;
4067 }
4068
4069 static test_return_t dump_test(memcached_st *memc)
4070 {
4071 memcached_return_t rc;
4072 size_t counter= 0;
4073 memcached_dump_fn callbacks[1];
4074 test_return_t main_rc;
4075
4076 callbacks[0]= &callback_dump_counter;
4077
4078 /* No support for Binary protocol yet */
4079 if (memc->flags.binary_protocol)
4080 return TEST_SUCCESS;
4081
4082 main_rc= set_test3(memc);
4083
4084 test_truth (main_rc == TEST_SUCCESS);
4085
4086 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
4087 test_truth(rc == MEMCACHED_SUCCESS);
4088
4089 /* We may have more then 32 if our previous flush has not completed */
4090 test_truth(counter >= 32);
4091
4092 return TEST_SUCCESS;
4093 }
4094
4095 #ifdef HAVE_LIBMEMCACHEDUTIL
4096 static void* connection_release(void *arg)
4097 {
4098 struct {
4099 memcached_pool_st* pool;
4100 memcached_st* mmc;
4101 } *resource= arg;
4102
4103 usleep(250);
4104 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
4105 return arg;
4106 }
4107
4108 static test_return_t connection_pool_test(memcached_st *memc)
4109 {
4110 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
4111 test_truth(pool != NULL);
4112 memcached_st* mmc[10];
4113 memcached_return_t rc;
4114
4115 for (size_t x= 0; x < 10; ++x)
4116 {
4117 mmc[x]= memcached_pool_pop(pool, false, &rc);
4118 test_truth(mmc[x] != NULL);
4119 test_truth(rc == MEMCACHED_SUCCESS);
4120 }
4121
4122 test_truth(memcached_pool_pop(pool, false, &rc) == NULL);
4123 test_truth(rc == MEMCACHED_SUCCESS);
4124
4125 pthread_t tid;
4126 struct {
4127 memcached_pool_st* pool;
4128 memcached_st* mmc;
4129 } item= { .pool = pool, .mmc = mmc[9] };
4130 pthread_create(&tid, NULL, connection_release, &item);
4131 mmc[9]= memcached_pool_pop(pool, true, &rc);
4132 test_truth(rc == MEMCACHED_SUCCESS);
4133 pthread_join(tid, NULL);
4134 test_truth(mmc[9] == item.mmc);
4135 const char *key= "key";
4136 size_t keylen= strlen(key);
4137
4138 // verify that I can do ops with all connections
4139 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
4140 test_truth(rc == MEMCACHED_SUCCESS);
4141
4142 for (size_t x= 0; x < 10; ++x)
4143 {
4144 uint64_t number_value;
4145 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
4146 test_truth(rc == MEMCACHED_SUCCESS);
4147 test_truth(number_value == (x+1));
4148 }
4149
4150 // Release them..
4151 for (size_t x= 0; x < 10; ++x)
4152 {
4153 test_truth(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
4154 }
4155
4156
4157 /* verify that I can set behaviors on the pool when I don't have all
4158 * of the connections in the pool. It should however be enabled
4159 * when I push the item into the pool
4160 */
4161 mmc[0]= memcached_pool_pop(pool, false, &rc);
4162 test_truth(mmc[0] != NULL);
4163
4164 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4165 test_truth(rc == MEMCACHED_SUCCESS);
4166
4167 mmc[1]= memcached_pool_pop(pool, false, &rc);
4168 test_truth(mmc[1] != NULL);
4169
4170 test_truth(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4171 test_truth(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
4172 test_truth(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4173
4174 mmc[0]= memcached_pool_pop(pool, false, &rc);
4175 test_truth(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4176 test_truth(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4177
4178
4179 test_truth(memcached_pool_destroy(pool) == memc);
4180 return TEST_SUCCESS;
4181 }
4182 #endif
4183
4184 static test_return_t replication_set_test(memcached_st *memc)
4185 {
4186 memcached_return_t rc;
4187 memcached_st *memc_clone= memcached_clone(NULL, memc);
4188 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4189
4190 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
4191 test_truth(rc == MEMCACHED_SUCCESS);
4192
4193 /*
4194 ** We are using the quiet commands to store the replicas, so we need
4195 ** to ensure that all of them are processed before we can continue.
4196 ** In the test we go directly from storing the object to trying to
4197 ** receive the object from all of the different servers, so we
4198 ** could end up in a race condition (the memcached server hasn't yet
4199 ** processed the quiet command from the replication set when it process
4200 ** the request from the other client (created by the clone)). As a
4201 ** workaround for that we call memcached_quit to send the quit command
4202 ** to the server and wait for the response ;-) If you use the test code
4203 ** as an example for your own code, please note that you shouldn't need
4204 ** to do this ;-)
4205 */
4206 memcached_quit(memc);
4207
4208 /*
4209 ** "bubba" should now be stored on all of our servers. We don't have an
4210 ** easy to use API to address each individual server, so I'll just iterate
4211 ** through a bunch of "master keys" and I should most likely hit all of the
4212 ** servers...
4213 */
4214 for (int x= 'a'; x <= 'z'; ++x)
4215 {
4216 char key[2]= { [0]= (char)x };
4217 size_t len;
4218 uint32_t flags;
4219 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4220 &len, &flags, &rc);
4221 test_truth(rc == MEMCACHED_SUCCESS);
4222 test_truth(val != NULL);
4223 free(val);
4224 }
4225
4226 memcached_free(memc_clone);
4227
4228 return TEST_SUCCESS;
4229 }
4230
4231 static test_return_t replication_get_test(memcached_st *memc)
4232 {
4233 memcached_return_t rc;
4234
4235 /*
4236 * Don't do the following in your code. I am abusing the internal details
4237 * within the library, and this is not a supported interface.
4238 * This is to verify correct behavior in the library
4239 */
4240 for (uint32_t host= 0; host < memcached_server_count(memc); ++host)
4241 {
4242 memcached_st *memc_clone= memcached_clone(NULL, memc);
4243 memcached_server_instance_st *instance=
4244 memcached_server_instance_fetch(memc_clone, host);
4245
4246 instance->port= 0;
4247
4248 for (int x= 'a'; x <= 'z'; ++x)
4249 {
4250 char key[2]= { [0]= (char)x };
4251 size_t len;
4252 uint32_t flags;
4253 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4254 &len, &flags, &rc);
4255 test_truth(rc == MEMCACHED_SUCCESS);
4256 test_truth(val != NULL);
4257 free(val);
4258 }
4259
4260 memcached_free(memc_clone);
4261 }
4262
4263 return TEST_SUCCESS;
4264 }
4265
4266 static test_return_t replication_mget_test(memcached_st *memc)
4267 {
4268 memcached_return_t rc;
4269 memcached_st *memc_clone= memcached_clone(NULL, memc);
4270 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4271
4272 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4273 size_t len[]= { 5, 4, 4, 4 };
4274
4275 for (size_t x= 0; x< 4; ++x)
4276 {
4277 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
4278 test_truth(rc == MEMCACHED_SUCCESS);
4279 }
4280
4281 /*
4282 ** We are using the quiet commands to store the replicas, so we need
4283 ** to ensure that all of them are processed before we can continue.
4284 ** In the test we go directly from storing the object to trying to
4285 ** receive the object from all of the different servers, so we
4286 ** could end up in a race condition (the memcached server hasn't yet
4287 ** processed the quiet command from the replication set when it process
4288 ** the request from the other client (created by the clone)). As a
4289 ** workaround for that we call memcached_quit to send the quit command
4290 ** to the server and wait for the response ;-) If you use the test code
4291 ** as an example for your own code, please note that you shouldn't need
4292 ** to do this ;-)
4293 */
4294 memcached_quit(memc);
4295
4296 /*
4297 * Don't do the following in your code. I am abusing the internal details
4298 * within the library, and this is not a supported interface.
4299 * This is to verify correct behavior in the library
4300 */
4301 memcached_result_st result_obj;
4302 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
4303 {
4304 memcached_st *new_clone= memcached_clone(NULL, memc);
4305 memcached_server_instance_st *instance=
4306 memcached_server_instance_fetch(new_clone, host);
4307 instance->port= 0;
4308
4309 for (int x= 'a'; x <= 'z'; ++x)
4310 {
4311 const char key[2]= { [0]= (const char)x };
4312
4313 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
4314 test_truth(rc == MEMCACHED_SUCCESS);
4315
4316 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
4317 test_truth(results);
4318
4319 int hits= 0;
4320 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
4321 {
4322 hits++;
4323 }
4324 test_truth(hits == 4);
4325 memcached_result_free(&result_obj);
4326 }
4327
4328 memcached_free(new_clone);
4329 }
4330
4331 memcached_free(memc_clone);
4332
4333 return TEST_SUCCESS;
4334 }
4335
4336 static test_return_t replication_randomize_mget_test(memcached_st *memc)
4337 {
4338 memcached_result_st result_obj;
4339 memcached_return_t rc;
4340 memcached_st *memc_clone= memcached_clone(NULL, memc);
4341 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3);
4342 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1);
4343
4344 const char *keys[]= { "key1", "key2", "key3", "key4", "key5", "key6", "key7" };
4345 size_t len[]= { 4, 4, 4, 4, 4, 4, 4 };
4346
4347 for (int x=0; x< 7; ++x)
4348 {
4349 rc= memcached_set(memc, keys[x], len[x], "1", 1, 0, 0);
4350 test_truth(rc == MEMCACHED_SUCCESS);
4351 }
4352
4353 memcached_quit(memc);
4354
4355 for (size_t x= 0; x< 7; ++x)
4356 {
4357 const char key[2]= { [0]= (const char)x };
4358
4359 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 7);
4360 test_truth(rc == MEMCACHED_SUCCESS);
4361
4362 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4363 test_truth(results);
4364
4365 int hits= 0;
4366 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4367 {
4368 ++hits;
4369 }
4370 test_truth(hits == 7);
4371 memcached_result_free(&result_obj);
4372 }
4373 memcached_free(memc_clone);
4374 return TEST_SUCCESS;
4375 }
4376
4377 static test_return_t replication_delete_test(memcached_st *memc)
4378 {
4379 memcached_return_t rc;
4380 memcached_st *memc_clone= memcached_clone(NULL, memc);
4381 /* Delete the items from all of the servers except 1 */
4382 uint64_t repl= memcached_behavior_get(memc,
4383 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
4384 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
4385
4386 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4387 size_t len[]= { 5, 4, 4, 4 };
4388
4389 for (size_t x= 0; x< 4; ++x)
4390 {
4391 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
4392 test_truth(rc == MEMCACHED_SUCCESS);
4393 }
4394
4395 /*
4396 * Don't do the following in your code. I am abusing the internal details
4397 * within the library, and this is not a supported interface.
4398 * This is to verify correct behavior in the library
4399 */
4400 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
4401 for (size_t x= 0; x < (repl + 1); ++x)
4402 {
4403 memcached_server_instance_st *instance=
4404 memcached_server_instance_fetch(memc_clone, x);
4405
4406 instance->port= 0;
4407 if (++hash == memc_clone->number_of_hosts)
4408 hash= 0;
4409 }
4410
4411 memcached_result_st result_obj;
4412 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
4413 {
4414 for (size_t x= 'a'; x <= 'z'; ++x)
4415 {
4416 const char key[2]= { [0]= (const char)x };
4417
4418 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
4419 test_truth(rc == MEMCACHED_SUCCESS);
4420
4421 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4422 test_truth(results);
4423
4424 int hits= 0;
4425 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4426 {
4427 ++hits;
4428 }
4429 test_truth(hits == 4);
4430 memcached_result_free(&result_obj);
4431 }
4432 }
4433 memcached_free(memc_clone);
4434
4435 return TEST_SUCCESS;
4436 }
4437
4438 static void increment_request_id(uint16_t *id)
4439 {
4440 (*id)++;
4441 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
4442 *id= 0;
4443 }
4444
4445 static uint16_t *get_udp_request_ids(memcached_st *memc)
4446 {
4447 uint16_t *ids= malloc(sizeof(uint16_t) * memcached_server_count(memc));
4448 assert(ids != NULL);
4449
4450 for (size_t x= 0; x < memcached_server_count(memc); x++)
4451 {
4452 memcached_server_instance_st *instance=
4453 memcached_server_instance_fetch(memc, x);
4454
4455 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) instance->write_buffer);
4456 }
4457
4458 return ids;
4459 }
4460
4461 static test_return_t post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
4462 {
4463 memcached_server_st *cur_server = memcached_server_list(memc);
4464 uint16_t *cur_req_ids = get_udp_request_ids(memc);
4465
4466 for (size_t x= 0; x < memcached_server_count(memc); x++)
4467 {
4468 test_truth(cur_server[x].cursor_active == 0);
4469 test_truth(cur_req_ids[x] == expected_req_ids[x]);
4470 }
4471 free(expected_req_ids);
4472 free(cur_req_ids);
4473
4474 return TEST_SUCCESS;
4475 }
4476
4477 /*
4478 ** There is a little bit of a hack here, instead of removing
4479 ** the servers, I just set num host to 0 and them add then new udp servers
4480 **/
4481 static test_return_t init_udp(memcached_st *memc)
4482 {
4483 memcached_version(memc);
4484 memcached_server_instance_st *instance=
4485 memcached_server_instance_fetch(memc, 0);
4486
4487 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
4488 if (instance->major_version != 1 || instance->minor_version != 2
4489 || instance->micro_version < 6)
4490 return TEST_SKIPPED;
4491
4492 uint32_t num_hosts= memcached_server_count(memc);
4493 memcached_server_st servers[num_hosts];
4494 memcpy(servers, memcached_server_list(memc), sizeof(memcached_server_st) * num_hosts);
4495 for (size_t x= 0; x < num_hosts; x++)
4496 {
4497 memcached_server_instance_st *set_instance=
4498 memcached_server_instance_fetch(memc, x);
4499
4500 memcached_server_free(set_instance);
4501 }
4502
4503 memc->number_of_hosts= 0;
4504 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
4505 for (size_t x= 0; x < num_hosts; x++)
4506 {
4507 memcached_server_instance_st *set_instance=
4508 memcached_server_instance_fetch(memc, x);
4509
4510 test_truth(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
4511 test_truth(set_instance->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4512 }
4513
4514 return TEST_SUCCESS;
4515 }
4516
4517 static test_return_t binary_init_udp(memcached_st *memc)
4518 {
4519 test_return_t test_rc;
4520 test_rc= pre_binary(memc);
4521
4522 if (test_rc != TEST_SUCCESS)
4523 return test_rc;
4524
4525 return init_udp(memc);
4526 }
4527
4528 /* Make sure that I cant add a tcp server to a udp client */
4529 static test_return_t add_tcp_server_udp_client_test(memcached_st *memc)
4530 {
4531 (void)memc;
4532 #if 0
4533 memcached_server_st server;
4534 memcached_server_instance_st *instance=
4535 memcached_server_instance_fetch(memc, 0);
4536 memcached_server_clone(&server, &memc->hosts[0]);
4537 test_truth(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4538 test_truth(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4539 #endif
4540 return TEST_SUCCESS;
4541 }
4542
4543 /* Make sure that I cant add a udp server to a tcp client */
4544 static test_return_t add_udp_server_tcp_client_test(memcached_st *memc)
4545 {
4546 (void)memc;
4547 #if 0
4548 memcached_server_st server;
4549 memcached_server_instance_st *instance=
4550 memcached_server_instance_fetch(memc, 0);
4551 memcached_server_clone(&server, &memc->hosts[0]);
4552 test_truth(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4553
4554 memcached_st tcp_client;
4555 memcached_create(&tcp_client);
4556 test_truth(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4557 #endif
4558
4559 return TEST_SUCCESS;
4560 }
4561
4562 static test_return_t set_udp_behavior_test(memcached_st *memc)
4563 {
4564
4565 memcached_quit(memc);
4566 memc->number_of_hosts= 0;
4567 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, memc->distribution);
4568 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
4569 test_truth(memc->flags.use_udp);
4570 test_truth(memc->flags.no_reply);
4571
4572 test_truth(memcached_server_count(memc) == 0);
4573
4574 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
4575 test_truth(! (memc->flags.use_udp));
4576 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
4577 test_truth(! (memc->flags.no_reply));
4578
4579 return TEST_SUCCESS;
4580 }
4581
4582 static test_return_t udp_set_test(memcached_st *memc)
4583 {
4584 unsigned int num_iters= 1025; //request id rolls over at 1024
4585
4586 for (size_t x= 0; x < num_iters;x++)
4587 {
4588 memcached_return_t rc;
4589 const char *key= "foo";
4590 const char *value= "when we sanitize";
4591 uint16_t *expected_ids= get_udp_request_ids(memc);
4592 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4593 memcached_server_instance_st *instance=
4594 memcached_server_instance_fetch(memc, server_key);
4595 size_t init_offset= instance->write_buffer_offset;
4596
4597 rc= memcached_set(memc, key, strlen(key),
4598 value, strlen(value),
4599 (time_t)0, (uint32_t)0);
4600 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4601 /** NB, the check below assumes that if new write_ptr is less than
4602 * the original write_ptr that we have flushed. For large payloads, this
4603 * maybe an invalid assumption, but for the small payload we have it is OK
4604 */
4605 if (rc == MEMCACHED_SUCCESS ||
4606 instance->write_buffer_offset < init_offset)
4607 increment_request_id(&expected_ids[server_key]);
4608
4609 if (rc == MEMCACHED_SUCCESS)
4610 {
4611 test_truth(instance->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4612 }
4613 else
4614 {
4615 test_truth(instance->write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4616 test_truth(instance->write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4617 }
4618 test_truth(post_udp_op_check(memc, expected_ids) == TEST_SUCCESS);
4619 }
4620 return TEST_SUCCESS;
4621 }
4622
4623 static test_return_t udp_buffered_set_test(memcached_st *memc)
4624 {
4625 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4626 return udp_set_test(memc);
4627 }
4628
4629 static test_return_t udp_set_too_big_test(memcached_st *memc)
4630 {
4631 memcached_return_t rc;
4632 const char *key= "bar";
4633 char value[MAX_UDP_DATAGRAM_LENGTH];
4634 uint16_t *expected_ids= get_udp_request_ids(memc);
4635 rc= memcached_set(memc, key, strlen(key),
4636 value, MAX_UDP_DATAGRAM_LENGTH,
4637 (time_t)0, (uint32_t)0);
4638 test_truth(rc == MEMCACHED_WRITE_FAILURE);
4639
4640 return post_udp_op_check(memc,expected_ids);
4641 }
4642
4643 static test_return_t udp_delete_test(memcached_st *memc)
4644 {
4645 unsigned int num_iters= 1025; //request id rolls over at 1024
4646
4647 for (size_t x= 0; x < num_iters;x++)
4648 {
4649 memcached_return_t rc;
4650 const char *key= "foo";
4651 uint16_t *expected_ids=get_udp_request_ids(memc);
4652 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4653 memcached_server_instance_st *instance=
4654 memcached_server_instance_fetch(memc, server_key);
4655 size_t init_offset= instance->write_buffer_offset;
4656
4657 rc= memcached_delete(memc, key, strlen(key), 0);
4658 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4659
4660 if (rc == MEMCACHED_SUCCESS || instance->write_buffer_offset < init_offset)
4661 increment_request_id(&expected_ids[server_key]);
4662 if (rc == MEMCACHED_SUCCESS)
4663 {
4664 test_truth(instance->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4665 }
4666 else
4667 {
4668 test_truth(instance->write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4669 test_truth(instance->write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4670 }
4671 test_truth(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4672 }
4673 return TEST_SUCCESS;
4674 }
4675
4676 static test_return_t udp_buffered_delete_test(memcached_st *memc)
4677 {
4678 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4679 return udp_delete_test(memc);
4680 }
4681
4682 static test_return_t udp_verbosity_test(memcached_st *memc)
4683 {
4684 memcached_return_t rc;
4685 uint16_t *expected_ids= get_udp_request_ids(memc);
4686
4687 for (size_t x= 0; x < memcached_server_count(memc); x++)
4688 {
4689 increment_request_id(&expected_ids[x]);
4690 }
4691
4692 rc= memcached_verbosity(memc,3);
4693 test_truth(rc == MEMCACHED_SUCCESS);
4694 return post_udp_op_check(memc,expected_ids);
4695 }
4696
4697 static test_return_t udp_quit_test(memcached_st *memc)
4698 {
4699 uint16_t *expected_ids= get_udp_request_ids(memc);
4700 memcached_quit(memc);
4701 return post_udp_op_check(memc, expected_ids);
4702 }
4703
4704 static test_return_t udp_flush_test(memcached_st *memc)
4705 {
4706 memcached_return_t rc;
4707 uint16_t *expected_ids= get_udp_request_ids(memc);
4708
4709 for (size_t x= 0; x < memcached_server_count(memc); x++)
4710 {
4711 increment_request_id(&expected_ids[x]);
4712 }
4713
4714 rc= memcached_flush(memc,0);
4715 test_truth(rc == MEMCACHED_SUCCESS);
4716 return post_udp_op_check(memc,expected_ids);
4717 }
4718
4719 static test_return_t udp_incr_test(memcached_st *memc)
4720 {
4721 memcached_return_t rc;
4722 const char *key= "incr";
4723 const char *value= "1";
4724 rc= memcached_set(memc, key, strlen(key),
4725 value, strlen(value),
4726 (time_t)0, (uint32_t)0);
4727
4728 test_truth(rc == MEMCACHED_SUCCESS);
4729 uint16_t *expected_ids= get_udp_request_ids(memc);
4730 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4731 increment_request_id(&expected_ids[server_key]);
4732 uint64_t newvalue;
4733 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
4734 test_truth(rc == MEMCACHED_SUCCESS);
4735 return post_udp_op_check(memc, expected_ids);
4736 }
4737
4738 static test_return_t udp_decr_test(memcached_st *memc)
4739 {
4740 memcached_return_t rc;
4741 const char *key= "decr";
4742 const char *value= "1";
4743 rc= memcached_set(memc, key, strlen(key),
4744 value, strlen(value),
4745 (time_t)0, (uint32_t)0);
4746
4747 test_truth(rc == MEMCACHED_SUCCESS);
4748 uint16_t *expected_ids= get_udp_request_ids(memc);
4749 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4750 increment_request_id(&expected_ids[server_key]);
4751 uint64_t newvalue;
4752 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4753 test_truth(rc == MEMCACHED_SUCCESS);
4754 return post_udp_op_check(memc, expected_ids);
4755 }
4756
4757
4758 static test_return_t udp_stat_test(memcached_st *memc)
4759 {
4760 memcached_stat_st * rv= NULL;
4761 memcached_return_t rc;
4762 char args[]= "";
4763 uint16_t *expected_ids = get_udp_request_ids(memc);
4764 rv = memcached_stat(memc, args, &rc);
4765 free(rv);
4766 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4767 return post_udp_op_check(memc, expected_ids);
4768 }
4769
4770 static test_return_t udp_version_test(memcached_st *memc)
4771 {
4772 memcached_return_t rc;
4773 uint16_t *expected_ids = get_udp_request_ids(memc);
4774 rc = memcached_version(memc);
4775 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4776 return post_udp_op_check(memc, expected_ids);
4777 }
4778
4779 static test_return_t udp_get_test(memcached_st *memc)
4780 {
4781 memcached_return_t rc;
4782 const char *key= "foo";
4783 size_t vlen;
4784 uint16_t *expected_ids = get_udp_request_ids(memc);
4785 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4786 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4787 test_truth(val == NULL);
4788 return post_udp_op_check(memc, expected_ids);
4789 }
4790
4791 static test_return_t udp_mixed_io_test(memcached_st *memc)
4792 {
4793 test_st current_op;
4794 test_st mixed_io_ops [] ={
4795 {"udp_set_test", 0,
4796 (test_callback_fn)udp_set_test},
4797 {"udp_set_too_big_test", 0,
4798 (test_callback_fn)udp_set_too_big_test},
4799 {"udp_delete_test", 0,
4800 (test_callback_fn)udp_delete_test},
4801 {"udp_verbosity_test", 0,
4802 (test_callback_fn)udp_verbosity_test},
4803 {"udp_quit_test", 0,
4804 (test_callback_fn)udp_quit_test},
4805 {"udp_flush_test", 0,
4806 (test_callback_fn)udp_flush_test},
4807 {"udp_incr_test", 0,
4808 (test_callback_fn)udp_incr_test},
4809 {"udp_decr_test", 0,
4810 (test_callback_fn)udp_decr_test},
4811 {"udp_version_test", 0,
4812 (test_callback_fn)udp_version_test}
4813 };
4814 for (size_t x= 0; x < 500; x++)
4815 {
4816 current_op= mixed_io_ops[random() % 9];
4817 test_truth(current_op.test_fn(memc) == TEST_SUCCESS);
4818 }
4819 return TEST_SUCCESS;
4820 }
4821
4822 #if 0
4823 static test_return_t hash_sanity_test (memcached_st *memc)
4824 {
4825 (void)memc;
4826
4827 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4828 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4829 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4830 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4831 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4832 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4833 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4834 #ifdef HAVE_HSIEH_HASH
4835 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4836 #endif
4837 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4838 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4839 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4840
4841 return TEST_SUCCESS;
4842 }
4843 #endif
4844
4845 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4846 {
4847 memcached_return_t expected_rc= MEMCACHED_FAILURE;
4848 #ifdef HAVE_HSIEH_HASH
4849 expected_rc= MEMCACHED_SUCCESS;
4850 #endif
4851 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4852 (uint64_t)MEMCACHED_HASH_HSIEH);
4853 test_truth(rc == expected_rc);
4854 return TEST_SUCCESS;
4855 }
4856
4857 static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
4858 {
4859 uint32_t x;
4860 const char **ptr;
4861
4862 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4863 {
4864 uint32_t hash_val;
4865
4866 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4867 test_truth(md5_values[x] == hash_val);
4868 }
4869
4870 return TEST_SUCCESS;
4871 }
4872
4873 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4874 {
4875 uint32_t x;
4876 const char **ptr;
4877
4878 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4879 {
4880 uint32_t hash_val;
4881
4882 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4883 test_truth(crc_values[x] == hash_val);
4884 }
4885
4886 return TEST_SUCCESS;
4887 }
4888
4889 static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
4890 {
4891 uint32_t x;
4892 const char **ptr;
4893
4894 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4895 {
4896 uint32_t hash_val;
4897
4898 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4899 test_truth(fnv1_64_values[x] == hash_val);
4900 }
4901
4902 return TEST_SUCCESS;
4903 }
4904
4905 static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4906 {
4907 uint32_t x;
4908 const char **ptr;
4909
4910 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4911 {
4912 uint32_t hash_val;
4913
4914 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4915 test_truth(fnv1a_64_values[x] == hash_val);
4916 }
4917
4918 return TEST_SUCCESS;
4919 }
4920
4921 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4922 {
4923 uint32_t x;
4924 const char **ptr;
4925
4926
4927 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4928 {
4929 uint32_t hash_val;
4930
4931 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4932 test_truth(fnv1_32_values[x] == hash_val);
4933 }
4934
4935 return TEST_SUCCESS;
4936 }
4937
4938 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4939 {
4940 uint32_t x;
4941 const char **ptr;
4942
4943 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4944 {
4945 uint32_t hash_val;
4946
4947 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4948 test_truth(fnv1a_32_values[x] == hash_val);
4949 }
4950
4951 return TEST_SUCCESS;
4952 }
4953
4954 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
4955 {
4956 uint32_t x;
4957 const char **ptr;
4958
4959 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4960 {
4961 uint32_t hash_val;
4962
4963 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4964 test_truth(hsieh_values[x] == hash_val);
4965 }
4966
4967 return TEST_SUCCESS;
4968 }
4969
4970 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
4971 {
4972 #ifdef __sparc
4973 return TEST_SKIPPED;
4974 #else
4975 uint32_t x;
4976 const char **ptr;
4977
4978 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4979 {
4980 uint32_t hash_val;
4981
4982 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4983 test_truth(murmur_values[x] == hash_val);
4984 }
4985
4986 return TEST_SUCCESS;
4987 #endif
4988 }
4989
4990 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
4991 {
4992 uint32_t x;
4993 const char **ptr;
4994
4995
4996 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4997 {
4998 uint32_t hash_val;
4999
5000 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
5001 test_truth(jenkins_values[x] == hash_val);
5002 }
5003
5004 return TEST_SUCCESS;
5005 }
5006
5007
5008 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
5009 {
5010 memcached_return_t rc;
5011 uint64_t value;
5012 int x;
5013 memcached_server_st *server_pool;
5014 memcached_st *memc;
5015
5016 (void)trash;
5017
5018 memc= memcached_create(NULL);
5019 test_truth(memc);
5020
5021 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5022 test_truth(rc == MEMCACHED_SUCCESS);
5023
5024 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5025 test_truth(value == 1);
5026
5027 test_truth(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
5028 test_truth(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
5029
5030
5031 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");
5032 memcached_server_push(memc, server_pool);
5033
5034 /* verify that the server list was parsed okay. */
5035 test_truth(memcached_server_count(memc) == 8);
5036 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5037 test_truth(server_pool[0].port == 11211);
5038 test_truth(server_pool[0].weight == 600);
5039 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5040 test_truth(server_pool[2].port == 11211);
5041 test_truth(server_pool[2].weight == 200);
5042 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5043 test_truth(server_pool[7].port == 11211);
5044 test_truth(server_pool[7].weight == 100);
5045
5046 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5047 * us test the boundary wraparound.
5048 */
5049 test_truth(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5050
5051 /* verify the standard ketama set. */
5052 for (x= 0; x < 99; x++)
5053 {
5054 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
5055 memcached_server_instance_st *instance=
5056 memcached_server_instance_fetch(memc, server_idx);
5057 char *hostname = instance->hostname;
5058
5059 test_strcmp(hostname, ketama_test_cases[x].server);
5060 }
5061
5062 memcached_server_list_free(server_pool);
5063 memcached_free(memc);
5064
5065 return TEST_SUCCESS;
5066 }
5067
5068 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
5069 {
5070 memcached_return_t rc;
5071 uint64_t value;
5072 int x;
5073 memcached_server_st *server_pool;
5074 memcached_st *memc;
5075
5076 (void)trash;
5077
5078 memc= memcached_create(NULL);
5079 test_truth(memc);
5080
5081 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5082 test_truth(rc == MEMCACHED_SUCCESS);
5083
5084 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5085 test_truth(value == 1);
5086
5087 test_truth(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
5088 test_truth(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
5089
5090 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");
5091 memcached_server_push(memc, server_pool);
5092
5093 /* verify that the server list was parsed okay. */
5094 test_truth(memcached_server_count(memc) == 8);
5095 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5096 test_truth(server_pool[0].port == 11211);
5097 test_truth(server_pool[0].weight == 600);
5098 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5099 test_truth(server_pool[2].port == 11211);
5100 test_truth(server_pool[2].weight == 200);
5101 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5102 test_truth(server_pool[7].port == 11211);
5103 test_truth(server_pool[7].weight == 100);
5104
5105 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5106 * us test the boundary wraparound.
5107 */
5108 test_truth(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5109
5110 /* verify the standard ketama set. */
5111 for (x= 0; x < 99; x++)
5112 {
5113 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5114 memcached_server_instance_st *instance=
5115 memcached_server_instance_fetch(memc, server_idx);
5116 char *hostname = instance->hostname;
5117 test_strcmp(hostname, ketama_test_cases_spy[x].server);
5118 }
5119
5120 memcached_server_list_free(server_pool);
5121 memcached_free(memc);
5122
5123 return TEST_SUCCESS;
5124 }
5125
5126 static test_return_t regression_bug_434484(memcached_st *memc)
5127 {
5128 test_return_t test_rc;
5129 test_rc= pre_binary(memc);
5130
5131 if (test_rc != TEST_SUCCESS)
5132 return test_rc;
5133
5134 memcached_return_t ret;
5135 const char *key= "regression_bug_434484";
5136 size_t keylen= strlen(key);
5137
5138 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5139 test_truth(ret == MEMCACHED_NOTSTORED);
5140
5141 size_t size= 2048 * 1024;
5142 void *data= calloc(1, size);
5143 test_truth(data != NULL);
5144 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5145 test_truth(ret == MEMCACHED_E2BIG);
5146 free(data);
5147
5148 return TEST_SUCCESS;
5149 }
5150
5151 static test_return_t regression_bug_434843(memcached_st *memc)
5152 {
5153 test_return_t test_rc;
5154 test_rc= pre_binary(memc);
5155
5156 if (test_rc != TEST_SUCCESS)
5157 return test_rc;
5158
5159 memcached_return_t rc;
5160 size_t counter= 0;
5161 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5162
5163 /*
5164 * I only want to hit only _one_ server so I know the number of requests I'm
5165 * sending in the pipleine to the server. Let's try to do a multiget of
5166 * 1024 (that should satisfy most users don't you think?). Future versions
5167 * will include a mget_execute function call if you need a higher number.
5168 */
5169 uint32_t number_of_hosts= memcached_server_count(memc);
5170 memc->number_of_hosts= 1;
5171 const size_t max_keys= 1024;
5172 char **keys= calloc(max_keys, sizeof(char*));
5173 size_t *key_length=calloc(max_keys, sizeof(size_t));
5174
5175 for (size_t x= 0; x < max_keys; ++x)
5176 {
5177 char k[251];
5178
5179 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5180 keys[x]= strdup(k);
5181 test_truth(keys[x] != NULL);
5182 }
5183
5184 /*
5185 * Run two times.. the first time we should have 100% cache miss,
5186 * and the second time we should have 100% cache hits
5187 */
5188 for (size_t y= 0; y < 2; y++)
5189 {
5190 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5191 test_truth(rc == MEMCACHED_SUCCESS);
5192 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5193
5194 if (y == 0)
5195 {
5196 /* The first iteration should give me a 100% cache miss. verify that*/
5197 char blob[1024]= { 0 };
5198
5199 test_truth(counter == 0);
5200
5201 for (size_t x= 0; x < max_keys; ++x)
5202 {
5203 rc= memcached_add(memc, keys[x], key_length[x],
5204 blob, sizeof(blob), 0, 0);
5205 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5206 }
5207 }
5208 else
5209 {
5210 /* Verify that we received all of the key/value pairs */
5211 test_truth(counter == max_keys);
5212 }
5213 }
5214
5215 /* Release allocated resources */
5216 for (size_t x= 0; x < max_keys; ++x)
5217 {
5218 free(keys[x]);
5219 }
5220 free(keys);
5221 free(key_length);
5222
5223 memc->number_of_hosts= number_of_hosts;
5224
5225 return TEST_SUCCESS;
5226 }
5227
5228 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5229 {
5230 memcached_return_t rc;
5231 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5232 test_truth(rc == MEMCACHED_SUCCESS);
5233
5234 return regression_bug_434843(memc);
5235 }
5236
5237 static test_return_t regression_bug_421108(memcached_st *memc)
5238 {
5239 memcached_return_t rc;
5240 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5241 test_truth(rc == MEMCACHED_SUCCESS);
5242
5243 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5244 test_truth(rc == MEMCACHED_SUCCESS);
5245 test_truth(bytes != NULL);
5246 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5247 "bytes_read", &rc);
5248 test_truth(rc == MEMCACHED_SUCCESS);
5249 test_truth(bytes_read != NULL);
5250
5251 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5252 "bytes_written", &rc);
5253 test_truth(rc == MEMCACHED_SUCCESS);
5254 test_truth(bytes_written != NULL);
5255
5256 test_truth(strcmp(bytes, bytes_read) != 0);
5257 test_truth(strcmp(bytes, bytes_written) != 0);
5258
5259 /* Release allocated resources */
5260 free(bytes);
5261 free(bytes_read);
5262 free(bytes_written);
5263 memcached_stat_free(NULL, memc_stat);
5264
5265 return TEST_SUCCESS;
5266 }
5267
5268 /*
5269 * The test case isn't obvious so I should probably document why
5270 * it works the way it does. Bug 442914 was caused by a bug
5271 * in the logic in memcached_purge (it did not handle the case
5272 * where the number of bytes sent was equal to the watermark).
5273 * In this test case, create messages so that we hit that case
5274 * and then disable noreply mode and issue a new command to
5275 * verify that it isn't stuck. If we change the format for the
5276 * delete command or the watermarks, we need to update this
5277 * test....
5278 */
5279 static test_return_t regression_bug_442914(memcached_st *memc)
5280 {
5281 memcached_return_t rc;
5282 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5283 test_truth(rc == MEMCACHED_SUCCESS);
5284 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5285
5286 uint32_t number_of_hosts= memcached_server_count(memc);
5287 memc->number_of_hosts= 1;
5288
5289 char k[250];
5290 size_t len;
5291
5292 for (int x= 0; x < 250; ++x)
5293 {
5294 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5295 rc= memcached_delete(memc, k, len, 0);
5296 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5297 }
5298
5299 len= (size_t)snprintf(k, sizeof(k), "%037u", 251);
5300 rc= memcached_delete(memc, k, len, 0);
5301 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5302
5303 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5304 test_truth(rc == MEMCACHED_SUCCESS);
5305 rc= memcached_delete(memc, k, len, 0);
5306 test_truth(rc == MEMCACHED_NOTFOUND);
5307
5308 memc->number_of_hosts= number_of_hosts;
5309
5310 return TEST_SUCCESS;
5311 }
5312
5313 static test_return_t regression_bug_447342(memcached_st *memc)
5314 {
5315 memcached_server_instance_st *instance_one;
5316 memcached_server_instance_st *instance_two;
5317
5318 if (memcached_server_count(memc) < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
5319 return TEST_SKIPPED;
5320
5321 memcached_return_t rc;
5322
5323 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5324 test_truth(rc == MEMCACHED_SUCCESS);
5325
5326 const size_t max_keys= 100;
5327 char **keys= calloc(max_keys, sizeof(char*));
5328 size_t *key_length= calloc(max_keys, sizeof(size_t));
5329
5330 for (size_t x= 0; x < max_keys; ++x)
5331 {
5332 char k[251];
5333
5334 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5335 keys[x]= strdup(k);
5336 test_truth(keys[x] != NULL);
5337 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5338 test_truth(rc == MEMCACHED_SUCCESS);
5339 }
5340
5341 /*
5342 ** We are using the quiet commands to store the replicas, so we need
5343 ** to ensure that all of them are processed before we can continue.
5344 ** In the test we go directly from storing the object to trying to
5345 ** receive the object from all of the different servers, so we
5346 ** could end up in a race condition (the memcached server hasn't yet
5347 ** processed the quiet command from the replication set when it process
5348 ** the request from the other client (created by the clone)). As a
5349 ** workaround for that we call memcached_quit to send the quit command
5350 ** to the server and wait for the response ;-) If you use the test code
5351 ** as an example for your own code, please note that you shouldn't need
5352 ** to do this ;-)
5353 */
5354 memcached_quit(memc);
5355
5356 /* Verify that all messages are stored, and we didn't stuff too much
5357 * into the servers
5358 */
5359 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5360 test_truth(rc == MEMCACHED_SUCCESS);
5361
5362 size_t counter= 0;
5363 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5364 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5365 /* Verify that we received all of the key/value pairs */
5366 test_truth(counter == max_keys);
5367
5368 memcached_quit(memc);
5369 /*
5370 * Don't do the following in your code. I am abusing the internal details
5371 * within the library, and this is not a supported interface.
5372 * This is to verify correct behavior in the library. Fake that two servers
5373 * are dead..
5374 */
5375 instance_one= memcached_server_instance_fetch(memc, 0);
5376 instance_two= memcached_server_instance_fetch(memc, 2);
5377 in_port_t port0= instance_one->port;
5378 in_port_t port2= instance_two->port;
5379
5380 instance_one->port= 0;
5381 instance_two->port= 0;
5382
5383 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5384 test_truth(rc == MEMCACHED_SUCCESS);
5385
5386 counter= 0;
5387 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5388 test_truth(counter == (unsigned int)max_keys);
5389
5390 /* restore the memc handle */
5391 instance_one->port= port0;
5392 instance_two->port= port2;
5393
5394 memcached_quit(memc);
5395
5396 /* Remove half of the objects */
5397 for (size_t x= 0; x < max_keys; ++x)
5398 {
5399 if (x & 1)
5400 {
5401 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5402 test_truth(rc == MEMCACHED_SUCCESS);
5403 }
5404 }
5405
5406 memcached_quit(memc);
5407 instance_one->port= 0;
5408 instance_two->port= 0;
5409
5410 /* now retry the command, this time we should have cache misses */
5411 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5412 test_truth(rc == MEMCACHED_SUCCESS);
5413
5414 counter= 0;
5415 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5416 test_truth(counter == (unsigned int)(max_keys >> 1));
5417
5418 /* Release allocated resources */
5419 for (size_t x= 0; x < max_keys; ++x)
5420 {
5421 free(keys[x]);
5422 }
5423 free(keys);
5424 free(key_length);
5425
5426 /* restore the memc handle */
5427 instance_one->port= port0;
5428 instance_two->port= port2;
5429
5430 return TEST_SUCCESS;
5431 }
5432
5433 static test_return_t regression_bug_463297(memcached_st *memc)
5434 {
5435 memcached_st *memc_clone= memcached_clone(NULL, memc);
5436 test_truth(memc_clone != NULL);
5437 test_truth(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5438
5439 memcached_server_instance_st *instance=
5440 memcached_server_instance_fetch(memc_clone, 0);
5441
5442 if (instance->major_version > 1 ||
5443 (instance->major_version == 1 &&
5444 instance->minor_version > 2))
5445 {
5446 /* Binary protocol doesn't support deferred delete */
5447 memcached_st *bin_clone= memcached_clone(NULL, memc);
5448 test_truth(bin_clone != NULL);
5449 test_truth(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5450 test_truth(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5451 memcached_free(bin_clone);
5452
5453 memcached_quit(memc_clone);
5454
5455 /* If we know the server version, deferred delete should fail
5456 * with invalid arguments */
5457 test_truth(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5458
5459 /* If we don't know the server version, we should get a protocol error */
5460 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5461
5462 /* but there is a bug in some of the memcached servers (1.4) that treats
5463 * the counter as noreply so it doesn't send the proper error message
5464 */
5465 test_truth(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5466
5467 /* And buffered mode should be disabled and we should get protocol error */
5468 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5469 rc= memcached_delete(memc, "foo", 3, 1);
5470 test_truth(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5471
5472 /* Same goes for noreply... */
5473 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5474 rc= memcached_delete(memc, "foo", 3, 1);
5475 test_truth(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5476
5477 /* but a normal request should go through (and be buffered) */
5478 test_truth((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5479 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5480
5481 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5482 /* unbuffered noreply should be success */
5483 test_truth(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5484 /* unbuffered with reply should be not found... */
5485 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5486 test_truth(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5487 }
5488
5489 memcached_free(memc_clone);
5490 return TEST_SUCCESS;
5491 }
5492
5493
5494 /* Test memcached_server_get_last_disconnect
5495 * For a working server set, shall be NULL
5496 * For a set of non existing server, shall not be NULL
5497 */
5498 static test_return_t test_get_last_disconnect(memcached_st *memc)
5499 {
5500 memcached_return_t rc;
5501 memcached_server_st *disconnected_server;
5502
5503 /* With the working set of server */
5504 const char *key= "marmotte";
5505 const char *value= "milka";
5506
5507 rc= memcached_set(memc, key, strlen(key),
5508 value, strlen(value),
5509 (time_t)0, (uint32_t)0);
5510 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5511
5512 disconnected_server = memcached_server_get_last_disconnect(memc);
5513 test_truth(disconnected_server == NULL);
5514
5515 /* With a non existing server */
5516 memcached_st *mine;
5517 memcached_server_st *servers;
5518
5519 const char *server_list= "localhost:9";
5520
5521 servers= memcached_servers_parse(server_list);
5522 test_truth(servers);
5523 mine= memcached_create(NULL);
5524 rc= memcached_server_push(mine, servers);
5525 test_truth(rc == MEMCACHED_SUCCESS);
5526 memcached_server_list_free(servers);
5527 test_truth(mine);
5528
5529 rc= memcached_set(mine, key, strlen(key),
5530 value, strlen(value),
5531 (time_t)0, (uint32_t)0);
5532 test_truth(rc != MEMCACHED_SUCCESS);
5533
5534 disconnected_server = memcached_server_get_last_disconnect(mine);
5535 test_truth(disconnected_server != NULL);
5536 test_truth(disconnected_server->port == 9);
5537 test_truth(strncmp(disconnected_server->hostname,"localhost",9) == 0);
5538
5539 memcached_quit(mine);
5540 memcached_free(mine);
5541
5542 return TEST_SUCCESS;
5543 }
5544
5545 /*
5546 * This test ensures that the failure counter isn't incremented during
5547 * normal termination of the memcached instance.
5548 */
5549 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5550 {
5551 memcached_return_t rc;
5552 memcached_server_instance_st *instance;
5553
5554 /* Set value to force connection to the server */
5555 const char *key= "marmotte";
5556 const char *value= "milka";
5557
5558 /*
5559 * Please note that I'm abusing the internal structures in libmemcached
5560 * in a non-portable way and you shouldn't be doing this. I'm only
5561 * doing this in order to verify that the library works the way it should
5562 */
5563 uint32_t number_of_hosts= memcached_server_count(memc);
5564 memc->number_of_hosts= 1;
5565
5566 /* Ensure that we are connected to the server by setting a value */
5567 rc= memcached_set(memc, key, strlen(key),
5568 value, strlen(value),
5569 (time_t)0, (uint32_t)0);
5570 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5571
5572
5573 instance= memcached_server_instance_fetch(memc, 0);
5574 /* The test is to see that the memcached_quit doesn't increase the
5575 * the server failure conter, so let's ensure that it is zero
5576 * before sending quit
5577 */
5578 instance->server_failure_counter= 0;
5579
5580 memcached_quit(memc);
5581
5582 /* Verify that it memcached_quit didn't increment the failure counter
5583 * Please note that this isn't bullet proof, because an error could
5584 * occur...
5585 */
5586 test_truth(instance->server_failure_counter == 0);
5587
5588 /* restore the instance */
5589 memc->number_of_hosts= number_of_hosts;
5590
5591 return TEST_SUCCESS;
5592 }
5593
5594
5595
5596
5597 /*
5598 * Test that ensures mget_execute does not end into recursive calls that finally fails
5599 */
5600 static test_return_t regression_bug_490486(memcached_st *memc)
5601 {
5602 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5603 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
5604 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5605 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5606 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5607
5608 /*
5609 * I only want to hit _one_ server so I know the number of requests I'm
5610 * sending in the pipeline.
5611 */
5612 uint32_t number_of_hosts= memc->number_of_hosts;
5613 memc->number_of_hosts= 1;
5614 size_t max_keys= 20480;
5615
5616
5617 char **keys= calloc(max_keys, sizeof(char*));
5618 size_t *key_length=calloc(max_keys, sizeof(size_t));
5619
5620 /* First add all of the items.. */
5621 char blob[1024]= { 0 };
5622 memcached_return rc;
5623 for (size_t x= 0; x < max_keys; ++x)
5624 {
5625 char k[251];
5626 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5627 keys[x]= strdup(k);
5628 assert(keys[x] != NULL);
5629 rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5630 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5631 }
5632
5633 /* Try to get all of them with a large multiget */
5634 size_t counter= 0;
5635 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
5636 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
5637 (size_t)max_keys, callbacks, &counter, 1);
5638
5639 assert(rc == MEMCACHED_SUCCESS);
5640 char* the_value= NULL;
5641 char the_key[MEMCACHED_MAX_KEY];
5642 size_t the_key_length;
5643 size_t the_value_length;
5644 uint32_t the_flags;
5645
5646 do {
5647 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
5648
5649 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
5650 {
5651 ++counter;
5652 free(the_value);
5653 }
5654
5655 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
5656
5657
5658 assert(rc == MEMCACHED_END);
5659
5660 /* Verify that we got all of the items */
5661 assert(counter == max_keys);
5662
5663 /* Release all allocated resources */
5664 for (size_t x= 0; x < max_keys; ++x)
5665 {
5666 free(keys[x]);
5667 }
5668 free(keys);
5669 free(key_length);
5670
5671 memc->number_of_hosts= number_of_hosts;
5672
5673 return TEST_SUCCESS;
5674 }
5675
5676
5677
5678
5679 test_st udp_setup_server_tests[] ={
5680 {"set_udp_behavior_test", 0, (test_callback_fn)set_udp_behavior_test},
5681 {"add_tcp_server_udp_client_test", 0, (test_callback_fn)add_tcp_server_udp_client_test},
5682 {"add_udp_server_tcp_client_test", 0, (test_callback_fn)add_udp_server_tcp_client_test},
5683 {0, 0, 0}
5684 };
5685
5686 test_st upd_io_tests[] ={
5687 {"udp_set_test", 0, (test_callback_fn)udp_set_test},
5688 {"udp_buffered_set_test", 0, (test_callback_fn)udp_buffered_set_test},
5689 {"udp_set_too_big_test", 0, (test_callback_fn)udp_set_too_big_test},
5690 {"udp_delete_test", 0, (test_callback_fn)udp_delete_test},
5691 {"udp_buffered_delete_test", 0, (test_callback_fn)udp_buffered_delete_test},
5692 {"udp_verbosity_test", 0, (test_callback_fn)udp_verbosity_test},
5693 {"udp_quit_test", 0, (test_callback_fn)udp_quit_test},
5694 {"udp_flush_test", 0, (test_callback_fn)udp_flush_test},
5695 {"udp_incr_test", 0, (test_callback_fn)udp_incr_test},
5696 {"udp_decr_test", 0, (test_callback_fn)udp_decr_test},
5697 {"udp_stat_test", 0, (test_callback_fn)udp_stat_test},
5698 {"udp_version_test", 0, (test_callback_fn)udp_version_test},
5699 {"udp_get_test", 0, (test_callback_fn)udp_get_test},
5700 {"udp_mixed_io_test", 0, (test_callback_fn)udp_mixed_io_test},
5701 {0, 0, 0}
5702 };
5703
5704 /* Clean the server before beginning testing */
5705 test_st tests[] ={
5706 {"flush", 0, (test_callback_fn)flush_test },
5707 {"init", 0, (test_callback_fn)init_test },
5708 {"allocation", 0, (test_callback_fn)allocation_test },
5709 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
5710 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
5711 {"server_sort", 0, (test_callback_fn)server_sort_test},
5712 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
5713 {"clone_test", 0, (test_callback_fn)clone_test },
5714 {"connection_test", 0, (test_callback_fn)connection_test},
5715 {"callback_test", 0, (test_callback_fn)callback_test},
5716 {"userdata_test", 0, (test_callback_fn)userdata_test},
5717 {"error", 0, (test_callback_fn)error_test },
5718 {"set", 0, (test_callback_fn)set_test },
5719 {"set2", 0, (test_callback_fn)set_test2 },
5720 {"set3", 0, (test_callback_fn)set_test3 },
5721 {"dump", 1, (test_callback_fn)dump_test},
5722 {"add", 1, (test_callback_fn)add_test },
5723 {"replace", 1, (test_callback_fn)replace_test },
5724 {"delete", 1, (test_callback_fn)delete_test },
5725 {"get", 1, (test_callback_fn)get_test },
5726 {"get2", 0, (test_callback_fn)get_test2 },
5727 {"get3", 0, (test_callback_fn)get_test3 },
5728 {"get4", 0, (test_callback_fn)get_test4 },
5729 {"partial mget", 0, (test_callback_fn)get_test5 },
5730 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
5731 {"increment", 0, (test_callback_fn)increment_test },
5732 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
5733 {"decrement", 0, (test_callback_fn)decrement_test },
5734 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
5735 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
5736 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
5737 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
5738 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
5739 {"quit", 0, (test_callback_fn)quit_test },
5740 {"mget", 1, (test_callback_fn)mget_test },
5741 {"mget_result", 1, (test_callback_fn)mget_result_test },
5742 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
5743 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
5744 {"mget_execute", 1, (test_callback_fn)mget_execute },
5745 {"mget_end", 0, (test_callback_fn)mget_end },
5746 {"get_stats", 0, (test_callback_fn)get_stats },
5747 {"add_host_test", 0, (test_callback_fn)add_host_test },
5748 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
5749 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
5750 {"version_string_test", 0, (test_callback_fn)version_string_test},
5751 {"bad_key", 1, (test_callback_fn)bad_key_test },
5752 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
5753 {"read_through", 1, (test_callback_fn)read_through },
5754 {"delete_through", 1, (test_callback_fn)delete_through },
5755 {"noreply", 1, (test_callback_fn)noreply_test},
5756 {"analyzer", 1, (test_callback_fn)analyzer_test},
5757 #ifdef HAVE_LIBMEMCACHEDUTIL
5758 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
5759 #endif
5760 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
5761 {0, 0, 0}
5762 };
5763
5764 test_st behavior_tests[] ={
5765 {"behavior_test", 0, (test_callback_fn)behavior_test},
5766 {0, 0, 0}
5767 };
5768
5769 test_st async_tests[] ={
5770 {"add", 1, (test_callback_fn)add_wrapper },
5771 {0, 0, 0}
5772 };
5773
5774 test_st string_tests[] ={
5775 {"string static with null", 0, (test_callback_fn)string_static_null },
5776 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
5777 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
5778 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
5779 {"string append", 0, (test_callback_fn)string_alloc_append },
5780 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
5781 {0, 0, (test_callback_fn)0}
5782 };
5783
5784 test_st result_tests[] ={
5785 {"result static", 0, (test_callback_fn)result_static},
5786 {"result alloc", 0, (test_callback_fn)result_alloc},
5787 {0, 0, (test_callback_fn)0}
5788 };
5789
5790 test_st version_1_2_3[] ={
5791 {"append", 0, (test_callback_fn)append_test },
5792 {"prepend", 0, (test_callback_fn)prepend_test },
5793 {"cas", 0, (test_callback_fn)cas_test },
5794 {"cas2", 0, (test_callback_fn)cas2_test },
5795 {"append_binary", 0, (test_callback_fn)append_binary_test },
5796 {0, 0, (test_callback_fn)0}
5797 };
5798
5799 test_st user_tests[] ={
5800 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
5801 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
5802 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
5803 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
5804 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
5805 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
5806 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
5807 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
5808 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
5809 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
5810 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
5811 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
5812 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
5813 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
5814 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
5815 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
5816 #ifndef __sun
5817 /*
5818 ** It seems to be something weird with the character sets..
5819 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
5820 ** guess I need to find out how this is supposed to work.. Perhaps I need
5821 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
5822 ** so just disable the code for now...).
5823 */
5824 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
5825 #endif
5826 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
5827 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
5828 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
5829 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
5830 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
5831 {0, 0, (test_callback_fn)0}
5832 };
5833
5834 test_st replication_tests[]= {
5835 {"set", 1, (test_callback_fn)replication_set_test },
5836 {"get", 0, (test_callback_fn)replication_get_test },
5837 {"mget", 0, (test_callback_fn)replication_mget_test },
5838 {"delete", 0, (test_callback_fn)replication_delete_test },
5839 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
5840 {0, 0, (test_callback_fn)0}
5841 };
5842
5843 /*
5844 * The following test suite is used to verify that we don't introduce
5845 * regression bugs. If you want more information about the bug / test,
5846 * you should look in the bug report at
5847 * http://bugs.launchpad.net/libmemcached
5848 */
5849 test_st regression_tests[]= {
5850 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
5851 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
5852 {"lp:434843 buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
5853 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
5854 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
5855 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
5856 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
5857 {"lp:490486", 1, (test_callback_fn)regression_bug_490486 },
5858 {0, 0, (test_callback_fn)0}
5859 };
5860
5861 test_st ketama_compatibility[]= {
5862 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
5863 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
5864 {0, 0, (test_callback_fn)0}
5865 };
5866
5867 test_st generate_tests[] ={
5868 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5869 {"generate_data", 1, (test_callback_fn)generate_data },
5870 {"get_read", 0, (test_callback_fn)get_read },
5871 {"delete_generate", 0, (test_callback_fn)delete_generate },
5872 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5873 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
5874 {"generate_data", 1, (test_callback_fn)generate_data },
5875 {"mget_read", 0, (test_callback_fn)mget_read },
5876 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
5877 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
5878 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5879 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
5880 {"generate_data", 1, (test_callback_fn)generate_data },
5881 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5882 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5883 {0, 0, (test_callback_fn)0}
5884 };
5885
5886 test_st consistent_tests[] ={
5887 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5888 {"generate_data", 1, (test_callback_fn)generate_data },
5889 {"get_read", 0, (test_callback_fn)get_read_count },
5890 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5891 {0, 0, (test_callback_fn)0}
5892 };
5893
5894 test_st consistent_weighted_tests[] ={
5895 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5896 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
5897 {"get_read", 0, (test_callback_fn)get_read_count },
5898 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5899 {0, 0, (test_callback_fn)0}
5900 };
5901
5902 test_st hsieh_availability[] ={
5903 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
5904 {0, 0, (test_callback_fn)0}
5905 };
5906
5907 #if 0
5908 test_st hash_sanity[] ={
5909 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
5910 {0, 0, (test_callback_fn)0}
5911 };
5912 #endif
5913
5914 test_st ketama_auto_eject_hosts[] ={
5915 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
5916 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
5917 {0, 0, (test_callback_fn)0}
5918 };
5919
5920 test_st hash_tests[] ={
5921 {"md5", 0, (test_callback_fn)md5_run },
5922 {"crc", 0, (test_callback_fn)crc_run },
5923 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
5924 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
5925 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
5926 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
5927 {"hsieh", 0, (test_callback_fn)hsieh_run },
5928 {"murmur", 0, (test_callback_fn)murmur_run },
5929 {"jenkis", 0, (test_callback_fn)jenkins_run },
5930 {0, 0, (test_callback_fn)0}
5931 };
5932
5933 collection_st collection[] ={
5934 #if 0
5935 {"hash_sanity", 0, 0, hash_sanity},
5936 #endif
5937 {"hsieh_availability", 0, 0, hsieh_availability},
5938 {"udp_setup", (test_callback_fn)init_udp, 0, udp_setup_server_tests},
5939 {"udp_io", (test_callback_fn)init_udp, 0, upd_io_tests},
5940 {"udp_binary_io", (test_callback_fn)binary_init_udp, 0, upd_io_tests},
5941 {"block", 0, 0, tests},
5942 {"binary", (test_callback_fn)pre_binary, 0, tests},
5943 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
5944 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5945 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
5946 {"md5", (test_callback_fn)pre_md5, 0, tests},
5947 {"crc", (test_callback_fn)pre_crc, 0, tests},
5948 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
5949 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
5950 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
5951 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
5952 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
5953 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
5954 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
5955 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
5956 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
5957 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5958 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
5959 {"gets", (test_callback_fn)enable_cas, 0, tests},
5960 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
5961 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
5962 #ifdef MEMCACHED_ENABLE_DEPRECATED
5963 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
5964 #endif
5965 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
5966 {"prefix", (test_callback_fn)set_prefix, 0, tests},
5967 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
5968 {"string", 0, 0, string_tests},
5969 {"result", 0, 0, result_tests},
5970 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
5971 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
5972 {"user", 0, 0, user_tests},
5973 {"generate", 0, 0, generate_tests},
5974 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
5975 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
5976 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
5977 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
5978 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
5979 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
5980 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
5981 {"consistent_not", 0, 0, consistent_tests},
5982 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
5983 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
5984 {"ketama_compat", 0, 0, ketama_compatibility},
5985 {"test_hashes", 0, 0, hash_tests},
5986 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
5987 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
5988 {"regression", 0, 0, regression_tests},
5989 {"behaviors", 0, 0, behavior_tests},
5990 {0, 0, 0, 0}
5991 };
5992
5993 #define SERVERS_TO_CREATE 5
5994
5995 #include "libmemcached_world.h"
5996
5997 void get_world(world_st *world)
5998 {
5999 world->collections= collection;
6000
6001 world->create= (test_callback_create_fn)world_create;
6002 world->destroy= (test_callback_fn)world_destroy;
6003
6004 world->test.startup= (test_callback_fn)world_test_startup;
6005 world->test.flush= (test_callback_fn)world_flush;
6006 world->test.pre_run= (test_callback_fn)world_pre_run;
6007 world->test.post_run= (test_callback_fn)world_post_run;
6008 world->test.on_error= (test_callback_error_fn)world_on_error;
6009
6010 world->collection.startup= (test_callback_fn)world_container_startup;
6011 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
6012
6013 world->runner= &defualt_libmemcached_runner;
6014 }