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