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