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