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