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