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