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