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