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