]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -* |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include <climits> | |
5 | ||
6 | #include "include/rados/librados.h" | |
7 | #include "include/rados/librados.hpp" | |
8 | #include "include/encoding.h" | |
c07f9fc5 | 9 | #include "include/err.h" |
7c673cae FG |
10 | #include "include/scope_guard.h" |
11 | #include "test/librados/test.h" | |
12 | #include "test/librados/TestCase.h" | |
13 | ||
14 | #include <errno.h> | |
15 | #include "gtest/gtest.h" | |
16 | ||
17 | using namespace librados; | |
18 | using std::string; | |
19 | ||
20 | typedef RadosTest LibRadosIo; | |
21 | typedef RadosTestEC LibRadosIoEC; | |
22 | typedef RadosTestPP LibRadosIoPP; | |
23 | typedef RadosTestECPP LibRadosIoECPP; | |
24 | ||
25 | TEST_F(LibRadosIo, SimpleWrite) { | |
26 | char buf[128]; | |
27 | memset(buf, 0xcc, sizeof(buf)); | |
28 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
29 | rados_ioctx_set_namespace(ioctx, "nspace"); | |
30 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
31 | } | |
32 | ||
33 | TEST_F(LibRadosIo, TooBig) { | |
34 | char buf[1]; | |
35 | ASSERT_EQ(-E2BIG, rados_write(ioctx, "A", buf, UINT_MAX, 0)); | |
36 | ASSERT_EQ(-E2BIG, rados_append(ioctx, "A", buf, UINT_MAX)); | |
37 | ASSERT_EQ(-E2BIG, rados_write_full(ioctx, "A", buf, UINT_MAX)); | |
38 | ASSERT_EQ(-E2BIG, rados_writesame(ioctx, "A", buf, sizeof(buf), UINT_MAX, 0)); | |
39 | IoCtx ioctx; | |
40 | bufferlist bl; | |
41 | ASSERT_EQ(-E2BIG, ioctx.write("foo", bl, UINT_MAX, 0)); | |
42 | ASSERT_EQ(-E2BIG, ioctx.append("foo", bl, UINT_MAX)); | |
43 | // ioctx.write_full no way to overflow bl.length() | |
44 | ASSERT_EQ(-E2BIG, ioctx.writesame("foo", bl, UINT_MAX, 0)); | |
45 | } | |
46 | ||
47 | TEST_F(LibRadosIo, ReadTimeout) { | |
48 | char buf[128]; | |
49 | memset(buf, 'a', sizeof(buf)); | |
50 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
51 | ||
52 | { | |
53 | // set up a second client | |
54 | rados_t cluster; | |
55 | rados_ioctx_t ioctx; | |
56 | ASSERT_EQ(0, rados_create(&cluster, "admin")); | |
57 | ASSERT_EQ(0, rados_conf_read_file(cluster, NULL)); | |
58 | ASSERT_EQ(0, rados_conf_parse_env(cluster, NULL)); | |
59 | ASSERT_EQ(0, rados_conf_set(cluster, "rados_osd_op_timeout", "0.00001")); // use any small value that will result in a timeout | |
60 | ASSERT_EQ(0, rados_connect(cluster)); | |
61 | ASSERT_EQ(0, rados_ioctx_create(cluster, pool_name.c_str(), &ioctx)); | |
62 | rados_ioctx_set_namespace(ioctx, nspace.c_str()); | |
63 | ||
64 | // then we show that the buffer is changed after rados_read returned | |
65 | // with a timeout | |
66 | for (int i=0; i<5; i++) { | |
67 | char buf2[sizeof(buf)]; | |
68 | memset(buf2, 0, sizeof(buf2)); | |
69 | int err = rados_read(ioctx, "foo", buf2, sizeof(buf2), 0); | |
70 | if (err == -110) { | |
71 | int startIndex = 0; | |
72 | // find the index until which librados already read the object before the timeout occurred | |
73 | for (unsigned b=0; b<sizeof(buf); b++) { | |
74 | if (buf2[b] != buf[b]) { | |
75 | startIndex = b; | |
76 | break; | |
77 | } | |
78 | } | |
79 | ||
80 | // wait some time to give librados a change to do something | |
81 | sleep(1); | |
82 | ||
83 | // then check if the buffer was changed after the call | |
84 | if (buf2[startIndex] == 'a') { | |
85 | printf("byte at index %d was changed after the timeout to %d\n", | |
86 | startIndex, (int)buf[startIndex]); | |
87 | ASSERT_TRUE(0); | |
88 | break; | |
89 | } | |
90 | } else { | |
91 | printf("no timeout :/\n"); | |
92 | } | |
93 | } | |
94 | rados_ioctx_destroy(ioctx); | |
95 | rados_shutdown(cluster); | |
96 | } | |
97 | } | |
98 | ||
99 | TEST_F(LibRadosIoPP, SimpleWritePP) { | |
100 | char buf[128]; | |
101 | memset(buf, 0xcc, sizeof(buf)); | |
102 | bufferlist bl; | |
103 | bl.append(buf, sizeof(buf)); | |
104 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
105 | ioctx.set_namespace("nspace"); | |
106 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
107 | } | |
108 | ||
109 | TEST_F(LibRadosIoPP, ReadOpPP) { | |
110 | char buf[128]; | |
111 | memset(buf, 0xcc, sizeof(buf)); | |
112 | bufferlist bl; | |
113 | bl.append(buf, sizeof(buf)); | |
114 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
115 | ||
116 | { | |
117 | bufferlist op_bl; | |
118 | ObjectReadOperation op; | |
119 | op.read(0, sizeof(buf), NULL, NULL); | |
120 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
121 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
122 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
123 | } | |
124 | ||
125 | { | |
126 | bufferlist op_bl; | |
127 | ObjectReadOperation op; | |
128 | op.read(0, 0, NULL, NULL); //len=0 mean read the whole object data. | |
129 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
130 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
131 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
132 | } | |
133 | ||
134 | { | |
135 | bufferlist read_bl, op_bl; | |
136 | ObjectReadOperation op; | |
137 | op.read(0, sizeof(buf), &read_bl, NULL); | |
138 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
139 | ASSERT_EQ(sizeof(buf), read_bl.length()); | |
140 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
141 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
142 | ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf))); | |
143 | } | |
144 | ||
145 | { | |
146 | bufferlist op_bl; | |
147 | int rval = 1000; | |
148 | ObjectReadOperation op; | |
149 | op.read(0, sizeof(buf), NULL, &rval); | |
150 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
151 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
152 | ASSERT_EQ(0, rval); | |
153 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
154 | } | |
155 | ||
156 | { | |
157 | bufferlist read_bl, op_bl; | |
158 | int rval = 1000; | |
159 | ObjectReadOperation op; | |
160 | op.read(0, sizeof(buf), &read_bl, &rval); | |
161 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
162 | ASSERT_EQ(sizeof(buf), read_bl.length()); | |
163 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
164 | ASSERT_EQ(0, rval); | |
165 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
166 | ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf))); | |
167 | } | |
168 | ||
169 | { | |
170 | bufferlist read_bl1, read_bl2, op_bl; | |
171 | int rval1 = 1000, rval2 = 1002; | |
172 | ObjectReadOperation op; | |
173 | op.read(0, sizeof(buf), &read_bl1, &rval1); | |
174 | op.read(0, sizeof(buf), &read_bl2, &rval2); | |
175 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
176 | ASSERT_EQ(sizeof(buf), read_bl1.length()); | |
177 | ASSERT_EQ(sizeof(buf), read_bl2.length()); | |
178 | ASSERT_EQ(sizeof(buf) * 2, op_bl.length()); | |
179 | ASSERT_EQ(0, rval1); | |
180 | ASSERT_EQ(0, rval2); | |
181 | ASSERT_EQ(0, memcmp(read_bl1.c_str(), buf, sizeof(buf))); | |
182 | ASSERT_EQ(0, memcmp(read_bl2.c_str(), buf, sizeof(buf))); | |
183 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
184 | ASSERT_EQ(0, memcmp(op_bl.c_str() + sizeof(buf), buf, sizeof(buf))); | |
185 | } | |
186 | ||
187 | { | |
188 | bufferlist op_bl; | |
189 | ObjectReadOperation op; | |
190 | op.read(0, sizeof(buf), NULL, NULL); | |
191 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
192 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
193 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
194 | } | |
195 | ||
196 | { | |
197 | bufferlist read_bl; | |
198 | ObjectReadOperation op; | |
199 | op.read(0, sizeof(buf), &read_bl, NULL); | |
200 | ASSERT_EQ(0, ioctx.operate("foo", &op, NULL)); | |
201 | ASSERT_EQ(sizeof(buf), read_bl.length()); | |
202 | ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf))); | |
203 | } | |
204 | ||
205 | { | |
206 | int rval = 1000; | |
207 | ObjectReadOperation op; | |
208 | op.read(0, sizeof(buf), NULL, &rval); | |
209 | ASSERT_EQ(0, ioctx.operate("foo", &op, NULL)); | |
210 | ASSERT_EQ(0, rval); | |
211 | } | |
212 | ||
213 | { | |
214 | bufferlist read_bl; | |
215 | int rval = 1000; | |
216 | ObjectReadOperation op; | |
217 | op.read(0, sizeof(buf), &read_bl, &rval); | |
218 | ASSERT_EQ(0, ioctx.operate("foo", &op, NULL)); | |
219 | ASSERT_EQ(sizeof(buf), read_bl.length()); | |
220 | ASSERT_EQ(0, rval); | |
221 | ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf))); | |
222 | } | |
223 | ||
224 | { | |
225 | bufferlist read_bl1, read_bl2; | |
226 | int rval1 = 1000, rval2 = 1002; | |
227 | ObjectReadOperation op; | |
228 | op.read(0, sizeof(buf), &read_bl1, &rval1); | |
229 | op.read(0, sizeof(buf), &read_bl2, &rval2); | |
230 | ASSERT_EQ(0, ioctx.operate("foo", &op, NULL)); | |
231 | ASSERT_EQ(sizeof(buf), read_bl1.length()); | |
232 | ASSERT_EQ(sizeof(buf), read_bl2.length()); | |
233 | ASSERT_EQ(0, rval1); | |
234 | ASSERT_EQ(0, rval2); | |
235 | ASSERT_EQ(0, memcmp(read_bl1.c_str(), buf, sizeof(buf))); | |
236 | ASSERT_EQ(0, memcmp(read_bl2.c_str(), buf, sizeof(buf))); | |
237 | } | |
238 | } | |
239 | ||
240 | TEST_F(LibRadosIoPP, SparseReadOpPP) { | |
241 | char buf[128]; | |
242 | memset(buf, 0xcc, sizeof(buf)); | |
243 | bufferlist bl; | |
244 | bl.append(buf, sizeof(buf)); | |
245 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
246 | ||
247 | { | |
248 | std::map<uint64_t, uint64_t> extents; | |
249 | bufferlist read_bl; | |
250 | int rval = -1; | |
251 | ObjectReadOperation op; | |
252 | op.sparse_read(0, sizeof(buf), &extents, &read_bl, &rval); | |
253 | ASSERT_EQ(0, ioctx.operate("foo", &op, nullptr)); | |
254 | ASSERT_EQ(0, rval); | |
255 | assert_eq_sparse(bl, extents, read_bl); | |
256 | } | |
257 | } | |
258 | ||
259 | TEST_F(LibRadosIo, RoundTrip) { | |
260 | char buf[128]; | |
261 | char buf2[128]; | |
262 | memset(buf, 0xcc, sizeof(buf)); | |
263 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
264 | memset(buf2, 0, sizeof(buf2)); | |
265 | ASSERT_EQ((int)sizeof(buf2), rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
266 | ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf))); | |
267 | ||
268 | uint64_t off = 19; | |
269 | memset(buf, 0xcc, sizeof(buf)); | |
270 | ASSERT_EQ(0, rados_write(ioctx, "bar", buf, sizeof(buf), off)); | |
271 | memset(buf2, 0, sizeof(buf2)); | |
272 | ASSERT_EQ((int)sizeof(buf2), rados_read(ioctx, "bar", buf2, sizeof(buf2), off)); | |
273 | ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf))); | |
274 | } | |
275 | ||
276 | TEST_F(LibRadosIoPP, RoundTripPP) { | |
277 | char buf[128]; | |
278 | Rados cluster; | |
279 | memset(buf, 0xcc, sizeof(buf)); | |
280 | bufferlist bl; | |
281 | bl.append(buf, sizeof(buf)); | |
282 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
283 | bufferlist cl; | |
284 | ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", cl, sizeof(buf), 0)); | |
285 | ASSERT_EQ(0, memcmp(buf, cl.c_str(), sizeof(buf))); | |
286 | } | |
287 | ||
288 | TEST_F(LibRadosIoPP, RoundTripPP2) | |
289 | { | |
290 | bufferlist bl; | |
291 | bl.append("ceph"); | |
292 | ObjectWriteOperation write; | |
293 | write.write(0, bl); | |
294 | write.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED); | |
295 | ASSERT_EQ(0, ioctx.operate("foo", &write)); | |
296 | ||
297 | ObjectReadOperation read; | |
298 | read.read(0, bl.length(), NULL, NULL); | |
299 | read.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE|LIBRADOS_OP_FLAG_FADVISE_RANDOM); | |
300 | ASSERT_EQ(0, ioctx.operate("foo", &read, &bl)); | |
301 | ASSERT_EQ(0, memcmp(bl.c_str(), "ceph", 4)); | |
302 | } | |
303 | ||
304 | TEST_F(LibRadosIo, Checksum) { | |
305 | char buf[128]; | |
306 | memset(buf, 0xcc, sizeof(buf)); | |
307 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
308 | ||
309 | uint32_t expected_crc = ceph_crc32c(-1, reinterpret_cast<const uint8_t*>(buf), | |
310 | sizeof(buf)); | |
311 | uint32_t init_value = -1; | |
312 | uint32_t crc[2]; | |
313 | ASSERT_EQ(0, rados_checksum(ioctx, "foo", LIBRADOS_CHECKSUM_TYPE_CRC32C, | |
314 | reinterpret_cast<char*>(&init_value), | |
315 | sizeof(init_value), sizeof(buf), 0, 0, | |
316 | reinterpret_cast<char*>(&crc), sizeof(crc))); | |
317 | ASSERT_EQ(1U, crc[0]); | |
318 | ASSERT_EQ(expected_crc, crc[1]); | |
319 | } | |
320 | ||
321 | TEST_F(LibRadosIoPP, Checksum) { | |
322 | char buf[128]; | |
323 | Rados cluster; | |
324 | memset(buf, 0xcc, sizeof(buf)); | |
325 | bufferlist bl; | |
326 | bl.append(buf, sizeof(buf)); | |
327 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
328 | bufferlist init_value_bl; | |
329 | ::encode(static_cast<uint32_t>(-1), init_value_bl); | |
330 | bufferlist csum_bl; | |
331 | ASSERT_EQ(0, ioctx.checksum("foo", LIBRADOS_CHECKSUM_TYPE_CRC32C, | |
332 | init_value_bl, sizeof(buf), 0, 0, &csum_bl)); | |
333 | auto csum_bl_it = csum_bl.begin(); | |
334 | uint32_t csum_count; | |
335 | ::decode(csum_count, csum_bl_it); | |
336 | ASSERT_EQ(1U, csum_count); | |
337 | uint32_t csum; | |
338 | ::decode(csum, csum_bl_it); | |
339 | ASSERT_EQ(bl.crc32c(-1), csum); | |
340 | } | |
341 | ||
342 | TEST_F(LibRadosIo, OverlappingWriteRoundTrip) { | |
343 | char buf[128]; | |
344 | char buf2[64]; | |
345 | char buf3[128]; | |
346 | memset(buf, 0xcc, sizeof(buf)); | |
347 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
348 | memset(buf2, 0xdd, sizeof(buf2)); | |
349 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
350 | memset(buf3, 0xdd, sizeof(buf3)); | |
351 | ASSERT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0)); | |
352 | ASSERT_EQ(0, memcmp(buf3, buf2, sizeof(buf2))); | |
353 | ASSERT_EQ(0, memcmp(buf3 + sizeof(buf2), buf, sizeof(buf) - sizeof(buf2))); | |
354 | } | |
355 | ||
356 | TEST_F(LibRadosIoPP, OverlappingWriteRoundTripPP) { | |
357 | char buf[128]; | |
358 | char buf2[64]; | |
359 | memset(buf, 0xcc, sizeof(buf)); | |
360 | bufferlist bl1; | |
361 | bl1.append(buf, sizeof(buf)); | |
362 | ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); | |
363 | memset(buf2, 0xdd, sizeof(buf2)); | |
364 | bufferlist bl2; | |
365 | bl2.append(buf2, sizeof(buf2)); | |
366 | ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), 0)); | |
367 | bufferlist bl3; | |
368 | ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), 0)); | |
369 | ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2))); | |
370 | ASSERT_EQ(0, memcmp(bl3.c_str() + sizeof(buf2), buf, sizeof(buf) - sizeof(buf2))); | |
371 | } | |
372 | ||
373 | TEST_F(LibRadosIo, WriteFullRoundTrip) { | |
374 | char buf[128]; | |
375 | char buf2[64]; | |
376 | char buf3[128]; | |
377 | memset(buf, 0xcc, sizeof(buf)); | |
378 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
379 | memset(buf2, 0xdd, sizeof(buf2)); | |
380 | ASSERT_EQ(0, rados_write_full(ioctx, "foo", buf2, sizeof(buf2))); | |
381 | memset(buf3, 0x00, sizeof(buf3)); | |
382 | ASSERT_EQ((int)sizeof(buf2), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0)); | |
383 | ASSERT_EQ(0, memcmp(buf2, buf3, sizeof(buf2))); | |
384 | } | |
385 | ||
386 | TEST_F(LibRadosIoPP, WriteFullRoundTripPP) { | |
387 | char buf[128]; | |
388 | char buf2[64]; | |
389 | memset(buf, 0xcc, sizeof(buf)); | |
390 | bufferlist bl1; | |
391 | bl1.append(buf, sizeof(buf)); | |
392 | ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); | |
393 | memset(buf2, 0xdd, sizeof(buf2)); | |
394 | bufferlist bl2; | |
395 | bl2.append(buf2, sizeof(buf2)); | |
396 | ASSERT_EQ(0, ioctx.write_full("foo", bl2)); | |
397 | bufferlist bl3; | |
398 | ASSERT_EQ((int)sizeof(buf2), ioctx.read("foo", bl3, sizeof(buf), 0)); | |
399 | ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2))); | |
400 | } | |
401 | ||
402 | TEST_F(LibRadosIoPP, WriteFullRoundTripPP2) | |
403 | { | |
404 | bufferlist bl; | |
405 | bl.append("ceph"); | |
406 | ObjectWriteOperation write; | |
407 | write.write_full(bl); | |
408 | write.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE); | |
409 | ASSERT_EQ(0, ioctx.operate("foo", &write)); | |
410 | ||
411 | ObjectReadOperation read; | |
412 | read.read(0, bl.length(), NULL, NULL); | |
413 | read.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED|LIBRADOS_OP_FLAG_FADVISE_RANDOM); | |
414 | ASSERT_EQ(0, ioctx.operate("foo", &read, &bl)); | |
415 | ASSERT_EQ(0, memcmp(bl.c_str(), "ceph", 4)); | |
416 | } | |
417 | ||
418 | TEST_F(LibRadosIo, AppendRoundTrip) { | |
419 | char buf[64]; | |
420 | char buf2[64]; | |
421 | char buf3[sizeof(buf) + sizeof(buf2)]; | |
422 | memset(buf, 0xde, sizeof(buf)); | |
423 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
424 | memset(buf2, 0xad, sizeof(buf2)); | |
425 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf2, sizeof(buf2))); | |
426 | memset(buf3, 0, sizeof(buf3)); | |
427 | ASSERT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0)); | |
428 | ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf))); | |
429 | ASSERT_EQ(0, memcmp(buf3 + sizeof(buf), buf2, sizeof(buf2))); | |
430 | } | |
431 | ||
432 | TEST_F(LibRadosIoPP, AppendRoundTripPP) { | |
433 | char buf[64]; | |
434 | char buf2[64]; | |
435 | memset(buf, 0xde, sizeof(buf)); | |
436 | bufferlist bl1; | |
437 | bl1.append(buf, sizeof(buf)); | |
438 | ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf))); | |
439 | memset(buf2, 0xad, sizeof(buf2)); | |
440 | bufferlist bl2; | |
441 | bl2.append(buf2, sizeof(buf2)); | |
442 | ASSERT_EQ(0, ioctx.append("foo", bl2, sizeof(buf2))); | |
443 | bufferlist bl3; | |
444 | ASSERT_EQ((int)(sizeof(buf) + sizeof(buf2)), | |
445 | ioctx.read("foo", bl3, (sizeof(buf) + sizeof(buf2)), 0)); | |
446 | const char *bl3_str = bl3.c_str(); | |
447 | ASSERT_EQ(0, memcmp(bl3_str, buf, sizeof(buf))); | |
448 | ASSERT_EQ(0, memcmp(bl3_str + sizeof(buf), buf2, sizeof(buf2))); | |
449 | } | |
450 | ||
451 | TEST_F(LibRadosIo, TruncTest) { | |
452 | char buf[128]; | |
453 | char buf2[sizeof(buf)]; | |
454 | memset(buf, 0xaa, sizeof(buf)); | |
455 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
456 | ASSERT_EQ(0, rados_trunc(ioctx, "foo", sizeof(buf) / 2)); | |
457 | memset(buf2, 0, sizeof(buf2)); | |
458 | ASSERT_EQ((int)(sizeof(buf)/2), rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
459 | ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)/2)); | |
460 | } | |
461 | ||
462 | TEST_F(LibRadosIoPP, TruncTestPP) { | |
463 | char buf[128]; | |
464 | memset(buf, 0xaa, sizeof(buf)); | |
465 | bufferlist bl; | |
466 | bl.append(buf, sizeof(buf)); | |
467 | ASSERT_EQ(0, ioctx.append("foo", bl, sizeof(buf))); | |
468 | ASSERT_EQ(0, ioctx.trunc("foo", sizeof(buf) / 2)); | |
469 | bufferlist bl2; | |
470 | ASSERT_EQ((int)(sizeof(buf)/2), ioctx.read("foo", bl2, sizeof(buf), 0)); | |
471 | ASSERT_EQ(0, memcmp(bl2.c_str(), buf, sizeof(buf)/2)); | |
472 | } | |
473 | ||
474 | TEST_F(LibRadosIo, RemoveTest) { | |
475 | char buf[128]; | |
476 | char buf2[sizeof(buf)]; | |
477 | memset(buf, 0xaa, sizeof(buf)); | |
478 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
479 | ASSERT_EQ(0, rados_remove(ioctx, "foo")); | |
480 | memset(buf2, 0, sizeof(buf2)); | |
481 | ASSERT_EQ(-ENOENT, rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
482 | } | |
483 | ||
484 | TEST_F(LibRadosIoPP, RemoveTestPP) { | |
485 | char buf[128]; | |
486 | memset(buf, 0xaa, sizeof(buf)); | |
487 | bufferlist bl1; | |
488 | bl1.append(buf, sizeof(buf)); | |
489 | ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf))); | |
490 | ASSERT_EQ(0, ioctx.remove("foo")); | |
491 | bufferlist bl2; | |
492 | ASSERT_EQ(-ENOENT, ioctx.read("foo", bl2, sizeof(buf), 0)); | |
493 | } | |
494 | ||
495 | TEST_F(LibRadosIo, XattrsRoundTrip) { | |
496 | char buf[128]; | |
497 | char attr1[] = "attr1"; | |
498 | char attr1_buf[] = "foo bar baz"; | |
499 | memset(buf, 0xaa, sizeof(buf)); | |
500 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
501 | ASSERT_EQ(-ENODATA, rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
502 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
503 | ASSERT_EQ((int)sizeof(attr1_buf), | |
504 | rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
505 | ASSERT_EQ(0, memcmp(attr1_buf, buf, sizeof(attr1_buf))); | |
506 | } | |
507 | ||
508 | TEST_F(LibRadosIoPP, XattrsRoundTripPP) { | |
509 | char buf[128]; | |
510 | char attr1[] = "attr1"; | |
511 | char attr1_buf[] = "foo bar baz"; | |
512 | memset(buf, 0xaa, sizeof(buf)); | |
513 | bufferlist bl1; | |
514 | bl1.append(buf, sizeof(buf)); | |
515 | ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf))); | |
516 | bufferlist bl2; | |
517 | ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl2)); | |
518 | bufferlist bl3; | |
519 | bl3.append(attr1_buf, sizeof(attr1_buf)); | |
520 | ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl3)); | |
521 | bufferlist bl4; | |
522 | ASSERT_EQ((int)sizeof(attr1_buf), | |
523 | ioctx.getxattr("foo", attr1, bl4)); | |
524 | ASSERT_EQ(0, memcmp(bl4.c_str(), attr1_buf, sizeof(attr1_buf))); | |
525 | } | |
526 | ||
527 | TEST_F(LibRadosIo, RmXattr) { | |
528 | char buf[128]; | |
529 | char attr1[] = "attr1"; | |
530 | char attr1_buf[] = "foo bar baz"; | |
531 | memset(buf, 0xaa, sizeof(buf)); | |
532 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
533 | ASSERT_EQ(0, | |
534 | rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
535 | ASSERT_EQ(0, rados_rmxattr(ioctx, "foo", attr1)); | |
536 | ASSERT_EQ(-ENODATA, rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
537 | ||
538 | // Test rmxattr on a removed object | |
539 | char buf2[128]; | |
540 | char attr2[] = "attr2"; | |
541 | char attr2_buf[] = "foo bar baz"; | |
542 | memset(buf2, 0xbb, sizeof(buf2)); | |
543 | ASSERT_EQ(0, rados_write(ioctx, "foo_rmxattr", buf2, sizeof(buf2), 0)); | |
544 | ASSERT_EQ(0, | |
545 | rados_setxattr(ioctx, "foo_rmxattr", attr2, attr2_buf, sizeof(attr2_buf))); | |
546 | ASSERT_EQ(0, rados_remove(ioctx, "foo_rmxattr")); | |
547 | ASSERT_EQ(-ENOENT, rados_rmxattr(ioctx, "foo_rmxattr", attr2)); | |
548 | } | |
549 | ||
550 | TEST_F(LibRadosIoPP, RmXattrPP) { | |
551 | char buf[128]; | |
552 | char attr1[] = "attr1"; | |
553 | char attr1_buf[] = "foo bar baz"; | |
554 | memset(buf, 0xaa, sizeof(buf)); | |
555 | bufferlist bl1; | |
556 | bl1.append(buf, sizeof(buf)); | |
557 | ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf))); | |
558 | bufferlist bl2; | |
559 | bl2.append(attr1_buf, sizeof(attr1_buf)); | |
560 | ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl2)); | |
561 | ASSERT_EQ(0, ioctx.rmxattr("foo", attr1)); | |
562 | bufferlist bl3; | |
563 | ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl3)); | |
564 | ||
565 | // Test rmxattr on a removed object | |
566 | char buf2[128]; | |
567 | char attr2[] = "attr2"; | |
568 | char attr2_buf[] = "foo bar baz"; | |
569 | memset(buf2, 0xbb, sizeof(buf2)); | |
570 | bufferlist bl21; | |
571 | bl21.append(buf, sizeof(buf)); | |
572 | ASSERT_EQ(0, ioctx.write("foo_rmxattr", bl21, sizeof(buf2), 0)); | |
573 | bufferlist bl22; | |
574 | bl22.append(attr2_buf, sizeof(attr2_buf)); | |
575 | ASSERT_EQ(0, ioctx.setxattr("foo_rmxattr", attr2, bl22)); | |
576 | ASSERT_EQ(0, ioctx.remove("foo_rmxattr")); | |
577 | ASSERT_EQ(-ENOENT, ioctx.rmxattr("foo_rmxattr", attr2)); | |
578 | } | |
579 | ||
580 | TEST_F(LibRadosIo, XattrIter) { | |
581 | char buf[128]; | |
582 | char attr1[] = "attr1"; | |
583 | char attr1_buf[] = "foo bar baz"; | |
584 | char attr2[] = "attr2"; | |
585 | char attr2_buf[256]; | |
586 | for (size_t j = 0; j < sizeof(attr2_buf); ++j) { | |
587 | attr2_buf[j] = j % 0xff; | |
588 | } | |
589 | memset(buf, 0xaa, sizeof(buf)); | |
590 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
591 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
592 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr2, attr2_buf, sizeof(attr2_buf))); | |
593 | rados_xattrs_iter_t iter; | |
594 | ASSERT_EQ(0, rados_getxattrs(ioctx, "foo", &iter)); | |
595 | int num_seen = 0; | |
596 | while (true) { | |
597 | const char *name; | |
598 | const char *val; | |
599 | size_t len; | |
600 | ASSERT_EQ(0, rados_getxattrs_next(iter, &name, &val, &len)); | |
601 | if (name == NULL) { | |
602 | break; | |
603 | } | |
604 | ASSERT_LT(num_seen, 2); | |
605 | if ((strcmp(name, attr1) == 0) && (val != NULL) && (memcmp(val, attr1_buf, len) == 0)) { | |
606 | num_seen++; | |
607 | continue; | |
608 | } | |
609 | else if ((strcmp(name, attr2) == 0) && (val != NULL) && (memcmp(val, attr2_buf, len) == 0)) { | |
610 | num_seen++; | |
611 | continue; | |
612 | } | |
613 | else { | |
614 | ASSERT_EQ(0, 1); | |
615 | } | |
616 | } | |
617 | rados_getxattrs_end(iter); | |
618 | } | |
619 | ||
620 | TEST_F(LibRadosIoPP, XattrListPP) { | |
621 | char buf[128]; | |
622 | char attr1[] = "attr1"; | |
623 | char attr1_buf[] = "foo bar baz"; | |
624 | char attr2[] = "attr2"; | |
625 | char attr2_buf[256]; | |
626 | for (size_t j = 0; j < sizeof(attr2_buf); ++j) { | |
627 | attr2_buf[j] = j % 0xff; | |
628 | } | |
629 | memset(buf, 0xaa, sizeof(buf)); | |
630 | bufferlist bl1; | |
631 | bl1.append(buf, sizeof(buf)); | |
632 | ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf))); | |
633 | bufferlist bl2; | |
634 | bl2.append(attr1_buf, sizeof(attr1_buf)); | |
635 | ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl2)); | |
636 | bufferlist bl3; | |
637 | bl3.append(attr2_buf, sizeof(attr2_buf)); | |
638 | ASSERT_EQ(0, ioctx.setxattr("foo", attr2, bl3)); | |
639 | std::map<std::string, bufferlist> attrset; | |
640 | ASSERT_EQ(0, ioctx.getxattrs("foo", attrset)); | |
641 | for (std::map<std::string, bufferlist>::iterator i = attrset.begin(); | |
642 | i != attrset.end(); ++i) { | |
643 | if (i->first == string(attr1)) { | |
644 | ASSERT_EQ(0, memcmp(i->second.c_str(), attr1_buf, sizeof(attr1_buf))); | |
645 | } | |
646 | else if (i->first == string(attr2)) { | |
647 | ASSERT_EQ(0, memcmp(i->second.c_str(), attr2_buf, sizeof(attr2_buf))); | |
648 | } | |
649 | else { | |
650 | ASSERT_EQ(0, 1); | |
651 | } | |
652 | } | |
653 | } | |
654 | ||
655 | TEST_F(LibRadosIoEC, SimpleWrite) { | |
656 | char buf[128]; | |
657 | memset(buf, 0xcc, sizeof(buf)); | |
658 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
659 | rados_ioctx_set_namespace(ioctx, "nspace"); | |
660 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
661 | } | |
662 | ||
663 | TEST_F(LibRadosIoECPP, SimpleWritePP) { | |
664 | char buf[128]; | |
665 | memset(buf, 0xcc, sizeof(buf)); | |
666 | bufferlist bl; | |
667 | bl.append(buf, sizeof(buf)); | |
668 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
669 | ioctx.set_namespace("nspace"); | |
670 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
671 | } | |
672 | ||
673 | TEST_F(LibRadosIoECPP, ReadOpPP) { | |
674 | char buf[128]; | |
675 | memset(buf, 0xcc, sizeof(buf)); | |
676 | bufferlist bl; | |
677 | bl.append(buf, sizeof(buf)); | |
678 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
679 | ||
680 | { | |
681 | bufferlist op_bl; | |
682 | ObjectReadOperation op; | |
683 | op.read(0, sizeof(buf), NULL, NULL); | |
684 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
685 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
686 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
687 | } | |
688 | ||
689 | { | |
690 | bufferlist op_bl; | |
691 | ObjectReadOperation op; | |
692 | op.read(0, 0, NULL, NULL); //len=0 mean read the whole object data | |
693 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
694 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
695 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
696 | } | |
697 | ||
698 | { | |
699 | bufferlist read_bl, op_bl; | |
700 | ObjectReadOperation op; | |
701 | op.read(0, sizeof(buf), &read_bl, NULL); | |
702 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
703 | ASSERT_EQ(sizeof(buf), read_bl.length()); | |
704 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
705 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
706 | ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf))); | |
707 | } | |
708 | ||
709 | { | |
710 | bufferlist op_bl; | |
711 | int rval = 1000; | |
712 | ObjectReadOperation op; | |
713 | op.read(0, sizeof(buf), NULL, &rval); | |
714 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
715 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
716 | ASSERT_EQ(0, rval); | |
717 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
718 | } | |
719 | ||
720 | { | |
721 | bufferlist read_bl, op_bl; | |
722 | int rval = 1000; | |
723 | ObjectReadOperation op; | |
724 | op.read(0, sizeof(buf), &read_bl, &rval); | |
725 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
726 | ASSERT_EQ(sizeof(buf), read_bl.length()); | |
727 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
728 | ASSERT_EQ(0, rval); | |
729 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
730 | ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf))); | |
731 | } | |
732 | ||
733 | { | |
734 | bufferlist read_bl1, read_bl2, op_bl; | |
735 | int rval1 = 1000, rval2 = 1002; | |
736 | ObjectReadOperation op; | |
737 | op.read(0, sizeof(buf), &read_bl1, &rval1); | |
738 | op.read(0, sizeof(buf), &read_bl2, &rval2); | |
739 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
740 | ASSERT_EQ(sizeof(buf), read_bl1.length()); | |
741 | ASSERT_EQ(sizeof(buf), read_bl2.length()); | |
742 | ASSERT_EQ(sizeof(buf) * 2, op_bl.length()); | |
743 | ASSERT_EQ(0, rval1); | |
744 | ASSERT_EQ(0, rval2); | |
745 | ASSERT_EQ(0, memcmp(read_bl1.c_str(), buf, sizeof(buf))); | |
746 | ASSERT_EQ(0, memcmp(read_bl2.c_str(), buf, sizeof(buf))); | |
747 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
748 | ASSERT_EQ(0, memcmp(op_bl.c_str() + sizeof(buf), buf, sizeof(buf))); | |
749 | } | |
750 | ||
751 | { | |
752 | bufferlist op_bl; | |
753 | ObjectReadOperation op; | |
754 | op.read(0, sizeof(buf), NULL, NULL); | |
755 | ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl)); | |
756 | ASSERT_EQ(sizeof(buf), op_bl.length()); | |
757 | ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf))); | |
758 | } | |
759 | ||
760 | { | |
761 | bufferlist read_bl; | |
762 | ObjectReadOperation op; | |
763 | op.read(0, sizeof(buf), &read_bl, NULL); | |
764 | ASSERT_EQ(0, ioctx.operate("foo", &op, NULL)); | |
765 | ASSERT_EQ(sizeof(buf), read_bl.length()); | |
766 | ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf))); | |
767 | } | |
768 | ||
769 | { | |
770 | int rval = 1000; | |
771 | ObjectReadOperation op; | |
772 | op.read(0, sizeof(buf), NULL, &rval); | |
773 | ASSERT_EQ(0, ioctx.operate("foo", &op, NULL)); | |
774 | ASSERT_EQ(0, rval); | |
775 | } | |
776 | ||
777 | { | |
778 | bufferlist read_bl; | |
779 | int rval = 1000; | |
780 | ObjectReadOperation op; | |
781 | op.read(0, sizeof(buf), &read_bl, &rval); | |
782 | ASSERT_EQ(0, ioctx.operate("foo", &op, NULL)); | |
783 | ASSERT_EQ(sizeof(buf), read_bl.length()); | |
784 | ASSERT_EQ(0, rval); | |
785 | ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf))); | |
786 | } | |
787 | ||
788 | { | |
789 | bufferlist read_bl1, read_bl2; | |
790 | int rval1 = 1000, rval2 = 1002; | |
791 | ObjectReadOperation op; | |
792 | op.read(0, sizeof(buf), &read_bl1, &rval1); | |
793 | op.read(0, sizeof(buf), &read_bl2, &rval2); | |
794 | ASSERT_EQ(0, ioctx.operate("foo", &op, NULL)); | |
795 | ASSERT_EQ(sizeof(buf), read_bl1.length()); | |
796 | ASSERT_EQ(sizeof(buf), read_bl2.length()); | |
797 | ASSERT_EQ(0, rval1); | |
798 | ASSERT_EQ(0, rval2); | |
799 | ASSERT_EQ(0, memcmp(read_bl1.c_str(), buf, sizeof(buf))); | |
800 | ASSERT_EQ(0, memcmp(read_bl2.c_str(), buf, sizeof(buf))); | |
801 | } | |
802 | } | |
803 | ||
804 | TEST_F(LibRadosIoECPP, SparseReadOpPP) { | |
805 | char buf[128]; | |
806 | memset(buf, 0xcc, sizeof(buf)); | |
807 | bufferlist bl; | |
808 | bl.append(buf, sizeof(buf)); | |
809 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
810 | ||
811 | { | |
812 | std::map<uint64_t, uint64_t> extents; | |
813 | bufferlist read_bl; | |
814 | int rval = -1; | |
815 | ObjectReadOperation op; | |
816 | op.sparse_read(0, sizeof(buf), &extents, &read_bl, &rval); | |
817 | ASSERT_EQ(0, ioctx.operate("foo", &op, nullptr)); | |
818 | ASSERT_EQ(0, rval); | |
819 | assert_eq_sparse(bl, extents, read_bl); | |
820 | } | |
821 | } | |
822 | ||
823 | TEST_F(LibRadosIoEC, RoundTrip) { | |
824 | char buf[128]; | |
825 | char buf2[128]; | |
826 | memset(buf, 0xcc, sizeof(buf)); | |
827 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
828 | memset(buf2, 0, sizeof(buf2)); | |
829 | ASSERT_EQ((int)sizeof(buf2), rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
830 | ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf))); | |
831 | ||
832 | uint64_t off = 19; | |
833 | ASSERT_EQ(-EOPNOTSUPP, rados_write(ioctx, "bar", buf, sizeof(buf), off)); | |
834 | } | |
835 | ||
836 | TEST_F(LibRadosIoECPP, RoundTripPP) { | |
837 | char buf[128]; | |
838 | Rados cluster; | |
839 | memset(buf, 0xcc, sizeof(buf)); | |
840 | bufferlist bl; | |
841 | bl.append(buf, sizeof(buf)); | |
842 | ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0)); | |
843 | bufferlist cl; | |
844 | ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", cl, sizeof(buf) * 3, 0)); | |
845 | ASSERT_EQ(0, memcmp(buf, cl.c_str(), sizeof(buf))); | |
846 | } | |
847 | ||
848 | TEST_F(LibRadosIoECPP, RoundTripPP2) | |
849 | { | |
850 | bufferlist bl; | |
851 | bl.append("ceph"); | |
852 | ObjectWriteOperation write; | |
853 | write.write(0, bl); | |
854 | write.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED); | |
855 | ASSERT_EQ(0, ioctx.operate("foo", &write)); | |
856 | ||
857 | ObjectReadOperation read; | |
858 | read.read(0, bl.length(), NULL, NULL); | |
859 | read.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED|LIBRADOS_OP_FLAG_FADVISE_RANDOM); | |
860 | ASSERT_EQ(0, ioctx.operate("foo", &read, &bl)); | |
861 | ASSERT_EQ(0, memcmp(bl.c_str(), "ceph", 4)); | |
862 | } | |
863 | ||
864 | TEST_F(LibRadosIoEC, OverlappingWriteRoundTrip) { | |
865 | int bsize = alignment; | |
866 | int dbsize = bsize * 2; | |
867 | char *buf = (char *)new char[dbsize]; | |
868 | char *buf2 = (char *)new char[bsize]; | |
869 | char *buf3 = (char *)new char[dbsize]; | |
870 | auto cleanup = [&] { | |
871 | delete[] buf; | |
872 | delete[] buf2; | |
873 | delete[] buf3; | |
874 | }; | |
875 | scope_guard<decltype(cleanup)> sg(std::move(cleanup)); | |
876 | memset(buf, 0xcc, dbsize); | |
877 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, dbsize, 0)); | |
878 | memset(buf2, 0xdd, bsize); | |
879 | ASSERT_EQ(-EOPNOTSUPP, rados_write(ioctx, "foo", buf2, bsize, 0)); | |
880 | memset(buf3, 0xdd, dbsize); | |
881 | ASSERT_EQ(dbsize, rados_read(ioctx, "foo", buf3, dbsize, 0)); | |
882 | // Read the same as first write | |
883 | ASSERT_EQ(0, memcmp(buf3, buf, dbsize)); | |
884 | } | |
885 | ||
886 | TEST_F(LibRadosIoECPP, OverlappingWriteRoundTripPP) { | |
887 | int bsize = alignment; | |
888 | int dbsize = bsize * 2; | |
889 | char *buf = (char *)new char[dbsize]; | |
890 | char *buf2 = (char *)new char[bsize]; | |
891 | auto cleanup = [&] { | |
892 | delete[] buf; | |
893 | delete[] buf2; | |
894 | }; | |
895 | scope_guard<decltype(cleanup)> sg(std::move(cleanup)); | |
896 | memset(buf, 0xcc, dbsize); | |
897 | bufferlist bl1; | |
898 | bl1.append(buf, dbsize); | |
899 | ASSERT_EQ(0, ioctx.write("foo", bl1, dbsize, 0)); | |
900 | memset(buf2, 0xdd, bsize); | |
901 | bufferlist bl2; | |
902 | bl2.append(buf2, bsize); | |
903 | ASSERT_EQ(-EOPNOTSUPP, ioctx.write("foo", bl2, bsize, 0)); | |
904 | bufferlist bl3; | |
905 | ASSERT_EQ(dbsize, ioctx.read("foo", bl3, dbsize, 0)); | |
906 | // Read the same as first write | |
907 | ASSERT_EQ(0, memcmp(bl3.c_str(), buf, dbsize)); | |
908 | } | |
909 | ||
910 | TEST_F(LibRadosIoEC, WriteFullRoundTrip) { | |
911 | char buf[128]; | |
912 | char buf2[64]; | |
913 | char buf3[128]; | |
914 | memset(buf, 0xcc, sizeof(buf)); | |
915 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
916 | memset(buf2, 0xdd, sizeof(buf2)); | |
917 | ASSERT_EQ(0, rados_write_full(ioctx, "foo", buf2, sizeof(buf2))); | |
918 | memset(buf3, 0xee, sizeof(buf3)); | |
919 | ASSERT_EQ((int)sizeof(buf2), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0)); | |
920 | ASSERT_EQ(0, memcmp(buf3, buf2, sizeof(buf2))); | |
921 | } | |
922 | ||
923 | TEST_F(LibRadosIoECPP, WriteFullRoundTripPP) { | |
924 | char buf[128]; | |
925 | char buf2[64]; | |
926 | memset(buf, 0xcc, sizeof(buf)); | |
927 | bufferlist bl1; | |
928 | bl1.append(buf, sizeof(buf)); | |
929 | ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); | |
930 | memset(buf2, 0xdd, sizeof(buf2)); | |
931 | bufferlist bl2; | |
932 | bl2.append(buf2, sizeof(buf2)); | |
933 | ASSERT_EQ(0, ioctx.write_full("foo", bl2)); | |
934 | bufferlist bl3; | |
935 | ASSERT_EQ((int)sizeof(buf2), ioctx.read("foo", bl3, sizeof(buf), 0)); | |
936 | ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2))); | |
937 | } | |
938 | ||
939 | TEST_F(LibRadosIoECPP, WriteFullRoundTripPP2) | |
940 | { | |
941 | bufferlist bl; | |
942 | bl.append("ceph"); | |
943 | ObjectWriteOperation write; | |
944 | write.write_full(bl); | |
945 | write.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED); | |
946 | ASSERT_EQ(0, ioctx.operate("foo", &write)); | |
947 | ||
948 | ObjectReadOperation read; | |
949 | read.read(0, bl.length(), NULL, NULL); | |
950 | read.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED|LIBRADOS_OP_FLAG_FADVISE_RANDOM); | |
951 | ASSERT_EQ(0, ioctx.operate("foo", &read, &bl)); | |
952 | ASSERT_EQ(0, memcmp(bl.c_str(), "ceph", 4)); | |
953 | } | |
954 | ||
955 | TEST_F(LibRadosIoEC, AppendRoundTrip) { | |
956 | char *buf = (char *)new char[alignment]; | |
957 | char *buf2 = (char *)new char[alignment]; | |
958 | char *buf3 = (char *)new char[alignment *2]; | |
959 | int uasize = alignment/2; | |
960 | char *unalignedbuf = (char *)new char[uasize]; | |
961 | auto cleanup = [&] { | |
962 | delete[] buf; | |
963 | delete[] buf2; | |
964 | delete[] buf3; | |
965 | delete[] unalignedbuf; | |
966 | }; | |
967 | scope_guard<decltype(cleanup)> sg(std::move(cleanup)); | |
968 | memset(buf, 0xde, alignment); | |
969 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, alignment)); | |
970 | memset(buf2, 0xad, alignment); | |
971 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf2, alignment)); | |
972 | memset(buf3, 0, alignment*2); | |
973 | ASSERT_EQ((int)alignment*2, rados_read(ioctx, "foo", buf3, alignment*2, 0)); | |
974 | ASSERT_EQ(0, memcmp(buf3, buf, alignment)); | |
975 | ASSERT_EQ(0, memcmp(buf3 + alignment, buf2, alignment)); | |
976 | memset(unalignedbuf, 0, uasize); | |
977 | ASSERT_EQ(0, rados_append(ioctx, "foo", unalignedbuf, uasize)); | |
978 | ASSERT_EQ(-EOPNOTSUPP, rados_append(ioctx, "foo", unalignedbuf, uasize)); | |
979 | } | |
980 | ||
981 | TEST_F(LibRadosIoECPP, AppendRoundTripPP) { | |
982 | char *buf = (char *)new char[alignment]; | |
983 | char *buf2 = (char *)new char[alignment]; | |
984 | auto cleanup = [&] { | |
985 | delete[] buf; | |
986 | delete[] buf2; | |
987 | }; | |
988 | scope_guard<decltype(cleanup)> sg(std::move(cleanup)); | |
989 | memset(buf, 0xde, alignment); | |
990 | bufferlist bl1; | |
991 | bl1.append(buf, alignment); | |
992 | ASSERT_EQ(0, ioctx.append("foo", bl1, alignment)); | |
993 | memset(buf2, 0xad, alignment); | |
994 | bufferlist bl2; | |
995 | bl2.append(buf2, alignment); | |
996 | ASSERT_EQ(0, ioctx.append("foo", bl2, alignment)); | |
997 | bufferlist bl3; | |
998 | ASSERT_EQ((int)(alignment * 2), | |
999 | ioctx.read("foo", bl3, (alignment * 4), 0)); | |
1000 | const char *bl3_str = bl3.c_str(); | |
1001 | ASSERT_EQ(0, memcmp(bl3_str, buf, alignment)); | |
1002 | ASSERT_EQ(0, memcmp(bl3_str + alignment, buf2, alignment)); | |
1003 | } | |
1004 | ||
1005 | TEST_F(LibRadosIoEC, TruncTest) { | |
1006 | char buf[128]; | |
1007 | char buf2[sizeof(buf)]; | |
1008 | memset(buf, 0xaa, sizeof(buf)); | |
1009 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
1010 | ASSERT_EQ(-EOPNOTSUPP, rados_trunc(ioctx, "foo", sizeof(buf) / 2)); | |
1011 | memset(buf2, 0, sizeof(buf2)); | |
1012 | // Same size | |
1013 | ASSERT_EQ((int)sizeof(buf), rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
1014 | // No change | |
1015 | ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf))); | |
1016 | } | |
1017 | ||
1018 | TEST_F(LibRadosIoECPP, TruncTestPP) { | |
1019 | char buf[128]; | |
1020 | memset(buf, 0xaa, sizeof(buf)); | |
1021 | bufferlist bl; | |
1022 | bl.append(buf, sizeof(buf)); | |
1023 | ASSERT_EQ(0, ioctx.append("foo", bl, sizeof(buf))); | |
1024 | ASSERT_EQ(-EOPNOTSUPP, ioctx.trunc("foo", sizeof(buf) / 2)); | |
1025 | bufferlist bl2; | |
1026 | // Same size | |
1027 | ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl2, sizeof(buf), 0)); | |
1028 | // No change | |
1029 | ASSERT_EQ(0, memcmp(bl2.c_str(), buf, sizeof(buf))); | |
1030 | } | |
1031 | ||
1032 | TEST_F(LibRadosIoEC, RemoveTest) { | |
1033 | char buf[128]; | |
1034 | char buf2[sizeof(buf)]; | |
1035 | memset(buf, 0xaa, sizeof(buf)); | |
1036 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
1037 | ASSERT_EQ(0, rados_remove(ioctx, "foo")); | |
1038 | memset(buf2, 0, sizeof(buf2)); | |
1039 | ASSERT_EQ(-ENOENT, rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
1040 | } | |
1041 | ||
1042 | TEST_F(LibRadosIoECPP, RemoveTestPP) { | |
1043 | char buf[128]; | |
1044 | memset(buf, 0xaa, sizeof(buf)); | |
1045 | bufferlist bl1; | |
1046 | bl1.append(buf, sizeof(buf)); | |
1047 | ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf))); | |
1048 | ASSERT_EQ(0, ioctx.remove("foo")); | |
1049 | bufferlist bl2; | |
1050 | ASSERT_EQ(-ENOENT, ioctx.read("foo", bl2, sizeof(buf), 0)); | |
1051 | } | |
1052 | ||
1053 | TEST_F(LibRadosIoEC, XattrsRoundTrip) { | |
1054 | char buf[128]; | |
1055 | char attr1[] = "attr1"; | |
1056 | char attr1_buf[] = "foo bar baz"; | |
1057 | memset(buf, 0xaa, sizeof(buf)); | |
1058 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
1059 | ASSERT_EQ(-ENODATA, rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
1060 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
1061 | ASSERT_EQ((int)sizeof(attr1_buf), | |
1062 | rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
1063 | ASSERT_EQ(0, memcmp(attr1_buf, buf, sizeof(attr1_buf))); | |
1064 | } | |
1065 | ||
1066 | TEST_F(LibRadosIoECPP, XattrsRoundTripPP) { | |
1067 | char buf[128]; | |
1068 | char attr1[] = "attr1"; | |
1069 | char attr1_buf[] = "foo bar baz"; | |
1070 | memset(buf, 0xaa, sizeof(buf)); | |
1071 | bufferlist bl1; | |
1072 | bl1.append(buf, sizeof(buf)); | |
1073 | ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf))); | |
1074 | bufferlist bl2; | |
1075 | ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl2)); | |
1076 | bufferlist bl3; | |
1077 | bl3.append(attr1_buf, sizeof(attr1_buf)); | |
1078 | ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl3)); | |
1079 | bufferlist bl4; | |
1080 | ASSERT_EQ((int)sizeof(attr1_buf), | |
1081 | ioctx.getxattr("foo", attr1, bl4)); | |
1082 | ASSERT_EQ(0, memcmp(bl4.c_str(), attr1_buf, sizeof(attr1_buf))); | |
1083 | } | |
1084 | ||
1085 | TEST_F(LibRadosIoEC, RmXattr) { | |
1086 | char buf[128]; | |
1087 | char attr1[] = "attr1"; | |
1088 | char attr1_buf[] = "foo bar baz"; | |
1089 | memset(buf, 0xaa, sizeof(buf)); | |
1090 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
1091 | ASSERT_EQ(0, | |
1092 | rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
1093 | ASSERT_EQ(0, rados_rmxattr(ioctx, "foo", attr1)); | |
1094 | ASSERT_EQ(-ENODATA, rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
1095 | ||
1096 | // Test rmxattr on a removed object | |
1097 | char buf2[128]; | |
1098 | char attr2[] = "attr2"; | |
1099 | char attr2_buf[] = "foo bar baz"; | |
1100 | memset(buf2, 0xbb, sizeof(buf2)); | |
1101 | ASSERT_EQ(0, rados_write(ioctx, "foo_rmxattr", buf2, sizeof(buf2), 0)); | |
1102 | ASSERT_EQ(0, | |
1103 | rados_setxattr(ioctx, "foo_rmxattr", attr2, attr2_buf, sizeof(attr2_buf))); | |
1104 | ASSERT_EQ(0, rados_remove(ioctx, "foo_rmxattr")); | |
1105 | ASSERT_EQ(-ENOENT, rados_rmxattr(ioctx, "foo_rmxattr", attr2)); | |
1106 | } | |
1107 | ||
1108 | TEST_F(LibRadosIoECPP, RmXattrPP) { | |
1109 | char buf[128]; | |
1110 | char attr1[] = "attr1"; | |
1111 | char attr1_buf[] = "foo bar baz"; | |
1112 | memset(buf, 0xaa, sizeof(buf)); | |
1113 | bufferlist bl1; | |
1114 | bl1.append(buf, sizeof(buf)); | |
1115 | ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf))); | |
1116 | bufferlist bl2; | |
1117 | bl2.append(attr1_buf, sizeof(attr1_buf)); | |
1118 | ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl2)); | |
1119 | ASSERT_EQ(0, ioctx.rmxattr("foo", attr1)); | |
1120 | bufferlist bl3; | |
1121 | ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl3)); | |
1122 | ||
1123 | // Test rmxattr on a removed object | |
1124 | char buf2[128]; | |
1125 | char attr2[] = "attr2"; | |
1126 | char attr2_buf[] = "foo bar baz"; | |
1127 | memset(buf2, 0xbb, sizeof(buf2)); | |
1128 | bufferlist bl21; | |
1129 | bl21.append(buf, sizeof(buf)); | |
1130 | ASSERT_EQ(0, ioctx.write("foo_rmxattr", bl21, sizeof(buf2), 0)); | |
1131 | bufferlist bl22; | |
1132 | bl22.append(attr2_buf, sizeof(attr2_buf)); | |
1133 | ASSERT_EQ(0, ioctx.setxattr("foo_rmxattr", attr2, bl22)); | |
1134 | ASSERT_EQ(0, ioctx.remove("foo_rmxattr")); | |
1135 | ASSERT_EQ(-ENOENT, ioctx.rmxattr("foo_rmxattr", attr2)); | |
1136 | } | |
1137 | ||
1138 | TEST_F(LibRadosIoEC, XattrIter) { | |
1139 | char buf[128]; | |
1140 | char attr1[] = "attr1"; | |
1141 | char attr1_buf[] = "foo bar baz"; | |
1142 | char attr2[] = "attr2"; | |
1143 | char attr2_buf[256]; | |
1144 | for (size_t j = 0; j < sizeof(attr2_buf); ++j) { | |
1145 | attr2_buf[j] = j % 0xff; | |
1146 | } | |
1147 | memset(buf, 0xaa, sizeof(buf)); | |
1148 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
1149 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
1150 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr2, attr2_buf, sizeof(attr2_buf))); | |
1151 | rados_xattrs_iter_t iter; | |
1152 | ASSERT_EQ(0, rados_getxattrs(ioctx, "foo", &iter)); | |
1153 | int num_seen = 0; | |
1154 | while (true) { | |
1155 | const char *name; | |
1156 | const char *val; | |
1157 | size_t len; | |
1158 | ASSERT_EQ(0, rados_getxattrs_next(iter, &name, &val, &len)); | |
1159 | if (name == NULL) { | |
1160 | break; | |
1161 | } | |
1162 | ASSERT_LT(num_seen, 2); | |
1163 | if ((strcmp(name, attr1) == 0) && (val != NULL) && (memcmp(val, attr1_buf, len) == 0)) { | |
1164 | num_seen++; | |
1165 | continue; | |
1166 | } | |
1167 | else if ((strcmp(name, attr2) == 0) && (val != NULL) && (memcmp(val, attr2_buf, len) == 0)) { | |
1168 | num_seen++; | |
1169 | continue; | |
1170 | } | |
1171 | else { | |
1172 | ASSERT_EQ(0, 1); | |
1173 | } | |
1174 | } | |
1175 | rados_getxattrs_end(iter); | |
1176 | } | |
1177 | ||
1178 | TEST_F(LibRadosIoECPP, XattrListPP) { | |
1179 | char buf[128]; | |
1180 | char attr1[] = "attr1"; | |
1181 | char attr1_buf[] = "foo bar baz"; | |
1182 | char attr2[] = "attr2"; | |
1183 | char attr2_buf[256]; | |
1184 | for (size_t j = 0; j < sizeof(attr2_buf); ++j) { | |
1185 | attr2_buf[j] = j % 0xff; | |
1186 | } | |
1187 | memset(buf, 0xaa, sizeof(buf)); | |
1188 | bufferlist bl1; | |
1189 | bl1.append(buf, sizeof(buf)); | |
1190 | ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf))); | |
1191 | bufferlist bl2; | |
1192 | bl2.append(attr1_buf, sizeof(attr1_buf)); | |
1193 | ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl2)); | |
1194 | bufferlist bl3; | |
1195 | bl3.append(attr2_buf, sizeof(attr2_buf)); | |
1196 | ASSERT_EQ(0, ioctx.setxattr("foo", attr2, bl3)); | |
1197 | std::map<std::string, bufferlist> attrset; | |
1198 | ASSERT_EQ(0, ioctx.getxattrs("foo", attrset)); | |
1199 | for (std::map<std::string, bufferlist>::iterator i = attrset.begin(); | |
1200 | i != attrset.end(); ++i) { | |
1201 | if (i->first == string(attr1)) { | |
1202 | ASSERT_EQ(0, memcmp(i->second.c_str(), attr1_buf, sizeof(attr1_buf))); | |
1203 | } | |
1204 | else if (i->first == string(attr2)) { | |
1205 | ASSERT_EQ(0, memcmp(i->second.c_str(), attr2_buf, sizeof(attr2_buf))); | |
1206 | } | |
1207 | else { | |
1208 | ASSERT_EQ(0, 1); | |
1209 | } | |
1210 | } | |
1211 | } | |
c07f9fc5 FG |
1212 | |
1213 | TEST_F(LibRadosIoPP, CmpExtPP) { | |
1214 | bufferlist bl; | |
1215 | bl.append("ceph"); | |
1216 | ObjectWriteOperation write1; | |
1217 | write1.write(0, bl); | |
1218 | ASSERT_EQ(0, ioctx.operate("foo", &write1)); | |
1219 | ||
1220 | bufferlist new_bl; | |
1221 | new_bl.append("CEPH"); | |
1222 | ObjectWriteOperation write2; | |
1223 | write2.cmpext(0, bl, nullptr); | |
1224 | write2.write(0, new_bl); | |
1225 | ASSERT_EQ(0, ioctx.operate("foo", &write2)); | |
1226 | ||
1227 | ObjectReadOperation read; | |
1228 | read.read(0, bl.length(), NULL, NULL); | |
1229 | ASSERT_EQ(0, ioctx.operate("foo", &read, &bl)); | |
1230 | ASSERT_EQ(0, memcmp(bl.c_str(), "CEPH", 4)); | |
1231 | } | |
1232 | ||
1233 | TEST_F(LibRadosIoPP, CmpExtDNEPP) { | |
1234 | bufferlist bl; | |
1235 | bl.append(std::string(4, '\0')); | |
1236 | ||
1237 | bufferlist new_bl; | |
1238 | new_bl.append("CEPH"); | |
1239 | ObjectWriteOperation write; | |
1240 | write.cmpext(0, bl, nullptr); | |
1241 | write.write(0, new_bl); | |
1242 | ASSERT_EQ(0, ioctx.operate("foo", &write)); | |
1243 | ||
1244 | ObjectReadOperation read; | |
1245 | read.read(0, bl.length(), NULL, NULL); | |
1246 | ASSERT_EQ(0, ioctx.operate("foo", &read, &bl)); | |
1247 | ASSERT_EQ(0, memcmp(bl.c_str(), "CEPH", 4)); | |
1248 | } | |
1249 | ||
1250 | TEST_F(LibRadosIoPP, CmpExtMismatchPP) { | |
1251 | bufferlist bl; | |
1252 | bl.append("ceph"); | |
1253 | ObjectWriteOperation write1; | |
1254 | write1.write(0, bl); | |
1255 | ASSERT_EQ(0, ioctx.operate("foo", &write1)); | |
1256 | ||
1257 | bufferlist new_bl; | |
1258 | new_bl.append("CEPH"); | |
1259 | ObjectWriteOperation write2; | |
1260 | write2.cmpext(0, new_bl, nullptr); | |
1261 | write2.write(0, new_bl); | |
1262 | ASSERT_EQ(-MAX_ERRNO, ioctx.operate("foo", &write2)); | |
1263 | ||
1264 | ObjectReadOperation read; | |
1265 | read.read(0, bl.length(), NULL, NULL); | |
1266 | ASSERT_EQ(0, ioctx.operate("foo", &read, &bl)); | |
1267 | ASSERT_EQ(0, memcmp(bl.c_str(), "ceph", 4)); | |
1268 | } | |
1269 | ||
1270 | TEST_F(LibRadosIoECPP, CmpExtPP) { | |
1271 | bufferlist bl; | |
1272 | bl.append("ceph"); | |
1273 | ObjectWriteOperation write1; | |
1274 | write1.write(0, bl); | |
1275 | ASSERT_EQ(0, ioctx.operate("foo", &write1)); | |
1276 | ||
1277 | bufferlist new_bl; | |
1278 | new_bl.append("CEPH"); | |
1279 | ObjectWriteOperation write2; | |
1280 | write2.cmpext(0, bl, nullptr); | |
1281 | write2.write_full(new_bl); | |
1282 | ASSERT_EQ(0, ioctx.operate("foo", &write2)); | |
1283 | ||
1284 | ObjectReadOperation read; | |
1285 | read.read(0, bl.length(), NULL, NULL); | |
1286 | ASSERT_EQ(0, ioctx.operate("foo", &read, &bl)); | |
1287 | ASSERT_EQ(0, memcmp(bl.c_str(), "CEPH", 4)); | |
1288 | } | |
1289 | ||
1290 | TEST_F(LibRadosIoECPP, CmpExtDNEPP) { | |
1291 | bufferlist bl; | |
1292 | bl.append(std::string(4, '\0')); | |
1293 | ||
1294 | bufferlist new_bl; | |
1295 | new_bl.append("CEPH"); | |
1296 | ObjectWriteOperation write; | |
1297 | write.cmpext(0, bl, nullptr); | |
1298 | write.write_full(new_bl); | |
1299 | ASSERT_EQ(0, ioctx.operate("foo", &write)); | |
1300 | ||
1301 | ObjectReadOperation read; | |
1302 | read.read(0, bl.length(), NULL, NULL); | |
1303 | ASSERT_EQ(0, ioctx.operate("foo", &read, &bl)); | |
1304 | ASSERT_EQ(0, memcmp(bl.c_str(), "CEPH", 4)); | |
1305 | } | |
1306 | ||
1307 | TEST_F(LibRadosIoECPP, CmpExtMismatchPP) { | |
1308 | bufferlist bl; | |
1309 | bl.append("ceph"); | |
1310 | ObjectWriteOperation write1; | |
1311 | write1.write(0, bl); | |
1312 | ASSERT_EQ(0, ioctx.operate("foo", &write1)); | |
1313 | ||
1314 | bufferlist new_bl; | |
1315 | new_bl.append("CEPH"); | |
1316 | ObjectWriteOperation write2; | |
1317 | write2.cmpext(0, new_bl, nullptr); | |
1318 | write2.write_full(new_bl); | |
1319 | ASSERT_EQ(-MAX_ERRNO, ioctx.operate("foo", &write2)); | |
1320 | ||
1321 | ObjectReadOperation read; | |
1322 | read.read(0, bl.length(), NULL, NULL); | |
1323 | ASSERT_EQ(0, ioctx.operate("foo", &read, &bl)); | |
1324 | ASSERT_EQ(0, memcmp(bl.c_str(), "ceph", 4)); | |
1325 | } |