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