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