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