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