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