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 using namespace librados
;
19 typedef RadosTestPP LibRadosIoPP
;
20 typedef RadosTestECPP LibRadosIoECPP
;
22 TEST_F(LibRadosIoPP
, TooBigPP
) {
25 ASSERT_EQ(-E2BIG
, ioctx
.write("foo", bl
, UINT_MAX
, 0));
26 ASSERT_EQ(-E2BIG
, ioctx
.append("foo", bl
, UINT_MAX
));
27 // ioctx.write_full no way to overflow bl.length()
28 ASSERT_EQ(-E2BIG
, ioctx
.writesame("foo", bl
, UINT_MAX
, 0));
31 TEST_F(LibRadosIoPP
, SimpleWritePP
) {
33 memset(buf
, 0xcc, sizeof(buf
));
35 bl
.append(buf
, sizeof(buf
));
36 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
37 ioctx
.set_namespace("nspace");
38 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
41 TEST_F(LibRadosIoPP
, ReadOpPP
) {
43 memset(buf
, 0xcc, sizeof(buf
));
45 bl
.append(buf
, sizeof(buf
));
46 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
50 ObjectReadOperation op
;
51 op
.read(0, sizeof(buf
), NULL
, NULL
);
52 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
53 ASSERT_EQ(sizeof(buf
), op_bl
.length());
54 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
59 ObjectReadOperation op
;
60 op
.read(0, 0, NULL
, NULL
); //len=0 mean read the whole object data.
61 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
62 ASSERT_EQ(sizeof(buf
), op_bl
.length());
63 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
67 bufferlist read_bl
, op_bl
;
68 ObjectReadOperation op
;
69 op
.read(0, sizeof(buf
), &read_bl
, NULL
);
70 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
71 ASSERT_EQ(sizeof(buf
), read_bl
.length());
72 ASSERT_EQ(sizeof(buf
), op_bl
.length());
73 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
74 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
80 ObjectReadOperation op
;
81 op
.read(0, sizeof(buf
), NULL
, &rval
);
82 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
83 ASSERT_EQ(sizeof(buf
), op_bl
.length());
85 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
89 bufferlist read_bl
, op_bl
;
91 ObjectReadOperation op
;
92 op
.read(0, sizeof(buf
), &read_bl
, &rval
);
93 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
94 ASSERT_EQ(sizeof(buf
), read_bl
.length());
95 ASSERT_EQ(sizeof(buf
), op_bl
.length());
97 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
98 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
102 bufferlist read_bl1
, read_bl2
, op_bl
;
103 int rval1
= 1000, rval2
= 1002;
104 ObjectReadOperation op
;
105 op
.read(0, sizeof(buf
), &read_bl1
, &rval1
);
106 op
.read(0, sizeof(buf
), &read_bl2
, &rval2
);
107 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
108 ASSERT_EQ(sizeof(buf
), read_bl1
.length());
109 ASSERT_EQ(sizeof(buf
), read_bl2
.length());
110 ASSERT_EQ(sizeof(buf
) * 2, op_bl
.length());
113 ASSERT_EQ(0, memcmp(read_bl1
.c_str(), buf
, sizeof(buf
)));
114 ASSERT_EQ(0, memcmp(read_bl2
.c_str(), buf
, sizeof(buf
)));
115 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
116 ASSERT_EQ(0, memcmp(op_bl
.c_str() + sizeof(buf
), buf
, sizeof(buf
)));
121 ObjectReadOperation op
;
122 op
.read(0, sizeof(buf
), NULL
, NULL
);
123 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
124 ASSERT_EQ(sizeof(buf
), op_bl
.length());
125 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
130 ObjectReadOperation op
;
131 op
.read(0, sizeof(buf
), &read_bl
, NULL
);
132 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
133 ASSERT_EQ(sizeof(buf
), read_bl
.length());
134 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
139 ObjectReadOperation op
;
140 op
.read(0, sizeof(buf
), NULL
, &rval
);
141 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
148 ObjectReadOperation op
;
149 op
.read(0, sizeof(buf
), &read_bl
, &rval
);
150 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
151 ASSERT_EQ(sizeof(buf
), read_bl
.length());
153 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
157 bufferlist read_bl1
, read_bl2
;
158 int rval1
= 1000, rval2
= 1002;
159 ObjectReadOperation op
;
160 op
.read(0, sizeof(buf
), &read_bl1
, &rval1
);
161 op
.read(0, sizeof(buf
), &read_bl2
, &rval2
);
162 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
163 ASSERT_EQ(sizeof(buf
), read_bl1
.length());
164 ASSERT_EQ(sizeof(buf
), read_bl2
.length());
167 ASSERT_EQ(0, memcmp(read_bl1
.c_str(), buf
, sizeof(buf
)));
168 ASSERT_EQ(0, memcmp(read_bl2
.c_str(), buf
, sizeof(buf
)));
171 // read into a preallocated buffer with a cached crc
174 op_bl
.append(std::string(sizeof(buf
), 'x'));
175 ASSERT_NE(op_bl
.crc32c(0), bl
.crc32c(0)); // cache 'x' crc
177 ObjectReadOperation op
;
178 op
.read(0, sizeof(buf
), NULL
, NULL
);
179 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
181 ASSERT_EQ(sizeof(buf
), op_bl
.length());
182 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
183 ASSERT_EQ(op_bl
.crc32c(0), bl
.crc32c(0));
187 TEST_F(LibRadosIoPP
, SparseReadOpPP
) {
189 memset(buf
, 0xcc, sizeof(buf
));
191 bl
.append(buf
, sizeof(buf
));
192 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
195 std::map
<uint64_t, uint64_t> extents
;
198 ObjectReadOperation op
;
199 op
.sparse_read(0, sizeof(buf
), &extents
, &read_bl
, &rval
);
200 ASSERT_EQ(0, ioctx
.operate("foo", &op
, nullptr));
202 assert_eq_sparse(bl
, extents
, read_bl
);
206 bl
.append(buf
, sizeof(buf
) / 2);
208 std::map
<uint64_t, uint64_t> extents
;
211 ObjectReadOperation op
;
212 op
.sparse_read(0, sizeof(buf
), &extents
, &read_bl
, &rval
, sizeof(buf
) / 2, 1);
213 ASSERT_EQ(0, ioctx
.operate("foo", &op
, nullptr));
215 assert_eq_sparse(bl
, extents
, read_bl
);
219 TEST_F(LibRadosIoPP
, RoundTripPP
) {
222 memset(buf
, 0xcc, sizeof(buf
));
224 bl
.append(buf
, sizeof(buf
));
225 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
227 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", cl
, sizeof(buf
), 0));
228 ASSERT_EQ(0, memcmp(buf
, cl
.c_str(), sizeof(buf
)));
231 TEST_F(LibRadosIoPP
, RoundTripPP2
)
235 ObjectWriteOperation write
;
237 write
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
238 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
240 ObjectReadOperation read
;
241 read
.read(0, bl
.length(), NULL
, NULL
);
242 read
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
243 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
244 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));
247 TEST_F(LibRadosIoPP
, Checksum
) {
250 memset(buf
, 0xcc, sizeof(buf
));
252 bl
.append(buf
, sizeof(buf
));
253 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
254 bufferlist init_value_bl
;
255 encode(static_cast<uint32_t>(-1), init_value_bl
);
257 ASSERT_EQ(0, ioctx
.checksum("foo", LIBRADOS_CHECKSUM_TYPE_CRC32C
,
258 init_value_bl
, sizeof(buf
), 0, 0, &csum_bl
));
259 auto csum_bl_it
= csum_bl
.cbegin();
261 decode(csum_count
, csum_bl_it
);
262 ASSERT_EQ(1U, csum_count
);
264 decode(csum
, csum_bl_it
);
265 ASSERT_EQ(bl
.crc32c(-1), csum
);
268 TEST_F(LibRadosIoPP
, ReadIntoBufferlist
) {
270 // here we test reading into a non-empty bufferlist referencing existing
275 memset(buf
, 0xcc, sizeof(buf
));
277 bl
.append(buf
, sizeof(buf
));
278 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
280 char buf2
[sizeof(buf
)];
281 memset(buf2
, 0xbb, sizeof(buf2
));
282 bl2
.append(buffer::create_static(sizeof(buf2
), buf2
));
283 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", bl2
, sizeof(buf
), 0));
284 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
285 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
288 TEST_F(LibRadosIoPP
, OverlappingWriteRoundTripPP
) {
291 memset(buf
, 0xcc, sizeof(buf
));
293 bl1
.append(buf
, sizeof(buf
));
294 ASSERT_EQ(0, ioctx
.write("foo", bl1
, sizeof(buf
), 0));
295 memset(buf2
, 0xdd, sizeof(buf2
));
297 bl2
.append(buf2
, sizeof(buf2
));
298 ASSERT_EQ(0, ioctx
.write("foo", bl2
, sizeof(buf2
), 0));
300 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", bl3
, sizeof(buf
), 0));
301 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
302 ASSERT_EQ(0, memcmp(bl3
.c_str() + sizeof(buf2
), buf
, sizeof(buf
) - sizeof(buf2
)));
305 TEST_F(LibRadosIoPP
, WriteFullRoundTripPP
) {
308 memset(buf
, 0xcc, sizeof(buf
));
310 bl1
.append(buf
, sizeof(buf
));
311 ASSERT_EQ(0, ioctx
.write("foo", bl1
, sizeof(buf
), 0));
312 memset(buf2
, 0xdd, sizeof(buf2
));
314 bl2
.append(buf2
, sizeof(buf2
));
315 ASSERT_EQ(0, ioctx
.write_full("foo", bl2
));
317 ASSERT_EQ((int)sizeof(buf2
), ioctx
.read("foo", bl3
, sizeof(buf
), 0));
318 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
321 TEST_F(LibRadosIoPP
, WriteFullRoundTripPP2
)
325 ObjectWriteOperation write
;
326 write
.write_full(bl
);
327 write
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE
);
328 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
330 ObjectReadOperation read
;
331 read
.read(0, bl
.length(), NULL
, NULL
);
332 read
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
333 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
334 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));
337 TEST_F(LibRadosIoPP
, AppendRoundTripPP
) {
340 memset(buf
, 0xde, sizeof(buf
));
342 bl1
.append(buf
, sizeof(buf
));
343 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
344 memset(buf2
, 0xad, sizeof(buf2
));
346 bl2
.append(buf2
, sizeof(buf2
));
347 ASSERT_EQ(0, ioctx
.append("foo", bl2
, sizeof(buf2
)));
349 ASSERT_EQ((int)(sizeof(buf
) + sizeof(buf2
)),
350 ioctx
.read("foo", bl3
, (sizeof(buf
) + sizeof(buf2
)), 0));
351 const char *bl3_str
= bl3
.c_str();
352 ASSERT_EQ(0, memcmp(bl3_str
, buf
, sizeof(buf
)));
353 ASSERT_EQ(0, memcmp(bl3_str
+ sizeof(buf
), buf2
, sizeof(buf2
)));
356 TEST_F(LibRadosIoPP
, TruncTestPP
) {
358 memset(buf
, 0xaa, sizeof(buf
));
360 bl
.append(buf
, sizeof(buf
));
361 ASSERT_EQ(0, ioctx
.append("foo", bl
, sizeof(buf
)));
362 ASSERT_EQ(0, ioctx
.trunc("foo", sizeof(buf
) / 2));
364 ASSERT_EQ((int)(sizeof(buf
)/2), ioctx
.read("foo", bl2
, sizeof(buf
), 0));
365 ASSERT_EQ(0, memcmp(bl2
.c_str(), buf
, sizeof(buf
)/2));
368 TEST_F(LibRadosIoPP
, RemoveTestPP
) {
370 memset(buf
, 0xaa, sizeof(buf
));
372 bl1
.append(buf
, sizeof(buf
));
373 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
374 ASSERT_EQ(0, ioctx
.remove("foo"));
376 ASSERT_EQ(-ENOENT
, ioctx
.read("foo", bl2
, sizeof(buf
), 0));
379 TEST_F(LibRadosIoPP
, XattrsRoundTripPP
) {
381 char attr1
[] = "attr1";
382 char attr1_buf
[] = "foo bar baz";
383 memset(buf
, 0xaa, sizeof(buf
));
385 bl1
.append(buf
, sizeof(buf
));
386 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
388 ASSERT_EQ(-ENODATA
, ioctx
.getxattr("foo", attr1
, bl2
));
390 bl3
.append(attr1_buf
, sizeof(attr1_buf
));
391 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl3
));
393 ASSERT_EQ((int)sizeof(attr1_buf
),
394 ioctx
.getxattr("foo", attr1
, bl4
));
395 ASSERT_EQ(0, memcmp(bl4
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
398 TEST_F(LibRadosIoPP
, RmXattrPP
) {
400 char attr1
[] = "attr1";
401 char attr1_buf
[] = "foo bar baz";
402 memset(buf
, 0xaa, sizeof(buf
));
404 bl1
.append(buf
, sizeof(buf
));
405 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
407 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
408 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl2
));
409 ASSERT_EQ(0, ioctx
.rmxattr("foo", attr1
));
411 ASSERT_EQ(-ENODATA
, ioctx
.getxattr("foo", attr1
, bl3
));
413 // Test rmxattr on a removed object
415 char attr2
[] = "attr2";
416 char attr2_buf
[] = "foo bar baz";
417 memset(buf2
, 0xbb, sizeof(buf2
));
419 bl21
.append(buf
, sizeof(buf
));
420 ASSERT_EQ(0, ioctx
.write("foo_rmxattr", bl21
, sizeof(buf2
), 0));
422 bl22
.append(attr2_buf
, sizeof(attr2_buf
));
423 ASSERT_EQ(0, ioctx
.setxattr("foo_rmxattr", attr2
, bl22
));
424 ASSERT_EQ(0, ioctx
.remove("foo_rmxattr"));
425 ASSERT_EQ(-ENOENT
, ioctx
.rmxattr("foo_rmxattr", attr2
));
428 TEST_F(LibRadosIoPP
, XattrListPP
) {
430 char attr1
[] = "attr1";
431 char attr1_buf
[] = "foo bar baz";
432 char attr2
[] = "attr2";
434 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
435 attr2_buf
[j
] = j
% 0xff;
437 memset(buf
, 0xaa, sizeof(buf
));
439 bl1
.append(buf
, sizeof(buf
));
440 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
442 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
443 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl2
));
445 bl3
.append(attr2_buf
, sizeof(attr2_buf
));
446 ASSERT_EQ(0, ioctx
.setxattr("foo", attr2
, bl3
));
447 std::map
<std::string
, bufferlist
> attrset
;
448 ASSERT_EQ(0, ioctx
.getxattrs("foo", attrset
));
449 for (std::map
<std::string
, bufferlist
>::iterator i
= attrset
.begin();
450 i
!= attrset
.end(); ++i
) {
451 if (i
->first
== string(attr1
)) {
452 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
454 else if (i
->first
== string(attr2
)) {
455 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr2_buf
, sizeof(attr2_buf
)));
463 TEST_F(LibRadosIoECPP
, SimpleWritePP
) {
465 memset(buf
, 0xcc, sizeof(buf
));
467 bl
.append(buf
, sizeof(buf
));
468 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
469 ioctx
.set_namespace("nspace");
470 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
473 TEST_F(LibRadosIoECPP
, ReadOpPP
) {
475 memset(buf
, 0xcc, sizeof(buf
));
477 bl
.append(buf
, sizeof(buf
));
478 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
482 ObjectReadOperation op
;
483 op
.read(0, sizeof(buf
), NULL
, NULL
);
484 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
485 ASSERT_EQ(sizeof(buf
), op_bl
.length());
486 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
491 ObjectReadOperation op
;
492 op
.read(0, 0, NULL
, NULL
); //len=0 mean read the whole object data
493 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
494 ASSERT_EQ(sizeof(buf
), op_bl
.length());
495 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
499 bufferlist read_bl
, op_bl
;
500 ObjectReadOperation op
;
501 op
.read(0, sizeof(buf
), &read_bl
, NULL
);
502 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
503 ASSERT_EQ(sizeof(buf
), read_bl
.length());
504 ASSERT_EQ(sizeof(buf
), op_bl
.length());
505 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
506 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
512 ObjectReadOperation op
;
513 op
.read(0, sizeof(buf
), NULL
, &rval
);
514 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
515 ASSERT_EQ(sizeof(buf
), op_bl
.length());
517 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
521 bufferlist read_bl
, op_bl
;
523 ObjectReadOperation op
;
524 op
.read(0, sizeof(buf
), &read_bl
, &rval
);
525 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
526 ASSERT_EQ(sizeof(buf
), read_bl
.length());
527 ASSERT_EQ(sizeof(buf
), op_bl
.length());
529 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
530 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
534 bufferlist read_bl1
, read_bl2
, op_bl
;
535 int rval1
= 1000, rval2
= 1002;
536 ObjectReadOperation op
;
537 op
.read(0, sizeof(buf
), &read_bl1
, &rval1
);
538 op
.read(0, sizeof(buf
), &read_bl2
, &rval2
);
539 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
540 ASSERT_EQ(sizeof(buf
), read_bl1
.length());
541 ASSERT_EQ(sizeof(buf
), read_bl2
.length());
542 ASSERT_EQ(sizeof(buf
) * 2, op_bl
.length());
545 ASSERT_EQ(0, memcmp(read_bl1
.c_str(), buf
, sizeof(buf
)));
546 ASSERT_EQ(0, memcmp(read_bl2
.c_str(), buf
, sizeof(buf
)));
547 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
548 ASSERT_EQ(0, memcmp(op_bl
.c_str() + sizeof(buf
), buf
, sizeof(buf
)));
553 ObjectReadOperation op
;
554 op
.read(0, sizeof(buf
), NULL
, NULL
);
555 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
556 ASSERT_EQ(sizeof(buf
), op_bl
.length());
557 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
562 ObjectReadOperation op
;
563 op
.read(0, sizeof(buf
), &read_bl
, NULL
);
564 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
565 ASSERT_EQ(sizeof(buf
), read_bl
.length());
566 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
571 ObjectReadOperation op
;
572 op
.read(0, sizeof(buf
), NULL
, &rval
);
573 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
580 ObjectReadOperation op
;
581 op
.read(0, sizeof(buf
), &read_bl
, &rval
);
582 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
583 ASSERT_EQ(sizeof(buf
), read_bl
.length());
585 ASSERT_EQ(0, memcmp(read_bl
.c_str(), buf
, sizeof(buf
)));
589 bufferlist read_bl1
, read_bl2
;
590 int rval1
= 1000, rval2
= 1002;
591 ObjectReadOperation op
;
592 op
.read(0, sizeof(buf
), &read_bl1
, &rval1
);
593 op
.read(0, sizeof(buf
), &read_bl2
, &rval2
);
594 ASSERT_EQ(0, ioctx
.operate("foo", &op
, NULL
));
595 ASSERT_EQ(sizeof(buf
), read_bl1
.length());
596 ASSERT_EQ(sizeof(buf
), read_bl2
.length());
599 ASSERT_EQ(0, memcmp(read_bl1
.c_str(), buf
, sizeof(buf
)));
600 ASSERT_EQ(0, memcmp(read_bl2
.c_str(), buf
, sizeof(buf
)));
603 // read into a preallocated buffer with a cached crc
606 op_bl
.append(std::string(sizeof(buf
), 'x'));
607 ASSERT_NE(op_bl
.crc32c(0), bl
.crc32c(0)); // cache 'x' crc
609 ObjectReadOperation op
;
610 op
.read(0, sizeof(buf
), NULL
, NULL
);
611 ASSERT_EQ(0, ioctx
.operate("foo", &op
, &op_bl
));
613 ASSERT_EQ(sizeof(buf
), op_bl
.length());
614 ASSERT_EQ(0, memcmp(op_bl
.c_str(), buf
, sizeof(buf
)));
615 ASSERT_EQ(op_bl
.crc32c(0), bl
.crc32c(0));
619 TEST_F(LibRadosIoECPP
, SparseReadOpPP
) {
621 memset(buf
, 0xcc, sizeof(buf
));
623 bl
.append(buf
, sizeof(buf
));
624 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
627 std::map
<uint64_t, uint64_t> extents
;
630 ObjectReadOperation op
;
631 op
.sparse_read(0, sizeof(buf
), &extents
, &read_bl
, &rval
);
632 ASSERT_EQ(0, ioctx
.operate("foo", &op
, nullptr));
634 assert_eq_sparse(bl
, extents
, read_bl
);
638 TEST_F(LibRadosIoECPP
, RoundTripPP
) {
641 memset(buf
, 0xcc, sizeof(buf
));
643 bl
.append(buf
, sizeof(buf
));
644 ASSERT_EQ(0, ioctx
.write("foo", bl
, sizeof(buf
), 0));
646 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", cl
, sizeof(buf
) * 3, 0));
647 ASSERT_EQ(0, memcmp(buf
, cl
.c_str(), sizeof(buf
)));
650 TEST_F(LibRadosIoECPP
, RoundTripPP2
)
654 ObjectWriteOperation write
;
656 write
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
657 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
659 ObjectReadOperation read
;
660 read
.read(0, bl
.length(), NULL
, NULL
);
661 read
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
662 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
663 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));
666 TEST_F(LibRadosIoECPP
, OverlappingWriteRoundTripPP
) {
667 int bsize
= alignment
;
668 int dbsize
= bsize
* 2;
669 char *buf
= (char *)new char[dbsize
];
670 char *buf2
= (char *)new char[bsize
];
675 scope_guard
<decltype(cleanup
)> sg(std::move(cleanup
));
676 memset(buf
, 0xcc, dbsize
);
678 bl1
.append(buf
, dbsize
);
679 ASSERT_EQ(0, ioctx
.write("foo", bl1
, dbsize
, 0));
680 memset(buf2
, 0xdd, bsize
);
682 bl2
.append(buf2
, bsize
);
683 ASSERT_EQ(-EOPNOTSUPP
, ioctx
.write("foo", bl2
, bsize
, 0));
685 ASSERT_EQ(dbsize
, ioctx
.read("foo", bl3
, dbsize
, 0));
686 // Read the same as first write
687 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, dbsize
));
690 TEST_F(LibRadosIoECPP
, WriteFullRoundTripPP
) {
693 memset(buf
, 0xcc, sizeof(buf
));
695 bl1
.append(buf
, sizeof(buf
));
696 ASSERT_EQ(0, ioctx
.write("foo", bl1
, sizeof(buf
), 0));
697 memset(buf2
, 0xdd, sizeof(buf2
));
699 bl2
.append(buf2
, sizeof(buf2
));
700 ASSERT_EQ(0, ioctx
.write_full("foo", bl2
));
702 ASSERT_EQ((int)sizeof(buf2
), ioctx
.read("foo", bl3
, sizeof(buf
), 0));
703 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
706 TEST_F(LibRadosIoECPP
, WriteFullRoundTripPP2
)
710 ObjectWriteOperation write
;
711 write
.write_full(bl
);
712 write
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
713 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
715 ObjectReadOperation read
;
716 read
.read(0, bl
.length(), NULL
, NULL
);
717 read
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
718 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
719 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));
722 TEST_F(LibRadosIoECPP
, AppendRoundTripPP
) {
723 char *buf
= (char *)new char[alignment
];
724 char *buf2
= (char *)new char[alignment
];
729 scope_guard
<decltype(cleanup
)> sg(std::move(cleanup
));
730 memset(buf
, 0xde, alignment
);
732 bl1
.append(buf
, alignment
);
733 ASSERT_EQ(0, ioctx
.append("foo", bl1
, alignment
));
734 memset(buf2
, 0xad, alignment
);
736 bl2
.append(buf2
, alignment
);
737 ASSERT_EQ(0, ioctx
.append("foo", bl2
, alignment
));
739 ASSERT_EQ((int)(alignment
* 2),
740 ioctx
.read("foo", bl3
, (alignment
* 4), 0));
741 const char *bl3_str
= bl3
.c_str();
742 ASSERT_EQ(0, memcmp(bl3_str
, buf
, alignment
));
743 ASSERT_EQ(0, memcmp(bl3_str
+ alignment
, buf2
, alignment
));
746 TEST_F(LibRadosIoECPP
, TruncTestPP
) {
748 memset(buf
, 0xaa, sizeof(buf
));
750 bl
.append(buf
, sizeof(buf
));
751 ASSERT_EQ(0, ioctx
.append("foo", bl
, sizeof(buf
)));
752 ASSERT_EQ(-EOPNOTSUPP
, ioctx
.trunc("foo", sizeof(buf
) / 2));
755 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", bl2
, sizeof(buf
), 0));
757 ASSERT_EQ(0, memcmp(bl2
.c_str(), buf
, sizeof(buf
)));
760 TEST_F(LibRadosIoECPP
, RemoveTestPP
) {
762 memset(buf
, 0xaa, sizeof(buf
));
764 bl1
.append(buf
, sizeof(buf
));
765 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
766 ASSERT_EQ(0, ioctx
.remove("foo"));
768 ASSERT_EQ(-ENOENT
, ioctx
.read("foo", bl2
, sizeof(buf
), 0));
771 TEST_F(LibRadosIoECPP
, XattrsRoundTripPP
) {
773 char attr1
[] = "attr1";
774 char attr1_buf
[] = "foo bar baz";
775 memset(buf
, 0xaa, sizeof(buf
));
777 bl1
.append(buf
, sizeof(buf
));
778 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
780 ASSERT_EQ(-ENODATA
, ioctx
.getxattr("foo", attr1
, bl2
));
782 bl3
.append(attr1_buf
, sizeof(attr1_buf
));
783 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl3
));
785 ASSERT_EQ((int)sizeof(attr1_buf
),
786 ioctx
.getxattr("foo", attr1
, bl4
));
787 ASSERT_EQ(0, memcmp(bl4
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
790 TEST_F(LibRadosIoECPP
, RmXattrPP
) {
792 char attr1
[] = "attr1";
793 char attr1_buf
[] = "foo bar baz";
794 memset(buf
, 0xaa, sizeof(buf
));
796 bl1
.append(buf
, sizeof(buf
));
797 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
799 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
800 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl2
));
801 ASSERT_EQ(0, ioctx
.rmxattr("foo", attr1
));
803 ASSERT_EQ(-ENODATA
, ioctx
.getxattr("foo", attr1
, bl3
));
805 // Test rmxattr on a removed object
807 char attr2
[] = "attr2";
808 char attr2_buf
[] = "foo bar baz";
809 memset(buf2
, 0xbb, sizeof(buf2
));
811 bl21
.append(buf
, sizeof(buf
));
812 ASSERT_EQ(0, ioctx
.write("foo_rmxattr", bl21
, sizeof(buf2
), 0));
814 bl22
.append(attr2_buf
, sizeof(attr2_buf
));
815 ASSERT_EQ(0, ioctx
.setxattr("foo_rmxattr", attr2
, bl22
));
816 ASSERT_EQ(0, ioctx
.remove("foo_rmxattr"));
817 ASSERT_EQ(-ENOENT
, ioctx
.rmxattr("foo_rmxattr", attr2
));
820 TEST_F(LibRadosIoECPP
, XattrListPP
) {
822 char attr1
[] = "attr1";
823 char attr1_buf
[] = "foo bar baz";
824 char attr2
[] = "attr2";
826 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
827 attr2_buf
[j
] = j
% 0xff;
829 memset(buf
, 0xaa, sizeof(buf
));
831 bl1
.append(buf
, sizeof(buf
));
832 ASSERT_EQ(0, ioctx
.append("foo", bl1
, sizeof(buf
)));
834 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
835 ASSERT_EQ(0, ioctx
.setxattr("foo", attr1
, bl2
));
837 bl3
.append(attr2_buf
, sizeof(attr2_buf
));
838 ASSERT_EQ(0, ioctx
.setxattr("foo", attr2
, bl3
));
839 std::map
<std::string
, bufferlist
> attrset
;
840 ASSERT_EQ(0, ioctx
.getxattrs("foo", attrset
));
841 for (std::map
<std::string
, bufferlist
>::iterator i
= attrset
.begin();
842 i
!= attrset
.end(); ++i
) {
843 if (i
->first
== string(attr1
)) {
844 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
846 else if (i
->first
== string(attr2
)) {
847 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr2_buf
, sizeof(attr2_buf
)));
855 TEST_F(LibRadosIoPP
, CmpExtPP
) {
858 ObjectWriteOperation write1
;
860 ASSERT_EQ(0, ioctx
.operate("foo", &write1
));
863 new_bl
.append("CEPH");
864 ObjectWriteOperation write2
;
865 write2
.cmpext(0, bl
, nullptr);
866 write2
.write(0, new_bl
);
867 ASSERT_EQ(0, ioctx
.operate("foo", &write2
));
869 ObjectReadOperation read
;
870 read
.read(0, bl
.length(), NULL
, NULL
);
871 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
872 ASSERT_EQ(0, memcmp(bl
.c_str(), "CEPH", 4));
875 TEST_F(LibRadosIoPP
, CmpExtDNEPP
) {
877 bl
.append(std::string(4, '\0'));
880 new_bl
.append("CEPH");
881 ObjectWriteOperation write
;
882 write
.cmpext(0, bl
, nullptr);
883 write
.write(0, new_bl
);
884 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
886 ObjectReadOperation read
;
887 read
.read(0, bl
.length(), NULL
, NULL
);
888 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
889 ASSERT_EQ(0, memcmp(bl
.c_str(), "CEPH", 4));
892 TEST_F(LibRadosIoPP
, CmpExtMismatchPP
) {
895 ObjectWriteOperation write1
;
897 ASSERT_EQ(0, ioctx
.operate("foo", &write1
));
900 new_bl
.append("CEPH");
901 ObjectWriteOperation write2
;
902 write2
.cmpext(0, new_bl
, nullptr);
903 write2
.write(0, new_bl
);
904 ASSERT_EQ(-MAX_ERRNO
, ioctx
.operate("foo", &write2
));
906 ObjectReadOperation read
;
907 read
.read(0, bl
.length(), NULL
, NULL
);
908 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
909 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));
912 TEST_F(LibRadosIoECPP
, CmpExtPP
) {
915 ObjectWriteOperation write1
;
917 ASSERT_EQ(0, ioctx
.operate("foo", &write1
));
920 new_bl
.append("CEPH");
921 ObjectWriteOperation write2
;
922 write2
.cmpext(0, bl
, nullptr);
923 write2
.write_full(new_bl
);
924 ASSERT_EQ(0, ioctx
.operate("foo", &write2
));
926 ObjectReadOperation read
;
927 read
.read(0, bl
.length(), NULL
, NULL
);
928 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
929 ASSERT_EQ(0, memcmp(bl
.c_str(), "CEPH", 4));
932 TEST_F(LibRadosIoECPP
, CmpExtDNEPP
) {
934 bl
.append(std::string(4, '\0'));
937 new_bl
.append("CEPH");
938 ObjectWriteOperation write
;
939 write
.cmpext(0, bl
, nullptr);
940 write
.write_full(new_bl
);
941 ASSERT_EQ(0, ioctx
.operate("foo", &write
));
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
, CmpExtMismatchPP
) {
952 ObjectWriteOperation write1
;
954 ASSERT_EQ(0, ioctx
.operate("foo", &write1
));
957 new_bl
.append("CEPH");
958 ObjectWriteOperation write2
;
959 write2
.cmpext(0, new_bl
, nullptr);
960 write2
.write_full(new_bl
);
961 ASSERT_EQ(-MAX_ERRNO
, ioctx
.operate("foo", &write2
));
963 ObjectReadOperation read
;
964 read
.read(0, bl
.length(), NULL
, NULL
);
965 ASSERT_EQ(0, ioctx
.operate("foo", &read
, &bl
));
966 ASSERT_EQ(0, memcmp(bl
.c_str(), "ceph", 4));