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