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