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