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