1 #include "config.h"
2 #include "iotests.h"
3 #include "internal.h"
4
5 class SnappyUnitTest : public MockUnitTest
6 {
7 protected:
setCompression(std::string mode)8 void setCompression(std::string mode)
9 {
10 MockEnvironment::getInstance()->setCompression(mode);
11 }
12
isCompressed(std::string & key)13 bool isCompressed(std::string &key)
14 {
15 const Json::Value info = MockEnvironment::getInstance()->getKeyInfo(key);
16 for (Json::Value::const_iterator ii = info.begin(); ii != info.end(); ii++) {
17 const Json::Value &node = *ii;
18 if (node.isNull()) {
19 continue;
20 }
21 if (node["Conf"]["Type"] == "master") {
22 return node["Cache"]["Snappy"].asBool();
23 }
24 }
25 return false;
26 }
27 };
28
29 struct SnappyCookie {
30 lcb_error_t rc;
31 bool called;
32 std::string value;
33
resetSnappyCookie34 void reset()
35 {
36 rc = LCB_SUCCESS;
37 called = false;
38 }
SnappyCookieSnappyCookie39 SnappyCookie() : rc(LCB_SUCCESS), called(false) {}
40
~SnappyCookieSnappyCookie41 ~SnappyCookie() {}
42 };
43
44 extern "C" {
storecb(lcb_t,int,const lcb_RESPBASE * rb)45 static void storecb(lcb_t, int, const lcb_RESPBASE *rb)
46 {
47 SnappyCookie *cookie = reinterpret_cast< SnappyCookie * >(rb->cookie);
48 cookie->called = true;
49 cookie->rc = rb->rc;
50 }
getcb(lcb_t,int,const lcb_RESPBASE * rb)51 static void getcb(lcb_t, int, const lcb_RESPBASE *rb)
52 {
53 SnappyCookie *cookie = reinterpret_cast< SnappyCookie * >(rb->cookie);
54 cookie->called = true;
55 cookie->rc = rb->rc;
56 const lcb_RESPGET *resp = reinterpret_cast< const lcb_RESPGET * >(rb);
57 cookie->value.assign((char *)resp->value, resp->nvalue);
58 }
59 }
60
TEST_F(SnappyUnitTest,testSpec)61 TEST_F(SnappyUnitTest, testSpec)
62 {
63 SKIP_UNLESS_MOCK();
64 HandleWrap hw;
65 lcb_t instance;
66
67 setCompression("passive");
68 createConnection(hw, instance);
69 lcb_cntl_setu32(instance, LCB_CNTL_COMPRESSION_OPTS, LCB_COMPRESS_INOUT);
70 lcb_install_callback3(instance, LCB_CALLBACK_GET, getcb);
71 lcb_install_callback3(instance, LCB_CALLBACK_STORE, storecb);
72
73 std::string key("hello");
74 std::string value("A big black bug bit a big black bear, made the big black bear bleed blood");
75 std::string compressed("IPA big black bug bit a.\x14");
76
77 SnappyCookie cookie;
78 lcb_CMDSTORE scmd;
79 lcb_CMDGET gcmd;
80
81 scmd = lcb_CMDSTORE();
82 scmd.operation = LCB_UPSERT;
83 LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
84 LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.size());
85 cookie = SnappyCookie();
86 lcb_store3(instance, &cookie, &scmd);
87 lcb_wait(instance);
88 ASSERT_TRUE(cookie.called);
89 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
90 /* now we have negotiated snappy feature */
91 cookie = SnappyCookie();
92 lcb_store3(instance, &cookie, &scmd);
93 lcb_wait(instance);
94 ASSERT_TRUE(cookie.called);
95 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
96
97 cookie = SnappyCookie();
98 gcmd = lcb_CMDGET();
99 LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
100 lcb_get3(instance, &cookie, &gcmd);
101 lcb_wait(instance);
102 ASSERT_TRUE(cookie.called);
103 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
104 ASSERT_STREQ(value.c_str(), cookie.value.c_str());
105 ASSERT_TRUE(isCompressed(key));
106
107 lcb_cntl_setu32(instance, LCB_CNTL_COMPRESSION_OPTS, LCB_COMPRESS_OUT);
108 cookie = SnappyCookie();
109 gcmd = lcb_CMDGET();
110 LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
111 lcb_get3(instance, &cookie, &gcmd);
112 lcb_wait(instance);
113 ASSERT_TRUE(cookie.called);
114 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
115 ASSERT_STREQ(compressed.c_str(), cookie.value.c_str());
116
117 setCompression("off");
118 hw.destroy();
119 createConnection(hw, instance);
120 lcb_cntl_setu32(instance, LCB_CNTL_COMPRESSION_OPTS, LCB_COMPRESS_INOUT);
121 lcb_install_callback3(instance, LCB_CALLBACK_GET, getcb);
122 lcb_install_callback3(instance, LCB_CALLBACK_STORE, storecb);
123
124 cookie = SnappyCookie();
125 gcmd = lcb_CMDGET();
126 LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
127 lcb_get3(instance, &cookie, &gcmd);
128 lcb_wait(instance);
129 ASSERT_TRUE(cookie.called);
130 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
131 ASSERT_STREQ(value.c_str(), cookie.value.c_str());
132
133 cookie = SnappyCookie();
134 lcb_store3(instance, &cookie, &scmd);
135 lcb_wait(instance);
136 ASSERT_TRUE(cookie.called);
137 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
138 ASSERT_FALSE(isCompressed(key));
139 }
140
TEST_F(SnappyUnitTest,testIOV)141 TEST_F(SnappyUnitTest, testIOV)
142 {
143
144 SKIP_UNLESS_MOCK();
145 HandleWrap hw;
146 lcb_t instance;
147
148 setCompression("passive");
149 createConnection(hw, instance);
150 lcb_cntl_setu32(instance, LCB_CNTL_COMPRESSION_OPTS, LCB_COMPRESS_INOUT);
151 lcb_install_callback3(instance, LCB_CALLBACK_GET, getcb);
152 lcb_install_callback3(instance, LCB_CALLBACK_STORE, storecb);
153
154 std::string key("hello");
155 std::string value1("A big black bug bit ");
156 std::string value2("a big black bear, ");
157 std::string value3("made the big black ");
158 std::string value4("bear bleed blood");
159 std::string value = value1 + value2 + value3 + value4;
160 std::string compressed("IPA big black bug bit a.\x14");
161
162 SnappyCookie cookie;
163 lcb_CMDSTORE scmd;
164 lcb_CMDGET gcmd;
165
166 lcb_IOV iov[4];
167 unsigned int niov = 4;
168 iov[0].iov_base = (void *)value1.c_str();
169 iov[0].iov_len = value1.size();
170 iov[1].iov_base = (void *)value2.c_str();
171 iov[1].iov_len = value2.size();
172 iov[2].iov_base = (void *)value3.c_str();
173 iov[2].iov_len = value3.size();
174 iov[3].iov_base = (void *)value4.c_str();
175 iov[3].iov_len = value4.size();
176
177 scmd = lcb_CMDSTORE();
178 scmd.operation = LCB_UPSERT;
179 LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
180 LCB_CMD_SET_VALUEIOV(&scmd, iov, niov);
181 cookie = SnappyCookie();
182 lcb_store3(instance, &cookie, &scmd);
183 lcb_wait(instance);
184 ASSERT_TRUE(cookie.called);
185 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
186 /* now we have negotiated snappy feature */
187 cookie = SnappyCookie();
188 lcb_store3(instance, &cookie, &scmd);
189 lcb_wait(instance);
190 ASSERT_TRUE(cookie.called);
191 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
192
193 cookie = SnappyCookie();
194 gcmd = lcb_CMDGET();
195 LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
196 lcb_get3(instance, &cookie, &gcmd);
197 lcb_wait(instance);
198 ASSERT_TRUE(cookie.called);
199 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
200 ASSERT_STREQ(value.c_str(), cookie.value.c_str());
201 ASSERT_TRUE(isCompressed(key));
202
203 lcb_cntl_setu32(instance, LCB_CNTL_COMPRESSION_OPTS, LCB_COMPRESS_OUT);
204 cookie = SnappyCookie();
205 gcmd = lcb_CMDGET();
206 LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
207 lcb_get3(instance, &cookie, &gcmd);
208 lcb_wait(instance);
209 ASSERT_TRUE(cookie.called);
210 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
211 ASSERT_STREQ(compressed.c_str(), cookie.value.c_str());
212 }
213
214
TEST_F(SnappyUnitTest,testSettings)215 TEST_F(SnappyUnitTest, testSettings)
216 {
217
218 SKIP_UNLESS_MOCK();
219 HandleWrap hw;
220 lcb_t instance;
221
222 setCompression("passive");
223 createConnection(hw, instance);
224 lcb_cntl_string(instance, "compression", "deflate_only");
225 lcb_install_callback3(instance, LCB_CALLBACK_GET, getcb);
226 lcb_install_callback3(instance, LCB_CALLBACK_STORE, storecb);
227
228 std::string key("hello");
229 std::string value("A big black bug bit a big black bear, made the big black bear bleed blood");
230 std::string compressed("IPA big black bug bit a.\x14");
231
232 SnappyCookie cookie;
233 lcb_CMDSTORE scmd;
234 lcb_CMDGET gcmd;
235
236 scmd = lcb_CMDSTORE();
237 scmd.operation = LCB_UPSERT;
238 LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
239 LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.size());
240 cookie = SnappyCookie();
241 lcb_store3(instance, &cookie, &scmd);
242 lcb_wait(instance);
243 ASSERT_TRUE(cookie.called);
244 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
245 /* now we have negotiated snappy feature */
246 cookie = SnappyCookie();
247 lcb_store3(instance, &cookie, &scmd);
248 lcb_wait(instance);
249 ASSERT_TRUE(cookie.called);
250 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
251
252 value = "A big black bug";
253 compressed = "A big black bug";
254 scmd = lcb_CMDSTORE();
255 scmd.operation = LCB_UPSERT;
256 LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
257 LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.size());
258 cookie = SnappyCookie();
259 lcb_store3(instance, &cookie, &scmd);
260 lcb_wait(instance);
261 ASSERT_TRUE(cookie.called);
262 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
263
264 cookie = SnappyCookie();
265 gcmd = lcb_CMDGET();
266 LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
267 lcb_get3(instance, &cookie, &gcmd);
268 lcb_wait(instance);
269 ASSERT_TRUE(cookie.called);
270 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
271 ASSERT_STREQ(compressed.c_str(), cookie.value.c_str());
272
273 lcb_cntl_string(instance, "compression_min_size", "1024"); /* greater than size of the value */
274 value = "A big black bug bit a big black bear, made the big black bear bleed blood";
275 compressed = "A big black bug bit a big black bear, made the big black bear bleed blood";
276 scmd = lcb_CMDSTORE();
277 scmd.operation = LCB_UPSERT;
278 LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
279 LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.size());
280 cookie = SnappyCookie();
281 lcb_store3(instance, &cookie, &scmd);
282 lcb_wait(instance);
283 ASSERT_TRUE(cookie.called);
284 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
285
286 cookie = SnappyCookie();
287 gcmd = lcb_CMDGET();
288 LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
289 lcb_get3(instance, &cookie, &gcmd);
290 lcb_wait(instance);
291 ASSERT_TRUE(cookie.called);
292 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
293 ASSERT_STREQ(compressed.c_str(), cookie.value.c_str());
294
295 lcb_cntl_string(instance, "compression_min_size", "40"); /* less than size of the value */
296 lcb_cntl_string(instance, "compression_min_ratio", "0.1"); /* expect to reduce size in 10 times */
297 value = "A big black bug bit a big black bear, made the big black bear bleed blood";
298 compressed = "A big black bug bit a big black bear, made the big black bear bleed blood";
299 scmd = lcb_CMDSTORE();
300 scmd.operation = LCB_UPSERT;
301 LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
302 LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.size());
303 cookie = SnappyCookie();
304 lcb_store3(instance, &cookie, &scmd);
305 lcb_wait(instance);
306 ASSERT_TRUE(cookie.called);
307 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
308
309 cookie = SnappyCookie();
310 gcmd = lcb_CMDGET();
311 LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
312 lcb_get3(instance, &cookie, &gcmd);
313 lcb_wait(instance);
314 ASSERT_TRUE(cookie.called);
315 ASSERT_EQ(LCB_SUCCESS, cookie.rc);
316 ASSERT_STREQ(compressed.c_str(), cookie.value.c_str());
317 }
318