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