6fa1995a4c26f7794e6bb66ee2276a7f69edee6c
[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_true(server_list == NULL);
72
73 server_list= memcached_server_list_append_with_weight(NULL, "localhost", 0, 0, NULL);
74 test_true(server_list == NULL);
75
76 server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, &rc);
77 test_true(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_true 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_true(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_true(memcached_server_count(local_memc) == x + 1);
112 test_true(memcached_servers_count(memcached_server_list(local_memc)) == x+1);
113 test_true(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_true 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_true(local_memc);
135 rc= memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
136 test_true(rc == MEMCACHED_SUCCESS);
137
138 rc= memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43043, 0);
139 test_true(rc == MEMCACHED_SUCCESS);
140 instance= memcached_server_instance_fetch(local_memc, 0);
141 test_true(instance->port == 43043);
142
143 rc= memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43042, 0);
144 test_true(rc == MEMCACHED_SUCCESS);
145
146 instance= memcached_server_instance_fetch(local_memc, 0);
147 test_true(instance->port == 43042);
148
149 instance= memcached_server_instance_fetch(local_memc, 1);
150 test_true(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_true in server_display_function */
175 size_t bigger= 0; /* Prime the value for the test_true 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_true(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_true(memcached_server_count(local_memc) == x+1);
188 test_true(memcached_servers_count(memcached_server_list(local_memc)) == x+1);
189 test_true(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_true(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_true(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_true(memc_clone);
231
232 test_true(memc_clone->call_free == memc->call_free);
233 test_true(memc_clone->call_malloc == memc->call_malloc);
234 test_true(memc_clone->call_realloc == memc->call_realloc);
235 test_true(memc_clone->call_calloc == memc->call_calloc);
236 test_true(memc_clone->connect_timeout == memc->connect_timeout);
237 test_true(memc_clone->delete_trigger == memc->delete_trigger);
238 test_true(memc_clone->distribution == memc->distribution);
239 { // Test all of the flags
240 test_true(memc_clone->flags.no_block == memc->flags.no_block);
241 test_true(memc_clone->flags.tcp_nodelay == memc->flags.tcp_nodelay);
242 test_true(memc_clone->flags.reuse_memory == memc->flags.reuse_memory);
243 test_true(memc_clone->flags.use_cache_lookups == memc->flags.use_cache_lookups);
244 test_true(memc_clone->flags.support_cas == memc->flags.support_cas);
245 test_true(memc_clone->flags.buffer_requests == memc->flags.buffer_requests);
246 test_true(memc_clone->flags.use_sort_hosts == memc->flags.use_sort_hosts);
247 test_true(memc_clone->flags.verify_key == memc->flags.verify_key);
248 test_true(memc_clone->flags.ketama_weighted == memc->flags.ketama_weighted);
249 test_true(memc_clone->flags.binary_protocol == memc->flags.binary_protocol);
250 test_true(memc_clone->flags.hash_with_prefix_key == memc->flags.hash_with_prefix_key);
251 test_true(memc_clone->flags.no_reply == memc->flags.no_reply);
252 test_true(memc_clone->flags.use_udp == memc->flags.use_udp);
253 test_true(memc_clone->flags.auto_eject_hosts == memc->flags.auto_eject_hosts);
254 test_true(memc_clone->flags.randomize_replica_read == memc->flags.randomize_replica_read);
255 }
256 test_true(memc_clone->get_key_failure == memc->get_key_failure);
257 test_true(memc_clone->hash == memc->hash);
258 test_true(memc_clone->distribution_hash == memc->distribution_hash);
259 test_true(memc_clone->io_bytes_watermark == memc->io_bytes_watermark);
260 test_true(memc_clone->io_msg_watermark == memc->io_msg_watermark);
261 test_true(memc_clone->io_key_prefetch == memc->io_key_prefetch);
262 test_true(memc_clone->on_cleanup == memc->on_cleanup);
263 test_true(memc_clone->on_clone == memc->on_clone);
264 test_true(memc_clone->poll_timeout == memc->poll_timeout);
265 test_true(memc_clone->rcv_timeout == memc->rcv_timeout);
266 test_true(memc_clone->recv_size == memc->recv_size);
267 test_true(memc_clone->retry_timeout == memc->retry_timeout);
268 test_true(memc_clone->send_size == memc->send_size);
269 test_true(memc_clone->server_failure_limit == memc->server_failure_limit);
270 test_true(memc_clone->snd_timeout == memc->snd_timeout);
271 test_true(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_true(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_true(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_true(memcached_set_user_data(memc, foo) == NULL);
303 test_true(memcached_get_user_data(memc) == foo);
304 test_true(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_true(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_true(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_true(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_true(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_true(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_true(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_true(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_true(rc == MEMCACHED_SUCCESS);
387
388 out_value= memcached_get(memc, key, strlen(key),
389 &value_length, &flags, &rc);
390 test_true(!memcmp(out_value, "we the people", strlen("we the people")));
391 test_true(strlen("we the people") == value_length);
392 test_true(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_true(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_true(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_true(rc == MEMCACHED_SUCCESS);
424 }
425
426 value= (uint32_t *)memcached_get(memc, key, strlen(key),
427 &value_length, &flags, &rc);
428 test_true((value_length == (sizeof(uint32_t) * x)));
429 test_true(rc == MEMCACHED_SUCCESS);
430
431 for (uint32_t counter= x, *ptr= value; counter; counter--)
432 {
433 test_true(*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_true(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_true(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_true(results);
472 test_true(results->cas);
473 test_true(rc == MEMCACHED_SUCCESS);
474 test_true(memcached_result_cas(results));
475
476 test_true(!memcmp(value, "we the people", strlen("we the people")));
477 test_true(strlen("we the people") == value_length);
478 test_true(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_true(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_true(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_true(results);
517 test_true(rc == MEMCACHED_SUCCESS);
518 test_true(memcached_result_cas(results));
519 test_true(!memcmp(value, memcached_result_value(results), value_length));
520 test_true(strlen(memcached_result_value(results)) == value_length);
521 test_true(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_true(rc == MEMCACHED_END);
527 test_true(results == NULL);
528 #endif
529
530 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
531 test_true(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_true(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_true(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_true(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_true(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_true(rc == MEMCACHED_SUCCESS);
571
572 out_value= memcached_get(memc, key, strlen(key),
573 &value_length, &flags, &rc);
574 test_true(!memcmp(out_value, "we the people", strlen("we the people")));
575 test_true(strlen("we the people") == value_length);
576 test_true(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_true(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_true(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_STORED);
608 }
609 else
610 {
611 test_true(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_true(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_true(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_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
671
672 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
673 test_true(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_true(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_true(memc_clone);
725
726 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
727 test_true(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_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
735 test_true(string_length == 0);
736 test_true(!string);
737
738 set= 0;
739 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
740 test_true(rc == MEMCACHED_SUCCESS);
741 string= memcached_get(memc_clone, key, strlen(key),
742 &string_length, &flags, &rc);
743 test_true(rc == MEMCACHED_NOTFOUND);
744 test_true(string_length == 0);
745 test_true(!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_true(rc == MEMCACHED_SUCCESS);
753
754 rc= memcached_mget(memc_clone, keys, key_lengths, 3);
755 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
756
757 rc= memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1);
758 test_true(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_true(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_true(rc == MEMCACHED_NOTFOUND);
776 test_true(string_length == 0);
777 test_true(!string);
778
779 string= memcached_get(memc_clone, longkey, max_keylen + 1,
780 &string_length, &flags, &rc);
781 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
782 test_true(string_length == 0);
783 test_true(!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_true(rc == MEMCACHED_SUCCESS);
793 string= memcached_get(memc_clone, key, 0,
794 &string_length, &flags, &rc);
795 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
796 test_true(string_length == 0);
797 test_true(!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_true(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_true(rc == MEMCACHED_SUCCESS);
833
834 string= memcached_get(memc, key, strlen(key),
835 &string_length, &flags, &rc);
836
837 test_true(rc == MEMCACHED_SUCCESS);
838 test_true(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_true(rc == MEMCACHED_SUCCESS);
846 test_true(string_length == strlen(READ_THROUGH_VALUE));
847 test_true(!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_true(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_true(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND);
885
886 string= memcached_get(memc, key, strlen(key),
887 &string_length, &flags, &rc);
888
889 test_true(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_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
909
910 string= memcached_get(memc, key, strlen(key),
911 &string_length, &flags, &rc);
912
913 test_true(string);
914 test_true(rc == MEMCACHED_SUCCESS);
915 test_true(string_length == strlen(value));
916 test_true(!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_true(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_true(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_true(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_true(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_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
994
995 string= memcached_get(memc, key, strlen(key),
996 &string_length, &flags, &rc);
997
998 test_true(rc == MEMCACHED_SUCCESS);
999 test_true(string);
1000 test_true(string_length == value_length);
1001 test_true(!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_true(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_true(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_true(rc == MEMCACHED_SUCCESS);
1037 test_true(string);
1038 test_true(string_length == value_length);
1039 test_true(!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_true(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_true(results);
1073 results=memcached_fetch_result(memc, &results_obj, &rc);
1074 test_true(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_true(rc == MEMCACHED_SUCCESS);
1080
1081 char *val= memcached_get_by_key(memc, keys[0], lengths[0], "yek", 3,
1082 &rlen, &flags, &rc);
1083 test_true(val == NULL);
1084 test_true(rc == MEMCACHED_NOTFOUND);
1085 val= memcached_get(memc, keys[0], lengths[0], &rlen, &flags, &rc);
1086 test_true(val != NULL);
1087 test_true(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_true(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_true(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_true(rc == MEMCACHED_SUCCESS);
1126 int val = 0;
1127 if (key_length == 4)
1128 val= 1;
1129 test_true(string_length == strlen(values[val]));
1130 test_true(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_true(rc == MEMCACHED_END);
1137
1138 // now get just one
1139 rc= memcached_mget(memc, keys, lengths, 1);
1140 test_true(rc == MEMCACHED_SUCCESS);
1141
1142 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1143 test_true(key_length == lengths[0]);
1144 test_true(strncmp(keys[0], key, key_length) == 0);
1145 test_true(string_length == strlen(values[0]));
1146 test_true(strncmp(values[0], string, string_length) == 0);
1147 test_true(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_true(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_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1183
1184 rc= memcached_increment(memc, key, strlen(key),
1185 1, &new_number);
1186 test_true(rc == MEMCACHED_SUCCESS);
1187 test_true(new_number == 1);
1188
1189 rc= memcached_increment(memc, key, strlen(key),
1190 1, &new_number);
1191 test_true(rc == MEMCACHED_SUCCESS);
1192 test_true(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_true(rc == MEMCACHED_SUCCESS);
1209 test_true(new_number == initial);
1210
1211 rc= memcached_increment_with_initial(memc, key, strlen(key),
1212 1, initial, 0, &new_number);
1213 test_true(rc == MEMCACHED_SUCCESS);
1214 test_true(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_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1230
1231 rc= memcached_decrement(memc, key, strlen(key),
1232 1, &new_number);
1233 test_true(rc == MEMCACHED_SUCCESS);
1234 test_true(new_number == 2);
1235
1236 rc= memcached_decrement(memc, key, strlen(key),
1237 1, &new_number);
1238 test_true(rc == MEMCACHED_SUCCESS);
1239 test_true(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_true(rc == MEMCACHED_SUCCESS);
1256 test_true(new_number == initial);
1257
1258 rc= memcached_decrement_with_initial(memc, key, strlen(key),
1259 1, initial, 0, &new_number);
1260 test_true(rc == MEMCACHED_SUCCESS);
1261 test_true(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_true(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_true(rc == MEMCACHED_SUCCESS);
1283 test_true(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_true(rc == MEMCACHED_SUCCESS);
1288 test_true(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_true(rc == MEMCACHED_SUCCESS);
1307 test_true(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_true(rc == MEMCACHED_SUCCESS);
1313 test_true(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_true(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_true(rc == MEMCACHED_SUCCESS);
1336 test_true(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_true(rc == MEMCACHED_SUCCESS);
1342 test_true(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_true(rc == MEMCACHED_SUCCESS);
1361 test_true(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_true(rc == MEMCACHED_SUCCESS);
1367 test_true(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_true(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_true(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_true(results);
1404 test_true(&results_obj == results);
1405
1406 /* We need to empty the server before continueing test */
1407 rc= memcached_flush(memc, 0);
1408 test_true(rc == MEMCACHED_SUCCESS);
1409
1410 rc= memcached_mget(memc, keys, key_length, 3);
1411 test_true(rc == MEMCACHED_SUCCESS);
1412
1413 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1414 {
1415 test_true(results);
1416 }
1417
1418 while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
1419 test_true(!results);
1420 test_true(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_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1428 }
1429
1430 rc= memcached_mget(memc, keys, key_length, 3);
1431 test_true(rc == MEMCACHED_SUCCESS);
1432
1433 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1434 {
1435 test_true(results);
1436 test_true(&results_obj == results);
1437 test_true(rc == MEMCACHED_SUCCESS);
1438 test_true(memcached_result_key_length(results) == memcached_result_length(results));
1439 test_true(!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_true(rc == MEMCACHED_SUCCESS);
1461
1462 rc= memcached_mget(memc, keys, key_length, 3);
1463 test_true(rc == MEMCACHED_SUCCESS);
1464
1465 while ((results= memcached_fetch_result(memc, NULL, &rc)) != NULL)
1466 {
1467 test_true(results);
1468 }
1469 test_true(!results);
1470 test_true(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_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1478 }
1479
1480 rc= memcached_mget(memc, keys, key_length, 3);
1481 test_true(rc == MEMCACHED_SUCCESS);
1482
1483 x= 0;
1484 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1485 {
1486 test_true(results);
1487 test_true(rc == MEMCACHED_SUCCESS);
1488 test_true(memcached_result_key_length(results) == memcached_result_length(results));
1489 test_true(!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_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1528 }
1529
1530 rc= memcached_mget(memc, keys, key_length, 3);
1531 test_true(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_true(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_true(rc == MEMCACHED_SUCCESS);
1558
1559 rc= memcached_mget(memc, keys, key_length, 3);
1560 test_true(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_true(return_value);
1566 }
1567 test_true(!return_value);
1568 test_true(return_value_length == 0);
1569 test_true(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_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1577 }
1578
1579 rc= memcached_mget(memc, keys, key_length, 3);
1580 test_true(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_true(return_value);
1587 test_true(rc == MEMCACHED_SUCCESS);
1588 test_true(return_key_length == return_value_length);
1589 test_true(!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_true(keys[x] != NULL);
1627 rc= memcached_add(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
1628 test_true(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_true(rc == MEMCACHED_SUCCESS);
1640
1641 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
1642 test_true(rc == MEMCACHED_END);
1643
1644 /* Verify that we got all of the items */
1645 test_true(counter == max_keys);
1646 }
1647 else
1648 {
1649 test_true(rc == MEMCACHED_NOT_SUPPORTED);
1650 test_true(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_true(rc == MEMCACHED_SUCCESS);
1674 for (ptr= stat_list; *ptr; ptr++)
1675 test_true(*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_true(!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_true(rc == MEMCACHED_SUCCESS);
1703
1704 test_true(rc == MEMCACHED_SUCCESS);
1705 test_true(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_true(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_true(servers);
1730 test_true(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_true(rc == MEMCACHED_SUCCESS);
1740 test_true(x == memcached_server_list_count(servers));
1741 }
1742
1743 rc= memcached_server_push(memc, servers);
1744 test_true(rc == MEMCACHED_SUCCESS);
1745 rc= memcached_server_push(memc, servers);
1746 test_true(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_true(rc == MEMCACHED_SUCCESS);
1773 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1774 test_true(*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_true(rc == MEMCACHED_SUCCESS);
1787 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1788 test_true(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_true(rc == MEMCACHED_SUCCESS);
1802 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1803 test_true(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_true(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_true(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_true(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_true(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_true(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_true(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_true(value == MEMCACHED_HASH_CRC);
1847
1848 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1849 test_true(value > 0);
1850
1851 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1852 test_true(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_true((value + 1) == memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
1857
1858 return TEST_SUCCESS;
1859 }
1860
1861 static test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
1862 {
1863 memcached_return_t rc;
1864 bool set= true;
1865 bool value;
1866
1867 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
1868 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
1869
1870 value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
1871
1872 if (rc == MEMCACHED_SUCCESS)
1873 {
1874 test_true((bool)value == set);
1875 }
1876 else
1877 {
1878 test_false((bool)value == set);
1879 }
1880
1881 return TEST_SUCCESS;
1882 }
1883
1884 static test_return_t fetch_all_results(memcached_st *memc)
1885 {
1886 memcached_return_t rc= MEMCACHED_SUCCESS;
1887 char return_key[MEMCACHED_MAX_KEY];
1888 size_t return_key_length;
1889 char *return_value;
1890 size_t return_value_length;
1891 uint32_t flags;
1892
1893 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1894 &return_value_length, &flags, &rc)))
1895 {
1896 test_true(return_value);
1897 test_true(rc == MEMCACHED_SUCCESS);
1898 free(return_value);
1899 }
1900
1901 return ((rc == MEMCACHED_END) || (rc == MEMCACHED_SUCCESS)) ? TEST_SUCCESS : TEST_FAILURE;
1902 }
1903
1904 /* Test case provided by Cal Haldenbrand */
1905 static test_return_t user_supplied_bug1(memcached_st *memc)
1906 {
1907 unsigned int setter= 1;
1908
1909 unsigned long long total= 0;
1910 uint32_t size= 0;
1911 char key[10];
1912 char randomstuff[6 * 1024];
1913 memcached_return_t rc;
1914
1915 memset(randomstuff, 0, 6 * 1024);
1916
1917 /* We just keep looking at the same values over and over */
1918 srandom(10);
1919
1920 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1921 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1922
1923
1924 /* add key */
1925 for (uint32_t x= 0 ; total < 20 * 1024576 ; x++ )
1926 {
1927 unsigned int j= 0;
1928
1929 size= (uint32_t)(rand() % ( 5 * 1024 ) ) + 400;
1930 memset(randomstuff, 0, 6 * 1024);
1931 test_true(size < 6 * 1024); /* Being safe here */
1932
1933 for (j= 0 ; j < size ;j++)
1934 randomstuff[j] = (signed char) ((rand() % 26) + 97);
1935
1936 total += size;
1937 snprintf(key, sizeof(key), "%u", x);
1938 rc = memcached_set(memc, key, strlen(key),
1939 randomstuff, strlen(randomstuff), 10, 0);
1940 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1941 /* If we fail, lets try again */
1942 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
1943 rc = memcached_set(memc, key, strlen(key),
1944 randomstuff, strlen(randomstuff), 10, 0);
1945 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1946 }
1947
1948 return TEST_SUCCESS;
1949 }
1950
1951 /* Test case provided by Cal Haldenbrand */
1952 static test_return_t user_supplied_bug2(memcached_st *memc)
1953 {
1954 unsigned int setter;
1955 size_t total= 0;
1956
1957 setter= 1;
1958 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1959 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1960 #ifdef NOT_YET
1961 setter = 20 * 1024576;
1962 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
1963 setter = 20 * 1024576;
1964 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
1965 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
1966 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
1967
1968 for (x= 0, errors= 0; total < 20 * 1024576 ; x++)
1969 #endif
1970
1971 for (uint32_t x= 0, errors= 0; total < 24576 ; x++)
1972 {
1973 memcached_return_t rc= MEMCACHED_SUCCESS;
1974 char buffer[SMALL_STRING_LEN];
1975 uint32_t flags= 0;
1976 size_t val_len= 0;
1977 char *getval;
1978
1979 memset(buffer, 0, SMALL_STRING_LEN);
1980
1981 snprintf(buffer, sizeof(buffer), "%u", x);
1982 getval= memcached_get(memc, buffer, strlen(buffer),
1983 &val_len, &flags, &rc);
1984 if (rc != MEMCACHED_SUCCESS)
1985 {
1986 if (rc == MEMCACHED_NOTFOUND)
1987 errors++;
1988 else
1989 {
1990 test_true(rc);
1991 }
1992
1993 continue;
1994 }
1995 total+= val_len;
1996 errors= 0;
1997 free(getval);
1998 }
1999
2000 return TEST_SUCCESS;
2001 }
2002
2003 /* Do a large mget() over all the keys we think exist */
2004 #define KEY_COUNT 3000 // * 1024576
2005 static test_return_t user_supplied_bug3(memcached_st *memc)
2006 {
2007 memcached_return_t rc;
2008 unsigned int setter;
2009 unsigned int x;
2010 char **keys;
2011 size_t key_lengths[KEY_COUNT];
2012
2013 setter= 1;
2014 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2015 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2016 #ifdef NOT_YET
2017 setter = 20 * 1024576;
2018 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2019 setter = 20 * 1024576;
2020 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2021 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2022 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2023 #endif
2024
2025 keys= calloc(KEY_COUNT, sizeof(char *));
2026 test_true(keys);
2027 for (x= 0; x < KEY_COUNT; x++)
2028 {
2029 char buffer[30];
2030
2031 snprintf(buffer, 30, "%u", x);
2032 keys[x]= strdup(buffer);
2033 key_lengths[x]= strlen(keys[x]);
2034 }
2035
2036 rc= memcached_mget(memc, (const char **)keys, key_lengths, KEY_COUNT);
2037 test_true(rc == MEMCACHED_SUCCESS);
2038
2039 test_true(fetch_all_results(memc) == TEST_SUCCESS);
2040
2041 for (x= 0; x < KEY_COUNT; x++)
2042 free(keys[x]);
2043 free(keys);
2044
2045 return TEST_SUCCESS;
2046 }
2047
2048 /* Make sure we behave properly if server list has no values */
2049 static test_return_t user_supplied_bug4(memcached_st *memc)
2050 {
2051 memcached_return_t rc;
2052 const char *keys[]= {"fudge", "son", "food"};
2053 size_t key_length[]= {5, 3, 4};
2054 unsigned int x;
2055 uint32_t flags;
2056 char return_key[MEMCACHED_MAX_KEY];
2057 size_t return_key_length;
2058 char *return_value;
2059 size_t return_value_length;
2060
2061 /* Here we free everything before running a bunch of mget tests */
2062 memcached_servers_reset(memc);
2063
2064
2065 /* We need to empty the server before continueing test */
2066 rc= memcached_flush(memc, 0);
2067 test_true(rc == MEMCACHED_NO_SERVERS);
2068
2069 rc= memcached_mget(memc, keys, key_length, 3);
2070 test_true(rc == MEMCACHED_NO_SERVERS);
2071
2072 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2073 &return_value_length, &flags, &rc)) != NULL)
2074 {
2075 test_true(return_value);
2076 }
2077 test_true(!return_value);
2078 test_true(return_value_length == 0);
2079 test_true(rc == MEMCACHED_NO_SERVERS);
2080
2081 for (x= 0; x < 3; x++)
2082 {
2083 rc= memcached_set(memc, keys[x], key_length[x],
2084 keys[x], key_length[x],
2085 (time_t)50, (uint32_t)9);
2086 test_true(rc == MEMCACHED_NO_SERVERS);
2087 }
2088
2089 rc= memcached_mget(memc, keys, key_length, 3);
2090 test_true(rc == MEMCACHED_NO_SERVERS);
2091
2092 x= 0;
2093 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2094 &return_value_length, &flags, &rc)))
2095 {
2096 test_true(return_value);
2097 test_true(rc == MEMCACHED_SUCCESS);
2098 test_true(return_key_length == return_value_length);
2099 test_true(!memcmp(return_value, return_key, return_value_length));
2100 free(return_value);
2101 x++;
2102 }
2103
2104 return TEST_SUCCESS;
2105 }
2106
2107 #define VALUE_SIZE_BUG5 1048064
2108 static test_return_t user_supplied_bug5(memcached_st *memc)
2109 {
2110 memcached_return_t rc;
2111 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2112 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2113 char return_key[MEMCACHED_MAX_KEY];
2114 size_t return_key_length;
2115 char *value;
2116 size_t value_length;
2117 uint32_t flags;
2118 unsigned int count;
2119 unsigned int x;
2120 char insert_data[VALUE_SIZE_BUG5];
2121
2122 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2123 insert_data[x]= (signed char)rand();
2124
2125 memcached_flush(memc, 0);
2126 value= memcached_get(memc, keys[0], key_length[0],
2127 &value_length, &flags, &rc);
2128 test_true(value == NULL);
2129 rc= memcached_mget(memc, keys, key_length, 4);
2130
2131 count= 0;
2132 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2133 &value_length, &flags, &rc)))
2134 count++;
2135 test_true(count == 0);
2136
2137 for (x= 0; x < 4; x++)
2138 {
2139 rc= memcached_set(memc, keys[x], key_length[x],
2140 insert_data, VALUE_SIZE_BUG5,
2141 (time_t)0, (uint32_t)0);
2142 test_true(rc == MEMCACHED_SUCCESS);
2143 }
2144
2145 for (x= 0; x < 10; x++)
2146 {
2147 value= memcached_get(memc, keys[0], key_length[0],
2148 &value_length, &flags, &rc);
2149 test_true(value);
2150 free(value);
2151
2152 rc= memcached_mget(memc, keys, key_length, 4);
2153 count= 0;
2154 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2155 &value_length, &flags, &rc)))
2156 {
2157 count++;
2158 free(value);
2159 }
2160 test_true(count == 4);
2161 }
2162
2163 return TEST_SUCCESS;
2164 }
2165
2166 static test_return_t user_supplied_bug6(memcached_st *memc)
2167 {
2168 memcached_return_t rc;
2169 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2170 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2171 char return_key[MEMCACHED_MAX_KEY];
2172 size_t return_key_length;
2173 char *value;
2174 size_t value_length;
2175 uint32_t flags;
2176 unsigned int count;
2177 unsigned int x;
2178 char insert_data[VALUE_SIZE_BUG5];
2179
2180 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2181 insert_data[x]= (signed char)rand();
2182
2183 memcached_flush(memc, 0);
2184 value= memcached_get(memc, keys[0], key_length[0],
2185 &value_length, &flags, &rc);
2186 test_true(value == NULL);
2187 test_true(rc == MEMCACHED_NOTFOUND);
2188 rc= memcached_mget(memc, keys, key_length, 4);
2189 test_true(rc == MEMCACHED_SUCCESS);
2190
2191 count= 0;
2192 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2193 &value_length, &flags, &rc)))
2194 count++;
2195 test_true(count == 0);
2196 test_true(rc == MEMCACHED_END);
2197
2198 for (x= 0; x < 4; x++)
2199 {
2200 rc= memcached_set(memc, keys[x], key_length[x],
2201 insert_data, VALUE_SIZE_BUG5,
2202 (time_t)0, (uint32_t)0);
2203 test_true(rc == MEMCACHED_SUCCESS);
2204 }
2205
2206 for (x= 0; x < 2; x++)
2207 {
2208 value= memcached_get(memc, keys[0], key_length[0],
2209 &value_length, &flags, &rc);
2210 test_true(value);
2211 free(value);
2212
2213 rc= memcached_mget(memc, keys, key_length, 4);
2214 test_true(rc == MEMCACHED_SUCCESS);
2215 count= 3;
2216 /* We test for purge of partial complete fetches */
2217 for (count= 3; count; count--)
2218 {
2219 value= memcached_fetch(memc, return_key, &return_key_length,
2220 &value_length, &flags, &rc);
2221 test_true(rc == MEMCACHED_SUCCESS);
2222 test_true(!(memcmp(value, insert_data, value_length)));
2223 test_true(value_length);
2224 free(value);
2225 }
2226 }
2227
2228 return TEST_SUCCESS;
2229 }
2230
2231 static test_return_t user_supplied_bug8(memcached_st *memc __attribute__((unused)))
2232 {
2233 memcached_return_t rc;
2234 memcached_st *mine;
2235 memcached_st *memc_clone;
2236
2237 memcached_server_st *servers;
2238 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";
2239
2240 servers= memcached_servers_parse(server_list);
2241 test_true(servers);
2242
2243 mine= memcached_create(NULL);
2244 rc= memcached_server_push(mine, servers);
2245 test_true(rc == MEMCACHED_SUCCESS);
2246 memcached_server_list_free(servers);
2247
2248 test_true(mine);
2249 memc_clone= memcached_clone(NULL, mine);
2250
2251 memcached_quit(mine);
2252 memcached_quit(memc_clone);
2253
2254
2255 memcached_free(mine);
2256 memcached_free(memc_clone);
2257
2258 return TEST_SUCCESS;
2259 }
2260
2261 /* Test flag store/retrieve */
2262 static test_return_t user_supplied_bug7(memcached_st *memc)
2263 {
2264 memcached_return_t rc;
2265 const char *keys= "036790384900";
2266 size_t key_length= strlen(keys);
2267 char return_key[MEMCACHED_MAX_KEY];
2268 size_t return_key_length;
2269 char *value;
2270 size_t value_length;
2271 uint32_t flags;
2272 unsigned int x;
2273 char insert_data[VALUE_SIZE_BUG5];
2274
2275 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2276 insert_data[x]= (signed char)rand();
2277
2278 memcached_flush(memc, 0);
2279
2280 flags= 245;
2281 rc= memcached_set(memc, keys, key_length,
2282 insert_data, VALUE_SIZE_BUG5,
2283 (time_t)0, flags);
2284 test_true(rc == MEMCACHED_SUCCESS);
2285
2286 flags= 0;
2287 value= memcached_get(memc, keys, key_length,
2288 &value_length, &flags, &rc);
2289 test_true(flags == 245);
2290 test_true(value);
2291 free(value);
2292
2293 rc= memcached_mget(memc, &keys, &key_length, 1);
2294
2295 flags= 0;
2296 value= memcached_fetch(memc, return_key, &return_key_length,
2297 &value_length, &flags, &rc);
2298 test_true(flags == 245);
2299 test_true(value);
2300 free(value);
2301
2302
2303 return TEST_SUCCESS;
2304 }
2305
2306 static test_return_t user_supplied_bug9(memcached_st *memc)
2307 {
2308 memcached_return_t rc;
2309 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2310 size_t key_length[3];
2311 unsigned int x;
2312 uint32_t flags;
2313 unsigned count= 0;
2314
2315 char return_key[MEMCACHED_MAX_KEY];
2316 size_t return_key_length;
2317 char *return_value;
2318 size_t return_value_length;
2319
2320
2321 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2322 key_length[1]= strlen("fudge&*@#");
2323 key_length[2]= strlen("for^#@&$not");
2324
2325
2326 for (x= 0; x < 3; x++)
2327 {
2328 rc= memcached_set(memc, keys[x], key_length[x],
2329 keys[x], key_length[x],
2330 (time_t)50, (uint32_t)9);
2331 test_true(rc == MEMCACHED_SUCCESS);
2332 }
2333
2334 rc= memcached_mget(memc, keys, key_length, 3);
2335 test_true(rc == MEMCACHED_SUCCESS);
2336
2337 /* We need to empty the server before continueing test */
2338 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2339 &return_value_length, &flags, &rc)) != NULL)
2340 {
2341 test_true(return_value);
2342 free(return_value);
2343 count++;
2344 }
2345 test_true(count == 3);
2346
2347 return TEST_SUCCESS;
2348 }
2349
2350 /* We are testing with aggressive timeout to get failures */
2351 static test_return_t user_supplied_bug10(memcached_st *memc)
2352 {
2353 const char *key= "foo";
2354 char *value;
2355 size_t value_length= 512;
2356 unsigned int x;
2357 size_t key_len= 3;
2358 memcached_return_t rc;
2359 unsigned int set= 1;
2360 memcached_st *mclone= memcached_clone(NULL, memc);
2361 int32_t timeout;
2362
2363 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2364 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2365 timeout= 2;
2366 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2367 (uint64_t)timeout);
2368
2369 value = (char*)malloc(value_length * sizeof(char));
2370
2371 for (x= 0; x < value_length; x++)
2372 value[x]= (char) (x % 127);
2373
2374 for (x= 1; x <= 100000; ++x)
2375 {
2376 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2377
2378 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE ||
2379 rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT);
2380
2381 if (rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_TIMEOUT)
2382 x--;
2383 }
2384
2385 free(value);
2386 memcached_free(mclone);
2387
2388 return TEST_SUCCESS;
2389 }
2390
2391 /*
2392 We are looking failures in the async protocol
2393 */
2394 static test_return_t user_supplied_bug11(memcached_st *memc)
2395 {
2396 const char *key= "foo";
2397 char *value;
2398 size_t value_length= 512;
2399 unsigned int x;
2400 size_t key_len= 3;
2401 memcached_return_t rc;
2402 unsigned int set= 1;
2403 int32_t timeout;
2404 memcached_st *mclone= memcached_clone(NULL, memc);
2405
2406 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2407 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2408 timeout= -1;
2409 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2410 (size_t)timeout);
2411
2412 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2413
2414 test_true(timeout == -1);
2415
2416 value = (char*)malloc(value_length * sizeof(char));
2417
2418 for (x= 0; x < value_length; x++)
2419 value[x]= (char) (x % 127);
2420
2421 for (x= 1; x <= 100000; ++x)
2422 {
2423 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2424 }
2425
2426 free(value);
2427 memcached_free(mclone);
2428
2429 return TEST_SUCCESS;
2430 }
2431
2432 /*
2433 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2434 */
2435 static test_return_t user_supplied_bug12(memcached_st *memc)
2436 {
2437 memcached_return_t rc;
2438 uint32_t flags;
2439 size_t value_length;
2440 char *value;
2441 uint64_t number_value;
2442
2443 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2444 &value_length, &flags, &rc);
2445 test_true(value == NULL);
2446 test_true(rc == MEMCACHED_NOTFOUND);
2447
2448 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2449 1, &number_value);
2450
2451 test_true(value == NULL);
2452 /* The binary protocol will set the key if it doesn't exist */
2453 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2454 {
2455 test_true(rc == MEMCACHED_SUCCESS);
2456 }
2457 else
2458 {
2459 test_true(rc == MEMCACHED_NOTFOUND);
2460 }
2461
2462 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2463
2464 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2465 &value_length, &flags, &rc);
2466 test_true(value);
2467 test_true(rc == MEMCACHED_SUCCESS);
2468 free(value);
2469
2470 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2471 1, &number_value);
2472 test_true(number_value == 2);
2473 test_true(rc == MEMCACHED_SUCCESS);
2474
2475 return TEST_SUCCESS;
2476 }
2477
2478 /*
2479 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2480 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2481 */
2482 static test_return_t user_supplied_bug13(memcached_st *memc)
2483 {
2484 char key[] = "key34567890";
2485 char *overflow;
2486 memcached_return_t rc;
2487 size_t overflowSize;
2488
2489 char commandFirst[]= "set key34567890 0 0 ";
2490 char commandLast[] = " \r\n"; /* first line of command sent to server */
2491 size_t commandLength;
2492 size_t testSize;
2493
2494 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2495
2496 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2497
2498 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2499 {
2500 overflow= malloc(testSize);
2501 test_true(overflow != NULL);
2502
2503 memset(overflow, 'x', testSize);
2504 rc= memcached_set(memc, key, strlen(key),
2505 overflow, testSize, 0, 0);
2506 test_true(rc == MEMCACHED_SUCCESS);
2507 free(overflow);
2508 }
2509
2510 return TEST_SUCCESS;
2511 }
2512
2513
2514 /*
2515 Test values of many different sizes
2516 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2517 set key34567890 0 0 8169 \r\n
2518 is sent followed by buffer of size 8169, followed by 8169
2519 */
2520 static test_return_t user_supplied_bug14(memcached_st *memc)
2521 {
2522 size_t setter= 1;
2523 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2524 memcached_return_t rc;
2525 const char *key= "foo";
2526 char *value;
2527 size_t value_length= 18000;
2528 char *string;
2529 size_t string_length;
2530 uint32_t flags;
2531 unsigned int x;
2532 size_t current_length;
2533
2534 value = (char*)malloc(value_length);
2535 test_true(value);
2536
2537 for (x= 0; x < value_length; x++)
2538 value[x] = (char) (x % 127);
2539
2540 for (current_length= 0; current_length < value_length; current_length++)
2541 {
2542 rc= memcached_set(memc, key, strlen(key),
2543 value, current_length,
2544 (time_t)0, (uint32_t)0);
2545 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2546
2547 string= memcached_get(memc, key, strlen(key),
2548 &string_length, &flags, &rc);
2549
2550 test_true(rc == MEMCACHED_SUCCESS);
2551 test_true(string_length == current_length);
2552 test_true(!memcmp(string, value, string_length));
2553
2554 free(string);
2555 }
2556
2557 free(value);
2558
2559 return TEST_SUCCESS;
2560 }
2561
2562 /*
2563 Look for zero length value problems
2564 */
2565 static test_return_t user_supplied_bug15(memcached_st *memc)
2566 {
2567 uint32_t x;
2568 memcached_return_t rc;
2569 const char *key= "mykey";
2570 char *value;
2571 size_t length;
2572 uint32_t flags;
2573
2574 for (x= 0; x < 2; x++)
2575 {
2576 rc= memcached_set(memc, key, strlen(key),
2577 NULL, 0,
2578 (time_t)0, (uint32_t)0);
2579
2580 test_true(rc == MEMCACHED_SUCCESS);
2581
2582 value= memcached_get(memc, key, strlen(key),
2583 &length, &flags, &rc);
2584
2585 test_true(rc == MEMCACHED_SUCCESS);
2586 test_true(value == NULL);
2587 test_true(length == 0);
2588 test_true(flags == 0);
2589
2590 value= memcached_get(memc, key, strlen(key),
2591 &length, &flags, &rc);
2592
2593 test_true(rc == MEMCACHED_SUCCESS);
2594 test_true(value == NULL);
2595 test_true(length == 0);
2596 test_true(flags == 0);
2597 }
2598
2599 return TEST_SUCCESS;
2600 }
2601
2602 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2603 static test_return_t user_supplied_bug16(memcached_st *memc)
2604 {
2605 memcached_return_t rc;
2606 const char *key= "mykey";
2607 char *value;
2608 size_t length;
2609 uint32_t flags;
2610
2611 rc= memcached_set(memc, key, strlen(key),
2612 NULL, 0,
2613 (time_t)0, UINT32_MAX);
2614
2615 test_true(rc == MEMCACHED_SUCCESS);
2616
2617 value= memcached_get(memc, key, strlen(key),
2618 &length, &flags, &rc);
2619
2620 test_true(rc == MEMCACHED_SUCCESS);
2621 test_true(value == NULL);
2622 test_true(length == 0);
2623 test_true(flags == UINT32_MAX);
2624
2625 return TEST_SUCCESS;
2626 }
2627
2628 #ifndef __sun
2629 /* Check the validity of chinese key*/
2630 static test_return_t user_supplied_bug17(memcached_st *memc)
2631 {
2632 memcached_return_t rc;
2633 const char *key= "豆瓣";
2634 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2635 char *value2;
2636 size_t length;
2637 uint32_t flags;
2638
2639 rc= memcached_set(memc, key, strlen(key),
2640 value, strlen(value),
2641 (time_t)0, 0);
2642
2643 test_true(rc == MEMCACHED_SUCCESS);
2644
2645 value2= memcached_get(memc, key, strlen(key),
2646 &length, &flags, &rc);
2647
2648 test_true(length==strlen(value));
2649 test_true(rc == MEMCACHED_SUCCESS);
2650 test_true(memcmp(value, value2, length)==0);
2651 free(value2);
2652
2653 return TEST_SUCCESS;
2654 }
2655 #endif
2656
2657 /*
2658 From Andrei on IRC
2659 */
2660
2661 static test_return_t user_supplied_bug19(memcached_st *memc)
2662 {
2663 memcached_st *m;
2664 memcached_server_st *s;
2665 memcached_return_t res;
2666
2667 (void)memc;
2668
2669 m= memcached_create(NULL);
2670 memcached_server_add_with_weight(m, "localhost", 11311, 100);
2671 memcached_server_add_with_weight(m, "localhost", 11312, 100);
2672
2673 s= memcached_server_by_key(m, "a", 1, &res);
2674 memcached_server_free(s);
2675
2676 memcached_free(m);
2677
2678 return TEST_SUCCESS;
2679 }
2680
2681 /* CAS test from Andei */
2682 static test_return_t user_supplied_bug20(memcached_st *memc)
2683 {
2684 memcached_return_t status;
2685 memcached_result_st *result, result_obj;
2686 const char *key = "abc";
2687 size_t key_len = strlen("abc");
2688 const char *value = "foobar";
2689 size_t value_len = strlen(value);
2690
2691 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2692
2693 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2694 test_true(status == MEMCACHED_SUCCESS);
2695
2696 status = memcached_mget(memc, &key, &key_len, 1);
2697 test_true(status == MEMCACHED_SUCCESS);
2698
2699 result= memcached_result_create(memc, &result_obj);
2700 test_true(result);
2701
2702 memcached_result_create(memc, &result_obj);
2703 result= memcached_fetch_result(memc, &result_obj, &status);
2704
2705 test_true(result);
2706 test_true(status == MEMCACHED_SUCCESS);
2707
2708 memcached_result_free(result);
2709
2710 return TEST_SUCCESS;
2711 }
2712
2713 #include "ketama_test_cases.h"
2714 static test_return_t user_supplied_bug18(memcached_st *trash)
2715 {
2716 memcached_return_t rc;
2717 uint64_t value;
2718 int x;
2719 memcached_server_st *server_pool;
2720 memcached_st *memc;
2721
2722 (void)trash;
2723
2724 memc= memcached_create(NULL);
2725 test_true(memc);
2726
2727 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2728 test_true(rc == MEMCACHED_SUCCESS);
2729
2730 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2731 test_true(value == 1);
2732
2733 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2734 test_true(rc == MEMCACHED_SUCCESS);
2735
2736 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2737 test_true(value == MEMCACHED_HASH_MD5);
2738
2739 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");
2740 memcached_server_push(memc, server_pool);
2741
2742 /* verify that the server list was parsed okay. */
2743 test_true(memcached_server_count(memc) == 8);
2744 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2745 test_true(server_pool[0].port == 11211);
2746 test_true(server_pool[0].weight == 600);
2747 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2748 test_true(server_pool[2].port == 11211);
2749 test_true(server_pool[2].weight == 200);
2750 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2751 test_true(server_pool[7].port == 11211);
2752 test_true(server_pool[7].weight == 100);
2753
2754 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2755 * us test the boundary wraparound.
2756 */
2757 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
2758
2759 /* verify the standard ketama set. */
2760 for (x= 0; x < 99; x++)
2761 {
2762 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2763 memcached_server_instance_st *instance=
2764 memcached_server_instance_fetch(memc, server_idx);
2765 char *hostname = instance->hostname;
2766 test_strcmp(hostname, ketama_test_cases[x].server);
2767 }
2768
2769 memcached_server_list_free(server_pool);
2770 memcached_free(memc);
2771
2772 return TEST_SUCCESS;
2773 }
2774
2775 /* Large mget() of missing keys with binary proto
2776 *
2777 * If many binary quiet commands (such as getq's in an mget) fill the output
2778 * buffer and the server chooses not to respond, memcached_flush hangs. See
2779 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2780 */
2781
2782 /* sighandler_t function that always asserts false */
2783 static void fail(int unused __attribute__((unused)))
2784 {
2785 assert(0);
2786 }
2787
2788
2789 static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2790 {
2791 memcached_return_t rc;
2792 unsigned int x;
2793 char **keys;
2794 size_t* key_lengths;
2795 void (*oldalarm)(int);
2796 memcached_st *memc_clone;
2797
2798 memc_clone= memcached_clone(NULL, memc);
2799 test_true(memc_clone);
2800
2801 /* only binproto uses getq for mget */
2802 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2803
2804 /* empty the cache to ensure misses (hence non-responses) */
2805 rc= memcached_flush(memc_clone, 0);
2806 test_true(rc == MEMCACHED_SUCCESS);
2807
2808 key_lengths= calloc(key_count, sizeof(size_t));
2809 keys= calloc(key_count, sizeof(char *));
2810 test_true(keys);
2811 for (x= 0; x < key_count; x++)
2812 {
2813 char buffer[30];
2814
2815 snprintf(buffer, 30, "%u", x);
2816 keys[x]= strdup(buffer);
2817 key_lengths[x]= strlen(keys[x]);
2818 }
2819
2820 oldalarm= signal(SIGALRM, fail);
2821 alarm(5);
2822
2823 rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
2824 test_true(rc == MEMCACHED_SUCCESS);
2825
2826 alarm(0);
2827 signal(SIGALRM, oldalarm);
2828
2829 test_true(fetch_all_results(memc) == TEST_SUCCESS);
2830
2831 for (x= 0; x < key_count; x++)
2832 free(keys[x]);
2833 free(keys);
2834 free(key_lengths);
2835
2836 memcached_free(memc_clone);
2837
2838 return TEST_SUCCESS;
2839 }
2840
2841 static test_return_t pre_binary(memcached_st *memc);
2842
2843 static test_return_t user_supplied_bug21(memcached_st *memc)
2844 {
2845 test_return_t test_rc;
2846 test_rc= pre_binary(memc);
2847
2848 if (test_rc != TEST_SUCCESS)
2849 return test_rc;
2850
2851 test_return_t rc;
2852
2853 /* should work as of r580 */
2854 rc= _user_supplied_bug21(memc, 10);
2855 test_true(rc == TEST_SUCCESS);
2856
2857 /* should fail as of r580 */
2858 rc= _user_supplied_bug21(memc, 1000);
2859 test_true(rc == TEST_SUCCESS);
2860
2861 return TEST_SUCCESS;
2862 }
2863
2864 static test_return_t auto_eject_hosts(memcached_st *trash)
2865 {
2866 (void) trash;
2867 memcached_server_instance_st *instance;
2868
2869 memcached_return_t rc;
2870 memcached_st *memc= memcached_create(NULL);
2871 test_true(memc);
2872
2873 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2874 test_true(rc == MEMCACHED_SUCCESS);
2875
2876 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2877 test_true(value == 1);
2878
2879 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2880 test_true(rc == MEMCACHED_SUCCESS);
2881
2882 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2883 test_true(value == MEMCACHED_HASH_MD5);
2884
2885 /* server should be removed when in delay */
2886 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
2887 test_true(rc == MEMCACHED_SUCCESS);
2888
2889 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
2890 test_true(value == 1);
2891
2892 memcached_server_st *server_pool;
2893 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");
2894 memcached_server_push(memc, server_pool);
2895
2896 /* verify that the server list was parsed okay. */
2897 test_true(memcached_server_count(memc) == 8);
2898 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2899 test_true(server_pool[0].port == 11211);
2900 test_true(server_pool[0].weight == 600);
2901 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2902 test_true(server_pool[2].port == 11211);
2903 test_true(server_pool[2].weight == 200);
2904 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2905 test_true(server_pool[7].port == 11211);
2906 test_true(server_pool[7].weight == 100);
2907
2908 instance= memcached_server_instance_fetch(memc, 2);
2909 instance->next_retry = time(NULL) + 15;
2910 memc->next_distribution_rebuild= time(NULL) - 1;
2911
2912 for (size_t x= 0; x < 99; x++)
2913 {
2914 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2915 test_true(server_idx != 2);
2916 }
2917
2918 /* and re-added when it's back. */
2919 instance->next_retry = time(NULL) - 1;
2920 memc->next_distribution_rebuild= time(NULL) - 1;
2921 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
2922 memc->distribution);
2923 for (size_t x= 0; x < 99; x++)
2924 {
2925 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2926 // We re-use instance from above.
2927 instance=
2928 memcached_server_instance_fetch(memc, server_idx);
2929 char *hostname = instance->hostname;
2930 test_true(strcmp(hostname, ketama_test_cases[x].server) == 0);
2931 }
2932
2933 memcached_server_list_free(server_pool);
2934 memcached_free(memc);
2935
2936 return TEST_SUCCESS;
2937 }
2938
2939 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
2940 {
2941 (void) trash;
2942
2943 memcached_return_t rc;
2944 memcached_st *memc= memcached_create(NULL);
2945 test_true(memc);
2946
2947
2948 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2949 test_true(rc == MEMCACHED_SUCCESS);
2950
2951 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2952 test_true(value == 1);
2953
2954 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2955 test_true(rc == MEMCACHED_SUCCESS);
2956
2957 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2958 test_true(value == MEMCACHED_HASH_MD5);
2959
2960
2961 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
2962
2963 memcached_server_st *server_pool;
2964 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");
2965 memcached_server_push(memc, server_pool);
2966
2967 // @todo this needs to be refactored to actually test something.
2968 #if 0
2969 FILE *fp;
2970 if ((fp = fopen("ketama_keys.txt", "w")))
2971 {
2972 // noop
2973 } else {
2974 printf("cannot write to file ketama_keys.txt");
2975 return TEST_FAILURE;
2976 }
2977
2978 for (int x= 0; x < 10000; x++)
2979 {
2980 char key[10];
2981 sprintf(key, "%d", x);
2982
2983 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
2984 char *hostname = memc->hosts[server_idx].hostname;
2985 in_port_t port = memc->hosts[server_idx].port;
2986 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
2987 }
2988 fclose(fp);
2989 #endif
2990 memcached_server_list_free(server_pool);
2991 memcached_free(memc);
2992
2993 return TEST_SUCCESS;
2994 }
2995
2996
2997 static test_return_t result_static(memcached_st *memc)
2998 {
2999 memcached_result_st result;
3000 memcached_result_st *result_ptr;
3001
3002 result_ptr= memcached_result_create(memc, &result);
3003 test_true(result.options.is_allocated == false);
3004 test_true(memcached_is_initialized(&result) == true);
3005 test_true(result_ptr);
3006 test_true(result_ptr == &result);
3007
3008 memcached_result_free(&result);
3009
3010 test_true(result.options.is_allocated == false);
3011 test_true(memcached_is_initialized(&result) == false);
3012
3013 return TEST_SUCCESS;
3014 }
3015
3016 static test_return_t result_alloc(memcached_st *memc)
3017 {
3018 memcached_result_st *result_ptr;
3019
3020 result_ptr= memcached_result_create(memc, NULL);
3021 test_true(result_ptr);
3022 test_true(result_ptr->options.is_allocated == true);
3023 test_true(memcached_is_initialized(result_ptr) == true);
3024 memcached_result_free(result_ptr);
3025
3026 return TEST_SUCCESS;
3027 }
3028
3029 static test_return_t string_static_null(memcached_st *memc)
3030 {
3031 memcached_string_st string;
3032 memcached_string_st *string_ptr;
3033
3034 string_ptr= memcached_string_create(memc, &string, 0);
3035 test_true(string.options.is_initialized == true);
3036 test_true(string_ptr);
3037
3038 /* The following two better be the same! */
3039 test_true(memcached_is_allocated(string_ptr) == false);
3040 test_true(memcached_is_allocated(&string) == false);
3041 test_true(&string == string_ptr);
3042
3043 test_true(string.options.is_initialized == true);
3044 test_true(memcached_is_initialized(&string) == true);
3045 memcached_string_free(&string);
3046 test_true(memcached_is_initialized(&string) == false);
3047
3048 return TEST_SUCCESS;
3049 }
3050
3051 static test_return_t string_alloc_null(memcached_st *memc)
3052 {
3053 memcached_string_st *string;
3054
3055 string= memcached_string_create(memc, NULL, 0);
3056 test_true(string);
3057 test_true(memcached_is_allocated(string) == true);
3058 test_true(memcached_is_initialized(string) == true);
3059 memcached_string_free(string);
3060
3061 return TEST_SUCCESS;
3062 }
3063
3064 static test_return_t string_alloc_with_size(memcached_st *memc)
3065 {
3066 memcached_string_st *string;
3067
3068 string= memcached_string_create(memc, NULL, 1024);
3069 test_true(string);
3070 test_true(memcached_is_allocated(string) == true);
3071 test_true(memcached_is_initialized(string) == true);
3072 memcached_string_free(string);
3073
3074 return TEST_SUCCESS;
3075 }
3076
3077 static test_return_t string_alloc_with_size_toobig(memcached_st *memc)
3078 {
3079 memcached_string_st *string;
3080
3081 string= memcached_string_create(memc, NULL, SIZE_MAX);
3082 test_true(string == NULL);
3083
3084 return TEST_SUCCESS;
3085 }
3086
3087 static test_return_t string_alloc_append(memcached_st *memc)
3088 {
3089 unsigned int x;
3090 char buffer[SMALL_STRING_LEN];
3091 memcached_string_st *string;
3092
3093 /* Ring the bell! */
3094 memset(buffer, 6, SMALL_STRING_LEN);
3095
3096 string= memcached_string_create(memc, NULL, 100);
3097 test_true(string);
3098 test_true(memcached_is_allocated(string) == true);
3099 test_true(memcached_is_initialized(string) == true);
3100
3101 for (x= 0; x < 1024; x++)
3102 {
3103 memcached_return_t rc;
3104 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3105 test_true(rc == MEMCACHED_SUCCESS);
3106 }
3107 test_true(memcached_is_allocated(string) == true);
3108 memcached_string_free(string);
3109
3110 return TEST_SUCCESS;
3111 }
3112
3113 static test_return_t string_alloc_append_toobig(memcached_st *memc)
3114 {
3115 memcached_return_t rc;
3116 unsigned int x;
3117 char buffer[SMALL_STRING_LEN];
3118 memcached_string_st *string;
3119
3120 /* Ring the bell! */
3121 memset(buffer, 6, SMALL_STRING_LEN);
3122
3123 string= memcached_string_create(memc, NULL, 100);
3124 test_true(string);
3125 test_true(memcached_is_allocated(string) == true);
3126 test_true(memcached_is_initialized(string) == true);
3127
3128 for (x= 0; x < 1024; x++)
3129 {
3130 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3131 test_true(rc == MEMCACHED_SUCCESS);
3132 }
3133 rc= memcached_string_append(string, buffer, SIZE_MAX);
3134 test_true(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
3135 test_true(memcached_is_allocated(string) == true);
3136 memcached_string_free(string);
3137
3138 return TEST_SUCCESS;
3139 }
3140
3141 static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused)))
3142 {
3143 pairs_free(global_pairs);
3144
3145 return TEST_SUCCESS;
3146 }
3147
3148 static test_return_t generate_pairs(memcached_st *memc __attribute__((unused)))
3149 {
3150 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3151 global_count= GLOBAL_COUNT;
3152
3153 for (size_t x= 0; x < global_count; x++)
3154 {
3155 global_keys[x]= global_pairs[x].key;
3156 global_keys_length[x]= global_pairs[x].key_length;
3157 }
3158
3159 return TEST_SUCCESS;
3160 }
3161
3162 static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unused)))
3163 {
3164 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3165 global_count= GLOBAL2_COUNT;
3166
3167 for (size_t x= 0; x < global_count; x++)
3168 {
3169 global_keys[x]= global_pairs[x].key;
3170 global_keys_length[x]= global_pairs[x].key_length;
3171 }
3172
3173 return TEST_SUCCESS;
3174 }
3175
3176 static test_return_t generate_data(memcached_st *memc)
3177 {
3178 execute_set(memc, global_pairs, global_count);
3179
3180 return TEST_SUCCESS;
3181 }
3182
3183 static test_return_t generate_data_with_stats(memcached_st *memc)
3184 {
3185 memcached_stat_st *stat_p;
3186 memcached_return_t rc;
3187 uint32_t host_index= 0;
3188 execute_set(memc, global_pairs, global_count);
3189
3190 //TODO: hosts used size stats
3191 stat_p= memcached_stat(memc, NULL, &rc);
3192 test_true(stat_p);
3193
3194 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3195 {
3196 /* This test was changes so that "make test" would work properlly */
3197 #ifdef DEBUG
3198 memcached_server_instance_st *instance=
3199 memcached_server_instance_fetch(memc, host_index);
3200
3201 printf("\nserver %u|%s|%u bytes: %llu\n", host_index, instance->hostname, instance->port, (unsigned long long)(stat_p + host_index)->bytes);
3202 #endif
3203 test_true((unsigned long long)(stat_p + host_index)->bytes);
3204 }
3205
3206 memcached_stat_free(NULL, stat_p);
3207
3208 return TEST_SUCCESS;
3209 }
3210 static test_return_t generate_buffer_data(memcached_st *memc)
3211 {
3212 size_t latch= 0;
3213
3214 latch= 1;
3215 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3216 generate_data(memc);
3217
3218 return TEST_SUCCESS;
3219 }
3220
3221 static test_return_t get_read_count(memcached_st *memc)
3222 {
3223 memcached_return_t rc;
3224 memcached_st *memc_clone;
3225
3226 memc_clone= memcached_clone(NULL, memc);
3227 test_true(memc_clone);
3228
3229 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3230
3231 {
3232 char *return_value;
3233 size_t return_value_length;
3234 uint32_t flags;
3235 uint32_t count;
3236
3237 for (size_t x= count= 0; x < global_count; x++)
3238 {
3239 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3240 &return_value_length, &flags, &rc);
3241 if (rc == MEMCACHED_SUCCESS)
3242 {
3243 count++;
3244 if (return_value)
3245 free(return_value);
3246 }
3247 }
3248 }
3249
3250 memcached_free(memc_clone);
3251
3252 return TEST_SUCCESS;
3253 }
3254
3255 static test_return_t get_read(memcached_st *memc)
3256 {
3257 memcached_return_t rc;
3258
3259 {
3260 char *return_value;
3261 size_t return_value_length;
3262 uint32_t flags;
3263
3264 for (size_t x= 0; x < global_count; x++)
3265 {
3266 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3267 &return_value_length, &flags, &rc);
3268 /*
3269 test_true(return_value);
3270 test_true(rc == MEMCACHED_SUCCESS);
3271 */
3272 if (rc == MEMCACHED_SUCCESS && return_value)
3273 free(return_value);
3274 }
3275 }
3276
3277 return TEST_SUCCESS;
3278 }
3279
3280 static test_return_t mget_read(memcached_st *memc)
3281 {
3282 memcached_return_t rc;
3283
3284 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3285 test_true(rc == MEMCACHED_SUCCESS);
3286 test_true(fetch_all_results(memc) == TEST_SUCCESS);
3287
3288 return TEST_SUCCESS;
3289 }
3290
3291 static test_return_t mget_read_result(memcached_st *memc)
3292 {
3293 memcached_return_t rc;
3294
3295 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3296 test_true(rc == MEMCACHED_SUCCESS);
3297 /* Turn this into a help function */
3298 {
3299 memcached_result_st results_obj;
3300 memcached_result_st *results;
3301
3302 results= memcached_result_create(memc, &results_obj);
3303
3304 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3305 {
3306 test_true(results);
3307 test_true(rc == MEMCACHED_SUCCESS);
3308 }
3309
3310 memcached_result_free(&results_obj);
3311 }
3312
3313 return TEST_SUCCESS;
3314 }
3315
3316 static test_return_t mget_read_function(memcached_st *memc)
3317 {
3318 memcached_return_t rc;
3319 size_t counter;
3320 memcached_execute_fn callbacks[1];
3321
3322 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3323 test_true(rc == MEMCACHED_SUCCESS);
3324
3325 callbacks[0]= &callback_counter;
3326 counter= 0;
3327 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3328
3329 return TEST_SUCCESS;
3330 }
3331
3332 static test_return_t delete_generate(memcached_st *memc)
3333 {
3334 for (size_t x= 0; x < global_count; x++)
3335 {
3336 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3337 }
3338
3339 return TEST_SUCCESS;
3340 }
3341
3342 static test_return_t delete_buffer_generate(memcached_st *memc)
3343 {
3344 uint64_t latch= 0;
3345
3346 latch= 1;
3347 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3348
3349 for (size_t x= 0; x < global_count; x++)
3350 {
3351 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3352 }
3353
3354 return TEST_SUCCESS;
3355 }
3356
3357 static test_return_t add_host_test1(memcached_st *memc)
3358 {
3359 memcached_return_t rc;
3360 char servername[]= "0.example.com";
3361 memcached_server_st *servers;
3362
3363 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3364 test_true(servers);
3365 test_true(1 == memcached_server_list_count(servers));
3366
3367 for (size_t x= 2; x < 20; x++)
3368 {
3369 char buffer[SMALL_STRING_LEN];
3370
3371 snprintf(buffer, SMALL_STRING_LEN, "%zu.example.com", 400+x);
3372 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3373 &rc);
3374 test_true(rc == MEMCACHED_SUCCESS);
3375 test_true(x == memcached_server_list_count(servers));
3376 }
3377
3378 rc= memcached_server_push(memc, servers);
3379 test_true(rc == MEMCACHED_SUCCESS);
3380 rc= memcached_server_push(memc, servers);
3381 test_true(rc == MEMCACHED_SUCCESS);
3382
3383 memcached_server_list_free(servers);
3384
3385 return TEST_SUCCESS;
3386 }
3387
3388 static test_return_t pre_nonblock(memcached_st *memc)
3389 {
3390 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3391
3392 return TEST_SUCCESS;
3393 }
3394
3395 static test_return_t pre_cork(memcached_st *memc)
3396 {
3397 memcached_return_t rc;
3398 bool set= true;
3399 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
3400
3401 if (rc == MEMCACHED_SUCCESS)
3402 return TEST_SUCCESS;
3403
3404 return TEST_SKIPPED;
3405 }
3406
3407 static test_return_t pre_cork_and_nonblock(memcached_st *memc)
3408 {
3409 test_return_t rc;
3410
3411 rc= pre_cork(memc);
3412
3413 if (rc != TEST_SUCCESS)
3414 return rc;
3415
3416 return pre_nonblock(memc);
3417 }
3418
3419 static test_return_t pre_nonblock_binary(memcached_st *memc)
3420 {
3421 memcached_return_t rc= MEMCACHED_FAILURE;
3422 memcached_st *memc_clone;
3423 memcached_server_instance_st *instance;
3424
3425 memc_clone= memcached_clone(NULL, memc);
3426 test_true(memc_clone);
3427 // The memcached_version needs to be done on a clone, because the server
3428 // will not toggle protocol on an connection.
3429 memcached_version(memc_clone);
3430
3431 instance= memcached_server_instance_fetch(memc_clone, 0);
3432
3433 if (instance->major_version >= 1 && instance->minor_version > 2)
3434 {
3435 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3436 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3437 test_true(rc == MEMCACHED_SUCCESS);
3438 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3439 }
3440 else
3441 {
3442 return TEST_SKIPPED;
3443 }
3444
3445 memcached_free(memc_clone);
3446
3447 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3448 }
3449
3450 static test_return_t pre_murmur(memcached_st *memc)
3451 {
3452 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3453
3454 return TEST_SUCCESS;
3455 }
3456
3457 static test_return_t pre_jenkins(memcached_st *memc)
3458 {
3459 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3460
3461 return TEST_SUCCESS;
3462 }
3463
3464
3465 static test_return_t pre_md5(memcached_st *memc)
3466 {
3467 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3468
3469 return TEST_SUCCESS;
3470 }
3471
3472 static test_return_t pre_crc(memcached_st *memc)
3473 {
3474 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3475
3476 return TEST_SUCCESS;
3477 }
3478
3479 static test_return_t pre_hsieh(memcached_st *memc)
3480 {
3481 #ifdef HAVE_HSIEH_HASH
3482 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3483 return TEST_SUCCESS;
3484 #else
3485 (void) memc;
3486 return TEST_SKIPPED;
3487 #endif
3488 }
3489
3490 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3491 {
3492 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3493
3494 return TEST_SUCCESS;
3495 }
3496
3497 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3498 {
3499 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3500
3501 return TEST_SUCCESS;
3502 }
3503
3504 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3505 {
3506 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3507
3508 return TEST_SUCCESS;
3509 }
3510
3511 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3512 {
3513 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3514
3515 return TEST_SUCCESS;
3516 }
3517
3518 static test_return_t pre_behavior_ketama(memcached_st *memc)
3519 {
3520 memcached_return_t rc;
3521 uint64_t value;
3522
3523 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3524 test_true(rc == MEMCACHED_SUCCESS);
3525
3526 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3527 test_true(value == 1);
3528
3529 return TEST_SUCCESS;
3530 }
3531
3532 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3533 {
3534 memcached_return_t rc;
3535 uint64_t value;
3536
3537 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3538 test_true(rc == MEMCACHED_SUCCESS);
3539
3540 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3541 test_true(value == 1);
3542
3543 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3544 test_true(rc == MEMCACHED_SUCCESS);
3545
3546 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3547 test_true(value == MEMCACHED_HASH_MD5);
3548
3549 return TEST_SUCCESS;
3550 }
3551
3552 /**
3553 @note This should be testing to see if the server really supports the binary protocol.
3554 */
3555 static test_return_t pre_binary(memcached_st *memc)
3556 {
3557 memcached_return_t rc= MEMCACHED_FAILURE;
3558 memcached_st *memc_clone;
3559 memcached_server_instance_st *instance;
3560
3561 memc_clone= memcached_clone(NULL, memc);
3562 test_true(memc_clone);
3563 // The memcached_version needs to be done on a clone, because the server
3564 // will not toggle protocol on an connection.
3565 memcached_version(memc_clone);
3566
3567 instance= memcached_server_instance_fetch(memc_clone, 0);
3568
3569 if (instance->major_version >= 1 && instance->minor_version > 2)
3570 {
3571 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3572 test_true(rc == MEMCACHED_SUCCESS);
3573 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3574 }
3575
3576 memcached_free(memc_clone);
3577
3578 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3579 }
3580
3581
3582 static test_return_t pre_replication(memcached_st *memc)
3583 {
3584 test_return_t test_rc;
3585 test_rc= pre_binary(memc);
3586
3587 if (test_rc != TEST_SUCCESS)
3588 return test_rc;
3589
3590 /*
3591 * Make sure that we store the item on all servers
3592 * (master + replicas == number of servers)
3593 */
3594 memcached_return_t rc;
3595 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3596 memcached_server_count(memc) - 1);
3597 test_true(rc == MEMCACHED_SUCCESS);
3598 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memcached_server_count(memc) - 1);
3599
3600 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3601 }
3602
3603
3604 static test_return_t pre_replication_noblock(memcached_st *memc)
3605 {
3606 test_return_t rc;
3607
3608 rc= pre_replication(memc);
3609 if (rc != TEST_SUCCESS)
3610 return rc;
3611
3612 rc= pre_nonblock(memc);
3613
3614 return rc;
3615 }
3616
3617
3618 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3619 {
3620 #ifdef HARD_MALLOC_TESTS
3621 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3622 free(real_ptr);
3623 #else
3624 free(mem);
3625 #endif
3626 }
3627
3628
3629 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3630 {
3631 #ifdef HARD_MALLOC_TESTS
3632 void *ret= malloc(size + 8);
3633 if (ret != NULL)
3634 {
3635 ret= (void*)((caddr_t)ret + 8);
3636 }
3637 #else
3638 void *ret= malloc(size);
3639 #endif
3640
3641 if (ret != NULL)
3642 {
3643 memset(ret, 0xff, size);
3644 }
3645
3646 return ret;
3647 }
3648
3649
3650 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3651 {
3652 #ifdef HARD_MALLOC_TESTS
3653 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3654 void *nmem= realloc(real_ptr, size + 8);
3655
3656 void *ret= NULL;
3657 if (nmem != NULL)
3658 {
3659 ret= (void*)((caddr_t)nmem + 8);
3660 }
3661
3662 return ret;
3663 #else
3664 return realloc(mem, size);
3665 #endif
3666 }
3667
3668
3669 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3670 {
3671 #ifdef HARD_MALLOC_TESTS
3672 void *mem= my_malloc(ptr, nelem * size);
3673 if (mem)
3674 {
3675 memset(mem, 0, nelem * size);
3676 }
3677
3678 return mem;
3679 #else
3680 return calloc(nelem, size);
3681 #endif
3682 }
3683
3684
3685 static test_return_t set_prefix(memcached_st *memc)
3686 {
3687 memcached_return_t rc;
3688 const char *key= "mine";
3689 char *value;
3690
3691 /* Make sure be default none exists */
3692 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3693 test_true(rc == MEMCACHED_FAILURE);
3694
3695 /* Test a clean set */
3696 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3697 test_true(rc == MEMCACHED_SUCCESS);
3698
3699 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3700 test_true(memcmp(value, key, 4) == 0);
3701 test_true(rc == MEMCACHED_SUCCESS);
3702
3703 /* Test that we can turn it off */
3704 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3705 test_true(rc == MEMCACHED_SUCCESS);
3706
3707 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3708 test_true(rc == MEMCACHED_FAILURE);
3709
3710 /* Now setup for main test */
3711 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3712 test_true(rc == MEMCACHED_SUCCESS);
3713
3714 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3715 test_true(rc == MEMCACHED_SUCCESS);
3716 test_true(memcmp(value, key, 4) == 0);
3717
3718 /* Set to Zero, and then Set to something too large */
3719 {
3720 char long_key[255];
3721 memset(long_key, 0, 255);
3722
3723 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3724 test_true(rc == MEMCACHED_SUCCESS);
3725
3726 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3727 test_true(rc == MEMCACHED_FAILURE);
3728 test_true(value == NULL);
3729
3730 /* Test a long key for failure */
3731 /* TODO, extend test to determine based on setting, what result should be */
3732 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3733 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3734 //test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3735 test_true(rc == MEMCACHED_SUCCESS);
3736
3737 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3738 strcpy(long_key, "This is more then the allotted number of characters");
3739 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3740 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3741
3742 /* Test for a bad prefix, but with a short key */
3743 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3744 test_true(rc == MEMCACHED_SUCCESS);
3745
3746 strcpy(long_key, "dog cat");
3747 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3748 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3749 }
3750
3751 return TEST_SUCCESS;
3752 }
3753
3754
3755 #ifdef MEMCACHED_ENABLE_DEPRECATED
3756 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3757 {
3758 void *test_ptr= NULL;
3759 void *cb_ptr= NULL;
3760 {
3761 memcached_malloc_fn malloc_cb=
3762 (memcached_malloc_fn)my_malloc;
3763 cb_ptr= *(void **)&malloc_cb;
3764 memcached_return_t rc;
3765
3766 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3767 test_true(rc == MEMCACHED_SUCCESS);
3768 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3769 test_true(rc == MEMCACHED_SUCCESS);
3770 test_true(test_ptr == cb_ptr);
3771 }
3772
3773 {
3774 memcached_realloc_fn realloc_cb=
3775 (memcached_realloc_fn)my_realloc;
3776 cb_ptr= *(void **)&realloc_cb;
3777 memcached_return_t rc;
3778
3779 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3780 test_true(rc == MEMCACHED_SUCCESS);
3781 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3782 test_true(rc == MEMCACHED_SUCCESS);
3783 test_true(test_ptr == cb_ptr);
3784 }
3785
3786 {
3787 memcached_free_fn free_cb=
3788 (memcached_free_fn)my_free;
3789 cb_ptr= *(void **)&free_cb;
3790 memcached_return_t rc;
3791
3792 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3793 test_true(rc == MEMCACHED_SUCCESS);
3794 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3795 test_true(rc == MEMCACHED_SUCCESS);
3796 test_true(test_ptr == cb_ptr);
3797 }
3798
3799 return TEST_SUCCESS;
3800 }
3801 #endif
3802
3803
3804 static test_return_t set_memory_alloc(memcached_st *memc)
3805 {
3806 memcached_return_t rc;
3807 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3808 my_realloc, my_calloc);
3809 test_true(rc == MEMCACHED_FAILURE);
3810
3811 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3812 my_realloc, my_calloc);
3813
3814 memcached_malloc_fn mem_malloc;
3815 memcached_free_fn mem_free;
3816 memcached_realloc_fn mem_realloc;
3817 memcached_calloc_fn mem_calloc;
3818 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3819 &mem_realloc, &mem_calloc);
3820
3821 test_true(mem_malloc == my_malloc);
3822 test_true(mem_realloc == my_realloc);
3823 test_true(mem_calloc == my_calloc);
3824 test_true(mem_free == my_free);
3825
3826 return TEST_SUCCESS;
3827 }
3828
3829 static test_return_t enable_consistent_crc(memcached_st *memc)
3830 {
3831 test_return_t rc;
3832 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3833 memcached_hash_t hash;
3834 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3835 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3836 return rc;
3837
3838 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3839 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3840
3841 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3842
3843 if (hash != MEMCACHED_HASH_CRC)
3844 return TEST_SKIPPED;
3845
3846 return TEST_SUCCESS;
3847 }
3848
3849 static test_return_t enable_consistent_hsieh(memcached_st *memc)
3850 {
3851 test_return_t rc;
3852 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3853 memcached_hash_t hash;
3854 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3855 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3856 return rc;
3857
3858 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3859 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3860
3861 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3862
3863 if (hash != MEMCACHED_HASH_HSIEH)
3864 return TEST_SKIPPED;
3865
3866
3867 return TEST_SUCCESS;
3868 }
3869
3870 static test_return_t enable_cas(memcached_st *memc)
3871 {
3872 unsigned int set= 1;
3873
3874 memcached_server_instance_st *instance=
3875 memcached_server_instance_fetch(memc, 0);
3876
3877 memcached_version(memc);
3878
3879 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3880 || instance->minor_version > 2)
3881 {
3882 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3883
3884 return TEST_SUCCESS;
3885 }
3886
3887 return TEST_SKIPPED;
3888 }
3889
3890 static test_return_t check_for_1_2_3(memcached_st *memc)
3891 {
3892 memcached_version(memc);
3893 memcached_server_instance_st *instance=
3894 memcached_server_instance_fetch(memc, 0);
3895
3896 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3897 || instance->minor_version > 2)
3898 return TEST_SUCCESS;
3899
3900 return TEST_SKIPPED;
3901 }
3902
3903 static test_return_t pre_unix_socket(memcached_st *memc)
3904 {
3905 memcached_return_t rc;
3906 struct stat buf;
3907
3908 memcached_servers_reset(memc);
3909
3910 if (stat("/tmp/memcached.socket", &buf))
3911 return TEST_SKIPPED;
3912
3913 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3914
3915 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
3916 }
3917
3918 static test_return_t pre_nodelay(memcached_st *memc)
3919 {
3920 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3921 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3922
3923 return TEST_SUCCESS;
3924 }
3925
3926 static test_return_t pre_settimer(memcached_st *memc)
3927 {
3928 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3929 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3930
3931 return TEST_SUCCESS;
3932 }
3933
3934 static test_return_t poll_timeout(memcached_st *memc)
3935 {
3936 size_t timeout;
3937
3938 timeout= 100;
3939
3940 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3941
3942 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3943
3944 test_true(timeout == 100);
3945
3946 return TEST_SUCCESS;
3947 }
3948
3949 static test_return_t noreply_test(memcached_st *memc)
3950 {
3951 memcached_return_t ret;
3952 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3953 test_true(ret == MEMCACHED_SUCCESS);
3954 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3955 test_true(ret == MEMCACHED_SUCCESS);
3956 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3957 test_true(ret == MEMCACHED_SUCCESS);
3958 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3959 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3960 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3961
3962 for (int count=0; count < 5; ++count)
3963 {
3964 for (size_t x= 0; x < 100; ++x)
3965 {
3966 char key[10];
3967 size_t len= (size_t)sprintf(key, "%zu", x);
3968 switch (count)
3969 {
3970 case 0:
3971 ret= memcached_add(memc, key, len, key, len, 0, 0);
3972 break;
3973 case 1:
3974 ret= memcached_replace(memc, key, len, key, len, 0, 0);
3975 break;
3976 case 2:
3977 ret= memcached_set(memc, key, len, key, len, 0, 0);
3978 break;
3979 case 3:
3980 ret= memcached_append(memc, key, len, key, len, 0, 0);
3981 break;
3982 case 4:
3983 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
3984 break;
3985 default:
3986 test_true(count);
3987 break;
3988 }
3989 test_true(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3990 }
3991
3992 /*
3993 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3994 ** API and is _ONLY_ done this way to verify that the library works the
3995 ** way it is supposed to do!!!!
3996 */
3997 int no_msg=0;
3998 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
3999 {
4000 memcached_server_instance_st *instance=
4001 memcached_server_instance_fetch(memc, x);
4002 no_msg+=(int)(instance->cursor_active);
4003 }
4004
4005 test_true(no_msg == 0);
4006 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4007
4008 /*
4009 ** Now validate that all items was set properly!
4010 */
4011 for (size_t x= 0; x < 100; ++x)
4012 {
4013 char key[10];
4014
4015 size_t len= (size_t)sprintf(key, "%zu", x);
4016 size_t length;
4017 uint32_t flags;
4018 char* value=memcached_get(memc, key, strlen(key),
4019 &length, &flags, &ret);
4020 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4021 switch (count)
4022 {
4023 case 0: /* FALLTHROUGH */
4024 case 1: /* FALLTHROUGH */
4025 case 2:
4026 test_true(strncmp(value, key, len) == 0);
4027 test_true(len == length);
4028 break;
4029 case 3:
4030 test_true(length == len * 2);
4031 break;
4032 case 4:
4033 test_true(length == len * 3);
4034 break;
4035 default:
4036 test_true(count);
4037 break;
4038 }
4039 free(value);
4040 }
4041 }
4042
4043 /* Try setting an illegal cas value (should not return an error to
4044 * the caller (because we don't expect a return message from the server)
4045 */
4046 const char* keys[]= {"0"};
4047 size_t lengths[]= {1};
4048 size_t length;
4049 uint32_t flags;
4050 memcached_result_st results_obj;
4051 memcached_result_st *results;
4052 ret= memcached_mget(memc, keys, lengths, 1);
4053 test_true(ret == MEMCACHED_SUCCESS);
4054
4055 results= memcached_result_create(memc, &results_obj);
4056 test_true(results);
4057 results= memcached_fetch_result(memc, &results_obj, &ret);
4058 test_true(results);
4059 test_true(ret == MEMCACHED_SUCCESS);
4060 uint64_t cas= memcached_result_cas(results);
4061 memcached_result_free(&results_obj);
4062
4063 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4064 test_true(ret == MEMCACHED_SUCCESS);
4065
4066 /*
4067 * The item will have a new cas value, so try to set it again with the old
4068 * value. This should fail!
4069 */
4070 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4071 test_true(ret == MEMCACHED_SUCCESS);
4072 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4073 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4074 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4075 free(value);
4076
4077 return TEST_SUCCESS;
4078 }
4079
4080 static test_return_t analyzer_test(memcached_st *memc)
4081 {
4082 memcached_return_t rc;
4083 memcached_stat_st *memc_stat;
4084 memcached_analysis_st *report;
4085
4086 memc_stat= memcached_stat(memc, NULL, &rc);
4087 test_true(rc == MEMCACHED_SUCCESS);
4088 test_true(memc_stat);
4089
4090 report= memcached_analyze(memc, memc_stat, &rc);
4091 test_true(rc == MEMCACHED_SUCCESS);
4092 test_true(report);
4093
4094 free(report);
4095 memcached_stat_free(NULL, memc_stat);
4096
4097 return TEST_SUCCESS;
4098 }
4099
4100 /* Count the objects */
4101 static memcached_return_t callback_dump_counter(memcached_st *ptr __attribute__((unused)),
4102 const char *key __attribute__((unused)),
4103 size_t key_length __attribute__((unused)),
4104 void *context)
4105 {
4106 size_t *counter= (size_t *)context;
4107
4108 *counter= *counter + 1;
4109
4110 return MEMCACHED_SUCCESS;
4111 }
4112
4113 static test_return_t dump_test(memcached_st *memc)
4114 {
4115 memcached_return_t rc;
4116 size_t counter= 0;
4117 memcached_dump_fn callbacks[1];
4118 test_return_t main_rc;
4119
4120 callbacks[0]= &callback_dump_counter;
4121
4122 /* No support for Binary protocol yet */
4123 if (memc->flags.binary_protocol)
4124 return TEST_SUCCESS;
4125
4126 main_rc= set_test3(memc);
4127
4128 test_true (main_rc == TEST_SUCCESS);
4129
4130 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
4131 test_true(rc == MEMCACHED_SUCCESS);
4132
4133 /* We may have more then 32 if our previous flush has not completed */
4134 test_true(counter >= 32);
4135
4136 return TEST_SUCCESS;
4137 }
4138
4139 #ifdef HAVE_LIBMEMCACHEDUTIL
4140 static void* connection_release(void *arg)
4141 {
4142 struct {
4143 memcached_pool_st* pool;
4144 memcached_st* mmc;
4145 } *resource= arg;
4146
4147 usleep(250);
4148 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
4149 return arg;
4150 }
4151
4152 static test_return_t connection_pool_test(memcached_st *memc)
4153 {
4154 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
4155 test_true(pool != NULL);
4156 memcached_st* mmc[10];
4157 memcached_return_t rc;
4158
4159 for (size_t x= 0; x < 10; ++x)
4160 {
4161 mmc[x]= memcached_pool_pop(pool, false, &rc);
4162 test_true(mmc[x] != NULL);
4163 test_true(rc == MEMCACHED_SUCCESS);
4164 }
4165
4166 test_true(memcached_pool_pop(pool, false, &rc) == NULL);
4167 test_true(rc == MEMCACHED_SUCCESS);
4168
4169 pthread_t tid;
4170 struct {
4171 memcached_pool_st* pool;
4172 memcached_st* mmc;
4173 } item= { .pool = pool, .mmc = mmc[9] };
4174 pthread_create(&tid, NULL, connection_release, &item);
4175 mmc[9]= memcached_pool_pop(pool, true, &rc);
4176 test_true(rc == MEMCACHED_SUCCESS);
4177 pthread_join(tid, NULL);
4178 test_true(mmc[9] == item.mmc);
4179 const char *key= "key";
4180 size_t keylen= strlen(key);
4181
4182 // verify that I can do ops with all connections
4183 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
4184 test_true(rc == MEMCACHED_SUCCESS);
4185
4186 for (size_t x= 0; x < 10; ++x)
4187 {
4188 uint64_t number_value;
4189 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
4190 test_true(rc == MEMCACHED_SUCCESS);
4191 test_true(number_value == (x+1));
4192 }
4193
4194 // Release them..
4195 for (size_t x= 0; x < 10; ++x)
4196 {
4197 test_true(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
4198 }
4199
4200
4201 /* verify that I can set behaviors on the pool when I don't have all
4202 * of the connections in the pool. It should however be enabled
4203 * when I push the item into the pool
4204 */
4205 mmc[0]= memcached_pool_pop(pool, false, &rc);
4206 test_true(mmc[0] != NULL);
4207
4208 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4209 test_true(rc == MEMCACHED_SUCCESS);
4210
4211 mmc[1]= memcached_pool_pop(pool, false, &rc);
4212 test_true(mmc[1] != NULL);
4213
4214 test_true(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4215 test_true(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
4216 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4217
4218 mmc[0]= memcached_pool_pop(pool, false, &rc);
4219 test_true(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4220 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4221
4222
4223 test_true(memcached_pool_destroy(pool) == memc);
4224 return TEST_SUCCESS;
4225 }
4226 #endif
4227
4228 static test_return_t replication_set_test(memcached_st *memc)
4229 {
4230 memcached_return_t rc;
4231 memcached_st *memc_clone= memcached_clone(NULL, memc);
4232 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4233
4234 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
4235 test_true(rc == MEMCACHED_SUCCESS);
4236
4237 /*
4238 ** We are using the quiet commands to store the replicas, so we need
4239 ** to ensure that all of them are processed before we can continue.
4240 ** In the test we go directly from storing the object to trying to
4241 ** receive the object from all of the different servers, so we
4242 ** could end up in a race condition (the memcached server hasn't yet
4243 ** processed the quiet command from the replication set when it process
4244 ** the request from the other client (created by the clone)). As a
4245 ** workaround for that we call memcached_quit to send the quit command
4246 ** to the server and wait for the response ;-) If you use the test code
4247 ** as an example for your own code, please note that you shouldn't need
4248 ** to do this ;-)
4249 */
4250 memcached_quit(memc);
4251
4252 /*
4253 ** "bubba" should now be stored on all of our servers. We don't have an
4254 ** easy to use API to address each individual server, so I'll just iterate
4255 ** through a bunch of "master keys" and I should most likely hit all of the
4256 ** servers...
4257 */
4258 for (int x= 'a'; x <= 'z'; ++x)
4259 {
4260 char key[2]= { [0]= (char)x };
4261 size_t len;
4262 uint32_t flags;
4263 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4264 &len, &flags, &rc);
4265 test_true(rc == MEMCACHED_SUCCESS);
4266 test_true(val != NULL);
4267 free(val);
4268 }
4269
4270 memcached_free(memc_clone);
4271
4272 return TEST_SUCCESS;
4273 }
4274
4275 static test_return_t replication_get_test(memcached_st *memc)
4276 {
4277 memcached_return_t rc;
4278
4279 /*
4280 * Don't do the following in your code. I am abusing the internal details
4281 * within the library, and this is not a supported interface.
4282 * This is to verify correct behavior in the library
4283 */
4284 for (uint32_t host= 0; host < memcached_server_count(memc); ++host)
4285 {
4286 memcached_st *memc_clone= memcached_clone(NULL, memc);
4287 memcached_server_instance_st *instance=
4288 memcached_server_instance_fetch(memc_clone, host);
4289
4290 instance->port= 0;
4291
4292 for (int x= 'a'; x <= 'z'; ++x)
4293 {
4294 char key[2]= { [0]= (char)x };
4295 size_t len;
4296 uint32_t flags;
4297 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4298 &len, &flags, &rc);
4299 test_true(rc == MEMCACHED_SUCCESS);
4300 test_true(val != NULL);
4301 free(val);
4302 }
4303
4304 memcached_free(memc_clone);
4305 }
4306
4307 return TEST_SUCCESS;
4308 }
4309
4310 static test_return_t replication_mget_test(memcached_st *memc)
4311 {
4312 memcached_return_t rc;
4313 memcached_st *memc_clone= memcached_clone(NULL, memc);
4314 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4315
4316 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4317 size_t len[]= { 5, 4, 4, 4 };
4318
4319 for (size_t x= 0; x< 4; ++x)
4320 {
4321 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
4322 test_true(rc == MEMCACHED_SUCCESS);
4323 }
4324
4325 /*
4326 ** We are using the quiet commands to store the replicas, so we need
4327 ** to ensure that all of them are processed before we can continue.
4328 ** In the test we go directly from storing the object to trying to
4329 ** receive the object from all of the different servers, so we
4330 ** could end up in a race condition (the memcached server hasn't yet
4331 ** processed the quiet command from the replication set when it process
4332 ** the request from the other client (created by the clone)). As a
4333 ** workaround for that we call memcached_quit to send the quit command
4334 ** to the server and wait for the response ;-) If you use the test code
4335 ** as an example for your own code, please note that you shouldn't need
4336 ** to do this ;-)
4337 */
4338 memcached_quit(memc);
4339
4340 /*
4341 * Don't do the following in your code. I am abusing the internal details
4342 * within the library, and this is not a supported interface.
4343 * This is to verify correct behavior in the library
4344 */
4345 memcached_result_st result_obj;
4346 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
4347 {
4348 memcached_st *new_clone= memcached_clone(NULL, memc);
4349 memcached_server_instance_st *instance=
4350 memcached_server_instance_fetch(new_clone, host);
4351 instance->port= 0;
4352
4353 for (int x= 'a'; x <= 'z'; ++x)
4354 {
4355 char key[2]= { [0]= (char)x, [1]= 0 };
4356
4357 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
4358 test_true(rc == MEMCACHED_SUCCESS);
4359
4360 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
4361 test_true(results);
4362
4363 int hits= 0;
4364 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
4365 {
4366 hits++;
4367 }
4368 test_true(hits == 4);
4369 memcached_result_free(&result_obj);
4370 }
4371
4372 memcached_free(new_clone);
4373 }
4374
4375 memcached_free(memc_clone);
4376
4377 return TEST_SUCCESS;
4378 }
4379
4380 static test_return_t replication_randomize_mget_test(memcached_st *memc)
4381 {
4382 memcached_result_st result_obj;
4383 memcached_return_t rc;
4384 memcached_st *memc_clone= memcached_clone(NULL, memc);
4385 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3);
4386 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1);
4387
4388 const char *keys[]= { "key1", "key2", "key3", "key4", "key5", "key6", "key7" };
4389 size_t len[]= { 4, 4, 4, 4, 4, 4, 4 };
4390
4391 for (int x=0; x< 7; ++x)
4392 {
4393 rc= memcached_set(memc, keys[x], len[x], "1", 1, 0, 0);
4394 test_true(rc == MEMCACHED_SUCCESS);
4395 }
4396
4397 memcached_quit(memc);
4398
4399 for (size_t x= 0; x< 7; ++x)
4400 {
4401 const char key[2]= { [0]= (const char)x };
4402
4403 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 7);
4404 test_true(rc == MEMCACHED_SUCCESS);
4405
4406 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4407 test_true(results);
4408
4409 int hits= 0;
4410 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4411 {
4412 ++hits;
4413 }
4414 test_true(hits == 7);
4415 memcached_result_free(&result_obj);
4416 }
4417 memcached_free(memc_clone);
4418 return TEST_SUCCESS;
4419 }
4420
4421 static test_return_t replication_delete_test(memcached_st *memc)
4422 {
4423 memcached_return_t rc;
4424 memcached_st *memc_clone= memcached_clone(NULL, memc);
4425 /* Delete the items from all of the servers except 1 */
4426 uint64_t repl= memcached_behavior_get(memc,
4427 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
4428 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
4429
4430 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4431 size_t len[]= { 5, 4, 4, 4 };
4432
4433 for (size_t x= 0; x< 4; ++x)
4434 {
4435 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
4436 test_true(rc == MEMCACHED_SUCCESS);
4437 }
4438
4439 /*
4440 * Don't do the following in your code. I am abusing the internal details
4441 * within the library, and this is not a supported interface.
4442 * This is to verify correct behavior in the library
4443 */
4444 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
4445 for (uint32_t x= 0; x < (repl + 1); ++x)
4446 {
4447 memcached_server_instance_st *instance=
4448 memcached_server_instance_fetch(memc_clone, x);
4449
4450 instance->port= 0;
4451 if (++hash == memc_clone->number_of_hosts)
4452 hash= 0;
4453 }
4454
4455 memcached_result_st result_obj;
4456 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
4457 {
4458 for (size_t x= 'a'; x <= 'z'; ++x)
4459 {
4460 const char key[2]= { [0]= (const char)x };
4461
4462 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
4463 test_true(rc == MEMCACHED_SUCCESS);
4464
4465 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4466 test_true(results);
4467
4468 int hits= 0;
4469 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4470 {
4471 ++hits;
4472 }
4473 test_true(hits == 4);
4474 memcached_result_free(&result_obj);
4475 }
4476 }
4477 memcached_free(memc_clone);
4478
4479 return TEST_SUCCESS;
4480 }
4481
4482 static void increment_request_id(uint16_t *id)
4483 {
4484 (*id)++;
4485 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
4486 *id= 0;
4487 }
4488
4489 static uint16_t *get_udp_request_ids(memcached_st *memc)
4490 {
4491 uint16_t *ids= malloc(sizeof(uint16_t) * memcached_server_count(memc));
4492 assert(ids != NULL);
4493
4494 for (uint32_t x= 0; x < memcached_server_count(memc); x++)
4495 {
4496 memcached_server_instance_st *instance=
4497 memcached_server_instance_fetch(memc, x);
4498
4499 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) instance->write_buffer);
4500 }
4501
4502 return ids;
4503 }
4504
4505 static test_return_t post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
4506 {
4507 memcached_server_st *cur_server = memcached_server_list(memc);
4508 uint16_t *cur_req_ids = get_udp_request_ids(memc);
4509
4510 for (size_t x= 0; x < memcached_server_count(memc); x++)
4511 {
4512 test_true(cur_server[x].cursor_active == 0);
4513 test_true(cur_req_ids[x] == expected_req_ids[x]);
4514 }
4515 free(expected_req_ids);
4516 free(cur_req_ids);
4517
4518 return TEST_SUCCESS;
4519 }
4520
4521 /*
4522 ** There is a little bit of a hack here, instead of removing
4523 ** the servers, I just set num host to 0 and them add then new udp servers
4524 **/
4525 static test_return_t init_udp(memcached_st *memc)
4526 {
4527 memcached_version(memc);
4528 memcached_server_instance_st *instance=
4529 memcached_server_instance_fetch(memc, 0);
4530
4531 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
4532 if (instance->major_version != 1 || instance->minor_version != 2
4533 || instance->micro_version < 6)
4534 return TEST_SKIPPED;
4535
4536 uint32_t num_hosts= memcached_server_count(memc);
4537 memcached_server_st servers[num_hosts];
4538 memcpy(servers, memcached_server_list(memc), sizeof(memcached_server_st) * num_hosts);
4539 for (uint32_t x= 0; x < num_hosts; x++)
4540 {
4541 memcached_server_instance_st *set_instance=
4542 memcached_server_instance_fetch(memc, x);
4543
4544 memcached_server_free(set_instance);
4545 }
4546
4547 memc->number_of_hosts= 0;
4548 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
4549 for (uint32_t x= 0; x < num_hosts; x++)
4550 {
4551 memcached_server_instance_st *set_instance=
4552 memcached_server_instance_fetch(memc, x);
4553
4554 test_true(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
4555 test_true(set_instance->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4556 }
4557
4558 return TEST_SUCCESS;
4559 }
4560
4561 static test_return_t binary_init_udp(memcached_st *memc)
4562 {
4563 test_return_t test_rc;
4564 test_rc= pre_binary(memc);
4565
4566 if (test_rc != TEST_SUCCESS)
4567 return test_rc;
4568
4569 return init_udp(memc);
4570 }
4571
4572 /* Make sure that I cant add a tcp server to a udp client */
4573 static test_return_t add_tcp_server_udp_client_test(memcached_st *memc)
4574 {
4575 (void)memc;
4576 #if 0
4577 memcached_server_st server;
4578 memcached_server_instance_st *instance=
4579 memcached_server_instance_fetch(memc, 0);
4580 memcached_server_clone(&server, &memc->hosts[0]);
4581 test_true(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4582 test_true(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4583 #endif
4584 return TEST_SUCCESS;
4585 }
4586
4587 /* Make sure that I cant add a udp server to a tcp client */
4588 static test_return_t add_udp_server_tcp_client_test(memcached_st *memc)
4589 {
4590 (void)memc;
4591 #if 0
4592 memcached_server_st server;
4593 memcached_server_instance_st *instance=
4594 memcached_server_instance_fetch(memc, 0);
4595 memcached_server_clone(&server, &memc->hosts[0]);
4596 test_true(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4597
4598 memcached_st tcp_client;
4599 memcached_create(&tcp_client);
4600 test_true(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4601 #endif
4602
4603 return TEST_SUCCESS;
4604 }
4605
4606 static test_return_t set_udp_behavior_test(memcached_st *memc)
4607 {
4608
4609 memcached_quit(memc);
4610 memc->number_of_hosts= 0;
4611 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, memc->distribution);
4612 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
4613 test_true(memc->flags.use_udp);
4614 test_true(memc->flags.no_reply);
4615
4616 test_true(memcached_server_count(memc) == 0);
4617
4618 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
4619 test_true(! (memc->flags.use_udp));
4620 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
4621 test_true(! (memc->flags.no_reply));
4622
4623 return TEST_SUCCESS;
4624 }
4625
4626 static test_return_t udp_set_test(memcached_st *memc)
4627 {
4628 unsigned int num_iters= 1025; //request id rolls over at 1024
4629
4630 for (size_t x= 0; x < num_iters;x++)
4631 {
4632 memcached_return_t rc;
4633 const char *key= "foo";
4634 const char *value= "when we sanitize";
4635 uint16_t *expected_ids= get_udp_request_ids(memc);
4636 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4637 memcached_server_instance_st *instance=
4638 memcached_server_instance_fetch(memc, server_key);
4639 size_t init_offset= instance->write_buffer_offset;
4640
4641 rc= memcached_set(memc, key, strlen(key),
4642 value, strlen(value),
4643 (time_t)0, (uint32_t)0);
4644 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4645 /** NB, the check below assumes that if new write_ptr is less than
4646 * the original write_ptr that we have flushed. For large payloads, this
4647 * maybe an invalid assumption, but for the small payload we have it is OK
4648 */
4649 if (rc == MEMCACHED_SUCCESS ||
4650 instance->write_buffer_offset < init_offset)
4651 increment_request_id(&expected_ids[server_key]);
4652
4653 if (rc == MEMCACHED_SUCCESS)
4654 {
4655 test_true(instance->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4656 }
4657 else
4658 {
4659 test_true(instance->write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4660 test_true(instance->write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4661 }
4662 test_true(post_udp_op_check(memc, expected_ids) == TEST_SUCCESS);
4663 }
4664 return TEST_SUCCESS;
4665 }
4666
4667 static test_return_t udp_buffered_set_test(memcached_st *memc)
4668 {
4669 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4670 return udp_set_test(memc);
4671 }
4672
4673 static test_return_t udp_set_too_big_test(memcached_st *memc)
4674 {
4675 memcached_return_t rc;
4676 const char *key= "bar";
4677 char value[MAX_UDP_DATAGRAM_LENGTH];
4678 uint16_t *expected_ids= get_udp_request_ids(memc);
4679 rc= memcached_set(memc, key, strlen(key),
4680 value, MAX_UDP_DATAGRAM_LENGTH,
4681 (time_t)0, (uint32_t)0);
4682 test_true(rc == MEMCACHED_WRITE_FAILURE);
4683
4684 return post_udp_op_check(memc,expected_ids);
4685 }
4686
4687 static test_return_t udp_delete_test(memcached_st *memc)
4688 {
4689 unsigned int num_iters= 1025; //request id rolls over at 1024
4690
4691 for (size_t x= 0; x < num_iters;x++)
4692 {
4693 memcached_return_t rc;
4694 const char *key= "foo";
4695 uint16_t *expected_ids=get_udp_request_ids(memc);
4696 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4697 memcached_server_instance_st *instance=
4698 memcached_server_instance_fetch(memc, server_key);
4699 size_t init_offset= instance->write_buffer_offset;
4700
4701 rc= memcached_delete(memc, key, strlen(key), 0);
4702 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4703
4704 if (rc == MEMCACHED_SUCCESS || instance->write_buffer_offset < init_offset)
4705 increment_request_id(&expected_ids[server_key]);
4706 if (rc == MEMCACHED_SUCCESS)
4707 {
4708 test_true(instance->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4709 }
4710 else
4711 {
4712 test_true(instance->write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4713 test_true(instance->write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4714 }
4715 test_true(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4716 }
4717 return TEST_SUCCESS;
4718 }
4719
4720 static test_return_t udp_buffered_delete_test(memcached_st *memc)
4721 {
4722 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4723 return udp_delete_test(memc);
4724 }
4725
4726 static test_return_t udp_verbosity_test(memcached_st *memc)
4727 {
4728 memcached_return_t rc;
4729 uint16_t *expected_ids= get_udp_request_ids(memc);
4730
4731 for (size_t x= 0; x < memcached_server_count(memc); x++)
4732 {
4733 increment_request_id(&expected_ids[x]);
4734 }
4735
4736 rc= memcached_verbosity(memc,3);
4737 test_true(rc == MEMCACHED_SUCCESS);
4738 return post_udp_op_check(memc,expected_ids);
4739 }
4740
4741 static test_return_t udp_quit_test(memcached_st *memc)
4742 {
4743 uint16_t *expected_ids= get_udp_request_ids(memc);
4744 memcached_quit(memc);
4745 return post_udp_op_check(memc, expected_ids);
4746 }
4747
4748 static test_return_t udp_flush_test(memcached_st *memc)
4749 {
4750 memcached_return_t rc;
4751 uint16_t *expected_ids= get_udp_request_ids(memc);
4752
4753 for (size_t x= 0; x < memcached_server_count(memc); x++)
4754 {
4755 increment_request_id(&expected_ids[x]);
4756 }
4757
4758 rc= memcached_flush(memc,0);
4759 test_true(rc == MEMCACHED_SUCCESS);
4760 return post_udp_op_check(memc,expected_ids);
4761 }
4762
4763 static test_return_t udp_incr_test(memcached_st *memc)
4764 {
4765 memcached_return_t rc;
4766 const char *key= "incr";
4767 const char *value= "1";
4768 rc= memcached_set(memc, key, strlen(key),
4769 value, strlen(value),
4770 (time_t)0, (uint32_t)0);
4771
4772 test_true(rc == MEMCACHED_SUCCESS);
4773 uint16_t *expected_ids= get_udp_request_ids(memc);
4774 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4775 increment_request_id(&expected_ids[server_key]);
4776 uint64_t newvalue;
4777 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
4778 test_true(rc == MEMCACHED_SUCCESS);
4779 return post_udp_op_check(memc, expected_ids);
4780 }
4781
4782 static test_return_t udp_decr_test(memcached_st *memc)
4783 {
4784 memcached_return_t rc;
4785 const char *key= "decr";
4786 const char *value= "1";
4787 rc= memcached_set(memc, key, strlen(key),
4788 value, strlen(value),
4789 (time_t)0, (uint32_t)0);
4790
4791 test_true(rc == MEMCACHED_SUCCESS);
4792 uint16_t *expected_ids= get_udp_request_ids(memc);
4793 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4794 increment_request_id(&expected_ids[server_key]);
4795 uint64_t newvalue;
4796 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4797 test_true(rc == MEMCACHED_SUCCESS);
4798 return post_udp_op_check(memc, expected_ids);
4799 }
4800
4801
4802 static test_return_t udp_stat_test(memcached_st *memc)
4803 {
4804 memcached_stat_st * rv= NULL;
4805 memcached_return_t rc;
4806 char args[]= "";
4807 uint16_t *expected_ids = get_udp_request_ids(memc);
4808 rv = memcached_stat(memc, args, &rc);
4809 free(rv);
4810 test_true(rc == MEMCACHED_NOT_SUPPORTED);
4811 return post_udp_op_check(memc, expected_ids);
4812 }
4813
4814 static test_return_t udp_version_test(memcached_st *memc)
4815 {
4816 memcached_return_t rc;
4817 uint16_t *expected_ids = get_udp_request_ids(memc);
4818 rc = memcached_version(memc);
4819 test_true(rc == MEMCACHED_NOT_SUPPORTED);
4820 return post_udp_op_check(memc, expected_ids);
4821 }
4822
4823 static test_return_t udp_get_test(memcached_st *memc)
4824 {
4825 memcached_return_t rc;
4826 const char *key= "foo";
4827 size_t vlen;
4828 uint16_t *expected_ids = get_udp_request_ids(memc);
4829 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4830 test_true(rc == MEMCACHED_NOT_SUPPORTED);
4831 test_true(val == NULL);
4832 return post_udp_op_check(memc, expected_ids);
4833 }
4834
4835 static test_return_t udp_mixed_io_test(memcached_st *memc)
4836 {
4837 test_st current_op;
4838 test_st mixed_io_ops [] ={
4839 {"udp_set_test", 0,
4840 (test_callback_fn)udp_set_test},
4841 {"udp_set_too_big_test", 0,
4842 (test_callback_fn)udp_set_too_big_test},
4843 {"udp_delete_test", 0,
4844 (test_callback_fn)udp_delete_test},
4845 {"udp_verbosity_test", 0,
4846 (test_callback_fn)udp_verbosity_test},
4847 {"udp_quit_test", 0,
4848 (test_callback_fn)udp_quit_test},
4849 {"udp_flush_test", 0,
4850 (test_callback_fn)udp_flush_test},
4851 {"udp_incr_test", 0,
4852 (test_callback_fn)udp_incr_test},
4853 {"udp_decr_test", 0,
4854 (test_callback_fn)udp_decr_test},
4855 {"udp_version_test", 0,
4856 (test_callback_fn)udp_version_test}
4857 };
4858 for (size_t x= 0; x < 500; x++)
4859 {
4860 current_op= mixed_io_ops[random() % 9];
4861 test_true(current_op.test_fn(memc) == TEST_SUCCESS);
4862 }
4863 return TEST_SUCCESS;
4864 }
4865
4866 #if 0
4867 static test_return_t hash_sanity_test (memcached_st *memc)
4868 {
4869 (void)memc;
4870
4871 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4872 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4873 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4874 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4875 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4876 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4877 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4878 #ifdef HAVE_HSIEH_HASH
4879 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4880 #endif
4881 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4882 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4883 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4884
4885 return TEST_SUCCESS;
4886 }
4887 #endif
4888
4889 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4890 {
4891 memcached_return_t expected_rc= MEMCACHED_FAILURE;
4892 #ifdef HAVE_HSIEH_HASH
4893 expected_rc= MEMCACHED_SUCCESS;
4894 #endif
4895 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4896 (uint64_t)MEMCACHED_HASH_HSIEH);
4897 test_true(rc == expected_rc);
4898
4899 return TEST_SUCCESS;
4900 }
4901
4902 static test_return_t md5_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_MD5);
4912 test_true(md5_values[x] == hash_val);
4913 }
4914
4915 return TEST_SUCCESS;
4916 }
4917
4918 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4919 {
4920 uint32_t x;
4921 const char **ptr;
4922
4923 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4924 {
4925 uint32_t hash_val;
4926
4927 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4928 test_true(crc_values[x] == hash_val);
4929 }
4930
4931 return TEST_SUCCESS;
4932 }
4933
4934 static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
4935 {
4936 uint32_t x;
4937 const char **ptr;
4938
4939 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4940 {
4941 uint32_t hash_val;
4942
4943 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4944 test_true(fnv1_64_values[x] == hash_val);
4945 }
4946
4947 return TEST_SUCCESS;
4948 }
4949
4950 static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4951 {
4952 uint32_t x;
4953 const char **ptr;
4954
4955 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4956 {
4957 uint32_t hash_val;
4958
4959 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4960 test_true(fnv1a_64_values[x] == hash_val);
4961 }
4962
4963 return TEST_SUCCESS;
4964 }
4965
4966 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4967 {
4968 uint32_t x;
4969 const char **ptr;
4970
4971
4972 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4973 {
4974 uint32_t hash_val;
4975
4976 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4977 test_true(fnv1_32_values[x] == hash_val);
4978 }
4979
4980 return TEST_SUCCESS;
4981 }
4982
4983 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4984 {
4985 uint32_t x;
4986 const char **ptr;
4987
4988 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4989 {
4990 uint32_t hash_val;
4991
4992 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4993 test_true(fnv1a_32_values[x] == hash_val);
4994 }
4995
4996 return TEST_SUCCESS;
4997 }
4998
4999 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
5000 {
5001 uint32_t x;
5002 const char **ptr;
5003
5004 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
5005 {
5006 uint32_t hash_val;
5007
5008 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
5009 test_true(hsieh_values[x] == hash_val);
5010 }
5011
5012 return TEST_SUCCESS;
5013 }
5014
5015 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
5016 {
5017 #ifdef __sparc
5018 return TEST_SKIPPED;
5019 #else
5020 uint32_t x;
5021 const char **ptr;
5022
5023 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
5024 {
5025 uint32_t hash_val;
5026
5027 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
5028 test_true(murmur_values[x] == hash_val);
5029 }
5030
5031 return TEST_SUCCESS;
5032 #endif
5033 }
5034
5035 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
5036 {
5037 uint32_t x;
5038 const char **ptr;
5039
5040
5041 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
5042 {
5043 uint32_t hash_val;
5044
5045 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
5046 test_true(jenkins_values[x] == hash_val);
5047 }
5048
5049 return TEST_SUCCESS;
5050 }
5051
5052
5053 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
5054 {
5055 memcached_return_t rc;
5056 uint64_t value;
5057 int x;
5058 memcached_server_st *server_pool;
5059 memcached_st *memc;
5060
5061 (void)trash;
5062
5063 memc= memcached_create(NULL);
5064 test_true(memc);
5065
5066 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5067 test_true(rc == MEMCACHED_SUCCESS);
5068
5069 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5070 test_true(value == 1);
5071
5072 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
5073 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
5074
5075
5076 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");
5077 memcached_server_push(memc, server_pool);
5078
5079 /* verify that the server list was parsed okay. */
5080 test_true(memcached_server_count(memc) == 8);
5081 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5082 test_true(server_pool[0].port == 11211);
5083 test_true(server_pool[0].weight == 600);
5084 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5085 test_true(server_pool[2].port == 11211);
5086 test_true(server_pool[2].weight == 200);
5087 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5088 test_true(server_pool[7].port == 11211);
5089 test_true(server_pool[7].weight == 100);
5090
5091 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5092 * us test the boundary wraparound.
5093 */
5094 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5095
5096 /* verify the standard ketama set. */
5097 for (x= 0; x < 99; x++)
5098 {
5099 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
5100 memcached_server_instance_st *instance=
5101 memcached_server_instance_fetch(memc, server_idx);
5102 char *hostname = instance->hostname;
5103
5104 test_strcmp(hostname, ketama_test_cases[x].server);
5105 }
5106
5107 memcached_server_list_free(server_pool);
5108 memcached_free(memc);
5109
5110 return TEST_SUCCESS;
5111 }
5112
5113 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
5114 {
5115 memcached_return_t rc;
5116 uint64_t value;
5117 int x;
5118 memcached_server_st *server_pool;
5119 memcached_st *memc;
5120
5121 (void)trash;
5122
5123 memc= memcached_create(NULL);
5124 test_true(memc);
5125
5126 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5127 test_true(rc == MEMCACHED_SUCCESS);
5128
5129 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5130 test_true(value == 1);
5131
5132 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
5133 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
5134
5135 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");
5136 memcached_server_push(memc, server_pool);
5137
5138 /* verify that the server list was parsed okay. */
5139 test_true(memcached_server_count(memc) == 8);
5140 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5141 test_true(server_pool[0].port == 11211);
5142 test_true(server_pool[0].weight == 600);
5143 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5144 test_true(server_pool[2].port == 11211);
5145 test_true(server_pool[2].weight == 200);
5146 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5147 test_true(server_pool[7].port == 11211);
5148 test_true(server_pool[7].weight == 100);
5149
5150 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5151 * us test the boundary wraparound.
5152 */
5153 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5154
5155 /* verify the standard ketama set. */
5156 for (x= 0; x < 99; x++)
5157 {
5158 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5159 memcached_server_instance_st *instance=
5160 memcached_server_instance_fetch(memc, server_idx);
5161 char *hostname = instance->hostname;
5162 test_strcmp(hostname, ketama_test_cases_spy[x].server);
5163 }
5164
5165 memcached_server_list_free(server_pool);
5166 memcached_free(memc);
5167
5168 return TEST_SUCCESS;
5169 }
5170
5171 static test_return_t regression_bug_434484(memcached_st *memc)
5172 {
5173 test_return_t test_rc;
5174 test_rc= pre_binary(memc);
5175
5176 if (test_rc != TEST_SUCCESS)
5177 return test_rc;
5178
5179 memcached_return_t ret;
5180 const char *key= "regression_bug_434484";
5181 size_t keylen= strlen(key);
5182
5183 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5184 test_true(ret == MEMCACHED_NOTSTORED);
5185
5186 size_t size= 2048 * 1024;
5187 void *data= calloc(1, size);
5188 test_true(data != NULL);
5189 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5190 test_true(ret == MEMCACHED_E2BIG);
5191 free(data);
5192
5193 return TEST_SUCCESS;
5194 }
5195
5196 static test_return_t regression_bug_434843(memcached_st *memc)
5197 {
5198 test_return_t test_rc;
5199 test_rc= pre_binary(memc);
5200
5201 if (test_rc != TEST_SUCCESS)
5202 return test_rc;
5203
5204 memcached_return_t rc;
5205 size_t counter= 0;
5206 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5207
5208 /*
5209 * I only want to hit only _one_ server so I know the number of requests I'm
5210 * sending in the pipleine to the server. Let's try to do a multiget of
5211 * 1024 (that should satisfy most users don't you think?). Future versions
5212 * will include a mget_execute function call if you need a higher number.
5213 */
5214 uint32_t number_of_hosts= memcached_server_count(memc);
5215 memc->number_of_hosts= 1;
5216 const size_t max_keys= 1024;
5217 char **keys= calloc(max_keys, sizeof(char*));
5218 size_t *key_length=calloc(max_keys, sizeof(size_t));
5219
5220 for (size_t x= 0; x < max_keys; ++x)
5221 {
5222 char k[251];
5223
5224 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5225 keys[x]= strdup(k);
5226 test_true(keys[x] != NULL);
5227 }
5228
5229 /*
5230 * Run two times.. the first time we should have 100% cache miss,
5231 * and the second time we should have 100% cache hits
5232 */
5233 for (size_t y= 0; y < 2; y++)
5234 {
5235 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5236 test_true(rc == MEMCACHED_SUCCESS);
5237 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5238
5239 if (y == 0)
5240 {
5241 /* The first iteration should give me a 100% cache miss. verify that*/
5242 char blob[1024]= { 0 };
5243
5244 test_true(counter == 0);
5245
5246 for (size_t x= 0; x < max_keys; ++x)
5247 {
5248 rc= memcached_add(memc, keys[x], key_length[x],
5249 blob, sizeof(blob), 0, 0);
5250 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5251 }
5252 }
5253 else
5254 {
5255 /* Verify that we received all of the key/value pairs */
5256 test_true(counter == max_keys);
5257 }
5258 }
5259
5260 /* Release allocated resources */
5261 for (size_t x= 0; x < max_keys; ++x)
5262 {
5263 free(keys[x]);
5264 }
5265 free(keys);
5266 free(key_length);
5267
5268 memc->number_of_hosts= number_of_hosts;
5269
5270 return TEST_SUCCESS;
5271 }
5272
5273 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5274 {
5275 memcached_return_t rc;
5276 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5277 test_true(rc == MEMCACHED_SUCCESS);
5278
5279 return regression_bug_434843(memc);
5280 }
5281
5282 static test_return_t regression_bug_421108(memcached_st *memc)
5283 {
5284 memcached_return_t rc;
5285 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5286 test_true(rc == MEMCACHED_SUCCESS);
5287
5288 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5289 test_true(rc == MEMCACHED_SUCCESS);
5290 test_true(bytes != NULL);
5291 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5292 "bytes_read", &rc);
5293 test_true(rc == MEMCACHED_SUCCESS);
5294 test_true(bytes_read != NULL);
5295
5296 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5297 "bytes_written", &rc);
5298 test_true(rc == MEMCACHED_SUCCESS);
5299 test_true(bytes_written != NULL);
5300
5301 test_true(strcmp(bytes, bytes_read) != 0);
5302 test_true(strcmp(bytes, bytes_written) != 0);
5303
5304 /* Release allocated resources */
5305 free(bytes);
5306 free(bytes_read);
5307 free(bytes_written);
5308 memcached_stat_free(NULL, memc_stat);
5309
5310 return TEST_SUCCESS;
5311 }
5312
5313 /*
5314 * The test case isn't obvious so I should probably document why
5315 * it works the way it does. Bug 442914 was caused by a bug
5316 * in the logic in memcached_purge (it did not handle the case
5317 * where the number of bytes sent was equal to the watermark).
5318 * In this test case, create messages so that we hit that case
5319 * and then disable noreply mode and issue a new command to
5320 * verify that it isn't stuck. If we change the format for the
5321 * delete command or the watermarks, we need to update this
5322 * test....
5323 */
5324 static test_return_t regression_bug_442914(memcached_st *memc)
5325 {
5326 memcached_return_t rc;
5327 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5328 test_true(rc == MEMCACHED_SUCCESS);
5329 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5330
5331 uint32_t number_of_hosts= memcached_server_count(memc);
5332 memc->number_of_hosts= 1;
5333
5334 char k[250];
5335 size_t len;
5336
5337 for (uint32_t x= 0; x < 250; ++x)
5338 {
5339 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5340 rc= memcached_delete(memc, k, len, 0);
5341 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5342 }
5343
5344 (void)snprintf(k, sizeof(k), "%037u", 251U);
5345 len= strlen(k);
5346
5347 rc= memcached_delete(memc, k, len, 0);
5348 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5349
5350 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5351 test_true(rc == MEMCACHED_SUCCESS);
5352 rc= memcached_delete(memc, k, len, 0);
5353 test_true(rc == MEMCACHED_NOTFOUND);
5354
5355 memc->number_of_hosts= number_of_hosts;
5356
5357 return TEST_SUCCESS;
5358 }
5359
5360 static test_return_t regression_bug_447342(memcached_st *memc)
5361 {
5362 memcached_server_instance_st *instance_one;
5363 memcached_server_instance_st *instance_two;
5364
5365 if (memcached_server_count(memc) < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
5366 return TEST_SKIPPED;
5367
5368 memcached_return_t rc;
5369
5370 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5371 test_true(rc == MEMCACHED_SUCCESS);
5372
5373 const size_t max_keys= 100;
5374 char **keys= calloc(max_keys, sizeof(char*));
5375 size_t *key_length= calloc(max_keys, sizeof(size_t));
5376
5377 for (size_t x= 0; x < max_keys; ++x)
5378 {
5379 char k[251];
5380
5381 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5382 keys[x]= strdup(k);
5383 test_true(keys[x] != NULL);
5384 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5385 test_true(rc == MEMCACHED_SUCCESS);
5386 }
5387
5388 /*
5389 ** We are using the quiet commands to store the replicas, so we need
5390 ** to ensure that all of them are processed before we can continue.
5391 ** In the test we go directly from storing the object to trying to
5392 ** receive the object from all of the different servers, so we
5393 ** could end up in a race condition (the memcached server hasn't yet
5394 ** processed the quiet command from the replication set when it process
5395 ** the request from the other client (created by the clone)). As a
5396 ** workaround for that we call memcached_quit to send the quit command
5397 ** to the server and wait for the response ;-) If you use the test code
5398 ** as an example for your own code, please note that you shouldn't need
5399 ** to do this ;-)
5400 */
5401 memcached_quit(memc);
5402
5403 /* Verify that all messages are stored, and we didn't stuff too much
5404 * into the servers
5405 */
5406 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5407 test_true(rc == MEMCACHED_SUCCESS);
5408
5409 size_t counter= 0;
5410 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5411 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5412 /* Verify that we received all of the key/value pairs */
5413 test_true(counter == max_keys);
5414
5415 memcached_quit(memc);
5416 /*
5417 * Don't do the following in your code. I am abusing the internal details
5418 * within the library, and this is not a supported interface.
5419 * This is to verify correct behavior in the library. Fake that two servers
5420 * are dead..
5421 */
5422 instance_one= memcached_server_instance_fetch(memc, 0);
5423 instance_two= memcached_server_instance_fetch(memc, 2);
5424 in_port_t port0= instance_one->port;
5425 in_port_t port2= instance_two->port;
5426
5427 instance_one->port= 0;
5428 instance_two->port= 0;
5429
5430 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5431 test_true(rc == MEMCACHED_SUCCESS);
5432
5433 counter= 0;
5434 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5435 test_true(counter == (unsigned int)max_keys);
5436
5437 /* restore the memc handle */
5438 instance_one->port= port0;
5439 instance_two->port= port2;
5440
5441 memcached_quit(memc);
5442
5443 /* Remove half of the objects */
5444 for (size_t x= 0; x < max_keys; ++x)
5445 {
5446 if (x & 1)
5447 {
5448 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5449 test_true(rc == MEMCACHED_SUCCESS);
5450 }
5451 }
5452
5453 memcached_quit(memc);
5454 instance_one->port= 0;
5455 instance_two->port= 0;
5456
5457 /* now retry the command, this time we should have cache misses */
5458 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5459 test_true(rc == MEMCACHED_SUCCESS);
5460
5461 counter= 0;
5462 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5463 test_true(counter == (unsigned int)(max_keys >> 1));
5464
5465 /* Release allocated resources */
5466 for (size_t x= 0; x < max_keys; ++x)
5467 {
5468 free(keys[x]);
5469 }
5470 free(keys);
5471 free(key_length);
5472
5473 /* restore the memc handle */
5474 instance_one->port= port0;
5475 instance_two->port= port2;
5476
5477 return TEST_SUCCESS;
5478 }
5479
5480 static test_return_t regression_bug_463297(memcached_st *memc)
5481 {
5482 memcached_st *memc_clone= memcached_clone(NULL, memc);
5483 test_true(memc_clone != NULL);
5484 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5485
5486 memcached_server_instance_st *instance=
5487 memcached_server_instance_fetch(memc_clone, 0);
5488
5489 if (instance->major_version > 1 ||
5490 (instance->major_version == 1 &&
5491 instance->minor_version > 2))
5492 {
5493 /* Binary protocol doesn't support deferred delete */
5494 memcached_st *bin_clone= memcached_clone(NULL, memc);
5495 test_true(bin_clone != NULL);
5496 test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5497 test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5498 memcached_free(bin_clone);
5499
5500 memcached_quit(memc_clone);
5501
5502 /* If we know the server version, deferred delete should fail
5503 * with invalid arguments */
5504 test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5505
5506 /* If we don't know the server version, we should get a protocol error */
5507 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5508
5509 /* but there is a bug in some of the memcached servers (1.4) that treats
5510 * the counter as noreply so it doesn't send the proper error message
5511 */
5512 test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5513
5514 /* And buffered mode should be disabled and we should get protocol error */
5515 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5516 rc= memcached_delete(memc, "foo", 3, 1);
5517 test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5518
5519 /* Same goes for noreply... */
5520 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5521 rc= memcached_delete(memc, "foo", 3, 1);
5522 test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5523
5524 /* but a normal request should go through (and be buffered) */
5525 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5526 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5527
5528 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5529 /* unbuffered noreply should be success */
5530 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5531 /* unbuffered with reply should be not found... */
5532 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5533 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5534 }
5535
5536 memcached_free(memc_clone);
5537 return TEST_SUCCESS;
5538 }
5539
5540
5541 /* Test memcached_server_get_last_disconnect
5542 * For a working server set, shall be NULL
5543 * For a set of non existing server, shall not be NULL
5544 */
5545 static test_return_t test_get_last_disconnect(memcached_st *memc)
5546 {
5547 memcached_return_t rc;
5548 memcached_server_st *disconnected_server;
5549
5550 /* With the working set of server */
5551 const char *key= "marmotte";
5552 const char *value= "milka";
5553
5554 rc= memcached_set(memc, key, strlen(key),
5555 value, strlen(value),
5556 (time_t)0, (uint32_t)0);
5557 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5558
5559 disconnected_server = memcached_server_get_last_disconnect(memc);
5560 test_true(disconnected_server == NULL);
5561
5562 /* With a non existing server */
5563 memcached_st *mine;
5564 memcached_server_st *servers;
5565
5566 const char *server_list= "localhost:9";
5567
5568 servers= memcached_servers_parse(server_list);
5569 test_true(servers);
5570 mine= memcached_create(NULL);
5571 rc= memcached_server_push(mine, servers);
5572 test_true(rc == MEMCACHED_SUCCESS);
5573 memcached_server_list_free(servers);
5574 test_true(mine);
5575
5576 rc= memcached_set(mine, key, strlen(key),
5577 value, strlen(value),
5578 (time_t)0, (uint32_t)0);
5579 test_true(rc != MEMCACHED_SUCCESS);
5580
5581 disconnected_server = memcached_server_get_last_disconnect(mine);
5582 test_true(disconnected_server != NULL);
5583 test_true(disconnected_server->port == 9);
5584 test_true(strncmp(disconnected_server->hostname,"localhost",9) == 0);
5585
5586 memcached_quit(mine);
5587 memcached_free(mine);
5588
5589 return TEST_SUCCESS;
5590 }
5591
5592 /*
5593 * This test ensures that the failure counter isn't incremented during
5594 * normal termination of the memcached instance.
5595 */
5596 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5597 {
5598 memcached_return_t rc;
5599 memcached_server_instance_st *instance;
5600
5601 /* Set value to force connection to the server */
5602 const char *key= "marmotte";
5603 const char *value= "milka";
5604
5605 /*
5606 * Please note that I'm abusing the internal structures in libmemcached
5607 * in a non-portable way and you shouldn't be doing this. I'm only
5608 * doing this in order to verify that the library works the way it should
5609 */
5610 uint32_t number_of_hosts= memcached_server_count(memc);
5611 memc->number_of_hosts= 1;
5612
5613 /* Ensure that we are connected to the server by setting a value */
5614 rc= memcached_set(memc, key, strlen(key),
5615 value, strlen(value),
5616 (time_t)0, (uint32_t)0);
5617 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5618
5619
5620 instance= memcached_server_instance_fetch(memc, 0);
5621 /* The test is to see that the memcached_quit doesn't increase the
5622 * the server failure conter, so let's ensure that it is zero
5623 * before sending quit
5624 */
5625 instance->server_failure_counter= 0;
5626
5627 memcached_quit(memc);
5628
5629 /* Verify that it memcached_quit didn't increment the failure counter
5630 * Please note that this isn't bullet proof, because an error could
5631 * occur...
5632 */
5633 test_true(instance->server_failure_counter == 0);
5634
5635 /* restore the instance */
5636 memc->number_of_hosts= number_of_hosts;
5637
5638 return TEST_SUCCESS;
5639 }
5640
5641
5642
5643
5644 /*
5645 * Test that ensures mget_execute does not end into recursive calls that finally fails
5646 */
5647 static test_return_t regression_bug_490486(memcached_st *memc)
5648 {
5649 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5650 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
5651 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5652 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5653 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5654
5655 /*
5656 * I only want to hit _one_ server so I know the number of requests I'm
5657 * sending in the pipeline.
5658 */
5659 uint32_t number_of_hosts= memc->number_of_hosts;
5660 memc->number_of_hosts= 1;
5661 size_t max_keys= 20480;
5662
5663
5664 char **keys= calloc(max_keys, sizeof(char*));
5665 size_t *key_length=calloc(max_keys, sizeof(size_t));
5666
5667 /* First add all of the items.. */
5668 char blob[1024]= { 0 };
5669 memcached_return rc;
5670 for (size_t x= 0; x < max_keys; ++x)
5671 {
5672 char k[251];
5673 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5674 keys[x]= strdup(k);
5675 assert(keys[x] != NULL);
5676 rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5677 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5678 }
5679
5680 /* Try to get all of them with a large multiget */
5681 size_t counter= 0;
5682 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
5683 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
5684 (size_t)max_keys, callbacks, &counter, 1);
5685
5686 assert(rc == MEMCACHED_SUCCESS);
5687 char* the_value= NULL;
5688 char the_key[MEMCACHED_MAX_KEY];
5689 size_t the_key_length;
5690 size_t the_value_length;
5691 uint32_t the_flags;
5692
5693 do {
5694 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
5695
5696 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
5697 {
5698 ++counter;
5699 free(the_value);
5700 }
5701
5702 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
5703
5704
5705 assert(rc == MEMCACHED_END);
5706
5707 /* Verify that we got all of the items */
5708 assert(counter == max_keys);
5709
5710 /* Release all allocated resources */
5711 for (size_t x= 0; x < max_keys; ++x)
5712 {
5713 free(keys[x]);
5714 }
5715 free(keys);
5716 free(key_length);
5717
5718 memc->number_of_hosts= number_of_hosts;
5719
5720 return TEST_SUCCESS;
5721 }
5722
5723
5724
5725
5726 test_st udp_setup_server_tests[] ={
5727 {"set_udp_behavior_test", 0, (test_callback_fn)set_udp_behavior_test},
5728 {"add_tcp_server_udp_client_test", 0, (test_callback_fn)add_tcp_server_udp_client_test},
5729 {"add_udp_server_tcp_client_test", 0, (test_callback_fn)add_udp_server_tcp_client_test},
5730 {0, 0, 0}
5731 };
5732
5733 test_st upd_io_tests[] ={
5734 {"udp_set_test", 0, (test_callback_fn)udp_set_test},
5735 {"udp_buffered_set_test", 0, (test_callback_fn)udp_buffered_set_test},
5736 {"udp_set_too_big_test", 0, (test_callback_fn)udp_set_too_big_test},
5737 {"udp_delete_test", 0, (test_callback_fn)udp_delete_test},
5738 {"udp_buffered_delete_test", 0, (test_callback_fn)udp_buffered_delete_test},
5739 {"udp_verbosity_test", 0, (test_callback_fn)udp_verbosity_test},
5740 {"udp_quit_test", 0, (test_callback_fn)udp_quit_test},
5741 {"udp_flush_test", 0, (test_callback_fn)udp_flush_test},
5742 {"udp_incr_test", 0, (test_callback_fn)udp_incr_test},
5743 {"udp_decr_test", 0, (test_callback_fn)udp_decr_test},
5744 {"udp_stat_test", 0, (test_callback_fn)udp_stat_test},
5745 {"udp_version_test", 0, (test_callback_fn)udp_version_test},
5746 {"udp_get_test", 0, (test_callback_fn)udp_get_test},
5747 {"udp_mixed_io_test", 0, (test_callback_fn)udp_mixed_io_test},
5748 {0, 0, 0}
5749 };
5750
5751 /* Clean the server before beginning testing */
5752 test_st tests[] ={
5753 {"flush", 0, (test_callback_fn)flush_test },
5754 {"init", 0, (test_callback_fn)init_test },
5755 {"allocation", 0, (test_callback_fn)allocation_test },
5756 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
5757 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
5758 {"server_sort", 0, (test_callback_fn)server_sort_test},
5759 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
5760 {"clone_test", 0, (test_callback_fn)clone_test },
5761 {"connection_test", 0, (test_callback_fn)connection_test},
5762 {"callback_test", 0, (test_callback_fn)callback_test},
5763 {"userdata_test", 0, (test_callback_fn)userdata_test},
5764 {"error", 0, (test_callback_fn)error_test },
5765 {"set", 0, (test_callback_fn)set_test },
5766 {"set2", 0, (test_callback_fn)set_test2 },
5767 {"set3", 0, (test_callback_fn)set_test3 },
5768 {"dump", 1, (test_callback_fn)dump_test},
5769 {"add", 1, (test_callback_fn)add_test },
5770 {"replace", 1, (test_callback_fn)replace_test },
5771 {"delete", 1, (test_callback_fn)delete_test },
5772 {"get", 1, (test_callback_fn)get_test },
5773 {"get2", 0, (test_callback_fn)get_test2 },
5774 {"get3", 0, (test_callback_fn)get_test3 },
5775 {"get4", 0, (test_callback_fn)get_test4 },
5776 {"partial mget", 0, (test_callback_fn)get_test5 },
5777 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
5778 {"increment", 0, (test_callback_fn)increment_test },
5779 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
5780 {"decrement", 0, (test_callback_fn)decrement_test },
5781 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
5782 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
5783 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
5784 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
5785 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
5786 {"quit", 0, (test_callback_fn)quit_test },
5787 {"mget", 1, (test_callback_fn)mget_test },
5788 {"mget_result", 1, (test_callback_fn)mget_result_test },
5789 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
5790 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
5791 {"mget_execute", 1, (test_callback_fn)mget_execute },
5792 {"mget_end", 0, (test_callback_fn)mget_end },
5793 {"get_stats", 0, (test_callback_fn)get_stats },
5794 {"add_host_test", 0, (test_callback_fn)add_host_test },
5795 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
5796 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
5797 {"version_string_test", 0, (test_callback_fn)version_string_test},
5798 {"bad_key", 1, (test_callback_fn)bad_key_test },
5799 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
5800 {"read_through", 1, (test_callback_fn)read_through },
5801 {"delete_through", 1, (test_callback_fn)delete_through },
5802 {"noreply", 1, (test_callback_fn)noreply_test},
5803 {"analyzer", 1, (test_callback_fn)analyzer_test},
5804 #ifdef HAVE_LIBMEMCACHEDUTIL
5805 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
5806 #endif
5807 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
5808 {0, 0, 0}
5809 };
5810
5811 test_st behavior_tests[] ={
5812 {"behavior_test", 0, (test_callback_fn)behavior_test},
5813 {"MEMCACHED_BEHAVIOR_CORK", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_CORK_test},
5814 {0, 0, 0}
5815 };
5816
5817 test_st async_tests[] ={
5818 {"add", 1, (test_callback_fn)add_wrapper },
5819 {0, 0, 0}
5820 };
5821
5822 test_st string_tests[] ={
5823 {"string static with null", 0, (test_callback_fn)string_static_null },
5824 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
5825 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
5826 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
5827 {"string append", 0, (test_callback_fn)string_alloc_append },
5828 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
5829 {0, 0, (test_callback_fn)0}
5830 };
5831
5832 test_st result_tests[] ={
5833 {"result static", 0, (test_callback_fn)result_static},
5834 {"result alloc", 0, (test_callback_fn)result_alloc},
5835 {0, 0, (test_callback_fn)0}
5836 };
5837
5838 test_st version_1_2_3[] ={
5839 {"append", 0, (test_callback_fn)append_test },
5840 {"prepend", 0, (test_callback_fn)prepend_test },
5841 {"cas", 0, (test_callback_fn)cas_test },
5842 {"cas2", 0, (test_callback_fn)cas2_test },
5843 {"append_binary", 0, (test_callback_fn)append_binary_test },
5844 {0, 0, (test_callback_fn)0}
5845 };
5846
5847 test_st user_tests[] ={
5848 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
5849 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
5850 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
5851 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
5852 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
5853 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
5854 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
5855 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
5856 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
5857 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
5858 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
5859 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
5860 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
5861 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
5862 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
5863 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
5864 #ifndef __sun
5865 /*
5866 ** It seems to be something weird with the character sets..
5867 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
5868 ** guess I need to find out how this is supposed to work.. Perhaps I need
5869 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
5870 ** so just disable the code for now...).
5871 */
5872 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
5873 #endif
5874 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
5875 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
5876 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
5877 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
5878 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
5879 {0, 0, (test_callback_fn)0}
5880 };
5881
5882 test_st replication_tests[]= {
5883 {"set", 1, (test_callback_fn)replication_set_test },
5884 {"get", 0, (test_callback_fn)replication_get_test },
5885 {"mget", 0, (test_callback_fn)replication_mget_test },
5886 {"delete", 0, (test_callback_fn)replication_delete_test },
5887 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
5888 {0, 0, (test_callback_fn)0}
5889 };
5890
5891 /*
5892 * The following test suite is used to verify that we don't introduce
5893 * regression bugs. If you want more information about the bug / test,
5894 * you should look in the bug report at
5895 * http://bugs.launchpad.net/libmemcached
5896 */
5897 test_st regression_tests[]= {
5898 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
5899 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
5900 {"lp:434843 buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
5901 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
5902 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
5903 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
5904 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
5905 {"lp:490486", 1, (test_callback_fn)regression_bug_490486 },
5906 {0, 0, (test_callback_fn)0}
5907 };
5908
5909 test_st ketama_compatibility[]= {
5910 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
5911 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
5912 {0, 0, (test_callback_fn)0}
5913 };
5914
5915 test_st generate_tests[] ={
5916 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5917 {"generate_data", 1, (test_callback_fn)generate_data },
5918 {"get_read", 0, (test_callback_fn)get_read },
5919 {"delete_generate", 0, (test_callback_fn)delete_generate },
5920 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5921 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
5922 {"generate_data", 1, (test_callback_fn)generate_data },
5923 {"mget_read", 0, (test_callback_fn)mget_read },
5924 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
5925 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
5926 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5927 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
5928 {"generate_data", 1, (test_callback_fn)generate_data },
5929 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5930 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5931 {0, 0, (test_callback_fn)0}
5932 };
5933
5934 test_st consistent_tests[] ={
5935 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5936 {"generate_data", 1, (test_callback_fn)generate_data },
5937 {"get_read", 0, (test_callback_fn)get_read_count },
5938 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5939 {0, 0, (test_callback_fn)0}
5940 };
5941
5942 test_st consistent_weighted_tests[] ={
5943 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5944 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
5945 {"get_read", 0, (test_callback_fn)get_read_count },
5946 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5947 {0, 0, (test_callback_fn)0}
5948 };
5949
5950 test_st hsieh_availability[] ={
5951 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
5952 {0, 0, (test_callback_fn)0}
5953 };
5954
5955 #if 0
5956 test_st hash_sanity[] ={
5957 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
5958 {0, 0, (test_callback_fn)0}
5959 };
5960 #endif
5961
5962 test_st ketama_auto_eject_hosts[] ={
5963 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
5964 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
5965 {0, 0, (test_callback_fn)0}
5966 };
5967
5968 test_st hash_tests[] ={
5969 {"md5", 0, (test_callback_fn)md5_run },
5970 {"crc", 0, (test_callback_fn)crc_run },
5971 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
5972 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
5973 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
5974 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
5975 {"hsieh", 0, (test_callback_fn)hsieh_run },
5976 {"murmur", 0, (test_callback_fn)murmur_run },
5977 {"jenkis", 0, (test_callback_fn)jenkins_run },
5978 {0, 0, (test_callback_fn)0}
5979 };
5980
5981 collection_st collection[] ={
5982 #if 0
5983 {"hash_sanity", 0, 0, hash_sanity},
5984 #endif
5985 {"hsieh_availability", 0, 0, hsieh_availability},
5986 {"udp_setup", (test_callback_fn)init_udp, 0, udp_setup_server_tests},
5987 {"udp_io", (test_callback_fn)init_udp, 0, upd_io_tests},
5988 {"udp_binary_io", (test_callback_fn)binary_init_udp, 0, upd_io_tests},
5989 {"block", 0, 0, tests},
5990 {"binary", (test_callback_fn)pre_binary, 0, tests},
5991 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
5992 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5993 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
5994 {"md5", (test_callback_fn)pre_md5, 0, tests},
5995 {"crc", (test_callback_fn)pre_crc, 0, tests},
5996 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
5997 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
5998 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
5999 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
6000 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
6001 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
6002 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
6003 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
6004 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
6005 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6006 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
6007 {"gets", (test_callback_fn)enable_cas, 0, tests},
6008 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
6009 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
6010 #ifdef MEMCACHED_ENABLE_DEPRECATED
6011 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
6012 #endif
6013 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
6014 {"prefix", (test_callback_fn)set_prefix, 0, tests},
6015 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
6016 {"string", 0, 0, string_tests},
6017 {"result", 0, 0, result_tests},
6018 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
6019 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
6020 {"user", 0, 0, user_tests},
6021 {"generate", 0, 0, generate_tests},
6022 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
6023 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
6024 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
6025 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
6026 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
6027 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
6028 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
6029 // Too slow
6030 {"generate_corked", (test_callback_fn)pre_cork, 0, generate_tests},
6031 {"generate_corked_and_nonblock", (test_callback_fn)pre_cork_and_nonblock, 0, generate_tests},
6032 {"consistent_not", 0, 0, consistent_tests},
6033 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
6034 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
6035 {"ketama_compat", 0, 0, ketama_compatibility},
6036 {"test_hashes", 0, 0, hash_tests},
6037 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
6038 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
6039 {"regression", 0, 0, regression_tests},
6040 {"behaviors", 0, 0, behavior_tests},
6041 {0, 0, 0, 0}
6042 };
6043
6044 #define SERVERS_TO_CREATE 5
6045
6046 #include "libmemcached_world.h"
6047
6048 void get_world(world_st *world)
6049 {
6050 world->collections= collection;
6051
6052 world->create= (test_callback_create_fn)world_create;
6053 world->destroy= (test_callback_fn)world_destroy;
6054
6055 world->test.startup= (test_callback_fn)world_test_startup;
6056 world->test.flush= (test_callback_fn)world_flush;
6057 world->test.pre_run= (test_callback_fn)world_pre_run;
6058 world->test.post_run= (test_callback_fn)world_post_run;
6059 world->test.on_error= (test_callback_error_fn)world_on_error;
6060
6061 world->collection.startup= (test_callback_fn)world_container_startup;
6062 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
6063
6064 world->runner= &defualt_libmemcached_runner;
6065 }