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