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