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