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