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