4473000dc2d9e5526442957be6ed2490318fd622
[awesomized/libmemcached] / tests / function.c
1 /*
2 Sample test application.
3 */
4 #include <assert.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/time.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <unistd.h>
12 #include <time.h>
13 #include "server.h"
14 #include "../clients/generator.h"
15 #include "../clients/execute.h"
16
17 #ifndef INT64_MAX
18 #define INT64_MAX LONG_MAX
19 #endif
20 #ifndef INT32_MAX
21 #define INT32_MAX INT_MAX
22 #endif
23
24
25 #include "test.h"
26
27 #define GLOBAL_COUNT 10000
28 #define GLOBAL2_COUNT 100
29 #define SERVERS_TO_CREATE 5
30 static uint32_t global_count;
31
32 static pairs_st *global_pairs;
33 static char *global_keys[GLOBAL_COUNT];
34 static size_t global_keys_length[GLOBAL_COUNT];
35
36 static test_return init_test(memcached_st *not_used __attribute__((unused)))
37 {
38 memcached_st memc;
39
40 (void)memcached_create(&memc);
41 memcached_free(&memc);
42
43 return 0;
44 }
45
46 static test_return server_list_null_test(memcached_st *ptr __attribute__((unused)))
47 {
48 memcached_server_st *server_list;
49 memcached_return rc;
50
51 server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, NULL);
52 assert(server_list == NULL);
53
54 server_list= memcached_server_list_append_with_weight(NULL, "localhost", 0, 0, NULL);
55 assert(server_list == NULL);
56
57 server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, &rc);
58 assert(server_list == NULL);
59
60 return 0;
61 }
62
63 #define TEST_PORT_COUNT 7
64 uint32_t test_ports[TEST_PORT_COUNT];
65
66 static memcached_return server_display_function(memcached_st *ptr __attribute__((unused)), memcached_server_st *server, void *context)
67 {
68 /* Do Nothing */
69 uint32_t bigger= *((uint32_t *)(context));
70 assert(bigger <= server->port);
71 *((uint32_t *)(context))= server->port;
72
73 return MEMCACHED_SUCCESS;
74 }
75
76 static test_return server_sort_test(memcached_st *ptr __attribute__((unused)))
77 {
78 uint32_t x;
79 uint32_t bigger= 0; /* Prime the value for the assert in server_display_function */
80 memcached_return rc;
81 memcached_server_function callbacks[1];
82 memcached_st *local_memc;
83
84 local_memc= memcached_create(NULL);
85 assert(local_memc);
86 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
87
88 for (x= 0; x < TEST_PORT_COUNT; x++)
89 {
90 test_ports[x]= random() % 64000;
91 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
92 assert(local_memc->number_of_hosts == x + 1);
93 assert(local_memc->hosts[0].count == x+1);
94 assert(rc == MEMCACHED_SUCCESS);
95 }
96
97 callbacks[0]= server_display_function;
98 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
99
100
101 memcached_free(local_memc);
102
103 return 0;
104 }
105
106 static test_return server_sort2_test(memcached_st *ptr __attribute__((unused)))
107 {
108 uint32_t bigger= 0; /* Prime the value for the assert in server_display_function */
109 memcached_return rc;
110 memcached_server_function callbacks[1];
111 memcached_st *local_memc;
112
113 local_memc= memcached_create(NULL);
114 assert(local_memc);
115 rc= memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
116 assert(rc == MEMCACHED_SUCCESS);
117
118 rc= memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43043, 0);
119 assert(rc == MEMCACHED_SUCCESS);
120 assert(local_memc->hosts[0].port == 43043);
121
122 rc= memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43042, 0);
123 assert(rc == MEMCACHED_SUCCESS);
124 assert(local_memc->hosts[0].port == 43042);
125 assert(local_memc->hosts[1].port == 43043);
126
127 callbacks[0]= server_display_function;
128 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
129
130
131 memcached_free(local_memc);
132
133 return 0;
134 }
135
136 static memcached_return server_display_unsort_function(memcached_st *ptr __attribute__((unused)), memcached_server_st *server, void *context)
137 {
138 /* Do Nothing */
139 uint32_t x= *((uint32_t *)(context));
140
141 assert(test_ports[x] == server->port);
142 *((uint32_t *)(context))= ++x;
143
144 return MEMCACHED_SUCCESS;
145 }
146
147 static test_return server_unsort_test(memcached_st *ptr __attribute__((unused)))
148 {
149 uint32_t x;
150 uint32_t counter= 0; /* Prime the value for the assert in server_display_function */
151 uint32_t bigger= 0; /* Prime the value for the assert in server_display_function */
152 memcached_return rc;
153 memcached_server_function callbacks[1];
154 memcached_st *local_memc;
155
156 local_memc= memcached_create(NULL);
157 assert(local_memc);
158
159 for (x= 0; x < TEST_PORT_COUNT; x++)
160 {
161 test_ports[x]= random() % 64000;
162 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
163 assert(local_memc->number_of_hosts == x+1);
164 assert(local_memc->hosts[0].count == x+1);
165 assert(rc == MEMCACHED_SUCCESS);
166 }
167
168 callbacks[0]= server_display_unsort_function;
169 memcached_server_cursor(local_memc, callbacks, (void *)&counter, 1);
170
171 /* Now we sort old data! */
172 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
173 callbacks[0]= server_display_function;
174 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
175
176
177 memcached_free(local_memc);
178
179 return 0;
180 }
181
182 static test_return allocation_test(memcached_st *not_used __attribute__((unused)))
183 {
184 memcached_st *memc;
185 memc= memcached_create(NULL);
186 assert(memc);
187 memcached_free(memc);
188
189 return 0;
190 }
191
192 static test_return clone_test(memcached_st *memc)
193 {
194 /* All null? */
195 {
196 memcached_st *clone;
197 clone= memcached_clone(NULL, NULL);
198 assert(clone);
199 memcached_free(clone);
200 }
201
202 /* Can we init from null? */
203 {
204 memcached_st *clone;
205 clone= memcached_clone(NULL, memc);
206 assert(clone);
207
208 assert(clone->call_free == memc->call_free);
209 assert(clone->call_malloc == memc->call_malloc);
210 assert(clone->call_realloc == memc->call_realloc);
211 assert(clone->connect_timeout == memc->connect_timeout);
212 assert(clone->delete_trigger == memc->delete_trigger);
213 assert(clone->distribution == memc->distribution);
214 assert(clone->flags == memc->flags);
215 assert(clone->get_key_failure == memc->get_key_failure);
216 assert(clone->hash == memc->hash);
217 assert(clone->hash_continuum == memc->hash_continuum);
218 assert(clone->io_bytes_watermark == memc->io_bytes_watermark);
219 assert(clone->io_msg_watermark == memc->io_msg_watermark);
220 assert(clone->on_cleanup == memc->on_cleanup);
221 assert(clone->on_clone == memc->on_clone);
222 assert(clone->poll_timeout == memc->poll_timeout);
223 assert(clone->rcv_timeout == memc->rcv_timeout);
224 assert(clone->recv_size == memc->recv_size);
225 assert(clone->retry_timeout == memc->retry_timeout);
226 assert(clone->send_size == memc->send_size);
227 assert(clone->server_failure_limit == memc->server_failure_limit);
228 assert(clone->snd_timeout == memc->snd_timeout);
229 assert(clone->user_data == memc->user_data);
230
231 memcached_free(clone);
232 }
233
234 /* Can we init from struct? */
235 {
236 memcached_st declared_clone;
237 memcached_st *clone;
238 memset(&declared_clone, 0 , sizeof(memcached_st));
239 clone= memcached_clone(&declared_clone, NULL);
240 assert(clone);
241 memcached_free(clone);
242 }
243
244 /* Can we init from struct? */
245 {
246 memcached_st declared_clone;
247 memcached_st *clone;
248 memset(&declared_clone, 0 , sizeof(memcached_st));
249 clone= memcached_clone(&declared_clone, memc);
250 assert(clone);
251 memcached_free(clone);
252 }
253
254 return 0;
255 }
256
257 static test_return connection_test(memcached_st *memc)
258 {
259 memcached_return rc;
260
261 rc= memcached_server_add_with_weight(memc, "localhost", 0, 0);
262 assert(rc == MEMCACHED_SUCCESS);
263
264 return 0;
265 }
266
267 static test_return error_test(memcached_st *memc)
268 {
269 memcached_return rc;
270
271 for (rc= MEMCACHED_SUCCESS; rc < MEMCACHED_MAXIMUM_RETURN; rc++)
272 {
273 printf("Error %d -> %s\n", rc, memcached_strerror(memc, rc));
274 }
275
276 return 0;
277 }
278
279 static test_return set_test(memcached_st *memc)
280 {
281 memcached_return rc;
282 char *key= "foo";
283 char *value= "when we sanitize";
284
285 rc= memcached_set(memc, key, strlen(key),
286 value, strlen(value),
287 (time_t)0, (uint32_t)0);
288 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
289
290 return 0;
291 }
292
293 static test_return append_test(memcached_st *memc)
294 {
295 memcached_return rc;
296 char *key= "fig";
297 char *value= "we";
298 size_t value_length;
299 uint32_t flags;
300
301 rc= memcached_flush(memc, 0);
302 assert(rc == MEMCACHED_SUCCESS);
303
304 rc= memcached_set(memc, key, strlen(key),
305 value, strlen(value),
306 (time_t)0, (uint32_t)0);
307 assert(rc == MEMCACHED_SUCCESS);
308
309 rc= memcached_append(memc, key, strlen(key),
310 " the", strlen(" the"),
311 (time_t)0, (uint32_t)0);
312 assert(rc == MEMCACHED_SUCCESS);
313
314 rc= memcached_append(memc, key, strlen(key),
315 " people", strlen(" people"),
316 (time_t)0, (uint32_t)0);
317 assert(rc == MEMCACHED_SUCCESS);
318
319 value= memcached_get(memc, key, strlen(key),
320 &value_length, &flags, &rc);
321 assert(!memcmp(value, "we the people", strlen("we the people")));
322 assert(strlen("we the people") == value_length);
323 assert(rc == MEMCACHED_SUCCESS);
324 free(value);
325
326 return 0;
327 }
328
329 static test_return append_binary_test(memcached_st *memc)
330 {
331 memcached_return rc;
332 char *key= "numbers";
333 unsigned int *store_ptr;
334 unsigned int store_list[] = { 23, 56, 499, 98, 32847, 0 };
335 char *value;
336 size_t value_length;
337 uint32_t flags;
338 unsigned int x;
339
340 rc= memcached_flush(memc, 0);
341 assert(rc == MEMCACHED_SUCCESS);
342
343 rc= memcached_set(memc,
344 key, strlen(key),
345 NULL, 0,
346 (time_t)0, (uint32_t)0);
347 assert(rc == MEMCACHED_SUCCESS);
348
349 for (x= 0; store_list[x] ; x++)
350 {
351 rc= memcached_append(memc,
352 key, strlen(key),
353 (char *)&store_list[x], sizeof(unsigned int),
354 (time_t)0, (uint32_t)0);
355 assert(rc == MEMCACHED_SUCCESS);
356 }
357
358 value= memcached_get(memc, key, strlen(key),
359 &value_length, &flags, &rc);
360 assert((value_length == (sizeof(unsigned int) * x)));
361 assert(rc == MEMCACHED_SUCCESS);
362
363 store_ptr= (unsigned int *)value;
364 x= 0;
365 while ((size_t)store_ptr < (size_t)(value + value_length))
366 {
367 assert(*store_ptr == store_list[x++]);
368 store_ptr++;
369 }
370 free(value);
371
372 return 0;
373 }
374
375 static test_return cas2_test(memcached_st *memc)
376 {
377 memcached_return rc;
378 char *keys[]= {"fudge", "son", "food"};
379 size_t key_length[]= {5, 3, 4};
380 char *value= "we the people";
381 size_t value_length= strlen("we the people");
382 unsigned int x;
383 memcached_result_st results_obj;
384 memcached_result_st *results;
385 unsigned int set= 1;
386
387 rc= memcached_flush(memc, 0);
388 assert(rc == MEMCACHED_SUCCESS);
389
390 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
391
392 for (x= 0; x < 3; x++)
393 {
394 rc= memcached_set(memc, keys[x], key_length[x],
395 keys[x], key_length[x],
396 (time_t)50, (uint32_t)9);
397 assert(rc == MEMCACHED_SUCCESS);
398 }
399
400 rc= memcached_mget(memc, keys, key_length, 3);
401
402 results= memcached_result_create(memc, &results_obj);
403
404 results= memcached_fetch_result(memc, &results_obj, &rc);
405 assert(results);
406 assert(results->cas);
407 assert(rc == MEMCACHED_SUCCESS);
408 WATCHPOINT_ASSERT(memcached_result_cas(results));
409
410 assert(!memcmp(value, "we the people", strlen("we the people")));
411 assert(strlen("we the people") == value_length);
412 assert(rc == MEMCACHED_SUCCESS);
413
414 memcached_result_free(&results_obj);
415
416 return 0;
417 }
418
419 static test_return cas_test(memcached_st *memc)
420 {
421 memcached_return rc;
422 const char *key= "fun";
423 size_t key_length= strlen(key);
424 const char *value= "we the people";
425 char* keys[2] = { (char*)key, NULL };
426 size_t keylengths[2] = { strlen(key), 0 };
427 size_t value_length= strlen(value);
428 const char *value2= "change the value";
429 size_t value2_length= strlen(value2);
430
431 memcached_result_st results_obj;
432 memcached_result_st *results;
433 unsigned int set= 1;
434
435 rc= memcached_flush(memc, 0);
436 assert(rc == MEMCACHED_SUCCESS);
437
438 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
439
440 rc= memcached_set(memc, key, strlen(key),
441 value, strlen(value),
442 (time_t)0, (uint32_t)0);
443 assert(rc == MEMCACHED_SUCCESS);
444
445 rc= memcached_mget(memc, keys, keylengths, 1);
446
447 results= memcached_result_create(memc, &results_obj);
448
449 results= memcached_fetch_result(memc, &results_obj, &rc);
450 assert(results);
451 assert(rc == MEMCACHED_SUCCESS);
452 WATCHPOINT_ASSERT(memcached_result_cas(results));
453 assert(!memcmp(value, memcached_result_value(results), value_length));
454 assert(strlen(memcached_result_value(results)) == value_length);
455 assert(rc == MEMCACHED_SUCCESS);
456 uint64_t cas = memcached_result_cas(results);
457
458 #if 0
459 results= memcached_fetch_result(memc, &results_obj, &rc);
460 assert(rc == MEMCACHED_END);
461 assert(results == NULL);
462 #endif
463
464 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
465 assert(rc == MEMCACHED_SUCCESS);
466
467 /*
468 * The item will have a new cas value, so try to set it again with the old
469 * value. This should fail!
470 */
471 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
472 assert(rc == MEMCACHED_DATA_EXISTS);
473
474 memcached_result_free(&results_obj);
475
476 return 0;
477 }
478
479 static test_return prepend_test(memcached_st *memc)
480 {
481 memcached_return rc;
482 char *key= "fig";
483 char *value= "people";
484 size_t value_length;
485 uint32_t flags;
486
487 rc= memcached_flush(memc, 0);
488 assert(rc == MEMCACHED_SUCCESS);
489
490 rc= memcached_set(memc, key, strlen(key),
491 value, strlen(value),
492 (time_t)0, (uint32_t)0);
493 assert(rc == MEMCACHED_SUCCESS);
494
495 rc= memcached_prepend(memc, key, strlen(key),
496 "the ", strlen("the "),
497 (time_t)0, (uint32_t)0);
498 assert(rc == MEMCACHED_SUCCESS);
499
500 rc= memcached_prepend(memc, key, strlen(key),
501 "we ", strlen("we "),
502 (time_t)0, (uint32_t)0);
503 assert(rc == MEMCACHED_SUCCESS);
504
505 value= memcached_get(memc, key, strlen(key),
506 &value_length, &flags, &rc);
507 assert(!memcmp(value, "we the people", strlen("we the people")));
508 assert(strlen("we the people") == value_length);
509 assert(rc == MEMCACHED_SUCCESS);
510 free(value);
511
512 return 0;
513 }
514
515 /*
516 Set the value, then quit to make sure it is flushed.
517 Come back in and test that add fails.
518 */
519 static test_return add_test(memcached_st *memc)
520 {
521 memcached_return rc;
522 char *key= "foo";
523 char *value= "when we sanitize";
524 unsigned long long setting_value;
525
526 setting_value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
527
528 rc= memcached_set(memc, key, strlen(key),
529 value, strlen(value),
530 (time_t)0, (uint32_t)0);
531 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
532 memcached_quit(memc);
533 rc= memcached_add(memc, key, strlen(key),
534 value, strlen(value),
535 (time_t)0, (uint32_t)0);
536
537 /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */
538 if (setting_value)
539 assert(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_STORED);
540 else
541 assert(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_DATA_EXISTS);
542
543 return 0;
544 }
545
546 /*
547 ** There was a problem of leaking filedescriptors in the initial release
548 ** of MacOSX 10.5. This test case triggers the problem. On some Solaris
549 ** systems it seems that the kernel is slow on reclaiming the resources
550 ** because the connects starts to time out (the test doesn't do much
551 ** anyway, so just loop 10 iterations)
552 */
553 static test_return add_wrapper(memcached_st *memc)
554 {
555 unsigned int x;
556 unsigned int max= 10000;
557 #ifdef __sun
558 max= 10;
559 #endif
560
561 for (x= 0; x < max; x++)
562 add_test(memc);
563
564 return 0;
565 }
566
567 static test_return replace_test(memcached_st *memc)
568 {
569 memcached_return rc;
570 char *key= "foo";
571 char *value= "when we sanitize";
572 char *original= "first we insert some data";
573
574 rc= memcached_set(memc, key, strlen(key),
575 original, strlen(original),
576 (time_t)0, (uint32_t)0);
577 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
578
579 rc= memcached_replace(memc, key, strlen(key),
580 value, strlen(value),
581 (time_t)0, (uint32_t)0);
582 assert(rc == MEMCACHED_SUCCESS);
583
584 return 0;
585 }
586
587 static test_return delete_test(memcached_st *memc)
588 {
589 memcached_return rc;
590 char *key= "foo";
591 char *value= "when we sanitize";
592
593 rc= memcached_set(memc, key, strlen(key),
594 value, strlen(value),
595 (time_t)0, (uint32_t)0);
596 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
597
598 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
599 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
600
601 return 0;
602 }
603
604 static test_return flush_test(memcached_st *memc)
605 {
606 memcached_return rc;
607
608 rc= memcached_flush(memc, 0);
609 assert(rc == MEMCACHED_SUCCESS);
610
611 return 0;
612 }
613
614 static memcached_return server_function(memcached_st *ptr __attribute__((unused)),
615 memcached_server_st *server __attribute__((unused)),
616 void *context __attribute__((unused)))
617 {
618 /* Do Nothing */
619
620 return MEMCACHED_SUCCESS;
621 }
622
623 static test_return memcached_server_cursor_test(memcached_st *memc)
624 {
625 char *context= "foo bad";
626 memcached_server_function callbacks[1];
627
628 callbacks[0]= server_function;
629 memcached_server_cursor(memc, callbacks, context, 1);
630
631 return 0;
632 }
633
634 static test_return bad_key_test(memcached_st *memc)
635 {
636 memcached_return rc;
637 char *key= "foo bad";
638 char *string;
639 size_t string_length;
640 uint32_t flags;
641 memcached_st *clone;
642 unsigned int set= 1;
643 size_t max_keylen= 0xffff;
644
645 clone= memcached_clone(NULL, memc);
646 assert(clone);
647
648 rc= memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
649 assert(rc == MEMCACHED_SUCCESS);
650
651 /* All keys are valid in the binary protocol (except for length) */
652 if (memcached_behavior_get(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 0)
653 {
654 string= memcached_get(clone, key, strlen(key),
655 &string_length, &flags, &rc);
656 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
657 assert(string_length == 0);
658 assert(!string);
659
660 set= 0;
661 rc= memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
662 assert(rc == MEMCACHED_SUCCESS);
663 string= memcached_get(clone, key, strlen(key),
664 &string_length, &flags, &rc);
665 assert(rc == MEMCACHED_NOTFOUND);
666 assert(string_length == 0);
667 assert(!string);
668
669 /* Test multi key for bad keys */
670 char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
671 size_t key_lengths[] = { 7, 7, 7 };
672 set= 1;
673 rc= memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
674 assert(rc == MEMCACHED_SUCCESS);
675
676 rc= memcached_mget(clone, keys, key_lengths, 3);
677 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
678
679 rc= memcached_mget_by_key(clone, "foo daddy", 9, keys, key_lengths, 1);
680 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
681
682 max_keylen= 250;
683
684 /* The following test should be moved to the end of this function when the
685 memcached server is updated to allow max size length of the keys in the
686 binary protocol
687 */
688 rc= memcached_callback_set(clone, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
689 assert(rc == MEMCACHED_SUCCESS);
690
691 char *longkey= malloc(max_keylen + 1);
692 if (longkey != NULL)
693 {
694 memset(longkey, 'a', max_keylen + 1);
695 string= memcached_get(clone, longkey, max_keylen,
696 &string_length, &flags, &rc);
697 assert(rc == MEMCACHED_NOTFOUND);
698 assert(string_length == 0);
699 assert(!string);
700
701 string= memcached_get(clone, longkey, max_keylen + 1,
702 &string_length, &flags, &rc);
703 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
704 assert(string_length == 0);
705 assert(!string);
706
707 free(longkey);
708 }
709 }
710
711 /* Make sure zero length keys are marked as bad */
712 set= 1;
713 rc= memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
714 assert(rc == MEMCACHED_SUCCESS);
715 string= memcached_get(clone, key, 0,
716 &string_length, &flags, &rc);
717 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
718 assert(string_length == 0);
719 assert(!string);
720
721 memcached_free(clone);
722
723 return 0;
724 }
725
726 #define READ_THROUGH_VALUE "set for me"
727 static memcached_return read_through_trigger(memcached_st *memc __attribute__((unused)),
728 char *key __attribute__((unused)),
729 size_t key_length __attribute__((unused)),
730 memcached_result_st *result)
731 {
732
733 return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE));
734 }
735
736 static test_return read_through(memcached_st *memc)
737 {
738 memcached_return rc;
739 char *key= "foo";
740 char *string;
741 size_t string_length;
742 uint32_t flags;
743
744 string= memcached_get(memc, key, strlen(key),
745 &string_length, &flags, &rc);
746
747 assert(rc == MEMCACHED_NOTFOUND);
748 assert(string_length == 0);
749 assert(!string);
750
751 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE, (void *)read_through_trigger);
752 assert(rc == MEMCACHED_SUCCESS);
753
754 string= memcached_get(memc, key, strlen(key),
755 &string_length, &flags, &rc);
756
757 assert(rc == MEMCACHED_SUCCESS);
758 assert(string_length == strlen(READ_THROUGH_VALUE));
759 assert(!strcmp(READ_THROUGH_VALUE, string));
760 free(string);
761
762 string= memcached_get(memc, key, strlen(key),
763 &string_length, &flags, &rc);
764
765 assert(rc == MEMCACHED_SUCCESS);
766 assert(string_length == strlen(READ_THROUGH_VALUE));
767 assert(!strcmp(READ_THROUGH_VALUE, string));
768 free(string);
769
770 return 0;
771 }
772
773 static memcached_return delete_trigger(memcached_st *ptr __attribute__((unused)),
774 const char *key,
775 size_t key_length __attribute__((unused)))
776 {
777 assert(key);
778
779 return MEMCACHED_SUCCESS;
780 }
781
782 static test_return delete_through(memcached_st *memc)
783 {
784 memcached_trigger_delete_key callback;
785 memcached_return rc;
786
787 callback= delete_trigger;
788
789 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, (void*)callback);
790 assert(rc == MEMCACHED_SUCCESS);
791
792 return 0;
793 }
794
795 static test_return get_test(memcached_st *memc)
796 {
797 memcached_return rc;
798 char *key= "foo";
799 char *string;
800 size_t string_length;
801 uint32_t flags;
802
803 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
804 assert(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND);
805
806 string= memcached_get(memc, key, strlen(key),
807 &string_length, &flags, &rc);
808
809 assert(rc == MEMCACHED_NOTFOUND);
810 assert(string_length == 0);
811 assert(!string);
812
813 return 0;
814 }
815
816 static test_return get_test2(memcached_st *memc)
817 {
818 memcached_return rc;
819 char *key= "foo";
820 char *value= "when we sanitize";
821 char *string;
822 size_t string_length;
823 uint32_t flags;
824
825 rc= memcached_set(memc, key, strlen(key),
826 value, strlen(value),
827 (time_t)0, (uint32_t)0);
828 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
829
830 string= memcached_get(memc, key, strlen(key),
831 &string_length, &flags, &rc);
832
833 assert(string);
834 assert(rc == MEMCACHED_SUCCESS);
835 assert(string_length == strlen(value));
836 assert(!memcmp(string, value, string_length));
837
838 free(string);
839
840 return 0;
841 }
842
843 static test_return set_test2(memcached_st *memc)
844 {
845 memcached_return rc;
846 char *key= "foo";
847 char *value= "train in the brain";
848 size_t value_length= strlen(value);
849 unsigned int x;
850
851 for (x= 0; x < 10; x++)
852 {
853 rc= memcached_set(memc, key, strlen(key),
854 value, value_length,
855 (time_t)0, (uint32_t)0);
856 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
857 }
858
859 return 0;
860 }
861
862 static test_return set_test3(memcached_st *memc)
863 {
864 memcached_return rc;
865 char *key= "foo";
866 char *value;
867 size_t value_length= 8191;
868 unsigned int x;
869
870 value = (char*)malloc(value_length);
871 assert(value);
872
873 for (x= 0; x < value_length; x++)
874 value[x] = (char) (x % 127);
875
876 for (x= 0; x < 1; x++)
877 {
878 rc= memcached_set(memc, key, strlen(key),
879 value, value_length,
880 (time_t)0, (uint32_t)0);
881 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
882 }
883
884 free(value);
885
886 return 0;
887 }
888
889 static test_return get_test3(memcached_st *memc)
890 {
891 memcached_return rc;
892 char *key= "foo";
893 char *value;
894 size_t value_length= 8191;
895 char *string;
896 size_t string_length;
897 uint32_t flags;
898 uint32_t x;
899
900 value = (char*)malloc(value_length);
901 assert(value);
902
903 for (x= 0; x < value_length; x++)
904 value[x] = (char) (x % 127);
905
906 rc= memcached_set(memc, key, strlen(key),
907 value, value_length,
908 (time_t)0, (uint32_t)0);
909 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
910
911 string= memcached_get(memc, key, strlen(key),
912 &string_length, &flags, &rc);
913
914 assert(rc == MEMCACHED_SUCCESS);
915 assert(string);
916 assert(string_length == value_length);
917 assert(!memcmp(string, value, string_length));
918
919 free(string);
920 free(value);
921
922 return 0;
923 }
924
925 static test_return get_test4(memcached_st *memc)
926 {
927 memcached_return rc;
928 char *key= "foo";
929 char *value;
930 size_t value_length= 8191;
931 char *string;
932 size_t string_length;
933 uint32_t flags;
934 uint32_t x;
935
936 value = (char*)malloc(value_length);
937 assert(value);
938
939 for (x= 0; x < value_length; x++)
940 value[x] = (char) (x % 127);
941
942 rc= memcached_set(memc, key, strlen(key),
943 value, value_length,
944 (time_t)0, (uint32_t)0);
945 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
946
947 for (x= 0; x < 10; x++)
948 {
949 string= memcached_get(memc, key, strlen(key),
950 &string_length, &flags, &rc);
951
952 assert(rc == MEMCACHED_SUCCESS);
953 assert(string);
954 assert(string_length == value_length);
955 assert(!memcmp(string, value, string_length));
956 free(string);
957 }
958
959 free(value);
960
961 return 0;
962 }
963
964 /*
965 * This test verifies that memcached_read_one_response doesn't try to
966 * dereference a NIL-pointer if you issue a multi-get and don't read out all
967 * responses before you execute a storage command.
968 */
969 static test_return get_test5(memcached_st *memc)
970 {
971 /*
972 ** Request the same key twice, to ensure that we hash to the same server
973 ** (so that we have multiple response values queued up) ;-)
974 */
975 char *keys[]= { "key", "key" };
976 size_t lengths[]= { 3, 3 };
977 uint32_t flags;
978 size_t rlen;
979
980 memcached_return rc= memcached_set(memc, keys[0], lengths[0],
981 keys[0], lengths[0], 0, 0);
982 assert(rc == MEMCACHED_SUCCESS);
983 rc= memcached_mget(memc, keys, lengths, 2);
984
985 memcached_result_st results_obj;
986 memcached_result_st *results;
987 results=memcached_result_create(memc, &results_obj);
988 assert(results);
989 results=memcached_fetch_result(memc, &results_obj, &rc);
990 assert(results);
991 memcached_result_free(&results_obj);
992
993 /* Don't read out the second result, but issue a set instead.. */
994 rc= memcached_set(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0);
995 assert(rc == MEMCACHED_SUCCESS);
996
997 char *val= memcached_get_by_key(memc, keys[0], lengths[0], "yek", 3,
998 &rlen, &flags, &rc);
999 assert(val == NULL);
1000 assert(rc == MEMCACHED_NOTFOUND);
1001 val= memcached_get(memc, keys[0], lengths[0], &rlen, &flags, &rc);
1002 assert(val != NULL);
1003 assert(rc == MEMCACHED_SUCCESS);
1004 free(val);
1005
1006 return TEST_SUCCESS;
1007 }
1008
1009 /* Do not copy the style of this code, I just access hosts to testthis function */
1010 static test_return stats_servername_test(memcached_st *memc)
1011 {
1012 memcached_return rc;
1013 memcached_stat_st stat;
1014 rc= memcached_stat_servername(&stat, NULL,
1015 memc->hosts[0].hostname,
1016 memc->hosts[0].port);
1017
1018 return 0;
1019 }
1020
1021 static test_return increment_test(memcached_st *memc)
1022 {
1023 uint64_t new_number;
1024 memcached_return rc;
1025 char *key= "number";
1026 char *value= "0";
1027
1028 rc= memcached_set(memc, key, strlen(key),
1029 value, strlen(value),
1030 (time_t)0, (uint32_t)0);
1031 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1032
1033 rc= memcached_increment(memc, key, strlen(key),
1034 1, &new_number);
1035 assert(rc == MEMCACHED_SUCCESS);
1036 assert(new_number == 1);
1037
1038 rc= memcached_increment(memc, key, strlen(key),
1039 1, &new_number);
1040 assert(rc == MEMCACHED_SUCCESS);
1041 assert(new_number == 2);
1042
1043 return 0;
1044 }
1045
1046 static test_return decrement_test(memcached_st *memc)
1047 {
1048 uint64_t new_number;
1049 memcached_return rc;
1050 char *key= "number";
1051 char *value= "3";
1052
1053 rc= memcached_set(memc, key, strlen(key),
1054 value, strlen(value),
1055 (time_t)0, (uint32_t)0);
1056 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1057
1058 rc= memcached_decrement(memc, key, strlen(key),
1059 1, &new_number);
1060 assert(rc == MEMCACHED_SUCCESS);
1061 assert(new_number == 2);
1062
1063 rc= memcached_decrement(memc, key, strlen(key),
1064 1, &new_number);
1065 assert(rc == MEMCACHED_SUCCESS);
1066 assert(new_number == 1);
1067
1068 return 0;
1069 }
1070
1071 static test_return quit_test(memcached_st *memc)
1072 {
1073 memcached_return rc;
1074 char *key= "fudge";
1075 char *value= "sanford and sun";
1076
1077 rc= memcached_set(memc, key, strlen(key),
1078 value, strlen(value),
1079 (time_t)10, (uint32_t)3);
1080 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1081 memcached_quit(memc);
1082
1083 rc= memcached_set(memc, key, strlen(key),
1084 value, strlen(value),
1085 (time_t)50, (uint32_t)9);
1086 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1087
1088 return 0;
1089 }
1090
1091 static test_return mget_result_test(memcached_st *memc)
1092 {
1093 memcached_return rc;
1094 char *keys[]= {"fudge", "son", "food"};
1095 size_t key_length[]= {5, 3, 4};
1096 unsigned int x;
1097
1098 memcached_result_st results_obj;
1099 memcached_result_st *results;
1100
1101 results= memcached_result_create(memc, &results_obj);
1102 assert(results);
1103 assert(&results_obj == results);
1104
1105 /* We need to empty the server before continueing test */
1106 rc= memcached_flush(memc, 0);
1107 assert(rc == MEMCACHED_SUCCESS);
1108
1109 rc= memcached_mget(memc, keys, key_length, 3);
1110 assert(rc == MEMCACHED_SUCCESS);
1111
1112 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1113 {
1114 assert(results);
1115 }
1116
1117 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1118 assert(!results);
1119 assert(rc == MEMCACHED_END);
1120
1121 for (x= 0; x < 3; x++)
1122 {
1123 rc= memcached_set(memc, keys[x], key_length[x],
1124 keys[x], key_length[x],
1125 (time_t)50, (uint32_t)9);
1126 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1127 }
1128
1129 rc= memcached_mget(memc, keys, key_length, 3);
1130 assert(rc == MEMCACHED_SUCCESS);
1131
1132 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1133 {
1134 assert(results);
1135 assert(&results_obj == results);
1136 assert(rc == MEMCACHED_SUCCESS);
1137 assert(memcached_result_key_length(results) == memcached_result_length(results));
1138 assert(!memcmp(memcached_result_key_value(results),
1139 memcached_result_value(results),
1140 memcached_result_length(results)));
1141 }
1142
1143 memcached_result_free(&results_obj);
1144
1145 return 0;
1146 }
1147
1148 static test_return mget_result_alloc_test(memcached_st *memc)
1149 {
1150 memcached_return rc;
1151 char *keys[]= {"fudge", "son", "food"};
1152 size_t key_length[]= {5, 3, 4};
1153 unsigned int x;
1154
1155 memcached_result_st *results;
1156
1157 /* We need to empty the server before continueing test */
1158 rc= memcached_flush(memc, 0);
1159 assert(rc == MEMCACHED_SUCCESS);
1160
1161 rc= memcached_mget(memc, keys, key_length, 3);
1162 assert(rc == MEMCACHED_SUCCESS);
1163
1164 while ((results= memcached_fetch_result(memc, NULL, &rc)) != NULL)
1165 {
1166 assert(results);
1167 }
1168 assert(!results);
1169 assert(rc == MEMCACHED_END);
1170
1171 for (x= 0; x < 3; x++)
1172 {
1173 rc= memcached_set(memc, keys[x], key_length[x],
1174 keys[x], key_length[x],
1175 (time_t)50, (uint32_t)9);
1176 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1177 }
1178
1179 rc= memcached_mget(memc, keys, key_length, 3);
1180 assert(rc == MEMCACHED_SUCCESS);
1181
1182 x= 0;
1183 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1184 {
1185 assert(results);
1186 assert(rc == MEMCACHED_SUCCESS);
1187 assert(memcached_result_key_length(results) == memcached_result_length(results));
1188 assert(!memcmp(memcached_result_key_value(results),
1189 memcached_result_value(results),
1190 memcached_result_length(results)));
1191 memcached_result_free(results);
1192 x++;
1193 }
1194
1195 return 0;
1196 }
1197
1198 /* Count the results */
1199 static memcached_return callback_counter(memcached_st *ptr __attribute__((unused)),
1200 memcached_result_st *result __attribute__((unused)),
1201 void *context)
1202 {
1203 unsigned int *counter= (unsigned int *)context;
1204
1205 *counter= *counter + 1;
1206
1207 return MEMCACHED_SUCCESS;
1208 }
1209
1210 static test_return mget_result_function(memcached_st *memc)
1211 {
1212 memcached_return rc;
1213 char *keys[]= {"fudge", "son", "food"};
1214 size_t key_length[]= {5, 3, 4};
1215 unsigned int x;
1216 unsigned int counter;
1217 memcached_execute_function callbacks[1];
1218
1219 /* We need to empty the server before continueing test */
1220 rc= memcached_flush(memc, 0);
1221 for (x= 0; x < 3; x++)
1222 {
1223 rc= memcached_set(memc, keys[x], key_length[x],
1224 keys[x], key_length[x],
1225 (time_t)50, (uint32_t)9);
1226 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1227 }
1228
1229 rc= memcached_mget(memc, keys, key_length, 3);
1230 assert(rc == MEMCACHED_SUCCESS);
1231
1232 callbacks[0]= &callback_counter;
1233 counter= 0;
1234 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
1235
1236 assert(counter == 3);
1237
1238 return 0;
1239 }
1240
1241 static test_return mget_test(memcached_st *memc)
1242 {
1243 memcached_return rc;
1244 char *keys[]= {"fudge", "son", "food"};
1245 size_t key_length[]= {5, 3, 4};
1246 unsigned int x;
1247 uint32_t flags;
1248
1249 char return_key[MEMCACHED_MAX_KEY];
1250 size_t return_key_length;
1251 char *return_value;
1252 size_t return_value_length;
1253
1254 /* We need to empty the server before continueing test */
1255 rc= memcached_flush(memc, 0);
1256 assert(rc == MEMCACHED_SUCCESS);
1257
1258 rc= memcached_mget(memc, keys, key_length, 3);
1259 assert(rc == MEMCACHED_SUCCESS);
1260
1261 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1262 &return_value_length, &flags, &rc)) != NULL)
1263 {
1264 assert(return_value);
1265 }
1266 assert(!return_value);
1267 assert(return_value_length == 0);
1268 assert(rc == MEMCACHED_END);
1269
1270 for (x= 0; x < 3; x++)
1271 {
1272 rc= memcached_set(memc, keys[x], key_length[x],
1273 keys[x], key_length[x],
1274 (time_t)50, (uint32_t)9);
1275 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1276 }
1277
1278 rc= memcached_mget(memc, keys, key_length, 3);
1279 assert(rc == MEMCACHED_SUCCESS);
1280
1281 x= 0;
1282 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1283 &return_value_length, &flags, &rc)))
1284 {
1285 assert(return_value);
1286 assert(rc == MEMCACHED_SUCCESS);
1287 assert(return_key_length == return_value_length);
1288 assert(!memcmp(return_value, return_key, return_value_length));
1289 free(return_value);
1290 x++;
1291 }
1292
1293 return 0;
1294 }
1295
1296 static test_return get_stats_keys(memcached_st *memc)
1297 {
1298 char **list;
1299 char **ptr;
1300 memcached_stat_st stat;
1301 memcached_return rc;
1302
1303 list= memcached_stat_get_keys(memc, &stat, &rc);
1304 assert(rc == MEMCACHED_SUCCESS);
1305 for (ptr= list; *ptr; ptr++)
1306 assert(*ptr);
1307 fflush(stdout);
1308
1309 free(list);
1310
1311 return 0;
1312 }
1313
1314 static test_return version_string_test(memcached_st *memc __attribute__((unused)))
1315 {
1316 const char *version_string;
1317
1318 version_string= memcached_lib_version();
1319
1320 assert(!strcmp(version_string, LIBMEMCACHED_VERSION_STRING));
1321
1322 return 0;
1323 }
1324
1325 static test_return get_stats(memcached_st *memc)
1326 {
1327 unsigned int x;
1328 char **list;
1329 char **ptr;
1330 memcached_return rc;
1331 memcached_stat_st *stat;
1332
1333 stat= memcached_stat(memc, NULL, &rc);
1334 assert(rc == MEMCACHED_SUCCESS);
1335
1336 assert(rc == MEMCACHED_SUCCESS);
1337 assert(stat);
1338
1339 for (x= 0; x < memcached_server_count(memc); x++)
1340 {
1341 list= memcached_stat_get_keys(memc, stat+x, &rc);
1342 assert(rc == MEMCACHED_SUCCESS);
1343 for (ptr= list; *ptr; ptr++);
1344
1345 free(list);
1346 }
1347
1348 memcached_stat_free(NULL, stat);
1349
1350 return 0;
1351 }
1352
1353 static test_return add_host_test(memcached_st *memc)
1354 {
1355 unsigned int x;
1356 memcached_server_st *servers;
1357 memcached_return rc;
1358 char servername[]= "0.example.com";
1359
1360 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1361 assert(servers);
1362 assert(1 == memcached_server_list_count(servers));
1363
1364 for (x= 2; x < 20; x++)
1365 {
1366 char buffer[SMALL_STRING_LEN];
1367
1368 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1369 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1370 &rc);
1371 assert(rc == MEMCACHED_SUCCESS);
1372 assert(x == memcached_server_list_count(servers));
1373 }
1374
1375 rc= memcached_server_push(memc, servers);
1376 assert(rc == MEMCACHED_SUCCESS);
1377 rc= memcached_server_push(memc, servers);
1378 assert(rc == MEMCACHED_SUCCESS);
1379
1380 memcached_server_list_free(servers);
1381
1382 return 0;
1383 }
1384
1385 static memcached_return clone_test_callback(memcached_st *parent __attribute__((unused)), memcached_st *clone __attribute__((unused)))
1386 {
1387 return MEMCACHED_SUCCESS;
1388 }
1389
1390 static memcached_return cleanup_test_callback(memcached_st *ptr __attribute__((unused)))
1391 {
1392 return MEMCACHED_SUCCESS;
1393 }
1394
1395 static test_return callback_test(memcached_st *memc)
1396 {
1397 /* Test User Data */
1398 {
1399 int x= 5;
1400 int *test_ptr;
1401 memcached_return rc;
1402
1403 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x);
1404 assert(rc == MEMCACHED_SUCCESS);
1405 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1406 assert(*test_ptr == x);
1407 }
1408
1409 /* Test Clone Callback */
1410 {
1411 memcached_clone_func temp_function;
1412 memcached_return rc;
1413
1414 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, (void*)clone_test_callback);
1415 assert(rc == MEMCACHED_SUCCESS);
1416 temp_function= (memcached_clone_func)memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1417 assert(temp_function == clone_test_callback);
1418 }
1419
1420 /* Test Cleanup Callback */
1421 {
1422 memcached_cleanup_func temp_function;
1423 memcached_return rc;
1424
1425 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, (void*)cleanup_test_callback);
1426 assert(rc == MEMCACHED_SUCCESS);
1427 temp_function= (memcached_cleanup_func)memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1428 assert(temp_function == cleanup_test_callback);
1429 }
1430
1431 return 0;
1432 }
1433
1434 /* We don't test the behavior itself, we test the switches */
1435 static test_return behavior_test(memcached_st *memc)
1436 {
1437 uint64_t value;
1438 uint32_t set= 1;
1439
1440 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1441 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1442 assert(value == 1);
1443
1444 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1445 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1446 assert(value == 1);
1447
1448 set= MEMCACHED_HASH_MD5;
1449 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1450 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1451 assert(value == MEMCACHED_HASH_MD5);
1452
1453 set= 0;
1454
1455 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1456 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1457 assert(value == 0);
1458
1459 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1460 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1461 assert(value == 0);
1462
1463 set= MEMCACHED_HASH_DEFAULT;
1464 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1465 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1466 assert(value == MEMCACHED_HASH_DEFAULT);
1467
1468 set= MEMCACHED_HASH_CRC;
1469 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1470 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1471 assert(value == MEMCACHED_HASH_CRC);
1472
1473 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1474 assert(value > 0);
1475
1476 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1477 assert(value > 0);
1478
1479 return 0;
1480 }
1481
1482 /* Test case provided by Cal Haldenbrand */
1483 static test_return user_supplied_bug1(memcached_st *memc)
1484 {
1485 unsigned int setter= 1;
1486 unsigned int x;
1487
1488 unsigned long long total= 0;
1489 uint32_t size= 0;
1490 char key[10];
1491 char randomstuff[6 * 1024];
1492 memcached_return rc;
1493
1494 memset(randomstuff, 0, 6 * 1024);
1495
1496 /* We just keep looking at the same values over and over */
1497 srandom(10);
1498
1499 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1500 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1501
1502
1503 /* add key */
1504 for (x= 0 ; total < 20 * 1024576 ; x++ )
1505 {
1506 unsigned int j= 0;
1507
1508 size= (rand() % ( 5 * 1024 ) ) + 400;
1509 memset(randomstuff, 0, 6 * 1024);
1510 assert(size < 6 * 1024); /* Being safe here */
1511
1512 for (j= 0 ; j < size ;j++)
1513 randomstuff[j] = (char) (rand() % 26) + 97;
1514
1515 total += size;
1516 sprintf(key, "%d", x);
1517 rc = memcached_set(memc, key, strlen(key),
1518 randomstuff, strlen(randomstuff), 10, 0);
1519 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1520 /* If we fail, lets try again */
1521 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
1522 rc = memcached_set(memc, key, strlen(key),
1523 randomstuff, strlen(randomstuff), 10, 0);
1524 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1525 }
1526
1527 return 0;
1528 }
1529
1530 /* Test case provided by Cal Haldenbrand */
1531 static test_return user_supplied_bug2(memcached_st *memc)
1532 {
1533 int errors;
1534 unsigned int setter;
1535 unsigned int x;
1536 unsigned long long total;
1537
1538 setter= 1;
1539 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1540 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1541 #ifdef NOT_YET
1542 setter = 20 * 1024576;
1543 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1544 setter = 20 * 1024576;
1545 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1546 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1547 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1548
1549 for (x= 0, errors= 0, total= 0 ; total < 20 * 1024576 ; x++)
1550 #endif
1551
1552 for (x= 0, errors= 0, total= 0 ; total < 24576 ; x++)
1553 {
1554 memcached_return rc= MEMCACHED_SUCCESS;
1555 char buffer[SMALL_STRING_LEN];
1556 uint32_t flags= 0;
1557 size_t val_len= 0;
1558 char *getval;
1559
1560 memset(buffer, 0, SMALL_STRING_LEN);
1561
1562 snprintf(buffer, SMALL_STRING_LEN, "%u", x);
1563 getval= memcached_get(memc, buffer, strlen(buffer),
1564 &val_len, &flags, &rc);
1565 if (rc != MEMCACHED_SUCCESS)
1566 {
1567 if (rc == MEMCACHED_NOTFOUND)
1568 errors++;
1569 else
1570 {
1571 WATCHPOINT_ERROR(rc);
1572 assert(0);
1573 }
1574
1575 continue;
1576 }
1577 total+= val_len;
1578 errors= 0;
1579 free(getval);
1580 }
1581
1582 return 0;
1583 }
1584
1585 /* Do a large mget() over all the keys we think exist */
1586 #define KEY_COUNT 3000 // * 1024576
1587 static test_return user_supplied_bug3(memcached_st *memc)
1588 {
1589 memcached_return rc;
1590 unsigned int setter;
1591 unsigned int x;
1592 char **keys;
1593 size_t key_lengths[KEY_COUNT];
1594
1595 setter= 1;
1596 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1597 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1598 #ifdef NOT_YET
1599 setter = 20 * 1024576;
1600 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1601 setter = 20 * 1024576;
1602 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1603 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1604 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1605 #endif
1606
1607 keys= (char **)malloc(sizeof(char *) * KEY_COUNT);
1608 assert(keys);
1609 memset(keys, 0, (sizeof(char *) * KEY_COUNT));
1610 for (x= 0; x < KEY_COUNT; x++)
1611 {
1612 char buffer[30];
1613
1614 snprintf(buffer, 30, "%u", x);
1615 keys[x]= strdup(buffer);
1616 key_lengths[x]= strlen(keys[x]);
1617 }
1618
1619 rc= memcached_mget(memc, keys, key_lengths, KEY_COUNT);
1620 assert(rc == MEMCACHED_SUCCESS);
1621
1622 /* Turn this into a help function */
1623 {
1624 char return_key[MEMCACHED_MAX_KEY];
1625 size_t return_key_length;
1626 char *return_value;
1627 size_t return_value_length;
1628 uint32_t flags;
1629
1630 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1631 &return_value_length, &flags, &rc)))
1632 {
1633 assert(return_value);
1634 assert(rc == MEMCACHED_SUCCESS);
1635 free(return_value);
1636 }
1637 }
1638
1639 for (x= 0; x < KEY_COUNT; x++)
1640 free(keys[x]);
1641 free(keys);
1642
1643 return 0;
1644 }
1645
1646 /* Make sure we behave properly if server list has no values */
1647 static test_return user_supplied_bug4(memcached_st *memc)
1648 {
1649 memcached_return rc;
1650 char *keys[]= {"fudge", "son", "food"};
1651 size_t key_length[]= {5, 3, 4};
1652 unsigned int x;
1653 uint32_t flags;
1654 char return_key[MEMCACHED_MAX_KEY];
1655 size_t return_key_length;
1656 char *return_value;
1657 size_t return_value_length;
1658
1659 /* Here we free everything before running a bunch of mget tests */
1660 {
1661 memcached_server_list_free(memc->hosts);
1662 memc->hosts= NULL;
1663 memc->number_of_hosts= 0;
1664 }
1665
1666
1667 /* We need to empty the server before continueing test */
1668 rc= memcached_flush(memc, 0);
1669 assert(rc == MEMCACHED_NO_SERVERS);
1670
1671 rc= memcached_mget(memc, keys, key_length, 3);
1672 assert(rc == MEMCACHED_NO_SERVERS);
1673
1674 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1675 &return_value_length, &flags, &rc)) != NULL)
1676 {
1677 assert(return_value);
1678 }
1679 assert(!return_value);
1680 assert(return_value_length == 0);
1681 assert(rc == MEMCACHED_NO_SERVERS);
1682
1683 for (x= 0; x < 3; x++)
1684 {
1685 rc= memcached_set(memc, keys[x], key_length[x],
1686 keys[x], key_length[x],
1687 (time_t)50, (uint32_t)9);
1688 assert(rc == MEMCACHED_NO_SERVERS);
1689 }
1690
1691 rc= memcached_mget(memc, keys, key_length, 3);
1692 assert(rc == MEMCACHED_NO_SERVERS);
1693
1694 x= 0;
1695 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1696 &return_value_length, &flags, &rc)))
1697 {
1698 assert(return_value);
1699 assert(rc == MEMCACHED_SUCCESS);
1700 assert(return_key_length == return_value_length);
1701 assert(!memcmp(return_value, return_key, return_value_length));
1702 free(return_value);
1703 x++;
1704 }
1705
1706 return 0;
1707 }
1708
1709 #define VALUE_SIZE_BUG5 1048064
1710 static test_return user_supplied_bug5(memcached_st *memc)
1711 {
1712 memcached_return rc;
1713 char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
1714 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
1715 char return_key[MEMCACHED_MAX_KEY];
1716 size_t return_key_length;
1717 char *value;
1718 size_t value_length;
1719 uint32_t flags;
1720 unsigned int count;
1721 unsigned int x;
1722 char insert_data[VALUE_SIZE_BUG5];
1723
1724 for (x= 0; x < VALUE_SIZE_BUG5; x++)
1725 insert_data[x]= rand();
1726
1727 memcached_flush(memc, 0);
1728 value= memcached_get(memc, keys[0], key_length[0],
1729 &value_length, &flags, &rc);
1730 assert(value == NULL);
1731 rc= memcached_mget(memc, keys, key_length, 4);
1732
1733 count= 0;
1734 while ((value= memcached_fetch(memc, return_key, &return_key_length,
1735 &value_length, &flags, &rc)))
1736 count++;
1737 assert(count == 0);
1738
1739 for (x= 0; x < 4; x++)
1740 {
1741 rc= memcached_set(memc, keys[x], key_length[x],
1742 insert_data, VALUE_SIZE_BUG5,
1743 (time_t)0, (uint32_t)0);
1744 assert(rc == MEMCACHED_SUCCESS);
1745 }
1746
1747 for (x= 0; x < 10; x++)
1748 {
1749 value= memcached_get(memc, keys[0], key_length[0],
1750 &value_length, &flags, &rc);
1751 assert(value);
1752 free(value);
1753
1754 rc= memcached_mget(memc, keys, key_length, 4);
1755 count= 0;
1756 while ((value= memcached_fetch(memc, return_key, &return_key_length,
1757 &value_length, &flags, &rc)))
1758 {
1759 count++;
1760 free(value);
1761 }
1762 assert(count == 4);
1763 }
1764
1765 return 0;
1766 }
1767
1768 static test_return user_supplied_bug6(memcached_st *memc)
1769 {
1770 memcached_return rc;
1771 char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
1772 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
1773 char return_key[MEMCACHED_MAX_KEY];
1774 size_t return_key_length;
1775 char *value;
1776 size_t value_length;
1777 uint32_t flags;
1778 unsigned int count;
1779 unsigned int x;
1780 char insert_data[VALUE_SIZE_BUG5];
1781
1782 for (x= 0; x < VALUE_SIZE_BUG5; x++)
1783 insert_data[x]= rand();
1784
1785 memcached_flush(memc, 0);
1786 value= memcached_get(memc, keys[0], key_length[0],
1787 &value_length, &flags, &rc);
1788 assert(value == NULL);
1789 assert(rc == MEMCACHED_NOTFOUND);
1790 rc= memcached_mget(memc, keys, key_length, 4);
1791 assert(rc == MEMCACHED_SUCCESS);
1792
1793 count= 0;
1794 while ((value= memcached_fetch(memc, return_key, &return_key_length,
1795 &value_length, &flags, &rc)))
1796 count++;
1797 assert(count == 0);
1798 assert(rc == MEMCACHED_END);
1799
1800 for (x= 0; x < 4; x++)
1801 {
1802 rc= memcached_set(memc, keys[x], key_length[x],
1803 insert_data, VALUE_SIZE_BUG5,
1804 (time_t)0, (uint32_t)0);
1805 assert(rc == MEMCACHED_SUCCESS);
1806 }
1807
1808 for (x= 0; x < 2; x++)
1809 {
1810 value= memcached_get(memc, keys[0], key_length[0],
1811 &value_length, &flags, &rc);
1812 assert(value);
1813 free(value);
1814
1815 rc= memcached_mget(memc, keys, key_length, 4);
1816 assert(rc == MEMCACHED_SUCCESS);
1817 count= 3;
1818 /* We test for purge of partial complete fetches */
1819 for (count= 3; count; count--)
1820 {
1821 value= memcached_fetch(memc, return_key, &return_key_length,
1822 &value_length, &flags, &rc);
1823 assert(rc == MEMCACHED_SUCCESS);
1824 assert(!(memcmp(value, insert_data, value_length)));
1825 assert(value_length);
1826 free(value);
1827 }
1828 }
1829
1830 return 0;
1831 }
1832
1833 static test_return user_supplied_bug8(memcached_st *memc __attribute__((unused)))
1834 {
1835 memcached_return rc;
1836 memcached_st *mine;
1837 memcached_st *clone;
1838
1839 memcached_server_st *servers;
1840 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";
1841
1842 servers= memcached_servers_parse(server_list);
1843 assert(servers);
1844
1845 mine= memcached_create(NULL);
1846 rc= memcached_server_push(mine, servers);
1847 assert(rc == MEMCACHED_SUCCESS);
1848 memcached_server_list_free(servers);
1849
1850 assert(mine);
1851 clone= memcached_clone(NULL, mine);
1852
1853 memcached_quit(mine);
1854 memcached_quit(clone);
1855
1856
1857 memcached_free(mine);
1858 memcached_free(clone);
1859
1860 return 0;
1861 }
1862
1863 /* Test flag store/retrieve */
1864 static test_return user_supplied_bug7(memcached_st *memc)
1865 {
1866 memcached_return rc;
1867 char *keys= "036790384900";
1868 size_t key_length= strlen("036790384900");
1869 char return_key[MEMCACHED_MAX_KEY];
1870 size_t return_key_length;
1871 char *value;
1872 size_t value_length;
1873 uint32_t flags;
1874 unsigned int x;
1875 char insert_data[VALUE_SIZE_BUG5];
1876
1877 for (x= 0; x < VALUE_SIZE_BUG5; x++)
1878 insert_data[x]= rand();
1879
1880 memcached_flush(memc, 0);
1881
1882 flags= 245;
1883 rc= memcached_set(memc, keys, key_length,
1884 insert_data, VALUE_SIZE_BUG5,
1885 (time_t)0, flags);
1886 assert(rc == MEMCACHED_SUCCESS);
1887
1888 flags= 0;
1889 value= memcached_get(memc, keys, key_length,
1890 &value_length, &flags, &rc);
1891 assert(flags == 245);
1892 assert(value);
1893 free(value);
1894
1895 rc= memcached_mget(memc, &keys, &key_length, 1);
1896
1897 flags= 0;
1898 value= memcached_fetch(memc, return_key, &return_key_length,
1899 &value_length, &flags, &rc);
1900 assert(flags == 245);
1901 assert(value);
1902 free(value);
1903
1904
1905 return 0;
1906 }
1907
1908 static test_return user_supplied_bug9(memcached_st *memc)
1909 {
1910 memcached_return rc;
1911 char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
1912 size_t key_length[3];
1913 unsigned int x;
1914 uint32_t flags;
1915 unsigned count= 0;
1916
1917 char return_key[MEMCACHED_MAX_KEY];
1918 size_t return_key_length;
1919 char *return_value;
1920 size_t return_value_length;
1921
1922
1923 key_length[0]= strlen("UDATA:edevil@sapo.pt");
1924 key_length[1]= strlen("fudge&*@#");
1925 key_length[2]= strlen("for^#@&$not");
1926
1927
1928 for (x= 0; x < 3; x++)
1929 {
1930 rc= memcached_set(memc, keys[x], key_length[x],
1931 keys[x], key_length[x],
1932 (time_t)50, (uint32_t)9);
1933 assert(rc == MEMCACHED_SUCCESS);
1934 }
1935
1936 rc= memcached_mget(memc, keys, key_length, 3);
1937 assert(rc == MEMCACHED_SUCCESS);
1938
1939 /* We need to empty the server before continueing test */
1940 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1941 &return_value_length, &flags, &rc)) != NULL)
1942 {
1943 assert(return_value);
1944 free(return_value);
1945 count++;
1946 }
1947 assert(count == 3);
1948
1949 return 0;
1950 }
1951
1952 /* We are testing with aggressive timeout to get failures */
1953 static test_return user_supplied_bug10(memcached_st *memc)
1954 {
1955 char *key= "foo";
1956 char *value;
1957 size_t value_length= 512;
1958 unsigned int x;
1959 int key_len= 3;
1960 memcached_return rc;
1961 unsigned int set= 1;
1962 memcached_st *mclone= memcached_clone(NULL, memc);
1963 int32_t timeout;
1964
1965 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1966 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1967 timeout= 2;
1968 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
1969
1970 value = (char*)malloc(value_length * sizeof(char));
1971
1972 for (x= 0; x < value_length; x++)
1973 value[x]= (char) (x % 127);
1974
1975 for (x= 1; x <= 100000; ++x)
1976 {
1977 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
1978
1979 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_BUFFERED);
1980
1981 if (rc == MEMCACHED_WRITE_FAILURE)
1982 x--;
1983 }
1984
1985 free(value);
1986 memcached_free(mclone);
1987
1988 return 0;
1989 }
1990
1991 /*
1992 We are looking failures in the async protocol
1993 */
1994 static test_return user_supplied_bug11(memcached_st *memc)
1995 {
1996 char *key= "foo";
1997 char *value;
1998 size_t value_length= 512;
1999 unsigned int x;
2000 int key_len= 3;
2001 memcached_return rc;
2002 unsigned int set= 1;
2003 int32_t timeout;
2004 memcached_st *mclone= memcached_clone(NULL, memc);
2005
2006 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2007 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2008 timeout= -1;
2009 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
2010
2011 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2012
2013 assert(timeout == -1);
2014
2015 value = (char*)malloc(value_length * sizeof(char));
2016
2017 for (x= 0; x < value_length; x++)
2018 value[x]= (char) (x % 127);
2019
2020 for (x= 1; x <= 100000; ++x)
2021 {
2022 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2023 }
2024
2025 free(value);
2026 memcached_free(mclone);
2027
2028 return 0;
2029 }
2030
2031 /*
2032 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2033 */
2034 static test_return user_supplied_bug12(memcached_st *memc)
2035 {
2036 memcached_return rc;
2037 uint32_t flags;
2038 size_t value_length;
2039 char *value;
2040 uint64_t number_value;
2041
2042 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2043 &value_length, &flags, &rc);
2044 assert(value == NULL);
2045 assert(rc == MEMCACHED_NOTFOUND);
2046
2047 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2048 1, &number_value);
2049
2050 assert(value == NULL);
2051 /* The binary protocol will set the key if it doesn't exist */
2052 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2053 assert(rc == MEMCACHED_SUCCESS);
2054 else
2055 assert(rc == MEMCACHED_NOTFOUND);
2056
2057 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2058
2059 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2060 &value_length, &flags, &rc);
2061 assert(value);
2062 assert(rc == MEMCACHED_SUCCESS);
2063 free(value);
2064
2065 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2066 1, &number_value);
2067 assert(number_value == 2);
2068 assert(rc == MEMCACHED_SUCCESS);
2069
2070 return 0;
2071 }
2072
2073 /*
2074 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2075 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2076 */
2077 static test_return user_supplied_bug13(memcached_st *memc)
2078 {
2079 char key[] = "key34567890";
2080 char *overflow;
2081 memcached_return rc;
2082 size_t overflowSize;
2083
2084 char commandFirst[]= "set key34567890 0 0 ";
2085 char commandLast[] = " \r\n"; /* first line of command sent to server */
2086 size_t commandLength;
2087 size_t testSize;
2088
2089 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2090
2091 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2092
2093 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2094 {
2095 overflow= malloc(testSize);
2096 assert(overflow != NULL);
2097
2098 memset(overflow, 'x', testSize);
2099 rc= memcached_set(memc, key, strlen(key),
2100 overflow, testSize, 0, 0);
2101 assert(rc == MEMCACHED_SUCCESS);
2102 free(overflow);
2103 }
2104
2105 return 0;
2106 }
2107
2108
2109 /*
2110 Test values of many different sizes
2111 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2112 set key34567890 0 0 8169 \r\n
2113 is sent followed by buffer of size 8169, followed by 8169
2114 */
2115 static test_return user_supplied_bug14(memcached_st *memc)
2116 {
2117 int setter= 1;
2118 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2119 memcached_return rc;
2120 char *key= "foo";
2121 char *value;
2122 size_t value_length= 18000;
2123 char *string;
2124 size_t string_length;
2125 uint32_t flags;
2126 unsigned int x;
2127 size_t current_length;
2128
2129 value = (char*)malloc(value_length);
2130 assert(value);
2131
2132 for (x= 0; x < value_length; x++)
2133 value[x] = (char) (x % 127);
2134
2135 for (current_length= 0; current_length < value_length; current_length++)
2136 {
2137 rc= memcached_set(memc, key, strlen(key),
2138 value, current_length,
2139 (time_t)0, (uint32_t)0);
2140 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2141
2142 string= memcached_get(memc, key, strlen(key),
2143 &string_length, &flags, &rc);
2144
2145 assert(rc == MEMCACHED_SUCCESS);
2146 assert(string_length == current_length);
2147 assert(!memcmp(string, value, string_length));
2148
2149 free(string);
2150 }
2151
2152 free(value);
2153
2154 return 0;
2155 }
2156
2157 /*
2158 Look for zero length value problems
2159 */
2160 static test_return user_supplied_bug15(memcached_st *memc)
2161 {
2162 uint32_t x;
2163 memcached_return rc;
2164 char *key= "mykey";
2165 char *value;
2166 size_t length;
2167 uint32_t flags;
2168
2169 for (x= 0; x < 2; x++)
2170 {
2171 rc= memcached_set(memc, key, strlen(key),
2172 NULL, 0,
2173 (time_t)0, (uint32_t)0);
2174
2175 assert(rc == MEMCACHED_SUCCESS);
2176
2177 value= memcached_get(memc, key, strlen(key),
2178 &length, &flags, &rc);
2179
2180 assert(rc == MEMCACHED_SUCCESS);
2181 assert(value == NULL);
2182 assert(length == 0);
2183 assert(flags == 0);
2184
2185 value= memcached_get(memc, key, strlen(key),
2186 &length, &flags, &rc);
2187
2188 assert(rc == MEMCACHED_SUCCESS);
2189 assert(value == NULL);
2190 assert(length == 0);
2191 assert(flags == 0);
2192 }
2193
2194 return 0;
2195 }
2196
2197 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2198 static test_return user_supplied_bug16(memcached_st *memc)
2199 {
2200 memcached_return rc;
2201 char *key= "mykey";
2202 char *value;
2203 size_t length;
2204 uint32_t flags;
2205
2206 rc= memcached_set(memc, key, strlen(key),
2207 NULL, 0,
2208 (time_t)0, UINT32_MAX);
2209
2210 assert(rc == MEMCACHED_SUCCESS);
2211
2212 value= memcached_get(memc, key, strlen(key),
2213 &length, &flags, &rc);
2214
2215 assert(rc == MEMCACHED_SUCCESS);
2216 assert(value == NULL);
2217 assert(length == 0);
2218 assert(flags == UINT32_MAX);
2219
2220 return 0;
2221 }
2222
2223 /* Check the validity of chinese key*/
2224 static test_return user_supplied_bug17(memcached_st *memc)
2225 {
2226 memcached_return rc;
2227 char *key= "豆瓣";
2228 char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2229 char *value2;
2230 size_t length;
2231 uint32_t flags;
2232
2233 rc= memcached_set(memc, key, strlen(key),
2234 value, strlen(value),
2235 (time_t)0, 0);
2236
2237 assert(rc == MEMCACHED_SUCCESS);
2238
2239 value2= memcached_get(memc, key, strlen(key),
2240 &length, &flags, &rc);
2241
2242 assert(length==strlen(value));
2243 assert(rc == MEMCACHED_SUCCESS);
2244 assert(memcmp(value, value2, length)==0);
2245 free(value2);
2246
2247 return 0;
2248 }
2249
2250 /*
2251 From Andrei on IRC
2252 */
2253
2254 test_return user_supplied_bug19(memcached_st *memc)
2255 {
2256 memcached_st *m;
2257 memcached_server_st *s;
2258 memcached_return res;
2259
2260 (void)memc;
2261
2262 m= memcached_create(NULL);
2263 memcached_server_add_with_weight(m, "localhost", 11311, 100);
2264 memcached_server_add_with_weight(m, "localhost", 11312, 100);
2265
2266 s= memcached_server_by_key(m, "a", 1, &res);
2267 memcached_server_free(s);
2268
2269 memcached_free(m);
2270
2271 return 0;
2272 }
2273
2274 /* CAS test from Andei */
2275 test_return user_supplied_bug20(memcached_st *memc)
2276 {
2277 memcached_return status;
2278 memcached_result_st *result, result_obj;
2279 char *key = "abc";
2280 size_t key_len = strlen("abc");
2281 char *value = "foobar";
2282 size_t value_len = strlen(value);
2283
2284 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2285
2286 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2287 assert(status == MEMCACHED_SUCCESS);
2288
2289 status = memcached_mget(memc, &key, &key_len, 1);
2290 assert(status == MEMCACHED_SUCCESS);
2291
2292 result= memcached_result_create(memc, &result_obj);
2293 assert(result);
2294
2295 memcached_result_create(memc, &result_obj);
2296 result= memcached_fetch_result(memc, &result_obj, &status);
2297
2298 assert(result);
2299 assert(status == MEMCACHED_SUCCESS);
2300
2301 memcached_result_free(result);
2302
2303 return 0;
2304 }
2305
2306 #include "ketama_test_cases.h"
2307 test_return user_supplied_bug18(memcached_st *trash)
2308 {
2309 memcached_return rc;
2310 int value;
2311 int x;
2312 memcached_server_st *server_pool;
2313 memcached_st *memc;
2314
2315 (void)trash;
2316
2317 memc= memcached_create(NULL);
2318 assert(memc);
2319
2320 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2321 assert(rc == MEMCACHED_SUCCESS);
2322
2323 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2324 assert(value == 1);
2325
2326 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2327 assert(rc == MEMCACHED_SUCCESS);
2328
2329 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2330 assert(value == MEMCACHED_HASH_MD5);
2331
2332 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");
2333 memcached_server_push(memc, server_pool);
2334
2335 /* verify that the server list was parsed okay. */
2336 assert(memc->number_of_hosts == 8);
2337 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2338 assert(server_pool[0].port == 11211);
2339 assert(server_pool[0].weight == 600);
2340 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2341 assert(server_pool[2].port == 11211);
2342 assert(server_pool[2].weight == 200);
2343 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2344 assert(server_pool[7].port == 11211);
2345 assert(server_pool[7].weight == 100);
2346
2347 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2348 * us test the boundary wraparound.
2349 */
2350 assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
2351
2352 /* verify the standard ketama set. */
2353 for (x= 0; x < 99; x++)
2354 {
2355 uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
2356 char *hostname = memc->hosts[server_idx].hostname;
2357 assert(strcmp(hostname, test_cases[x].server) == 0);
2358 }
2359
2360 memcached_server_list_free(server_pool);
2361 memcached_free(memc);
2362
2363 return 0;
2364 }
2365
2366 static test_return result_static(memcached_st *memc)
2367 {
2368 memcached_result_st result;
2369 memcached_result_st *result_ptr;
2370
2371 result_ptr= memcached_result_create(memc, &result);
2372 assert(result.is_allocated == false);
2373 assert(result_ptr);
2374 memcached_result_free(&result);
2375
2376 return 0;
2377 }
2378
2379 static test_return result_alloc(memcached_st *memc)
2380 {
2381 memcached_result_st *result;
2382
2383 result= memcached_result_create(memc, NULL);
2384 assert(result);
2385 memcached_result_free(result);
2386
2387 return 0;
2388 }
2389
2390 static test_return string_static_null(memcached_st *memc)
2391 {
2392 memcached_string_st string;
2393 memcached_string_st *string_ptr;
2394
2395 string_ptr= memcached_string_create(memc, &string, 0);
2396 assert(string.is_allocated == false);
2397 assert(string_ptr);
2398 memcached_string_free(&string);
2399
2400 return 0;
2401 }
2402
2403 static test_return string_alloc_null(memcached_st *memc)
2404 {
2405 memcached_string_st *string;
2406
2407 string= memcached_string_create(memc, NULL, 0);
2408 assert(string);
2409 memcached_string_free(string);
2410
2411 return 0;
2412 }
2413
2414 static test_return string_alloc_with_size(memcached_st *memc)
2415 {
2416 memcached_string_st *string;
2417
2418 string= memcached_string_create(memc, NULL, 1024);
2419 assert(string);
2420 memcached_string_free(string);
2421
2422 return 0;
2423 }
2424
2425 static test_return string_alloc_with_size_toobig(memcached_st *memc)
2426 {
2427 memcached_string_st *string;
2428
2429 string= memcached_string_create(memc, NULL, INT64_MAX);
2430 assert(string == NULL);
2431
2432 return 0;
2433 }
2434
2435 static test_return string_alloc_append(memcached_st *memc)
2436 {
2437 unsigned int x;
2438 char buffer[SMALL_STRING_LEN];
2439 memcached_string_st *string;
2440
2441 /* Ring the bell! */
2442 memset(buffer, 6, SMALL_STRING_LEN);
2443
2444 string= memcached_string_create(memc, NULL, 100);
2445 assert(string);
2446
2447 for (x= 0; x < 1024; x++)
2448 {
2449 memcached_return rc;
2450 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
2451 assert(rc == MEMCACHED_SUCCESS);
2452 }
2453 memcached_string_free(string);
2454
2455 return 0;
2456 }
2457
2458 static test_return string_alloc_append_toobig(memcached_st *memc)
2459 {
2460 memcached_return rc;
2461 unsigned int x;
2462 char buffer[SMALL_STRING_LEN];
2463 memcached_string_st *string;
2464
2465 /* Ring the bell! */
2466 memset(buffer, 6, SMALL_STRING_LEN);
2467
2468 string= memcached_string_create(memc, NULL, 100);
2469 assert(string);
2470
2471 for (x= 0; x < 1024; x++)
2472 {
2473 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
2474 assert(rc == MEMCACHED_SUCCESS);
2475 }
2476 rc= memcached_string_append(string, buffer, INT64_MAX);
2477 assert(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
2478 memcached_string_free(string);
2479
2480 return 0;
2481 }
2482
2483 static test_return cleanup_pairs(memcached_st *memc __attribute__((unused)))
2484 {
2485 pairs_free(global_pairs);
2486
2487 return 0;
2488 }
2489
2490 static test_return generate_pairs(memcached_st *memc __attribute__((unused)))
2491 {
2492 unsigned long long x;
2493 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
2494 global_count= GLOBAL_COUNT;
2495
2496 for (x= 0; x < global_count; x++)
2497 {
2498 global_keys[x]= global_pairs[x].key;
2499 global_keys_length[x]= global_pairs[x].key_length;
2500 }
2501
2502 return 0;
2503 }
2504
2505 static test_return generate_large_pairs(memcached_st *memc __attribute__((unused)))
2506 {
2507 unsigned long long x;
2508 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
2509 global_count= GLOBAL2_COUNT;
2510
2511 for (x= 0; x < global_count; x++)
2512 {
2513 global_keys[x]= global_pairs[x].key;
2514 global_keys_length[x]= global_pairs[x].key_length;
2515 }
2516
2517 return 0;
2518 }
2519
2520 static test_return generate_data(memcached_st *memc)
2521 {
2522 execute_set(memc, global_pairs, global_count);
2523
2524 return 0;
2525 }
2526
2527 static test_return generate_data_with_stats(memcached_st *memc)
2528 {
2529 memcached_stat_st *stat_p;
2530 memcached_return rc;
2531 uint32_t host_index= 0;
2532 execute_set(memc, global_pairs, global_count);
2533
2534 //TODO: hosts used size stats
2535 stat_p= memcached_stat(memc, NULL, &rc);
2536 assert(stat_p);
2537
2538 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
2539 {
2540 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);
2541 }
2542
2543 memcached_stat_free(NULL, stat_p);
2544
2545 return 0;
2546 }
2547 static test_return generate_buffer_data(memcached_st *memc)
2548 {
2549 int latch= 0;
2550
2551 latch= 1;
2552 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
2553 generate_data(memc);
2554
2555 return 0;
2556 }
2557
2558 static test_return get_read_count(memcached_st *memc)
2559 {
2560 unsigned int x;
2561 memcached_return rc;
2562 memcached_st *clone;
2563
2564 clone= memcached_clone(NULL, memc);
2565 assert(clone);
2566
2567 memcached_server_add_with_weight(clone, "localhost", 6666, 0);
2568
2569 {
2570 char *return_value;
2571 size_t return_value_length;
2572 uint32_t flags;
2573 uint32_t count;
2574
2575 for (x= count= 0; x < global_count; x++)
2576 {
2577 return_value= memcached_get(clone, global_keys[x], global_keys_length[x],
2578 &return_value_length, &flags, &rc);
2579 if (rc == MEMCACHED_SUCCESS)
2580 {
2581 count++;
2582 if (return_value)
2583 free(return_value);
2584 }
2585 }
2586 fprintf(stderr, "\t%u -> %u", global_count, count);
2587 }
2588
2589 memcached_free(clone);
2590
2591 return 0;
2592 }
2593
2594 static test_return get_read(memcached_st *memc)
2595 {
2596 unsigned int x;
2597 memcached_return rc;
2598
2599 {
2600 char *return_value;
2601 size_t return_value_length;
2602 uint32_t flags;
2603
2604 for (x= 0; x < global_count; x++)
2605 {
2606 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
2607 &return_value_length, &flags, &rc);
2608 /*
2609 assert(return_value);
2610 assert(rc == MEMCACHED_SUCCESS);
2611 */
2612 if (rc == MEMCACHED_SUCCESS && return_value)
2613 free(return_value);
2614 }
2615 }
2616
2617 return 0;
2618 }
2619
2620 static test_return mget_read(memcached_st *memc)
2621 {
2622 memcached_return rc;
2623
2624 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
2625 assert(rc == MEMCACHED_SUCCESS);
2626 /* Turn this into a help function */
2627 {
2628 char return_key[MEMCACHED_MAX_KEY];
2629 size_t return_key_length;
2630 char *return_value;
2631 size_t return_value_length;
2632 uint32_t flags;
2633
2634 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2635 &return_value_length, &flags, &rc)))
2636 {
2637 assert(return_value);
2638 assert(rc == MEMCACHED_SUCCESS);
2639 free(return_value);
2640 }
2641 }
2642
2643 return 0;
2644 }
2645
2646 static test_return mget_read_result(memcached_st *memc)
2647 {
2648 memcached_return rc;
2649
2650 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
2651 assert(rc == MEMCACHED_SUCCESS);
2652 /* Turn this into a help function */
2653 {
2654 memcached_result_st results_obj;
2655 memcached_result_st *results;
2656
2657 results= memcached_result_create(memc, &results_obj);
2658
2659 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
2660 {
2661 assert(results);
2662 assert(rc == MEMCACHED_SUCCESS);
2663 }
2664
2665 memcached_result_free(&results_obj);
2666 }
2667
2668 return 0;
2669 }
2670
2671 static test_return mget_read_function(memcached_st *memc)
2672 {
2673 memcached_return rc;
2674 unsigned int counter;
2675 memcached_execute_function callbacks[1];
2676
2677 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
2678 assert(rc == MEMCACHED_SUCCESS);
2679
2680 callbacks[0]= &callback_counter;
2681 counter= 0;
2682 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
2683
2684 return 0;
2685 }
2686
2687 static test_return delete_generate(memcached_st *memc)
2688 {
2689 unsigned int x;
2690
2691 for (x= 0; x < global_count; x++)
2692 {
2693 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
2694 }
2695
2696 return 0;
2697 }
2698
2699 static test_return delete_buffer_generate(memcached_st *memc)
2700 {
2701 int latch= 0;
2702 unsigned int x;
2703
2704 latch= 1;
2705 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
2706
2707 for (x= 0; x < global_count; x++)
2708 {
2709 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
2710 }
2711
2712 return 0;
2713 }
2714
2715 static test_return free_data(memcached_st *memc __attribute__((unused)))
2716 {
2717 pairs_free(global_pairs);
2718
2719 return 0;
2720 }
2721
2722 static test_return add_host_test1(memcached_st *memc)
2723 {
2724 unsigned int x;
2725 memcached_return rc;
2726 char servername[]= "0.example.com";
2727 memcached_server_st *servers;
2728
2729 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
2730 assert(servers);
2731 assert(1 == memcached_server_list_count(servers));
2732
2733 for (x= 2; x < 20; x++)
2734 {
2735 char buffer[SMALL_STRING_LEN];
2736
2737 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
2738 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
2739 &rc);
2740 assert(rc == MEMCACHED_SUCCESS);
2741 assert(x == memcached_server_list_count(servers));
2742 }
2743
2744 rc= memcached_server_push(memc, servers);
2745 assert(rc == MEMCACHED_SUCCESS);
2746 rc= memcached_server_push(memc, servers);
2747 assert(rc == MEMCACHED_SUCCESS);
2748
2749 memcached_server_list_free(servers);
2750
2751 return 0;
2752 }
2753
2754 static memcached_return pre_nonblock(memcached_st *memc)
2755 {
2756 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
2757
2758 return MEMCACHED_SUCCESS;
2759 }
2760
2761 static memcached_return pre_nonblock_binary(memcached_st *memc)
2762 {
2763 memcached_return rc= MEMCACHED_FAILURE;
2764 memcached_st *clone;
2765
2766 clone= memcached_clone(NULL, memc);
2767 assert(clone);
2768 // The memcached_version needs to be done on a clone, because the server
2769 // will not toggle protocol on an connection.
2770 memcached_version(clone);
2771
2772 if (clone->hosts[0].major_version >= 1 && clone->hosts[0].minor_version > 2)
2773 {
2774 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
2775 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2776 assert(rc == MEMCACHED_SUCCESS);
2777 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
2778 }
2779
2780 memcached_free(clone);
2781 return rc;
2782 }
2783
2784 static memcached_return pre_murmur(memcached_st *memc)
2785 {
2786 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
2787
2788 return MEMCACHED_SUCCESS;
2789 }
2790
2791 static memcached_return pre_jenkins(memcached_st *memc)
2792 {
2793 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
2794
2795 return MEMCACHED_SUCCESS;
2796 }
2797
2798
2799 static memcached_return pre_md5(memcached_st *memc)
2800 {
2801 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
2802
2803 return MEMCACHED_SUCCESS;
2804 }
2805
2806 static memcached_return pre_crc(memcached_st *memc)
2807 {
2808 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
2809
2810 return MEMCACHED_SUCCESS;
2811 }
2812
2813 static memcached_return pre_hsieh(memcached_st *memc)
2814 {
2815 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
2816
2817 return MEMCACHED_SUCCESS;
2818 }
2819
2820 static memcached_return pre_hash_fnv1_64(memcached_st *memc)
2821 {
2822 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_64);
2823
2824 return MEMCACHED_SUCCESS;
2825 }
2826
2827 static memcached_return pre_hash_fnv1a_64(memcached_st *memc)
2828 {
2829 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
2830
2831 return MEMCACHED_SUCCESS;
2832 }
2833
2834 static memcached_return pre_hash_fnv1_32(memcached_st *memc)
2835 {
2836 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
2837
2838 return MEMCACHED_SUCCESS;
2839 }
2840
2841 static memcached_return pre_hash_fnv1a_32(memcached_st *memc)
2842 {
2843 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
2844
2845 return MEMCACHED_SUCCESS;
2846 }
2847
2848 static memcached_return pre_behavior_ketama(memcached_st *memc)
2849 {
2850 memcached_return rc;
2851 uint64_t value;
2852
2853 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
2854 assert(rc == MEMCACHED_SUCCESS);
2855
2856 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
2857 assert(value == 1);
2858
2859 return MEMCACHED_SUCCESS;
2860 }
2861
2862 static memcached_return pre_behavior_ketama_weighted(memcached_st *memc)
2863 {
2864 memcached_return rc;
2865 uint64_t value;
2866
2867 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2868 assert(rc == MEMCACHED_SUCCESS);
2869
2870 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2871 assert(value == 1);
2872
2873 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2874 assert(rc == MEMCACHED_SUCCESS);
2875
2876 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2877 assert(value == MEMCACHED_HASH_MD5);
2878 return MEMCACHED_SUCCESS;
2879 }
2880
2881 static memcached_return pre_binary(memcached_st *memc)
2882 {
2883 memcached_return rc= MEMCACHED_FAILURE;
2884 memcached_st *clone;
2885
2886 clone= memcached_clone(NULL, memc);
2887 assert(clone);
2888 // The memcached_version needs to be done on a clone, because the server
2889 // will not toggle protocol on an connection.
2890 memcached_version(clone);
2891
2892 if (clone->hosts[0].major_version >= 1 && clone->hosts[0].minor_version > 2)
2893 {
2894 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2895 assert(rc == MEMCACHED_SUCCESS);
2896 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
2897 }
2898
2899 memcached_free(clone);
2900 return rc;
2901 }
2902
2903 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
2904 {
2905 free(mem);
2906 }
2907
2908 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
2909 {
2910 return malloc(size);
2911 }
2912
2913 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
2914 {
2915 return realloc(mem, size);
2916 }
2917
2918 static memcached_return set_prefix(memcached_st *memc)
2919 {
2920 memcached_return rc;
2921 const char *key= "mine";
2922 char *value;
2923
2924 /* Make sure be default none exists */
2925 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
2926 assert(rc == MEMCACHED_FAILURE);
2927
2928 /* Test a clean set */
2929 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
2930 assert(rc == MEMCACHED_SUCCESS);
2931
2932 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
2933 assert(memcmp(value, key, 4) == 0);
2934 assert(rc == MEMCACHED_SUCCESS);
2935
2936 /* Test that we can turn it off */
2937 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
2938 assert(rc == MEMCACHED_SUCCESS);
2939
2940 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
2941 assert(rc == MEMCACHED_FAILURE);
2942
2943 /* Now setup for main test */
2944 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
2945 assert(rc == MEMCACHED_SUCCESS);
2946
2947 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
2948 assert(rc == MEMCACHED_SUCCESS);
2949 assert(memcmp(value, key, 4) == 0);
2950
2951 /* Set to Zero, and then Set to something too large */
2952 {
2953 char *long_key;
2954 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
2955 assert(rc == MEMCACHED_SUCCESS);
2956
2957 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
2958 assert(rc == MEMCACHED_FAILURE);
2959 assert(value == NULL);
2960
2961 /* Test a long key for failure */
2962 /* TODO, extend test to determine based on setting, what result should be */
2963 long_key= "Thisismorethentheallottednumberofcharacters";
2964 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
2965 //assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
2966 assert(rc == MEMCACHED_SUCCESS);
2967
2968 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
2969 long_key= "This is more then the allotted number of characters";
2970 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
2971 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
2972
2973 /* Test for a bad prefix, but with a short key */
2974 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
2975 assert(rc == MEMCACHED_SUCCESS);
2976
2977 long_key= "dog cat";
2978 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
2979 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
2980 }
2981
2982 return MEMCACHED_SUCCESS;
2983 }
2984
2985 static memcached_return set_memory_alloc(memcached_st *memc)
2986 {
2987 {
2988 memcached_malloc_function test_ptr;
2989 memcached_return rc;
2990
2991 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, (void*)&my_malloc);
2992 assert(rc == MEMCACHED_SUCCESS);
2993 test_ptr= (memcached_malloc_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
2994 assert(rc == MEMCACHED_SUCCESS);
2995 assert(test_ptr == my_malloc);
2996 }
2997
2998 {
2999 memcached_realloc_function test_ptr;
3000 memcached_return rc;
3001
3002 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, (void*)&my_realloc);
3003 assert(rc == MEMCACHED_SUCCESS);
3004 test_ptr= (memcached_realloc_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3005 assert(rc == MEMCACHED_SUCCESS);
3006 assert(test_ptr == my_realloc);
3007 }
3008
3009 {
3010 memcached_free_function test_ptr;
3011 memcached_return rc;
3012
3013 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, (void*)my_free);
3014 assert(rc == MEMCACHED_SUCCESS);
3015 test_ptr= (memcached_free_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3016 assert(rc == MEMCACHED_SUCCESS);
3017 assert(test_ptr == my_free);
3018 }
3019
3020 return MEMCACHED_SUCCESS;
3021 }
3022
3023 static memcached_return enable_consistent(memcached_st *memc)
3024 {
3025 memcached_server_distribution value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3026 memcached_hash hash;
3027 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3028 pre_hsieh(memc);
3029
3030 value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3031 assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3032
3033 hash= (memcached_hash)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3034 assert(hash == MEMCACHED_HASH_HSIEH);
3035
3036
3037 return MEMCACHED_SUCCESS;
3038 }
3039
3040 static memcached_return enable_cas(memcached_st *memc)
3041 {
3042 unsigned int set= 1;
3043
3044 memcached_version(memc);
3045
3046 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3047 || memc->hosts[0].minor_version > 2)
3048 {
3049 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3050
3051 return MEMCACHED_SUCCESS;
3052 }
3053
3054 return MEMCACHED_FAILURE;
3055 }
3056
3057 static memcached_return check_for_1_2_3(memcached_st *memc)
3058 {
3059 memcached_version(memc);
3060
3061 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3062 || memc->hosts[0].minor_version > 2)
3063 return MEMCACHED_SUCCESS;
3064
3065 return MEMCACHED_FAILURE;
3066 }
3067
3068 static memcached_return pre_unix_socket(memcached_st *memc)
3069 {
3070 memcached_return rc;
3071 struct stat buf;
3072
3073 memcached_server_list_free(memc->hosts);
3074 memc->hosts= NULL;
3075 memc->number_of_hosts= 0;
3076
3077 if (stat("/tmp/memcached.socket", &buf))
3078 return MEMCACHED_FAILURE;
3079
3080 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3081
3082 return rc;
3083 }
3084
3085 static memcached_return pre_nodelay(memcached_st *memc)
3086 {
3087 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3088 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3089
3090 return MEMCACHED_SUCCESS;
3091 }
3092
3093 static memcached_return pre_settimer(memcached_st *memc)
3094 {
3095 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3096 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3097
3098 return MEMCACHED_SUCCESS;
3099 }
3100
3101 static memcached_return poll_timeout(memcached_st *memc)
3102 {
3103 int32_t timeout;
3104
3105 timeout= 100;
3106
3107 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3108
3109 timeout= (int32_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3110
3111 assert(timeout == 100);
3112
3113 return MEMCACHED_SUCCESS;
3114 }
3115
3116 static test_return noreply_test(memcached_st *memc)
3117 {
3118 memcached_return ret;
3119 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3120 assert(ret == MEMCACHED_SUCCESS);
3121 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3122 assert(ret == MEMCACHED_SUCCESS);
3123 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3124 assert(ret == MEMCACHED_SUCCESS);
3125 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3126 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3127 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3128
3129 for (int count=0; count < 5; ++count)
3130 {
3131 for (int x=0; x < 100; ++x)
3132 {
3133 char key[10];
3134 size_t len=sprintf(key, "%d", x);
3135 switch (count)
3136 {
3137 case 0:
3138 ret=memcached_add(memc, key, len, key, len, 0, 0);
3139 break;
3140 case 1:
3141 ret=memcached_replace(memc, key, len, key, len, 0, 0);
3142 break;
3143 case 2:
3144 ret=memcached_set(memc, key, len, key, len, 0, 0);
3145 break;
3146 case 3:
3147 ret=memcached_append(memc, key, len, key, len, 0, 0);
3148 break;
3149 case 4:
3150 ret=memcached_prepend(memc, key, len, key, len, 0, 0);
3151 break;
3152 }
3153 assert(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3154 }
3155
3156 /*
3157 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3158 ** API and is _ONLY_ done this way to verify that the library works the
3159 ** way it is supposed to do!!!!
3160 */
3161 int no_msg=0;
3162 for (int x=0; x < memc->number_of_hosts; ++x)
3163 no_msg+=memc->hosts[x].cursor_active;
3164
3165 assert(no_msg == 0);
3166 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3167
3168 /*
3169 ** Now validate that all items was set properly!
3170 */
3171 for (int x=0; x < 100; ++x)
3172 {
3173 char key[10];
3174 size_t len=sprintf(key, "%d", x);
3175 size_t length;
3176 uint32_t flags;
3177 char* value=memcached_get(memc, key, strlen(key),
3178 &length, &flags, &ret);
3179 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3180 switch (count)
3181 {
3182 case 0: /* FALLTHROUGH */
3183 case 1: /* FALLTHROUGH */
3184 case 2:
3185 assert(strncmp(value, key, len) == 0);
3186 assert(len == length);
3187 break;
3188 case 3:
3189 assert(length == len * 2);
3190 break;
3191 case 4:
3192 assert(length == len * 3);
3193 break;
3194 }
3195 free(value);
3196 }
3197 }
3198
3199 /* Try setting an illegal cas value (should not return an error to
3200 * the caller (because we don't expect a return message from the server)
3201 */
3202 char* keys[]= {"0"};
3203 size_t lengths[]= {1};
3204 size_t length;
3205 uint32_t flags;
3206 memcached_result_st results_obj;
3207 memcached_result_st *results;
3208 ret=memcached_mget(memc, keys, lengths, 1);
3209 assert(ret == MEMCACHED_SUCCESS);
3210
3211 results=memcached_result_create(memc, &results_obj);
3212 assert(results);
3213 results=memcached_fetch_result(memc, &results_obj, &ret);
3214 assert(results);
3215 assert(ret == MEMCACHED_SUCCESS);
3216 uint64_t cas= memcached_result_cas(results);
3217 memcached_result_free(&results_obj);
3218
3219 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3220 assert(ret == MEMCACHED_SUCCESS);
3221
3222 /*
3223 * The item will have a new cas value, so try to set it again with the old
3224 * value. This should fail!
3225 */
3226 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3227 assert(ret == MEMCACHED_SUCCESS);
3228 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3229 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3230 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3231 free(value);
3232
3233 return TEST_SUCCESS;
3234 }
3235
3236 static test_return analyzer_test(memcached_st *memc)
3237 {
3238 memcached_return rc;
3239 memcached_stat_st *stat;
3240 memcached_analysis_st *report;
3241
3242 stat= memcached_stat(memc, NULL, &rc);
3243 assert(rc == MEMCACHED_SUCCESS);
3244 assert(stat);
3245
3246 report= memcached_analyze(memc, stat, &rc);
3247 assert(rc == MEMCACHED_SUCCESS);
3248 assert(report);
3249
3250 free(report);
3251 memcached_stat_free(NULL, stat);
3252
3253 return TEST_SUCCESS;
3254 }
3255
3256 static void increment_request_id(uint16_t *id)
3257 {
3258 (*id)++;
3259 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
3260 *id= 0;
3261 }
3262
3263 static uint16_t *get_udp_request_ids(memcached_st *memc)
3264 {
3265 uint16_t *ids= malloc(sizeof(uint16_t) * memc->number_of_hosts);
3266 assert(ids != NULL);
3267 unsigned int x;
3268 for (x= 0; x < memc->number_of_hosts; x++)
3269 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
3270
3271 return ids;
3272 }
3273
3274 static test_return post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
3275 {
3276 unsigned int x;
3277 memcached_server_st *cur_server = memc->hosts;
3278 uint16_t *cur_req_ids = get_udp_request_ids(memc);
3279 for (x= 0; x < memc->number_of_hosts; x++)
3280 {
3281 assert(cur_server[x].cursor_active == 0);
3282 assert(cur_req_ids[x] == expected_req_ids[x]);
3283 }
3284 free(expected_req_ids);
3285 free(cur_req_ids);
3286 return TEST_SUCCESS;
3287 }
3288
3289 /*
3290 ** There is a little bit of a hack here, instead of removing
3291 ** the servers, I just set num host to 0 and them add then new udp servers
3292 **/
3293 static memcached_return init_udp(memcached_st *memc)
3294 {
3295 memcached_version(memc);
3296 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
3297 if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
3298 || memc->hosts[0].micro_version < 6)
3299 return MEMCACHED_FAILURE;
3300
3301 uint32_t num_hosts= memc->number_of_hosts;
3302 unsigned int x= 0;
3303 memcached_server_st servers[num_hosts];
3304 memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
3305 for (x= 0; x < num_hosts; x++)
3306 memcached_server_free(&memc->hosts[x]);
3307 memc->number_of_hosts= 0;
3308 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
3309 for (x= 0; x < num_hosts; x++)
3310 {
3311 assert(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
3312 assert(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
3313 }
3314 return MEMCACHED_SUCCESS;
3315 }
3316
3317 static memcached_return binary_init_udp(memcached_st *memc)
3318 {
3319 pre_binary(memc);
3320 return init_udp(memc);
3321 }
3322
3323 /* Make sure that I cant add a tcp server to a udp client */
3324 static test_return add_tcp_server_udp_client_test(memcached_st *memc)
3325 {
3326 memcached_server_st server;
3327 memcached_server_clone(&server, &memc->hosts[0]);
3328 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
3329 assert(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
3330 return TEST_SUCCESS;
3331 }
3332
3333 /* Make sure that I cant add a udp server to a tcp client */
3334 static test_return add_udp_server_tcp_client_test(memcached_st *memc)
3335 {
3336 memcached_server_st server;
3337 memcached_server_clone(&server, &memc->hosts[0]);
3338 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
3339
3340 memcached_st tcp_client;
3341 memcached_create(&tcp_client);
3342 assert(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
3343 return TEST_SUCCESS;
3344 }
3345
3346 static test_return set_udp_behavior_test(memcached_st *memc)
3347 {
3348
3349 memcached_quit(memc);
3350 memc->number_of_hosts= 0;
3351 run_distribution(memc);
3352 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
3353 assert(memc->flags & MEM_USE_UDP);
3354 assert(memc->flags & MEM_NOREPLY);;
3355
3356 assert(memc->number_of_hosts == 0);
3357
3358 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
3359 assert(!(memc->flags & MEM_USE_UDP));
3360 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
3361 assert(!(memc->flags & MEM_NOREPLY));
3362 return TEST_SUCCESS;
3363 }
3364
3365 static test_return udp_set_test(memcached_st *memc)
3366 {
3367 unsigned int x= 0;
3368 unsigned int num_iters= 1025; //request id rolls over at 1024
3369 for (x= 0; x < num_iters;x++)
3370 {
3371 memcached_return rc;
3372 char *key= "foo";
3373 char *value= "when we sanitize";
3374 uint16_t *expected_ids= get_udp_request_ids(memc);
3375 unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
3376 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
3377 rc= memcached_set(memc, key, strlen(key),
3378 value, strlen(value),
3379 (time_t)0, (uint32_t)0);
3380 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
3381 /** NB, the check below assumes that if new write_ptr is less than
3382 * the original write_ptr that we have flushed. For large payloads, this
3383 * maybe an invalid assumption, but for the small payload we have it is OK
3384 */
3385 if (rc == MEMCACHED_SUCCESS ||
3386 memc->hosts[server_key].write_buffer_offset < init_offset)
3387 increment_request_id(&expected_ids[server_key]);
3388
3389 if (rc == MEMCACHED_SUCCESS)
3390 {
3391 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
3392 }
3393 else
3394 {
3395 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
3396 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
3397 }
3398 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
3399 }
3400 return TEST_SUCCESS;
3401 }
3402
3403 static test_return udp_buffered_set_test(memcached_st *memc)
3404 {
3405 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3406 return udp_set_test(memc);
3407 }
3408
3409 static test_return udp_set_too_big_test(memcached_st *memc)
3410 {
3411 memcached_return rc;
3412 char *key= "bar";
3413 char value[MAX_UDP_DATAGRAM_LENGTH];
3414 uint16_t *expected_ids= get_udp_request_ids(memc);
3415 rc= memcached_set(memc, key, strlen(key),
3416 value, MAX_UDP_DATAGRAM_LENGTH,
3417 (time_t)0, (uint32_t)0);
3418 assert(rc == MEMCACHED_WRITE_FAILURE);
3419 return post_udp_op_check(memc,expected_ids);
3420 }
3421
3422 test_return udp_delete_test(memcached_st *memc)
3423 {
3424 unsigned int x= 0;
3425 unsigned int num_iters= 1025; //request id rolls over at 1024
3426 for (x= 0; x < num_iters;x++)
3427 {
3428 memcached_return rc;
3429 char *key= "foo";
3430 uint16_t *expected_ids=get_udp_request_ids(memc);
3431 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
3432 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
3433 rc= memcached_delete(memc, key, strlen(key), 0);
3434 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
3435 if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
3436 increment_request_id(&expected_ids[server_key]);
3437 if (rc == MEMCACHED_SUCCESS)
3438 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
3439 else
3440 {
3441 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
3442 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
3443 }
3444 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
3445 }
3446 return TEST_SUCCESS;
3447 }
3448
3449 static test_return udp_buffered_delete_test(memcached_st *memc)
3450 {
3451 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3452 return udp_delete_test(memc);
3453 }
3454
3455 test_return udp_verbosity_test(memcached_st *memc)
3456 {
3457 memcached_return rc;
3458 uint16_t *expected_ids= get_udp_request_ids(memc);
3459 unsigned int x;
3460 for (x= 0; x < memc->number_of_hosts;x++)
3461 increment_request_id(&expected_ids[x]);
3462
3463 rc= memcached_verbosity(memc,3);
3464 assert(rc == MEMCACHED_SUCCESS);
3465 return post_udp_op_check(memc,expected_ids);
3466 }
3467
3468 test_return udp_quit_test(memcached_st *memc)
3469 {
3470 uint16_t *expected_ids= get_udp_request_ids(memc);
3471 memcached_quit(memc);
3472 return post_udp_op_check(memc, expected_ids);
3473 }
3474
3475 test_return udp_flush_test(memcached_st *memc)
3476 {
3477 memcached_return rc;
3478 uint16_t *expected_ids= get_udp_request_ids(memc);
3479 unsigned int x;
3480 for (x= 0; x < memc->number_of_hosts;x++)
3481 increment_request_id(&expected_ids[x]);
3482
3483 rc= memcached_flush(memc,0);
3484 assert(rc == MEMCACHED_SUCCESS);
3485 return post_udp_op_check(memc,expected_ids);
3486 }
3487
3488 test_return udp_incr_test(memcached_st *memc)
3489 {
3490 memcached_return rc;
3491 char *key= "incr";
3492 char *value= "1";
3493 rc= memcached_set(memc, key, strlen(key),
3494 value, strlen(value),
3495 (time_t)0, (uint32_t)0);
3496
3497 assert(rc == MEMCACHED_SUCCESS);
3498 uint16_t *expected_ids= get_udp_request_ids(memc);
3499 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
3500 increment_request_id(&expected_ids[server_key]);
3501 uint64_t newvalue;
3502 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
3503 assert(rc == MEMCACHED_SUCCESS);
3504 return post_udp_op_check(memc, expected_ids);
3505 }
3506
3507 test_return udp_decr_test(memcached_st *memc)
3508 {
3509 memcached_return rc;
3510 char *key= "decr";
3511 char *value= "1";
3512 rc= memcached_set(memc, key, strlen(key),
3513 value, strlen(value),
3514 (time_t)0, (uint32_t)0);
3515
3516 assert(rc == MEMCACHED_SUCCESS);
3517 uint16_t *expected_ids= get_udp_request_ids(memc);
3518 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
3519 increment_request_id(&expected_ids[server_key]);
3520 uint64_t newvalue;
3521 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
3522 assert(rc == MEMCACHED_SUCCESS);
3523 return post_udp_op_check(memc, expected_ids);
3524 }
3525
3526
3527 test_return udp_stat_test(memcached_st *memc)
3528 {
3529 memcached_stat_st * rv= NULL;
3530 memcached_return rc;
3531 char args[]= "";
3532 uint16_t *expected_ids = get_udp_request_ids(memc);
3533 rv = memcached_stat(memc, args, &rc);
3534 free(rv);
3535 assert(rc == MEMCACHED_NOT_SUPPORTED);
3536 return post_udp_op_check(memc, expected_ids);
3537 }
3538
3539 test_return udp_version_test(memcached_st *memc)
3540 {
3541 memcached_return rc;
3542 uint16_t *expected_ids = get_udp_request_ids(memc);
3543 rc = memcached_version(memc);
3544 assert(rc == MEMCACHED_NOT_SUPPORTED);
3545 return post_udp_op_check(memc, expected_ids);
3546 }
3547
3548 test_return udp_get_test(memcached_st *memc)
3549 {
3550 memcached_return rc;
3551 char *key= "foo";
3552 size_t vlen;
3553 uint16_t *expected_ids = get_udp_request_ids(memc);
3554 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
3555 assert(rc == MEMCACHED_NOT_SUPPORTED);
3556 assert(val == NULL);
3557 return post_udp_op_check(memc, expected_ids);
3558 }
3559
3560 test_return udp_mixed_io_test(memcached_st *memc)
3561 {
3562 test_st current_op;
3563 test_st mixed_io_ops [] ={
3564 {"udp_set_test", 0, udp_set_test},
3565 {"udp_set_too_big_test", 0, udp_set_too_big_test},
3566 {"udp_delete_test", 0, udp_delete_test},
3567 {"udp_verbosity_test", 0, udp_verbosity_test},
3568 {"udp_quit_test", 0, udp_quit_test},
3569 {"udp_flush_test", 0, udp_flush_test},
3570 {"udp_incr_test", 0, udp_incr_test},
3571 {"udp_decr_test", 0, udp_decr_test},
3572 {"udp_version_test", 0, udp_version_test}
3573 };
3574 unsigned int x= 0;
3575 for (x= 0; x < 500; x++)
3576 {
3577 current_op= mixed_io_ops[random() % 9];
3578 assert(current_op.function(memc) == TEST_SUCCESS);
3579 }
3580 return TEST_SUCCESS;
3581 }
3582
3583 test_st udp_setup_server_tests[] ={
3584 {"set_udp_behavior_test", 0, set_udp_behavior_test},
3585 {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test},
3586 {"add_udp_server_tcp_client_test", 0, add_udp_server_tcp_client_test},
3587 {0, 0, 0}
3588 };
3589
3590 test_st upd_io_tests[] ={
3591 {"udp_set_test", 0, udp_set_test},
3592 {"udp_buffered_set_test", 0, udp_buffered_set_test},
3593 {"udp_set_too_big_test", 0, udp_set_too_big_test},
3594 {"udp_delete_test", 0, udp_delete_test},
3595 {"udp_buffered_delete_test", 0, udp_buffered_delete_test},
3596 {"udp_verbosity_test", 0, udp_verbosity_test},
3597 {"udp_quit_test", 0, udp_quit_test},
3598 {"udp_flush_test", 0, udp_flush_test},
3599 {"udp_incr_test", 0, udp_incr_test},
3600 {"udp_decr_test", 0, udp_decr_test},
3601 {"udp_stat_test", 0, udp_stat_test},
3602 {"udp_version_test", 0, udp_version_test},
3603 {"udp_get_test", 0, udp_get_test},
3604 {"udp_mixed_io_test", 0, udp_mixed_io_test},
3605 {0, 0, 0}
3606 };
3607
3608 /* Clean the server before beginning testing */
3609 test_st tests[] ={
3610 {"flush", 0, flush_test },
3611 {"init", 0, init_test },
3612 {"allocation", 0, allocation_test },
3613 {"server_list_null_test", 0, server_list_null_test},
3614 {"server_unsort", 0, server_unsort_test},
3615 {"server_sort", 0, server_sort_test},
3616 {"server_sort2", 0, server_sort2_test},
3617 {"clone_test", 0, clone_test },
3618 {"error", 0, error_test },
3619 {"set", 0, set_test },
3620 {"set2", 0, set_test2 },
3621 {"set3", 0, set_test3 },
3622 {"add", 1, add_test },
3623 {"replace", 1, replace_test },
3624 {"delete", 1, delete_test },
3625 {"get", 1, get_test },
3626 {"get2", 0, get_test2 },
3627 {"get3", 0, get_test3 },
3628 {"get4", 0, get_test4 },
3629 {"partial mget", 0, get_test5 },
3630 {"stats_servername", 0, stats_servername_test },
3631 {"increment", 0, increment_test },
3632 {"decrement", 0, decrement_test },
3633 {"quit", 0, quit_test },
3634 {"mget", 1, mget_test },
3635 {"mget_result", 1, mget_result_test },
3636 {"mget_result_alloc", 1, mget_result_alloc_test },
3637 {"mget_result_function", 1, mget_result_function },
3638 {"get_stats", 0, get_stats },
3639 {"add_host_test", 0, add_host_test },
3640 {"add_host_test_1", 0, add_host_test1 },
3641 {"get_stats_keys", 0, get_stats_keys },
3642 {"behavior_test", 0, get_stats_keys },
3643 {"callback_test", 0, get_stats_keys },
3644 {"version_string_test", 0, version_string_test},
3645 {"bad_key", 1, bad_key_test },
3646 {"memcached_server_cursor", 1, memcached_server_cursor_test },
3647 {"read_through", 1, read_through },
3648 {"delete_through", 1, delete_through },
3649 {"noreply", 1, noreply_test},
3650 {"analyzer", 1, analyzer_test},
3651 {0, 0, 0}
3652 };
3653
3654 test_st async_tests[] ={
3655 {"add", 1, add_wrapper },
3656 {0, 0, 0}
3657 };
3658
3659 test_st string_tests[] ={
3660 {"string static with null", 0, string_static_null },
3661 {"string alloc with null", 0, string_alloc_null },
3662 {"string alloc with 1K", 0, string_alloc_with_size },
3663 {"string alloc with malloc failure", 0, string_alloc_with_size_toobig },
3664 {"string append", 0, string_alloc_append },
3665 {"string append failure (too big)", 0, string_alloc_append_toobig },
3666 {0, 0, 0}
3667 };
3668
3669 test_st result_tests[] ={
3670 {"result static", 0, result_static},
3671 {"result alloc", 0, result_alloc},
3672 {0, 0, 0}
3673 };
3674
3675 test_st version_1_2_3[] ={
3676 {"append", 0, append_test },
3677 {"prepend", 0, prepend_test },
3678 {"cas", 0, cas_test },
3679 {"cas2", 0, cas2_test },
3680 {"append_binary", 0, append_binary_test },
3681 {0, 0, 0}
3682 };
3683
3684 test_st user_tests[] ={
3685 {"user_supplied_bug1", 0, user_supplied_bug1 },
3686 {"user_supplied_bug2", 0, user_supplied_bug2 },
3687 {"user_supplied_bug3", 0, user_supplied_bug3 },
3688 {"user_supplied_bug4", 0, user_supplied_bug4 },
3689 {"user_supplied_bug5", 1, user_supplied_bug5 },
3690 {"user_supplied_bug6", 1, user_supplied_bug6 },
3691 {"user_supplied_bug7", 1, user_supplied_bug7 },
3692 {"user_supplied_bug8", 1, user_supplied_bug8 },
3693 {"user_supplied_bug9", 1, user_supplied_bug9 },
3694 {"user_supplied_bug10", 1, user_supplied_bug10 },
3695 {"user_supplied_bug11", 1, user_supplied_bug11 },
3696 {"user_supplied_bug12", 1, user_supplied_bug12 },
3697 {"user_supplied_bug13", 1, user_supplied_bug13 },
3698 {"user_supplied_bug14", 1, user_supplied_bug14 },
3699 {"user_supplied_bug15", 1, user_supplied_bug15 },
3700 {"user_supplied_bug16", 1, user_supplied_bug16 },
3701 #ifndef __sun
3702 /*
3703 ** It seems to be something weird with the character sets..
3704 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
3705 ** guess I need to find out how this is supposed to work.. Perhaps I need
3706 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
3707 ** so just disable the code for now...).
3708 */
3709 {"user_supplied_bug17", 1, user_supplied_bug17 },
3710 #endif
3711 {"user_supplied_bug18", 1, user_supplied_bug18 },
3712 {"user_supplied_bug19", 1, user_supplied_bug19 },
3713 {"user_supplied_bug20", 1, user_supplied_bug20 },
3714 {0, 0, 0}
3715 };
3716
3717 test_st generate_tests[] ={
3718 {"generate_pairs", 1, generate_pairs },
3719 {"generate_data", 1, generate_data },
3720 {"get_read", 0, get_read },
3721 {"delete_generate", 0, delete_generate },
3722 {"generate_buffer_data", 1, generate_buffer_data },
3723 {"delete_buffer", 0, delete_buffer_generate},
3724 {"generate_data", 1, generate_data },
3725 {"mget_read", 0, mget_read },
3726 {"mget_read_result", 0, mget_read_result },
3727 {"mget_read_function", 0, mget_read_function },
3728 {"cleanup", 1, cleanup_pairs },
3729 {"generate_large_pairs", 1, generate_large_pairs },
3730 {"generate_data", 1, generate_data },
3731 {"generate_buffer_data", 1, generate_buffer_data },
3732 {"cleanup", 1, cleanup_pairs },
3733 {0, 0, 0}
3734 };
3735
3736 test_st consistent_tests[] ={
3737 {"generate_pairs", 1, generate_pairs },
3738 {"generate_data", 1, generate_data },
3739 {"get_read", 0, get_read_count },
3740 {"cleanup", 1, cleanup_pairs },
3741 {0, 0, 0}
3742 };
3743
3744 test_st consistent_weighted_tests[] ={
3745 {"generate_pairs", 1, generate_pairs },
3746 {"generate_data", 1, generate_data_with_stats },
3747 {"get_read", 0, get_read_count },
3748 {"cleanup", 1, cleanup_pairs },
3749 {0, 0, 0}
3750 };
3751
3752 collection_st collection[] ={
3753 {"udp_setup", init_udp, 0, udp_setup_server_tests},
3754 {"udp_io", init_udp, 0, upd_io_tests},
3755 {"udp_binary_io", binary_init_udp, 0, upd_io_tests},
3756 {"block", 0, 0, tests},
3757 {"binary", pre_binary, 0, tests},
3758 {"nonblock", pre_nonblock, 0, tests},
3759 {"nodelay", pre_nodelay, 0, tests},
3760 {"settimer", pre_settimer, 0, tests},
3761 {"md5", pre_md5, 0, tests},
3762 {"crc", pre_crc, 0, tests},
3763 {"hsieh", pre_hsieh, 0, tests},
3764 {"jenkins", pre_jenkins, 0, tests},
3765 {"fnv1_64", pre_hash_fnv1_64, 0, tests},
3766 {"fnv1a_64", pre_hash_fnv1a_64, 0, tests},
3767 {"fnv1_32", pre_hash_fnv1_32, 0, tests},
3768 {"fnv1a_32", pre_hash_fnv1a_32, 0, tests},
3769 {"ketama", pre_behavior_ketama, 0, tests},
3770 {"unix_socket", pre_unix_socket, 0, tests},
3771 {"unix_socket_nodelay", pre_nodelay, 0, tests},
3772 {"poll_timeout", poll_timeout, 0, tests},
3773 {"gets", enable_cas, 0, tests},
3774 {"consistent", enable_consistent, 0, tests},
3775 {"memory_allocators", set_memory_alloc, 0, tests},
3776 {"prefix", set_prefix, 0, tests},
3777 {"version_1_2_3", check_for_1_2_3, 0, version_1_2_3},
3778 {"string", 0, 0, string_tests},
3779 {"result", 0, 0, result_tests},
3780 {"async", pre_nonblock, 0, async_tests},
3781 {"async_binary", pre_nonblock_binary, 0, async_tests},
3782 {"user", 0, 0, user_tests},
3783 {"generate", 0, 0, generate_tests},
3784 {"generate_hsieh", pre_hsieh, 0, generate_tests},
3785 {"generate_ketama", pre_behavior_ketama, 0, generate_tests},
3786 {"generate_hsieh_consistent", enable_consistent, 0, generate_tests},
3787 {"generate_md5", pre_md5, 0, generate_tests},
3788 {"generate_murmur", pre_murmur, 0, generate_tests},
3789 {"generate_jenkins", pre_jenkins, 0, generate_tests},
3790 {"generate_nonblock", pre_nonblock, 0, generate_tests},
3791 {"consistent_not", 0, 0, consistent_tests},
3792 {"consistent_ketama", pre_behavior_ketama, 0, consistent_tests},
3793 {"consistent_ketama_weighted", pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
3794 {0, 0, 0, 0}
3795 };
3796
3797 #define SERVERS_TO_CREATE 5
3798
3799 /* Prototypes for functions we will pass to test framework */
3800 void *world_create(void);
3801 void world_destroy(void *p);
3802
3803 void *world_create(void)
3804 {
3805 server_startup_st *construct;
3806
3807 construct= (server_startup_st *)malloc(sizeof(server_startup_st));
3808 memset(construct, 0, sizeof(server_startup_st));
3809 construct->count= SERVERS_TO_CREATE;
3810 construct->udp= 0;
3811 server_startup(construct);
3812
3813 return construct;
3814 }
3815
3816
3817 void world_destroy(void *p)
3818 {
3819 server_startup_st *construct= (server_startup_st *)p;
3820 memcached_server_st *servers= (memcached_server_st *)construct->servers;
3821 memcached_server_list_free(servers);
3822
3823 server_shutdown(construct);
3824 free(construct);
3825 }
3826
3827 void get_world(world_st *world)
3828 {
3829 world->collections= collection;
3830 world->create= world_create;
3831 world->destroy= world_destroy;
3832 }