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