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