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