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