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