Fixes condition where we were not correctly setting weighted vs not.
[m6w6/libmemcached] / tests / libmemcached-1.0 / 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 #if defined(HAVE_LIBUUID) && HAVE_LIBUUID
42 #include <uuid/uuid.h>
43 #endif
44
45 /*
46 Test cases
47 */
48
49 #include <libmemcached-1.0/memcached.h>
50 #include <libmemcached/is.h>
51 #include <libmemcached/server_instance.h>
52
53 #include <libhashkit-1.0/hashkit.h>
54
55 #include <cerrno>
56 #include <memory>
57 #include <pthread.h>
58 #include <semaphore.h>
59 #include <signal.h>
60 #include <sys/stat.h>
61 #include <sys/time.h>
62 #include <sys/types.h>
63 #include <unistd.h>
64
65 #include <iostream>
66
67 #include <libtest/server.h>
68
69 #include "clients/generator.h"
70
71 #define SMALL_STRING_LEN 1024
72
73 #include <libtest/test.hpp>
74
75 using namespace libtest;
76
77 #include <libmemcached/util.h>
78
79 #include "tests/hash_results.h"
80
81 #include "tests/libmemcached-1.0/callback_counter.h"
82 #include "tests/libmemcached-1.0/fetch_all_results.h"
83 #include "tests/libmemcached-1.0/mem_functions.h"
84 #include "tests/libmemcached-1.0/setup_and_teardowns.h"
85 #include "tests/print.h"
86 #include "tests/debug.h"
87
88 #define UUID_STRING_MAXLENGTH 36
89
90 #include "tests/keys.hpp"
91
92 static memcached_st * create_single_instance_memcached(const memcached_st *original_memc, const char *options)
93 {
94 /*
95 If no options are given, copy over at least the binary flag.
96 */
97 char options_buffer[1024]= { 0 };
98 if (options == NULL)
99 {
100 if (memcached_is_binary(original_memc))
101 {
102 snprintf(options_buffer, sizeof(options_buffer), "--BINARY");
103 }
104 }
105
106 /*
107 * I only want to hit _one_ server so I know the number of requests I'm
108 * sending in the pipeline.
109 */
110 memcached_server_instance_st instance= memcached_server_instance_by_position(original_memc, 0);
111
112 char server_string[1024];
113 int server_string_length;
114 if (instance->type == MEMCACHED_CONNECTION_UNIX_SOCKET)
115 {
116 if (options)
117 {
118 server_string_length= snprintf(server_string, sizeof(server_string), "--SOCKET=\"%s\" %s",
119 memcached_server_name(instance), options);
120 }
121 else
122 {
123 server_string_length= snprintf(server_string, sizeof(server_string), "--SOCKET=\"%s\"",
124 memcached_server_name(instance));
125 }
126 }
127 else
128 {
129 if (options)
130 {
131 server_string_length= snprintf(server_string, sizeof(server_string), "--server=%s:%d %s",
132 memcached_server_name(instance), int(memcached_server_port(instance)),
133 options);
134 }
135 else
136 {
137 server_string_length= snprintf(server_string, sizeof(server_string), "--server=%s:%d",
138 memcached_server_name(instance), int(memcached_server_port(instance)));
139 }
140 }
141
142 if (server_string_length <= 0)
143 {
144 return NULL;
145 }
146
147 char errror_buffer[1024];
148 if (memcached_failed(libmemcached_check_configuration(server_string, server_string_length, errror_buffer, sizeof(errror_buffer))))
149 {
150 Error << "Failed to parse (" << server_string << ") " << errror_buffer;
151 return NULL;
152 }
153
154 return memcached(server_string, server_string_length);
155 }
156
157
158 test_return_t init_test(memcached_st *not_used)
159 {
160 memcached_st memc;
161 (void)not_used;
162
163 (void)memcached_create(&memc);
164 memcached_free(&memc);
165
166 return TEST_SUCCESS;
167 }
168
169 #define TEST_PORT_COUNT 7
170 in_port_t test_ports[TEST_PORT_COUNT];
171
172 static memcached_return_t server_display_function(const memcached_st *ptr,
173 const memcached_server_st *server,
174 void *context)
175 {
176 /* Do Nothing */
177 size_t bigger= *((size_t *)(context));
178 (void)ptr;
179 fatal_assert(bigger <= memcached_server_port(server));
180 *((size_t *)(context))= memcached_server_port(server);
181
182 return MEMCACHED_SUCCESS;
183 }
184
185 static memcached_return_t dump_server_information(const memcached_st *ptr,
186 const memcached_server_st *instance,
187 void *context)
188 {
189 /* Do Nothing */
190 FILE *stream= (FILE *)context;
191 (void)ptr;
192
193 fprintf(stream, "Memcached Server: %s %u Version %u.%u.%u\n",
194 memcached_server_name(instance),
195 memcached_server_port(instance),
196 instance->major_version,
197 instance->minor_version,
198 instance->micro_version);
199
200 return MEMCACHED_SUCCESS;
201 }
202
203 test_return_t server_sort_test(memcached_st *ptr)
204 {
205 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
206
207 memcached_return_t rc;
208 memcached_server_fn callbacks[1];
209 memcached_st *local_memc;
210 (void)ptr;
211
212 local_memc= memcached_create(NULL);
213 test_true(local_memc);
214 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
215
216 for (uint32_t x= 0; x < TEST_PORT_COUNT; x++)
217 {
218 test_ports[x]= (in_port_t)random() % 64000;
219 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
220 test_compare(memcached_server_count(local_memc), x +1);
221 #if 0 // Rewrite
222 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
223 #endif
224 test_compare(MEMCACHED_SUCCESS, rc);
225 }
226
227 callbacks[0]= server_display_function;
228 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
229
230
231 memcached_free(local_memc);
232
233 return TEST_SUCCESS;
234 }
235
236 test_return_t server_sort2_test(memcached_st *ptr)
237 {
238 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
239 memcached_server_fn callbacks[1];
240 memcached_st *local_memc;
241 memcached_server_instance_st instance;
242 (void)ptr;
243
244 local_memc= memcached_create(NULL);
245 test_true(local_memc);
246 test_compare(MEMCACHED_SUCCESS,
247 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1));
248
249 test_compare(MEMCACHED_SUCCESS,
250 memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43043, 0));
251 instance= memcached_server_instance_by_position(local_memc, 0);
252 test_compare(in_port_t(43043), memcached_server_port(instance));
253
254 test_compare(MEMCACHED_SUCCESS,
255 memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43042, 0));
256
257 instance= memcached_server_instance_by_position(local_memc, 0);
258 test_compare(in_port_t(43042), memcached_server_port(instance));
259
260 instance= memcached_server_instance_by_position(local_memc, 1);
261 test_compare(in_port_t(43043), memcached_server_port(instance));
262
263 callbacks[0]= server_display_function;
264 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
265
266
267 memcached_free(local_memc);
268
269 return TEST_SUCCESS;
270 }
271
272 test_return_t memcached_server_remove_test(memcached_st*)
273 {
274 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";
275 char buffer[BUFSIZ];
276
277 test_compare(MEMCACHED_SUCCESS,
278 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
279 memcached_st *memc= memcached(server_string, strlen(server_string));
280 test_true(memc);
281
282 memcached_server_fn callbacks[1];
283 callbacks[0]= server_print_callback;
284 memcached_server_cursor(memc, callbacks, NULL, 1);
285
286 memcached_free(memc);
287
288 return TEST_SUCCESS;
289 }
290
291 static memcached_return_t server_display_unsort_function(const memcached_st*,
292 const memcached_server_st *server,
293 void *context)
294 {
295 /* Do Nothing */
296 uint32_t x= *((uint32_t *)(context));
297
298 if (! (test_ports[x] == server->port))
299 {
300 fprintf(stderr, "%lu -> %lu\n", (unsigned long)test_ports[x], (unsigned long)server->port);
301 return MEMCACHED_FAILURE;
302 }
303
304 *((uint32_t *)(context))= ++x;
305
306 return MEMCACHED_SUCCESS;
307 }
308
309 test_return_t server_unsort_test(memcached_st *ptr)
310 {
311 size_t counter= 0; /* Prime the value for the test_true in server_display_function */
312 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
313 memcached_server_fn callbacks[1];
314 memcached_st *local_memc;
315 (void)ptr;
316
317 local_memc= memcached_create(NULL);
318 test_true(local_memc);
319
320 for (uint32_t x= 0; x < TEST_PORT_COUNT; x++)
321 {
322 test_ports[x]= (in_port_t)(random() % 64000);
323 test_compare(MEMCACHED_SUCCESS,
324 memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0));
325 test_compare(memcached_server_count(local_memc), x +1);
326 #if 0 // Rewrite
327 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
328 #endif
329 }
330
331 callbacks[0]= server_display_unsort_function;
332 memcached_server_cursor(local_memc, callbacks, (void *)&counter, 1);
333
334 /* Now we sort old data! */
335 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
336 callbacks[0]= server_display_function;
337 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
338
339
340 memcached_free(local_memc);
341
342 return TEST_SUCCESS;
343 }
344
345 test_return_t allocation_test(memcached_st *not_used)
346 {
347 (void)not_used;
348 memcached_st *memc;
349 memc= memcached_create(NULL);
350 test_true(memc);
351 memcached_free(memc);
352
353 return TEST_SUCCESS;
354 }
355
356 test_return_t clone_test(memcached_st *memc)
357 {
358 /* All null? */
359 {
360 memcached_st *memc_clone;
361 memc_clone= memcached_clone(NULL, NULL);
362 test_true(memc_clone);
363 memcached_free(memc_clone);
364 }
365
366 /* Can we init from null? */
367 {
368 memcached_st *memc_clone;
369 memc_clone= memcached_clone(NULL, memc);
370 test_true(memc_clone);
371
372 { // Test allocators
373 test_true(memc_clone->allocators.free == memc->allocators.free);
374 test_true(memc_clone->allocators.malloc == memc->allocators.malloc);
375 test_true(memc_clone->allocators.realloc == memc->allocators.realloc);
376 test_true(memc_clone->allocators.calloc == memc->allocators.calloc);
377 }
378
379 test_true(memc_clone->connect_timeout == memc->connect_timeout);
380 test_true(memc_clone->delete_trigger == memc->delete_trigger);
381 test_true(memc_clone->distribution == memc->distribution);
382 { // Test all of the flags
383 test_true(memc_clone->flags.no_block == memc->flags.no_block);
384 test_true(memc_clone->flags.tcp_nodelay == memc->flags.tcp_nodelay);
385 test_true(memc_clone->flags.support_cas == memc->flags.support_cas);
386 test_true(memc_clone->flags.buffer_requests == memc->flags.buffer_requests);
387 test_true(memc_clone->flags.use_sort_hosts == memc->flags.use_sort_hosts);
388 test_true(memc_clone->flags.verify_key == memc->flags.verify_key);
389 test_true(memc_clone->ketama.weighted == memc->ketama.weighted);
390 test_true(memc_clone->flags.binary_protocol == memc->flags.binary_protocol);
391 test_true(memc_clone->flags.hash_with_namespace == memc->flags.hash_with_namespace);
392 test_true(memc_clone->flags.reply == memc->flags.reply);
393 test_true(memc_clone->flags.use_udp == memc->flags.use_udp);
394 test_true(memc_clone->flags.auto_eject_hosts == memc->flags.auto_eject_hosts);
395 test_true(memc_clone->flags.randomize_replica_read == memc->flags.randomize_replica_read);
396 }
397 test_true(memc_clone->get_key_failure == memc->get_key_failure);
398 test_true(hashkit_compare(&memc_clone->hashkit, &memc->hashkit));
399 test_true(memc_clone->io_bytes_watermark == memc->io_bytes_watermark);
400 test_true(memc_clone->io_msg_watermark == memc->io_msg_watermark);
401 test_true(memc_clone->io_key_prefetch == memc->io_key_prefetch);
402 test_true(memc_clone->on_cleanup == memc->on_cleanup);
403 test_true(memc_clone->on_clone == memc->on_clone);
404 test_true(memc_clone->poll_timeout == memc->poll_timeout);
405 test_true(memc_clone->rcv_timeout == memc->rcv_timeout);
406 test_true(memc_clone->recv_size == memc->recv_size);
407 test_true(memc_clone->retry_timeout == memc->retry_timeout);
408 test_true(memc_clone->send_size == memc->send_size);
409 test_true(memc_clone->server_failure_limit == memc->server_failure_limit);
410 test_true(memc_clone->snd_timeout == memc->snd_timeout);
411 test_true(memc_clone->user_data == memc->user_data);
412
413 memcached_free(memc_clone);
414 }
415
416 /* Can we init from struct? */
417 {
418 memcached_st declared_clone;
419 memcached_st *memc_clone;
420 memset(&declared_clone, 0 , sizeof(memcached_st));
421 memc_clone= memcached_clone(&declared_clone, NULL);
422 test_true(memc_clone);
423 memcached_free(memc_clone);
424 }
425
426 /* Can we init from struct? */
427 {
428 memcached_st declared_clone;
429 memcached_st *memc_clone;
430 memset(&declared_clone, 0 , sizeof(memcached_st));
431 memc_clone= memcached_clone(&declared_clone, memc);
432 test_true(memc_clone);
433 memcached_free(memc_clone);
434 }
435
436 return TEST_SUCCESS;
437 }
438
439 test_return_t userdata_test(memcached_st *memc)
440 {
441 void* foo= NULL;
442 test_false(memcached_set_user_data(memc, foo));
443 test_true(memcached_get_user_data(memc) == foo);
444 test_true(memcached_set_user_data(memc, NULL) == foo);
445
446 return TEST_SUCCESS;
447 }
448
449 test_return_t connection_test(memcached_st *memc)
450 {
451 test_compare(MEMCACHED_SUCCESS,
452 memcached_server_add_with_weight(memc, "localhost", 0, 0));
453
454 return TEST_SUCCESS;
455 }
456
457 test_return_t libmemcached_string_behavior_test(memcached_st *)
458 {
459 for (int x= MEMCACHED_BEHAVIOR_NO_BLOCK; x < int(MEMCACHED_BEHAVIOR_MAX); ++x)
460 {
461 test_true(libmemcached_string_behavior(memcached_behavior_t(x)));
462 }
463 test_compare(37, int(MEMCACHED_BEHAVIOR_MAX));
464
465 return TEST_SUCCESS;
466 }
467
468 test_return_t libmemcached_string_distribution_test(memcached_st *)
469 {
470 for (int x= MEMCACHED_DISTRIBUTION_MODULA; x < int(MEMCACHED_DISTRIBUTION_CONSISTENT_MAX); ++x)
471 {
472 test_true(libmemcached_string_distribution(memcached_server_distribution_t(x)));
473 }
474 test_compare(7, int(MEMCACHED_DISTRIBUTION_CONSISTENT_MAX));
475
476 return TEST_SUCCESS;
477 }
478
479 test_return_t memcached_return_t_TEST(memcached_st *memc)
480 {
481 uint32_t values[] = { 851992627U, 2337886783U, 4109241422U, 4001849190U,
482 982370485U, 1263635348U, 4242906218U, 3829656100U,
483 1891735253U, 334139633U, 2257084983U, 3351789013U,
484 13199785U, 2542027183U, 1097051614U, 199566778U,
485 2748246961U, 2465192557U, 1664094137U, 2405439045U,
486 1842224848U, 692413798U, 3479807801U, 919913813U,
487 4269430871U, 610793021U, 527273862U, 1437122909U,
488 2300930706U, 2943759320U, 674306647U, 2400528935U,
489 54481931U, 4186304426U, 1741088401U, 2979625118U,
490 4159057246U, 3425930182U, 2593724503U, 1868899624U,
491 1769812374U, 2302537950U, 1110330676U, 3365377466U,
492 1336171666U, 3021258493U, 2334992265U, 3861994737U,
493 3582734124U, 3365377466U };
494
495 // You have updated the memcache_error messages but not updated docs/tests.
496 for (int rc= int(MEMCACHED_SUCCESS); rc < int(MEMCACHED_MAXIMUM_RETURN); ++rc)
497 {
498 uint32_t hash_val;
499 const char *msg= memcached_strerror(memc, memcached_return_t(rc));
500 hash_val= memcached_generate_hash_value(msg, strlen(msg),
501 MEMCACHED_HASH_JENKINS);
502 if (values[rc] != hash_val)
503 {
504 fprintf(stderr, "\n\nYou have updated memcached_return_t without updating the memcached_return_t_TEST\n");
505 fprintf(stderr, "%u, %s, (%u)\n\n", (uint32_t)rc, memcached_strerror(memc, memcached_return_t(rc)), hash_val);
506 }
507 test_compare(values[rc], hash_val);
508 }
509 test_compare(49, int(MEMCACHED_MAXIMUM_RETURN));
510
511 return TEST_SUCCESS;
512 }
513
514 test_return_t set_test(memcached_st *memc)
515 {
516 memcached_return_t rc= memcached_set(memc,
517 test_literal_param("foo"),
518 test_literal_param("when we sanitize"),
519 time_t(0), (uint32_t)0);
520 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_last_error_message(memc));
521
522 return TEST_SUCCESS;
523 }
524
525 test_return_t append_test(memcached_st *memc)
526 {
527 memcached_return_t rc;
528 const char *in_value= "we";
529 size_t value_length;
530 uint32_t flags;
531
532 test_compare(MEMCACHED_SUCCESS,
533 memcached_flush(memc, 0));
534
535 test_compare(MEMCACHED_SUCCESS,
536 memcached_set(memc,
537 test_literal_param(__func__),
538 in_value, strlen(in_value),
539 time_t(0), uint32_t(0)));
540
541 test_compare(MEMCACHED_SUCCESS,
542 memcached_append(memc,
543 test_literal_param(__func__),
544 " the", strlen(" the"),
545 time_t(0), uint32_t(0)));
546
547 test_compare(MEMCACHED_SUCCESS,
548 memcached_append(memc,
549 test_literal_param(__func__),
550 " people", strlen(" people"),
551 time_t(0), uint32_t(0)));
552
553 char *out_value= memcached_get(memc,
554 test_literal_param(__func__),
555 &value_length, &flags, &rc);
556 test_memcmp(out_value, "we the people", strlen("we the people"));
557 test_compare(strlen("we the people"), value_length);
558 test_compare(MEMCACHED_SUCCESS, rc);
559 free(out_value);
560
561 return TEST_SUCCESS;
562 }
563
564 test_return_t append_binary_test(memcached_st *memc)
565 {
566 uint32_t store_list[] = { 23, 56, 499, 98, 32847, 0 };
567
568 test_compare(MEMCACHED_SUCCESS,
569 memcached_flush(memc, 0));
570
571 test_compare(MEMCACHED_SUCCESS,
572 memcached_set(memc,
573 test_literal_param(__func__),
574 NULL, 0,
575 time_t(0), uint32_t(0)));
576
577 size_t count= 0;
578 for (uint32_t x= 0; store_list[x] ; x++)
579 {
580 test_compare(MEMCACHED_SUCCESS,
581 memcached_append(memc,
582 test_literal_param(__func__),
583 (char *)&store_list[x], sizeof(uint32_t),
584 time_t(0), uint32_t(0)));
585 count++;
586 }
587
588 size_t value_length;
589 uint32_t flags;
590 memcached_return_t rc;
591 uint32_t *value= (uint32_t *)memcached_get(memc,
592 test_literal_param(__func__),
593 &value_length, &flags, &rc);
594 test_compare(value_length, sizeof(uint32_t) * count);
595 test_compare(MEMCACHED_SUCCESS, rc);
596
597 for (uint32_t counter= count, *ptr= value; counter; counter--)
598 {
599 test_compare(*ptr, store_list[count - counter]);
600 ptr++;
601 }
602 free(value);
603
604 return TEST_SUCCESS;
605 }
606
607 test_return_t memcached_mget_mixed_memcached_get_TEST(memcached_st *memc)
608 {
609 keys_st keys(200);
610
611 for (libtest::vchar_ptr_t::iterator iter= keys.begin();
612 iter != keys.end();
613 iter++)
614 {
615 test_compare_hint(MEMCACHED_SUCCESS,
616 memcached_set(memc,
617 (*iter), 36,
618 NULL, 0,
619 time_t(0), uint32_t(0)),
620 memcached_last_error_message(memc));
621 }
622
623 for (ptrdiff_t loop= 0; loop < 20; loop++)
624 {
625 if (random() %2)
626 {
627 test_compare(MEMCACHED_SUCCESS,
628 memcached_mget(memc, keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
629
630 memcached_result_st *results= memcached_result_create(memc, NULL);
631 test_true(results);
632
633 size_t result_count= 0;
634 memcached_return_t rc;
635 while (memcached_fetch_result(memc, results, &rc))
636 {
637 result_count++;
638 }
639 test_true(keys.size() >= result_count);
640 }
641 else
642 {
643 int which_key= random() %keys.size();
644 size_t value_length;
645 uint32_t flags;
646 memcached_return_t rc;
647 char *out_value= memcached_get(memc, keys.key_at(which_key), keys.length_at(which_key),
648 &value_length, &flags, &rc);
649 if (rc == MEMCACHED_NOTFOUND)
650 { } // It is possible that the value has been purged.
651 else
652 {
653 test_compare_hint(MEMCACHED_SUCCESS, rc, memcached_last_error_message(memc));
654 }
655 test_null(out_value);
656 test_zero(value_length);
657 test_zero(flags);
658 }
659 }
660
661 return TEST_SUCCESS;
662 }
663
664 test_return_t cas2_test(memcached_st *memc)
665 {
666 const char *keys[]= {"fudge", "son", "food"};
667 size_t key_length[]= {5, 3, 4};
668 const char *value= "we the people";
669 size_t value_length= strlen("we the people");
670
671 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
672
673 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
674
675 for (uint32_t x= 0; x < 3; x++)
676 {
677 test_compare(MEMCACHED_SUCCESS,
678 memcached_set(memc, keys[x], key_length[x],
679 keys[x], key_length[x],
680 time_t(50), uint32_t(9)));
681 }
682
683 test_compare(MEMCACHED_SUCCESS,
684 memcached_mget(memc, keys, key_length, 3));
685
686 memcached_result_st *results= memcached_result_create(memc, NULL);
687 test_true(results);
688
689 memcached_return_t rc;
690 results= memcached_fetch_result(memc, results, &rc);
691 test_true(results);
692 test_true(results->item_cas);
693 test_compare(MEMCACHED_SUCCESS, rc);
694 test_true(memcached_result_cas(results));
695
696 test_memcmp(value, "we the people", strlen("we the people"));
697 test_compare(strlen("we the people"), value_length);
698 test_compare(MEMCACHED_SUCCESS, rc);
699
700 memcached_result_free(results);
701
702 return TEST_SUCCESS;
703 }
704
705 test_return_t cas_test(memcached_st *memc)
706 {
707 const char* keys[2] = { __func__, NULL };
708 size_t keylengths[2] = { strlen(__func__), 0 };
709
710 memcached_result_st results_obj;
711
712 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
713
714 test_skip(true, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
715
716 test_compare(MEMCACHED_SUCCESS,
717 memcached_set(memc,
718 test_literal_param(__func__),
719 test_literal_param("we the people"),
720 (time_t)0, (uint32_t)0));
721
722 test_compare(MEMCACHED_SUCCESS,
723 memcached_mget(memc, keys, keylengths, 1));
724
725 memcached_result_st *results= memcached_result_create(memc, &results_obj);
726 test_true(results);
727
728 memcached_return_t rc;
729 results= memcached_fetch_result(memc, &results_obj, &rc);
730 test_true(results);
731 test_compare(MEMCACHED_SUCCESS, rc);
732 test_true(memcached_result_cas(results));
733 test_memcmp("we the people", memcached_result_value(results), test_literal_param_size("we the people"));
734 test_compare(test_literal_param_size("we the people"),
735 strlen(memcached_result_value(results)));
736
737 uint64_t cas= memcached_result_cas(results);
738
739 #if 0
740 results= memcached_fetch_result(memc, &results_obj, &rc);
741 test_true(rc == MEMCACHED_END);
742 test_true(results == NULL);
743 #endif
744
745 test_compare(MEMCACHED_SUCCESS,
746 memcached_cas(memc,
747 test_literal_param(__func__),
748 test_literal_param("change the value"),
749 0, 0, cas));
750
751 /*
752 * The item will have a new cas value, so try to set it again with the old
753 * value. This should fail!
754 */
755 test_compare(MEMCACHED_DATA_EXISTS,
756 memcached_cas(memc,
757 test_literal_param(__func__),
758 test_literal_param("change the value"),
759 0, 0, cas));
760
761 memcached_result_free(&results_obj);
762
763 return TEST_SUCCESS;
764 }
765
766
767 test_return_t prepend_test(memcached_st *memc)
768 {
769 const char *key= "fig";
770 const char *value= "people";
771
772 test_compare(MEMCACHED_SUCCESS,
773 memcached_flush(memc, 0));
774
775 test_compare(MEMCACHED_SUCCESS,
776 memcached_set(memc, key, strlen(key),
777 value, strlen(value),
778 time_t(0), uint32_t(0)));
779
780 test_compare(MEMCACHED_SUCCESS,
781 memcached_prepend(memc, key, strlen(key),
782 "the ", strlen("the "),
783 time_t(0), uint32_t(0)));
784
785 test_compare(MEMCACHED_SUCCESS,
786 memcached_prepend(memc, key, strlen(key),
787 "we ", strlen("we "),
788 time_t(0), uint32_t(0)));
789
790 size_t value_length;
791 uint32_t flags;
792 memcached_return_t rc;
793 char *out_value= memcached_get(memc, key, strlen(key),
794 &value_length, &flags, &rc);
795 test_memcmp(out_value, "we the people", strlen("we the people"));
796 test_compare(strlen("we the people"), value_length);
797 test_compare(MEMCACHED_SUCCESS, rc);
798 free(out_value);
799
800 return TEST_SUCCESS;
801 }
802
803 /*
804 Set the value, then quit to make sure it is flushed.
805 Come back in and test that add fails.
806 */
807 test_return_t memcached_add_SUCCESS_TEST(memcached_st *memc)
808 {
809 memcached_return_t rc;
810 test_null(memcached_get(memc, test_literal_param(__func__), NULL, NULL, &rc));
811 test_compare(MEMCACHED_NOTFOUND, rc);
812
813 test_compare(MEMCACHED_SUCCESS,
814 memcached_add(memc,
815 test_literal_param(__func__),
816 test_literal_param("try something else"),
817 time_t(0), uint32_t(0)));
818
819 return TEST_SUCCESS;
820 }
821
822 /*
823 Set the value, then quit to make sure it is flushed.
824 Come back in and test that add fails.
825 */
826 test_return_t add_test(memcached_st *memc)
827 {
828 test_compare(return_value_based_on_buffering(memc),
829 memcached_set(memc,
830 test_literal_param(__func__),
831 test_literal_param("when we sanitize"),
832 time_t(0), uint32_t(0)));
833
834 memcached_quit(memc);
835
836 size_t value_length;
837 uint32_t flags;
838 memcached_return_t rc;
839 char *check_value= memcached_get(memc,
840 test_literal_param(__func__),
841 &value_length, &flags, &rc);
842 test_memcmp(check_value, "when we sanitize", strlen("when we sanitize"));
843 test_compare(test_literal_param_size("when we sanitize"), value_length);
844 test_compare(MEMCACHED_SUCCESS, rc);
845 free(check_value);
846
847 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_DATA_EXISTS : MEMCACHED_NOTSTORED,
848 memcached_add(memc,
849 test_literal_param(__func__),
850 test_literal_param("try something else"),
851 time_t(0), uint32_t(0)));
852
853 return TEST_SUCCESS;
854 }
855
856 /*
857 ** There was a problem of leaking filedescriptors in the initial release
858 ** of MacOSX 10.5. This test case triggers the problem. On some Solaris
859 ** systems it seems that the kernel is slow on reclaiming the resources
860 ** because the connects starts to time out (the test doesn't do much
861 ** anyway, so just loop 10 iterations)
862 */
863 test_return_t add_wrapper(memcached_st *memc)
864 {
865 unsigned int max= 10000;
866 #ifdef __sun
867 max= 10;
868 #endif
869 #ifdef __APPLE__
870 max= 10;
871 #endif
872
873 for (uint32_t x= 0; x < max; x++)
874 {
875 add_test(memc);
876 }
877
878 return TEST_SUCCESS;
879 }
880
881 test_return_t replace_test(memcached_st *memc)
882 {
883 test_compare(return_value_based_on_buffering(memc),
884 memcached_set(memc,
885 test_literal_param(__func__),
886 test_literal_param("when we sanitize"),
887 time_t(0), uint32_t(0)));
888
889 test_compare(MEMCACHED_SUCCESS,
890 memcached_replace(memc,
891 test_literal_param(__func__),
892 test_literal_param("first we insert some data"),
893 time_t(0), uint32_t(0)));
894
895 return TEST_SUCCESS;
896 }
897
898 test_return_t delete_test(memcached_st *memc)
899 {
900 test_compare(return_value_based_on_buffering(memc),
901 memcached_set(memc,
902 test_literal_param(__func__),
903 test_literal_param("when we sanitize"),
904 time_t(0), uint32_t(0)));
905
906 test_compare(return_value_based_on_buffering(memc),
907 memcached_delete(memc,
908 test_literal_param(__func__),
909 time_t(0)));
910
911 return TEST_SUCCESS;
912 }
913
914 test_return_t flush_test(memcached_st *memc)
915 {
916 uint64_t query_id= memcached_query_id(memc);
917 test_compare(MEMCACHED_SUCCESS,
918 memcached_flush(memc, 0));
919 test_compare(query_id +1, memcached_query_id(memc));
920
921 return TEST_SUCCESS;
922 }
923
924 static memcached_return_t server_function(const memcached_st *,
925 const memcached_server_st *,
926 void *)
927 {
928 /* Do Nothing */
929 return MEMCACHED_SUCCESS;
930 }
931
932 test_return_t memcached_server_cursor_test(memcached_st *memc)
933 {
934 char context[10];
935 strncpy(context, "foo bad", sizeof(context));
936 memcached_server_fn callbacks[1];
937
938 callbacks[0]= server_function;
939 memcached_server_cursor(memc, callbacks, context, 1);
940 return TEST_SUCCESS;
941 }
942
943 test_return_t bad_key_test(memcached_st *memc)
944 {
945 memcached_return_t rc;
946 const char *key= "foo bad";
947 uint32_t flags;
948
949 uint64_t query_id= memcached_query_id(memc);
950
951 // Just skip if we are in binary mode.
952 test_skip(false, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
953
954 test_compare(query_id, memcached_query_id(memc)); // We should not increase the query_id for memcached_behavior_get()
955
956 memcached_st *memc_clone= memcached_clone(NULL, memc);
957 test_true(memc_clone);
958
959 query_id= memcached_query_id(memc_clone);
960 test_compare(MEMCACHED_SUCCESS,
961 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
962 test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
963
964 /* All keys are valid in the binary protocol (except for length) */
965 if (memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == false)
966 {
967 uint64_t before_query_id= memcached_query_id(memc_clone);
968 {
969 size_t string_length;
970 char *string= memcached_get(memc_clone, key, strlen(key),
971 &string_length, &flags, &rc);
972 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
973 test_zero(string_length);
974 test_false(string);
975 }
976 test_compare(before_query_id +1, memcached_query_id(memc_clone));
977
978 query_id= memcached_query_id(memc_clone);
979 test_compare(MEMCACHED_SUCCESS,
980 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, false));
981 test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
982 {
983 size_t string_length;
984 char *string= memcached_get(memc_clone, key, strlen(key),
985 &string_length, &flags, &rc);
986 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
987 test_zero(string_length);
988 test_false(string);
989 }
990
991 /* Test multi key for bad keys */
992 const char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
993 size_t key_lengths[] = { 7, 7, 7 };
994 query_id= memcached_query_id(memc_clone);
995 test_compare(MEMCACHED_SUCCESS,
996 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
997 test_compare(query_id, memcached_query_id(memc_clone));
998
999 query_id= memcached_query_id(memc_clone);
1000 test_compare(MEMCACHED_BAD_KEY_PROVIDED,
1001 memcached_mget(memc_clone, keys, key_lengths, 3));
1002 test_compare(query_id +1, memcached_query_id(memc_clone));
1003
1004 query_id= memcached_query_id(memc_clone);
1005 // Grouping keys are not required to follow normal key behaviors
1006 test_compare(MEMCACHED_SUCCESS,
1007 memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1));
1008 test_compare(query_id +1, memcached_query_id(memc_clone));
1009
1010 /* The following test should be moved to the end of this function when the
1011 memcached server is updated to allow max size length of the keys in the
1012 binary protocol
1013 */
1014 test_compare(MEMCACHED_SUCCESS,
1015 memcached_callback_set(memc_clone, MEMCACHED_CALLBACK_NAMESPACE, NULL));
1016
1017 libtest::vchar_t longkey;
1018 {
1019 libtest::vchar_t::iterator it= longkey.begin();
1020 longkey.insert(it, MEMCACHED_MAX_KEY, 'a');
1021 }
1022
1023 test_compare(longkey.size(), size_t(MEMCACHED_MAX_KEY));
1024 {
1025 size_t string_length;
1026 // We subtract 1
1027 test_null(memcached_get(memc_clone, &longkey[0], longkey.size() -1, &string_length, &flags, &rc));
1028 test_compare(MEMCACHED_NOTFOUND, rc);
1029 test_zero(string_length);
1030
1031 test_null(memcached_get(memc_clone, &longkey[0], longkey.size(), &string_length, &flags, &rc));
1032 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
1033 test_zero(string_length);
1034 }
1035 }
1036
1037 /* Make sure zero length keys are marked as bad */
1038 {
1039 test_compare(MEMCACHED_SUCCESS,
1040 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
1041 size_t string_length;
1042 char *string= memcached_get(memc_clone, key, 0,
1043 &string_length, &flags, &rc);
1044 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
1045 test_zero(string_length);
1046 test_false(string);
1047 }
1048
1049 memcached_free(memc_clone);
1050
1051 return TEST_SUCCESS;
1052 }
1053
1054 #define READ_THROUGH_VALUE "set for me"
1055 static memcached_return_t read_through_trigger(memcached_st *, // memc
1056 char *, // key
1057 size_t, // key_length,
1058 memcached_result_st *result)
1059 {
1060 return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE));
1061 }
1062
1063 #ifndef __INTEL_COMPILER
1064 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
1065 #endif
1066
1067 test_return_t read_through(memcached_st *memc)
1068 {
1069 memcached_trigger_key_fn cb= (memcached_trigger_key_fn)read_through_trigger;
1070
1071 size_t string_length;
1072 uint32_t flags;
1073 memcached_return_t rc;
1074 char *string= memcached_get(memc,
1075 test_literal_param(__func__),
1076 &string_length, &flags, &rc);
1077
1078 test_compare(MEMCACHED_NOTFOUND, rc);
1079 test_false(string_length);
1080 test_false(string);
1081
1082 test_compare(MEMCACHED_SUCCESS,
1083 memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE, *(void **)&cb));
1084
1085 string= memcached_get(memc,
1086 test_literal_param(__func__),
1087 &string_length, &flags, &rc);
1088
1089 test_compare(MEMCACHED_SUCCESS, rc);
1090 test_compare(sizeof(READ_THROUGH_VALUE) -1, string_length);
1091 test_compare(0, string[sizeof(READ_THROUGH_VALUE) -1]);
1092 test_strcmp(READ_THROUGH_VALUE, string);
1093 free(string);
1094
1095 string= memcached_get(memc,
1096 test_literal_param(__func__),
1097 &string_length, &flags, &rc);
1098
1099 test_compare(MEMCACHED_SUCCESS, rc);
1100 test_true(string);
1101 test_compare(string_length, sizeof(READ_THROUGH_VALUE) -1);
1102 test_true(string[sizeof(READ_THROUGH_VALUE) -1] == 0);
1103 test_strcmp(READ_THROUGH_VALUE, string);
1104 free(string);
1105
1106 return TEST_SUCCESS;
1107 }
1108
1109 test_return_t set_test2(memcached_st *memc)
1110 {
1111 for (uint32_t x= 0; x < 10; x++)
1112 {
1113 test_compare(return_value_based_on_buffering(memc),
1114 memcached_set(memc,
1115 test_literal_param("foo"),
1116 test_literal_param("train in the brain"),
1117 time_t(0), uint32_t(0)));
1118 }
1119
1120 return TEST_SUCCESS;
1121 }
1122
1123 test_return_t set_test3(memcached_st *memc)
1124 {
1125 size_t value_length= 8191;
1126
1127 libtest::vchar_t value;
1128 value.reserve(value_length);
1129 for (uint32_t x= 0; x < value_length; x++)
1130 {
1131 value.push_back(char(x % 127));
1132 }
1133
1134 /* The dump test relies on there being at least 32 items in memcached */
1135 for (uint32_t x= 0; x < 32; x++)
1136 {
1137 char key[16];
1138
1139 snprintf(key, sizeof(key), "foo%u", x);
1140
1141 uint64_t query_id= memcached_query_id(memc);
1142 test_compare(return_value_based_on_buffering(memc),
1143 memcached_set(memc, key, strlen(key),
1144 &value[0], value.size(),
1145 time_t(0), uint32_t(0)));
1146 test_compare(query_id +1, memcached_query_id(memc));
1147 }
1148
1149 return TEST_SUCCESS;
1150 }
1151
1152 test_return_t mget_end(memcached_st *memc)
1153 {
1154 const char *keys[]= { "foo", "foo2" };
1155 size_t lengths[]= { 3, 4 };
1156 const char *values[]= { "fjord", "41" };
1157
1158 // Set foo and foo2
1159 for (size_t x= 0; x < test_array_length(keys); x++)
1160 {
1161 test_compare(MEMCACHED_SUCCESS,
1162 memcached_set(memc,
1163 keys[x], lengths[x],
1164 values[x], strlen(values[x]),
1165 time_t(0), uint32_t(0)));
1166 }
1167
1168 char *string;
1169 size_t string_length;
1170 uint32_t flags;
1171
1172 // retrieve both via mget
1173 test_compare(MEMCACHED_SUCCESS,
1174 memcached_mget(memc,
1175 keys, lengths,
1176 test_array_length(keys)));
1177
1178 char key[MEMCACHED_MAX_KEY];
1179 size_t key_length;
1180 memcached_return_t rc;
1181
1182 // this should get both
1183 for (size_t x= 0; x < test_array_length(keys); x++)
1184 {
1185 string= memcached_fetch(memc, key, &key_length, &string_length,
1186 &flags, &rc);
1187 test_compare(MEMCACHED_SUCCESS, rc);
1188 int val = 0;
1189 if (key_length == 4)
1190 {
1191 val= 1;
1192 }
1193
1194 test_compare(string_length, strlen(values[val]));
1195 test_true(strncmp(values[val], string, string_length) == 0);
1196 free(string);
1197 }
1198
1199 // this should indicate end
1200 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1201 test_compare(MEMCACHED_END, rc);
1202 test_null(string);
1203
1204 // now get just one
1205 test_compare(MEMCACHED_SUCCESS,
1206 memcached_mget(memc, keys, lengths, 1));
1207
1208 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1209 test_compare(key_length, lengths[0]);
1210 test_true(strncmp(keys[0], key, key_length) == 0);
1211 test_compare(string_length, strlen(values[0]));
1212 test_true(strncmp(values[0], string, string_length) == 0);
1213 test_compare(MEMCACHED_SUCCESS, rc);
1214 free(string);
1215
1216 // this should indicate end
1217 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1218 test_compare(MEMCACHED_END, rc);
1219 test_null(string);
1220
1221 return TEST_SUCCESS;
1222 }
1223
1224 /* Do not copy the style of this code, I just access hosts to testthis function */
1225 test_return_t stats_servername_test(memcached_st *memc)
1226 {
1227 memcached_stat_st memc_stat;
1228 memcached_server_instance_st instance=
1229 memcached_server_instance_by_position(memc, 0);
1230
1231 if (LIBMEMCACHED_WITH_SASL_SUPPORT and memcached_get_sasl_callbacks(memc))
1232 {
1233 return TEST_SKIPPED;
1234 }
1235
1236 test_compare(MEMCACHED_SUCCESS, memcached_stat_servername(&memc_stat, NULL,
1237 memcached_server_name(instance),
1238 memcached_server_port(instance)));
1239
1240 return TEST_SUCCESS;
1241 }
1242
1243 test_return_t increment_test(memcached_st *memc)
1244 {
1245 uint64_t new_number;
1246
1247 test_compare(MEMCACHED_SUCCESS,
1248 memcached_set(memc,
1249 test_literal_param("number"),
1250 test_literal_param("0"),
1251 (time_t)0, (uint32_t)0));
1252
1253 test_compare(MEMCACHED_SUCCESS,
1254 memcached_increment(memc, test_literal_param("number"), 1, &new_number));
1255 test_compare(uint64_t(1), new_number);
1256
1257 test_compare(MEMCACHED_SUCCESS,
1258 memcached_increment(memc, test_literal_param("number"), 1, &new_number));
1259 test_compare(uint64_t(2), new_number);
1260
1261 return TEST_SUCCESS;
1262 }
1263
1264 test_return_t increment_with_initial_test(memcached_st *memc)
1265 {
1266 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1267
1268 uint64_t new_number;
1269 uint64_t initial= 0;
1270
1271 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1272
1273 test_compare(MEMCACHED_SUCCESS,
1274 memcached_increment_with_initial(memc, test_literal_param("number"), 1, initial, 0, &new_number));
1275 test_compare(new_number, initial);
1276
1277 test_compare(MEMCACHED_SUCCESS,
1278 memcached_increment_with_initial(memc, test_literal_param("number"), 1, initial, 0, &new_number));
1279 test_compare(new_number, (initial +1));
1280
1281 return TEST_SUCCESS;
1282 }
1283
1284 test_return_t decrement_test(memcached_st *memc)
1285 {
1286 test_compare(return_value_based_on_buffering(memc),
1287 memcached_set(memc,
1288 test_literal_param(__func__),
1289 test_literal_param("3"),
1290 time_t(0), uint32_t(0)));
1291
1292 // Make sure we flush the value we just set
1293 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1294
1295 uint64_t new_number;
1296 test_compare(MEMCACHED_SUCCESS,
1297 memcached_decrement(memc,
1298 test_literal_param(__func__),
1299 1, &new_number));
1300 test_compare(uint64_t(2), new_number);
1301
1302 test_compare(MEMCACHED_SUCCESS,
1303 memcached_decrement(memc,
1304 test_literal_param(__func__),
1305 1, &new_number));
1306 test_compare(uint64_t(1), new_number);
1307
1308 return TEST_SUCCESS;
1309 }
1310
1311 test_return_t decrement_with_initial_test(memcached_st *memc)
1312 {
1313 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1314
1315 uint64_t initial= 3;
1316
1317 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1318
1319 uint64_t new_number;
1320 test_compare(MEMCACHED_SUCCESS,
1321 memcached_decrement_with_initial(memc,
1322 test_literal_param(__func__),
1323 1, initial,
1324 0, &new_number));
1325 test_compare(new_number, initial);
1326
1327 test_compare(MEMCACHED_SUCCESS,
1328 memcached_decrement_with_initial(memc,
1329 test_literal_param(__func__),
1330 1, initial,
1331 0, &new_number));
1332 test_compare(new_number, (initial - 1));
1333
1334 return TEST_SUCCESS;
1335 }
1336
1337 test_return_t increment_by_key_test(memcached_st *memc)
1338 {
1339 const char *master_key= "foo";
1340 const char *key= "number";
1341 const char *value= "0";
1342
1343 test_compare(return_value_based_on_buffering(memc),
1344 memcached_set_by_key(memc, master_key, strlen(master_key),
1345 key, strlen(key),
1346 value, strlen(value),
1347 time_t(0), uint32_t(0)));
1348
1349 // Make sure we flush the value we just set
1350 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1351
1352 uint64_t new_number;
1353 test_compare(MEMCACHED_SUCCESS,
1354 memcached_increment_by_key(memc, master_key, strlen(master_key),
1355 key, strlen(key), 1, &new_number));
1356 test_compare(uint64_t(1), new_number);
1357
1358 test_compare(MEMCACHED_SUCCESS,
1359 memcached_increment_by_key(memc, master_key, strlen(master_key),
1360 key, strlen(key), 1, &new_number));
1361 test_compare(uint64_t(2), new_number);
1362
1363 return TEST_SUCCESS;
1364 }
1365
1366 test_return_t increment_with_initial_by_key_test(memcached_st *memc)
1367 {
1368 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1369
1370 uint64_t new_number;
1371 const char *master_key= "foo";
1372 const char *key= "number";
1373 uint64_t initial= 0;
1374
1375 test_compare(MEMCACHED_SUCCESS,
1376 memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1377 key, strlen(key),
1378 1, initial, 0, &new_number));
1379 test_compare(new_number, initial);
1380
1381 test_compare(MEMCACHED_SUCCESS,
1382 memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1383 key, strlen(key),
1384 1, initial, 0, &new_number));
1385 test_compare(new_number, (initial +1));
1386
1387 return TEST_SUCCESS;
1388 }
1389
1390 test_return_t decrement_by_key_test(memcached_st *memc)
1391 {
1392 uint64_t new_number;
1393 const char *value= "3";
1394
1395 test_compare(return_value_based_on_buffering(memc),
1396 memcached_set_by_key(memc,
1397 test_literal_param("foo"),
1398 test_literal_param("number"),
1399 value, strlen(value),
1400 (time_t)0, (uint32_t)0));
1401
1402 test_compare(MEMCACHED_SUCCESS,
1403 memcached_decrement_by_key(memc,
1404 test_literal_param("foo"),
1405 test_literal_param("number"),
1406 1, &new_number));
1407 test_compare(uint64_t(2), new_number);
1408
1409 test_compare(MEMCACHED_SUCCESS,
1410 memcached_decrement_by_key(memc,
1411 test_literal_param("foo"),
1412 test_literal_param("number"),
1413 1, &new_number));
1414 test_compare(uint64_t(1), new_number);
1415
1416 return TEST_SUCCESS;
1417 }
1418
1419 test_return_t decrement_with_initial_by_key_test(memcached_st *memc)
1420 {
1421 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1422
1423 uint64_t new_number;
1424 uint64_t initial= 3;
1425
1426 test_compare(MEMCACHED_SUCCESS,
1427 memcached_decrement_with_initial_by_key(memc,
1428 test_literal_param("foo"),
1429 test_literal_param("number"),
1430 1, initial, 0, &new_number));
1431 test_compare(new_number, initial);
1432
1433 test_compare(MEMCACHED_SUCCESS,
1434 memcached_decrement_with_initial_by_key(memc,
1435 test_literal_param("foo"),
1436 test_literal_param("number"),
1437 1, initial, 0, &new_number));
1438 test_compare(new_number, (initial - 1));
1439
1440 return TEST_SUCCESS;
1441 }
1442 test_return_t binary_increment_with_prefix_test(memcached_st *memc)
1443 {
1444 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1445
1446 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)"namespace:"));
1447
1448 test_compare(return_value_based_on_buffering(memc),
1449 memcached_set(memc,
1450 test_literal_param("number"),
1451 test_literal_param("0"),
1452 (time_t)0, (uint32_t)0));
1453
1454 uint64_t new_number;
1455 test_compare(MEMCACHED_SUCCESS, memcached_increment(memc,
1456 test_literal_param("number"),
1457 1, &new_number));
1458 test_compare(uint64_t(1), new_number);
1459
1460 test_compare(MEMCACHED_SUCCESS, memcached_increment(memc,
1461 test_literal_param("number"),
1462 1, &new_number));
1463 test_compare(uint64_t(2), new_number);
1464
1465 return TEST_SUCCESS;
1466 }
1467
1468 test_return_t quit_test(memcached_st *memc)
1469 {
1470 const char *value= "sanford and sun";
1471
1472 test_compare(return_value_based_on_buffering(memc),
1473 memcached_set(memc,
1474 test_literal_param(__func__),
1475 value, strlen(value),
1476 time_t(10), uint32_t(3)));
1477 memcached_quit(memc);
1478
1479 test_compare(return_value_based_on_buffering(memc),
1480 memcached_set(memc,
1481 test_literal_param(__func__),
1482 value, strlen(value),
1483 time_t(50), uint32_t(9)));
1484
1485 return TEST_SUCCESS;
1486 }
1487
1488 test_return_t mget_result_test(memcached_st *memc)
1489 {
1490 const char *keys[]= {"fudge", "son", "food"};
1491 size_t key_length[]= {5, 3, 4};
1492
1493 memcached_result_st results_obj;
1494 memcached_result_st *results= memcached_result_create(memc, &results_obj);
1495 test_true(results);
1496 test_true(&results_obj == results);
1497
1498 /* We need to empty the server before continueing test */
1499 test_compare(MEMCACHED_SUCCESS,
1500 memcached_flush(memc, 0));
1501
1502 test_compare(MEMCACHED_SUCCESS,
1503 memcached_mget(memc, keys, key_length, 3));
1504
1505 memcached_return_t rc;
1506 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1507 {
1508 test_true(results);
1509 }
1510
1511 while ((results= memcached_fetch_result(memc, &results_obj, &rc))) { test_true(false); /* We should never see a value returned */ };
1512 test_false(results);
1513 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1514
1515 for (uint32_t x= 0; x < 3; x++)
1516 {
1517 rc= memcached_set(memc, keys[x], key_length[x],
1518 keys[x], key_length[x],
1519 (time_t)50, (uint32_t)9);
1520 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
1521 }
1522
1523 test_compare(MEMCACHED_SUCCESS,
1524 memcached_mget(memc, keys, key_length, 3));
1525
1526 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1527 {
1528 test_true(results);
1529 test_true(&results_obj == results);
1530 test_compare(MEMCACHED_SUCCESS, rc);
1531 test_memcmp(memcached_result_key_value(results),
1532 memcached_result_value(results),
1533 memcached_result_length(results));
1534 test_compare(memcached_result_key_length(results), memcached_result_length(results));
1535 }
1536
1537 memcached_result_free(&results_obj);
1538
1539 return TEST_SUCCESS;
1540 }
1541
1542 test_return_t mget_result_alloc_test(memcached_st *memc)
1543 {
1544 const char *keys[]= {"fudge", "son", "food"};
1545 size_t key_length[]= {5, 3, 4};
1546
1547 memcached_result_st *results;
1548
1549 /* We need to empty the server before continueing test */
1550 test_compare(MEMCACHED_SUCCESS,
1551 memcached_flush(memc, 0));
1552
1553 test_compare(MEMCACHED_SUCCESS,
1554 memcached_mget(memc, keys, key_length, 3));
1555
1556 memcached_return_t rc;
1557 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1558 {
1559 test_true(results);
1560 }
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 uint32_t x= 0;
1576 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1577 {
1578 test_true(results);
1579 test_compare(MEMCACHED_SUCCESS, rc);
1580 test_compare(memcached_result_key_length(results), memcached_result_length(results));
1581 test_memcmp(memcached_result_key_value(results),
1582 memcached_result_value(results),
1583 memcached_result_length(results));
1584 memcached_result_free(results);
1585 x++;
1586 }
1587
1588 return TEST_SUCCESS;
1589 }
1590
1591 test_return_t mget_result_function(memcached_st *memc)
1592 {
1593 const char *keys[]= {"fudge", "son", "food"};
1594 size_t key_length[]= {5, 3, 4};
1595 size_t counter;
1596 memcached_execute_fn callbacks[1];
1597
1598 for (uint32_t x= 0; x < 3; x++)
1599 {
1600 test_compare(return_value_based_on_buffering(memc),
1601 memcached_set(memc, keys[x], key_length[x],
1602 keys[x], key_length[x],
1603 time_t(50), uint32_t(9)));
1604 }
1605 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1606 memcached_quit(memc);
1607
1608 test_compare(MEMCACHED_SUCCESS,
1609 memcached_mget(memc, keys, key_length, 3));
1610
1611 callbacks[0]= &callback_counter;
1612 counter= 0;
1613
1614 test_compare(MEMCACHED_SUCCESS,
1615 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
1616
1617 test_compare(size_t(3), counter);
1618
1619 return TEST_SUCCESS;
1620 }
1621
1622 test_return_t mget_test(memcached_st *memc)
1623 {
1624 const char *keys[]= {"fudge", "son", "food"};
1625 size_t key_length[]= {5, 3, 4};
1626
1627 char return_key[MEMCACHED_MAX_KEY];
1628 size_t return_key_length;
1629 char *return_value;
1630 size_t return_value_length;
1631
1632 test_compare(MEMCACHED_SUCCESS,
1633 memcached_mget(memc, keys, key_length, 3));
1634
1635 uint32_t flags;
1636 memcached_return_t rc;
1637 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1638 &return_value_length, &flags, &rc)))
1639 {
1640 test_true(return_value);
1641 }
1642 test_false(return_value);
1643 test_zero(return_value_length);
1644 test_compare(MEMCACHED_NOTFOUND, rc);
1645
1646 for (uint32_t x= 0; x < 3; x++)
1647 {
1648 rc= memcached_set(memc, keys[x], key_length[x],
1649 keys[x], key_length[x],
1650 (time_t)50, (uint32_t)9);
1651 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
1652 }
1653 test_compare(MEMCACHED_SUCCESS,
1654 memcached_mget(memc, keys, key_length, 3));
1655
1656 uint32_t x= 0;
1657 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1658 &return_value_length, &flags, &rc)))
1659 {
1660 test_true(return_value);
1661 test_compare(MEMCACHED_SUCCESS, rc);
1662 if (not memc->_namespace)
1663 {
1664 test_compare(return_key_length, return_value_length);
1665 test_memcmp(return_value, return_key, return_value_length);
1666 }
1667 free(return_value);
1668 x++;
1669 }
1670
1671 return TEST_SUCCESS;
1672 }
1673
1674 test_return_t mget_execute(memcached_st *original_memc)
1675 {
1676 test_skip(true, memcached_behavior_get(original_memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1677
1678 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
1679 test_true(memc);
1680
1681 keys_st keys(20480);
1682
1683 /* First add all of the items.. */
1684 char blob[1024] = {0};
1685
1686 for (size_t x= 0; x < keys.size(); ++x)
1687 {
1688 uint64_t query_id= memcached_query_id(memc);
1689 memcached_return_t rc= memcached_add(memc,
1690 keys.key_at(x), keys.length_at(x),
1691 blob, sizeof(blob),
1692 0, 0);
1693 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED,
1694 memcached_last_error_message(memc));
1695 test_compare(query_id +1, memcached_query_id(memc));
1696 }
1697
1698 /* Try to get all of them with a large multiget */
1699 size_t counter= 0;
1700 memcached_execute_fn callbacks[]= { &callback_counter };
1701 test_compare(MEMCACHED_SUCCESS,
1702 memcached_mget_execute(memc,
1703 keys.keys_ptr(), keys.lengths_ptr(),
1704 keys.size(), callbacks, &counter, 1));
1705
1706 {
1707 uint64_t query_id= memcached_query_id(memc);
1708 test_compare(MEMCACHED_SUCCESS,
1709 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
1710 test_compare(query_id, memcached_query_id(memc));
1711
1712 /* Verify that we got all of the items */
1713 test_compare(keys.size(), counter);
1714 }
1715
1716 memcached_free(memc);
1717
1718 return TEST_SUCCESS;
1719 }
1720
1721 #define REGRESSION_BINARY_VS_BLOCK_COUNT 20480
1722 static pairs_st *global_pairs= NULL;
1723
1724 test_return_t key_setup(memcached_st *memc)
1725 {
1726 test_skip(TEST_SUCCESS, pre_binary(memc));
1727
1728 global_pairs= pairs_generate(REGRESSION_BINARY_VS_BLOCK_COUNT, 0);
1729
1730 return TEST_SUCCESS;
1731 }
1732
1733 test_return_t key_teardown(memcached_st *)
1734 {
1735 pairs_free(global_pairs);
1736 global_pairs= NULL;
1737
1738 return TEST_SUCCESS;
1739 }
1740
1741 test_return_t block_add_regression(memcached_st *memc)
1742 {
1743 /* First add all of the items.. */
1744 for (ptrdiff_t x= 0; x < REGRESSION_BINARY_VS_BLOCK_COUNT; ++x)
1745 {
1746 libtest::vchar_t blob;
1747 libtest::vchar::make(blob, 1024);
1748
1749 memcached_return_t rc= memcached_add_by_key(memc,
1750 test_literal_param("bob"),
1751 global_pairs[x].key, global_pairs[x].key_length,
1752 &blob[0], blob.size(),
1753 time_t(0), uint32_t(0));
1754 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE, memcached_strerror(NULL, rc));
1755 }
1756
1757 return TEST_SUCCESS;
1758 }
1759
1760 test_return_t binary_add_regression(memcached_st *memc)
1761 {
1762 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
1763 test_return_t rc= block_add_regression(memc);
1764
1765 return rc;
1766 }
1767
1768 test_return_t get_stats_keys(memcached_st *memc)
1769 {
1770 char **stat_list;
1771 char **ptr;
1772 memcached_stat_st memc_stat;
1773 memcached_return_t rc;
1774
1775 stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc);
1776 test_compare(MEMCACHED_SUCCESS, rc);
1777 for (ptr= stat_list; *ptr; ptr++)
1778 test_true(*ptr);
1779
1780 free(stat_list);
1781
1782 return TEST_SUCCESS;
1783 }
1784
1785 test_return_t version_string_test(memcached_st *)
1786 {
1787 test_strcmp(LIBMEMCACHED_VERSION_STRING, memcached_lib_version());
1788
1789 return TEST_SUCCESS;
1790 }
1791
1792 test_return_t get_stats(memcached_st *memc)
1793 {
1794 memcached_return_t rc;
1795
1796 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
1797 test_compare(MEMCACHED_SUCCESS, rc);
1798 test_true(memc_stat);
1799
1800 for (uint32_t x= 0; x < memcached_server_count(memc); x++)
1801 {
1802 char **stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
1803 test_compare(MEMCACHED_SUCCESS, rc);
1804 for (char **ptr= stat_list; *ptr; ptr++) {};
1805
1806 free(stat_list);
1807 }
1808
1809 memcached_stat_free(NULL, memc_stat);
1810
1811 return TEST_SUCCESS;
1812 }
1813
1814 test_return_t add_host_test(memcached_st *memc)
1815 {
1816 char servername[]= "0.example.com";
1817
1818 memcached_return_t rc;
1819 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1820 test_compare(1U, memcached_server_list_count(servers));
1821
1822 for (unsigned int x= 2; x < 20; x++)
1823 {
1824 char buffer[SMALL_STRING_LEN];
1825
1826 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1827 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1828 &rc);
1829 test_compare(MEMCACHED_SUCCESS, rc);
1830 test_compare(x, memcached_server_list_count(servers));
1831 }
1832
1833 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
1834 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
1835
1836 memcached_server_list_free(servers);
1837
1838 return TEST_SUCCESS;
1839 }
1840
1841 test_return_t memcached_fetch_result_NOT_FOUND(memcached_st *memc)
1842 {
1843 memcached_return_t rc;
1844
1845 const char *key= "not_found";
1846 size_t key_length= test_literal_param_size("not_found");
1847
1848 test_compare(MEMCACHED_SUCCESS,
1849 memcached_mget(memc, &key, &key_length, 1));
1850
1851 memcached_result_st *result= memcached_fetch_result(memc, NULL, &rc);
1852 test_null(result);
1853 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1854
1855 memcached_result_free(result);
1856
1857 return TEST_SUCCESS;
1858 }
1859
1860 static memcached_return_t clone_test_callback(memcached_st *, memcached_st *)
1861 {
1862 return MEMCACHED_SUCCESS;
1863 }
1864
1865 static memcached_return_t cleanup_test_callback(memcached_st *)
1866 {
1867 return MEMCACHED_SUCCESS;
1868 }
1869
1870 test_return_t callback_test(memcached_st *memc)
1871 {
1872 /* Test User Data */
1873 {
1874 int x= 5;
1875 int *test_ptr;
1876 memcached_return_t rc;
1877
1878 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x));
1879 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1880 test_true(*test_ptr == x);
1881 }
1882
1883 /* Test Clone Callback */
1884 {
1885 memcached_clone_fn clone_cb= (memcached_clone_fn)clone_test_callback;
1886 void *clone_cb_ptr= *(void **)&clone_cb;
1887 void *temp_function= NULL;
1888
1889 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, clone_cb_ptr));
1890 memcached_return_t rc;
1891 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1892 test_true(temp_function == clone_cb_ptr);
1893 test_compare(MEMCACHED_SUCCESS, rc);
1894 }
1895
1896 /* Test Cleanup Callback */
1897 {
1898 memcached_cleanup_fn cleanup_cb= (memcached_cleanup_fn)cleanup_test_callback;
1899 void *cleanup_cb_ptr= *(void **)&cleanup_cb;
1900 void *temp_function= NULL;
1901 memcached_return_t rc;
1902
1903 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, cleanup_cb_ptr));
1904 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1905 test_true(temp_function == cleanup_cb_ptr);
1906 }
1907
1908 return TEST_SUCCESS;
1909 }
1910
1911 /* We don't test the behavior itself, we test the switches */
1912 test_return_t behavior_test(memcached_st *memc)
1913 {
1914 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
1915 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
1916
1917 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
1918 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
1919
1920 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_MD5);
1921 test_compare(uint64_t(MEMCACHED_HASH_MD5), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1922
1923 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
1924 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
1925
1926 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
1927 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
1928
1929 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_DEFAULT);
1930 test_compare(uint64_t(MEMCACHED_HASH_DEFAULT), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1931
1932 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_CRC);
1933 test_compare(uint64_t(MEMCACHED_HASH_CRC), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1934
1935 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE));
1936
1937 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE));
1938
1939 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
1940 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value +1);
1941 test_compare((value +1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
1942
1943 return TEST_SUCCESS;
1944 }
1945
1946 test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
1947 {
1948 test_compare(MEMCACHED_DEPRECATED,
1949 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, true));
1950
1951 // Platform dependent
1952 #if 0
1953 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
1954 test_false(value);
1955 #endif
1956
1957 return TEST_SUCCESS;
1958 }
1959
1960
1961 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test(memcached_st *memc)
1962 {
1963 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, true);
1964 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
1965
1966 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE);
1967
1968 if (memcached_success(rc))
1969 {
1970 test_true(value);
1971 }
1972 else
1973 {
1974 test_false(value);
1975 }
1976
1977 return TEST_SUCCESS;
1978 }
1979
1980
1981 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc)
1982 {
1983 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE, true);
1984 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
1985
1986 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE);
1987
1988 if (memcached_success(rc))
1989 {
1990 test_true(value);
1991 }
1992 else
1993 {
1994 test_false(value);
1995 }
1996
1997 return TEST_SUCCESS;
1998 }
1999
2000 /* Make sure we behave properly if server list has no values */
2001 test_return_t user_supplied_bug4(memcached_st *memc)
2002 {
2003 const char *keys[]= {"fudge", "son", "food"};
2004 size_t key_length[]= {5, 3, 4};
2005
2006 /* Here we free everything before running a bunch of mget tests */
2007 memcached_servers_reset(memc);
2008
2009
2010 /* We need to empty the server before continueing test */
2011 test_compare(MEMCACHED_NO_SERVERS,
2012 memcached_flush(memc, 0));
2013
2014 test_compare(MEMCACHED_NO_SERVERS,
2015 memcached_mget(memc, keys, key_length, 3));
2016
2017 {
2018 unsigned int keys_returned;
2019 memcached_return_t rc;
2020 test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, rc));
2021 test_compare(MEMCACHED_NOTFOUND, rc);
2022 test_zero(keys_returned);
2023 }
2024
2025 for (uint32_t x= 0; x < 3; x++)
2026 {
2027 test_compare(MEMCACHED_NO_SERVERS,
2028 memcached_set(memc, keys[x], key_length[x],
2029 keys[x], key_length[x],
2030 (time_t)50, (uint32_t)9));
2031 }
2032
2033 test_compare(MEMCACHED_NO_SERVERS,
2034 memcached_mget(memc, keys, key_length, 3));
2035
2036 {
2037 char *return_value;
2038 char return_key[MEMCACHED_MAX_KEY];
2039 memcached_return_t rc;
2040 size_t return_key_length;
2041 size_t return_value_length;
2042 uint32_t flags;
2043 uint32_t x= 0;
2044 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2045 &return_value_length, &flags, &rc)))
2046 {
2047 test_true(return_value);
2048 test_compare(MEMCACHED_SUCCESS, rc);
2049 test_true(return_key_length == return_value_length);
2050 test_memcmp(return_value, return_key, return_value_length);
2051 free(return_value);
2052 x++;
2053 }
2054 }
2055
2056 return TEST_SUCCESS;
2057 }
2058
2059 #define VALUE_SIZE_BUG5 1048064
2060 test_return_t user_supplied_bug5(memcached_st *memc)
2061 {
2062 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2063 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2064 char *value;
2065 size_t value_length;
2066 uint32_t flags;
2067 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2068
2069 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2070 {
2071 insert_data[x]= (signed char)rand();
2072 }
2073
2074 test_compare(MEMCACHED_SUCCESS,
2075 memcached_flush(memc, 0));
2076
2077 memcached_return_t rc;
2078 test_null(memcached_get(memc, keys[0], key_length[0], &value_length, &flags, &rc));
2079 test_compare(MEMCACHED_SUCCESS,
2080 memcached_mget(memc, keys, key_length, 4));
2081
2082 unsigned int count;
2083 test_compare(TEST_SUCCESS, fetch_all_results(memc, count, rc));
2084 test_compare(MEMCACHED_NOTFOUND, rc);
2085 test_zero(count);
2086
2087 for (uint32_t x= 0; x < 4; x++)
2088 {
2089 test_compare(MEMCACHED_SUCCESS,
2090 memcached_set(memc, keys[x], key_length[x],
2091 insert_data, VALUE_SIZE_BUG5,
2092 (time_t)0, (uint32_t)0));
2093 }
2094
2095 for (uint32_t x= 0; x < 10; x++)
2096 {
2097 value= memcached_get(memc, keys[0], key_length[0],
2098 &value_length, &flags, &rc);
2099 test_compare(rc, MEMCACHED_SUCCESS);
2100 test_true(value);
2101 ::free(value);
2102
2103 test_compare(MEMCACHED_SUCCESS,
2104 memcached_mget(memc, keys, key_length, 4));
2105
2106 test_compare(TEST_SUCCESS, fetch_all_results(memc, count));
2107 test_compare(4U, count);
2108 }
2109 delete [] insert_data;
2110
2111 return TEST_SUCCESS;
2112 }
2113
2114 test_return_t user_supplied_bug6(memcached_st *memc)
2115 {
2116 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2117 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2118 char return_key[MEMCACHED_MAX_KEY];
2119 size_t return_key_length;
2120 char *value;
2121 size_t value_length;
2122 uint32_t flags;
2123 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2124
2125 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2126 {
2127 insert_data[x]= (signed char)rand();
2128 }
2129
2130 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
2131
2132 test_compare(TEST_SUCCESS, confirm_keys_dont_exist(memc, keys, test_array_length(keys)));
2133
2134 // We will now confirm that memcached_mget() returns success, but we will
2135 // then check to make sure that no actual keys are returned.
2136 test_compare(MEMCACHED_SUCCESS,
2137 memcached_mget(memc, keys, key_length, 4));
2138
2139 memcached_return_t rc;
2140 uint32_t count= 0;
2141 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2142 &value_length, &flags, &rc)))
2143 {
2144 count++;
2145 }
2146 test_zero(count);
2147 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
2148
2149 for (uint32_t x= 0; x < test_array_length(keys); x++)
2150 {
2151 test_compare(MEMCACHED_SUCCESS,
2152 memcached_set(memc, keys[x], key_length[x],
2153 insert_data, VALUE_SIZE_BUG5,
2154 (time_t)0, (uint32_t)0));
2155 }
2156 test_compare(TEST_SUCCESS, confirm_keys_exist(memc, keys, test_array_length(keys)));
2157
2158 for (uint32_t x= 0; x < 2; x++)
2159 {
2160 value= memcached_get(memc, keys[0], key_length[0],
2161 &value_length, &flags, &rc);
2162 test_true(value);
2163 free(value);
2164
2165 test_compare(MEMCACHED_SUCCESS,
2166 memcached_mget(memc, keys, key_length, 4));
2167 /* We test for purge of partial complete fetches */
2168 for (count= 3; count; count--)
2169 {
2170 value= memcached_fetch(memc, return_key, &return_key_length,
2171 &value_length, &flags, &rc);
2172 test_compare(MEMCACHED_SUCCESS, rc);
2173 test_memcmp(value, insert_data, value_length);
2174 test_true(value_length);
2175 free(value);
2176 }
2177 }
2178 delete [] insert_data;
2179
2180 return TEST_SUCCESS;
2181 }
2182
2183 test_return_t user_supplied_bug8(memcached_st *)
2184 {
2185 memcached_return_t rc;
2186 memcached_st *mine;
2187 memcached_st *memc_clone;
2188
2189 memcached_server_st *servers;
2190 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";
2191
2192 servers= memcached_servers_parse(server_list);
2193 test_true(servers);
2194
2195 mine= memcached_create(NULL);
2196 rc= memcached_server_push(mine, servers);
2197 test_compare(MEMCACHED_SUCCESS, rc);
2198 memcached_server_list_free(servers);
2199
2200 test_true(mine);
2201 memc_clone= memcached_clone(NULL, mine);
2202
2203 memcached_quit(mine);
2204 memcached_quit(memc_clone);
2205
2206
2207 memcached_free(mine);
2208 memcached_free(memc_clone);
2209
2210 return TEST_SUCCESS;
2211 }
2212
2213 /* Test flag store/retrieve */
2214 test_return_t user_supplied_bug7(memcached_st *memc)
2215 {
2216 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2217 test_true(insert_data);
2218
2219 for (size_t x= 0; x < VALUE_SIZE_BUG5; x++)
2220 {
2221 insert_data[x]= (signed char)rand();
2222 }
2223
2224 memcached_flush(memc, 0);
2225
2226 const char *keys= "036790384900";
2227 size_t key_length= strlen(keys);
2228 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys, key_length,
2229 insert_data, VALUE_SIZE_BUG5,
2230 time_t(0), 245U));
2231
2232 memcached_return_t rc;
2233 size_t value_length;
2234 uint32_t flags= 0;
2235 char *value= memcached_get(memc, keys, key_length,
2236 &value_length, &flags, &rc);
2237 test_compare(245U, flags);
2238 test_true(value);
2239 free(value);
2240
2241 test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, &keys, &key_length, 1));
2242
2243 char return_key[MEMCACHED_MAX_KEY];
2244 size_t return_key_length;
2245 flags= 0;
2246 value= memcached_fetch(memc, return_key, &return_key_length,
2247 &value_length, &flags, &rc);
2248 test_compare(uint32_t(245), flags);
2249 test_true(value);
2250 free(value);
2251 delete [] insert_data;
2252
2253
2254 return TEST_SUCCESS;
2255 }
2256
2257 test_return_t user_supplied_bug9(memcached_st *memc)
2258 {
2259 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2260 size_t key_length[3];
2261 uint32_t flags;
2262 unsigned count= 0;
2263
2264 char return_key[MEMCACHED_MAX_KEY];
2265 size_t return_key_length;
2266 char *return_value;
2267 size_t return_value_length;
2268
2269
2270 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2271 key_length[1]= strlen("fudge&*@#");
2272 key_length[2]= strlen("for^#@&$not");
2273
2274
2275 for (unsigned int x= 0; x < 3; x++)
2276 {
2277 memcached_return_t rc= memcached_set(memc, keys[x], key_length[x],
2278 keys[x], key_length[x],
2279 (time_t)50, (uint32_t)9);
2280 test_compare(MEMCACHED_SUCCESS, rc);
2281 }
2282
2283 memcached_return_t rc= memcached_mget(memc, keys, key_length, 3);
2284 test_compare(MEMCACHED_SUCCESS, rc);
2285
2286 /* We need to empty the server before continueing test */
2287 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2288 &return_value_length, &flags, &rc)) != NULL)
2289 {
2290 test_true(return_value);
2291 free(return_value);
2292 count++;
2293 }
2294 test_compare(3U, count);
2295
2296 return TEST_SUCCESS;
2297 }
2298
2299 /* We are testing with aggressive timeout to get failures */
2300 test_return_t user_supplied_bug10(memcached_st *memc)
2301 {
2302 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
2303
2304 size_t value_length= 512;
2305 unsigned int set= 1;
2306 memcached_st *mclone= memcached_clone(NULL, memc);
2307
2308 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2309 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2310 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, uint64_t(0));
2311
2312 libtest::vchar_t value;
2313 value.reserve(value_length);
2314 for (uint32_t x= 0; x < value_length; x++)
2315 {
2316 value.push_back(char(x % 127));
2317 }
2318
2319 for (unsigned int x= 1; x <= 100000; ++x)
2320 {
2321 memcached_return_t rc= memcached_set(mclone,
2322 test_literal_param("foo"),
2323 &value[0], value.size(),
2324 0, 0);
2325
2326 test_true_got((rc == MEMCACHED_SUCCESS or rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_BUFFERED or rc == MEMCACHED_TIMEOUT or rc == MEMCACHED_CONNECTION_FAILURE
2327 or rc == MEMCACHED_SERVER_TEMPORARILY_DISABLED),
2328 memcached_strerror(NULL, rc));
2329
2330 if (rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_TIMEOUT)
2331 {
2332 x--;
2333 }
2334 }
2335
2336 memcached_free(mclone);
2337
2338 return TEST_SUCCESS;
2339 }
2340
2341 /*
2342 We are looking failures in the async protocol
2343 */
2344 test_return_t user_supplied_bug11(memcached_st *memc)
2345 {
2346 memcached_st *mclone= memcached_clone(NULL, memc);
2347
2348 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, true);
2349 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
2350 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, size_t(-1));
2351
2352 test_compare(-1, int32_t(memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT)));
2353
2354
2355 libtest::vchar_t value;
2356 value.reserve(512);
2357 for (unsigned int x= 0; x < 512; x++)
2358 {
2359 value.push_back(char(x % 127));
2360 }
2361
2362 for (unsigned int x= 1; x <= 100000; ++x)
2363 {
2364 memcached_return_t rc= memcached_set(mclone, test_literal_param("foo"), &value[0], value.size(), 0, 0);
2365 (void)rc;
2366 }
2367
2368 memcached_free(mclone);
2369
2370 return TEST_SUCCESS;
2371 }
2372
2373 /*
2374 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2375 */
2376 test_return_t user_supplied_bug12(memcached_st *memc)
2377 {
2378 memcached_return_t rc;
2379 uint32_t flags;
2380 size_t value_length;
2381 char *value;
2382 uint64_t number_value;
2383
2384 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2385 &value_length, &flags, &rc);
2386 test_null(value);
2387 test_compare(MEMCACHED_NOTFOUND, rc);
2388
2389 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2390 1, &number_value);
2391 test_null(value);
2392 /* The binary protocol will set the key if it doesn't exist */
2393 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2394 {
2395 test_compare(MEMCACHED_SUCCESS, rc);
2396 }
2397 else
2398 {
2399 test_compare(MEMCACHED_NOTFOUND, rc);
2400 }
2401
2402 test_compare(MEMCACHED_SUCCESS,
2403 memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0));
2404
2405 value= memcached_get(memc, "autoincrement", strlen("autoincrement"), &value_length, &flags, &rc);
2406 test_true(value);
2407 free(value);
2408
2409 test_compare(MEMCACHED_SUCCESS,
2410 memcached_increment(memc, "autoincrement", strlen("autoincrement"), 1, &number_value));
2411 test_compare(2UL, number_value);
2412
2413 return TEST_SUCCESS;
2414 }
2415
2416 /*
2417 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2418 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2419 */
2420 test_return_t user_supplied_bug13(memcached_st *memc)
2421 {
2422 char key[] = "key34567890";
2423
2424 char commandFirst[]= "set key34567890 0 0 ";
2425 char commandLast[] = " \r\n"; /* first line of command sent to server */
2426 size_t commandLength;
2427
2428 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2429
2430 size_t overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2431
2432 for (size_t testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2433 {
2434 char *overflow= new (std::nothrow) char[testSize];
2435 test_true(overflow);
2436
2437 memset(overflow, 'x', testSize);
2438 test_compare(MEMCACHED_SUCCESS,
2439 memcached_set(memc, key, strlen(key),
2440 overflow, testSize, 0, 0));
2441 delete [] overflow;
2442 }
2443
2444 return TEST_SUCCESS;
2445 }
2446
2447
2448 /*
2449 Test values of many different sizes
2450 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2451 set key34567890 0 0 8169 \r\n
2452 is sent followed by buffer of size 8169, followed by 8169
2453 */
2454 test_return_t user_supplied_bug14(memcached_st *memc)
2455 {
2456 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
2457
2458 libtest::vchar_t value;
2459 value.reserve(18000);
2460 for (ptrdiff_t x= 0; x < 18000; x++)
2461 {
2462 value.push_back((char) (x % 127));
2463 }
2464
2465 for (size_t current_length= 1; current_length < value.size(); current_length++)
2466 {
2467 memcached_return_t rc= memcached_set(memc, test_literal_param("foo"),
2468 &value[0], current_length,
2469 (time_t)0, (uint32_t)0);
2470 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
2471
2472 size_t string_length;
2473 uint32_t flags;
2474 char *string= memcached_get(memc, test_literal_param("foo"),
2475 &string_length, &flags, &rc);
2476
2477 test_compare(MEMCACHED_SUCCESS, rc);
2478 test_compare(string_length, current_length);
2479 char buffer[1024];
2480 snprintf(buffer, sizeof(buffer), "%u", uint32_t(string_length));
2481 test_memcmp_hint(string, &value[0], string_length, buffer);
2482
2483 free(string);
2484 }
2485
2486 return TEST_SUCCESS;
2487 }
2488
2489 /*
2490 Look for zero length value problems
2491 */
2492 test_return_t user_supplied_bug15(memcached_st *memc)
2493 {
2494 for (uint32_t x= 0; x < 2; x++)
2495 {
2496 memcached_return_t rc= memcached_set(memc, test_literal_param("mykey"),
2497 NULL, 0,
2498 (time_t)0, (uint32_t)0);
2499
2500 test_compare(MEMCACHED_SUCCESS, rc);
2501
2502 size_t length;
2503 uint32_t flags;
2504 char *value= memcached_get(memc, test_literal_param("mykey"),
2505 &length, &flags, &rc);
2506
2507 test_compare(MEMCACHED_SUCCESS, rc);
2508 test_false(value);
2509 test_zero(length);
2510 test_zero(flags);
2511
2512 value= memcached_get(memc, test_literal_param("mykey"),
2513 &length, &flags, &rc);
2514
2515 test_compare(MEMCACHED_SUCCESS, rc);
2516 test_null(value);
2517 test_zero(length);
2518 test_zero(flags);
2519 }
2520
2521 return TEST_SUCCESS;
2522 }
2523
2524 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2525 test_return_t user_supplied_bug16(memcached_st *memc)
2526 {
2527 test_compare_hint(MEMCACHED_SUCCESS, memcached_set(memc, test_literal_param("mykey"),
2528 NULL, 0,
2529 (time_t)0, UINT32_MAX),
2530 memcached_last_error_message(memc));
2531
2532
2533 size_t length;
2534 uint32_t flags;
2535 memcached_return_t rc;
2536 char *value= memcached_get(memc, test_literal_param("mykey"),
2537 &length, &flags, &rc);
2538
2539 test_compare(MEMCACHED_SUCCESS, rc);
2540 test_null(value);
2541 test_zero(length);
2542 test_compare(flags, UINT32_MAX);
2543
2544 return TEST_SUCCESS;
2545 }
2546
2547 #if !defined(__sun) && !defined(__OpenBSD__)
2548 /* Check the validity of chinese key*/
2549 test_return_t user_supplied_bug17(memcached_st *memc)
2550 {
2551 const char *key= "豆瓣";
2552 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2553 memcached_return_t rc= memcached_set(memc, key, strlen(key),
2554 value, strlen(value),
2555 (time_t)0, 0);
2556
2557 test_compare(MEMCACHED_SUCCESS, rc);
2558
2559 size_t length;
2560 uint32_t flags;
2561 char *value2= memcached_get(memc, key, strlen(key),
2562 &length, &flags, &rc);
2563
2564 test_compare(length, strlen(value));
2565 test_compare(MEMCACHED_SUCCESS, rc);
2566 test_memcmp(value, value2, length);
2567 free(value2);
2568
2569 return TEST_SUCCESS;
2570 }
2571 #endif
2572
2573 /*
2574 From Andrei on IRC
2575 */
2576
2577 test_return_t user_supplied_bug19(memcached_st *)
2578 {
2579 memcached_return_t res;
2580
2581 memcached_st *memc= memcached(test_literal_param("--server=localhost:11311/?100 --server=localhost:11312/?100"));
2582
2583 const memcached_server_st *server= memcached_server_by_key(memc, "a", 1, &res);
2584 test_true(server);
2585
2586 memcached_free(memc);
2587
2588 return TEST_SUCCESS;
2589 }
2590
2591 /* CAS test from Andei */
2592 test_return_t user_supplied_bug20(memcached_st *memc)
2593 {
2594 const char *key= "abc";
2595 size_t key_len= strlen("abc");
2596
2597 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
2598
2599 test_compare(MEMCACHED_SUCCESS,
2600 memcached_set(memc,
2601 test_literal_param("abc"),
2602 test_literal_param("foobar"),
2603 (time_t)0, (uint32_t)0));
2604
2605 test_compare(MEMCACHED_SUCCESS,
2606 memcached_mget(memc, &key, &key_len, 1));
2607
2608 memcached_result_st result_obj;
2609 memcached_result_st *result= memcached_result_create(memc, &result_obj);
2610 test_true(result);
2611
2612 memcached_result_create(memc, &result_obj);
2613 memcached_return_t status;
2614 result= memcached_fetch_result(memc, &result_obj, &status);
2615
2616 test_true(result);
2617 test_compare(MEMCACHED_SUCCESS, status);
2618
2619 memcached_result_free(result);
2620
2621 return TEST_SUCCESS;
2622 }
2623
2624 /* Large mget() of missing keys with binary proto
2625 *
2626 * If many binary quiet commands (such as getq's in an mget) fill the output
2627 * buffer and the server chooses not to respond, memcached_flush hangs. See
2628 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2629 */
2630
2631 /* sighandler_t function that always asserts false */
2632 static void fail(int)
2633 {
2634 fatal_assert(0);
2635 }
2636
2637
2638 test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2639 {
2640 #ifdef WIN32
2641 (void)memc;
2642 (void)key_count;
2643 return TEST_SKIPPED;
2644 #else
2645 void (*oldalarm)(int);
2646
2647 memcached_st *memc_clone= memcached_clone(NULL, memc);
2648 test_true(memc_clone);
2649
2650 /* only binproto uses getq for mget */
2651 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
2652
2653 /* empty the cache to ensure misses (hence non-responses) */
2654 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc_clone, 0));
2655
2656 keys_st keys(key_count);
2657
2658 oldalarm= signal(SIGALRM, fail);
2659 alarm(5);
2660
2661 test_compare_got(MEMCACHED_SUCCESS,
2662 memcached_mget(memc_clone, keys.keys_ptr(), keys.lengths_ptr(), keys.size()),
2663 memcached_last_error_message(memc_clone));
2664
2665 alarm(0);
2666 signal(SIGALRM, oldalarm);
2667
2668 memcached_return_t rc;
2669 uint32_t flags;
2670 char return_key[MEMCACHED_MAX_KEY];
2671 size_t return_key_length;
2672 char *return_value;
2673 size_t return_value_length;
2674 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2675 &return_value_length, &flags, &rc)))
2676 {
2677 test_false(return_value); // There are no keys to fetch, so the value should never be returned
2678 }
2679 test_compare(MEMCACHED_NOTFOUND, rc);
2680 test_zero(return_value_length);
2681 test_zero(return_key_length);
2682 test_false(return_key[0]);
2683 test_false(return_value);
2684
2685 memcached_free(memc_clone);
2686
2687 return TEST_SUCCESS;
2688 #endif
2689 }
2690
2691 test_return_t user_supplied_bug21(memcached_st *memc)
2692 {
2693 test_skip(TEST_SUCCESS, pre_binary(memc));
2694
2695 /* should work as of r580 */
2696 test_compare(TEST_SUCCESS,
2697 _user_supplied_bug21(memc, 10));
2698
2699 /* should fail as of r580 */
2700 test_compare(TEST_SUCCESS,
2701 _user_supplied_bug21(memc, 1000));
2702
2703 return TEST_SUCCESS;
2704 }
2705
2706 test_return_t output_ketama_weighted_keys(memcached_st *)
2707 {
2708 memcached_st *memc= memcached_create(NULL);
2709 test_true(memc);
2710
2711
2712 test_compare(MEMCACHED_SUCCESS,
2713 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true));
2714
2715 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2716 test_compare(value, uint64_t(1));
2717
2718 test_compare(MEMCACHED_SUCCESS,
2719 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5));
2720
2721 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2722 test_true(value == MEMCACHED_HASH_MD5);
2723
2724
2725 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
2726
2727 memcached_server_st *server_pool;
2728 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");
2729 memcached_server_push(memc, server_pool);
2730
2731 // @todo this needs to be refactored to actually test something.
2732 #if 0
2733 FILE *fp;
2734 if ((fp = fopen("ketama_keys.txt", "w")))
2735 {
2736 // noop
2737 } else {
2738 printf("cannot write to file ketama_keys.txt");
2739 return TEST_FAILURE;
2740 }
2741
2742 for (int x= 0; x < 10000; x++)
2743 {
2744 char key[10];
2745 snprintf(key, sizeof(key), "%d", x);
2746
2747 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
2748 char *hostname = memc->hosts[server_idx].hostname;
2749 in_port_t port = memc->hosts[server_idx].port;
2750 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
2751 memcached_server_instance_st instance=
2752 memcached_server_instance_by_position(memc, host_index);
2753 }
2754 fclose(fp);
2755 #endif
2756 memcached_server_list_free(server_pool);
2757 memcached_free(memc);
2758
2759 return TEST_SUCCESS;
2760 }
2761
2762
2763 test_return_t result_static(memcached_st *memc)
2764 {
2765 memcached_result_st result;
2766 memcached_result_st *result_ptr= memcached_result_create(memc, &result);
2767 test_false(result.options.is_allocated);
2768 test_true(memcached_is_initialized(&result));
2769 test_true(result_ptr);
2770 test_true(result_ptr == &result);
2771
2772 memcached_result_free(&result);
2773
2774 test_false(result.options.is_allocated);
2775 test_false(memcached_is_initialized(&result));
2776
2777 return TEST_SUCCESS;
2778 }
2779
2780 test_return_t result_alloc(memcached_st *memc)
2781 {
2782 memcached_result_st *result_ptr= memcached_result_create(memc, NULL);
2783 test_true(result_ptr);
2784 test_true(result_ptr->options.is_allocated);
2785 test_true(memcached_is_initialized(result_ptr));
2786 memcached_result_free(result_ptr);
2787
2788 return TEST_SUCCESS;
2789 }
2790
2791
2792 test_return_t add_host_test1(memcached_st *memc)
2793 {
2794 memcached_return_t rc;
2795 char servername[]= "0.example.com";
2796
2797 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
2798 test_true(servers);
2799 test_compare(1U, memcached_server_list_count(servers));
2800
2801 for (uint32_t x= 2; x < 20; x++)
2802 {
2803 char buffer[SMALL_STRING_LEN];
2804
2805 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
2806 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
2807 &rc);
2808 test_compare(MEMCACHED_SUCCESS, rc);
2809 test_compare(x, memcached_server_list_count(servers));
2810 }
2811
2812 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
2813 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
2814
2815 memcached_server_list_free(servers);
2816
2817 return TEST_SUCCESS;
2818 }
2819
2820
2821 static void my_free(const memcached_st *ptr, void *mem, void *context)
2822 {
2823 (void)context;
2824 (void)ptr;
2825 #ifdef HARD_MALLOC_TESTS
2826 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
2827 free(real_ptr);
2828 #else
2829 free(mem);
2830 #endif
2831 }
2832
2833
2834 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
2835 {
2836 (void)context;
2837 (void)ptr;
2838 #ifdef HARD_MALLOC_TESTS
2839 void *ret= malloc(size + 8);
2840 if (ret != NULL)
2841 {
2842 ret= (void*)((caddr_t)ret + 8);
2843 }
2844 #else
2845 void *ret= malloc(size);
2846 #endif
2847
2848 if (ret != NULL)
2849 {
2850 memset(ret, 0xff, size);
2851 }
2852
2853 return ret;
2854 }
2855
2856
2857 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *)
2858 {
2859 #ifdef HARD_MALLOC_TESTS
2860 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
2861 void *nmem= realloc(real_ptr, size + 8);
2862
2863 void *ret= NULL;
2864 if (nmem != NULL)
2865 {
2866 ret= (void*)((caddr_t)nmem + 8);
2867 }
2868
2869 return ret;
2870 #else
2871 (void)ptr;
2872 return realloc(mem, size);
2873 #endif
2874 }
2875
2876
2877 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *)
2878 {
2879 #ifdef HARD_MALLOC_TESTS
2880 void *mem= my_malloc(ptr, nelem * size);
2881 if (mem)
2882 {
2883 memset(mem, 0, nelem * size);
2884 }
2885
2886 return mem;
2887 #else
2888 (void)ptr;
2889 return calloc(nelem, size);
2890 #endif
2891 }
2892
2893 test_return_t selection_of_namespace_tests(memcached_st *memc)
2894 {
2895 memcached_return_t rc;
2896 const char *key= "mine";
2897 char *value;
2898
2899 /* Make sure be default none exists */
2900 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2901 test_null(value);
2902 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2903
2904 /* Test a clean set */
2905 test_compare(MEMCACHED_SUCCESS,
2906 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
2907
2908 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2909 test_true(value);
2910 test_memcmp(value, key, 4);
2911 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2912
2913 /* Test that we can turn it off */
2914 test_compare(MEMCACHED_SUCCESS,
2915 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
2916
2917 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2918 test_null(value);
2919 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2920
2921 /* Now setup for main test */
2922 test_compare(MEMCACHED_SUCCESS,
2923 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
2924
2925 value= (char *)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2926 test_true(value);
2927 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2928 test_memcmp(value, key, 4);
2929
2930 /* Set to Zero, and then Set to something too large */
2931 {
2932 char long_key[255];
2933 memset(long_key, 0, 255);
2934
2935 test_compare(MEMCACHED_SUCCESS,
2936 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
2937
2938 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2939 test_null(value);
2940 test_compare(MEMCACHED_SUCCESS, rc);
2941
2942 /* Test a long key for failure */
2943 /* TODO, extend test to determine based on setting, what result should be */
2944 strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key));
2945 test_compare(MEMCACHED_SUCCESS,
2946 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
2947
2948 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
2949 strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key));
2950 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
2951 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
2952
2953 /* Test for a bad prefix, but with a short key */
2954 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_INVALID_ARGUMENTS : MEMCACHED_SUCCESS,
2955 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1));
2956
2957 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
2958 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, "dog cat"));
2959 }
2960
2961 return TEST_SUCCESS;
2962 }
2963
2964 test_return_t set_namespace(memcached_st *memc)
2965 {
2966 memcached_return_t rc;
2967 const char *key= "mine";
2968 char *value;
2969
2970 // Make sure we default to a null namespace
2971 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2972 test_null(value);
2973 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2974
2975 /* Test a clean set */
2976 test_compare(MEMCACHED_SUCCESS,
2977 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
2978
2979 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2980 test_true(value);
2981 test_memcmp(value, key, 4);
2982 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2983
2984 return TEST_SUCCESS;
2985 }
2986
2987 test_return_t set_namespace_and_binary(memcached_st *memc)
2988 {
2989 test_return_if(pre_binary(memc));
2990 test_return_if(set_namespace(memc));
2991
2992 return TEST_SUCCESS;
2993 }
2994
2995 #ifdef MEMCACHED_ENABLE_DEPRECATED
2996 test_return_t deprecated_set_memory_alloc(memcached_st *memc)
2997 {
2998 void *test_ptr= NULL;
2999 void *cb_ptr= NULL;
3000 {
3001 memcached_malloc_fn malloc_cb= (memcached_malloc_fn)my_malloc;
3002 cb_ptr= *(void **)&malloc_cb;
3003 memcached_return_t rc;
3004
3005 test_compare(MEMCACHED_SUCCESS,
3006 memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr));
3007 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3008 test_compare(MEMCACHED_SUCCESS, rc);
3009 test_true(test_ptr == cb_ptr);
3010 }
3011
3012 {
3013 memcached_realloc_fn realloc_cb=
3014 (memcached_realloc_fn)my_realloc;
3015 cb_ptr= *(void **)&realloc_cb;
3016 memcached_return_t rc;
3017
3018 test_compare(MEMCACHED_SUCCESS,
3019 memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr));
3020 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3021 test_compare(MEMCACHED_SUCCESS, rc);
3022 test_true(test_ptr == cb_ptr);
3023 }
3024
3025 {
3026 memcached_free_fn free_cb=
3027 (memcached_free_fn)my_free;
3028 cb_ptr= *(void **)&free_cb;
3029 memcached_return_t rc;
3030
3031 test_compare(MEMCACHED_SUCCESS,
3032 memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr));
3033 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3034 test_compare(MEMCACHED_SUCCESS, rc);
3035 test_true(test_ptr == cb_ptr);
3036 }
3037
3038 return TEST_SUCCESS;
3039 }
3040 #endif
3041
3042
3043 test_return_t set_memory_alloc(memcached_st *memc)
3044 {
3045 test_compare(MEMCACHED_INVALID_ARGUMENTS,
3046 memcached_set_memory_allocators(memc, NULL, my_free,
3047 my_realloc, my_calloc, NULL));
3048
3049 test_compare(MEMCACHED_SUCCESS,
3050 memcached_set_memory_allocators(memc, my_malloc, my_free,
3051 my_realloc, my_calloc, NULL));
3052
3053 memcached_malloc_fn mem_malloc;
3054 memcached_free_fn mem_free;
3055 memcached_realloc_fn mem_realloc;
3056 memcached_calloc_fn mem_calloc;
3057 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3058 &mem_realloc, &mem_calloc);
3059
3060 test_true(mem_malloc == my_malloc);
3061 test_true(mem_realloc == my_realloc);
3062 test_true(mem_calloc == my_calloc);
3063 test_true(mem_free == my_free);
3064
3065 return TEST_SUCCESS;
3066 }
3067
3068 test_return_t enable_consistent_crc(memcached_st *memc)
3069 {
3070 test_return_t rc;
3071 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3072 memcached_hash_t hash;
3073 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3074 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3075 return rc;
3076
3077 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3078 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3079
3080 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3081
3082 if (hash != MEMCACHED_HASH_CRC)
3083 return TEST_SKIPPED;
3084
3085 return TEST_SUCCESS;
3086 }
3087
3088 test_return_t enable_consistent_hsieh(memcached_st *memc)
3089 {
3090 test_return_t rc;
3091 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3092 memcached_hash_t hash;
3093 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3094 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3095 {
3096 return rc;
3097 }
3098
3099 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3100 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3101
3102 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3103
3104 if (hash != MEMCACHED_HASH_HSIEH)
3105 return TEST_SKIPPED;
3106
3107
3108 return TEST_SUCCESS;
3109 }
3110
3111 test_return_t enable_cas(memcached_st *memc)
3112 {
3113 unsigned int set= 1;
3114
3115 if (libmemcached_util_version_check(memc, 1, 2, 4))
3116 {
3117 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3118
3119 return TEST_SUCCESS;
3120 }
3121
3122 return TEST_SKIPPED;
3123 }
3124
3125 test_return_t check_for_1_2_3(memcached_st *memc)
3126 {
3127 memcached_version(memc);
3128
3129 memcached_server_instance_st instance=
3130 memcached_server_instance_by_position(memc, 0);
3131
3132 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3133 or instance->minor_version > 2)
3134 {
3135 return TEST_SUCCESS;
3136 }
3137
3138 return TEST_SKIPPED;
3139 }
3140
3141 test_return_t MEMCACHED_BEHAVIOR_POLL_TIMEOUT_test(memcached_st *memc)
3142 {
3143 const uint64_t timeout= 100; // Not using, just checking that it sets
3144
3145 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3146
3147 test_compare(timeout, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT));
3148
3149 return TEST_SUCCESS;
3150 }
3151
3152 test_return_t noreply_test(memcached_st *memc)
3153 {
3154 test_compare(MEMCACHED_SUCCESS,
3155 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, true));
3156 test_compare(MEMCACHED_SUCCESS,
3157 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
3158 test_compare(MEMCACHED_SUCCESS,
3159 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
3160 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY));
3161 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS));
3162 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS));
3163
3164 memcached_return_t ret;
3165 for (int count= 0; count < 5; ++count)
3166 {
3167 for (size_t x= 0; x < 100; ++x)
3168 {
3169 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
3170 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
3171 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
3172
3173 size_t len= (size_t)check_length;
3174
3175 switch (count)
3176 {
3177 case 0:
3178 ret= memcached_add(memc, key, len, key, len, 0, 0);
3179 break;
3180 case 1:
3181 ret= memcached_replace(memc, key, len, key, len, 0, 0);
3182 break;
3183 case 2:
3184 ret= memcached_set(memc, key, len, key, len, 0, 0);
3185 break;
3186 case 3:
3187 ret= memcached_append(memc, key, len, key, len, 0, 0);
3188 break;
3189 case 4:
3190 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
3191 break;
3192 default:
3193 test_true(count);
3194 break;
3195 }
3196 test_true_got(ret == MEMCACHED_SUCCESS or ret == MEMCACHED_BUFFERED,
3197 memcached_strerror(NULL, ret));
3198 }
3199
3200 /*
3201 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3202 ** API and is _ONLY_ done this way to verify that the library works the
3203 ** way it is supposed to do!!!!
3204 */
3205 #if 0
3206 int no_msg=0;
3207 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
3208 {
3209 memcached_server_instance_st instance=
3210 memcached_server_instance_by_position(memc, x);
3211 no_msg+=(int)(instance->cursor_active);
3212 }
3213
3214 test_true(no_msg == 0);
3215 #endif
3216 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
3217
3218 /*
3219 ** Now validate that all items was set properly!
3220 */
3221 for (size_t x= 0; x < 100; ++x)
3222 {
3223 char key[10];
3224
3225 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
3226
3227 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
3228
3229 size_t len= (size_t)check_length;
3230 size_t length;
3231 uint32_t flags;
3232 char* value=memcached_get(memc, key, strlen(key),
3233 &length, &flags, &ret);
3234 // For the moment we will just go to the next key
3235 if (MEMCACHED_TIMEOUT == ret)
3236 {
3237 continue;
3238 }
3239 test_true_hint(ret == MEMCACHED_SUCCESS and value != NULL, memcached_last_error_message(memc));
3240 switch (count)
3241 {
3242 case 0: /* FALLTHROUGH */
3243 case 1: /* FALLTHROUGH */
3244 case 2:
3245 test_true(strncmp(value, key, len) == 0);
3246 test_true(len == length);
3247 break;
3248 case 3:
3249 test_true(length == len * 2);
3250 break;
3251 case 4:
3252 test_true(length == len * 3);
3253 break;
3254 default:
3255 test_true(count);
3256 break;
3257 }
3258 free(value);
3259 }
3260 }
3261
3262 /* Try setting an illegal cas value (should not return an error to
3263 * the caller (because we don't expect a return message from the server)
3264 */
3265 const char* keys[]= {"0"};
3266 size_t lengths[]= {1};
3267 size_t length;
3268 uint32_t flags;
3269 memcached_result_st results_obj;
3270 memcached_result_st *results;
3271 test_compare(MEMCACHED_SUCCESS,
3272 memcached_mget(memc, keys, lengths, 1));
3273
3274 results= memcached_result_create(memc, &results_obj);
3275 test_true(results);
3276 results= memcached_fetch_result(memc, &results_obj, &ret);
3277 test_true(results);
3278 test_compare(MEMCACHED_SUCCESS, ret);
3279 uint64_t cas= memcached_result_cas(results);
3280 memcached_result_free(&results_obj);
3281
3282 test_compare(MEMCACHED_SUCCESS,
3283 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
3284
3285 /*
3286 * The item will have a new cas value, so try to set it again with the old
3287 * value. This should fail!
3288 */
3289 test_compare(MEMCACHED_SUCCESS,
3290 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
3291 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3292 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3293 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
3294 free(value);
3295
3296 return TEST_SUCCESS;
3297 }
3298
3299 test_return_t analyzer_test(memcached_st *memc)
3300 {
3301 memcached_analysis_st *report;
3302 memcached_return_t rc;
3303
3304 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
3305 test_compare(MEMCACHED_SUCCESS, rc);
3306 test_true(memc_stat);
3307
3308 report= memcached_analyze(memc, memc_stat, &rc);
3309 test_compare(MEMCACHED_SUCCESS, rc);
3310 test_true(report);
3311
3312 free(report);
3313 memcached_stat_free(NULL, memc_stat);
3314
3315 return TEST_SUCCESS;
3316 }
3317
3318 test_return_t util_version_test(memcached_st *memc)
3319 {
3320 test_compare_hint(MEMCACHED_SUCCESS, memcached_version(memc), memcached_last_error_message(memc));
3321 test_true(libmemcached_util_version_check(memc, 0, 0, 0));
3322
3323 bool if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
3324
3325 // We expect failure
3326 if (if_successful)
3327 {
3328 fprintf(stderr, "\n----------------------------------------------------------------------\n");
3329 fprintf(stderr, "\nDumping Server Information\n\n");
3330 memcached_server_fn callbacks[1];
3331
3332 callbacks[0]= dump_server_information;
3333 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
3334 fprintf(stderr, "\n----------------------------------------------------------------------\n");
3335 }
3336 test_true(if_successful == false);
3337
3338 memcached_server_instance_st instance=
3339 memcached_server_instance_by_position(memc, 0);
3340
3341 memcached_version(memc);
3342
3343 // We only use one binary when we test, so this should be just fine.
3344 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
3345 test_true(if_successful == true);
3346
3347 if (instance->micro_version > 0)
3348 {
3349 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
3350 }
3351 else if (instance->minor_version > 0)
3352 {
3353 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
3354 }
3355 else if (instance->major_version > 0)
3356 {
3357 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
3358 }
3359
3360 test_true(if_successful == true);
3361
3362 if (instance->micro_version > 0)
3363 {
3364 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
3365 }
3366 else if (instance->minor_version > 0)
3367 {
3368 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
3369 }
3370 else if (instance->major_version > 0)
3371 {
3372 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
3373 }
3374
3375 test_true(if_successful == false);
3376
3377 return TEST_SUCCESS;
3378 }
3379
3380 test_return_t getpid_connection_failure_test(memcached_st *memc)
3381 {
3382 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
3383 memcached_return_t rc;
3384 memcached_server_instance_st instance=
3385 memcached_server_instance_by_position(memc, 0);
3386
3387 // Test both the version that returns a code, and the one that does not.
3388 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3389 memcached_server_port(instance) -1, NULL) == -1);
3390
3391 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3392 memcached_server_port(instance) -1, &rc) == -1);
3393 test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_strerror(memc, rc));
3394
3395 return TEST_SUCCESS;
3396 }
3397
3398
3399 test_return_t getpid_test(memcached_st *memc)
3400 {
3401 memcached_return_t rc;
3402 memcached_server_instance_st instance=
3403 memcached_server_instance_by_position(memc, 0);
3404
3405 // Test both the version that returns a code, and the one that does not.
3406 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3407 memcached_server_port(instance), NULL) > -1);
3408
3409 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3410 memcached_server_port(instance), &rc) > -1);
3411 test_compare(MEMCACHED_SUCCESS, rc);
3412
3413 return TEST_SUCCESS;
3414 }
3415
3416 static memcached_return_t ping_each_server(const memcached_st*,
3417 const memcached_server_st *instance,
3418 void*)
3419 {
3420 // Test both the version that returns a code, and the one that does not.
3421 memcached_return_t rc;
3422 if (libmemcached_util_ping(memcached_server_name(instance),
3423 memcached_server_port(instance), &rc) == false)
3424 {
3425 throw libtest::fatal(LIBYATL_DEFAULT_PARAM, "%s:%d %s", memcached_server_name(instance),
3426 memcached_server_port(instance), memcached_strerror(NULL, rc));
3427 }
3428
3429 if (libmemcached_util_ping(memcached_server_name(instance),
3430 memcached_server_port(instance), NULL) == false)
3431 {
3432 throw libtest::fatal(LIBYATL_DEFAULT_PARAM, "%s:%d", memcached_server_name(instance), memcached_server_port(instance));
3433 }
3434
3435 return MEMCACHED_SUCCESS;
3436 }
3437
3438 test_return_t libmemcached_util_ping_TEST(memcached_st *memc)
3439 {
3440 memcached_server_fn callbacks[1]= { ping_each_server };
3441 memcached_server_cursor(memc, callbacks, NULL, 1);
3442
3443 return TEST_SUCCESS;
3444 }
3445
3446
3447 #if 0
3448 test_return_t hash_sanity_test (memcached_st *memc)
3449 {
3450 (void)memc;
3451
3452 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
3453 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
3454 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
3455 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
3456 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
3457 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
3458 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
3459 #ifdef HAVE_HSIEH_HASH
3460 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
3461 #endif
3462 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
3463 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
3464 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
3465
3466 return TEST_SUCCESS;
3467 }
3468 #endif
3469
3470 test_return_t hsieh_avaibility_test (memcached_st *memc)
3471 {
3472 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
3473
3474 test_compare(MEMCACHED_SUCCESS,
3475 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
3476 (uint64_t)MEMCACHED_HASH_HSIEH));
3477
3478 return TEST_SUCCESS;
3479 }
3480
3481 test_return_t murmur_avaibility_test (memcached_st *memc)
3482 {
3483 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
3484
3485 test_compare(MEMCACHED_SUCCESS,
3486 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR));
3487
3488 return TEST_SUCCESS;
3489 }
3490
3491 test_return_t one_at_a_time_run (memcached_st *)
3492 {
3493 uint32_t x;
3494 const char **ptr;
3495
3496 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3497 {
3498 test_compare(one_at_a_time_values[x],
3499 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT));
3500 }
3501
3502 return TEST_SUCCESS;
3503 }
3504
3505 test_return_t md5_run (memcached_st *)
3506 {
3507 uint32_t x;
3508 const char **ptr;
3509
3510 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3511 {
3512 test_compare(md5_values[x],
3513 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5));
3514 }
3515
3516 return TEST_SUCCESS;
3517 }
3518
3519 test_return_t crc_run (memcached_st *)
3520 {
3521 uint32_t x;
3522 const char **ptr;
3523
3524 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3525 {
3526 test_compare(crc_values[x],
3527 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC));
3528 }
3529
3530 return TEST_SUCCESS;
3531 }
3532
3533 test_return_t fnv1_64_run (memcached_st *)
3534 {
3535 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1_64));
3536
3537 uint32_t x;
3538 const char **ptr;
3539
3540 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3541 {
3542 test_compare(fnv1_64_values[x],
3543 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64));
3544 }
3545
3546 return TEST_SUCCESS;
3547 }
3548
3549 test_return_t fnv1a_64_run (memcached_st *)
3550 {
3551 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1A_64));
3552
3553 uint32_t x;
3554 const char **ptr;
3555
3556 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3557 {
3558 test_compare(fnv1a_64_values[x],
3559 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64));
3560 }
3561
3562 return TEST_SUCCESS;
3563 }
3564
3565 test_return_t fnv1_32_run (memcached_st *)
3566 {
3567 uint32_t x;
3568 const char **ptr;
3569
3570 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3571 {
3572 test_compare(fnv1_32_values[x],
3573 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32));
3574 }
3575
3576 return TEST_SUCCESS;
3577 }
3578
3579 test_return_t fnv1a_32_run (memcached_st *)
3580 {
3581 uint32_t x;
3582 const char **ptr;
3583
3584 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3585 {
3586 test_compare(fnv1a_32_values[x],
3587 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32));
3588 }
3589
3590 return TEST_SUCCESS;
3591 }
3592
3593 test_return_t hsieh_run (memcached_st *)
3594 {
3595 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
3596
3597 uint32_t x;
3598 const char **ptr;
3599
3600 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3601 {
3602 test_compare(hsieh_values[x],
3603 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH));
3604 }
3605
3606 return TEST_SUCCESS;
3607 }
3608
3609 test_return_t murmur_run (memcached_st *)
3610 {
3611 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
3612
3613 #ifdef WORDS_BIGENDIAN
3614 (void)murmur_values;
3615 return TEST_SKIPPED;
3616 #else
3617 uint32_t x;
3618 const char **ptr;
3619
3620 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3621 {
3622 test_compare(murmur_values[x],
3623 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR));
3624 }
3625
3626 return TEST_SUCCESS;
3627 #endif
3628 }
3629
3630 test_return_t jenkins_run (memcached_st *)
3631 {
3632 uint32_t x;
3633 const char **ptr;
3634
3635 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3636 {
3637 test_compare(jenkins_values[x],
3638 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS));
3639 }
3640
3641 return TEST_SUCCESS;
3642 }
3643
3644 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *)
3645 {
3646 return libhashkit_md5(string, string_length);
3647 }
3648
3649 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *)
3650 {
3651 return libhashkit_crc32(string, string_length);
3652 }
3653
3654 test_return_t memcached_get_hashkit_test (memcached_st *)
3655 {
3656 uint32_t x;
3657 const char **ptr;
3658 hashkit_st new_kit;
3659
3660 memcached_st *memc= memcached(test_literal_param("--server=localhost:1 --server=localhost:2 --server=localhost:3 --server=localhost:4 --server=localhost5 --DISTRIBUTION=modula"));
3661
3662 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};
3663 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};
3664
3665 const hashkit_st *kit= memcached_get_hashkit(memc);
3666
3667 hashkit_clone(&new_kit, kit);
3668 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL));
3669
3670 memcached_set_hashkit(memc, &new_kit);
3671
3672 /*
3673 Verify Setting the hash.
3674 */
3675 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3676 {
3677 uint32_t hash_val;
3678
3679 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
3680 test_compare_got(md5_values[x], hash_val, *ptr);
3681 }
3682
3683
3684 /*
3685 Now check memcached_st.
3686 */
3687 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3688 {
3689 uint32_t hash_val;
3690
3691 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
3692 test_compare_got(md5_hosts[x], hash_val, *ptr);
3693 }
3694
3695 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL));
3696
3697 memcached_set_hashkit(memc, &new_kit);
3698
3699 /*
3700 Verify Setting the hash.
3701 */
3702 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3703 {
3704 uint32_t hash_val;
3705
3706 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
3707 test_true(crc_values[x] == hash_val);
3708 }
3709
3710 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3711 {
3712 uint32_t hash_val;
3713
3714 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
3715 test_compare(crc_hosts[x], hash_val);
3716 }
3717
3718 memcached_free(memc);
3719
3720 return TEST_SUCCESS;
3721 }
3722
3723 /*
3724 Test case adapted from John Gorman <johngorman2@gmail.com>
3725
3726 We are testing the error condition when we connect to a server via memcached_get()
3727 but find that the server is not available.
3728 */
3729 test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *)
3730 {
3731 size_t len;
3732 uint32_t flags;
3733 memcached_return rc;
3734
3735 // Create a handle.
3736 memcached_st *tl_memc_h= memcached(test_literal_param("--server=localhost:9898 --server=localhost:9899")); // This server should not exist
3737
3738 // See if memcached is reachable.
3739 char *value= memcached_get(tl_memc_h,
3740 test_literal_param(__func__),
3741 &len, &flags, &rc);
3742
3743 test_false(value);
3744 test_zero(len);
3745 test_true(memcached_failed(rc));
3746
3747 memcached_free(tl_memc_h);
3748
3749 return TEST_SUCCESS;
3750 }
3751
3752 /*
3753 We connect to a server which exists, but search for a key that does not exist.
3754 */
3755 test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
3756 {
3757 size_t len;
3758 uint32_t flags;
3759 memcached_return rc;
3760
3761 // See if memcached is reachable.
3762 char *value= memcached_get(memc,
3763 test_literal_param(__func__),
3764 &len, &flags, &rc);
3765
3766 test_false(value);
3767 test_zero(len);
3768 test_compare(MEMCACHED_NOTFOUND, rc);
3769
3770 return TEST_SUCCESS;
3771 }
3772
3773 /*
3774 Test case adapted from John Gorman <johngorman2@gmail.com>
3775
3776 We are testing the error condition when we connect to a server via memcached_get_by_key()
3777 but find that the server is not available.
3778 */
3779 test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *)
3780 {
3781 size_t len;
3782 uint32_t flags;
3783 memcached_return rc;
3784
3785 // Create a handle.
3786 memcached_st *tl_memc_h= memcached_create(NULL);
3787 memcached_server_st *servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
3788 memcached_server_push(tl_memc_h, servers);
3789 memcached_server_list_free(servers);
3790
3791 // See if memcached is reachable.
3792 char *value= memcached_get_by_key(tl_memc_h,
3793 test_literal_param(__func__), // Key
3794 test_literal_param(__func__), // Value
3795 &len, &flags, &rc);
3796
3797 test_false(value);
3798 test_zero(len);
3799 test_true(memcached_failed(rc));
3800
3801 memcached_free(tl_memc_h);
3802
3803 return TEST_SUCCESS;
3804 }
3805
3806 /*
3807 We connect to a server which exists, but search for a key that does not exist.
3808 */
3809 test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
3810 {
3811 size_t len;
3812 uint32_t flags;
3813 memcached_return rc;
3814
3815 // See if memcached is reachable.
3816 char *value= memcached_get_by_key(memc,
3817 test_literal_param(__func__), // Key
3818 test_literal_param(__func__), // Value
3819 &len, &flags, &rc);
3820
3821 test_false(value);
3822 test_zero(len);
3823 test_compare(MEMCACHED_NOTFOUND, rc);
3824
3825 return TEST_SUCCESS;
3826 }
3827
3828 test_return_t regression_bug_434484(memcached_st *memc)
3829 {
3830 test_skip(TEST_SUCCESS, pre_binary(memc));
3831
3832 test_compare(MEMCACHED_NOTSTORED,
3833 memcached_append(memc,
3834 test_literal_param(__func__), // Key
3835 test_literal_param(__func__), // Value
3836 0, 0));
3837
3838 libtest::vchar_t data;
3839 data.resize(2048 * 1024);
3840 test_compare(MEMCACHED_E2BIG,
3841 memcached_set(memc,
3842 test_literal_param(__func__), // Key
3843 &data[0], data.size(), 0, 0));
3844
3845 return TEST_SUCCESS;
3846 }
3847
3848 test_return_t regression_bug_434843(memcached_st *original_memc)
3849 {
3850 test_skip(TEST_SUCCESS, pre_binary(original_memc));
3851
3852 memcached_return_t rc;
3853 size_t counter= 0;
3854 memcached_execute_fn callbacks[]= { &callback_counter };
3855
3856 /*
3857 * I only want to hit only _one_ server so I know the number of requests I'm
3858 * sending in the pipleine to the server. Let's try to do a multiget of
3859 * 1024 (that should satisfy most users don't you think?). Future versions
3860 * will include a mget_execute function call if you need a higher number.
3861 */
3862 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
3863
3864 keys_st keys(1024);
3865
3866 /*
3867 * Run two times.. the first time we should have 100% cache miss,
3868 * and the second time we should have 100% cache hits
3869 */
3870 for (ptrdiff_t y= 0; y < 2; y++)
3871 {
3872 test_compare(MEMCACHED_SUCCESS,
3873 memcached_mget(memc, keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
3874
3875 // One the first run we should get a NOT_FOUND, but on the second some data
3876 // should be returned.
3877 test_compare(y ? MEMCACHED_SUCCESS : MEMCACHED_NOTFOUND,
3878 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
3879
3880 if (y == 0)
3881 {
3882 /* The first iteration should give me a 100% cache miss. verify that*/
3883 char blob[1024]= { 0 };
3884
3885 test_false(counter);
3886
3887 for (size_t x= 0; x < keys.size(); ++x)
3888 {
3889 rc= memcached_add(memc,
3890 keys.key_at(x), keys.length_at(x),
3891 blob, sizeof(blob), 0, 0);
3892 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
3893 }
3894 }
3895 else
3896 {
3897 /* Verify that we received all of the key/value pairs */
3898 test_compare(counter, keys.size());
3899 }
3900 }
3901
3902 memcached_free(memc);
3903
3904 return TEST_SUCCESS;
3905 }
3906
3907 test_return_t regression_bug_434843_buffered(memcached_st *memc)
3908 {
3909 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
3910
3911 return regression_bug_434843(memc);
3912 }
3913
3914 test_return_t regression_bug_421108(memcached_st *memc)
3915 {
3916 memcached_return_t rc;
3917 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
3918 test_compare(MEMCACHED_SUCCESS, rc);
3919
3920 char *bytes_str= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
3921 test_compare(MEMCACHED_SUCCESS, rc);
3922 test_true(bytes_str);
3923 char *bytes_read_str= memcached_stat_get_value(memc, memc_stat,
3924 "bytes_read", &rc);
3925 test_compare(MEMCACHED_SUCCESS, rc);
3926 test_true(bytes_read_str);
3927
3928 char *bytes_written_str= memcached_stat_get_value(memc, memc_stat,
3929 "bytes_written", &rc);
3930 test_compare(MEMCACHED_SUCCESS, rc);
3931 test_true(bytes_written_str);
3932
3933 unsigned long long bytes= strtoull(bytes_str, 0, 10);
3934 unsigned long long bytes_read= strtoull(bytes_read_str, 0, 10);
3935 unsigned long long bytes_written= strtoull(bytes_written_str, 0, 10);
3936
3937 test_true(bytes != bytes_read);
3938 test_true(bytes != bytes_written);
3939
3940 /* Release allocated resources */
3941 free(bytes_str);
3942 free(bytes_read_str);
3943 free(bytes_written_str);
3944 memcached_stat_free(NULL, memc_stat);
3945
3946 return TEST_SUCCESS;
3947 }
3948
3949 /*
3950 * The test case isn't obvious so I should probably document why
3951 * it works the way it does. Bug 442914 was caused by a bug
3952 * in the logic in memcached_purge (it did not handle the case
3953 * where the number of bytes sent was equal to the watermark).
3954 * In this test case, create messages so that we hit that case
3955 * and then disable noreply mode and issue a new command to
3956 * verify that it isn't stuck. If we change the format for the
3957 * delete command or the watermarks, we need to update this
3958 * test....
3959 */
3960 test_return_t regression_bug_442914(memcached_st *original_memc)
3961 {
3962 test_skip(original_memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
3963
3964 memcached_st* memc= create_single_instance_memcached(original_memc, "--NOREPLY --TCP-NODELAY");
3965
3966 for (uint32_t x= 0; x < 250; ++x)
3967 {
3968 char key[250];
3969 size_t len= (size_t)snprintf(key, sizeof(key), "%0250u", x);
3970 memcached_return_t rc= memcached_delete(memc, key, len, 0);
3971 char error_buffer[2048]= { 0 };
3972 snprintf(error_buffer, sizeof(error_buffer), "%s key: %s", memcached_last_error_message(memc), key);
3973 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, error_buffer);
3974 }
3975
3976 // Delete, and then delete again to look for not found
3977 {
3978 char key[250];
3979 size_t len= snprintf(key, sizeof(key), "%037u", 251U);
3980 memcached_return_t rc= memcached_delete(memc, key, len, 0);
3981 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
3982
3983 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, false));
3984 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, key, len, 0));
3985 }
3986
3987 memcached_free(memc);
3988
3989 return TEST_SUCCESS;
3990 }
3991
3992 test_return_t regression_bug_447342(memcached_st *memc)
3993 {
3994 if (memcached_server_count(memc) < 3 or pre_replication(memc) != TEST_SUCCESS)
3995 {
3996 return TEST_SKIPPED;
3997 }
3998
3999 test_compare(MEMCACHED_SUCCESS,
4000 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2));
4001
4002 keys_st keys(100);
4003
4004 for (size_t x= 0; x < keys.size(); ++x)
4005 {
4006 test_compare(MEMCACHED_SUCCESS,
4007 memcached_set(memc,
4008 keys.key_at(x), keys.length_at(x), // Keys
4009 keys.key_at(x), keys.length_at(x), // Values
4010 0, 0));
4011 }
4012
4013 /*
4014 ** We are using the quiet commands to store the replicas, so we need
4015 ** to ensure that all of them are processed before we can continue.
4016 ** In the test we go directly from storing the object to trying to
4017 ** receive the object from all of the different servers, so we
4018 ** could end up in a race condition (the memcached server hasn't yet
4019 ** processed the quiet command from the replication set when it process
4020 ** the request from the other client (created by the clone)). As a
4021 ** workaround for that we call memcached_quit to send the quit command
4022 ** to the server and wait for the response ;-) If you use the test code
4023 ** as an example for your own code, please note that you shouldn't need
4024 ** to do this ;-)
4025 */
4026 memcached_quit(memc);
4027
4028 /* Verify that all messages are stored, and we didn't stuff too much
4029 * into the servers
4030 */
4031 test_compare(MEMCACHED_SUCCESS,
4032 memcached_mget(memc,
4033 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4034
4035 unsigned int counter= 0;
4036 memcached_execute_fn callbacks[]= { &callback_counter };
4037 test_compare(MEMCACHED_SUCCESS,
4038 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4039
4040 /* Verify that we received all of the key/value pairs */
4041 test_compare(counter, keys.size());
4042
4043 memcached_quit(memc);
4044 /*
4045 * Don't do the following in your code. I am abusing the internal details
4046 * within the library, and this is not a supported interface.
4047 * This is to verify correct behavior in the library. Fake that two servers
4048 * are dead..
4049 */
4050 memcached_server_instance_st instance_one= memcached_server_instance_by_position(memc, 0);
4051 memcached_server_instance_st instance_two= memcached_server_instance_by_position(memc, 2);
4052 in_port_t port0= instance_one->port;
4053 in_port_t port2= instance_two->port;
4054
4055 ((memcached_server_write_instance_st)instance_one)->port= 0;
4056 ((memcached_server_write_instance_st)instance_two)->port= 0;
4057
4058 test_compare(MEMCACHED_SUCCESS,
4059 memcached_mget(memc,
4060 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4061
4062 counter= 0;
4063 test_compare(MEMCACHED_SUCCESS,
4064 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4065 test_compare(counter, keys.size());
4066
4067 /* restore the memc handle */
4068 ((memcached_server_write_instance_st)instance_one)->port= port0;
4069 ((memcached_server_write_instance_st)instance_two)->port= port2;
4070
4071 memcached_quit(memc);
4072
4073 /* Remove half of the objects */
4074 for (size_t x= 0; x < keys.size(); ++x)
4075 {
4076 if (x & 1)
4077 {
4078 test_compare(MEMCACHED_SUCCESS,
4079 memcached_delete(memc, keys.key_at(x), keys.length_at(x), 0));
4080 }
4081 }
4082
4083 memcached_quit(memc);
4084 ((memcached_server_write_instance_st)instance_one)->port= 0;
4085 ((memcached_server_write_instance_st)instance_two)->port= 0;
4086
4087 /* now retry the command, this time we should have cache misses */
4088 test_compare(MEMCACHED_SUCCESS,
4089 memcached_mget(memc,
4090 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4091
4092 counter= 0;
4093 test_compare(MEMCACHED_SUCCESS,
4094 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4095 test_compare(counter, (unsigned int)(keys.size() >> 1));
4096
4097 /* restore the memc handle */
4098 ((memcached_server_write_instance_st)instance_one)->port= port0;
4099 ((memcached_server_write_instance_st)instance_two)->port= port2;
4100
4101 return TEST_SUCCESS;
4102 }
4103
4104 test_return_t regression_bug_463297(memcached_st *memc)
4105 {
4106 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc, "foo", 3, 1));
4107
4108 // Since we blocked timed delete, this test is no longer valid.
4109 #if 0
4110 memcached_st *memc_clone= memcached_clone(NULL, memc);
4111 test_true(memc_clone);
4112 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
4113
4114 memcached_server_instance_st instance=
4115 memcached_server_instance_by_position(memc_clone, 0);
4116
4117 if (instance->major_version > 1 ||
4118 (instance->major_version == 1 &&
4119 instance->minor_version > 2))
4120 {
4121 /* Binary protocol doesn't support deferred delete */
4122 memcached_st *bin_clone= memcached_clone(NULL, memc);
4123 test_true(bin_clone);
4124 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4125 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(bin_clone, "foo", 3, 1));
4126 memcached_free(bin_clone);
4127
4128 memcached_quit(memc_clone);
4129
4130 /* If we know the server version, deferred delete should fail
4131 * with invalid arguments */
4132 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc_clone, "foo", 3, 1));
4133
4134 /* If we don't know the server version, we should get a protocol error */
4135 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
4136
4137 /* but there is a bug in some of the memcached servers (1.4) that treats
4138 * the counter as noreply so it doesn't send the proper error message
4139 */
4140 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4141
4142 /* And buffered mode should be disabled and we should get protocol error */
4143 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
4144 rc= memcached_delete(memc, "foo", 3, 1);
4145 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4146
4147 /* Same goes for noreply... */
4148 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
4149 rc= memcached_delete(memc, "foo", 3, 1);
4150 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4151
4152 /* but a normal request should go through (and be buffered) */
4153 test_compare(MEMCACHED_BUFFERED, (rc= memcached_delete(memc, "foo", 3, 0)));
4154 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
4155
4156 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0));
4157 /* unbuffered noreply should be success */
4158 test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
4159 /* unbuffered with reply should be not found... */
4160 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
4161 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, "foo", 3, 0));
4162 }
4163
4164 memcached_free(memc_clone);
4165 #endif
4166
4167 return TEST_SUCCESS;
4168 }
4169
4170
4171 /* Test memcached_server_get_last_disconnect
4172 * For a working server set, shall be NULL
4173 * For a set of non existing server, shall not be NULL
4174 */
4175 test_return_t test_get_last_disconnect(memcached_st *memc)
4176 {
4177 memcached_return_t rc;
4178 memcached_server_instance_st disconnected_server;
4179
4180 /* With the working set of server */
4181 const char *key= "marmotte";
4182 const char *value= "milka";
4183
4184 memcached_reset_last_disconnected_server(memc);
4185 test_false(memc->last_disconnected_server);
4186 rc= memcached_set(memc, key, strlen(key),
4187 value, strlen(value),
4188 (time_t)0, (uint32_t)0);
4189 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4190
4191 disconnected_server = memcached_server_get_last_disconnect(memc);
4192 test_false(disconnected_server);
4193
4194 /* With a non existing server */
4195 memcached_st *mine;
4196 memcached_server_st *servers;
4197
4198 const char *server_list= "localhost:9";
4199
4200 servers= memcached_servers_parse(server_list);
4201 test_true(servers);
4202 mine= memcached_create(NULL);
4203 rc= memcached_server_push(mine, servers);
4204 test_compare(MEMCACHED_SUCCESS, rc);
4205 memcached_server_list_free(servers);
4206 test_true(mine);
4207
4208 rc= memcached_set(mine, key, strlen(key),
4209 value, strlen(value),
4210 (time_t)0, (uint32_t)0);
4211 test_true(memcached_failed(rc));
4212
4213 disconnected_server= memcached_server_get_last_disconnect(mine);
4214 test_true_got(disconnected_server, memcached_strerror(mine, rc));
4215 test_compare(in_port_t(9), memcached_server_port(disconnected_server));
4216 test_false(strncmp(memcached_server_name(disconnected_server),"localhost",9));
4217
4218 memcached_quit(mine);
4219 memcached_free(mine);
4220
4221 return TEST_SUCCESS;
4222 }
4223
4224 test_return_t test_multiple_get_last_disconnect(memcached_st *)
4225 {
4226 const char *server_string= "--server=localhost:8888 --server=localhost:8889 --server=localhost:8890 --server=localhost:8891 --server=localhost:8892";
4227 char buffer[BUFSIZ];
4228
4229 test_compare(MEMCACHED_SUCCESS,
4230 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
4231
4232 memcached_st *memc= memcached(server_string, strlen(server_string));
4233 test_true(memc);
4234
4235 // We will just use the error strings as our keys
4236 uint32_t counter= 100;
4237 while (--counter)
4238 {
4239 for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x)
4240 {
4241 const char *msg= memcached_strerror(memc, memcached_return_t(x));
4242 memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
4243 test_true_got((ret == MEMCACHED_CONNECTION_FAILURE or ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED), memcached_last_error_message(memc));
4244
4245 memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc);
4246 test_true(disconnected_server);
4247 test_strcmp("localhost", memcached_server_name(disconnected_server));
4248 test_true(memcached_server_port(disconnected_server) >= 8888 and memcached_server_port(disconnected_server) <= 8892);
4249
4250 if (random() % 2)
4251 {
4252 memcached_reset_last_disconnected_server(memc);
4253 }
4254 }
4255 }
4256
4257 memcached_free(memc);
4258
4259 return TEST_SUCCESS;
4260 }
4261
4262 test_return_t test_verbosity(memcached_st *memc)
4263 {
4264 memcached_verbosity(memc, 3);
4265
4266 return TEST_SUCCESS;
4267 }
4268
4269
4270 static memcached_return_t stat_printer(memcached_server_instance_st server,
4271 const char *key, size_t key_length,
4272 const char *value, size_t value_length,
4273 void *context)
4274 {
4275 (void)server;
4276 (void)context;
4277 (void)key;
4278 (void)key_length;
4279 (void)value;
4280 (void)value_length;
4281
4282 return MEMCACHED_SUCCESS;
4283 }
4284
4285 test_return_t memcached_stat_execute_test(memcached_st *memc)
4286 {
4287 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
4288 test_compare(MEMCACHED_SUCCESS, rc);
4289
4290 test_compare(MEMCACHED_SUCCESS,
4291 memcached_stat_execute(memc, "slabs", stat_printer, NULL));
4292
4293 test_compare(MEMCACHED_SUCCESS,
4294 memcached_stat_execute(memc, "items", stat_printer, NULL));
4295
4296 test_compare(MEMCACHED_SUCCESS,
4297 memcached_stat_execute(memc, "sizes", stat_printer, NULL));
4298
4299 return TEST_SUCCESS;
4300 }
4301
4302 /*
4303 * This test ensures that the failure counter isn't incremented during
4304 * normal termination of the memcached instance.
4305 */
4306 test_return_t wrong_failure_counter_test(memcached_st *original_memc)
4307 {
4308 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
4309
4310 /* Ensure that we are connected to the server by setting a value */
4311 memcached_return_t rc= memcached_set(memc,
4312 test_literal_param(__func__), // Key
4313 test_literal_param(__func__), // Value
4314 time_t(0), uint32_t(0));
4315 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
4316
4317
4318 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
4319
4320 /* The test is to see that the memcached_quit doesn't increase the
4321 * the server failure conter, so let's ensure that it is zero
4322 * before sending quit
4323 */
4324 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
4325
4326 memcached_quit(memc);
4327
4328 /* Verify that it memcached_quit didn't increment the failure counter
4329 * Please note that this isn't bullet proof, because an error could
4330 * occur...
4331 */
4332 test_zero(instance->server_failure_counter);
4333
4334 memcached_free(memc);
4335
4336 return TEST_SUCCESS;
4337 }
4338
4339 /*
4340 * This tests ensures expected disconnections (for some behavior changes
4341 * for instance) do not wrongly increase failure counter
4342 */
4343 test_return_t wrong_failure_counter_two_test(memcached_st *memc)
4344 {
4345 /* Set value to force connection to the server */
4346 const char *key= "marmotte";
4347 const char *value= "milka";
4348
4349 test_compare_hint(MEMCACHED_SUCCESS,
4350 memcached_set(memc, key, strlen(key),
4351 value, strlen(value),
4352 (time_t)0, (uint32_t)0),
4353 memcached_last_error_message(memc));
4354
4355
4356 /* put failure limit to 1 */
4357 test_compare(MEMCACHED_SUCCESS,
4358 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, true));
4359
4360 /* Put a retry timeout to effectively activate failure_limit effect */
4361 test_compare(MEMCACHED_SUCCESS,
4362 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, true));
4363
4364 /* change behavior that triggers memcached_quit()*/
4365 test_compare(MEMCACHED_SUCCESS,
4366 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true));
4367
4368
4369 /* Check if we still are connected */
4370 uint32_t flags;
4371 size_t string_length;
4372 memcached_return rc;
4373 char *string= memcached_get(memc, key, strlen(key),
4374 &string_length, &flags, &rc);
4375
4376 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
4377 test_true(string);
4378 free(string);
4379
4380 return TEST_SUCCESS;
4381 }
4382
4383 test_return_t regression_996813_TEST(memcached_st *)
4384 {
4385 memcached_st* memc= memcached_create(NULL);
4386
4387 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
4388 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1));
4389 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
4390 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4391 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1));
4392 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 300));
4393 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 30));
4394
4395 // We will never connect to these servers
4396 in_port_t base_port= 11211;
4397 for (size_t x= 0; x < 17; x++)
4398 {
4399 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", base_port +x));
4400 }
4401 test_compare(16U, memcached_generate_hash(memc, test_literal_param("SZ6hu0SHweFmpwpc0w2R")));
4402 test_compare(1U, memcached_generate_hash(memc, test_literal_param("SQCK9eiCf53YxHWnYA.o")));
4403 test_compare(10U, memcached_generate_hash(memc, test_literal_param("SUSDkGXuuZC9t9VhMwa.")));
4404 test_compare(8U, memcached_generate_hash(memc, test_literal_param("SnnqnJARfaCNT679iAF_")));
4405
4406 memcached_free(memc);
4407
4408 return TEST_SUCCESS;
4409 }
4410
4411
4412 /*
4413 * Test that ensures mget_execute does not end into recursive calls that finally fails
4414 */
4415 test_return_t regression_bug_490486(memcached_st *original_memc)
4416 {
4417
4418 #ifdef __APPLE__
4419 return TEST_SKIPPED; // My MAC can't handle this test
4420 #endif
4421
4422 test_skip(TEST_SUCCESS, pre_binary(original_memc));
4423
4424 /*
4425 * I only want to hit _one_ server so I know the number of requests I'm
4426 * sending in the pipeline.
4427 */
4428 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL --POLL-TIMEOUT=1000 --REMOVE-FAILED-SERVERS=1 --RETRY-TIMEOUT=3600");
4429 test_true(memc);
4430
4431 keys_st keys(20480);
4432
4433 /* First add all of the items.. */
4434 char blob[1024]= { 0 };
4435 for (size_t x= 0; x < keys.size(); ++x)
4436 {
4437 memcached_return rc= memcached_set(memc,
4438 keys.key_at(x), keys.length_at(x),
4439 blob, sizeof(blob), 0, 0);
4440 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); // MEMCACHED_TIMEOUT <-- hash been observed on OSX
4441 }
4442
4443 {
4444
4445 /* Try to get all of them with a large multiget */
4446 size_t counter= 0;
4447 memcached_execute_function callbacks[]= { &callback_counter };
4448 memcached_return_t rc= memcached_mget_execute(memc,
4449 keys.keys_ptr(), keys.lengths_ptr(), keys.size(),
4450 callbacks, &counter, 1);
4451 test_compare(MEMCACHED_SUCCESS, rc);
4452
4453 char* the_value= NULL;
4454 char the_key[MEMCACHED_MAX_KEY];
4455 size_t the_key_length;
4456 size_t the_value_length;
4457 uint32_t the_flags;
4458
4459 do {
4460 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
4461
4462 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
4463 {
4464 ++counter;
4465 free(the_value);
4466 }
4467
4468 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
4469
4470
4471 test_compare(MEMCACHED_END, rc);
4472
4473 /* Verify that we got all of the items */
4474 test_compare(counter, keys.size());
4475 }
4476
4477 memcached_free(memc);
4478
4479 return TEST_SUCCESS;
4480 }
4481
4482 test_return_t regression_bug_583031(memcached_st *)
4483 {
4484 memcached_st *memc= memcached_create(NULL);
4485 test_true(memc);
4486 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", 11211));
4487
4488 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
4489 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
4490 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4491 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4492 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
4493 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
4494
4495 memcached_return_t rc;
4496 size_t length;
4497 uint32_t flags;
4498
4499 const char *value= memcached_get(memc, "dsf", 3, &length, &flags, &rc);
4500 test_false(value);
4501 test_zero(length);
4502
4503 test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_last_error_message(memc));
4504
4505 memcached_free(memc);
4506
4507 return TEST_SUCCESS;
4508 }
4509
4510 test_return_t regression_bug_581030(memcached_st *)
4511 {
4512 #ifndef DEBUG
4513 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
4514 test_false(local_stat);
4515
4516 memcached_stat_free(NULL, NULL);
4517 #endif
4518
4519 return TEST_SUCCESS;
4520 }
4521
4522 #define regression_bug_655423_COUNT 6000
4523 test_return_t regression_bug_655423(memcached_st *memc)
4524 {
4525 memcached_st *clone= memcached_clone(NULL, memc);
4526 memc= NULL; // Just to make sure it is not used
4527 test_true(clone);
4528 char payload[100];
4529
4530 #ifdef __APPLE__
4531 return TEST_SKIPPED;
4532 #endif
4533
4534 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4535 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1));
4536 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
4537 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 1));
4538
4539 memset(payload, int('x'), sizeof(payload));
4540
4541 keys_st keys(regression_bug_655423_COUNT);
4542
4543 for (size_t x= 0; x < keys.size(); x++)
4544 {
4545 test_compare(MEMCACHED_SUCCESS, memcached_set(clone,
4546 keys.key_at(x),
4547 keys.length_at(x),
4548 payload, sizeof(payload), 0, 0));
4549 }
4550
4551 for (size_t x= 0; x < keys.size(); x++)
4552 {
4553 size_t value_length;
4554 memcached_return_t rc;
4555 char *value= memcached_get(clone,
4556 keys.key_at(x),
4557 keys.length_at(x),
4558 &value_length, NULL, &rc);
4559
4560 if (rc == MEMCACHED_NOTFOUND)
4561 {
4562 test_false(value);
4563 test_zero(value_length);
4564 continue;
4565 }
4566
4567 test_compare(MEMCACHED_SUCCESS, rc);
4568 test_true(value);
4569 test_compare(100LLU, value_length);
4570 free(value);
4571 }
4572
4573 test_compare(MEMCACHED_SUCCESS,
4574 memcached_mget(clone,
4575 keys.keys_ptr(), keys.lengths_ptr(),
4576 keys.size()));
4577
4578 uint32_t count= 0;
4579 memcached_result_st *result= NULL;
4580 while ((result= memcached_fetch_result(clone, result, NULL)))
4581 {
4582 test_compare(size_t(100), memcached_result_length(result));
4583 count++;
4584 }
4585
4586 test_true(count > 100); // If we don't get back atleast this, something is up
4587
4588 memcached_free(clone);
4589
4590 return TEST_SUCCESS;
4591 }
4592
4593 /*
4594 * Test that ensures that buffered set to not trigger problems during io_flush
4595 */
4596 #define regression_bug_490520_COUNT 200480
4597 test_return_t regression_bug_490520(memcached_st *original_memc)
4598 {
4599 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
4600
4601 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK,1);
4602 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,1);
4603 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
4604 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,1);
4605 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
4606
4607 /* First add all of the items.. */
4608 char blob[3333] = {0};
4609 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
4610 {
4611 char key[251];
4612 int key_length= snprintf(key, sizeof(key), "0200%u", x);
4613
4614 memcached_return rc= memcached_set(memc, key, key_length, blob, sizeof(blob), 0, 0);
4615 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_last_error_message(memc));
4616 }
4617
4618 memcached_free(memc);
4619
4620 return TEST_SUCCESS;
4621 }
4622
4623 test_return_t regression_1009493_TEST(memcached_st*)
4624 {
4625 memcached_st* memc= memcached_create(NULL);
4626 test_true(memc);
4627 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, true));
4628
4629 memcached_st* clone= memcached_clone(NULL, memc);
4630 test_true(clone);
4631
4632 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED),
4633 memcached_behavior_get(clone, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
4634
4635 memcached_free(memc);
4636 memcached_free(clone);
4637
4638 return TEST_SUCCESS;
4639 }
4640
4641 test_return_t regression_994772_TEST(memcached_st* memc)
4642 {
4643 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4644
4645 test_compare(MEMCACHED_SUCCESS,
4646 memcached_set(memc,
4647 test_literal_param(__func__), // Key
4648 test_literal_param(__func__), // Value
4649 time_t(0), uint32_t(0)));
4650
4651 const char *keys[] = { __func__ };
4652 size_t key_length[]= { strlen(__func__) };
4653 test_compare(MEMCACHED_SUCCESS,
4654 memcached_mget(memc, keys, key_length, 1));
4655
4656 memcached_return_t rc;
4657 memcached_result_st *results= memcached_fetch_result(memc, NULL, &rc);
4658 test_true(results);
4659 test_compare(MEMCACHED_SUCCESS, rc);
4660
4661 test_strcmp(__func__, memcached_result_value(results));
4662 uint64_t cas_value= memcached_result_cas(results);
4663 test_true(cas_value);
4664
4665 memcached_result_free(results);
4666
4667 // Bad cas value, sanity check
4668 test_true(cas_value != 9999);
4669 test_compare(MEMCACHED_END,
4670 memcached_cas(memc,
4671 test_literal_param(__func__), // Key
4672 test_literal_param(__FILE__), // Value
4673 time_t(0), uint32_t(0), 9999));
4674
4675 test_compare(MEMCACHED_SUCCESS, memcached_set(memc,
4676 "different", strlen("different"), // Key
4677 test_literal_param(__FILE__), // Value
4678 time_t(0), uint32_t(0)));
4679
4680 return TEST_SUCCESS;
4681 }
4682
4683 test_return_t regression_bug_854604(memcached_st *)
4684 {
4685 char buffer[1024];
4686
4687 test_compare(MEMCACHED_INVALID_ARGUMENTS, libmemcached_check_configuration(0, 0, buffer, 0));
4688
4689 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 0));
4690
4691 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 1));
4692 test_compare(buffer[0], 0);
4693
4694 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 10));
4695 test_true(strlen(buffer));
4696
4697 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, sizeof(buffer)));
4698 test_true(strlen(buffer));
4699
4700 return TEST_SUCCESS;
4701 }
4702
4703 static void die_message(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
4704 {
4705 fprintf(stderr, "Iteration #%u: ", it);
4706
4707 if (error == MEMCACHED_ERRNO)
4708 {
4709 fprintf(stderr, "system error %d from %s: %s\n",
4710 errno, what, strerror(errno));
4711 }
4712 else
4713 {
4714 fprintf(stderr, "error %d from %s: %s\n", error, what,
4715 memcached_strerror(mc, error));
4716 }
4717 }
4718
4719 #define TEST_CONSTANT_CREATION 200
4720
4721 test_return_t regression_bug_(memcached_st *memc)
4722 {
4723 const char *remote_server;
4724 (void)memc;
4725
4726 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
4727 {
4728 return TEST_SKIPPED;
4729 }
4730
4731 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
4732 {
4733 memcached_st* mc= memcached_create(NULL);
4734 memcached_return rc;
4735
4736 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
4737 if (rc != MEMCACHED_SUCCESS)
4738 {
4739 die_message(mc, rc, "memcached_behavior_set", x);
4740 }
4741
4742 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
4743 if (rc != MEMCACHED_SUCCESS)
4744 {
4745 die_message(mc, rc, "memcached_behavior_set", x);
4746 }
4747
4748 rc= memcached_server_add(mc, remote_server, 0);
4749 if (rc != MEMCACHED_SUCCESS)
4750 {
4751 die_message(mc, rc, "memcached_server_add", x);
4752 }
4753
4754 const char *set_key= "akey";
4755 const size_t set_key_len= strlen(set_key);
4756 const char *set_value= "a value";
4757 const size_t set_value_len= strlen(set_value);
4758
4759 if (rc == MEMCACHED_SUCCESS)
4760 {
4761 if (x > 0)
4762 {
4763 size_t get_value_len;
4764 char *get_value;
4765 uint32_t get_value_flags;
4766
4767 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
4768 &get_value_flags, &rc);
4769 if (rc != MEMCACHED_SUCCESS)
4770 {
4771 die_message(mc, rc, "memcached_get", x);
4772 }
4773 else
4774 {
4775
4776 if (x != 0 &&
4777 (get_value_len != set_value_len
4778 || 0!=strncmp(get_value, set_value, get_value_len)))
4779 {
4780 fprintf(stderr, "Values don't match?\n");
4781 rc= MEMCACHED_FAILURE;
4782 }
4783 free(get_value);
4784 }
4785 }
4786
4787 rc= memcached_set(mc,
4788 set_key, set_key_len,
4789 set_value, set_value_len,
4790 0, /* time */
4791 0 /* flags */
4792 );
4793 if (rc != MEMCACHED_SUCCESS)
4794 {
4795 die_message(mc, rc, "memcached_set", x);
4796 }
4797 }
4798
4799 memcached_quit(mc);
4800 memcached_free(mc);
4801
4802 if (rc != MEMCACHED_SUCCESS)
4803 {
4804 break;
4805 }
4806 }
4807
4808 return TEST_SUCCESS;
4809 }
4810
4811 test_return_t kill_HUP_TEST(memcached_st *original_memc)
4812 {
4813 memcached_st *memc= create_single_instance_memcached(original_memc, 0);
4814 test_true(memc);
4815
4816 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
4817
4818 pid_t pid;
4819 test_true((pid= libmemcached_util_getpid(memcached_server_name(instance),
4820 memcached_server_port(instance), NULL)) > -1);
4821
4822
4823 test_compare(MEMCACHED_SUCCESS,
4824 memcached_set(memc,
4825 test_literal_param(__func__), // Keys
4826 test_literal_param(__func__), // Values
4827 0, 0));
4828 test_true_got(kill(pid, SIGHUP) == 0, strerror(errno));
4829
4830 test_compare(MEMCACHED_CONNECTION_FAILURE,
4831 memcached_set(memc,
4832 test_literal_param(__func__), // Keys
4833 test_literal_param(__func__), // Values
4834 0, 0));
4835
4836 memcached_free(memc);
4837
4838 return TEST_SUCCESS;
4839 }