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