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