Fixed actual loop in add_wrapper ;-)
[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 /* Do not copy the style of this code, I just access hosts to testthis function */
965 static test_return stats_servername_test(memcached_st *memc)
966 {
967 memcached_return rc;
968 memcached_stat_st stat;
969 rc= memcached_stat_servername(&stat, NULL,
970 memc->hosts[0].hostname,
971 memc->hosts[0].port);
972
973 return 0;
974 }
975
976 static test_return increment_test(memcached_st *memc)
977 {
978 uint64_t new_number;
979 memcached_return rc;
980 char *key= "number";
981 char *value= "0";
982
983 rc= memcached_set(memc, key, strlen(key),
984 value, strlen(value),
985 (time_t)0, (uint32_t)0);
986 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
987
988 rc= memcached_increment(memc, key, strlen(key),
989 1, &new_number);
990 assert(rc == MEMCACHED_SUCCESS);
991 assert(new_number == 1);
992
993 rc= memcached_increment(memc, key, strlen(key),
994 1, &new_number);
995 assert(rc == MEMCACHED_SUCCESS);
996 assert(new_number == 2);
997
998 return 0;
999 }
1000
1001 static test_return decrement_test(memcached_st *memc)
1002 {
1003 uint64_t new_number;
1004 memcached_return rc;
1005 char *key= "number";
1006 char *value= "3";
1007
1008 rc= memcached_set(memc, key, strlen(key),
1009 value, strlen(value),
1010 (time_t)0, (uint32_t)0);
1011 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1012
1013 rc= memcached_decrement(memc, key, strlen(key),
1014 1, &new_number);
1015 assert(rc == MEMCACHED_SUCCESS);
1016 assert(new_number == 2);
1017
1018 rc= memcached_decrement(memc, key, strlen(key),
1019 1, &new_number);
1020 assert(rc == MEMCACHED_SUCCESS);
1021 assert(new_number == 1);
1022
1023 return 0;
1024 }
1025
1026 static test_return quit_test(memcached_st *memc)
1027 {
1028 memcached_return rc;
1029 char *key= "fudge";
1030 char *value= "sanford and sun";
1031
1032 rc= memcached_set(memc, key, strlen(key),
1033 value, strlen(value),
1034 (time_t)10, (uint32_t)3);
1035 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1036 memcached_quit(memc);
1037
1038 rc= memcached_set(memc, key, strlen(key),
1039 value, strlen(value),
1040 (time_t)50, (uint32_t)9);
1041 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1042
1043 return 0;
1044 }
1045
1046 static test_return mget_result_test(memcached_st *memc)
1047 {
1048 memcached_return rc;
1049 char *keys[]= {"fudge", "son", "food"};
1050 size_t key_length[]= {5, 3, 4};
1051 unsigned int x;
1052
1053 memcached_result_st results_obj;
1054 memcached_result_st *results;
1055
1056 results= memcached_result_create(memc, &results_obj);
1057 assert(results);
1058 assert(&results_obj == results);
1059
1060 /* We need to empty the server before continueing test */
1061 rc= memcached_flush(memc, 0);
1062 assert(rc == MEMCACHED_SUCCESS);
1063
1064 rc= memcached_mget(memc, keys, key_length, 3);
1065 assert(rc == MEMCACHED_SUCCESS);
1066
1067 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1068 {
1069 assert(results);
1070 }
1071
1072 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1073 assert(!results);
1074 assert(rc == MEMCACHED_END);
1075
1076 for (x= 0; x < 3; x++)
1077 {
1078 rc= memcached_set(memc, keys[x], key_length[x],
1079 keys[x], key_length[x],
1080 (time_t)50, (uint32_t)9);
1081 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1082 }
1083
1084 rc= memcached_mget(memc, keys, key_length, 3);
1085 assert(rc == MEMCACHED_SUCCESS);
1086
1087 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1088 {
1089 assert(results);
1090 assert(&results_obj == results);
1091 assert(rc == MEMCACHED_SUCCESS);
1092 assert(memcached_result_key_length(results) == memcached_result_length(results));
1093 assert(!memcmp(memcached_result_key_value(results),
1094 memcached_result_value(results),
1095 memcached_result_length(results)));
1096 }
1097
1098 memcached_result_free(&results_obj);
1099
1100 return 0;
1101 }
1102
1103 static test_return mget_result_alloc_test(memcached_st *memc)
1104 {
1105 memcached_return rc;
1106 char *keys[]= {"fudge", "son", "food"};
1107 size_t key_length[]= {5, 3, 4};
1108 unsigned int x;
1109
1110 memcached_result_st *results;
1111
1112 /* We need to empty the server before continueing test */
1113 rc= memcached_flush(memc, 0);
1114 assert(rc == MEMCACHED_SUCCESS);
1115
1116 rc= memcached_mget(memc, keys, key_length, 3);
1117 assert(rc == MEMCACHED_SUCCESS);
1118
1119 while ((results= memcached_fetch_result(memc, NULL, &rc)) != NULL)
1120 {
1121 assert(results);
1122 }
1123 assert(!results);
1124 assert(rc == MEMCACHED_END);
1125
1126 for (x= 0; x < 3; x++)
1127 {
1128 rc= memcached_set(memc, keys[x], key_length[x],
1129 keys[x], key_length[x],
1130 (time_t)50, (uint32_t)9);
1131 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1132 }
1133
1134 rc= memcached_mget(memc, keys, key_length, 3);
1135 assert(rc == MEMCACHED_SUCCESS);
1136
1137 x= 0;
1138 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1139 {
1140 assert(results);
1141 assert(rc == MEMCACHED_SUCCESS);
1142 assert(memcached_result_key_length(results) == memcached_result_length(results));
1143 assert(!memcmp(memcached_result_key_value(results),
1144 memcached_result_value(results),
1145 memcached_result_length(results)));
1146 memcached_result_free(results);
1147 x++;
1148 }
1149
1150 return 0;
1151 }
1152
1153 /* Count the results */
1154 static memcached_return callback_counter(memcached_st *ptr __attribute__((unused)),
1155 memcached_result_st *result __attribute__((unused)),
1156 void *context)
1157 {
1158 unsigned int *counter= (unsigned int *)context;
1159
1160 *counter= *counter + 1;
1161
1162 return MEMCACHED_SUCCESS;
1163 }
1164
1165 static test_return mget_result_function(memcached_st *memc)
1166 {
1167 memcached_return rc;
1168 char *keys[]= {"fudge", "son", "food"};
1169 size_t key_length[]= {5, 3, 4};
1170 unsigned int x;
1171 unsigned int counter;
1172 memcached_execute_function callbacks[1];
1173
1174 /* We need to empty the server before continueing test */
1175 rc= memcached_flush(memc, 0);
1176 for (x= 0; x < 3; x++)
1177 {
1178 rc= memcached_set(memc, keys[x], key_length[x],
1179 keys[x], key_length[x],
1180 (time_t)50, (uint32_t)9);
1181 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1182 }
1183
1184 rc= memcached_mget(memc, keys, key_length, 3);
1185 assert(rc == MEMCACHED_SUCCESS);
1186
1187 callbacks[0]= &callback_counter;
1188 counter= 0;
1189 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
1190
1191 assert(counter == 3);
1192
1193 return 0;
1194 }
1195
1196 static test_return mget_test(memcached_st *memc)
1197 {
1198 memcached_return rc;
1199 char *keys[]= {"fudge", "son", "food"};
1200 size_t key_length[]= {5, 3, 4};
1201 unsigned int x;
1202 uint32_t flags;
1203
1204 char return_key[MEMCACHED_MAX_KEY];
1205 size_t return_key_length;
1206 char *return_value;
1207 size_t return_value_length;
1208
1209 /* We need to empty the server before continueing test */
1210 rc= memcached_flush(memc, 0);
1211 assert(rc == MEMCACHED_SUCCESS);
1212
1213 rc= memcached_mget(memc, keys, key_length, 3);
1214 assert(rc == MEMCACHED_SUCCESS);
1215
1216 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1217 &return_value_length, &flags, &rc)) != NULL)
1218 {
1219 assert(return_value);
1220 }
1221 assert(!return_value);
1222 assert(return_value_length == 0);
1223 assert(rc == MEMCACHED_END);
1224
1225 for (x= 0; x < 3; x++)
1226 {
1227 rc= memcached_set(memc, keys[x], key_length[x],
1228 keys[x], key_length[x],
1229 (time_t)50, (uint32_t)9);
1230 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1231 }
1232
1233 rc= memcached_mget(memc, keys, key_length, 3);
1234 assert(rc == MEMCACHED_SUCCESS);
1235
1236 x= 0;
1237 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1238 &return_value_length, &flags, &rc)))
1239 {
1240 assert(return_value);
1241 assert(rc == MEMCACHED_SUCCESS);
1242 assert(return_key_length == return_value_length);
1243 assert(!memcmp(return_value, return_key, return_value_length));
1244 free(return_value);
1245 x++;
1246 }
1247
1248 return 0;
1249 }
1250
1251 static test_return get_stats_keys(memcached_st *memc)
1252 {
1253 char **list;
1254 char **ptr;
1255 memcached_stat_st stat;
1256 memcached_return rc;
1257
1258 list= memcached_stat_get_keys(memc, &stat, &rc);
1259 assert(rc == MEMCACHED_SUCCESS);
1260 for (ptr= list; *ptr; ptr++)
1261 assert(*ptr);
1262 fflush(stdout);
1263
1264 free(list);
1265
1266 return 0;
1267 }
1268
1269 static test_return version_string_test(memcached_st *memc __attribute__((unused)))
1270 {
1271 const char *version_string;
1272
1273 version_string= memcached_lib_version();
1274
1275 assert(!strcmp(version_string, LIBMEMCACHED_VERSION_STRING));
1276
1277 return 0;
1278 }
1279
1280 static test_return get_stats(memcached_st *memc)
1281 {
1282 unsigned int x;
1283 char **list;
1284 char **ptr;
1285 memcached_return rc;
1286 memcached_stat_st *stat;
1287
1288 stat= memcached_stat(memc, NULL, &rc);
1289 assert(rc == MEMCACHED_SUCCESS);
1290
1291 assert(rc == MEMCACHED_SUCCESS);
1292 assert(stat);
1293
1294 for (x= 0; x < memcached_server_count(memc); x++)
1295 {
1296 list= memcached_stat_get_keys(memc, stat+x, &rc);
1297 assert(rc == MEMCACHED_SUCCESS);
1298 for (ptr= list; *ptr; ptr++);
1299
1300 free(list);
1301 }
1302
1303 memcached_stat_free(NULL, stat);
1304
1305 return 0;
1306 }
1307
1308 static test_return add_host_test(memcached_st *memc)
1309 {
1310 unsigned int x;
1311 memcached_server_st *servers;
1312 memcached_return rc;
1313 char servername[]= "0.example.com";
1314
1315 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1316 assert(servers);
1317 assert(1 == memcached_server_list_count(servers));
1318
1319 for (x= 2; x < 20; x++)
1320 {
1321 char buffer[SMALL_STRING_LEN];
1322
1323 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1324 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1325 &rc);
1326 assert(rc == MEMCACHED_SUCCESS);
1327 assert(x == memcached_server_list_count(servers));
1328 }
1329
1330 rc= memcached_server_push(memc, servers);
1331 assert(rc == MEMCACHED_SUCCESS);
1332 rc= memcached_server_push(memc, servers);
1333 assert(rc == MEMCACHED_SUCCESS);
1334
1335 memcached_server_list_free(servers);
1336
1337 return 0;
1338 }
1339
1340 static memcached_return clone_test_callback(memcached_st *parent __attribute__((unused)), memcached_st *clone __attribute__((unused)))
1341 {
1342 return MEMCACHED_SUCCESS;
1343 }
1344
1345 static memcached_return cleanup_test_callback(memcached_st *ptr __attribute__((unused)))
1346 {
1347 return MEMCACHED_SUCCESS;
1348 }
1349
1350 static test_return callback_test(memcached_st *memc)
1351 {
1352 /* Test User Data */
1353 {
1354 int x= 5;
1355 int *test_ptr;
1356 memcached_return rc;
1357
1358 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x);
1359 assert(rc == MEMCACHED_SUCCESS);
1360 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1361 assert(*test_ptr == x);
1362 }
1363
1364 /* Test Clone Callback */
1365 {
1366 memcached_clone_func temp_function;
1367 memcached_return rc;
1368
1369 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, (void*)clone_test_callback);
1370 assert(rc == MEMCACHED_SUCCESS);
1371 temp_function= (memcached_clone_func)memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1372 assert(temp_function == clone_test_callback);
1373 }
1374
1375 /* Test Cleanup Callback */
1376 {
1377 memcached_cleanup_func temp_function;
1378 memcached_return rc;
1379
1380 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, (void*)cleanup_test_callback);
1381 assert(rc == MEMCACHED_SUCCESS);
1382 temp_function= (memcached_cleanup_func)memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1383 assert(temp_function == cleanup_test_callback);
1384 }
1385
1386 return 0;
1387 }
1388
1389 /* We don't test the behavior itself, we test the switches */
1390 static test_return behavior_test(memcached_st *memc)
1391 {
1392 uint64_t value;
1393 uint32_t set= 1;
1394
1395 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1396 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1397 assert(value == 1);
1398
1399 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1400 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1401 assert(value == 1);
1402
1403 set= MEMCACHED_HASH_MD5;
1404 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1405 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1406 assert(value == MEMCACHED_HASH_MD5);
1407
1408 set= 0;
1409
1410 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1411 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
1412 assert(value == 0);
1413
1414 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1415 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
1416 assert(value == 0);
1417
1418 set= MEMCACHED_HASH_DEFAULT;
1419 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1420 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1421 assert(value == MEMCACHED_HASH_DEFAULT);
1422
1423 set= MEMCACHED_HASH_CRC;
1424 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
1425 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
1426 assert(value == MEMCACHED_HASH_CRC);
1427
1428 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1429 assert(value > 0);
1430
1431 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1432 assert(value > 0);
1433
1434 return 0;
1435 }
1436
1437 /* Test case provided by Cal Haldenbrand */
1438 static test_return user_supplied_bug1(memcached_st *memc)
1439 {
1440 unsigned int setter= 1;
1441 unsigned int x;
1442
1443 unsigned long long total= 0;
1444 uint32_t size= 0;
1445 char key[10];
1446 char randomstuff[6 * 1024];
1447 memcached_return rc;
1448
1449 memset(randomstuff, 0, 6 * 1024);
1450
1451 /* We just keep looking at the same values over and over */
1452 srandom(10);
1453
1454 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1455 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1456
1457
1458 /* add key */
1459 for (x= 0 ; total < 20 * 1024576 ; x++ )
1460 {
1461 unsigned int j= 0;
1462
1463 size= (rand() % ( 5 * 1024 ) ) + 400;
1464 memset(randomstuff, 0, 6 * 1024);
1465 assert(size < 6 * 1024); /* Being safe here */
1466
1467 for (j= 0 ; j < size ;j++)
1468 randomstuff[j] = (char) (rand() % 26) + 97;
1469
1470 total += size;
1471 sprintf(key, "%d", x);
1472 rc = memcached_set(memc, key, strlen(key),
1473 randomstuff, strlen(randomstuff), 10, 0);
1474 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1475 /* If we fail, lets try again */
1476 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
1477 rc = memcached_set(memc, key, strlen(key),
1478 randomstuff, strlen(randomstuff), 10, 0);
1479 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1480 }
1481
1482 return 0;
1483 }
1484
1485 /* Test case provided by Cal Haldenbrand */
1486 static test_return user_supplied_bug2(memcached_st *memc)
1487 {
1488 int errors;
1489 unsigned int setter;
1490 unsigned int x;
1491 unsigned long long total;
1492
1493 setter= 1;
1494 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1495 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1496 #ifdef NOT_YET
1497 setter = 20 * 1024576;
1498 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1499 setter = 20 * 1024576;
1500 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1501 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1502 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1503
1504 for (x= 0, errors= 0, total= 0 ; total < 20 * 1024576 ; x++)
1505 #endif
1506
1507 for (x= 0, errors= 0, total= 0 ; total < 24576 ; x++)
1508 {
1509 memcached_return rc= MEMCACHED_SUCCESS;
1510 char buffer[SMALL_STRING_LEN];
1511 uint32_t flags= 0;
1512 size_t val_len= 0;
1513 char *getval;
1514
1515 memset(buffer, 0, SMALL_STRING_LEN);
1516
1517 snprintf(buffer, SMALL_STRING_LEN, "%u", x);
1518 getval= memcached_get(memc, buffer, strlen(buffer),
1519 &val_len, &flags, &rc);
1520 if (rc != MEMCACHED_SUCCESS)
1521 {
1522 if (rc == MEMCACHED_NOTFOUND)
1523 errors++;
1524 else
1525 {
1526 WATCHPOINT_ERROR(rc);
1527 assert(0);
1528 }
1529
1530 continue;
1531 }
1532 total+= val_len;
1533 errors= 0;
1534 free(getval);
1535 }
1536
1537 return 0;
1538 }
1539
1540 /* Do a large mget() over all the keys we think exist */
1541 #define KEY_COUNT 3000 // * 1024576
1542 static test_return user_supplied_bug3(memcached_st *memc)
1543 {
1544 memcached_return rc;
1545 unsigned int setter;
1546 unsigned int x;
1547 char **keys;
1548 size_t key_lengths[KEY_COUNT];
1549
1550 setter= 1;
1551 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1552 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1553 #ifdef NOT_YET
1554 setter = 20 * 1024576;
1555 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1556 setter = 20 * 1024576;
1557 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1558 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1559 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1560 #endif
1561
1562 keys= (char **)malloc(sizeof(char *) * KEY_COUNT);
1563 assert(keys);
1564 memset(keys, 0, (sizeof(char *) * KEY_COUNT));
1565 for (x= 0; x < KEY_COUNT; x++)
1566 {
1567 char buffer[30];
1568
1569 snprintf(buffer, 30, "%u", x);
1570 keys[x]= strdup(buffer);
1571 key_lengths[x]= strlen(keys[x]);
1572 }
1573
1574 rc= memcached_mget(memc, keys, key_lengths, KEY_COUNT);
1575 assert(rc == MEMCACHED_SUCCESS);
1576
1577 /* Turn this into a help function */
1578 {
1579 char return_key[MEMCACHED_MAX_KEY];
1580 size_t return_key_length;
1581 char *return_value;
1582 size_t return_value_length;
1583 uint32_t flags;
1584
1585 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1586 &return_value_length, &flags, &rc)))
1587 {
1588 assert(return_value);
1589 assert(rc == MEMCACHED_SUCCESS);
1590 free(return_value);
1591 }
1592 }
1593
1594 for (x= 0; x < KEY_COUNT; x++)
1595 free(keys[x]);
1596 free(keys);
1597
1598 return 0;
1599 }
1600
1601 /* Make sure we behave properly if server list has no values */
1602 static test_return user_supplied_bug4(memcached_st *memc)
1603 {
1604 memcached_return rc;
1605 char *keys[]= {"fudge", "son", "food"};
1606 size_t key_length[]= {5, 3, 4};
1607 unsigned int x;
1608 uint32_t flags;
1609 char return_key[MEMCACHED_MAX_KEY];
1610 size_t return_key_length;
1611 char *return_value;
1612 size_t return_value_length;
1613
1614 /* Here we free everything before running a bunch of mget tests */
1615 {
1616 memcached_server_list_free(memc->hosts);
1617 memc->hosts= NULL;
1618 memc->number_of_hosts= 0;
1619 }
1620
1621
1622 /* We need to empty the server before continueing test */
1623 rc= memcached_flush(memc, 0);
1624 assert(rc == MEMCACHED_NO_SERVERS);
1625
1626 rc= memcached_mget(memc, keys, key_length, 3);
1627 assert(rc == MEMCACHED_NO_SERVERS);
1628
1629 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1630 &return_value_length, &flags, &rc)) != NULL)
1631 {
1632 assert(return_value);
1633 }
1634 assert(!return_value);
1635 assert(return_value_length == 0);
1636 assert(rc == MEMCACHED_NO_SERVERS);
1637
1638 for (x= 0; x < 3; x++)
1639 {
1640 rc= memcached_set(memc, keys[x], key_length[x],
1641 keys[x], key_length[x],
1642 (time_t)50, (uint32_t)9);
1643 assert(rc == MEMCACHED_NO_SERVERS);
1644 }
1645
1646 rc= memcached_mget(memc, keys, key_length, 3);
1647 assert(rc == MEMCACHED_NO_SERVERS);
1648
1649 x= 0;
1650 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1651 &return_value_length, &flags, &rc)))
1652 {
1653 assert(return_value);
1654 assert(rc == MEMCACHED_SUCCESS);
1655 assert(return_key_length == return_value_length);
1656 assert(!memcmp(return_value, return_key, return_value_length));
1657 free(return_value);
1658 x++;
1659 }
1660
1661 return 0;
1662 }
1663
1664 #define VALUE_SIZE_BUG5 1048064
1665 static test_return user_supplied_bug5(memcached_st *memc)
1666 {
1667 memcached_return rc;
1668 char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
1669 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
1670 char return_key[MEMCACHED_MAX_KEY];
1671 size_t return_key_length;
1672 char *value;
1673 size_t value_length;
1674 uint32_t flags;
1675 unsigned int count;
1676 unsigned int x;
1677 char insert_data[VALUE_SIZE_BUG5];
1678
1679 for (x= 0; x < VALUE_SIZE_BUG5; x++)
1680 insert_data[x]= rand();
1681
1682 memcached_flush(memc, 0);
1683 value= memcached_get(memc, keys[0], key_length[0],
1684 &value_length, &flags, &rc);
1685 assert(value == NULL);
1686 rc= memcached_mget(memc, keys, key_length, 4);
1687
1688 count= 0;
1689 while ((value= memcached_fetch(memc, return_key, &return_key_length,
1690 &value_length, &flags, &rc)))
1691 count++;
1692 assert(count == 0);
1693
1694 for (x= 0; x < 4; x++)
1695 {
1696 rc= memcached_set(memc, keys[x], key_length[x],
1697 insert_data, VALUE_SIZE_BUG5,
1698 (time_t)0, (uint32_t)0);
1699 assert(rc == MEMCACHED_SUCCESS);
1700 }
1701
1702 for (x= 0; x < 10; x++)
1703 {
1704 value= memcached_get(memc, keys[0], key_length[0],
1705 &value_length, &flags, &rc);
1706 assert(value);
1707 free(value);
1708
1709 rc= memcached_mget(memc, keys, key_length, 4);
1710 count= 0;
1711 while ((value= memcached_fetch(memc, return_key, &return_key_length,
1712 &value_length, &flags, &rc)))
1713 {
1714 count++;
1715 free(value);
1716 }
1717 assert(count == 4);
1718 }
1719
1720 return 0;
1721 }
1722
1723 static test_return user_supplied_bug6(memcached_st *memc)
1724 {
1725 memcached_return rc;
1726 char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
1727 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
1728 char return_key[MEMCACHED_MAX_KEY];
1729 size_t return_key_length;
1730 char *value;
1731 size_t value_length;
1732 uint32_t flags;
1733 unsigned int count;
1734 unsigned int x;
1735 char insert_data[VALUE_SIZE_BUG5];
1736
1737 for (x= 0; x < VALUE_SIZE_BUG5; x++)
1738 insert_data[x]= rand();
1739
1740 memcached_flush(memc, 0);
1741 value= memcached_get(memc, keys[0], key_length[0],
1742 &value_length, &flags, &rc);
1743 assert(value == NULL);
1744 assert(rc == MEMCACHED_NOTFOUND);
1745 rc= memcached_mget(memc, keys, key_length, 4);
1746 assert(rc == MEMCACHED_SUCCESS);
1747
1748 count= 0;
1749 while ((value= memcached_fetch(memc, return_key, &return_key_length,
1750 &value_length, &flags, &rc)))
1751 count++;
1752 assert(count == 0);
1753 assert(rc == MEMCACHED_END);
1754
1755 for (x= 0; x < 4; x++)
1756 {
1757 rc= memcached_set(memc, keys[x], key_length[x],
1758 insert_data, VALUE_SIZE_BUG5,
1759 (time_t)0, (uint32_t)0);
1760 assert(rc == MEMCACHED_SUCCESS);
1761 }
1762
1763 for (x= 0; x < 2; x++)
1764 {
1765 value= memcached_get(memc, keys[0], key_length[0],
1766 &value_length, &flags, &rc);
1767 assert(value);
1768 free(value);
1769
1770 rc= memcached_mget(memc, keys, key_length, 4);
1771 assert(rc == MEMCACHED_SUCCESS);
1772 count= 3;
1773 /* We test for purge of partial complete fetches */
1774 for (count= 3; count; count--)
1775 {
1776 value= memcached_fetch(memc, return_key, &return_key_length,
1777 &value_length, &flags, &rc);
1778 assert(rc == MEMCACHED_SUCCESS);
1779 assert(!(memcmp(value, insert_data, value_length)));
1780 assert(value_length);
1781 free(value);
1782 }
1783 }
1784
1785 return 0;
1786 }
1787
1788 static test_return user_supplied_bug8(memcached_st *memc __attribute__((unused)))
1789 {
1790 memcached_return rc;
1791 memcached_st *mine;
1792 memcached_st *clone;
1793
1794 memcached_server_st *servers;
1795 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";
1796
1797 servers= memcached_servers_parse(server_list);
1798 assert(servers);
1799
1800 mine= memcached_create(NULL);
1801 rc= memcached_server_push(mine, servers);
1802 assert(rc == MEMCACHED_SUCCESS);
1803 memcached_server_list_free(servers);
1804
1805 assert(mine);
1806 clone= memcached_clone(NULL, mine);
1807
1808 memcached_quit(mine);
1809 memcached_quit(clone);
1810
1811
1812 memcached_free(mine);
1813 memcached_free(clone);
1814
1815 return 0;
1816 }
1817
1818 /* Test flag store/retrieve */
1819 static test_return user_supplied_bug7(memcached_st *memc)
1820 {
1821 memcached_return rc;
1822 char *keys= "036790384900";
1823 size_t key_length= strlen("036790384900");
1824 char return_key[MEMCACHED_MAX_KEY];
1825 size_t return_key_length;
1826 char *value;
1827 size_t value_length;
1828 uint32_t flags;
1829 unsigned int x;
1830 char insert_data[VALUE_SIZE_BUG5];
1831
1832 for (x= 0; x < VALUE_SIZE_BUG5; x++)
1833 insert_data[x]= rand();
1834
1835 memcached_flush(memc, 0);
1836
1837 flags= 245;
1838 rc= memcached_set(memc, keys, key_length,
1839 insert_data, VALUE_SIZE_BUG5,
1840 (time_t)0, flags);
1841 assert(rc == MEMCACHED_SUCCESS);
1842
1843 flags= 0;
1844 value= memcached_get(memc, keys, key_length,
1845 &value_length, &flags, &rc);
1846 assert(flags == 245);
1847 assert(value);
1848 free(value);
1849
1850 rc= memcached_mget(memc, &keys, &key_length, 1);
1851
1852 flags= 0;
1853 value= memcached_fetch(memc, return_key, &return_key_length,
1854 &value_length, &flags, &rc);
1855 assert(flags == 245);
1856 assert(value);
1857 free(value);
1858
1859
1860 return 0;
1861 }
1862
1863 static test_return user_supplied_bug9(memcached_st *memc)
1864 {
1865 memcached_return rc;
1866 char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
1867 size_t key_length[3];
1868 unsigned int x;
1869 uint32_t flags;
1870 unsigned count= 0;
1871
1872 char return_key[MEMCACHED_MAX_KEY];
1873 size_t return_key_length;
1874 char *return_value;
1875 size_t return_value_length;
1876
1877
1878 key_length[0]= strlen("UDATA:edevil@sapo.pt");
1879 key_length[1]= strlen("fudge&*@#");
1880 key_length[2]= strlen("for^#@&$not");
1881
1882
1883 for (x= 0; x < 3; x++)
1884 {
1885 rc= memcached_set(memc, keys[x], key_length[x],
1886 keys[x], key_length[x],
1887 (time_t)50, (uint32_t)9);
1888 assert(rc == MEMCACHED_SUCCESS);
1889 }
1890
1891 rc= memcached_mget(memc, keys, key_length, 3);
1892 assert(rc == MEMCACHED_SUCCESS);
1893
1894 /* We need to empty the server before continueing test */
1895 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1896 &return_value_length, &flags, &rc)) != NULL)
1897 {
1898 assert(return_value);
1899 free(return_value);
1900 count++;
1901 }
1902 assert(count == 3);
1903
1904 return 0;
1905 }
1906
1907 /* We are testing with aggressive timeout to get failures */
1908 static test_return user_supplied_bug10(memcached_st *memc)
1909 {
1910 char *key= "foo";
1911 char *value;
1912 size_t value_length= 512;
1913 unsigned int x;
1914 int key_len= 3;
1915 memcached_return rc;
1916 unsigned int set= 1;
1917 memcached_st *mclone= memcached_clone(NULL, memc);
1918 int32_t timeout;
1919
1920 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1921 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1922 timeout= 2;
1923 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
1924
1925 value = (char*)malloc(value_length * sizeof(char));
1926
1927 for (x= 0; x < value_length; x++)
1928 value[x]= (char) (x % 127);
1929
1930 for (x= 1; x <= 100000; ++x)
1931 {
1932 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
1933
1934 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_BUFFERED);
1935
1936 if (rc == MEMCACHED_WRITE_FAILURE)
1937 x--;
1938 }
1939
1940 free(value);
1941 memcached_free(mclone);
1942
1943 return 0;
1944 }
1945
1946 /*
1947 We are looking failures in the async protocol
1948 */
1949 static test_return user_supplied_bug11(memcached_st *memc)
1950 {
1951 char *key= "foo";
1952 char *value;
1953 size_t value_length= 512;
1954 unsigned int x;
1955 int key_len= 3;
1956 memcached_return rc;
1957 unsigned int set= 1;
1958 int32_t timeout;
1959 memcached_st *mclone= memcached_clone(NULL, memc);
1960
1961 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
1962 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
1963 timeout= -1;
1964 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
1965
1966 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
1967
1968 assert(timeout == -1);
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
1980 free(value);
1981 memcached_free(mclone);
1982
1983 return 0;
1984 }
1985
1986 /*
1987 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
1988 */
1989 static test_return user_supplied_bug12(memcached_st *memc)
1990 {
1991 memcached_return rc;
1992 uint32_t flags;
1993 size_t value_length;
1994 char *value;
1995 uint64_t number_value;
1996
1997 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
1998 &value_length, &flags, &rc);
1999 assert(value == NULL);
2000 assert(rc == MEMCACHED_NOTFOUND);
2001
2002 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2003 1, &number_value);
2004
2005 assert(value == NULL);
2006 /* The binary protocol will set the key if it doesn't exist */
2007 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2008 assert(rc == MEMCACHED_SUCCESS);
2009 else
2010 assert(rc == MEMCACHED_NOTFOUND);
2011
2012 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2013
2014 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2015 &value_length, &flags, &rc);
2016 assert(value);
2017 assert(rc == MEMCACHED_SUCCESS);
2018 free(value);
2019
2020 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2021 1, &number_value);
2022 assert(number_value == 2);
2023 assert(rc == MEMCACHED_SUCCESS);
2024
2025 return 0;
2026 }
2027
2028 /*
2029 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2030 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2031 */
2032 static test_return user_supplied_bug13(memcached_st *memc)
2033 {
2034 char key[] = "key34567890";
2035 char *overflow;
2036 memcached_return rc;
2037 size_t overflowSize;
2038
2039 char commandFirst[]= "set key34567890 0 0 ";
2040 char commandLast[] = " \r\n"; /* first line of command sent to server */
2041 size_t commandLength;
2042 size_t testSize;
2043
2044 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2045
2046 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2047
2048 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2049 {
2050 overflow= malloc(testSize);
2051 assert(overflow != NULL);
2052
2053 memset(overflow, 'x', testSize);
2054 rc= memcached_set(memc, key, strlen(key),
2055 overflow, testSize, 0, 0);
2056 assert(rc == MEMCACHED_SUCCESS);
2057 free(overflow);
2058 }
2059
2060 return 0;
2061 }
2062
2063
2064 /*
2065 Test values of many different sizes
2066 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2067 set key34567890 0 0 8169 \r\n
2068 is sent followed by buffer of size 8169, followed by 8169
2069 */
2070 static test_return user_supplied_bug14(memcached_st *memc)
2071 {
2072 int setter= 1;
2073 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2074 memcached_return rc;
2075 char *key= "foo";
2076 char *value;
2077 size_t value_length= 18000;
2078 char *string;
2079 size_t string_length;
2080 uint32_t flags;
2081 unsigned int x;
2082 size_t current_length;
2083
2084 value = (char*)malloc(value_length);
2085 assert(value);
2086
2087 for (x= 0; x < value_length; x++)
2088 value[x] = (char) (x % 127);
2089
2090 for (current_length= 0; current_length < value_length; current_length++)
2091 {
2092 rc= memcached_set(memc, key, strlen(key),
2093 value, current_length,
2094 (time_t)0, (uint32_t)0);
2095 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2096
2097 string= memcached_get(memc, key, strlen(key),
2098 &string_length, &flags, &rc);
2099
2100 assert(rc == MEMCACHED_SUCCESS);
2101 assert(string_length == current_length);
2102 assert(!memcmp(string, value, string_length));
2103
2104 free(string);
2105 }
2106
2107 free(value);
2108
2109 return 0;
2110 }
2111
2112 /*
2113 Look for zero length value problems
2114 */
2115 static test_return user_supplied_bug15(memcached_st *memc)
2116 {
2117 uint32_t x;
2118 memcached_return rc;
2119 char *key= "mykey";
2120 char *value;
2121 size_t length;
2122 uint32_t flags;
2123
2124 for (x= 0; x < 2; x++)
2125 {
2126 rc= memcached_set(memc, key, strlen(key),
2127 NULL, 0,
2128 (time_t)0, (uint32_t)0);
2129
2130 assert(rc == MEMCACHED_SUCCESS);
2131
2132 value= memcached_get(memc, key, strlen(key),
2133 &length, &flags, &rc);
2134
2135 assert(rc == MEMCACHED_SUCCESS);
2136 assert(value == NULL);
2137 assert(length == 0);
2138 assert(flags == 0);
2139
2140 value= memcached_get(memc, key, strlen(key),
2141 &length, &flags, &rc);
2142
2143 assert(rc == MEMCACHED_SUCCESS);
2144 assert(value == NULL);
2145 assert(length == 0);
2146 assert(flags == 0);
2147 }
2148
2149 return 0;
2150 }
2151
2152 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2153 static test_return user_supplied_bug16(memcached_st *memc)
2154 {
2155 memcached_return rc;
2156 char *key= "mykey";
2157 char *value;
2158 size_t length;
2159 uint32_t flags;
2160
2161 rc= memcached_set(memc, key, strlen(key),
2162 NULL, 0,
2163 (time_t)0, UINT32_MAX);
2164
2165 assert(rc == MEMCACHED_SUCCESS);
2166
2167 value= memcached_get(memc, key, strlen(key),
2168 &length, &flags, &rc);
2169
2170 assert(rc == MEMCACHED_SUCCESS);
2171 assert(value == NULL);
2172 assert(length == 0);
2173 assert(flags == UINT32_MAX);
2174
2175 return 0;
2176 }
2177
2178 /* Check the validity of chinese key*/
2179 static test_return user_supplied_bug17(memcached_st *memc)
2180 {
2181 memcached_return rc;
2182 char *key= "豆瓣";
2183 char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2184 char *value2;
2185 size_t length;
2186 uint32_t flags;
2187
2188 rc= memcached_set(memc, key, strlen(key),
2189 value, strlen(value),
2190 (time_t)0, 0);
2191
2192 assert(rc == MEMCACHED_SUCCESS);
2193
2194 value2= memcached_get(memc, key, strlen(key),
2195 &length, &flags, &rc);
2196
2197 assert(length==strlen(value));
2198 assert(rc == MEMCACHED_SUCCESS);
2199 assert(memcmp(value, value2, length)==0);
2200 free(value2);
2201
2202 return 0;
2203 }
2204
2205 /*
2206 From Andrei on IRC
2207 */
2208
2209 test_return user_supplied_bug19(memcached_st *memc)
2210 {
2211 memcached_st *m;
2212 memcached_server_st *s;
2213 memcached_return res;
2214
2215 (void)memc;
2216
2217 m= memcached_create(NULL);
2218 memcached_server_add_with_weight(m, "localhost", 11311, 100);
2219 memcached_server_add_with_weight(m, "localhost", 11312, 100);
2220
2221 s= memcached_server_by_key(m, "a", 1, &res);
2222 memcached_server_free(s);
2223
2224 memcached_free(m);
2225
2226 return 0;
2227 }
2228
2229 /* CAS test from Andei */
2230 test_return user_supplied_bug20(memcached_st *memc)
2231 {
2232 memcached_return status;
2233 memcached_result_st *result, result_obj;
2234 char *key = "abc";
2235 size_t key_len = strlen("abc");
2236 char *value = "foobar";
2237 size_t value_len = strlen(value);
2238
2239 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2240
2241 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2242 assert(status == MEMCACHED_SUCCESS);
2243
2244 status = memcached_mget(memc, &key, &key_len, 1);
2245 assert(status == MEMCACHED_SUCCESS);
2246
2247 result= memcached_result_create(memc, &result_obj);
2248 assert(result);
2249
2250 memcached_result_create(memc, &result_obj);
2251 result= memcached_fetch_result(memc, &result_obj, &status);
2252
2253 assert(result);
2254 assert(status == MEMCACHED_SUCCESS);
2255
2256 memcached_result_free(result);
2257
2258 return 0;
2259 }
2260
2261 #include "ketama_test_cases.h"
2262 test_return user_supplied_bug18(memcached_st *trash)
2263 {
2264 memcached_return rc;
2265 int value;
2266 int x;
2267 memcached_server_st *server_pool;
2268 memcached_st *memc;
2269
2270 (void)trash;
2271
2272 memc= memcached_create(NULL);
2273 assert(memc);
2274
2275 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2276 assert(rc == MEMCACHED_SUCCESS);
2277
2278 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2279 assert(value == 1);
2280
2281 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2282 assert(rc == MEMCACHED_SUCCESS);
2283
2284 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2285 assert(value == MEMCACHED_HASH_MD5);
2286
2287 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");
2288 memcached_server_push(memc, server_pool);
2289
2290 /* verify that the server list was parsed okay. */
2291 assert(memc->number_of_hosts == 8);
2292 assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2293 assert(server_pool[0].port == 11211);
2294 assert(server_pool[0].weight == 600);
2295 assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2296 assert(server_pool[2].port == 11211);
2297 assert(server_pool[2].weight == 200);
2298 assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2299 assert(server_pool[7].port == 11211);
2300 assert(server_pool[7].weight == 100);
2301
2302 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2303 * us test the boundary wraparound.
2304 */
2305 assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
2306
2307 /* verify the standard ketama set. */
2308 for (x= 0; x < 99; x++)
2309 {
2310 uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
2311 char *hostname = memc->hosts[server_idx].hostname;
2312 assert(strcmp(hostname, test_cases[x].server) == 0);
2313 }
2314
2315 memcached_server_list_free(server_pool);
2316 memcached_free(memc);
2317
2318 return 0;
2319 }
2320
2321 static test_return result_static(memcached_st *memc)
2322 {
2323 memcached_result_st result;
2324 memcached_result_st *result_ptr;
2325
2326 result_ptr= memcached_result_create(memc, &result);
2327 assert(result.is_allocated == false);
2328 assert(result_ptr);
2329 memcached_result_free(&result);
2330
2331 return 0;
2332 }
2333
2334 static test_return result_alloc(memcached_st *memc)
2335 {
2336 memcached_result_st *result;
2337
2338 result= memcached_result_create(memc, NULL);
2339 assert(result);
2340 memcached_result_free(result);
2341
2342 return 0;
2343 }
2344
2345 static test_return string_static_null(memcached_st *memc)
2346 {
2347 memcached_string_st string;
2348 memcached_string_st *string_ptr;
2349
2350 string_ptr= memcached_string_create(memc, &string, 0);
2351 assert(string.is_allocated == false);
2352 assert(string_ptr);
2353 memcached_string_free(&string);
2354
2355 return 0;
2356 }
2357
2358 static test_return string_alloc_null(memcached_st *memc)
2359 {
2360 memcached_string_st *string;
2361
2362 string= memcached_string_create(memc, NULL, 0);
2363 assert(string);
2364 memcached_string_free(string);
2365
2366 return 0;
2367 }
2368
2369 static test_return string_alloc_with_size(memcached_st *memc)
2370 {
2371 memcached_string_st *string;
2372
2373 string= memcached_string_create(memc, NULL, 1024);
2374 assert(string);
2375 memcached_string_free(string);
2376
2377 return 0;
2378 }
2379
2380 static test_return string_alloc_with_size_toobig(memcached_st *memc)
2381 {
2382 memcached_string_st *string;
2383
2384 string= memcached_string_create(memc, NULL, INT64_MAX);
2385 assert(string == NULL);
2386
2387 return 0;
2388 }
2389
2390 static test_return string_alloc_append(memcached_st *memc)
2391 {
2392 unsigned int x;
2393 char buffer[SMALL_STRING_LEN];
2394 memcached_string_st *string;
2395
2396 /* Ring the bell! */
2397 memset(buffer, 6, SMALL_STRING_LEN);
2398
2399 string= memcached_string_create(memc, NULL, 100);
2400 assert(string);
2401
2402 for (x= 0; x < 1024; x++)
2403 {
2404 memcached_return rc;
2405 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
2406 assert(rc == MEMCACHED_SUCCESS);
2407 }
2408 memcached_string_free(string);
2409
2410 return 0;
2411 }
2412
2413 static test_return string_alloc_append_toobig(memcached_st *memc)
2414 {
2415 memcached_return rc;
2416 unsigned int x;
2417 char buffer[SMALL_STRING_LEN];
2418 memcached_string_st *string;
2419
2420 /* Ring the bell! */
2421 memset(buffer, 6, SMALL_STRING_LEN);
2422
2423 string= memcached_string_create(memc, NULL, 100);
2424 assert(string);
2425
2426 for (x= 0; x < 1024; x++)
2427 {
2428 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
2429 assert(rc == MEMCACHED_SUCCESS);
2430 }
2431 rc= memcached_string_append(string, buffer, INT64_MAX);
2432 assert(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
2433 memcached_string_free(string);
2434
2435 return 0;
2436 }
2437
2438 static test_return cleanup_pairs(memcached_st *memc __attribute__((unused)))
2439 {
2440 pairs_free(global_pairs);
2441
2442 return 0;
2443 }
2444
2445 static test_return generate_pairs(memcached_st *memc __attribute__((unused)))
2446 {
2447 unsigned long long x;
2448 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
2449 global_count= GLOBAL_COUNT;
2450
2451 for (x= 0; x < global_count; x++)
2452 {
2453 global_keys[x]= global_pairs[x].key;
2454 global_keys_length[x]= global_pairs[x].key_length;
2455 }
2456
2457 return 0;
2458 }
2459
2460 static test_return generate_large_pairs(memcached_st *memc __attribute__((unused)))
2461 {
2462 unsigned long long x;
2463 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
2464 global_count= GLOBAL2_COUNT;
2465
2466 for (x= 0; x < global_count; x++)
2467 {
2468 global_keys[x]= global_pairs[x].key;
2469 global_keys_length[x]= global_pairs[x].key_length;
2470 }
2471
2472 return 0;
2473 }
2474
2475 static test_return generate_data(memcached_st *memc)
2476 {
2477 execute_set(memc, global_pairs, global_count);
2478
2479 return 0;
2480 }
2481
2482 static test_return generate_data_with_stats(memcached_st *memc)
2483 {
2484 memcached_stat_st *stat_p;
2485 memcached_return rc;
2486 uint32_t host_index= 0;
2487 execute_set(memc, global_pairs, global_count);
2488
2489 //TODO: hosts used size stats
2490 stat_p= memcached_stat(memc, NULL, &rc);
2491 assert(stat_p);
2492
2493 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
2494 {
2495 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);
2496 }
2497
2498 memcached_stat_free(NULL, stat_p);
2499
2500 return 0;
2501 }
2502 static test_return generate_buffer_data(memcached_st *memc)
2503 {
2504 int latch= 0;
2505
2506 latch= 1;
2507 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
2508 generate_data(memc);
2509
2510 return 0;
2511 }
2512
2513 static test_return get_read_count(memcached_st *memc)
2514 {
2515 unsigned int x;
2516 memcached_return rc;
2517 memcached_st *clone;
2518
2519 clone= memcached_clone(NULL, memc);
2520 assert(clone);
2521
2522 memcached_server_add_with_weight(clone, "localhost", 6666, 0);
2523
2524 {
2525 char *return_value;
2526 size_t return_value_length;
2527 uint32_t flags;
2528 uint32_t count;
2529
2530 for (x= count= 0; x < global_count; x++)
2531 {
2532 return_value= memcached_get(clone, global_keys[x], global_keys_length[x],
2533 &return_value_length, &flags, &rc);
2534 if (rc == MEMCACHED_SUCCESS)
2535 {
2536 count++;
2537 if (return_value)
2538 free(return_value);
2539 }
2540 }
2541 fprintf(stderr, "\t%u -> %u", global_count, count);
2542 }
2543
2544 memcached_free(clone);
2545
2546 return 0;
2547 }
2548
2549 static test_return get_read(memcached_st *memc)
2550 {
2551 unsigned int x;
2552 memcached_return rc;
2553
2554 {
2555 char *return_value;
2556 size_t return_value_length;
2557 uint32_t flags;
2558
2559 for (x= 0; x < global_count; x++)
2560 {
2561 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
2562 &return_value_length, &flags, &rc);
2563 /*
2564 assert(return_value);
2565 assert(rc == MEMCACHED_SUCCESS);
2566 */
2567 if (rc == MEMCACHED_SUCCESS && return_value)
2568 free(return_value);
2569 }
2570 }
2571
2572 return 0;
2573 }
2574
2575 static test_return mget_read(memcached_st *memc)
2576 {
2577 memcached_return rc;
2578
2579 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
2580 assert(rc == MEMCACHED_SUCCESS);
2581 /* Turn this into a help function */
2582 {
2583 char return_key[MEMCACHED_MAX_KEY];
2584 size_t return_key_length;
2585 char *return_value;
2586 size_t return_value_length;
2587 uint32_t flags;
2588
2589 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2590 &return_value_length, &flags, &rc)))
2591 {
2592 assert(return_value);
2593 assert(rc == MEMCACHED_SUCCESS);
2594 free(return_value);
2595 }
2596 }
2597
2598 return 0;
2599 }
2600
2601 static test_return mget_read_result(memcached_st *memc)
2602 {
2603 memcached_return rc;
2604
2605 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
2606 assert(rc == MEMCACHED_SUCCESS);
2607 /* Turn this into a help function */
2608 {
2609 memcached_result_st results_obj;
2610 memcached_result_st *results;
2611
2612 results= memcached_result_create(memc, &results_obj);
2613
2614 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
2615 {
2616 assert(results);
2617 assert(rc == MEMCACHED_SUCCESS);
2618 }
2619
2620 memcached_result_free(&results_obj);
2621 }
2622
2623 return 0;
2624 }
2625
2626 static test_return mget_read_function(memcached_st *memc)
2627 {
2628 memcached_return rc;
2629 unsigned int counter;
2630 memcached_execute_function callbacks[1];
2631
2632 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
2633 assert(rc == MEMCACHED_SUCCESS);
2634
2635 callbacks[0]= &callback_counter;
2636 counter= 0;
2637 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
2638
2639 return 0;
2640 }
2641
2642 static test_return delete_generate(memcached_st *memc)
2643 {
2644 unsigned int x;
2645
2646 for (x= 0; x < global_count; x++)
2647 {
2648 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
2649 }
2650
2651 return 0;
2652 }
2653
2654 static test_return delete_buffer_generate(memcached_st *memc)
2655 {
2656 int latch= 0;
2657 unsigned int x;
2658
2659 latch= 1;
2660 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
2661
2662 for (x= 0; x < global_count; x++)
2663 {
2664 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
2665 }
2666
2667 return 0;
2668 }
2669
2670 static test_return free_data(memcached_st *memc __attribute__((unused)))
2671 {
2672 pairs_free(global_pairs);
2673
2674 return 0;
2675 }
2676
2677 static test_return add_host_test1(memcached_st *memc)
2678 {
2679 unsigned int x;
2680 memcached_return rc;
2681 char servername[]= "0.example.com";
2682 memcached_server_st *servers;
2683
2684 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
2685 assert(servers);
2686 assert(1 == memcached_server_list_count(servers));
2687
2688 for (x= 2; x < 20; x++)
2689 {
2690 char buffer[SMALL_STRING_LEN];
2691
2692 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
2693 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
2694 &rc);
2695 assert(rc == MEMCACHED_SUCCESS);
2696 assert(x == memcached_server_list_count(servers));
2697 }
2698
2699 rc= memcached_server_push(memc, servers);
2700 assert(rc == MEMCACHED_SUCCESS);
2701 rc= memcached_server_push(memc, servers);
2702 assert(rc == MEMCACHED_SUCCESS);
2703
2704 memcached_server_list_free(servers);
2705
2706 return 0;
2707 }
2708
2709 static memcached_return pre_nonblock(memcached_st *memc)
2710 {
2711 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
2712
2713 return MEMCACHED_SUCCESS;
2714 }
2715
2716 static memcached_return pre_nonblock_binary(memcached_st *memc)
2717 {
2718 memcached_return rc= MEMCACHED_FAILURE;
2719 memcached_st *clone;
2720
2721 clone= memcached_clone(NULL, memc);
2722 assert(clone);
2723 // The memcached_version needs to be done on a clone, because the server
2724 // will not toggle protocol on an connection.
2725 memcached_version(clone);
2726
2727 if (clone->hosts[0].major_version >= 1 && clone->hosts[0].minor_version > 2)
2728 {
2729 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
2730 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2731 assert(rc == MEMCACHED_SUCCESS);
2732 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
2733 }
2734
2735 memcached_free(clone);
2736 return rc;
2737 }
2738
2739 static memcached_return pre_murmur(memcached_st *memc)
2740 {
2741 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
2742
2743 return MEMCACHED_SUCCESS;
2744 }
2745
2746 static memcached_return pre_jenkins(memcached_st *memc)
2747 {
2748 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
2749
2750 return MEMCACHED_SUCCESS;
2751 }
2752
2753
2754 static memcached_return pre_md5(memcached_st *memc)
2755 {
2756 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
2757
2758 return MEMCACHED_SUCCESS;
2759 }
2760
2761 static memcached_return pre_crc(memcached_st *memc)
2762 {
2763 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
2764
2765 return MEMCACHED_SUCCESS;
2766 }
2767
2768 static memcached_return pre_hsieh(memcached_st *memc)
2769 {
2770 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
2771
2772 return MEMCACHED_SUCCESS;
2773 }
2774
2775 static memcached_return pre_hash_fnv1_64(memcached_st *memc)
2776 {
2777 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_64);
2778
2779 return MEMCACHED_SUCCESS;
2780 }
2781
2782 static memcached_return pre_hash_fnv1a_64(memcached_st *memc)
2783 {
2784 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
2785
2786 return MEMCACHED_SUCCESS;
2787 }
2788
2789 static memcached_return pre_hash_fnv1_32(memcached_st *memc)
2790 {
2791 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
2792
2793 return MEMCACHED_SUCCESS;
2794 }
2795
2796 static memcached_return pre_hash_fnv1a_32(memcached_st *memc)
2797 {
2798 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
2799
2800 return MEMCACHED_SUCCESS;
2801 }
2802
2803 static memcached_return pre_behavior_ketama(memcached_st *memc)
2804 {
2805 memcached_return rc;
2806 uint64_t value;
2807
2808 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
2809 assert(rc == MEMCACHED_SUCCESS);
2810
2811 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
2812 assert(value == 1);
2813
2814 return MEMCACHED_SUCCESS;
2815 }
2816
2817 static memcached_return pre_behavior_ketama_weighted(memcached_st *memc)
2818 {
2819 memcached_return rc;
2820 uint64_t value;
2821
2822 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2823 assert(rc == MEMCACHED_SUCCESS);
2824
2825 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2826 assert(value == 1);
2827
2828 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2829 assert(rc == MEMCACHED_SUCCESS);
2830
2831 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2832 assert(value == MEMCACHED_HASH_MD5);
2833 return MEMCACHED_SUCCESS;
2834 }
2835
2836 static memcached_return pre_binary(memcached_st *memc)
2837 {
2838 memcached_return rc= MEMCACHED_FAILURE;
2839 memcached_st *clone;
2840
2841 clone= memcached_clone(NULL, memc);
2842 assert(clone);
2843 // The memcached_version needs to be done on a clone, because the server
2844 // will not toggle protocol on an connection.
2845 memcached_version(clone);
2846
2847 if (clone->hosts[0].major_version >= 1 && clone->hosts[0].minor_version > 2)
2848 {
2849 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2850 assert(rc == MEMCACHED_SUCCESS);
2851 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
2852 }
2853
2854 memcached_free(clone);
2855 return rc;
2856 }
2857
2858 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
2859 {
2860 free(mem);
2861 }
2862
2863 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
2864 {
2865 return malloc(size);
2866 }
2867
2868 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
2869 {
2870 return realloc(mem, size);
2871 }
2872
2873 static memcached_return set_prefix(memcached_st *memc)
2874 {
2875 memcached_return rc;
2876 const char *key= "mine";
2877 char *value;
2878
2879 /* Make sure be default none exists */
2880 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
2881 assert(rc == MEMCACHED_FAILURE);
2882
2883 /* Test a clean set */
2884 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
2885 assert(rc == MEMCACHED_SUCCESS);
2886
2887 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
2888 assert(memcmp(value, key, 4) == 0);
2889 assert(rc == MEMCACHED_SUCCESS);
2890
2891 /* Test that we can turn it off */
2892 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
2893 assert(rc == MEMCACHED_SUCCESS);
2894
2895 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
2896 assert(rc == MEMCACHED_FAILURE);
2897
2898 /* Now setup for main test */
2899 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
2900 assert(rc == MEMCACHED_SUCCESS);
2901
2902 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
2903 assert(rc == MEMCACHED_SUCCESS);
2904 assert(memcmp(value, key, 4) == 0);
2905
2906 /* Set to Zero, and then Set to something too large */
2907 {
2908 char *long_key;
2909 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
2910 assert(rc == MEMCACHED_SUCCESS);
2911
2912 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
2913 assert(rc == MEMCACHED_FAILURE);
2914 assert(value == NULL);
2915
2916 /* Test a long key for failure */
2917 /* TODO, extend test to determine based on setting, what result should be */
2918 long_key= "Thisismorethentheallottednumberofcharacters";
2919 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
2920 //assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
2921 assert(rc == MEMCACHED_SUCCESS);
2922
2923 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
2924 long_key= "This is more then the allotted number of characters";
2925 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
2926 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
2927
2928 /* Test for a bad prefix, but with a short key */
2929 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
2930 assert(rc == MEMCACHED_SUCCESS);
2931
2932 long_key= "dog cat";
2933 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
2934 assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
2935 }
2936
2937 return MEMCACHED_SUCCESS;
2938 }
2939
2940 static memcached_return set_memory_alloc(memcached_st *memc)
2941 {
2942 {
2943 memcached_malloc_function test_ptr;
2944 memcached_return rc;
2945
2946 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, (void*)&my_malloc);
2947 assert(rc == MEMCACHED_SUCCESS);
2948 test_ptr= (memcached_malloc_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
2949 assert(rc == MEMCACHED_SUCCESS);
2950 assert(test_ptr == my_malloc);
2951 }
2952
2953 {
2954 memcached_realloc_function test_ptr;
2955 memcached_return rc;
2956
2957 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, (void*)&my_realloc);
2958 assert(rc == MEMCACHED_SUCCESS);
2959 test_ptr= (memcached_realloc_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
2960 assert(rc == MEMCACHED_SUCCESS);
2961 assert(test_ptr == my_realloc);
2962 }
2963
2964 {
2965 memcached_free_function test_ptr;
2966 memcached_return rc;
2967
2968 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, (void*)my_free);
2969 assert(rc == MEMCACHED_SUCCESS);
2970 test_ptr= (memcached_free_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
2971 assert(rc == MEMCACHED_SUCCESS);
2972 assert(test_ptr == my_free);
2973 }
2974
2975 return MEMCACHED_SUCCESS;
2976 }
2977
2978 static memcached_return enable_consistent(memcached_st *memc)
2979 {
2980 memcached_server_distribution value= MEMCACHED_DISTRIBUTION_CONSISTENT;
2981 memcached_hash hash;
2982 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
2983 pre_hsieh(memc);
2984
2985 value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
2986 assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
2987
2988 hash= (memcached_hash)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
2989 assert(hash == MEMCACHED_HASH_HSIEH);
2990
2991
2992 return MEMCACHED_SUCCESS;
2993 }
2994
2995 static memcached_return enable_cas(memcached_st *memc)
2996 {
2997 unsigned int set= 1;
2998
2999 memcached_version(memc);
3000
3001 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3002 || memc->hosts[0].minor_version > 2)
3003 {
3004 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3005
3006 return MEMCACHED_SUCCESS;
3007 }
3008
3009 return MEMCACHED_FAILURE;
3010 }
3011
3012 static memcached_return check_for_1_2_3(memcached_st *memc)
3013 {
3014 memcached_version(memc);
3015
3016 if ((memc->hosts[0].major_version >= 1 && (memc->hosts[0].minor_version == 2 && memc->hosts[0].micro_version >= 4))
3017 || memc->hosts[0].minor_version > 2)
3018 return MEMCACHED_SUCCESS;
3019
3020 return MEMCACHED_FAILURE;
3021 }
3022
3023 static memcached_return pre_unix_socket(memcached_st *memc)
3024 {
3025 memcached_return rc;
3026 struct stat buf;
3027
3028 memcached_server_list_free(memc->hosts);
3029 memc->hosts= NULL;
3030 memc->number_of_hosts= 0;
3031
3032 if (stat("/tmp/memcached.socket", &buf))
3033 return MEMCACHED_FAILURE;
3034
3035 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3036
3037 return rc;
3038 }
3039
3040 static memcached_return pre_nodelay(memcached_st *memc)
3041 {
3042 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3043 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3044
3045 return MEMCACHED_SUCCESS;
3046 }
3047
3048 static memcached_return pre_settimer(memcached_st *memc)
3049 {
3050 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3051 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3052
3053 return MEMCACHED_SUCCESS;
3054 }
3055
3056 static memcached_return poll_timeout(memcached_st *memc)
3057 {
3058 int32_t timeout;
3059
3060 timeout= 100;
3061
3062 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3063
3064 timeout= (int32_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3065
3066 assert(timeout == 100);
3067
3068 return MEMCACHED_SUCCESS;
3069 }
3070
3071 static test_return noreply_test(memcached_st *memc)
3072 {
3073 memcached_return ret;
3074 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3075 assert(ret == MEMCACHED_SUCCESS);
3076 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3077 assert(ret == MEMCACHED_SUCCESS);
3078 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3079 assert(ret == MEMCACHED_SUCCESS);
3080 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3081 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3082 assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3083
3084 for (int count=0; count < 5; ++count)
3085 {
3086 for (int x=0; x < 100; ++x)
3087 {
3088 char key[10];
3089 size_t len=sprintf(key, "%d", x);
3090 switch (count)
3091 {
3092 case 0:
3093 ret=memcached_add(memc, key, len, key, len, 0, 0);
3094 break;
3095 case 1:
3096 ret=memcached_replace(memc, key, len, key, len, 0, 0);
3097 break;
3098 case 2:
3099 ret=memcached_set(memc, key, len, key, len, 0, 0);
3100 break;
3101 case 3:
3102 ret=memcached_append(memc, key, len, key, len, 0, 0);
3103 break;
3104 case 4:
3105 ret=memcached_prepend(memc, key, len, key, len, 0, 0);
3106 break;
3107 }
3108 assert(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3109 }
3110
3111 /*
3112 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3113 ** API and is _ONLY_ done this way to verify that the library works the
3114 ** way it is supposed to do!!!!
3115 */
3116 int no_msg=0;
3117 for (int x=0; x < memc->number_of_hosts; ++x)
3118 no_msg+=memc->hosts[x].cursor_active;
3119
3120 assert(no_msg == 0);
3121 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3122
3123 /*
3124 ** Now validate that all items was set properly!
3125 */
3126 for (int x=0; x < 100; ++x)
3127 {
3128 char key[10];
3129 size_t len=sprintf(key, "%d", x);
3130 size_t length;
3131 uint32_t flags;
3132 char* value=memcached_get(memc, key, strlen(key),
3133 &length, &flags, &ret);
3134 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3135 switch (count)
3136 {
3137 case 0: /* FALLTHROUGH */
3138 case 1: /* FALLTHROUGH */
3139 case 2:
3140 assert(strncmp(value, key, len) == 0);
3141 assert(len == length);
3142 break;
3143 case 3:
3144 assert(length == len * 2);
3145 break;
3146 case 4:
3147 assert(length == len * 3);
3148 break;
3149 }
3150 free(value);
3151 }
3152 }
3153
3154 /* Try setting an illegal cas value (should not return an error to
3155 * the caller (because we don't expect a return message from the server)
3156 */
3157 char* keys[]= {"0"};
3158 size_t lengths[]= {1};
3159 size_t length;
3160 uint32_t flags;
3161 memcached_result_st results_obj;
3162 memcached_result_st *results;
3163 ret=memcached_mget(memc, keys, lengths, 1);
3164 assert(ret == MEMCACHED_SUCCESS);
3165
3166 results=memcached_result_create(memc, &results_obj);
3167 assert(results);
3168 results=memcached_fetch_result(memc, &results_obj, &ret);
3169 assert(results);
3170 assert(ret == MEMCACHED_SUCCESS);
3171 uint64_t cas= memcached_result_cas(results);
3172 memcached_result_free(&results_obj);
3173
3174 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3175 assert(ret == MEMCACHED_SUCCESS);
3176
3177 /*
3178 * The item will have a new cas value, so try to set it again with the old
3179 * value. This should fail!
3180 */
3181 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
3182 assert(ret == MEMCACHED_SUCCESS);
3183 assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3184 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3185 assert(ret == MEMCACHED_SUCCESS && value != NULL);
3186 free(value);
3187
3188 return TEST_SUCCESS;
3189 }
3190
3191 static test_return analyzer_test(memcached_st *memc)
3192 {
3193 memcached_return rc;
3194 memcached_stat_st *stat;
3195 memcached_analysis_st *report;
3196
3197 stat= memcached_stat(memc, NULL, &rc);
3198 assert(rc == MEMCACHED_SUCCESS);
3199 assert(stat);
3200
3201 report= memcached_analyze(memc, stat, &rc);
3202 assert(rc == MEMCACHED_SUCCESS);
3203 assert(report);
3204
3205 free(report);
3206 memcached_stat_free(NULL, stat);
3207
3208 return TEST_SUCCESS;
3209 }
3210
3211 static void increment_request_id(uint16_t *id)
3212 {
3213 (*id)++;
3214 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
3215 *id= 0;
3216 }
3217
3218 static uint16_t *get_udp_request_ids(memcached_st *memc)
3219 {
3220 uint16_t *ids= malloc(sizeof(uint16_t) * memc->number_of_hosts);
3221 assert(ids != NULL);
3222 unsigned int x;
3223 for (x= 0; x < memc->number_of_hosts; x++)
3224 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) memc->hosts[x].write_buffer);
3225
3226 return ids;
3227 }
3228
3229 static test_return post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
3230 {
3231 unsigned int x;
3232 memcached_server_st *cur_server = memc->hosts;
3233 uint16_t *cur_req_ids = get_udp_request_ids(memc);
3234 for (x= 0; x < memc->number_of_hosts; x++)
3235 {
3236 assert(cur_server[x].cursor_active == 0);
3237 assert(cur_req_ids[x] == expected_req_ids[x]);
3238 }
3239 free(expected_req_ids);
3240 free(cur_req_ids);
3241 return TEST_SUCCESS;
3242 }
3243
3244 /*
3245 ** There is a little bit of a hack here, instead of removing
3246 ** the servers, I just set num host to 0 and them add then new udp servers
3247 **/
3248 static memcached_return init_udp(memcached_st *memc)
3249 {
3250 memcached_version(memc);
3251 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
3252 if (memc->hosts[0].major_version != 1 || memc->hosts[0].minor_version != 2
3253 || memc->hosts[0].micro_version < 6)
3254 return MEMCACHED_FAILURE;
3255
3256 uint32_t num_hosts= memc->number_of_hosts;
3257 unsigned int x= 0;
3258 memcached_server_st servers[num_hosts];
3259 memcpy(servers, memc->hosts, sizeof(memcached_server_st) * num_hosts);
3260 memc->number_of_hosts= 0;
3261 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
3262 for (x= 0; x < num_hosts; x++)
3263 {
3264 assert(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
3265 assert(memc->hosts[x].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
3266 }
3267 return MEMCACHED_SUCCESS;
3268 }
3269
3270 static memcached_return binary_init_udp(memcached_st *memc)
3271 {
3272 pre_binary(memc);
3273 return init_udp(memc);
3274 }
3275
3276 /* Make sure that I cant add a tcp server to a udp client */
3277 static test_return add_tcp_server_udp_client_test(memcached_st *memc)
3278 {
3279 memcached_server_st server;
3280 memcached_server_clone(&server, &memc->hosts[0]);
3281 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
3282 assert(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
3283 return TEST_SUCCESS;
3284 }
3285
3286 /* Make sure that I cant add a udp server to a tcp client */
3287 static test_return add_udp_server_tcp_client_test(memcached_st *memc)
3288 {
3289 memcached_server_st server;
3290 memcached_server_clone(&server, &memc->hosts[0]);
3291 assert(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
3292
3293 memcached_st tcp_client;
3294 memcached_create(&tcp_client);
3295 assert(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
3296 return TEST_SUCCESS;
3297 }
3298
3299 static test_return set_udp_behavior_test(memcached_st *memc)
3300 {
3301
3302 memcached_quit(memc);
3303 memc->number_of_hosts= 0;
3304 run_distribution(memc);
3305 assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
3306 assert(memc->flags & MEM_USE_UDP);
3307 assert(memc->flags & MEM_NOREPLY);;
3308
3309 assert(memc->number_of_hosts == 0);
3310
3311 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
3312 assert(!(memc->flags & MEM_USE_UDP));
3313 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
3314 assert(!(memc->flags & MEM_NOREPLY));
3315 return TEST_SUCCESS;
3316 }
3317
3318 static test_return udp_set_test(memcached_st *memc)
3319 {
3320 unsigned int x= 0;
3321 unsigned int num_iters= 1025; //request id rolls over at 1024
3322 for (x= 0; x < num_iters;x++)
3323 {
3324 memcached_return rc;
3325 char *key= "foo";
3326 char *value= "when we sanitize";
3327 uint16_t *expected_ids= get_udp_request_ids(memc);
3328 unsigned int server_key= memcached_generate_hash(memc,key,strlen(key));
3329 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
3330 rc= memcached_set(memc, key, strlen(key),
3331 value, strlen(value),
3332 (time_t)0, (uint32_t)0);
3333 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
3334 /** NB, the check below assumes that if new write_ptr is less than
3335 * the original write_ptr that we have flushed. For large payloads, this
3336 * maybe an invalid assumption, but for the small payload we have it is OK
3337 */
3338 if (rc == MEMCACHED_SUCCESS ||
3339 memc->hosts[server_key].write_buffer_offset < init_offset)
3340 increment_request_id(&expected_ids[server_key]);
3341
3342 if (rc == MEMCACHED_SUCCESS)
3343 {
3344 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
3345 }
3346 else
3347 {
3348 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
3349 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
3350 }
3351 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
3352 }
3353 return TEST_SUCCESS;
3354 }
3355
3356 static test_return udp_buffered_set_test(memcached_st *memc)
3357 {
3358 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3359 return udp_set_test(memc);
3360 }
3361
3362 static test_return udp_set_too_big_test(memcached_st *memc)
3363 {
3364 memcached_return rc;
3365 char *key= "bar";
3366 char value[MAX_UDP_DATAGRAM_LENGTH];
3367 uint16_t *expected_ids= get_udp_request_ids(memc);
3368 rc= memcached_set(memc, key, strlen(key),
3369 value, MAX_UDP_DATAGRAM_LENGTH,
3370 (time_t)0, (uint32_t)0);
3371 assert(rc == MEMCACHED_WRITE_FAILURE);
3372 return post_udp_op_check(memc,expected_ids);
3373 }
3374
3375 test_return udp_delete_test(memcached_st *memc)
3376 {
3377 unsigned int x= 0;
3378 unsigned int num_iters= 1025; //request id rolls over at 1024
3379 for (x= 0; x < num_iters;x++)
3380 {
3381 memcached_return rc;
3382 char *key= "foo";
3383 uint16_t *expected_ids=get_udp_request_ids(memc);
3384 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
3385 size_t init_offset= memc->hosts[server_key].write_buffer_offset;
3386 rc= memcached_delete(memc, key, strlen(key), 0);
3387 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
3388 if (rc == MEMCACHED_SUCCESS || memc->hosts[server_key].write_buffer_offset < init_offset)
3389 increment_request_id(&expected_ids[server_key]);
3390 if (rc == MEMCACHED_SUCCESS)
3391 assert(memc->hosts[server_key].write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
3392 else
3393 {
3394 assert(memc->hosts[server_key].write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
3395 assert(memc->hosts[server_key].write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
3396 }
3397 assert(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
3398 }
3399 return TEST_SUCCESS;
3400 }
3401
3402 static test_return udp_buffered_delete_test(memcached_st *memc)
3403 {
3404 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3405 return udp_delete_test(memc);
3406 }
3407
3408 test_return udp_verbosity_test(memcached_st *memc)
3409 {
3410 memcached_return rc;
3411 uint16_t *expected_ids= get_udp_request_ids(memc);
3412 unsigned int x;
3413 for (x= 0; x < memc->number_of_hosts;x++)
3414 increment_request_id(&expected_ids[x]);
3415
3416 rc= memcached_verbosity(memc,3);
3417 assert(rc == MEMCACHED_SUCCESS);
3418 return post_udp_op_check(memc,expected_ids);
3419 }
3420
3421 test_return udp_quit_test(memcached_st *memc)
3422 {
3423 uint16_t *expected_ids= get_udp_request_ids(memc);
3424 memcached_quit(memc);
3425 return post_udp_op_check(memc, expected_ids);
3426 }
3427
3428 test_return udp_flush_test(memcached_st *memc)
3429 {
3430 memcached_return rc;
3431 uint16_t *expected_ids= get_udp_request_ids(memc);
3432 unsigned int x;
3433 for (x= 0; x < memc->number_of_hosts;x++)
3434 increment_request_id(&expected_ids[x]);
3435
3436 rc= memcached_flush(memc,0);
3437 assert(rc == MEMCACHED_SUCCESS);
3438 return post_udp_op_check(memc,expected_ids);
3439 }
3440
3441 test_return udp_incr_test(memcached_st *memc)
3442 {
3443 memcached_return rc;
3444 char *key= "incr";
3445 char *value= "1";
3446 rc= memcached_set(memc, key, strlen(key),
3447 value, strlen(value),
3448 (time_t)0, (uint32_t)0);
3449
3450 assert(rc == MEMCACHED_SUCCESS);
3451 uint16_t *expected_ids= get_udp_request_ids(memc);
3452 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
3453 increment_request_id(&expected_ids[server_key]);
3454 uint64_t newvalue;
3455 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
3456 assert(rc == MEMCACHED_SUCCESS);
3457 return post_udp_op_check(memc, expected_ids);
3458 }
3459
3460 test_return udp_decr_test(memcached_st *memc)
3461 {
3462 memcached_return rc;
3463 char *key= "decr";
3464 char *value= "1";
3465 rc= memcached_set(memc, key, strlen(key),
3466 value, strlen(value),
3467 (time_t)0, (uint32_t)0);
3468
3469 assert(rc == MEMCACHED_SUCCESS);
3470 uint16_t *expected_ids= get_udp_request_ids(memc);
3471 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
3472 increment_request_id(&expected_ids[server_key]);
3473 uint64_t newvalue;
3474 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
3475 assert(rc == MEMCACHED_SUCCESS);
3476 return post_udp_op_check(memc, expected_ids);
3477 }
3478
3479
3480 test_return udp_stat_test(memcached_st *memc)
3481 {
3482 memcached_stat_st * rv= NULL;
3483 memcached_return rc;
3484 char args[]= "";
3485 uint16_t *expected_ids = get_udp_request_ids(memc);
3486 rv = memcached_stat(memc, args, &rc);
3487 free(rv);
3488 assert(rc == MEMCACHED_NOT_SUPPORTED);
3489 return post_udp_op_check(memc, expected_ids);
3490 }
3491
3492 test_return udp_version_test(memcached_st *memc)
3493 {
3494 memcached_return rc;
3495 uint16_t *expected_ids = get_udp_request_ids(memc);
3496 rc = memcached_version(memc);
3497 assert(rc == MEMCACHED_NOT_SUPPORTED);
3498 return post_udp_op_check(memc, expected_ids);
3499 }
3500
3501 test_return udp_get_test(memcached_st *memc)
3502 {
3503 memcached_return rc;
3504 char *key= "foo";
3505 size_t vlen;
3506 uint16_t *expected_ids = get_udp_request_ids(memc);
3507 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
3508 assert(rc == MEMCACHED_NOT_SUPPORTED);
3509 assert(val == NULL);
3510 return post_udp_op_check(memc, expected_ids);
3511 }
3512
3513 test_return udp_mixed_io_test(memcached_st *memc)
3514 {
3515 test_st current_op;
3516 test_st mixed_io_ops [] ={
3517 {"udp_set_test", 0, udp_set_test},
3518 {"udp_set_too_big_test", 0, udp_set_too_big_test},
3519 {"udp_delete_test", 0, udp_delete_test},
3520 {"udp_verbosity_test", 0, udp_verbosity_test},
3521 {"udp_quit_test", 0, udp_quit_test},
3522 {"udp_flush_test", 0, udp_flush_test},
3523 {"udp_incr_test", 0, udp_incr_test},
3524 {"udp_decr_test", 0, udp_decr_test},
3525 {"udp_version_test", 0, udp_version_test}
3526 };
3527 unsigned int x= 0;
3528 for (x= 0; x < 500; x++)
3529 {
3530 current_op= mixed_io_ops[random() % 9];
3531 assert(current_op.function(memc) == TEST_SUCCESS);
3532 }
3533 return TEST_SUCCESS;
3534 }
3535
3536 test_st udp_setup_server_tests[] ={
3537 {"set_udp_behavior_test", 0, set_udp_behavior_test},
3538 {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test},
3539 {"add_udp_server_tcp_client_test", 0, add_udp_server_tcp_client_test},
3540 {0, 0, 0}
3541 };
3542
3543 test_st upd_io_tests[] ={
3544 {"udp_set_test", 0, udp_set_test},
3545 {"udp_buffered_set_test", 0, udp_buffered_set_test},
3546 {"udp_set_too_big_test", 0, udp_set_too_big_test},
3547 {"udp_delete_test", 0, udp_delete_test},
3548 {"udp_buffered_delete_test", 0, udp_buffered_delete_test},
3549 {"udp_verbosity_test", 0, udp_verbosity_test},
3550 {"udp_quit_test", 0, udp_quit_test},
3551 {"udp_flush_test", 0, udp_flush_test},
3552 {"udp_incr_test", 0, udp_incr_test},
3553 {"udp_decr_test", 0, udp_decr_test},
3554 {"udp_stat_test", 0, udp_stat_test},
3555 {"udp_version_test", 0, udp_version_test},
3556 {"udp_get_test", 0, udp_get_test},
3557 {"udp_mixed_io_test", 0, udp_mixed_io_test},
3558 {0, 0, 0}
3559 };
3560
3561 /* Clean the server before beginning testing */
3562 test_st tests[] ={
3563 {"flush", 0, flush_test },
3564 {"init", 0, init_test },
3565 {"allocation", 0, allocation_test },
3566 {"server_list_null_test", 0, server_list_null_test},
3567 {"server_unsort", 0, server_unsort_test},
3568 {"server_sort", 0, server_sort_test},
3569 {"server_sort2", 0, server_sort2_test},
3570 {"clone_test", 0, clone_test },
3571 {"error", 0, error_test },
3572 {"set", 0, set_test },
3573 {"set2", 0, set_test2 },
3574 {"set3", 0, set_test3 },
3575 {"add", 1, add_test },
3576 {"replace", 1, replace_test },
3577 {"delete", 1, delete_test },
3578 {"get", 1, get_test },
3579 {"get2", 0, get_test2 },
3580 {"get3", 0, get_test3 },
3581 {"get4", 0, get_test4 },
3582 {"stats_servername", 0, stats_servername_test },
3583 {"increment", 0, increment_test },
3584 {"decrement", 0, decrement_test },
3585 {"quit", 0, quit_test },
3586 {"mget", 1, mget_test },
3587 {"mget_result", 1, mget_result_test },
3588 {"mget_result_alloc", 1, mget_result_alloc_test },
3589 {"mget_result_function", 1, mget_result_function },
3590 {"get_stats", 0, get_stats },
3591 {"add_host_test", 0, add_host_test },
3592 {"add_host_test_1", 0, add_host_test1 },
3593 {"get_stats_keys", 0, get_stats_keys },
3594 {"behavior_test", 0, get_stats_keys },
3595 {"callback_test", 0, get_stats_keys },
3596 {"version_string_test", 0, version_string_test},
3597 {"bad_key", 1, bad_key_test },
3598 {"memcached_server_cursor", 1, memcached_server_cursor_test },
3599 {"read_through", 1, read_through },
3600 {"delete_through", 1, delete_through },
3601 {"noreply", 1, noreply_test},
3602 {"analyzer", 1, analyzer_test},
3603 {0, 0, 0}
3604 };
3605
3606 test_st async_tests[] ={
3607 {"add", 1, add_wrapper },
3608 {0, 0, 0}
3609 };
3610
3611 test_st string_tests[] ={
3612 {"string static with null", 0, string_static_null },
3613 {"string alloc with null", 0, string_alloc_null },
3614 {"string alloc with 1K", 0, string_alloc_with_size },
3615 {"string alloc with malloc failure", 0, string_alloc_with_size_toobig },
3616 {"string append", 0, string_alloc_append },
3617 {"string append failure (too big)", 0, string_alloc_append_toobig },
3618 {0, 0, 0}
3619 };
3620
3621 test_st result_tests[] ={
3622 {"result static", 0, result_static},
3623 {"result alloc", 0, result_alloc},
3624 {0, 0, 0}
3625 };
3626
3627 test_st version_1_2_3[] ={
3628 {"append", 0, append_test },
3629 {"prepend", 0, prepend_test },
3630 {"cas", 0, cas_test },
3631 {"cas2", 0, cas2_test },
3632 {"append_binary", 0, append_binary_test },
3633 {0, 0, 0}
3634 };
3635
3636 test_st user_tests[] ={
3637 {"user_supplied_bug1", 0, user_supplied_bug1 },
3638 {"user_supplied_bug2", 0, user_supplied_bug2 },
3639 {"user_supplied_bug3", 0, user_supplied_bug3 },
3640 {"user_supplied_bug4", 0, user_supplied_bug4 },
3641 {"user_supplied_bug5", 1, user_supplied_bug5 },
3642 {"user_supplied_bug6", 1, user_supplied_bug6 },
3643 {"user_supplied_bug7", 1, user_supplied_bug7 },
3644 {"user_supplied_bug8", 1, user_supplied_bug8 },
3645 {"user_supplied_bug9", 1, user_supplied_bug9 },
3646 {"user_supplied_bug10", 1, user_supplied_bug10 },
3647 {"user_supplied_bug11", 1, user_supplied_bug11 },
3648 {"user_supplied_bug12", 1, user_supplied_bug12 },
3649 {"user_supplied_bug13", 1, user_supplied_bug13 },
3650 {"user_supplied_bug14", 1, user_supplied_bug14 },
3651 {"user_supplied_bug15", 1, user_supplied_bug15 },
3652 {"user_supplied_bug16", 1, user_supplied_bug16 },
3653 #ifndef __sun
3654 /*
3655 ** It seems to be something weird with the character sets..
3656 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
3657 ** guess I need to find out how this is supposed to work.. Perhaps I need
3658 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
3659 ** so just disable the code for now...).
3660 */
3661 {"user_supplied_bug17", 1, user_supplied_bug17 },
3662 #endif
3663 {"user_supplied_bug18", 1, user_supplied_bug18 },
3664 {"user_supplied_bug19", 1, user_supplied_bug19 },
3665 {"user_supplied_bug20", 1, user_supplied_bug20 },
3666 {0, 0, 0}
3667 };
3668
3669 test_st generate_tests[] ={
3670 {"generate_pairs", 1, generate_pairs },
3671 {"generate_data", 1, generate_data },
3672 {"get_read", 0, get_read },
3673 {"delete_generate", 0, delete_generate },
3674 {"generate_buffer_data", 1, generate_buffer_data },
3675 {"delete_buffer", 0, delete_buffer_generate},
3676 {"generate_data", 1, generate_data },
3677 {"mget_read", 0, mget_read },
3678 {"mget_read_result", 0, mget_read_result },
3679 {"mget_read_function", 0, mget_read_function },
3680 {"cleanup", 1, cleanup_pairs },
3681 {"generate_large_pairs", 1, generate_large_pairs },
3682 {"generate_data", 1, generate_data },
3683 {"generate_buffer_data", 1, generate_buffer_data },
3684 {"cleanup", 1, cleanup_pairs },
3685 {0, 0, 0}
3686 };
3687
3688 test_st consistent_tests[] ={
3689 {"generate_pairs", 1, generate_pairs },
3690 {"generate_data", 1, generate_data },
3691 {"get_read", 0, get_read_count },
3692 {"cleanup", 1, cleanup_pairs },
3693 {0, 0, 0}
3694 };
3695
3696 test_st consistent_weighted_tests[] ={
3697 {"generate_pairs", 1, generate_pairs },
3698 {"generate_data", 1, generate_data_with_stats },
3699 {"get_read", 0, get_read_count },
3700 {"cleanup", 1, cleanup_pairs },
3701 {0, 0, 0}
3702 };
3703
3704 collection_st collection[] ={
3705 {"udp_setup", init_udp, 0, udp_setup_server_tests},
3706 {"udp_io", init_udp, 0, upd_io_tests},
3707 {"udp_binary_io", binary_init_udp, 0, upd_io_tests},
3708 {"block", 0, 0, tests},
3709 {"binary", pre_binary, 0, tests},
3710 {"nonblock", pre_nonblock, 0, tests},
3711 {"nodelay", pre_nodelay, 0, tests},
3712 {"settimer", pre_settimer, 0, tests},
3713 {"md5", pre_md5, 0, tests},
3714 {"crc", pre_crc, 0, tests},
3715 {"hsieh", pre_hsieh, 0, tests},
3716 {"jenkins", pre_jenkins, 0, tests},
3717 {"fnv1_64", pre_hash_fnv1_64, 0, tests},
3718 {"fnv1a_64", pre_hash_fnv1a_64, 0, tests},
3719 {"fnv1_32", pre_hash_fnv1_32, 0, tests},
3720 {"fnv1a_32", pre_hash_fnv1a_32, 0, tests},
3721 {"ketama", pre_behavior_ketama, 0, tests},
3722 {"unix_socket", pre_unix_socket, 0, tests},
3723 {"unix_socket_nodelay", pre_nodelay, 0, tests},
3724 {"poll_timeout", poll_timeout, 0, tests},
3725 {"gets", enable_cas, 0, tests},
3726 {"consistent", enable_consistent, 0, tests},
3727 {"memory_allocators", set_memory_alloc, 0, tests},
3728 {"prefix", set_prefix, 0, tests},
3729 {"version_1_2_3", check_for_1_2_3, 0, version_1_2_3},
3730 {"string", 0, 0, string_tests},
3731 {"result", 0, 0, result_tests},
3732 {"async", pre_nonblock, 0, async_tests},
3733 {"async_binary", pre_nonblock_binary, 0, async_tests},
3734 {"user", 0, 0, user_tests},
3735 {"generate", 0, 0, generate_tests},
3736 {"generate_hsieh", pre_hsieh, 0, generate_tests},
3737 {"generate_ketama", pre_behavior_ketama, 0, generate_tests},
3738 {"generate_hsieh_consistent", enable_consistent, 0, generate_tests},
3739 {"generate_md5", pre_md5, 0, generate_tests},
3740 {"generate_murmur", pre_murmur, 0, generate_tests},
3741 {"generate_jenkins", pre_jenkins, 0, generate_tests},
3742 {"generate_nonblock", pre_nonblock, 0, generate_tests},
3743 {"consistent_not", 0, 0, consistent_tests},
3744 {"consistent_ketama", pre_behavior_ketama, 0, consistent_tests},
3745 {"consistent_ketama_weighted", pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
3746 {0, 0, 0, 0}
3747 };
3748
3749 #define SERVERS_TO_CREATE 5
3750
3751 /* Prototypes for functions we will pass to test framework */
3752 void *world_create(void);
3753 void world_destroy(void *p);
3754
3755 void *world_create(void)
3756 {
3757 server_startup_st *construct;
3758
3759 construct= (server_startup_st *)malloc(sizeof(server_startup_st));
3760 memset(construct, 0, sizeof(server_startup_st));
3761 construct->count= SERVERS_TO_CREATE;
3762 construct->udp= 0;
3763 server_startup(construct);
3764
3765 return construct;
3766 }
3767
3768
3769 void world_destroy(void *p)
3770 {
3771 server_startup_st *construct= (server_startup_st *)p;
3772 memcached_server_st *servers= (memcached_server_st *)construct->servers;
3773 memcached_server_list_free(servers);
3774
3775 server_shutdown(construct);
3776 free(construct);
3777 }
3778
3779 void get_world(world_st *world)
3780 {
3781 world->collections= collection;
3782 world->create= world_create;
3783 world->destroy= world_destroy;
3784 }