1 /*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2  *
3  *  Libmemcached Client and Server
4  *
5  *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
6  *  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 #include <libmemcached-1.0/memcached.h>
42 #include <libmemcachedutil-1.0/util.h>
43 
44 #include "tests/libmemcached-1.0/encoding_key.h"
45 
46 using namespace libtest;
47 
memcached_set_encoding_key_TEST(memcached_st * memc)48 test_return_t memcached_set_encoding_key_TEST(memcached_st* memc)
49 {
50   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
51 
52   return TEST_SUCCESS;
53 }
54 
memcached_set_encoding_key_set_get_TEST(memcached_st * memc)55 test_return_t memcached_set_encoding_key_set_get_TEST(memcached_st* memc)
56 {
57   memcached_st *memc_no_crypt= memcached_clone(NULL, memc);
58   test_true(memc_no_crypt);
59   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
60 
61   test_compare(MEMCACHED_SUCCESS, memcached_set(memc,
62                                                 test_literal_param(__func__), // Key
63                                                 test_literal_param(__func__), // Value
64                                                 time_t(0),
65                                                 uint32_t(0)));
66 
67   {
68     memcached_return_t rc;
69     size_t value_length;
70     char *value;
71     test_true((value= memcached_get(memc,
72                                     test_literal_param(__func__), // Key
73                                     &value_length, NULL, &rc)));
74     test_compare(MEMCACHED_SUCCESS, rc);
75     test_compare(test_literal_param_size(__func__), value_length);
76     test_memcmp(__func__, value, value_length);
77 
78     size_t raw_value_length;
79     char *raw_value;
80     test_true((raw_value= memcached_get(memc_no_crypt,
81                                         test_literal_param(__func__), // Key
82                                         &raw_value_length, NULL, &rc)));
83     test_compare(MEMCACHED_SUCCESS, rc);
84     test_ne_compare(value_length, raw_value_length);
85     test_ne_compare(0, memcmp(value, raw_value, raw_value_length));
86 
87     free(value);
88     free(raw_value);
89   }
90 
91   memcached_free(memc_no_crypt);
92 
93   return TEST_SUCCESS;
94 }
95 
memcached_set_encoding_key_add_get_TEST(memcached_st * memc)96 test_return_t memcached_set_encoding_key_add_get_TEST(memcached_st* memc)
97 {
98   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
99 
100   test_compare(MEMCACHED_SUCCESS, memcached_add(memc,
101                                                      test_literal_param(__func__), // Key
102                                                      test_literal_param(__func__), // Value
103                                                      time_t(0),
104                                                      uint32_t(0)));
105 
106   {
107     memcached_return_t rc;
108     size_t value_length;
109     char *value;
110     test_true((value= memcached_get(memc,
111                                     test_literal_param(__func__), // Key
112                                     &value_length, NULL, &rc)));
113     test_compare(MEMCACHED_SUCCESS, rc);
114     test_compare(test_literal_param_size(__func__), value_length);
115     test_memcmp(__func__, value, value_length);
116     free(value);
117   }
118 
119   return TEST_SUCCESS;
120 }
121 
memcached_set_encoding_key_replace_get_TEST(memcached_st * memc)122 test_return_t memcached_set_encoding_key_replace_get_TEST(memcached_st* memc)
123 {
124   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
125 
126   // First we add the key
127   {
128     test_compare(MEMCACHED_SUCCESS, memcached_add(memc,
129                                                   test_literal_param(__func__), // Key
130                                                   test_literal_param(__func__), // Value
131                                                   time_t(0),
132                                                   uint32_t(0)));
133 
134     memcached_return_t rc;
135     size_t value_length;
136     char *value;
137     test_true((value= memcached_get(memc,
138                                     test_literal_param(__func__), // Key
139                                     &value_length, NULL, &rc)));
140     test_compare(MEMCACHED_SUCCESS, rc);
141     test_compare(test_literal_param_size(__func__), value_length);
142     test_memcmp(__func__, value, value_length);
143     free(value);
144   }
145 
146   // Then we replace the key
147   {
148     libtest::vchar_t new_value;
149     vchar::make(new_value);
150 
151     test_compare(MEMCACHED_SUCCESS, memcached_replace(memc,
152                                                       test_literal_param(__func__), // Key
153                                                       vchar_param(new_value), // Value
154                                                       time_t(0),
155                                                       uint32_t(0)));
156 
157     memcached_return_t rc;
158     size_t value_length;
159     char *value;
160     test_true((value= memcached_get(memc,
161                                     test_literal_param(__func__), // Key
162                                     &value_length, NULL, &rc)));
163     test_compare(MEMCACHED_SUCCESS, rc);
164     test_compare(new_value.size(), value_length);
165     test_compare(0, vchar::compare(new_value, value, value_length));
166     free(value);
167   }
168 
169   return TEST_SUCCESS;
170 }
171 
memcached_set_encoding_key_increment_TEST(memcached_st * memc)172 test_return_t memcached_set_encoding_key_increment_TEST(memcached_st* memc)
173 {
174   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
175 
176   test_compare(MEMCACHED_NOT_SUPPORTED, memcached_increment(memc,
177                                                             test_literal_param(__func__), // Key
178                                                             uint32_t(0),
179                                                             NULL));
180 
181   return TEST_SUCCESS;
182 }
183 
memcached_set_encoding_key_decrement_TEST(memcached_st * memc)184 test_return_t memcached_set_encoding_key_decrement_TEST(memcached_st* memc)
185 {
186   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
187 
188   test_compare(MEMCACHED_NOT_SUPPORTED, memcached_decrement(memc,
189                                                             test_literal_param(__func__), // Key
190                                                             uint32_t(0),
191                                                             NULL));
192 
193   return TEST_SUCCESS;
194 }
195 
memcached_set_encoding_key_increment_with_initial_TEST(memcached_st * memc)196 test_return_t memcached_set_encoding_key_increment_with_initial_TEST(memcached_st* memc)
197 {
198   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
199 
200   test_compare(MEMCACHED_NOT_SUPPORTED, memcached_increment_with_initial(memc,
201                                                                          test_literal_param(__func__), // Key
202                                                                          uint32_t(0),
203                                                                          uint32_t(0),
204                                                                          time_t(0),
205                                                                          NULL));
206 
207   return TEST_SUCCESS;
208 }
209 
memcached_set_encoding_key_decrement_with_initial_TEST(memcached_st * memc)210 test_return_t memcached_set_encoding_key_decrement_with_initial_TEST(memcached_st* memc)
211 {
212   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
213 
214   test_compare(MEMCACHED_NOT_SUPPORTED, memcached_decrement_with_initial(memc,
215                                                                          test_literal_param(__func__), // Key
216                                                                          uint32_t(0),
217                                                                          uint32_t(0),
218                                                                          time_t(0),
219                                                                          NULL));
220 
221   return TEST_SUCCESS;
222 }
223 
memcached_set_encoding_key_append_TEST(memcached_st * memc)224 test_return_t memcached_set_encoding_key_append_TEST(memcached_st* memc)
225 {
226   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
227 
228   test_compare(MEMCACHED_NOT_SUPPORTED, memcached_append(memc,
229                                                          test_literal_param(__func__), // Key
230                                                          test_literal_param(__func__), // Value
231                                                          time_t(0),
232                                                          uint32_t(0)));
233 
234   return TEST_SUCCESS;
235 }
236 
memcached_set_encoding_key_prepend_TEST(memcached_st * memc)237 test_return_t memcached_set_encoding_key_prepend_TEST(memcached_st* memc)
238 {
239   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
240 
241   test_compare(MEMCACHED_NOT_SUPPORTED, memcached_prepend(memc,
242                                                          test_literal_param(__func__), // Key
243                                                          test_literal_param(__func__), // Value
244                                                          time_t(0),
245                                                          uint32_t(0)));
246 
247   return TEST_SUCCESS;
248 }
249 
memcached_set_encoding_key_set_get_clone_TEST(memcached_st * memc)250 test_return_t memcached_set_encoding_key_set_get_clone_TEST(memcached_st* memc)
251 {
252   memcached_st *memc_no_crypt= memcached_clone(NULL, memc);
253   test_true(memc_no_crypt);
254 
255   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
256 
257   memcached_st *memc_crypt= memcached_clone(NULL, memc);
258   test_true(memc_crypt);
259 
260   test_compare(MEMCACHED_SUCCESS, memcached_set(memc,
261                                                      test_literal_param(__func__), // Key
262                                                      test_literal_param(__func__), // Value
263                                                      time_t(0),
264                                                      uint32_t(0)));
265 
266   {
267     memcached_return_t rc;
268     size_t value_length;
269     char *value;
270     test_true((value= memcached_get(memc,
271                                     test_literal_param(__func__), // Key
272                                     &value_length, NULL, &rc)));
273     test_compare(MEMCACHED_SUCCESS, rc);
274     test_compare(test_literal_param_size(__func__), value_length);
275     test_memcmp(__func__, value, value_length);
276 
277     /*
278       Check to make sure that the raw value is not the original.
279     */
280     size_t raw_value_length;
281     char *raw_value;
282     test_true((raw_value= memcached_get(memc_no_crypt,
283                                         test_literal_param(__func__), // Key
284                                         &raw_value_length, NULL, &rc)));
285     test_compare(MEMCACHED_SUCCESS, rc);
286     test_ne_compare(test_literal_param_size(__func__), raw_value_length);
287     test_ne_compare(0, memcmp(__func__, raw_value, raw_value_length));
288 
289     /*
290       Now we will use our clone, and make sure the encrypted values are the same.
291     */
292     size_t second_value_length;
293     char *second_value;
294     test_true((second_value= memcached_get(memc_crypt,
295                                            test_literal_param(__func__), // Key
296                                            &second_value_length, NULL, &rc)));
297     test_compare(MEMCACHED_SUCCESS, rc);
298     test_compare(value_length, second_value_length);
299     test_compare(0, memcmp(value, second_value, second_value_length));
300     test_compare(test_literal_param_size(__func__), second_value_length);
301     test_compare(value_length, second_value_length);
302     test_memcmp(__func__, second_value, second_value_length);
303     test_memcmp(value, second_value, second_value_length);
304 
305     free(value);
306     free(raw_value);
307     free(second_value);
308   }
309 
310   memcached_free(memc_no_crypt);
311   memcached_free(memc_crypt);
312 
313   return TEST_SUCCESS;
314 }
315 
memcached_set_encoding_key_set_grow_key_TEST(memcached_st * memc)316 test_return_t memcached_set_encoding_key_set_grow_key_TEST(memcached_st* memc)
317 {
318   memcached_st *memc_no_crypt= memcached_clone(NULL, memc);
319   test_true(memc_no_crypt);
320   test_compare(MEMCACHED_SUCCESS, memcached_set_encoding_key(memc, test_literal_param(__func__)));
321 
322   size_t payload_size[] = { 100, 1000, 10000, 1000000, 1000000, 0 };
323   libtest::vchar_t payload;
324   for (size_t *ptr= payload_size; *ptr; ptr++)
325   {
326     payload.reserve(*ptr);
327     for (size_t x= payload.size(); x < *ptr; x++)
328     {
329       payload.push_back(rand());
330     }
331 
332     {
333       memcached_return_t rc= memcached_set(memc,
334                                            test_literal_param(__func__), // Key
335                                            &payload[0], payload.size(), // Value
336                                            time_t(0),
337                                            uint32_t(0));
338 
339       // If we run out of space on the server, we just end the test early.
340       if (rc == MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE)
341       {
342         break;
343       }
344       test_compare(MEMCACHED_SUCCESS, rc);
345     }
346 
347     {
348       memcached_return_t rc;
349       size_t value_length;
350       char *value;
351       test_true((value= memcached_get(memc,
352                                       test_literal_param(__func__), // Key
353                                       &value_length, NULL, &rc)));
354       test_compare(MEMCACHED_SUCCESS, rc);
355       test_compare(payload.size(), value_length);
356       test_memcmp(&payload[0], value, value_length);
357 
358       size_t raw_value_length;
359       char *raw_value;
360       test_true((raw_value= memcached_get(memc_no_crypt,
361                                           test_literal_param(__func__), // Key
362                                           &raw_value_length, NULL, &rc)));
363       test_compare(MEMCACHED_SUCCESS, rc);
364       test_ne_compare(payload.size(), raw_value_length);
365       test_ne_compare(0, memcmp(&payload[0], raw_value, raw_value_length));
366 
367       free(value);
368       free(raw_value);
369     }
370   }
371 
372   memcached_free(memc_no_crypt);
373 
374   return TEST_SUCCESS;
375 }
376