Fix for test case failure.
[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(MEMCACHED_SUCCESS, rc);
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(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1694 test_compare(query_id +1, memcached_query_id(memc));
1695 }
1696
1697 /* Try to get all of them with a large multiget */
1698 size_t counter= 0;
1699 memcached_execute_fn callbacks[]= { &callback_counter };
1700 test_compare(MEMCACHED_SUCCESS,
1701 memcached_mget_execute(memc,
1702 keys.keys_ptr(), keys.lengths_ptr(),
1703 keys.size(), callbacks, &counter, 1));
1704
1705 {
1706 uint64_t query_id= memcached_query_id(memc);
1707 test_compare(MEMCACHED_SUCCESS,
1708 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
1709 test_compare(query_id, memcached_query_id(memc));
1710
1711 /* Verify that we got all of the items */
1712 test_compare(keys.size(), counter);
1713 }
1714
1715 memcached_free(memc);
1716
1717 return TEST_SUCCESS;
1718 }
1719
1720 #define REGRESSION_BINARY_VS_BLOCK_COUNT 20480
1721 static pairs_st *global_pairs= NULL;
1722
1723 test_return_t key_setup(memcached_st *memc)
1724 {
1725 test_skip(TEST_SUCCESS, pre_binary(memc));
1726
1727 global_pairs= pairs_generate(REGRESSION_BINARY_VS_BLOCK_COUNT, 0);
1728
1729 return TEST_SUCCESS;
1730 }
1731
1732 test_return_t key_teardown(memcached_st *)
1733 {
1734 pairs_free(global_pairs);
1735 global_pairs= NULL;
1736
1737 return TEST_SUCCESS;
1738 }
1739
1740 test_return_t block_add_regression(memcached_st *memc)
1741 {
1742 /* First add all of the items.. */
1743 for (ptrdiff_t x= 0; x < REGRESSION_BINARY_VS_BLOCK_COUNT; ++x)
1744 {
1745 libtest::vchar_t blob;
1746 libtest::vchar::make(blob, 1024);
1747
1748 memcached_return_t rc= memcached_add_by_key(memc,
1749 test_literal_param("bob"),
1750 global_pairs[x].key, global_pairs[x].key_length,
1751 &blob[0], blob.size(),
1752 time_t(0), uint32_t(0));
1753 test_true_got(rc == MEMCACHED_SUCCESS
1754 or rc == MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE
1755 or rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE, memcached_strerror(NULL, rc));
1756 }
1757
1758 return TEST_SUCCESS;
1759 }
1760
1761 test_return_t binary_add_regression(memcached_st *memc)
1762 {
1763 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
1764 test_return_t rc= block_add_regression(memc);
1765
1766 return rc;
1767 }
1768
1769 test_return_t get_stats_keys(memcached_st *memc)
1770 {
1771 char **stat_list;
1772 char **ptr;
1773 memcached_stat_st memc_stat;
1774 memcached_return_t rc;
1775
1776 stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc);
1777 test_compare(MEMCACHED_SUCCESS, rc);
1778 for (ptr= stat_list; *ptr; ptr++)
1779 test_true(*ptr);
1780
1781 free(stat_list);
1782
1783 return TEST_SUCCESS;
1784 }
1785
1786 test_return_t version_string_test(memcached_st *)
1787 {
1788 test_strcmp(LIBMEMCACHED_VERSION_STRING, memcached_lib_version());
1789
1790 return TEST_SUCCESS;
1791 }
1792
1793 test_return_t get_stats(memcached_st *memc)
1794 {
1795 memcached_return_t rc;
1796
1797 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
1798 test_compare(MEMCACHED_SUCCESS, rc);
1799 test_true(memc_stat);
1800
1801 for (uint32_t x= 0; x < memcached_server_count(memc); x++)
1802 {
1803 char **stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
1804 test_compare(MEMCACHED_SUCCESS, rc);
1805 for (char **ptr= stat_list; *ptr; ptr++) {};
1806
1807 free(stat_list);
1808 }
1809
1810 memcached_stat_free(NULL, memc_stat);
1811
1812 return TEST_SUCCESS;
1813 }
1814
1815 test_return_t add_host_test(memcached_st *memc)
1816 {
1817 char servername[]= "0.example.com";
1818
1819 memcached_return_t rc;
1820 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1821 test_compare(1U, memcached_server_list_count(servers));
1822
1823 for (unsigned int x= 2; x < 20; x++)
1824 {
1825 char buffer[SMALL_STRING_LEN];
1826
1827 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1828 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1829 &rc);
1830 test_compare(MEMCACHED_SUCCESS, rc);
1831 test_compare(x, memcached_server_list_count(servers));
1832 }
1833
1834 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
1835 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
1836
1837 memcached_server_list_free(servers);
1838
1839 return TEST_SUCCESS;
1840 }
1841
1842 test_return_t memcached_fetch_result_NOT_FOUND(memcached_st *memc)
1843 {
1844 memcached_return_t rc;
1845
1846 const char *key= "not_found";
1847 size_t key_length= test_literal_param_size("not_found");
1848
1849 test_compare(MEMCACHED_SUCCESS,
1850 memcached_mget(memc, &key, &key_length, 1));
1851
1852 memcached_result_st *result= memcached_fetch_result(memc, NULL, &rc);
1853 test_null(result);
1854 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1855
1856 memcached_result_free(result);
1857
1858 return TEST_SUCCESS;
1859 }
1860
1861 static memcached_return_t clone_test_callback(memcached_st *, memcached_st *)
1862 {
1863 return MEMCACHED_SUCCESS;
1864 }
1865
1866 static memcached_return_t cleanup_test_callback(memcached_st *)
1867 {
1868 return MEMCACHED_SUCCESS;
1869 }
1870
1871 test_return_t callback_test(memcached_st *memc)
1872 {
1873 /* Test User Data */
1874 {
1875 int x= 5;
1876 int *test_ptr;
1877 memcached_return_t rc;
1878
1879 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x));
1880 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1881 test_true(*test_ptr == x);
1882 }
1883
1884 /* Test Clone Callback */
1885 {
1886 memcached_clone_fn clone_cb= (memcached_clone_fn)clone_test_callback;
1887 void *clone_cb_ptr= *(void **)&clone_cb;
1888 void *temp_function= NULL;
1889
1890 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, clone_cb_ptr));
1891 memcached_return_t rc;
1892 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1893 test_true(temp_function == clone_cb_ptr);
1894 test_compare(MEMCACHED_SUCCESS, rc);
1895 }
1896
1897 /* Test Cleanup Callback */
1898 {
1899 memcached_cleanup_fn cleanup_cb= (memcached_cleanup_fn)cleanup_test_callback;
1900 void *cleanup_cb_ptr= *(void **)&cleanup_cb;
1901 void *temp_function= NULL;
1902 memcached_return_t rc;
1903
1904 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, cleanup_cb_ptr));
1905 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1906 test_true(temp_function == cleanup_cb_ptr);
1907 }
1908
1909 return TEST_SUCCESS;
1910 }
1911
1912 /* We don't test the behavior itself, we test the switches */
1913 test_return_t behavior_test(memcached_st *memc)
1914 {
1915 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
1916 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
1917
1918 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
1919 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
1920
1921 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_MD5);
1922 test_compare(uint64_t(MEMCACHED_HASH_MD5), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1923
1924 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
1925 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
1926
1927 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
1928 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
1929
1930 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_DEFAULT);
1931 test_compare(uint64_t(MEMCACHED_HASH_DEFAULT), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1932
1933 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_CRC);
1934 test_compare(uint64_t(MEMCACHED_HASH_CRC), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1935
1936 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE));
1937
1938 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE));
1939
1940 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
1941 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value +1);
1942 test_compare((value +1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
1943
1944 return TEST_SUCCESS;
1945 }
1946
1947 test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
1948 {
1949 test_compare(MEMCACHED_DEPRECATED,
1950 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, true));
1951
1952 // Platform dependent
1953 #if 0
1954 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
1955 test_false(value);
1956 #endif
1957
1958 return TEST_SUCCESS;
1959 }
1960
1961
1962 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test(memcached_st *memc)
1963 {
1964 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, true);
1965 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
1966
1967 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE);
1968
1969 if (memcached_success(rc))
1970 {
1971 test_true(value);
1972 }
1973 else
1974 {
1975 test_false(value);
1976 }
1977
1978 return TEST_SUCCESS;
1979 }
1980
1981
1982 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc)
1983 {
1984 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE, true);
1985 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
1986
1987 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE);
1988
1989 if (memcached_success(rc))
1990 {
1991 test_true(value);
1992 }
1993 else
1994 {
1995 test_false(value);
1996 }
1997
1998 return TEST_SUCCESS;
1999 }
2000
2001 /* Make sure we behave properly if server list has no values */
2002 test_return_t user_supplied_bug4(memcached_st *memc)
2003 {
2004 const char *keys[]= {"fudge", "son", "food"};
2005 size_t key_length[]= {5, 3, 4};
2006
2007 /* Here we free everything before running a bunch of mget tests */
2008 memcached_servers_reset(memc);
2009
2010
2011 /* We need to empty the server before continueing test */
2012 test_compare(MEMCACHED_NO_SERVERS,
2013 memcached_flush(memc, 0));
2014
2015 test_compare(MEMCACHED_NO_SERVERS,
2016 memcached_mget(memc, keys, key_length, 3));
2017
2018 {
2019 unsigned int keys_returned;
2020 memcached_return_t rc;
2021 test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, rc));
2022 test_compare(MEMCACHED_NOTFOUND, rc);
2023 test_zero(keys_returned);
2024 }
2025
2026 for (uint32_t x= 0; x < 3; x++)
2027 {
2028 test_compare(MEMCACHED_NO_SERVERS,
2029 memcached_set(memc, keys[x], key_length[x],
2030 keys[x], key_length[x],
2031 (time_t)50, (uint32_t)9));
2032 }
2033
2034 test_compare(MEMCACHED_NO_SERVERS,
2035 memcached_mget(memc, keys, key_length, 3));
2036
2037 {
2038 char *return_value;
2039 char return_key[MEMCACHED_MAX_KEY];
2040 memcached_return_t rc;
2041 size_t return_key_length;
2042 size_t return_value_length;
2043 uint32_t flags;
2044 uint32_t x= 0;
2045 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2046 &return_value_length, &flags, &rc)))
2047 {
2048 test_true(return_value);
2049 test_compare(MEMCACHED_SUCCESS, rc);
2050 test_true(return_key_length == return_value_length);
2051 test_memcmp(return_value, return_key, return_value_length);
2052 free(return_value);
2053 x++;
2054 }
2055 }
2056
2057 return TEST_SUCCESS;
2058 }
2059
2060 #define VALUE_SIZE_BUG5 1048064
2061 test_return_t user_supplied_bug5(memcached_st *memc)
2062 {
2063 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2064 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2065 char *value;
2066 size_t value_length;
2067 uint32_t flags;
2068 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2069
2070 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2071 {
2072 insert_data[x]= (signed char)rand();
2073 }
2074
2075 test_compare(MEMCACHED_SUCCESS,
2076 memcached_flush(memc, 0));
2077
2078 memcached_return_t rc;
2079 test_null(memcached_get(memc, keys[0], key_length[0], &value_length, &flags, &rc));
2080 test_compare(MEMCACHED_SUCCESS,
2081 memcached_mget(memc, keys, key_length, 4));
2082
2083 unsigned int count;
2084 test_compare(TEST_SUCCESS, fetch_all_results(memc, count, rc));
2085 test_compare(MEMCACHED_NOTFOUND, rc);
2086 test_zero(count);
2087
2088 for (uint32_t x= 0; x < 4; x++)
2089 {
2090 test_compare(MEMCACHED_SUCCESS,
2091 memcached_set(memc, keys[x], key_length[x],
2092 insert_data, VALUE_SIZE_BUG5,
2093 (time_t)0, (uint32_t)0));
2094 }
2095
2096 for (uint32_t x= 0; x < 10; x++)
2097 {
2098 value= memcached_get(memc, keys[0], key_length[0],
2099 &value_length, &flags, &rc);
2100 test_compare(rc, MEMCACHED_SUCCESS);
2101 test_true(value);
2102 ::free(value);
2103
2104 test_compare(MEMCACHED_SUCCESS,
2105 memcached_mget(memc, keys, key_length, 4));
2106
2107 test_compare(TEST_SUCCESS, fetch_all_results(memc, count));
2108 test_compare(4U, count);
2109 }
2110 delete [] insert_data;
2111
2112 return TEST_SUCCESS;
2113 }
2114
2115 test_return_t user_supplied_bug6(memcached_st *memc)
2116 {
2117 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2118 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2119 char return_key[MEMCACHED_MAX_KEY];
2120 size_t return_key_length;
2121 char *value;
2122 size_t value_length;
2123 uint32_t flags;
2124 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2125
2126 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2127 {
2128 insert_data[x]= (signed char)rand();
2129 }
2130
2131 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
2132
2133 test_compare(TEST_SUCCESS, confirm_keys_dont_exist(memc, keys, test_array_length(keys)));
2134
2135 // We will now confirm that memcached_mget() returns success, but we will
2136 // then check to make sure that no actual keys are returned.
2137 test_compare(MEMCACHED_SUCCESS,
2138 memcached_mget(memc, keys, key_length, 4));
2139
2140 memcached_return_t rc;
2141 uint32_t count= 0;
2142 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2143 &value_length, &flags, &rc)))
2144 {
2145 count++;
2146 }
2147 test_zero(count);
2148 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
2149
2150 for (uint32_t x= 0; x < test_array_length(keys); x++)
2151 {
2152 test_compare(MEMCACHED_SUCCESS,
2153 memcached_set(memc, keys[x], key_length[x],
2154 insert_data, VALUE_SIZE_BUG5,
2155 (time_t)0, (uint32_t)0));
2156 }
2157 test_compare(TEST_SUCCESS, confirm_keys_exist(memc, keys, test_array_length(keys)));
2158
2159 for (uint32_t x= 0; x < 2; x++)
2160 {
2161 value= memcached_get(memc, keys[0], key_length[0],
2162 &value_length, &flags, &rc);
2163 test_true(value);
2164 free(value);
2165
2166 test_compare(MEMCACHED_SUCCESS,
2167 memcached_mget(memc, keys, key_length, 4));
2168 /* We test for purge of partial complete fetches */
2169 for (count= 3; count; count--)
2170 {
2171 value= memcached_fetch(memc, return_key, &return_key_length,
2172 &value_length, &flags, &rc);
2173 test_compare(MEMCACHED_SUCCESS, rc);
2174 test_memcmp(value, insert_data, value_length);
2175 test_true(value_length);
2176 free(value);
2177 }
2178 }
2179 delete [] insert_data;
2180
2181 return TEST_SUCCESS;
2182 }
2183
2184 test_return_t user_supplied_bug8(memcached_st *)
2185 {
2186 memcached_return_t rc;
2187 memcached_st *mine;
2188 memcached_st *memc_clone;
2189
2190 memcached_server_st *servers;
2191 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";
2192
2193 servers= memcached_servers_parse(server_list);
2194 test_true(servers);
2195
2196 mine= memcached_create(NULL);
2197 rc= memcached_server_push(mine, servers);
2198 test_compare(MEMCACHED_SUCCESS, rc);
2199 memcached_server_list_free(servers);
2200
2201 test_true(mine);
2202 memc_clone= memcached_clone(NULL, mine);
2203
2204 memcached_quit(mine);
2205 memcached_quit(memc_clone);
2206
2207
2208 memcached_free(mine);
2209 memcached_free(memc_clone);
2210
2211 return TEST_SUCCESS;
2212 }
2213
2214 /* Test flag store/retrieve */
2215 test_return_t user_supplied_bug7(memcached_st *memc)
2216 {
2217 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2218 test_true(insert_data);
2219
2220 for (size_t x= 0; x < VALUE_SIZE_BUG5; x++)
2221 {
2222 insert_data[x]= (signed char)rand();
2223 }
2224
2225 memcached_flush(memc, 0);
2226
2227 const char *keys= "036790384900";
2228 size_t key_length= strlen(keys);
2229 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys, key_length,
2230 insert_data, VALUE_SIZE_BUG5,
2231 time_t(0), 245U));
2232
2233 memcached_return_t rc;
2234 size_t value_length;
2235 uint32_t flags= 0;
2236 char *value= memcached_get(memc, keys, key_length,
2237 &value_length, &flags, &rc);
2238 test_compare(245U, flags);
2239 test_true(value);
2240 free(value);
2241
2242 test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, &keys, &key_length, 1));
2243
2244 char return_key[MEMCACHED_MAX_KEY];
2245 size_t return_key_length;
2246 flags= 0;
2247 value= memcached_fetch(memc, return_key, &return_key_length,
2248 &value_length, &flags, &rc);
2249 test_compare(uint32_t(245), flags);
2250 test_true(value);
2251 free(value);
2252 delete [] insert_data;
2253
2254
2255 return TEST_SUCCESS;
2256 }
2257
2258 test_return_t user_supplied_bug9(memcached_st *memc)
2259 {
2260 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2261 size_t key_length[3];
2262 uint32_t flags;
2263 unsigned count= 0;
2264
2265 char return_key[MEMCACHED_MAX_KEY];
2266 size_t return_key_length;
2267 char *return_value;
2268 size_t return_value_length;
2269
2270
2271 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2272 key_length[1]= strlen("fudge&*@#");
2273 key_length[2]= strlen("for^#@&$not");
2274
2275
2276 for (unsigned int x= 0; x < 3; x++)
2277 {
2278 memcached_return_t rc= memcached_set(memc, keys[x], key_length[x],
2279 keys[x], key_length[x],
2280 (time_t)50, (uint32_t)9);
2281 test_compare(MEMCACHED_SUCCESS, rc);
2282 }
2283
2284 memcached_return_t rc= memcached_mget(memc, keys, key_length, 3);
2285 test_compare(MEMCACHED_SUCCESS, rc);
2286
2287 /* We need to empty the server before continueing test */
2288 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2289 &return_value_length, &flags, &rc)) != NULL)
2290 {
2291 test_true(return_value);
2292 free(return_value);
2293 count++;
2294 }
2295 test_compare(3U, count);
2296
2297 return TEST_SUCCESS;
2298 }
2299
2300 /* We are testing with aggressive timeout to get failures */
2301 test_return_t user_supplied_bug10(memcached_st *memc)
2302 {
2303 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
2304
2305 size_t value_length= 512;
2306 unsigned int set= 1;
2307 memcached_st *mclone= memcached_clone(NULL, memc);
2308
2309 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2310 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2311 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, uint64_t(0));
2312
2313 libtest::vchar_t value;
2314 value.reserve(value_length);
2315 for (uint32_t x= 0; x < value_length; x++)
2316 {
2317 value.push_back(char(x % 127));
2318 }
2319
2320 for (unsigned int x= 1; x <= 100000; ++x)
2321 {
2322 memcached_return_t rc= memcached_set(mclone,
2323 test_literal_param("foo"),
2324 &value[0], value.size(),
2325 0, 0);
2326
2327 test_true_got((rc == MEMCACHED_SUCCESS or rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_BUFFERED or rc == MEMCACHED_TIMEOUT or rc == MEMCACHED_CONNECTION_FAILURE
2328 or rc == MEMCACHED_SERVER_TEMPORARILY_DISABLED),
2329 memcached_strerror(NULL, rc));
2330
2331 if (rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_TIMEOUT)
2332 {
2333 x--;
2334 }
2335 }
2336
2337 memcached_free(mclone);
2338
2339 return TEST_SUCCESS;
2340 }
2341
2342 /*
2343 We are looking failures in the async protocol
2344 */
2345 test_return_t user_supplied_bug11(memcached_st *memc)
2346 {
2347 memcached_st *mclone= memcached_clone(NULL, memc);
2348
2349 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, true);
2350 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
2351 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, size_t(-1));
2352
2353 test_compare(-1, int32_t(memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT)));
2354
2355
2356 libtest::vchar_t value;
2357 value.reserve(512);
2358 for (unsigned int x= 0; x < 512; x++)
2359 {
2360 value.push_back(char(x % 127));
2361 }
2362
2363 for (unsigned int x= 1; x <= 100000; ++x)
2364 {
2365 memcached_return_t rc= memcached_set(mclone, test_literal_param("foo"), &value[0], value.size(), 0, 0);
2366 (void)rc;
2367 }
2368
2369 memcached_free(mclone);
2370
2371 return TEST_SUCCESS;
2372 }
2373
2374 /*
2375 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2376 */
2377 test_return_t user_supplied_bug12(memcached_st *memc)
2378 {
2379 memcached_return_t rc;
2380 uint32_t flags;
2381 size_t value_length;
2382 char *value;
2383 uint64_t number_value;
2384
2385 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2386 &value_length, &flags, &rc);
2387 test_null(value);
2388 test_compare(MEMCACHED_NOTFOUND, rc);
2389
2390 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2391 1, &number_value);
2392 test_null(value);
2393 /* The binary protocol will set the key if it doesn't exist */
2394 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2395 {
2396 test_compare(MEMCACHED_SUCCESS, rc);
2397 }
2398 else
2399 {
2400 test_compare(MEMCACHED_NOTFOUND, rc);
2401 }
2402
2403 test_compare(MEMCACHED_SUCCESS,
2404 memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0));
2405
2406 value= memcached_get(memc, "autoincrement", strlen("autoincrement"), &value_length, &flags, &rc);
2407 test_true(value);
2408 free(value);
2409
2410 test_compare(MEMCACHED_SUCCESS,
2411 memcached_increment(memc, "autoincrement", strlen("autoincrement"), 1, &number_value));
2412 test_compare(2UL, number_value);
2413
2414 return TEST_SUCCESS;
2415 }
2416
2417 /*
2418 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2419 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2420 */
2421 test_return_t user_supplied_bug13(memcached_st *memc)
2422 {
2423 char key[] = "key34567890";
2424
2425 char commandFirst[]= "set key34567890 0 0 ";
2426 char commandLast[] = " \r\n"; /* first line of command sent to server */
2427 size_t commandLength;
2428
2429 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2430
2431 size_t overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2432
2433 for (size_t testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2434 {
2435 char *overflow= new (std::nothrow) char[testSize];
2436 test_true(overflow);
2437
2438 memset(overflow, 'x', testSize);
2439 test_compare(MEMCACHED_SUCCESS,
2440 memcached_set(memc, key, strlen(key),
2441 overflow, testSize, 0, 0));
2442 delete [] overflow;
2443 }
2444
2445 return TEST_SUCCESS;
2446 }
2447
2448
2449 /*
2450 Test values of many different sizes
2451 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2452 set key34567890 0 0 8169 \r\n
2453 is sent followed by buffer of size 8169, followed by 8169
2454 */
2455 test_return_t user_supplied_bug14(memcached_st *memc)
2456 {
2457 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
2458
2459 libtest::vchar_t value;
2460 value.reserve(18000);
2461 for (ptrdiff_t x= 0; x < 18000; x++)
2462 {
2463 value.push_back((char) (x % 127));
2464 }
2465
2466 for (size_t current_length= 1; current_length < value.size(); current_length++)
2467 {
2468 memcached_return_t rc= memcached_set(memc, test_literal_param("foo"),
2469 &value[0], current_length,
2470 (time_t)0, (uint32_t)0);
2471 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
2472
2473 size_t string_length;
2474 uint32_t flags;
2475 char *string= memcached_get(memc, test_literal_param("foo"),
2476 &string_length, &flags, &rc);
2477
2478 test_compare(MEMCACHED_SUCCESS, rc);
2479 test_compare(string_length, current_length);
2480 char buffer[1024];
2481 snprintf(buffer, sizeof(buffer), "%u", uint32_t(string_length));
2482 test_memcmp_hint(string, &value[0], string_length, buffer);
2483
2484 free(string);
2485 }
2486
2487 return TEST_SUCCESS;
2488 }
2489
2490 /*
2491 Look for zero length value problems
2492 */
2493 test_return_t user_supplied_bug15(memcached_st *memc)
2494 {
2495 for (uint32_t x= 0; x < 2; x++)
2496 {
2497 memcached_return_t rc= memcached_set(memc, test_literal_param("mykey"),
2498 NULL, 0,
2499 (time_t)0, (uint32_t)0);
2500
2501 test_compare(MEMCACHED_SUCCESS, rc);
2502
2503 size_t length;
2504 uint32_t flags;
2505 char *value= memcached_get(memc, test_literal_param("mykey"),
2506 &length, &flags, &rc);
2507
2508 test_compare(MEMCACHED_SUCCESS, rc);
2509 test_false(value);
2510 test_zero(length);
2511 test_zero(flags);
2512
2513 value= memcached_get(memc, test_literal_param("mykey"),
2514 &length, &flags, &rc);
2515
2516 test_compare(MEMCACHED_SUCCESS, rc);
2517 test_null(value);
2518 test_zero(length);
2519 test_zero(flags);
2520 }
2521
2522 return TEST_SUCCESS;
2523 }
2524
2525 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2526 test_return_t user_supplied_bug16(memcached_st *memc)
2527 {
2528 test_compare_hint(MEMCACHED_SUCCESS, memcached_set(memc, test_literal_param("mykey"),
2529 NULL, 0,
2530 (time_t)0, UINT32_MAX),
2531 memcached_last_error_message(memc));
2532
2533
2534 size_t length;
2535 uint32_t flags;
2536 memcached_return_t rc;
2537 char *value= memcached_get(memc, test_literal_param("mykey"),
2538 &length, &flags, &rc);
2539
2540 test_compare(MEMCACHED_SUCCESS, rc);
2541 test_null(value);
2542 test_zero(length);
2543 test_compare(flags, UINT32_MAX);
2544
2545 return TEST_SUCCESS;
2546 }
2547
2548 #if !defined(__sun) && !defined(__OpenBSD__)
2549 /* Check the validity of chinese key*/
2550 test_return_t user_supplied_bug17(memcached_st *memc)
2551 {
2552 const char *key= "豆瓣";
2553 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2554 memcached_return_t rc= memcached_set(memc, key, strlen(key),
2555 value, strlen(value),
2556 (time_t)0, 0);
2557
2558 test_compare(MEMCACHED_SUCCESS, rc);
2559
2560 size_t length;
2561 uint32_t flags;
2562 char *value2= memcached_get(memc, key, strlen(key),
2563 &length, &flags, &rc);
2564
2565 test_compare(length, strlen(value));
2566 test_compare(MEMCACHED_SUCCESS, rc);
2567 test_memcmp(value, value2, length);
2568 free(value2);
2569
2570 return TEST_SUCCESS;
2571 }
2572 #endif
2573
2574 /*
2575 From Andrei on IRC
2576 */
2577
2578 test_return_t user_supplied_bug19(memcached_st *)
2579 {
2580 memcached_return_t res;
2581
2582 memcached_st *memc= memcached(test_literal_param("--server=localhost:11311/?100 --server=localhost:11312/?100"));
2583
2584 const memcached_server_st *server= memcached_server_by_key(memc, "a", 1, &res);
2585 test_true(server);
2586
2587 memcached_free(memc);
2588
2589 return TEST_SUCCESS;
2590 }
2591
2592 /* CAS test from Andei */
2593 test_return_t user_supplied_bug20(memcached_st *memc)
2594 {
2595 const char *key= "abc";
2596 size_t key_len= strlen("abc");
2597
2598 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
2599
2600 test_compare(MEMCACHED_SUCCESS,
2601 memcached_set(memc,
2602 test_literal_param("abc"),
2603 test_literal_param("foobar"),
2604 (time_t)0, (uint32_t)0));
2605
2606 test_compare(MEMCACHED_SUCCESS,
2607 memcached_mget(memc, &key, &key_len, 1));
2608
2609 memcached_result_st result_obj;
2610 memcached_result_st *result= memcached_result_create(memc, &result_obj);
2611 test_true(result);
2612
2613 memcached_result_create(memc, &result_obj);
2614 memcached_return_t status;
2615 result= memcached_fetch_result(memc, &result_obj, &status);
2616
2617 test_true(result);
2618 test_compare(MEMCACHED_SUCCESS, status);
2619
2620 memcached_result_free(result);
2621
2622 return TEST_SUCCESS;
2623 }
2624
2625 /* Large mget() of missing keys with binary proto
2626 *
2627 * If many binary quiet commands (such as getq's in an mget) fill the output
2628 * buffer and the server chooses not to respond, memcached_flush hangs. See
2629 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2630 */
2631
2632 /* sighandler_t function that always asserts false */
2633 static void fail(int)
2634 {
2635 fatal_assert(0);
2636 }
2637
2638
2639 test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2640 {
2641 #ifdef WIN32
2642 (void)memc;
2643 (void)key_count;
2644 return TEST_SKIPPED;
2645 #else
2646 void (*oldalarm)(int);
2647
2648 memcached_st *memc_clone= memcached_clone(NULL, memc);
2649 test_true(memc_clone);
2650
2651 /* only binproto uses getq for mget */
2652 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
2653
2654 /* empty the cache to ensure misses (hence non-responses) */
2655 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc_clone, 0));
2656
2657 keys_st keys(key_count);
2658
2659 oldalarm= signal(SIGALRM, fail);
2660 alarm(5);
2661
2662 test_compare_got(MEMCACHED_SUCCESS,
2663 memcached_mget(memc_clone, keys.keys_ptr(), keys.lengths_ptr(), keys.size()),
2664 memcached_last_error_message(memc_clone));
2665
2666 alarm(0);
2667 signal(SIGALRM, oldalarm);
2668
2669 memcached_return_t rc;
2670 uint32_t flags;
2671 char return_key[MEMCACHED_MAX_KEY];
2672 size_t return_key_length;
2673 char *return_value;
2674 size_t return_value_length;
2675 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2676 &return_value_length, &flags, &rc)))
2677 {
2678 test_false(return_value); // There are no keys to fetch, so the value should never be returned
2679 }
2680 test_compare(MEMCACHED_NOTFOUND, rc);
2681 test_zero(return_value_length);
2682 test_zero(return_key_length);
2683 test_false(return_key[0]);
2684 test_false(return_value);
2685
2686 memcached_free(memc_clone);
2687
2688 return TEST_SUCCESS;
2689 #endif
2690 }
2691
2692 test_return_t user_supplied_bug21(memcached_st *memc)
2693 {
2694 test_skip(TEST_SUCCESS, pre_binary(memc));
2695
2696 /* should work as of r580 */
2697 test_compare(TEST_SUCCESS,
2698 _user_supplied_bug21(memc, 10));
2699
2700 /* should fail as of r580 */
2701 test_compare(TEST_SUCCESS,
2702 _user_supplied_bug21(memc, 1000));
2703
2704 return TEST_SUCCESS;
2705 }
2706
2707 test_return_t output_ketama_weighted_keys(memcached_st *)
2708 {
2709 memcached_st *memc= memcached_create(NULL);
2710 test_true(memc);
2711
2712
2713 test_compare(MEMCACHED_SUCCESS,
2714 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true));
2715
2716 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2717 test_compare(value, uint64_t(1));
2718
2719 test_compare(MEMCACHED_SUCCESS,
2720 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5));
2721
2722 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2723 test_true(value == MEMCACHED_HASH_MD5);
2724
2725
2726 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
2727
2728 memcached_server_st *server_pool;
2729 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");
2730 memcached_server_push(memc, server_pool);
2731
2732 // @todo this needs to be refactored to actually test something.
2733 #if 0
2734 FILE *fp;
2735 if ((fp = fopen("ketama_keys.txt", "w")))
2736 {
2737 // noop
2738 } else {
2739 printf("cannot write to file ketama_keys.txt");
2740 return TEST_FAILURE;
2741 }
2742
2743 for (int x= 0; x < 10000; x++)
2744 {
2745 char key[10];
2746 snprintf(key, sizeof(key), "%d", x);
2747
2748 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
2749 char *hostname = memc->hosts[server_idx].hostname;
2750 in_port_t port = memc->hosts[server_idx].port;
2751 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
2752 memcached_server_instance_st instance=
2753 memcached_server_instance_by_position(memc, host_index);
2754 }
2755 fclose(fp);
2756 #endif
2757 memcached_server_list_free(server_pool);
2758 memcached_free(memc);
2759
2760 return TEST_SUCCESS;
2761 }
2762
2763
2764 test_return_t result_static(memcached_st *memc)
2765 {
2766 memcached_result_st result;
2767 memcached_result_st *result_ptr= memcached_result_create(memc, &result);
2768 test_false(result.options.is_allocated);
2769 test_true(memcached_is_initialized(&result));
2770 test_true(result_ptr);
2771 test_true(result_ptr == &result);
2772
2773 memcached_result_free(&result);
2774
2775 test_false(result.options.is_allocated);
2776 test_false(memcached_is_initialized(&result));
2777
2778 return TEST_SUCCESS;
2779 }
2780
2781 test_return_t result_alloc(memcached_st *memc)
2782 {
2783 memcached_result_st *result_ptr= memcached_result_create(memc, NULL);
2784 test_true(result_ptr);
2785 test_true(result_ptr->options.is_allocated);
2786 test_true(memcached_is_initialized(result_ptr));
2787 memcached_result_free(result_ptr);
2788
2789 return TEST_SUCCESS;
2790 }
2791
2792
2793 test_return_t add_host_test1(memcached_st *memc)
2794 {
2795 memcached_return_t rc;
2796 char servername[]= "0.example.com";
2797
2798 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
2799 test_true(servers);
2800 test_compare(1U, memcached_server_list_count(servers));
2801
2802 for (uint32_t x= 2; x < 20; x++)
2803 {
2804 char buffer[SMALL_STRING_LEN];
2805
2806 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
2807 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
2808 &rc);
2809 test_compare(MEMCACHED_SUCCESS, rc);
2810 test_compare(x, memcached_server_list_count(servers));
2811 }
2812
2813 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
2814 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
2815
2816 memcached_server_list_free(servers);
2817
2818 return TEST_SUCCESS;
2819 }
2820
2821
2822 static void my_free(const memcached_st *ptr, void *mem, void *context)
2823 {
2824 (void)context;
2825 (void)ptr;
2826 #ifdef HARD_MALLOC_TESTS
2827 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
2828 free(real_ptr);
2829 #else
2830 free(mem);
2831 #endif
2832 }
2833
2834
2835 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
2836 {
2837 (void)context;
2838 (void)ptr;
2839 #ifdef HARD_MALLOC_TESTS
2840 void *ret= malloc(size + 8);
2841 if (ret != NULL)
2842 {
2843 ret= (void*)((caddr_t)ret + 8);
2844 }
2845 #else
2846 void *ret= malloc(size);
2847 #endif
2848
2849 if (ret != NULL)
2850 {
2851 memset(ret, 0xff, size);
2852 }
2853
2854 return ret;
2855 }
2856
2857
2858 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *)
2859 {
2860 #ifdef HARD_MALLOC_TESTS
2861 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
2862 void *nmem= realloc(real_ptr, size + 8);
2863
2864 void *ret= NULL;
2865 if (nmem != NULL)
2866 {
2867 ret= (void*)((caddr_t)nmem + 8);
2868 }
2869
2870 return ret;
2871 #else
2872 (void)ptr;
2873 return realloc(mem, size);
2874 #endif
2875 }
2876
2877
2878 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *)
2879 {
2880 #ifdef HARD_MALLOC_TESTS
2881 void *mem= my_malloc(ptr, nelem * size);
2882 if (mem)
2883 {
2884 memset(mem, 0, nelem * size);
2885 }
2886
2887 return mem;
2888 #else
2889 (void)ptr;
2890 return calloc(nelem, size);
2891 #endif
2892 }
2893
2894 test_return_t selection_of_namespace_tests(memcached_st *memc)
2895 {
2896 memcached_return_t rc;
2897 const char *key= "mine";
2898 char *value;
2899
2900 /* Make sure be default none exists */
2901 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2902 test_null(value);
2903 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2904
2905 /* Test a clean set */
2906 test_compare(MEMCACHED_SUCCESS,
2907 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
2908
2909 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2910 test_true(value);
2911 test_memcmp(value, key, 4);
2912 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2913
2914 /* Test that we can turn it off */
2915 test_compare(MEMCACHED_SUCCESS,
2916 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
2917
2918 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2919 test_null(value);
2920 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2921
2922 /* Now setup for main test */
2923 test_compare(MEMCACHED_SUCCESS,
2924 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
2925
2926 value= (char *)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2927 test_true(value);
2928 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2929 test_memcmp(value, key, 4);
2930
2931 /* Set to Zero, and then Set to something too large */
2932 {
2933 char long_key[255];
2934 memset(long_key, 0, 255);
2935
2936 test_compare(MEMCACHED_SUCCESS,
2937 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
2938
2939 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2940 test_null(value);
2941 test_compare(MEMCACHED_SUCCESS, rc);
2942
2943 /* Test a long key for failure */
2944 /* TODO, extend test to determine based on setting, what result should be */
2945 strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key));
2946 test_compare(MEMCACHED_SUCCESS,
2947 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
2948
2949 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
2950 strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key));
2951 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
2952 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
2953
2954 /* Test for a bad prefix, but with a short key */
2955 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_INVALID_ARGUMENTS : MEMCACHED_SUCCESS,
2956 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1));
2957
2958 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
2959 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, "dog cat"));
2960 }
2961
2962 return TEST_SUCCESS;
2963 }
2964
2965 test_return_t set_namespace(memcached_st *memc)
2966 {
2967 memcached_return_t rc;
2968 const char *key= "mine";
2969 char *value;
2970
2971 // Make sure we default to a null namespace
2972 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2973 test_null(value);
2974 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2975
2976 /* Test a clean set */
2977 test_compare(MEMCACHED_SUCCESS,
2978 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
2979
2980 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2981 test_true(value);
2982 test_memcmp(value, key, 4);
2983 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2984
2985 return TEST_SUCCESS;
2986 }
2987
2988 test_return_t set_namespace_and_binary(memcached_st *memc)
2989 {
2990 test_return_if(pre_binary(memc));
2991 test_return_if(set_namespace(memc));
2992
2993 return TEST_SUCCESS;
2994 }
2995
2996 #ifdef MEMCACHED_ENABLE_DEPRECATED
2997 test_return_t deprecated_set_memory_alloc(memcached_st *memc)
2998 {
2999 void *test_ptr= NULL;
3000 void *cb_ptr= NULL;
3001 {
3002 memcached_malloc_fn malloc_cb= (memcached_malloc_fn)my_malloc;
3003 cb_ptr= *(void **)&malloc_cb;
3004 memcached_return_t rc;
3005
3006 test_compare(MEMCACHED_SUCCESS,
3007 memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr));
3008 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3009 test_compare(MEMCACHED_SUCCESS, rc);
3010 test_true(test_ptr == cb_ptr);
3011 }
3012
3013 {
3014 memcached_realloc_fn realloc_cb=
3015 (memcached_realloc_fn)my_realloc;
3016 cb_ptr= *(void **)&realloc_cb;
3017 memcached_return_t rc;
3018
3019 test_compare(MEMCACHED_SUCCESS,
3020 memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr));
3021 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3022 test_compare(MEMCACHED_SUCCESS, rc);
3023 test_true(test_ptr == cb_ptr);
3024 }
3025
3026 {
3027 memcached_free_fn free_cb=
3028 (memcached_free_fn)my_free;
3029 cb_ptr= *(void **)&free_cb;
3030 memcached_return_t rc;
3031
3032 test_compare(MEMCACHED_SUCCESS,
3033 memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr));
3034 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3035 test_compare(MEMCACHED_SUCCESS, rc);
3036 test_true(test_ptr == cb_ptr);
3037 }
3038
3039 return TEST_SUCCESS;
3040 }
3041 #endif
3042
3043
3044 test_return_t set_memory_alloc(memcached_st *memc)
3045 {
3046 test_compare(MEMCACHED_INVALID_ARGUMENTS,
3047 memcached_set_memory_allocators(memc, NULL, my_free,
3048 my_realloc, my_calloc, NULL));
3049
3050 test_compare(MEMCACHED_SUCCESS,
3051 memcached_set_memory_allocators(memc, my_malloc, my_free,
3052 my_realloc, my_calloc, NULL));
3053
3054 memcached_malloc_fn mem_malloc;
3055 memcached_free_fn mem_free;
3056 memcached_realloc_fn mem_realloc;
3057 memcached_calloc_fn mem_calloc;
3058 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3059 &mem_realloc, &mem_calloc);
3060
3061 test_true(mem_malloc == my_malloc);
3062 test_true(mem_realloc == my_realloc);
3063 test_true(mem_calloc == my_calloc);
3064 test_true(mem_free == my_free);
3065
3066 return TEST_SUCCESS;
3067 }
3068
3069 test_return_t enable_consistent_crc(memcached_st *memc)
3070 {
3071 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT));
3072 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
3073
3074 test_return_t rc;
3075 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3076 {
3077 return rc;
3078 }
3079
3080 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
3081
3082 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH) != MEMCACHED_HASH_CRC)
3083 {
3084 return TEST_SKIPPED;
3085 }
3086
3087 return TEST_SUCCESS;
3088 }
3089
3090 test_return_t enable_consistent_hsieh(memcached_st *memc)
3091 {
3092 test_return_t rc;
3093 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT);
3094 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3095 {
3096 return rc;
3097 }
3098
3099 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
3100
3101 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH) != MEMCACHED_HASH_HSIEH)
3102 {
3103 return TEST_SKIPPED;
3104 }
3105
3106 return TEST_SUCCESS;
3107 }
3108
3109 test_return_t enable_cas(memcached_st *memc)
3110 {
3111 unsigned int set= 1;
3112
3113 if (libmemcached_util_version_check(memc, 1, 2, 4))
3114 {
3115 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3116
3117 return TEST_SUCCESS;
3118 }
3119
3120 return TEST_SKIPPED;
3121 }
3122
3123 test_return_t check_for_1_2_3(memcached_st *memc)
3124 {
3125 memcached_version(memc);
3126
3127 memcached_server_instance_st instance=
3128 memcached_server_instance_by_position(memc, 0);
3129
3130 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3131 or instance->minor_version > 2)
3132 {
3133 return TEST_SUCCESS;
3134 }
3135
3136 return TEST_SKIPPED;
3137 }
3138
3139 test_return_t MEMCACHED_BEHAVIOR_POLL_TIMEOUT_test(memcached_st *memc)
3140 {
3141 const uint64_t timeout= 100; // Not using, just checking that it sets
3142
3143 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3144
3145 test_compare(timeout, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT));
3146
3147 return TEST_SUCCESS;
3148 }
3149
3150 test_return_t noreply_test(memcached_st *memc)
3151 {
3152 test_compare(MEMCACHED_SUCCESS,
3153 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, true));
3154 test_compare(MEMCACHED_SUCCESS,
3155 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
3156 test_compare(MEMCACHED_SUCCESS,
3157 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
3158 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY));
3159 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS));
3160 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS));
3161
3162 memcached_return_t ret;
3163 for (int count= 0; count < 5; ++count)
3164 {
3165 for (size_t x= 0; x < 100; ++x)
3166 {
3167 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
3168 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
3169 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
3170
3171 size_t len= (size_t)check_length;
3172
3173 switch (count)
3174 {
3175 case 0:
3176 ret= memcached_add(memc, key, len, key, len, 0, 0);
3177 break;
3178 case 1:
3179 ret= memcached_replace(memc, key, len, key, len, 0, 0);
3180 break;
3181 case 2:
3182 ret= memcached_set(memc, key, len, key, len, 0, 0);
3183 break;
3184 case 3:
3185 ret= memcached_append(memc, key, len, key, len, 0, 0);
3186 break;
3187 case 4:
3188 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
3189 break;
3190 default:
3191 test_true(count);
3192 break;
3193 }
3194 test_true_got(ret == MEMCACHED_SUCCESS or ret == MEMCACHED_BUFFERED,
3195 memcached_strerror(NULL, ret));
3196 }
3197
3198 /*
3199 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3200 ** API and is _ONLY_ done this way to verify that the library works the
3201 ** way it is supposed to do!!!!
3202 */
3203 #if 0
3204 int no_msg=0;
3205 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
3206 {
3207 memcached_server_instance_st instance=
3208 memcached_server_instance_by_position(memc, x);
3209 no_msg+=(int)(instance->cursor_active);
3210 }
3211
3212 test_true(no_msg == 0);
3213 #endif
3214 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
3215
3216 /*
3217 ** Now validate that all items was set properly!
3218 */
3219 for (size_t x= 0; x < 100; ++x)
3220 {
3221 char key[10];
3222
3223 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
3224
3225 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
3226
3227 size_t len= (size_t)check_length;
3228 size_t length;
3229 uint32_t flags;
3230 char* value=memcached_get(memc, key, strlen(key),
3231 &length, &flags, &ret);
3232 // For the moment we will just go to the next key
3233 if (MEMCACHED_TIMEOUT == ret)
3234 {
3235 continue;
3236 }
3237 test_true(ret == MEMCACHED_SUCCESS and value != NULL);
3238 switch (count)
3239 {
3240 case 0: /* FALLTHROUGH */
3241 case 1: /* FALLTHROUGH */
3242 case 2:
3243 test_true(strncmp(value, key, len) == 0);
3244 test_true(len == length);
3245 break;
3246 case 3:
3247 test_true(length == len * 2);
3248 break;
3249 case 4:
3250 test_true(length == len * 3);
3251 break;
3252 default:
3253 test_true(count);
3254 break;
3255 }
3256 free(value);
3257 }
3258 }
3259
3260 /* Try setting an illegal cas value (should not return an error to
3261 * the caller (because we don't expect a return message from the server)
3262 */
3263 const char* keys[]= {"0"};
3264 size_t lengths[]= {1};
3265 size_t length;
3266 uint32_t flags;
3267 memcached_result_st results_obj;
3268 memcached_result_st *results;
3269 test_compare(MEMCACHED_SUCCESS,
3270 memcached_mget(memc, keys, lengths, 1));
3271
3272 results= memcached_result_create(memc, &results_obj);
3273 test_true(results);
3274 results= memcached_fetch_result(memc, &results_obj, &ret);
3275 test_true(results);
3276 test_compare(MEMCACHED_SUCCESS, ret);
3277 uint64_t cas= memcached_result_cas(results);
3278 memcached_result_free(&results_obj);
3279
3280 test_compare(MEMCACHED_SUCCESS,
3281 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
3282
3283 /*
3284 * The item will have a new cas value, so try to set it again with the old
3285 * value. This should fail!
3286 */
3287 test_compare(MEMCACHED_SUCCESS,
3288 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
3289 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3290 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3291 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
3292 free(value);
3293
3294 return TEST_SUCCESS;
3295 }
3296
3297 test_return_t analyzer_test(memcached_st *memc)
3298 {
3299 memcached_analysis_st *report;
3300 memcached_return_t rc;
3301
3302 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
3303 test_compare(MEMCACHED_SUCCESS, rc);
3304 test_true(memc_stat);
3305
3306 report= memcached_analyze(memc, memc_stat, &rc);
3307 test_compare(MEMCACHED_SUCCESS, rc);
3308 test_true(report);
3309
3310 free(report);
3311 memcached_stat_free(NULL, memc_stat);
3312
3313 return TEST_SUCCESS;
3314 }
3315
3316 test_return_t util_version_test(memcached_st *memc)
3317 {
3318 test_compare_hint(MEMCACHED_SUCCESS, memcached_version(memc), memcached_last_error_message(memc));
3319 test_true(libmemcached_util_version_check(memc, 0, 0, 0));
3320
3321 bool if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
3322
3323 // We expect failure
3324 if (if_successful)
3325 {
3326 fprintf(stderr, "\n----------------------------------------------------------------------\n");
3327 fprintf(stderr, "\nDumping Server Information\n\n");
3328 memcached_server_fn callbacks[1];
3329
3330 callbacks[0]= dump_server_information;
3331 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
3332 fprintf(stderr, "\n----------------------------------------------------------------------\n");
3333 }
3334 test_true(if_successful == false);
3335
3336 memcached_server_instance_st instance=
3337 memcached_server_instance_by_position(memc, 0);
3338
3339 memcached_version(memc);
3340
3341 // We only use one binary when we test, so this should be just fine.
3342 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
3343 test_true(if_successful == true);
3344
3345 if (instance->micro_version > 0)
3346 {
3347 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
3348 }
3349 else if (instance->minor_version > 0)
3350 {
3351 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
3352 }
3353 else if (instance->major_version > 0)
3354 {
3355 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
3356 }
3357
3358 test_true(if_successful == true);
3359
3360 if (instance->micro_version > 0)
3361 {
3362 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
3363 }
3364 else if (instance->minor_version > 0)
3365 {
3366 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
3367 }
3368 else if (instance->major_version > 0)
3369 {
3370 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
3371 }
3372
3373 test_true(if_successful == false);
3374
3375 return TEST_SUCCESS;
3376 }
3377
3378 test_return_t getpid_connection_failure_test(memcached_st *memc)
3379 {
3380 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
3381 memcached_return_t rc;
3382 memcached_server_instance_st instance=
3383 memcached_server_instance_by_position(memc, 0);
3384
3385 // Test both the version that returns a code, and the one that does not.
3386 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3387 memcached_server_port(instance) -1, NULL) == -1);
3388
3389 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3390 memcached_server_port(instance) -1, &rc) == -1);
3391 test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_strerror(memc, rc));
3392
3393 return TEST_SUCCESS;
3394 }
3395
3396
3397 test_return_t getpid_test(memcached_st *memc)
3398 {
3399 memcached_return_t rc;
3400 memcached_server_instance_st instance=
3401 memcached_server_instance_by_position(memc, 0);
3402
3403 // Test both the version that returns a code, and the one that does not.
3404 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3405 memcached_server_port(instance), NULL) > -1);
3406
3407 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3408 memcached_server_port(instance), &rc) > -1);
3409 test_compare(MEMCACHED_SUCCESS, rc);
3410
3411 return TEST_SUCCESS;
3412 }
3413
3414 static memcached_return_t ping_each_server(const memcached_st*,
3415 const memcached_server_st *instance,
3416 void*)
3417 {
3418 // Test both the version that returns a code, and the one that does not.
3419 memcached_return_t rc;
3420 if (libmemcached_util_ping(memcached_server_name(instance),
3421 memcached_server_port(instance), &rc) == false)
3422 {
3423 throw libtest::fatal(LIBYATL_DEFAULT_PARAM, "%s:%d %s", memcached_server_name(instance),
3424 memcached_server_port(instance), memcached_strerror(NULL, rc));
3425 }
3426
3427 if (libmemcached_util_ping(memcached_server_name(instance),
3428 memcached_server_port(instance), NULL) == false)
3429 {
3430 throw libtest::fatal(LIBYATL_DEFAULT_PARAM, "%s:%d", memcached_server_name(instance), memcached_server_port(instance));
3431 }
3432
3433 return MEMCACHED_SUCCESS;
3434 }
3435
3436 test_return_t libmemcached_util_ping_TEST(memcached_st *memc)
3437 {
3438 memcached_server_fn callbacks[1]= { ping_each_server };
3439 memcached_server_cursor(memc, callbacks, NULL, 1);
3440
3441 return TEST_SUCCESS;
3442 }
3443
3444
3445 #if 0
3446 test_return_t hash_sanity_test (memcached_st *memc)
3447 {
3448 (void)memc;
3449
3450 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
3451 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
3452 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
3453 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
3454 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
3455 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
3456 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
3457 #ifdef HAVE_HSIEH_HASH
3458 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
3459 #endif
3460 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
3461 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
3462 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
3463
3464 return TEST_SUCCESS;
3465 }
3466 #endif
3467
3468 test_return_t hsieh_avaibility_test (memcached_st *memc)
3469 {
3470 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
3471
3472 test_compare(MEMCACHED_SUCCESS,
3473 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
3474 (uint64_t)MEMCACHED_HASH_HSIEH));
3475
3476 return TEST_SUCCESS;
3477 }
3478
3479 test_return_t murmur_avaibility_test (memcached_st *memc)
3480 {
3481 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
3482
3483 test_compare(MEMCACHED_SUCCESS,
3484 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR));
3485
3486 return TEST_SUCCESS;
3487 }
3488
3489 test_return_t one_at_a_time_run (memcached_st *)
3490 {
3491 uint32_t x;
3492 const char **ptr;
3493
3494 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3495 {
3496 test_compare(one_at_a_time_values[x],
3497 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT));
3498 }
3499
3500 return TEST_SUCCESS;
3501 }
3502
3503 test_return_t md5_run (memcached_st *)
3504 {
3505 uint32_t x;
3506 const char **ptr;
3507
3508 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3509 {
3510 test_compare(md5_values[x],
3511 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5));
3512 }
3513
3514 return TEST_SUCCESS;
3515 }
3516
3517 test_return_t crc_run (memcached_st *)
3518 {
3519 uint32_t x;
3520 const char **ptr;
3521
3522 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3523 {
3524 test_compare(crc_values[x],
3525 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC));
3526 }
3527
3528 return TEST_SUCCESS;
3529 }
3530
3531 test_return_t fnv1_64_run (memcached_st *)
3532 {
3533 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1_64));
3534
3535 uint32_t x;
3536 const char **ptr;
3537
3538 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3539 {
3540 test_compare(fnv1_64_values[x],
3541 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64));
3542 }
3543
3544 return TEST_SUCCESS;
3545 }
3546
3547 test_return_t fnv1a_64_run (memcached_st *)
3548 {
3549 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1A_64));
3550
3551 uint32_t x;
3552 const char **ptr;
3553
3554 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3555 {
3556 test_compare(fnv1a_64_values[x],
3557 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64));
3558 }
3559
3560 return TEST_SUCCESS;
3561 }
3562
3563 test_return_t fnv1_32_run (memcached_st *)
3564 {
3565 uint32_t x;
3566 const char **ptr;
3567
3568 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3569 {
3570 test_compare(fnv1_32_values[x],
3571 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32));
3572 }
3573
3574 return TEST_SUCCESS;
3575 }
3576
3577 test_return_t fnv1a_32_run (memcached_st *)
3578 {
3579 uint32_t x;
3580 const char **ptr;
3581
3582 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3583 {
3584 test_compare(fnv1a_32_values[x],
3585 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32));
3586 }
3587
3588 return TEST_SUCCESS;
3589 }
3590
3591 test_return_t hsieh_run (memcached_st *)
3592 {
3593 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
3594
3595 uint32_t x;
3596 const char **ptr;
3597
3598 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3599 {
3600 test_compare(hsieh_values[x],
3601 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH));
3602 }
3603
3604 return TEST_SUCCESS;
3605 }
3606
3607 test_return_t murmur_run (memcached_st *)
3608 {
3609 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
3610
3611 #ifdef WORDS_BIGENDIAN
3612 (void)murmur_values;
3613 return TEST_SKIPPED;
3614 #else
3615 uint32_t x;
3616 const char **ptr;
3617
3618 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3619 {
3620 test_compare(murmur_values[x],
3621 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR));
3622 }
3623
3624 return TEST_SUCCESS;
3625 #endif
3626 }
3627
3628 test_return_t jenkins_run (memcached_st *)
3629 {
3630 uint32_t x;
3631 const char **ptr;
3632
3633 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3634 {
3635 test_compare(jenkins_values[x],
3636 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS));
3637 }
3638
3639 return TEST_SUCCESS;
3640 }
3641
3642 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *)
3643 {
3644 return libhashkit_md5(string, string_length);
3645 }
3646
3647 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *)
3648 {
3649 return libhashkit_crc32(string, string_length);
3650 }
3651
3652 test_return_t memcached_get_hashkit_test (memcached_st *)
3653 {
3654 uint32_t x;
3655 const char **ptr;
3656 hashkit_st new_kit;
3657
3658 memcached_st *memc= memcached(test_literal_param("--server=localhost:1 --server=localhost:2 --server=localhost:3 --server=localhost:4 --server=localhost5 --DISTRIBUTION=modula"));
3659
3660 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};
3661 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};
3662
3663 const hashkit_st *kit= memcached_get_hashkit(memc);
3664
3665 hashkit_clone(&new_kit, kit);
3666 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL));
3667
3668 memcached_set_hashkit(memc, &new_kit);
3669
3670 /*
3671 Verify Setting the hash.
3672 */
3673 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3674 {
3675 uint32_t hash_val;
3676
3677 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
3678 test_compare_got(md5_values[x], hash_val, *ptr);
3679 }
3680
3681
3682 /*
3683 Now check memcached_st.
3684 */
3685 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3686 {
3687 uint32_t hash_val;
3688
3689 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
3690 test_compare_got(md5_hosts[x], hash_val, *ptr);
3691 }
3692
3693 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL));
3694
3695 memcached_set_hashkit(memc, &new_kit);
3696
3697 /*
3698 Verify Setting the hash.
3699 */
3700 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3701 {
3702 uint32_t hash_val;
3703
3704 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
3705 test_true(crc_values[x] == hash_val);
3706 }
3707
3708 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3709 {
3710 uint32_t hash_val;
3711
3712 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
3713 test_compare(crc_hosts[x], hash_val);
3714 }
3715
3716 memcached_free(memc);
3717
3718 return TEST_SUCCESS;
3719 }
3720
3721 /*
3722 Test case adapted from John Gorman <johngorman2@gmail.com>
3723
3724 We are testing the error condition when we connect to a server via memcached_get()
3725 but find that the server is not available.
3726 */
3727 test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *)
3728 {
3729 size_t len;
3730 uint32_t flags;
3731 memcached_return rc;
3732
3733 // Create a handle.
3734 memcached_st *tl_memc_h= memcached(test_literal_param("--server=localhost:9898 --server=localhost:9899")); // This server should not exist
3735
3736 // See if memcached is reachable.
3737 char *value= memcached_get(tl_memc_h,
3738 test_literal_param(__func__),
3739 &len, &flags, &rc);
3740
3741 test_false(value);
3742 test_zero(len);
3743 test_true(memcached_failed(rc));
3744
3745 memcached_free(tl_memc_h);
3746
3747 return TEST_SUCCESS;
3748 }
3749
3750 /*
3751 We connect to a server which exists, but search for a key that does not exist.
3752 */
3753 test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
3754 {
3755 size_t len;
3756 uint32_t flags;
3757 memcached_return rc;
3758
3759 // See if memcached is reachable.
3760 char *value= memcached_get(memc,
3761 test_literal_param(__func__),
3762 &len, &flags, &rc);
3763
3764 test_false(value);
3765 test_zero(len);
3766 test_compare(MEMCACHED_NOTFOUND, rc);
3767
3768 return TEST_SUCCESS;
3769 }
3770
3771 /*
3772 Test case adapted from John Gorman <johngorman2@gmail.com>
3773
3774 We are testing the error condition when we connect to a server via memcached_get_by_key()
3775 but find that the server is not available.
3776 */
3777 test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *)
3778 {
3779 size_t len;
3780 uint32_t flags;
3781 memcached_return rc;
3782
3783 // Create a handle.
3784 memcached_st *tl_memc_h= memcached_create(NULL);
3785 memcached_server_st *servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
3786 memcached_server_push(tl_memc_h, servers);
3787 memcached_server_list_free(servers);
3788
3789 // See if memcached is reachable.
3790 char *value= memcached_get_by_key(tl_memc_h,
3791 test_literal_param(__func__), // Key
3792 test_literal_param(__func__), // Value
3793 &len, &flags, &rc);
3794
3795 test_false(value);
3796 test_zero(len);
3797 test_true(memcached_failed(rc));
3798
3799 memcached_free(tl_memc_h);
3800
3801 return TEST_SUCCESS;
3802 }
3803
3804 /*
3805 We connect to a server which exists, but search for a key that does not exist.
3806 */
3807 test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
3808 {
3809 size_t len;
3810 uint32_t flags;
3811 memcached_return rc;
3812
3813 // See if memcached is reachable.
3814 char *value= memcached_get_by_key(memc,
3815 test_literal_param(__func__), // Key
3816 test_literal_param(__func__), // Value
3817 &len, &flags, &rc);
3818
3819 test_false(value);
3820 test_zero(len);
3821 test_compare(MEMCACHED_NOTFOUND, rc);
3822
3823 return TEST_SUCCESS;
3824 }
3825
3826 test_return_t regression_bug_434484(memcached_st *memc)
3827 {
3828 test_skip(TEST_SUCCESS, pre_binary(memc));
3829
3830 test_compare(MEMCACHED_NOTSTORED,
3831 memcached_append(memc,
3832 test_literal_param(__func__), // Key
3833 test_literal_param(__func__), // Value
3834 0, 0));
3835
3836 libtest::vchar_t data;
3837 data.resize(2048 * 1024);
3838 test_compare(MEMCACHED_E2BIG,
3839 memcached_set(memc,
3840 test_literal_param(__func__), // Key
3841 &data[0], data.size(), 0, 0));
3842
3843 return TEST_SUCCESS;
3844 }
3845
3846 test_return_t regression_bug_434843(memcached_st *original_memc)
3847 {
3848 test_skip(TEST_SUCCESS, pre_binary(original_memc));
3849
3850 memcached_return_t rc;
3851 size_t counter= 0;
3852 memcached_execute_fn callbacks[]= { &callback_counter };
3853
3854 /*
3855 * I only want to hit only _one_ server so I know the number of requests I'm
3856 * sending in the pipleine to the server. Let's try to do a multiget of
3857 * 1024 (that should satisfy most users don't you think?). Future versions
3858 * will include a mget_execute function call if you need a higher number.
3859 */
3860 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
3861
3862 keys_st keys(1024);
3863
3864 /*
3865 * Run two times.. the first time we should have 100% cache miss,
3866 * and the second time we should have 100% cache hits
3867 */
3868 for (ptrdiff_t y= 0; y < 2; y++)
3869 {
3870 test_compare(MEMCACHED_SUCCESS,
3871 memcached_mget(memc, keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
3872
3873 // One the first run we should get a NOT_FOUND, but on the second some data
3874 // should be returned.
3875 test_compare(y ? MEMCACHED_SUCCESS : MEMCACHED_NOTFOUND,
3876 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
3877
3878 if (y == 0)
3879 {
3880 /* The first iteration should give me a 100% cache miss. verify that*/
3881 char blob[1024]= { 0 };
3882
3883 test_false(counter);
3884
3885 for (size_t x= 0; x < keys.size(); ++x)
3886 {
3887 rc= memcached_add(memc,
3888 keys.key_at(x), keys.length_at(x),
3889 blob, sizeof(blob), 0, 0);
3890 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
3891 }
3892 }
3893 else
3894 {
3895 /* Verify that we received all of the key/value pairs */
3896 test_compare(counter, keys.size());
3897 }
3898 }
3899
3900 memcached_free(memc);
3901
3902 return TEST_SUCCESS;
3903 }
3904
3905 test_return_t regression_bug_434843_buffered(memcached_st *memc)
3906 {
3907 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
3908
3909 return regression_bug_434843(memc);
3910 }
3911
3912 test_return_t regression_bug_421108(memcached_st *memc)
3913 {
3914 memcached_return_t rc;
3915 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
3916 test_compare(MEMCACHED_SUCCESS, rc);
3917
3918 char *bytes_str= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
3919 test_compare(MEMCACHED_SUCCESS, rc);
3920 test_true(bytes_str);
3921 char *bytes_read_str= memcached_stat_get_value(memc, memc_stat,
3922 "bytes_read", &rc);
3923 test_compare(MEMCACHED_SUCCESS, rc);
3924 test_true(bytes_read_str);
3925
3926 char *bytes_written_str= memcached_stat_get_value(memc, memc_stat,
3927 "bytes_written", &rc);
3928 test_compare(MEMCACHED_SUCCESS, rc);
3929 test_true(bytes_written_str);
3930
3931 unsigned long long bytes= strtoull(bytes_str, 0, 10);
3932 unsigned long long bytes_read= strtoull(bytes_read_str, 0, 10);
3933 unsigned long long bytes_written= strtoull(bytes_written_str, 0, 10);
3934
3935 test_true(bytes != bytes_read);
3936 test_true(bytes != bytes_written);
3937
3938 /* Release allocated resources */
3939 free(bytes_str);
3940 free(bytes_read_str);
3941 free(bytes_written_str);
3942 memcached_stat_free(NULL, memc_stat);
3943
3944 return TEST_SUCCESS;
3945 }
3946
3947 /*
3948 * The test case isn't obvious so I should probably document why
3949 * it works the way it does. Bug 442914 was caused by a bug
3950 * in the logic in memcached_purge (it did not handle the case
3951 * where the number of bytes sent was equal to the watermark).
3952 * In this test case, create messages so that we hit that case
3953 * and then disable noreply mode and issue a new command to
3954 * verify that it isn't stuck. If we change the format for the
3955 * delete command or the watermarks, we need to update this
3956 * test....
3957 */
3958 test_return_t regression_bug_442914(memcached_st *original_memc)
3959 {
3960 test_skip(original_memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
3961
3962 memcached_st* memc= create_single_instance_memcached(original_memc, "--NOREPLY --TCP-NODELAY");
3963
3964 for (uint32_t x= 0; x < 250; ++x)
3965 {
3966 char key[250];
3967 size_t len= (size_t)snprintf(key, sizeof(key), "%0250u", x);
3968 memcached_return_t rc= memcached_delete(memc, key, len, 0);
3969 char error_buffer[2048]= { 0 };
3970 snprintf(error_buffer, sizeof(error_buffer), "%s key: %s", memcached_last_error_message(memc), key);
3971 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, error_buffer);
3972 }
3973
3974 // Delete, and then delete again to look for not found
3975 {
3976 char key[250];
3977 size_t len= snprintf(key, sizeof(key), "%037u", 251U);
3978 memcached_return_t rc= memcached_delete(memc, key, len, 0);
3979 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
3980
3981 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, false));
3982 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, key, len, 0));
3983 }
3984
3985 memcached_free(memc);
3986
3987 return TEST_SUCCESS;
3988 }
3989
3990 test_return_t regression_bug_447342(memcached_st *memc)
3991 {
3992 if (memcached_server_count(memc) < 3 or pre_replication(memc) != TEST_SUCCESS)
3993 {
3994 return TEST_SKIPPED;
3995 }
3996
3997 test_compare(MEMCACHED_SUCCESS,
3998 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2));
3999
4000 keys_st keys(100);
4001
4002 for (size_t x= 0; x < keys.size(); ++x)
4003 {
4004 test_compare(MEMCACHED_SUCCESS,
4005 memcached_set(memc,
4006 keys.key_at(x), keys.length_at(x), // Keys
4007 keys.key_at(x), keys.length_at(x), // Values
4008 0, 0));
4009 }
4010
4011 /*
4012 ** We are using the quiet commands to store the replicas, so we need
4013 ** to ensure that all of them are processed before we can continue.
4014 ** In the test we go directly from storing the object to trying to
4015 ** receive the object from all of the different servers, so we
4016 ** could end up in a race condition (the memcached server hasn't yet
4017 ** processed the quiet command from the replication set when it process
4018 ** the request from the other client (created by the clone)). As a
4019 ** workaround for that we call memcached_quit to send the quit command
4020 ** to the server and wait for the response ;-) If you use the test code
4021 ** as an example for your own code, please note that you shouldn't need
4022 ** to do this ;-)
4023 */
4024 memcached_quit(memc);
4025
4026 /* Verify that all messages are stored, and we didn't stuff too much
4027 * into the servers
4028 */
4029 test_compare(MEMCACHED_SUCCESS,
4030 memcached_mget(memc,
4031 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4032
4033 unsigned int counter= 0;
4034 memcached_execute_fn callbacks[]= { &callback_counter };
4035 test_compare(MEMCACHED_SUCCESS,
4036 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4037
4038 /* Verify that we received all of the key/value pairs */
4039 test_compare(counter, keys.size());
4040
4041 memcached_quit(memc);
4042 /*
4043 * Don't do the following in your code. I am abusing the internal details
4044 * within the library, and this is not a supported interface.
4045 * This is to verify correct behavior in the library. Fake that two servers
4046 * are dead..
4047 */
4048 memcached_server_instance_st instance_one= memcached_server_instance_by_position(memc, 0);
4049 memcached_server_instance_st instance_two= memcached_server_instance_by_position(memc, 2);
4050 in_port_t port0= instance_one->port;
4051 in_port_t port2= instance_two->port;
4052
4053 ((memcached_server_write_instance_st)instance_one)->port= 0;
4054 ((memcached_server_write_instance_st)instance_two)->port= 0;
4055
4056 test_compare(MEMCACHED_SUCCESS,
4057 memcached_mget(memc,
4058 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4059
4060 counter= 0;
4061 test_compare(MEMCACHED_SUCCESS,
4062 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4063 test_compare(counter, keys.size());
4064
4065 /* restore the memc handle */
4066 ((memcached_server_write_instance_st)instance_one)->port= port0;
4067 ((memcached_server_write_instance_st)instance_two)->port= port2;
4068
4069 memcached_quit(memc);
4070
4071 /* Remove half of the objects */
4072 for (size_t x= 0; x < keys.size(); ++x)
4073 {
4074 if (x & 1)
4075 {
4076 test_compare(MEMCACHED_SUCCESS,
4077 memcached_delete(memc, keys.key_at(x), keys.length_at(x), 0));
4078 }
4079 }
4080
4081 memcached_quit(memc);
4082 ((memcached_server_write_instance_st)instance_one)->port= 0;
4083 ((memcached_server_write_instance_st)instance_two)->port= 0;
4084
4085 /* now retry the command, this time we should have cache misses */
4086 test_compare(MEMCACHED_SUCCESS,
4087 memcached_mget(memc,
4088 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4089
4090 counter= 0;
4091 test_compare(MEMCACHED_SUCCESS,
4092 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4093 test_compare(counter, (unsigned int)(keys.size() >> 1));
4094
4095 /* restore the memc handle */
4096 ((memcached_server_write_instance_st)instance_one)->port= port0;
4097 ((memcached_server_write_instance_st)instance_two)->port= port2;
4098
4099 return TEST_SUCCESS;
4100 }
4101
4102 test_return_t regression_bug_463297(memcached_st *memc)
4103 {
4104 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc, "foo", 3, 1));
4105
4106 // Since we blocked timed delete, this test is no longer valid.
4107 #if 0
4108 memcached_st *memc_clone= memcached_clone(NULL, memc);
4109 test_true(memc_clone);
4110 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
4111
4112 memcached_server_instance_st instance=
4113 memcached_server_instance_by_position(memc_clone, 0);
4114
4115 if (instance->major_version > 1 ||
4116 (instance->major_version == 1 &&
4117 instance->minor_version > 2))
4118 {
4119 /* Binary protocol doesn't support deferred delete */
4120 memcached_st *bin_clone= memcached_clone(NULL, memc);
4121 test_true(bin_clone);
4122 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4123 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(bin_clone, "foo", 3, 1));
4124 memcached_free(bin_clone);
4125
4126 memcached_quit(memc_clone);
4127
4128 /* If we know the server version, deferred delete should fail
4129 * with invalid arguments */
4130 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc_clone, "foo", 3, 1));
4131
4132 /* If we don't know the server version, we should get a protocol error */
4133 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
4134
4135 /* but there is a bug in some of the memcached servers (1.4) that treats
4136 * the counter as noreply so it doesn't send the proper error message
4137 */
4138 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4139
4140 /* And buffered mode should be disabled and we should get protocol error */
4141 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
4142 rc= memcached_delete(memc, "foo", 3, 1);
4143 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4144
4145 /* Same goes for noreply... */
4146 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
4147 rc= memcached_delete(memc, "foo", 3, 1);
4148 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4149
4150 /* but a normal request should go through (and be buffered) */
4151 test_compare(MEMCACHED_BUFFERED, (rc= memcached_delete(memc, "foo", 3, 0)));
4152 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
4153
4154 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0));
4155 /* unbuffered noreply should be success */
4156 test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
4157 /* unbuffered with reply should be not found... */
4158 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
4159 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, "foo", 3, 0));
4160 }
4161
4162 memcached_free(memc_clone);
4163 #endif
4164
4165 return TEST_SUCCESS;
4166 }
4167
4168
4169 /* Test memcached_server_get_last_disconnect
4170 * For a working server set, shall be NULL
4171 * For a set of non existing server, shall not be NULL
4172 */
4173 test_return_t test_get_last_disconnect(memcached_st *memc)
4174 {
4175 memcached_return_t rc;
4176 memcached_server_instance_st disconnected_server;
4177
4178 /* With the working set of server */
4179 const char *key= "marmotte";
4180 const char *value= "milka";
4181
4182 memcached_reset_last_disconnected_server(memc);
4183 test_false(memc->last_disconnected_server);
4184 rc= memcached_set(memc, key, strlen(key),
4185 value, strlen(value),
4186 (time_t)0, (uint32_t)0);
4187 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4188
4189 disconnected_server = memcached_server_get_last_disconnect(memc);
4190 test_false(disconnected_server);
4191
4192 /* With a non existing server */
4193 memcached_st *mine;
4194 memcached_server_st *servers;
4195
4196 const char *server_list= "localhost:9";
4197
4198 servers= memcached_servers_parse(server_list);
4199 test_true(servers);
4200 mine= memcached_create(NULL);
4201 rc= memcached_server_push(mine, servers);
4202 test_compare(MEMCACHED_SUCCESS, rc);
4203 memcached_server_list_free(servers);
4204 test_true(mine);
4205
4206 rc= memcached_set(mine, key, strlen(key),
4207 value, strlen(value),
4208 (time_t)0, (uint32_t)0);
4209 test_true(memcached_failed(rc));
4210
4211 disconnected_server= memcached_server_get_last_disconnect(mine);
4212 test_true_got(disconnected_server, memcached_strerror(mine, rc));
4213 test_compare(in_port_t(9), memcached_server_port(disconnected_server));
4214 test_false(strncmp(memcached_server_name(disconnected_server),"localhost",9));
4215
4216 memcached_quit(mine);
4217 memcached_free(mine);
4218
4219 return TEST_SUCCESS;
4220 }
4221
4222 test_return_t test_multiple_get_last_disconnect(memcached_st *)
4223 {
4224 const char *server_string= "--server=localhost:8888 --server=localhost:8889 --server=localhost:8890 --server=localhost:8891 --server=localhost:8892";
4225 char buffer[BUFSIZ];
4226
4227 test_compare(MEMCACHED_SUCCESS,
4228 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
4229
4230 memcached_st *memc= memcached(server_string, strlen(server_string));
4231 test_true(memc);
4232
4233 // We will just use the error strings as our keys
4234 uint32_t counter= 100;
4235 while (--counter)
4236 {
4237 for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x)
4238 {
4239 const char *msg= memcached_strerror(memc, memcached_return_t(x));
4240 memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
4241 test_true_got((ret == MEMCACHED_CONNECTION_FAILURE or ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED), memcached_last_error_message(memc));
4242
4243 memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc);
4244 test_true(disconnected_server);
4245 test_strcmp("localhost", memcached_server_name(disconnected_server));
4246 test_true(memcached_server_port(disconnected_server) >= 8888 and memcached_server_port(disconnected_server) <= 8892);
4247
4248 if (random() % 2)
4249 {
4250 memcached_reset_last_disconnected_server(memc);
4251 }
4252 }
4253 }
4254
4255 memcached_free(memc);
4256
4257 return TEST_SUCCESS;
4258 }
4259
4260 test_return_t test_verbosity(memcached_st *memc)
4261 {
4262 memcached_verbosity(memc, 3);
4263
4264 return TEST_SUCCESS;
4265 }
4266
4267
4268 static memcached_return_t stat_printer(memcached_server_instance_st server,
4269 const char *key, size_t key_length,
4270 const char *value, size_t value_length,
4271 void *context)
4272 {
4273 (void)server;
4274 (void)context;
4275 (void)key;
4276 (void)key_length;
4277 (void)value;
4278 (void)value_length;
4279
4280 return MEMCACHED_SUCCESS;
4281 }
4282
4283 test_return_t memcached_stat_execute_test(memcached_st *memc)
4284 {
4285 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
4286 test_compare(MEMCACHED_SUCCESS, rc);
4287
4288 test_compare(MEMCACHED_SUCCESS,
4289 memcached_stat_execute(memc, "slabs", stat_printer, NULL));
4290
4291 test_compare(MEMCACHED_SUCCESS,
4292 memcached_stat_execute(memc, "items", stat_printer, NULL));
4293
4294 test_compare(MEMCACHED_SUCCESS,
4295 memcached_stat_execute(memc, "sizes", stat_printer, NULL));
4296
4297 return TEST_SUCCESS;
4298 }
4299
4300 /*
4301 * This test ensures that the failure counter isn't incremented during
4302 * normal termination of the memcached instance.
4303 */
4304 test_return_t wrong_failure_counter_test(memcached_st *original_memc)
4305 {
4306 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
4307
4308 /* Ensure that we are connected to the server by setting a value */
4309 memcached_return_t rc= memcached_set(memc,
4310 test_literal_param(__func__), // Key
4311 test_literal_param(__func__), // Value
4312 time_t(0), uint32_t(0));
4313 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
4314
4315
4316 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
4317
4318 /* The test is to see that the memcached_quit doesn't increase the
4319 * the server failure conter, so let's ensure that it is zero
4320 * before sending quit
4321 */
4322 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
4323
4324 memcached_quit(memc);
4325
4326 /* Verify that it memcached_quit didn't increment the failure counter
4327 * Please note that this isn't bullet proof, because an error could
4328 * occur...
4329 */
4330 test_zero(instance->server_failure_counter);
4331
4332 memcached_free(memc);
4333
4334 return TEST_SUCCESS;
4335 }
4336
4337 /*
4338 * This tests ensures expected disconnections (for some behavior changes
4339 * for instance) do not wrongly increase failure counter
4340 */
4341 test_return_t wrong_failure_counter_two_test(memcached_st *memc)
4342 {
4343 /* Set value to force connection to the server */
4344 const char *key= "marmotte";
4345 const char *value= "milka";
4346
4347 test_compare_hint(MEMCACHED_SUCCESS,
4348 memcached_set(memc, key, strlen(key),
4349 value, strlen(value),
4350 (time_t)0, (uint32_t)0),
4351 memcached_last_error_message(memc));
4352
4353
4354 /* put failure limit to 1 */
4355 test_compare(MEMCACHED_SUCCESS,
4356 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, true));
4357
4358 /* Put a retry timeout to effectively activate failure_limit effect */
4359 test_compare(MEMCACHED_SUCCESS,
4360 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, true));
4361
4362 /* change behavior that triggers memcached_quit()*/
4363 test_compare(MEMCACHED_SUCCESS,
4364 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true));
4365
4366
4367 /* Check if we still are connected */
4368 uint32_t flags;
4369 size_t string_length;
4370 memcached_return rc;
4371 char *string= memcached_get(memc, key, strlen(key),
4372 &string_length, &flags, &rc);
4373
4374 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
4375 test_true(string);
4376 free(string);
4377
4378 return TEST_SUCCESS;
4379 }
4380
4381 test_return_t regression_996813_TEST(memcached_st *)
4382 {
4383 memcached_st* memc= memcached_create(NULL);
4384
4385 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
4386 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1));
4387 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
4388 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4389 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1));
4390 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 300));
4391 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 30));
4392
4393 // We will never connect to these servers
4394 in_port_t base_port= 11211;
4395 for (size_t x= 0; x < 17; x++)
4396 {
4397 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", base_port +x));
4398 }
4399 test_compare(6U, memcached_generate_hash(memc, test_literal_param("SZ6hu0SHweFmpwpc0w2R")));
4400 test_compare(1U, memcached_generate_hash(memc, test_literal_param("SQCK9eiCf53YxHWnYA.o")));
4401 test_compare(9U, memcached_generate_hash(memc, test_literal_param("SUSDkGXuuZC9t9VhMwa.")));
4402 test_compare(0U, memcached_generate_hash(memc, test_literal_param("SnnqnJARfaCNT679iAF_")));
4403
4404 memcached_free(memc);
4405
4406 return TEST_SUCCESS;
4407 }
4408
4409
4410 /*
4411 * Test that ensures mget_execute does not end into recursive calls that finally fails
4412 */
4413 test_return_t regression_bug_490486(memcached_st *original_memc)
4414 {
4415
4416 #ifdef __APPLE__
4417 return TEST_SKIPPED; // My MAC can't handle this test
4418 #endif
4419
4420 test_skip(TEST_SUCCESS, pre_binary(original_memc));
4421
4422 /*
4423 * I only want to hit _one_ server so I know the number of requests I'm
4424 * sending in the pipeline.
4425 */
4426 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL --POLL-TIMEOUT=1000 --REMOVE-FAILED-SERVERS=1 --RETRY-TIMEOUT=3600");
4427 test_true(memc);
4428
4429 keys_st keys(20480);
4430
4431 /* First add all of the items.. */
4432 char blob[1024]= { 0 };
4433 for (size_t x= 0; x < keys.size(); ++x)
4434 {
4435 memcached_return rc= memcached_set(memc,
4436 keys.key_at(x), keys.length_at(x),
4437 blob, sizeof(blob), 0, 0);
4438 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); // MEMCACHED_TIMEOUT <-- hash been observed on OSX
4439 }
4440
4441 {
4442
4443 /* Try to get all of them with a large multiget */
4444 size_t counter= 0;
4445 memcached_execute_function callbacks[]= { &callback_counter };
4446 memcached_return_t rc= memcached_mget_execute(memc,
4447 keys.keys_ptr(), keys.lengths_ptr(), keys.size(),
4448 callbacks, &counter, 1);
4449 test_compare(MEMCACHED_SUCCESS, rc);
4450
4451 char* the_value= NULL;
4452 char the_key[MEMCACHED_MAX_KEY];
4453 size_t the_key_length;
4454 size_t the_value_length;
4455 uint32_t the_flags;
4456
4457 do {
4458 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
4459
4460 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
4461 {
4462 ++counter;
4463 free(the_value);
4464 }
4465
4466 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
4467
4468
4469 test_compare(MEMCACHED_END, rc);
4470
4471 /* Verify that we got all of the items */
4472 test_compare(counter, keys.size());
4473 }
4474
4475 memcached_free(memc);
4476
4477 return TEST_SUCCESS;
4478 }
4479
4480 test_return_t regression_bug_583031(memcached_st *)
4481 {
4482 memcached_st *memc= memcached_create(NULL);
4483 test_true(memc);
4484 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", 11211));
4485
4486 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
4487 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
4488 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4489 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4490 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
4491 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
4492
4493 memcached_return_t rc;
4494 size_t length;
4495 uint32_t flags;
4496
4497 const char *value= memcached_get(memc, "dsf", 3, &length, &flags, &rc);
4498 test_false(value);
4499 test_zero(length);
4500
4501 test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_last_error_message(memc));
4502
4503 memcached_free(memc);
4504
4505 return TEST_SUCCESS;
4506 }
4507
4508 test_return_t regression_bug_581030(memcached_st *)
4509 {
4510 #ifndef DEBUG
4511 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
4512 test_false(local_stat);
4513
4514 memcached_stat_free(NULL, NULL);
4515 #endif
4516
4517 return TEST_SUCCESS;
4518 }
4519
4520 #define regression_bug_655423_COUNT 6000
4521 test_return_t regression_bug_655423(memcached_st *memc)
4522 {
4523 memcached_st *clone= memcached_clone(NULL, memc);
4524 memc= NULL; // Just to make sure it is not used
4525 test_true(clone);
4526 char payload[100];
4527
4528 #ifdef __APPLE__
4529 return TEST_SKIPPED;
4530 #endif
4531
4532 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4533 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1));
4534 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
4535 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 1));
4536
4537 memset(payload, int('x'), sizeof(payload));
4538
4539 keys_st keys(regression_bug_655423_COUNT);
4540
4541 for (size_t x= 0; x < keys.size(); x++)
4542 {
4543 test_compare(MEMCACHED_SUCCESS, memcached_set(clone,
4544 keys.key_at(x),
4545 keys.length_at(x),
4546 payload, sizeof(payload), 0, 0));
4547 }
4548
4549 for (size_t x= 0; x < keys.size(); x++)
4550 {
4551 size_t value_length;
4552 memcached_return_t rc;
4553 char *value= memcached_get(clone,
4554 keys.key_at(x),
4555 keys.length_at(x),
4556 &value_length, NULL, &rc);
4557
4558 if (rc == MEMCACHED_NOTFOUND)
4559 {
4560 test_false(value);
4561 test_zero(value_length);
4562 continue;
4563 }
4564
4565 test_compare(MEMCACHED_SUCCESS, rc);
4566 test_true(value);
4567 test_compare(100LLU, value_length);
4568 free(value);
4569 }
4570
4571 test_compare(MEMCACHED_SUCCESS,
4572 memcached_mget(clone,
4573 keys.keys_ptr(), keys.lengths_ptr(),
4574 keys.size()));
4575
4576 uint32_t count= 0;
4577 memcached_result_st *result= NULL;
4578 while ((result= memcached_fetch_result(clone, result, NULL)))
4579 {
4580 test_compare(size_t(100), memcached_result_length(result));
4581 count++;
4582 }
4583
4584 test_true(count > 100); // If we don't get back atleast this, something is up
4585
4586 memcached_free(clone);
4587
4588 return TEST_SUCCESS;
4589 }
4590
4591 /*
4592 * Test that ensures that buffered set to not trigger problems during io_flush
4593 */
4594 #define regression_bug_490520_COUNT 200480
4595 test_return_t regression_bug_490520(memcached_st *original_memc)
4596 {
4597 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
4598
4599 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK,1);
4600 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,1);
4601 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
4602 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,1);
4603 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
4604
4605 /* First add all of the items.. */
4606 char blob[3333] = {0};
4607 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
4608 {
4609 char key[251];
4610 int key_length= snprintf(key, sizeof(key), "0200%u", x);
4611
4612 memcached_return rc= memcached_set(memc, key, key_length, blob, sizeof(blob), 0, 0);
4613 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_last_error_message(memc));
4614 }
4615
4616 memcached_free(memc);
4617
4618 return TEST_SUCCESS;
4619 }
4620
4621 test_return_t regression_1009493_TEST(memcached_st*)
4622 {
4623 memcached_st* memc= memcached_create(NULL);
4624 test_true(memc);
4625 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, true));
4626
4627 memcached_st* clone= memcached_clone(NULL, memc);
4628 test_true(clone);
4629
4630 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED),
4631 memcached_behavior_get(clone, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
4632
4633 memcached_free(memc);
4634 memcached_free(clone);
4635
4636 return TEST_SUCCESS;
4637 }
4638
4639 test_return_t regression_994772_TEST(memcached_st* memc)
4640 {
4641 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4642
4643 test_compare(MEMCACHED_SUCCESS,
4644 memcached_set(memc,
4645 test_literal_param(__func__), // Key
4646 test_literal_param(__func__), // Value
4647 time_t(0), uint32_t(0)));
4648
4649 const char *keys[] = { __func__ };
4650 size_t key_length[]= { strlen(__func__) };
4651 test_compare(MEMCACHED_SUCCESS,
4652 memcached_mget(memc, keys, key_length, 1));
4653
4654 memcached_return_t rc;
4655 memcached_result_st *results= memcached_fetch_result(memc, NULL, &rc);
4656 test_true(results);
4657 test_compare(MEMCACHED_SUCCESS, rc);
4658
4659 test_strcmp(__func__, memcached_result_value(results));
4660 uint64_t cas_value= memcached_result_cas(results);
4661 test_true(cas_value);
4662
4663 memcached_result_free(results);
4664
4665 // Bad cas value, sanity check
4666 test_true(cas_value != 9999);
4667 test_compare(MEMCACHED_END,
4668 memcached_cas(memc,
4669 test_literal_param(__func__), // Key
4670 test_literal_param(__FILE__), // Value
4671 time_t(0), uint32_t(0), 9999));
4672
4673 test_compare(MEMCACHED_SUCCESS, memcached_set(memc,
4674 "different", strlen("different"), // Key
4675 test_literal_param(__FILE__), // Value
4676 time_t(0), uint32_t(0)));
4677
4678 return TEST_SUCCESS;
4679 }
4680
4681 test_return_t regression_bug_854604(memcached_st *)
4682 {
4683 char buffer[1024];
4684
4685 test_compare(MEMCACHED_INVALID_ARGUMENTS, libmemcached_check_configuration(0, 0, buffer, 0));
4686
4687 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 0));
4688
4689 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 1));
4690 test_compare(buffer[0], 0);
4691
4692 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 10));
4693 test_true(strlen(buffer));
4694
4695 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, sizeof(buffer)));
4696 test_true(strlen(buffer));
4697
4698 return TEST_SUCCESS;
4699 }
4700
4701 static void die_message(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
4702 {
4703 fprintf(stderr, "Iteration #%u: ", it);
4704
4705 if (error == MEMCACHED_ERRNO)
4706 {
4707 fprintf(stderr, "system error %d from %s: %s\n",
4708 errno, what, strerror(errno));
4709 }
4710 else
4711 {
4712 fprintf(stderr, "error %d from %s: %s\n", error, what,
4713 memcached_strerror(mc, error));
4714 }
4715 }
4716
4717 #define TEST_CONSTANT_CREATION 200
4718
4719 test_return_t regression_bug_(memcached_st *memc)
4720 {
4721 const char *remote_server;
4722 (void)memc;
4723
4724 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
4725 {
4726 return TEST_SKIPPED;
4727 }
4728
4729 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
4730 {
4731 memcached_st* mc= memcached_create(NULL);
4732 memcached_return rc;
4733
4734 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
4735 if (rc != MEMCACHED_SUCCESS)
4736 {
4737 die_message(mc, rc, "memcached_behavior_set", x);
4738 }
4739
4740 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
4741 if (rc != MEMCACHED_SUCCESS)
4742 {
4743 die_message(mc, rc, "memcached_behavior_set", x);
4744 }
4745
4746 rc= memcached_server_add(mc, remote_server, 0);
4747 if (rc != MEMCACHED_SUCCESS)
4748 {
4749 die_message(mc, rc, "memcached_server_add", x);
4750 }
4751
4752 const char *set_key= "akey";
4753 const size_t set_key_len= strlen(set_key);
4754 const char *set_value= "a value";
4755 const size_t set_value_len= strlen(set_value);
4756
4757 if (rc == MEMCACHED_SUCCESS)
4758 {
4759 if (x > 0)
4760 {
4761 size_t get_value_len;
4762 char *get_value;
4763 uint32_t get_value_flags;
4764
4765 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
4766 &get_value_flags, &rc);
4767 if (rc != MEMCACHED_SUCCESS)
4768 {
4769 die_message(mc, rc, "memcached_get", x);
4770 }
4771 else
4772 {
4773
4774 if (x != 0 &&
4775 (get_value_len != set_value_len
4776 || 0!=strncmp(get_value, set_value, get_value_len)))
4777 {
4778 fprintf(stderr, "Values don't match?\n");
4779 rc= MEMCACHED_FAILURE;
4780 }
4781 free(get_value);
4782 }
4783 }
4784
4785 rc= memcached_set(mc,
4786 set_key, set_key_len,
4787 set_value, set_value_len,
4788 0, /* time */
4789 0 /* flags */
4790 );
4791 if (rc != MEMCACHED_SUCCESS)
4792 {
4793 die_message(mc, rc, "memcached_set", x);
4794 }
4795 }
4796
4797 memcached_quit(mc);
4798 memcached_free(mc);
4799
4800 if (rc != MEMCACHED_SUCCESS)
4801 {
4802 break;
4803 }
4804 }
4805
4806 return TEST_SUCCESS;
4807 }
4808
4809 test_return_t kill_HUP_TEST(memcached_st *original_memc)
4810 {
4811 memcached_st *memc= create_single_instance_memcached(original_memc, 0);
4812 test_true(memc);
4813
4814 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
4815
4816 pid_t pid;
4817 test_true((pid= libmemcached_util_getpid(memcached_server_name(instance),
4818 memcached_server_port(instance), NULL)) > -1);
4819
4820
4821 test_compare(MEMCACHED_SUCCESS,
4822 memcached_set(memc,
4823 test_literal_param(__func__), // Keys
4824 test_literal_param(__func__), // Values
4825 0, 0));
4826 test_true_got(kill(pid, SIGHUP) == 0, strerror(errno));
4827
4828 test_compare(MEMCACHED_CONNECTION_FAILURE,
4829 memcached_set(memc,
4830 test_literal_param(__func__), // Keys
4831 test_literal_param(__func__), // Values
4832 0, 0));
4833
4834 memcached_free(memc);
4835
4836 return TEST_SUCCESS;
4837 }