1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*
2 // vim: ts=8 sw=2 smarttab
6 #include "include/rados/librados.h"
7 #include "include/rados/librados.hpp"
8 #include "include/encoding.h"
9 #include "include/err.h"
10 #include "include/scope_guard.h"
11 #include "test/librados/test.h"
12 #include "test/librados/TestCase.h"
15 #include "gtest/gtest.h"
17 using namespace librados;
20 typedef RadosTest LibRadosIo;
21 typedef RadosTestEC LibRadosIoEC;
22 typedef RadosTestPP LibRadosIoPP;
23 typedef RadosTestECPP LibRadosIoECPP;
25 TEST_F(LibRadosIo, SimpleWrite) {
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));
33 TEST_F(LibRadosIo, TooBig) {
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));
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));
47 TEST_F(LibRadosIo, ReadTimeout) {
49 memset(buf, 'a', sizeof(buf));
50 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
53 // set up a second client
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());
64 // then we show that the buffer is changed after rados_read returned
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);
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]) {
80 // wait some time to give librados a change to do something
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]);
91 printf("no timeout :/\n");
94 rados_ioctx_destroy(ioctx);
95 rados_shutdown(cluster);
99 TEST_F(LibRadosIoPP, SimpleWritePP) {
101 memset(buf, 0xcc, sizeof(buf));
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));
109 TEST_F(LibRadosIoPP, ReadOpPP) {
111 memset(buf, 0xcc, sizeof(buf));
113 bl.append(buf, sizeof(buf));
114 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
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)));
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)));
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)));
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());
153 ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf)));
157 bufferlist read_bl, op_bl;
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());
165 ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf)));
166 ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf)));
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());
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)));
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)));
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)));
207 ObjectReadOperation op;
208 op.read(0, sizeof(buf), NULL, &rval);
209 ASSERT_EQ(0, ioctx.operate("foo", &op, NULL));
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());
221 ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf)));
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());
235 ASSERT_EQ(0, memcmp(read_bl1.c_str(), buf, sizeof(buf)));
236 ASSERT_EQ(0, memcmp(read_bl2.c_str(), buf, sizeof(buf)));
240 TEST_F(LibRadosIoPP, SparseReadOpPP) {
242 memset(buf, 0xcc, sizeof(buf));
244 bl.append(buf, sizeof(buf));
245 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
248 std::map<uint64_t, uint64_t> extents;
251 ObjectReadOperation op;
252 op.sparse_read(0, sizeof(buf), &extents, &read_bl, &rval);
253 ASSERT_EQ(0, ioctx.operate("foo", &op, nullptr));
255 assert_eq_sparse(bl, extents, read_bl);
259 TEST_F(LibRadosIo, RoundTrip) {
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)));
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)));
276 TEST_F(LibRadosIoPP, RoundTripPP) {
279 memset(buf, 0xcc, sizeof(buf));
281 bl.append(buf, sizeof(buf));
282 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
284 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", cl, sizeof(buf), 0));
285 ASSERT_EQ(0, memcmp(buf, cl.c_str(), sizeof(buf)));
288 TEST_F(LibRadosIoPP, RoundTripPP2)
292 ObjectWriteOperation write;
294 write.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
295 ASSERT_EQ(0, ioctx.operate("foo", &write));
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));
304 TEST_F(LibRadosIo, Checksum) {
306 memset(buf, 0xcc, sizeof(buf));
307 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
309 uint32_t expected_crc = ceph_crc32c(-1, reinterpret_cast<const uint8_t*>(buf),
311 uint32_t init_value = -1;
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]);
321 TEST_F(LibRadosIoPP, Checksum) {
324 memset(buf, 0xcc, sizeof(buf));
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);
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();
335 ::decode(csum_count, csum_bl_it);
336 ASSERT_EQ(1U, csum_count);
338 ::decode(csum, csum_bl_it);
339 ASSERT_EQ(bl.crc32c(-1), csum);
342 TEST_F(LibRadosIo, OverlappingWriteRoundTrip) {
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)));
356 TEST_F(LibRadosIoPP, OverlappingWriteRoundTripPP) {
359 memset(buf, 0xcc, sizeof(buf));
361 bl1.append(buf, sizeof(buf));
362 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
363 memset(buf2, 0xdd, sizeof(buf2));
365 bl2.append(buf2, sizeof(buf2));
366 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), 0));
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)));
373 TEST_F(LibRadosIo, WriteFullRoundTrip) {
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)));
386 TEST_F(LibRadosIoPP, WriteFullRoundTripPP) {
389 memset(buf, 0xcc, sizeof(buf));
391 bl1.append(buf, sizeof(buf));
392 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
393 memset(buf2, 0xdd, sizeof(buf2));
395 bl2.append(buf2, sizeof(buf2));
396 ASSERT_EQ(0, ioctx.write_full("foo", bl2));
398 ASSERT_EQ((int)sizeof(buf2), ioctx.read("foo", bl3, sizeof(buf), 0));
399 ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2)));
402 TEST_F(LibRadosIoPP, WriteFullRoundTripPP2)
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));
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));
418 TEST_F(LibRadosIo, AppendRoundTrip) {
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)));
432 TEST_F(LibRadosIoPP, AppendRoundTripPP) {
435 memset(buf, 0xde, sizeof(buf));
437 bl1.append(buf, sizeof(buf));
438 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
439 memset(buf2, 0xad, sizeof(buf2));
441 bl2.append(buf2, sizeof(buf2));
442 ASSERT_EQ(0, ioctx.append("foo", bl2, sizeof(buf2)));
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)));
451 TEST_F(LibRadosIo, TruncTest) {
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));
462 TEST_F(LibRadosIoPP, TruncTestPP) {
464 memset(buf, 0xaa, sizeof(buf));
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));
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));
474 TEST_F(LibRadosIo, RemoveTest) {
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));
484 TEST_F(LibRadosIoPP, RemoveTestPP) {
486 memset(buf, 0xaa, sizeof(buf));
488 bl1.append(buf, sizeof(buf));
489 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
490 ASSERT_EQ(0, ioctx.remove("foo"));
492 ASSERT_EQ(-ENOENT, ioctx.read("foo", bl2, sizeof(buf), 0));
495 TEST_F(LibRadosIo, XattrsRoundTrip) {
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)));
508 TEST_F(LibRadosIoPP, XattrsRoundTripPP) {
510 char attr1[] = "attr1";
511 char attr1_buf[] = "foo bar baz";
512 memset(buf, 0xaa, sizeof(buf));
514 bl1.append(buf, sizeof(buf));
515 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
517 ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl2));
519 bl3.append(attr1_buf, sizeof(attr1_buf));
520 ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl3));
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)));
527 TEST_F(LibRadosIo, RmXattr) {
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)));
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)));
538 // Test rmxattr on a removed object
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));
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));
550 TEST_F(LibRadosIoPP, RmXattrPP) {
552 char attr1[] = "attr1";
553 char attr1_buf[] = "foo bar baz";
554 memset(buf, 0xaa, sizeof(buf));
556 bl1.append(buf, sizeof(buf));
557 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
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));
563 ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl3));
565 // Test rmxattr on a removed object
567 char attr2[] = "attr2";
568 char attr2_buf[] = "foo bar baz";
569 memset(buf2, 0xbb, sizeof(buf2));
571 bl21.append(buf, sizeof(buf));
572 ASSERT_EQ(0, ioctx.write("foo_rmxattr", bl21, sizeof(buf2), 0));
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));
580 TEST_F(LibRadosIo, XattrIter) {
582 char attr1[] = "attr1";
583 char attr1_buf[] = "foo bar baz";
584 char attr2[] = "attr2";
586 for (size_t j = 0; j < sizeof(attr2_buf); ++j) {
587 attr2_buf[j] = j % 0xff;
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));
600 ASSERT_EQ(0, rados_getxattrs_next(iter, &name, &val, &len));
604 ASSERT_LT(num_seen, 2);
605 if ((strcmp(name, attr1) == 0) && (val != NULL) && (memcmp(val, attr1_buf, len) == 0)) {
609 else if ((strcmp(name, attr2) == 0) && (val != NULL) && (memcmp(val, attr2_buf, len) == 0)) {
617 rados_getxattrs_end(iter);
620 TEST_F(LibRadosIoPP, XattrListPP) {
622 char attr1[] = "attr1";
623 char attr1_buf[] = "foo bar baz";
624 char attr2[] = "attr2";
626 for (size_t j = 0; j < sizeof(attr2_buf); ++j) {
627 attr2_buf[j] = j % 0xff;
629 memset(buf, 0xaa, sizeof(buf));
631 bl1.append(buf, sizeof(buf));
632 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
634 bl2.append(attr1_buf, sizeof(attr1_buf));
635 ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl2));
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)));
646 else if (i->first == string(attr2)) {
647 ASSERT_EQ(0, memcmp(i->second.c_str(), attr2_buf, sizeof(attr2_buf)));
655 TEST_F(LibRadosIoEC, SimpleWrite) {
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));
663 TEST_F(LibRadosIoECPP, SimpleWritePP) {
665 memset(buf, 0xcc, sizeof(buf));
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));
673 TEST_F(LibRadosIoECPP, ReadOpPP) {
675 memset(buf, 0xcc, sizeof(buf));
677 bl.append(buf, sizeof(buf));
678 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
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)));
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)));
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)));
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());
717 ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf)));
721 bufferlist read_bl, op_bl;
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());
729 ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf)));
730 ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf)));
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());
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)));
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)));
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)));
771 ObjectReadOperation op;
772 op.read(0, sizeof(buf), NULL, &rval);
773 ASSERT_EQ(0, ioctx.operate("foo", &op, NULL));
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());
785 ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf)));
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());
799 ASSERT_EQ(0, memcmp(read_bl1.c_str(), buf, sizeof(buf)));
800 ASSERT_EQ(0, memcmp(read_bl2.c_str(), buf, sizeof(buf)));
804 TEST_F(LibRadosIoECPP, SparseReadOpPP) {
806 memset(buf, 0xcc, sizeof(buf));
808 bl.append(buf, sizeof(buf));
809 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
812 std::map<uint64_t, uint64_t> extents;
815 ObjectReadOperation op;
816 op.sparse_read(0, sizeof(buf), &extents, &read_bl, &rval);
817 ASSERT_EQ(0, ioctx.operate("foo", &op, nullptr));
819 assert_eq_sparse(bl, extents, read_bl);
823 TEST_F(LibRadosIoEC, RoundTrip) {
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)));
833 ASSERT_EQ(-EOPNOTSUPP, rados_write(ioctx, "bar", buf, sizeof(buf), off));
836 TEST_F(LibRadosIoECPP, RoundTripPP) {
839 memset(buf, 0xcc, sizeof(buf));
841 bl.append(buf, sizeof(buf));
842 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
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)));
848 TEST_F(LibRadosIoECPP, RoundTripPP2)
852 ObjectWriteOperation write;
854 write.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
855 ASSERT_EQ(0, ioctx.operate("foo", &write));
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));
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];
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));
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];
895 scope_guard<decltype(cleanup)> sg(std::move(cleanup));
896 memset(buf, 0xcc, dbsize);
898 bl1.append(buf, dbsize);
899 ASSERT_EQ(0, ioctx.write("foo", bl1, dbsize, 0));
900 memset(buf2, 0xdd, bsize);
902 bl2.append(buf2, bsize);
903 ASSERT_EQ(-EOPNOTSUPP, ioctx.write("foo", bl2, bsize, 0));
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));
910 TEST_F(LibRadosIoEC, WriteFullRoundTrip) {
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)));
923 TEST_F(LibRadosIoECPP, WriteFullRoundTripPP) {
926 memset(buf, 0xcc, sizeof(buf));
928 bl1.append(buf, sizeof(buf));
929 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
930 memset(buf2, 0xdd, sizeof(buf2));
932 bl2.append(buf2, sizeof(buf2));
933 ASSERT_EQ(0, ioctx.write_full("foo", bl2));
935 ASSERT_EQ((int)sizeof(buf2), ioctx.read("foo", bl3, sizeof(buf), 0));
936 ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2)));
939 TEST_F(LibRadosIoECPP, WriteFullRoundTripPP2)
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));
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));
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];
965 delete[] unalignedbuf;
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));
981 TEST_F(LibRadosIoECPP, AppendRoundTripPP) {
982 char *buf = (char *)new char[alignment];
983 char *buf2 = (char *)new char[alignment];
988 scope_guard<decltype(cleanup)> sg(std::move(cleanup));
989 memset(buf, 0xde, alignment);
991 bl1.append(buf, alignment);
992 ASSERT_EQ(0, ioctx.append("foo", bl1, alignment));
993 memset(buf2, 0xad, alignment);
995 bl2.append(buf2, alignment);
996 ASSERT_EQ(0, ioctx.append("foo", bl2, alignment));
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));
1005 TEST_F(LibRadosIoEC, TruncTest) {
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));
1013 ASSERT_EQ((int)sizeof(buf), rados_read(ioctx, "foo", buf2, sizeof(buf2), 0));
1015 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1018 TEST_F(LibRadosIoECPP, TruncTestPP) {
1020 memset(buf, 0xaa, sizeof(buf));
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));
1027 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl2, sizeof(buf), 0));
1029 ASSERT_EQ(0, memcmp(bl2.c_str(), buf, sizeof(buf)));
1032 TEST_F(LibRadosIoEC, RemoveTest) {
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));
1042 TEST_F(LibRadosIoECPP, RemoveTestPP) {
1044 memset(buf, 0xaa, sizeof(buf));
1046 bl1.append(buf, sizeof(buf));
1047 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
1048 ASSERT_EQ(0, ioctx.remove("foo"));
1050 ASSERT_EQ(-ENOENT, ioctx.read("foo", bl2, sizeof(buf), 0));
1053 TEST_F(LibRadosIoEC, XattrsRoundTrip) {
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)));
1066 TEST_F(LibRadosIoECPP, XattrsRoundTripPP) {
1068 char attr1[] = "attr1";
1069 char attr1_buf[] = "foo bar baz";
1070 memset(buf, 0xaa, sizeof(buf));
1072 bl1.append(buf, sizeof(buf));
1073 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
1075 ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl2));
1077 bl3.append(attr1_buf, sizeof(attr1_buf));
1078 ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl3));
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)));
1085 TEST_F(LibRadosIoEC, RmXattr) {
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)));
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)));
1096 // Test rmxattr on a removed object
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));
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));
1108 TEST_F(LibRadosIoECPP, RmXattrPP) {
1110 char attr1[] = "attr1";
1111 char attr1_buf[] = "foo bar baz";
1112 memset(buf, 0xaa, sizeof(buf));
1114 bl1.append(buf, sizeof(buf));
1115 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
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));
1121 ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl3));
1123 // Test rmxattr on a removed object
1125 char attr2[] = "attr2";
1126 char attr2_buf[] = "foo bar baz";
1127 memset(buf2, 0xbb, sizeof(buf2));
1129 bl21.append(buf, sizeof(buf));
1130 ASSERT_EQ(0, ioctx.write("foo_rmxattr", bl21, sizeof(buf2), 0));
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));
1138 TEST_F(LibRadosIoEC, XattrIter) {
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;
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));
1158 ASSERT_EQ(0, rados_getxattrs_next(iter, &name, &val, &len));
1162 ASSERT_LT(num_seen, 2);
1163 if ((strcmp(name, attr1) == 0) && (val != NULL) && (memcmp(val, attr1_buf, len) == 0)) {
1167 else if ((strcmp(name, attr2) == 0) && (val != NULL) && (memcmp(val, attr2_buf, len) == 0)) {
1175 rados_getxattrs_end(iter);
1178 TEST_F(LibRadosIoECPP, XattrListPP) {
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;
1187 memset(buf, 0xaa, sizeof(buf));
1189 bl1.append(buf, sizeof(buf));
1190 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
1192 bl2.append(attr1_buf, sizeof(attr1_buf));
1193 ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl2));
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)));
1204 else if (i->first == string(attr2)) {
1205 ASSERT_EQ(0, memcmp(i->second.c_str(), attr2_buf, sizeof(attr2_buf)));
1213 TEST_F(LibRadosIoPP, CmpExtPP) {
1216 ObjectWriteOperation write1;
1217 write1.write(0, bl);
1218 ASSERT_EQ(0, ioctx.operate("foo", &write1));
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));
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));
1233 TEST_F(LibRadosIoPP, CmpExtDNEPP) {
1235 bl.append(std::string(4, '\0'));
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));
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));
1250 TEST_F(LibRadosIoPP, CmpExtMismatchPP) {
1253 ObjectWriteOperation write1;
1254 write1.write(0, bl);
1255 ASSERT_EQ(0, ioctx.operate("foo", &write1));
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));
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));
1270 TEST_F(LibRadosIoECPP, CmpExtPP) {
1273 ObjectWriteOperation write1;
1274 write1.write(0, bl);
1275 ASSERT_EQ(0, ioctx.operate("foo", &write1));
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));
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));
1290 TEST_F(LibRadosIoECPP, CmpExtDNEPP) {
1292 bl.append(std::string(4, '\0'));
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));
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));
1307 TEST_F(LibRadosIoECPP, CmpExtMismatchPP) {
1310 ObjectWriteOperation write1;
1311 write1.write(0, bl);
1312 ASSERT_EQ(0, ioctx.operate("foo", &write1));
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));
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));