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