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