1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*
2 // vim: ts=8 sw=2 smarttab
7 #include "gtest/gtest.h"
9 #include "include/rados/librados.hpp"
10 #include "include/encoding.h"
11 #include "include/err.h"
12 #include "include/scope_guard.h"
13 #include "test/librados/test_cxx.h"
14 #include "test/librados/testcase_cxx.h"
16 #include "crimson_utils.h"
18 using namespace librados
;
21 typedef RadosTestPP LibRadosIoPP
;
22 typedef RadosTestECPP LibRadosIoECPP
;
24 TEST_F(LibRadosIoPP
, TooBigPP
) {
27 ASSERT_EQ(-E2BIG
, ioctx
.write("foo", bl
, UINT_MAX
, 0));
28 ASSERT_EQ(-E2BIG
, ioctx
.append("foo", bl
, UINT_MAX
));
29 // ioctx.write_full no way to overflow bl.length()
30 ASSERT_EQ(-E2BIG
, ioctx
.writesame("foo", bl
, UINT_MAX
, 0));
33 TEST_F(LibRadosIoPP
, SimpleWritePP
) {
35 memset(buf
, 0xcc, sizeof(buf
));
37 bl
.append(buf
, sizeof(buf
));
38 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
39 ioctx
.set_namespace("nspace");
40 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
43 TEST_F(LibRadosIoPP
, ReadOpPP
) {
45 memset(buf
, 0xcc, sizeof(buf
));
47 bl
.append(buf
, sizeof(buf
));
48 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
52 ObjectReadOperation op
;
53 op
.read(0, sizeof(buf
), NULL
, NULL
);
54 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
55 ASSERT_EQ(sizeof(buf
), op_bl
.length());
56 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
61 ObjectReadOperation op
;
62 op
.read(0, 0, NULL
, NULL
); //len=0 mean read the whole object data.
63 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
64 ASSERT_EQ(sizeof(buf
), op_bl
.length());
65 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
69 bufferlist read_bl
, op_bl
;
70 ObjectReadOperation op
;
71 op
.read(0, sizeof(buf
), &read_bl
, NULL
);
72 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
73 ASSERT_EQ(sizeof(buf
), read_bl
.length());
74 ASSERT_EQ(sizeof(buf
), op_bl
.length());
75 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
76 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
82 ObjectReadOperation op
;
83 op
.read(0, sizeof(buf
), NULL
, &rval
);
84 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
85 ASSERT_EQ(sizeof(buf
), op_bl
.length());
87 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
91 bufferlist read_bl
, op_bl
;
93 ObjectReadOperation op
;
94 op
.read(0, sizeof(buf
), &read_bl
, &rval
);
95 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
96 ASSERT_EQ(sizeof(buf
), read_bl
.length());
97 ASSERT_EQ(sizeof(buf
), op_bl
.length());
99 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
100 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
104 bufferlist read_bl1
, read_bl2
, op_bl
;
105 int rval1
= 1000, rval2
= 1002;
106 ObjectReadOperation op
;
107 op
.read(0, sizeof(buf
), &read_bl1
, &rval1
);
108 op
.read(0, sizeof(buf
), &read_bl2
, &rval2
);
109 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
110 ASSERT_EQ(sizeof(buf
), read_bl1
.length());
111 ASSERT_EQ(sizeof(buf
), read_bl2
.length());
112 ASSERT_EQ(sizeof(buf
) * 2, op_bl
.length());
115 ASSERT_EQ(0, memcmp(read_bl1
.c_str(), buf
, sizeof(buf
)));
116 ASSERT_EQ(0, memcmp(read_bl2
.c_str(), buf
, sizeof(buf
)));
117 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
118 ASSERT_EQ(0, memcmp(op_bl
.c_str() + sizeof(buf
), buf
, sizeof(buf
)));
123 ObjectReadOperation op
;
124 op
.read(0, sizeof(buf
), NULL
, NULL
);
125 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
126 ASSERT_EQ(sizeof(buf
), op_bl
.length());
127 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
132 ObjectReadOperation op
;
133 op
.read(0, sizeof(buf
), &read_bl
, NULL
);
134 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
135 ASSERT_EQ(sizeof(buf
), read_bl
.length());
136 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
141 ObjectReadOperation op
;
142 op
.read(0, sizeof(buf
), NULL
, &rval
);
143 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
150 ObjectReadOperation op
;
151 op
.read(0, sizeof(buf
), &read_bl
, &rval
);
152 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
153 ASSERT_EQ(sizeof(buf
), read_bl
.length());
155 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
159 bufferlist read_bl1
, read_bl2
;
160 int rval1
= 1000, rval2
= 1002;
161 ObjectReadOperation op
;
162 op
.read(0, sizeof(buf
), &read_bl1
, &rval1
);
163 op
.read(0, sizeof(buf
), &read_bl2
, &rval2
);
164 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
165 ASSERT_EQ(sizeof(buf
), read_bl1
.length());
166 ASSERT_EQ(sizeof(buf
), read_bl2
.length());
169 ASSERT_EQ(0, memcmp(read_bl1
.c_str(), buf
, sizeof(buf
)));
170 ASSERT_EQ(0, memcmp(read_bl2
.c_str(), buf
, sizeof(buf
)));
173 // read into a preallocated buffer with a cached crc
176 op_bl
.append(std::string(sizeof(buf
), 'x'));
177 ASSERT_NE(op_bl
.crc32c(0), bl
.crc32c(0)); // cache 'x' crc
179 ObjectReadOperation op
;
180 op
.read(0, sizeof(buf
), NULL
, NULL
);
181 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
183 ASSERT_EQ(sizeof(buf
), op_bl
.length());
184 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
185 ASSERT_EQ(op_bl
.crc32c(0), bl
.crc32c(0));
189 TEST_F(LibRadosIoPP
, SparseReadOpPP
) {
191 memset(buf
, 0xcc, sizeof(buf
));
193 bl
.append(buf
, sizeof(buf
));
194 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
197 std::map
<uint64_t, uint64_t> extents
;
200 ObjectReadOperation op
;
201 op
.sparse_read(0, sizeof(buf
), &extents
, &read_bl
, &rval
);
202 ASSERT_EQ(0, ioctx
.operate("foo", &op
, nullptr));
204 assert_eq_sparse(bl
, extents
, read_bl
);
208 bl
.append(buf
, sizeof(buf
) / 2);
210 std::map
<uint64_t, uint64_t> extents
;
213 ObjectReadOperation op
;
214 op
.sparse_read(0, sizeof(buf
), &extents
, &read_bl
, &rval
, sizeof(buf
) / 2, 1);
215 ASSERT_EQ(0, ioctx
.operate("foo", &op
, nullptr));
217 assert_eq_sparse(bl
, extents
, read_bl
);
221 TEST_F(LibRadosIoPP
, RoundTripPP
) {
224 memset(buf
, 0xcc, sizeof(buf
));
226 bl
.append(buf
, sizeof(buf
));
227 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
229 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", cl
, sizeof(buf
), 0));
230 ASSERT_EQ(0, memcmp(buf
, cl
.c_str(), sizeof(buf
)));
233 TEST_F(LibRadosIoPP
, RoundTripPP2
)
237 ObjectWriteOperation write
;
239 write
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
240 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
242 ObjectReadOperation read
;
243 read
.read(0, bl
.length(), NULL
, NULL
);
244 read
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
245 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
246 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));
249 TEST_F(LibRadosIoPP
, Checksum
) {
252 memset(buf
, 0xcc, sizeof(buf
));
254 bl
.append(buf
, sizeof(buf
));
255 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
256 bufferlist init_value_bl
;
257 encode(static_cast<uint32_t>(-1), init_value_bl
);
259 ASSERT_EQ(0, ioctx
.checksum("foo", LIBRADOS_CHECKSUM_TYPE_CRC32C
,
260 init_value_bl
, sizeof(buf
), 0, 0, &csum_bl
));
261 auto csum_bl_it
= csum_bl
.cbegin();
263 decode(csum_count
, csum_bl_it
);
264 ASSERT_EQ(1U, csum_count
);
266 decode(csum
, csum_bl_it
);
267 ASSERT_EQ(bl
.crc32c(-1), csum
);
270 TEST_F(LibRadosIoPP
, ReadIntoBufferlist
) {
272 // here we test reading into a non-empty bufferlist referencing existing
277 memset(buf
, 0xcc, sizeof(buf
));
279 bl
.append(buf
, sizeof(buf
));
280 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
282 char buf2
[sizeof(buf
)];
283 memset(buf2
, 0xbb, sizeof(buf2
));
284 bl2
.append(buffer::create_static(sizeof(buf2
), buf2
));
285 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", bl2
, sizeof(buf
), 0));
286 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
287 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
290 TEST_F(LibRadosIoPP
, OverlappingWriteRoundTripPP
) {
293 memset(buf
, 0xcc, sizeof(buf
));
295 bl1
.append(buf
, sizeof(buf
));
296 ASSERT_EQ(0, ioctx
.write("foo", bl1
, sizeof(buf
), 0));
297 memset(buf2
, 0xdd, sizeof(buf2
));
299 bl2
.append(buf2
, sizeof(buf2
));
300 ASSERT_EQ(0, ioctx
.write("foo", bl2
, sizeof(buf2
), 0));
302 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", bl3
, sizeof(buf
), 0));
303 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
304 ASSERT_EQ(0, memcmp(bl3
.c_str() + sizeof(buf2
), buf
, sizeof(buf
) - sizeof(buf2
)));
307 TEST_F(LibRadosIoPP
, WriteFullRoundTripPP
) {
310 memset(buf
, 0xcc, sizeof(buf
));
312 bl1
.append(buf
, sizeof(buf
));
313 ASSERT_EQ(0, ioctx
.write("foo", bl1
, sizeof(buf
), 0));
314 memset(buf2
, 0xdd, sizeof(buf2
));
316 bl2
.append(buf2
, sizeof(buf2
));
317 ASSERT_EQ(0, ioctx
.write_full("foo", bl2
));
319 ASSERT_EQ((int)sizeof(buf2
), ioctx
.read("foo", bl3
, sizeof(buf
), 0));
320 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
323 TEST_F(LibRadosIoPP
, WriteFullRoundTripPP2
)
327 ObjectWriteOperation write
;
328 write
.write_full(bl
);
329 write
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE
);
330 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
332 ObjectReadOperation read
;
333 read
.read(0, bl
.length(), NULL
, NULL
);
334 read
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
335 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
336 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));
339 TEST_F(LibRadosIoPP
, AppendRoundTripPP
) {
342 memset(buf
, 0xde, sizeof(buf
));
344 bl1
.append(buf
, sizeof(buf
));
345 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
346 memset(buf2
, 0xad, sizeof(buf2
));
348 bl2
.append(buf2
, sizeof(buf2
));
349 ASSERT_EQ(0, ioctx
.append("foo", bl2
, sizeof(buf2
)));
351 ASSERT_EQ((int)(sizeof(buf
) + sizeof(buf2
)),
352 ioctx
.read("foo", bl3
, (sizeof(buf
) + sizeof(buf2
)), 0));
353 const char *bl3_str
= bl3
.c_str();
354 ASSERT_EQ(0, memcmp(bl3_str
, buf
, sizeof(buf
)));
355 ASSERT_EQ(0, memcmp(bl3_str
+ sizeof(buf
), buf2
, sizeof(buf2
)));
358 TEST_F(LibRadosIoPP
, TruncTestPP
) {
360 memset(buf
, 0xaa, sizeof(buf
));
362 bl
.append(buf
, sizeof(buf
));
363 ASSERT_EQ(0, ioctx
.append("foo", bl
, sizeof(buf
)));
364 ASSERT_EQ(0, ioctx
.trunc("foo", sizeof(buf
) / 2));
366 ASSERT_EQ((int)(sizeof(buf
)/2), ioctx
.read("foo", bl2
, sizeof(buf
), 0));
367 ASSERT_EQ(0, memcmp(bl2
.c_str(), buf
, sizeof(buf
)/2));
370 TEST_F(LibRadosIoPP
, RemoveTestPP
) {
372 memset(buf
, 0xaa, sizeof(buf
));
374 bl1
.append(buf
, sizeof(buf
));
375 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
376 ASSERT_EQ(0, ioctx
.remove("foo"));
378 ASSERT_EQ(-ENOENT
, ioctx
.read("foo", bl2
, sizeof(buf
), 0));
381 TEST_F(LibRadosIoPP
, XattrsRoundTripPP
) {
383 char attr1
[] = "attr1";
384 char attr1_buf
[] = "foo bar baz";
385 memset(buf
, 0xaa, sizeof(buf
));
387 bl1
.append(buf
, sizeof(buf
));
388 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
390 ASSERT_EQ(-ENODATA
, ioctx
.getxattr("foo", attr1
, bl2
));
392 bl3
.append(attr1_buf
, sizeof(attr1_buf
));
393 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl3
));
395 ASSERT_EQ((int)sizeof(attr1_buf
),
396 ioctx
.getxattr("foo", attr1
, bl4
));
397 ASSERT_EQ(0, memcmp(bl4
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
400 TEST_F(LibRadosIoPP
, RmXattrPP
) {
402 char attr1
[] = "attr1";
403 char attr1_buf
[] = "foo bar baz";
404 memset(buf
, 0xaa, sizeof(buf
));
406 bl1
.append(buf
, sizeof(buf
));
407 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
409 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
410 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl2
));
411 ASSERT_EQ(0, ioctx
.rmxattr("foo", attr1
));
413 ASSERT_EQ(-ENODATA
, ioctx
.getxattr("foo", attr1
, bl3
));
415 // Test rmxattr on a removed object
417 char attr2
[] = "attr2";
418 char attr2_buf
[] = "foo bar baz";
419 memset(buf2
, 0xbb, sizeof(buf2
));
421 bl21
.append(buf
, sizeof(buf
));
422 ASSERT_EQ(0, ioctx
.write("foo_rmxattr", bl21
, sizeof(buf2
), 0));
424 bl22
.append(attr2_buf
, sizeof(attr2_buf
));
425 ASSERT_EQ(0, ioctx
.setxattr("foo_rmxattr", attr2
, bl22
));
426 ASSERT_EQ(0, ioctx
.remove("foo_rmxattr"));
427 ASSERT_EQ(-ENOENT
, ioctx
.rmxattr("foo_rmxattr", attr2
));
430 TEST_F(LibRadosIoPP
, XattrListPP
) {
432 char attr1
[] = "attr1";
433 char attr1_buf
[] = "foo bar baz";
434 char attr2
[] = "attr2";
436 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
437 attr2_buf
[j
] = j
% 0xff;
439 memset(buf
, 0xaa, sizeof(buf
));
441 bl1
.append(buf
, sizeof(buf
));
442 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
444 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
445 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl2
));
447 bl3
.append(attr2_buf
, sizeof(attr2_buf
));
448 ASSERT_EQ(0, ioctx
.setxattr("foo", attr2
, bl3
));
449 std::map
<std::string
, bufferlist
> attrset
;
450 ASSERT_EQ(0, ioctx
.getxattrs("foo", attrset
));
451 for (std::map
<std::string
, bufferlist
>::iterator i
= attrset
.begin();
452 i
!= attrset
.end(); ++i
) {
453 if (i
->first
== string(attr1
)) {
454 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
456 else if (i
->first
== string(attr2
)) {
457 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr2_buf
, sizeof(attr2_buf
)));
465 TEST_F(LibRadosIoECPP
, SimpleWritePP
) {
468 memset(buf
, 0xcc, sizeof(buf
));
470 bl
.append(buf
, sizeof(buf
));
471 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
472 ioctx
.set_namespace("nspace");
473 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
476 TEST_F(LibRadosIoECPP
, ReadOpPP
) {
479 memset(buf
, 0xcc, sizeof(buf
));
481 bl
.append(buf
, sizeof(buf
));
482 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
486 ObjectReadOperation op
;
487 op
.read(0, sizeof(buf
), NULL
, NULL
);
488 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
489 ASSERT_EQ(sizeof(buf
), op_bl
.length());
490 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
495 ObjectReadOperation op
;
496 op
.read(0, 0, NULL
, NULL
); //len=0 mean read the whole object data
497 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
498 ASSERT_EQ(sizeof(buf
), op_bl
.length());
499 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
503 bufferlist read_bl
, op_bl
;
504 ObjectReadOperation op
;
505 op
.read(0, sizeof(buf
), &read_bl
, NULL
);
506 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
507 ASSERT_EQ(sizeof(buf
), read_bl
.length());
508 ASSERT_EQ(sizeof(buf
), op_bl
.length());
509 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
510 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
516 ObjectReadOperation op
;
517 op
.read(0, sizeof(buf
), NULL
, &rval
);
518 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
519 ASSERT_EQ(sizeof(buf
), op_bl
.length());
521 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
525 bufferlist read_bl
, op_bl
;
527 ObjectReadOperation op
;
528 op
.read(0, sizeof(buf
), &read_bl
, &rval
);
529 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
530 ASSERT_EQ(sizeof(buf
), read_bl
.length());
531 ASSERT_EQ(sizeof(buf
), op_bl
.length());
533 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
534 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
538 bufferlist read_bl1
, read_bl2
, op_bl
;
539 int rval1
= 1000, rval2
= 1002;
540 ObjectReadOperation op
;
541 op
.read(0, sizeof(buf
), &read_bl1
, &rval1
);
542 op
.read(0, sizeof(buf
), &read_bl2
, &rval2
);
543 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
544 ASSERT_EQ(sizeof(buf
), read_bl1
.length());
545 ASSERT_EQ(sizeof(buf
), read_bl2
.length());
546 ASSERT_EQ(sizeof(buf
) * 2, op_bl
.length());
549 ASSERT_EQ(0, memcmp(read_bl1
.c_str(), buf
, sizeof(buf
)));
550 ASSERT_EQ(0, memcmp(read_bl2
.c_str(), buf
, sizeof(buf
)));
551 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
552 ASSERT_EQ(0, memcmp(op_bl
.c_str() + sizeof(buf
), buf
, sizeof(buf
)));
557 ObjectReadOperation op
;
558 op
.read(0, sizeof(buf
), NULL
, NULL
);
559 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
560 ASSERT_EQ(sizeof(buf
), op_bl
.length());
561 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
566 ObjectReadOperation op
;
567 op
.read(0, sizeof(buf
), &read_bl
, NULL
);
568 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
569 ASSERT_EQ(sizeof(buf
), read_bl
.length());
570 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
575 ObjectReadOperation op
;
576 op
.read(0, sizeof(buf
), NULL
, &rval
);
577 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
584 ObjectReadOperation op
;
585 op
.read(0, sizeof(buf
), &read_bl
, &rval
);
586 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
587 ASSERT_EQ(sizeof(buf
), read_bl
.length());
589 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
593 bufferlist read_bl1
, read_bl2
;
594 int rval1
= 1000, rval2
= 1002;
595 ObjectReadOperation op
;
596 op
.read(0, sizeof(buf
), &read_bl1
, &rval1
);
597 op
.read(0, sizeof(buf
), &read_bl2
, &rval2
);
598 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
599 ASSERT_EQ(sizeof(buf
), read_bl1
.length());
600 ASSERT_EQ(sizeof(buf
), read_bl2
.length());
603 ASSERT_EQ(0, memcmp(read_bl1
.c_str(), buf
, sizeof(buf
)));
604 ASSERT_EQ(0, memcmp(read_bl2
.c_str(), buf
, sizeof(buf
)));
607 // read into a preallocated buffer with a cached crc
610 op_bl
.append(std::string(sizeof(buf
), 'x'));
611 ASSERT_NE(op_bl
.crc32c(0), bl
.crc32c(0)); // cache 'x' crc
613 ObjectReadOperation op
;
614 op
.read(0, sizeof(buf
), NULL
, NULL
);
615 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
617 ASSERT_EQ(sizeof(buf
), op_bl
.length());
618 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
619 ASSERT_EQ(op_bl
.crc32c(0), bl
.crc32c(0));
623 TEST_F(LibRadosIoECPP
, SparseReadOpPP
) {
626 memset(buf
, 0xcc, sizeof(buf
));
628 bl
.append(buf
, sizeof(buf
));
629 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
632 std::map
<uint64_t, uint64_t> extents
;
635 ObjectReadOperation op
;
636 op
.sparse_read(0, sizeof(buf
), &extents
, &read_bl
, &rval
);
637 ASSERT_EQ(0, ioctx
.operate("foo", &op
, nullptr));
639 assert_eq_sparse(bl
, extents
, read_bl
);
643 TEST_F(LibRadosIoECPP
, RoundTripPP
) {
647 memset(buf
, 0xcc, sizeof(buf
));
649 bl
.append(buf
, sizeof(buf
));
650 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
652 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", cl
, sizeof(buf
) * 3, 0));
653 ASSERT_EQ(0, memcmp(buf
, cl
.c_str(), sizeof(buf
)));
656 TEST_F(LibRadosIoECPP
, RoundTripPP2
)
661 ObjectWriteOperation write
;
663 write
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
664 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
666 ObjectReadOperation read
;
667 read
.read(0, bl
.length(), NULL
, NULL
);
668 read
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
669 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
670 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));
673 TEST_F(LibRadosIoECPP
, OverlappingWriteRoundTripPP
) {
675 int bsize
= alignment
;
676 int dbsize
= bsize
* 2;
677 char *buf
= (char *)new char[dbsize
];
678 char *buf2
= (char *)new char[bsize
];
683 scope_guard
<decltype(cleanup
)> sg(std::move(cleanup
));
684 memset(buf
, 0xcc, dbsize
);
686 bl1
.append(buf
, dbsize
);
687 ASSERT_EQ(0, ioctx
.write("foo", bl1
, dbsize
, 0));
688 memset(buf2
, 0xdd, bsize
);
690 bl2
.append(buf2
, bsize
);
691 ASSERT_EQ(-EOPNOTSUPP
, ioctx
.write("foo", bl2
, bsize
, 0));
693 ASSERT_EQ(dbsize
, ioctx
.read("foo", bl3
, dbsize
, 0));
694 // Read the same as first write
695 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, dbsize
));
698 TEST_F(LibRadosIoECPP
, WriteFullRoundTripPP
) {
702 memset(buf
, 0xcc, sizeof(buf
));
704 bl1
.append(buf
, sizeof(buf
));
705 ASSERT_EQ(0, ioctx
.write("foo", bl1
, sizeof(buf
), 0));
706 memset(buf2
, 0xdd, sizeof(buf2
));
708 bl2
.append(buf2
, sizeof(buf2
));
709 ASSERT_EQ(0, ioctx
.write_full("foo", bl2
));
711 ASSERT_EQ((int)sizeof(buf2
), ioctx
.read("foo", bl3
, sizeof(buf
), 0));
712 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
715 TEST_F(LibRadosIoECPP
, WriteFullRoundTripPP2
)
720 ObjectWriteOperation write
;
721 write
.write_full(bl
);
722 write
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
723 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
725 ObjectReadOperation read
;
726 read
.read(0, bl
.length(), NULL
, NULL
);
727 read
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
728 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
729 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));
732 TEST_F(LibRadosIoECPP
, AppendRoundTripPP
) {
734 char *buf
= (char *)new char[alignment
];
735 char *buf2
= (char *)new char[alignment
];
740 scope_guard
<decltype(cleanup
)> sg(std::move(cleanup
));
741 memset(buf
, 0xde, alignment
);
743 bl1
.append(buf
, alignment
);
744 ASSERT_EQ(0, ioctx
.append("foo", bl1
, alignment
));
745 memset(buf2
, 0xad, alignment
);
747 bl2
.append(buf2
, alignment
);
748 ASSERT_EQ(0, ioctx
.append("foo", bl2
, alignment
));
750 ASSERT_EQ((int)(alignment
* 2),
751 ioctx
.read("foo", bl3
, (alignment
* 4), 0));
752 const char *bl3_str
= bl3
.c_str();
753 ASSERT_EQ(0, memcmp(bl3_str
, buf
, alignment
));
754 ASSERT_EQ(0, memcmp(bl3_str
+ alignment
, buf2
, alignment
));
757 TEST_F(LibRadosIoECPP
, TruncTestPP
) {
760 memset(buf
, 0xaa, sizeof(buf
));
762 bl
.append(buf
, sizeof(buf
));
763 ASSERT_EQ(0, ioctx
.append("foo", bl
, sizeof(buf
)));
764 ASSERT_EQ(-EOPNOTSUPP
, ioctx
.trunc("foo", sizeof(buf
) / 2));
767 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", bl2
, sizeof(buf
), 0));
769 ASSERT_EQ(0, memcmp(bl2
.c_str(), buf
, sizeof(buf
)));
772 TEST_F(LibRadosIoECPP
, RemoveTestPP
) {
775 memset(buf
, 0xaa, sizeof(buf
));
777 bl1
.append(buf
, sizeof(buf
));
778 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
779 ASSERT_EQ(0, ioctx
.remove("foo"));
781 ASSERT_EQ(-ENOENT
, ioctx
.read("foo", bl2
, sizeof(buf
), 0));
784 TEST_F(LibRadosIoECPP
, XattrsRoundTripPP
) {
787 char attr1
[] = "attr1";
788 char attr1_buf
[] = "foo bar baz";
789 memset(buf
, 0xaa, sizeof(buf
));
791 bl1
.append(buf
, sizeof(buf
));
792 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
794 ASSERT_EQ(-ENODATA
, ioctx
.getxattr("foo", attr1
, bl2
));
796 bl3
.append(attr1_buf
, sizeof(attr1_buf
));
797 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl3
));
799 ASSERT_EQ((int)sizeof(attr1_buf
),
800 ioctx
.getxattr("foo", attr1
, bl4
));
801 ASSERT_EQ(0, memcmp(bl4
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
804 TEST_F(LibRadosIoECPP
, RmXattrPP
) {
807 char attr1
[] = "attr1";
808 char attr1_buf
[] = "foo bar baz";
809 memset(buf
, 0xaa, sizeof(buf
));
811 bl1
.append(buf
, sizeof(buf
));
812 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
814 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
815 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl2
));
816 ASSERT_EQ(0, ioctx
.rmxattr("foo", attr1
));
818 ASSERT_EQ(-ENODATA
, ioctx
.getxattr("foo", attr1
, bl3
));
820 // Test rmxattr on a removed object
822 char attr2
[] = "attr2";
823 char attr2_buf
[] = "foo bar baz";
824 memset(buf2
, 0xbb, sizeof(buf2
));
826 bl21
.append(buf
, sizeof(buf
));
827 ASSERT_EQ(0, ioctx
.write("foo_rmxattr", bl21
, sizeof(buf2
), 0));
829 bl22
.append(attr2_buf
, sizeof(attr2_buf
));
830 ASSERT_EQ(0, ioctx
.setxattr("foo_rmxattr", attr2
, bl22
));
831 ASSERT_EQ(0, ioctx
.remove("foo_rmxattr"));
832 ASSERT_EQ(-ENOENT
, ioctx
.rmxattr("foo_rmxattr", attr2
));
835 TEST_F(LibRadosIoECPP
, XattrListPP
) {
838 char attr1
[] = "attr1";
839 char attr1_buf
[] = "foo bar baz";
840 char attr2
[] = "attr2";
842 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
843 attr2_buf
[j
] = j
% 0xff;
845 memset(buf
, 0xaa, sizeof(buf
));
847 bl1
.append(buf
, sizeof(buf
));
848 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
850 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
851 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl2
));
853 bl3
.append(attr2_buf
, sizeof(attr2_buf
));
854 ASSERT_EQ(0, ioctx
.setxattr("foo", attr2
, bl3
));
855 std::map
<std::string
, bufferlist
> attrset
;
856 ASSERT_EQ(0, ioctx
.getxattrs("foo", attrset
));
857 for (std::map
<std::string
, bufferlist
>::iterator i
= attrset
.begin();
858 i
!= attrset
.end(); ++i
) {
859 if (i
->first
== string(attr1
)) {
860 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
862 else if (i
->first
== string(attr2
)) {
863 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr2_buf
, sizeof(attr2_buf
)));
871 TEST_F(LibRadosIoPP
, CmpExtPP
) {
874 ObjectWriteOperation write1
;
876 ASSERT_EQ(0, ioctx
.operate("foo", &write1
));
879 new_bl
.append("CEPH");
880 ObjectWriteOperation write2
;
881 write2
.cmpext(0, bl
, nullptr);
882 write2
.write(0, new_bl
);
883 ASSERT_EQ(0, ioctx
.operate("foo", &write2
));
885 ObjectReadOperation read
;
886 read
.read(0, bl
.length(), NULL
, NULL
);
887 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
888 ASSERT_EQ(0, memcmp(bl
.c_str(), "CEPH", 4));
891 TEST_F(LibRadosIoPP
, CmpExtDNEPP
) {
893 bl
.append(std::string(4, '\0'));
896 new_bl
.append("CEPH");
897 ObjectWriteOperation write
;
898 write
.cmpext(0, bl
, nullptr);
899 write
.write(0, new_bl
);
900 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
902 ObjectReadOperation read
;
903 read
.read(0, bl
.length(), NULL
, NULL
);
904 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
905 ASSERT_EQ(0, memcmp(bl
.c_str(), "CEPH", 4));
908 TEST_F(LibRadosIoPP
, CmpExtMismatchPP
) {
911 ObjectWriteOperation write1
;
913 ASSERT_EQ(0, ioctx
.operate("foo", &write1
));
916 new_bl
.append("CEPH");
917 ObjectWriteOperation write2
;
918 write2
.cmpext(0, new_bl
, nullptr);
919 write2
.write(0, new_bl
);
920 ASSERT_EQ(-MAX_ERRNO
, ioctx
.operate("foo", &write2
));
922 ObjectReadOperation read
;
923 read
.read(0, bl
.length(), NULL
, NULL
);
924 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
925 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));
928 TEST_F(LibRadosIoECPP
, CmpExtPP
) {
932 ObjectWriteOperation write1
;
934 ASSERT_EQ(0, ioctx
.operate("foo", &write1
));
937 new_bl
.append("CEPH");
938 ObjectWriteOperation write2
;
939 write2
.cmpext(0, bl
, nullptr);
940 write2
.write_full(new_bl
);
941 ASSERT_EQ(0, ioctx
.operate("foo", &write2
));
943 ObjectReadOperation read
;
944 read
.read(0, bl
.length(), NULL
, NULL
);
945 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
946 ASSERT_EQ(0, memcmp(bl
.c_str(), "CEPH", 4));
949 TEST_F(LibRadosIoECPP
, CmpExtDNEPP
) {
952 bl
.append(std::string(4, '\0'));
955 new_bl
.append("CEPH");
956 ObjectWriteOperation write
;
957 write
.cmpext(0, bl
, nullptr);
958 write
.write_full(new_bl
);
959 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
961 ObjectReadOperation read
;
962 read
.read(0, bl
.length(), NULL
, NULL
);
963 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
964 ASSERT_EQ(0, memcmp(bl
.c_str(), "CEPH", 4));
967 TEST_F(LibRadosIoECPP
, CmpExtMismatchPP
) {
971 ObjectWriteOperation write1
;
973 ASSERT_EQ(0, ioctx
.operate("foo", &write1
));
976 new_bl
.append("CEPH");
977 ObjectWriteOperation write2
;
978 write2
.cmpext(0, new_bl
, nullptr);
979 write2
.write_full(new_bl
);
980 ASSERT_EQ(-MAX_ERRNO
, ioctx
.operate("foo", &write2
));
982 ObjectReadOperation read
;
983 read
.read(0, bl
.length(), NULL
, NULL
);
984 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
985 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));