]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/librados/io_cxx.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / test / librados / io_cxx.cc
CommitLineData
11fdf7f2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*
2// vim: ts=8 sw=2 smarttab
3
4#include <climits>
5#include <errno.h>
6
7#include "gtest/gtest.h"
8
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"
15
1e59de90
TL
16#include "crimson_utils.h"
17
11fdf7f2
TL
18using namespace librados;
19using std::string;
20
21typedef RadosTestPP LibRadosIoPP;
22typedef RadosTestECPP LibRadosIoECPP;
23
24TEST_F(LibRadosIoPP, TooBigPP) {
25 IoCtx ioctx;
26 bufferlist bl;
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));
31}
32
33TEST_F(LibRadosIoPP, SimpleWritePP) {
34 char buf[128];
35 memset(buf, 0xcc, sizeof(buf));
36 bufferlist bl;
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));
41}
42
43TEST_F(LibRadosIoPP, ReadOpPP) {
44 char buf[128];
45 memset(buf, 0xcc, sizeof(buf));
46 bufferlist bl;
47 bl.append(buf, sizeof(buf));
48 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
49
50 {
51 bufferlist op_bl;
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)));
57 }
58
59 {
60 bufferlist op_bl;
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)));
66 }
67
68 {
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)));
77 }
78
79 {
80 bufferlist op_bl;
81 int rval = 1000;
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());
86 ASSERT_EQ(0, rval);
87 ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf)));
88 }
89
90 {
91 bufferlist read_bl, op_bl;
92 int rval = 1000;
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());
98 ASSERT_EQ(0, rval);
99 ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf)));
100 ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf)));
101 }
102
103 {
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());
113 ASSERT_EQ(0, rval1);
114 ASSERT_EQ(0, rval2);
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)));
119 }
120
121 {
122 bufferlist op_bl;
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)));
128 }
129
130 {
131 bufferlist read_bl;
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)));
137 }
138
139 {
140 int rval = 1000;
141 ObjectReadOperation op;
142 op.read(0, sizeof(buf), NULL, &rval);
143 ASSERT_EQ(0, ioctx.operate("foo", &op, NULL));
144 ASSERT_EQ(0, rval);
145 }
146
147 {
148 bufferlist read_bl;
149 int rval = 1000;
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());
154 ASSERT_EQ(0, rval);
155 ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf)));
156 }
157
158 {
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());
167 ASSERT_EQ(0, rval1);
168 ASSERT_EQ(0, rval2);
169 ASSERT_EQ(0, memcmp(read_bl1.c_str(), buf, sizeof(buf)));
170 ASSERT_EQ(0, memcmp(read_bl2.c_str(), buf, sizeof(buf)));
171 }
172
173 // read into a preallocated buffer with a cached crc
174 {
175 bufferlist op_bl;
176 op_bl.append(std::string(sizeof(buf), 'x'));
177 ASSERT_NE(op_bl.crc32c(0), bl.crc32c(0)); // cache 'x' crc
178
179 ObjectReadOperation op;
180 op.read(0, sizeof(buf), NULL, NULL);
181 ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl));
182
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));
186 }
187}
188
189TEST_F(LibRadosIoPP, SparseReadOpPP) {
190 char buf[128];
191 memset(buf, 0xcc, sizeof(buf));
192 bufferlist bl;
193 bl.append(buf, sizeof(buf));
194 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
195
196 {
197 std::map<uint64_t, uint64_t> extents;
198 bufferlist read_bl;
199 int rval = -1;
200 ObjectReadOperation op;
201 op.sparse_read(0, sizeof(buf), &extents, &read_bl, &rval);
202 ASSERT_EQ(0, ioctx.operate("foo", &op, nullptr));
203 ASSERT_EQ(0, rval);
204 assert_eq_sparse(bl, extents, read_bl);
205 }
1d09f67e
TL
206 {
207 bufferlist bl;
208 bl.append(buf, sizeof(buf) / 2);
209
210 std::map<uint64_t, uint64_t> extents;
211 bufferlist read_bl;
212 int rval = -1;
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));
216 ASSERT_EQ(0, rval);
217 assert_eq_sparse(bl, extents, read_bl);
218 }
11fdf7f2
TL
219}
220
221TEST_F(LibRadosIoPP, RoundTripPP) {
222 char buf[128];
223 Rados cluster;
224 memset(buf, 0xcc, sizeof(buf));
225 bufferlist bl;
226 bl.append(buf, sizeof(buf));
227 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
228 bufferlist cl;
229 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", cl, sizeof(buf), 0));
230 ASSERT_EQ(0, memcmp(buf, cl.c_str(), sizeof(buf)));
231}
232
233TEST_F(LibRadosIoPP, RoundTripPP2)
234{
235 bufferlist bl;
236 bl.append("ceph");
237 ObjectWriteOperation write;
238 write.write(0, bl);
239 write.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
240 ASSERT_EQ(0, ioctx.operate("foo", &write));
241
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));
247}
248
249TEST_F(LibRadosIoPP, Checksum) {
250 char buf[128];
251 Rados cluster;
252 memset(buf, 0xcc, sizeof(buf));
253 bufferlist bl;
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);
258 bufferlist csum_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();
262 uint32_t csum_count;
263 decode(csum_count, csum_bl_it);
264 ASSERT_EQ(1U, csum_count);
265 uint32_t csum;
266 decode(csum, csum_bl_it);
267 ASSERT_EQ(bl.crc32c(-1), csum);
268}
269
270TEST_F(LibRadosIoPP, ReadIntoBufferlist) {
271
272 // here we test reading into a non-empty bufferlist referencing existing
273 // buffers
274
275 char buf[128];
276 Rados cluster;
277 memset(buf, 0xcc, sizeof(buf));
278 bufferlist bl;
279 bl.append(buf, sizeof(buf));
280 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
281 bufferlist bl2;
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)));
288}
289
290TEST_F(LibRadosIoPP, OverlappingWriteRoundTripPP) {
291 char buf[128];
292 char buf2[64];
293 memset(buf, 0xcc, sizeof(buf));
294 bufferlist bl1;
295 bl1.append(buf, sizeof(buf));
296 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
297 memset(buf2, 0xdd, sizeof(buf2));
298 bufferlist bl2;
299 bl2.append(buf2, sizeof(buf2));
300 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), 0));
301 bufferlist bl3;
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)));
305}
306
307TEST_F(LibRadosIoPP, WriteFullRoundTripPP) {
308 char buf[128];
309 char buf2[64];
310 memset(buf, 0xcc, sizeof(buf));
311 bufferlist bl1;
312 bl1.append(buf, sizeof(buf));
313 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
314 memset(buf2, 0xdd, sizeof(buf2));
315 bufferlist bl2;
316 bl2.append(buf2, sizeof(buf2));
317 ASSERT_EQ(0, ioctx.write_full("foo", bl2));
318 bufferlist bl3;
319 ASSERT_EQ((int)sizeof(buf2), ioctx.read("foo", bl3, sizeof(buf), 0));
320 ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2)));
321}
322
323TEST_F(LibRadosIoPP, WriteFullRoundTripPP2)
324{
325 bufferlist bl;
326 bl.append("ceph");
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));
331
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));
337}
338
339TEST_F(LibRadosIoPP, AppendRoundTripPP) {
340 char buf[64];
341 char buf2[64];
342 memset(buf, 0xde, sizeof(buf));
343 bufferlist bl1;
344 bl1.append(buf, sizeof(buf));
345 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
346 memset(buf2, 0xad, sizeof(buf2));
347 bufferlist bl2;
348 bl2.append(buf2, sizeof(buf2));
349 ASSERT_EQ(0, ioctx.append("foo", bl2, sizeof(buf2)));
350 bufferlist bl3;
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)));
356}
357
358TEST_F(LibRadosIoPP, TruncTestPP) {
359 char buf[128];
360 memset(buf, 0xaa, sizeof(buf));
361 bufferlist bl;
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));
365 bufferlist bl2;
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));
368}
369
370TEST_F(LibRadosIoPP, RemoveTestPP) {
371 char buf[128];
372 memset(buf, 0xaa, sizeof(buf));
373 bufferlist bl1;
374 bl1.append(buf, sizeof(buf));
375 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
376 ASSERT_EQ(0, ioctx.remove("foo"));
377 bufferlist bl2;
378 ASSERT_EQ(-ENOENT, ioctx.read("foo", bl2, sizeof(buf), 0));
379}
380
381TEST_F(LibRadosIoPP, XattrsRoundTripPP) {
382 char buf[128];
383 char attr1[] = "attr1";
384 char attr1_buf[] = "foo bar baz";
385 memset(buf, 0xaa, sizeof(buf));
386 bufferlist bl1;
387 bl1.append(buf, sizeof(buf));
388 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
389 bufferlist bl2;
390 ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl2));
391 bufferlist bl3;
392 bl3.append(attr1_buf, sizeof(attr1_buf));
393 ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl3));
394 bufferlist bl4;
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)));
398}
399
400TEST_F(LibRadosIoPP, RmXattrPP) {
401 char buf[128];
402 char attr1[] = "attr1";
403 char attr1_buf[] = "foo bar baz";
404 memset(buf, 0xaa, sizeof(buf));
405 bufferlist bl1;
406 bl1.append(buf, sizeof(buf));
407 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
408 bufferlist bl2;
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));
412 bufferlist bl3;
413 ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl3));
414
415 // Test rmxattr on a removed object
416 char buf2[128];
417 char attr2[] = "attr2";
418 char attr2_buf[] = "foo bar baz";
419 memset(buf2, 0xbb, sizeof(buf2));
420 bufferlist bl21;
421 bl21.append(buf, sizeof(buf));
422 ASSERT_EQ(0, ioctx.write("foo_rmxattr", bl21, sizeof(buf2), 0));
423 bufferlist bl22;
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));
428}
429
430TEST_F(LibRadosIoPP, XattrListPP) {
431 char buf[128];
432 char attr1[] = "attr1";
433 char attr1_buf[] = "foo bar baz";
434 char attr2[] = "attr2";
435 char attr2_buf[256];
436 for (size_t j = 0; j < sizeof(attr2_buf); ++j) {
437 attr2_buf[j] = j % 0xff;
438 }
439 memset(buf, 0xaa, sizeof(buf));
440 bufferlist bl1;
441 bl1.append(buf, sizeof(buf));
442 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
443 bufferlist bl2;
444 bl2.append(attr1_buf, sizeof(attr1_buf));
445 ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl2));
446 bufferlist bl3;
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)));
455 }
456 else if (i->first == string(attr2)) {
457 ASSERT_EQ(0, memcmp(i->second.c_str(), attr2_buf, sizeof(attr2_buf)));
458 }
459 else {
460 ASSERT_EQ(0, 1);
461 }
462 }
463}
464
465TEST_F(LibRadosIoECPP, SimpleWritePP) {
1e59de90 466 SKIP_IF_CRIMSON();
11fdf7f2
TL
467 char buf[128];
468 memset(buf, 0xcc, sizeof(buf));
469 bufferlist bl;
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));
474}
475
476TEST_F(LibRadosIoECPP, ReadOpPP) {
1e59de90 477 SKIP_IF_CRIMSON();
11fdf7f2
TL
478 char buf[128];
479 memset(buf, 0xcc, sizeof(buf));
480 bufferlist bl;
481 bl.append(buf, sizeof(buf));
482 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
483
484 {
485 bufferlist op_bl;
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)));
491 }
492
493 {
494 bufferlist op_bl;
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)));
500 }
501
502 {
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)));
511 }
512
513 {
514 bufferlist op_bl;
515 int rval = 1000;
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());
520 ASSERT_EQ(0, rval);
521 ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf)));
522 }
523
524 {
525 bufferlist read_bl, op_bl;
526 int rval = 1000;
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());
532 ASSERT_EQ(0, rval);
533 ASSERT_EQ(0, memcmp(op_bl.c_str(), buf, sizeof(buf)));
534 ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf)));
535 }
536
537 {
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());
547 ASSERT_EQ(0, rval1);
548 ASSERT_EQ(0, rval2);
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)));
553 }
554
555 {
556 bufferlist op_bl;
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)));
562 }
563
564 {
565 bufferlist read_bl;
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)));
571 }
572
573 {
574 int rval = 1000;
575 ObjectReadOperation op;
576 op.read(0, sizeof(buf), NULL, &rval);
577 ASSERT_EQ(0, ioctx.operate("foo", &op, NULL));
578 ASSERT_EQ(0, rval);
579 }
580
581 {
582 bufferlist read_bl;
583 int rval = 1000;
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());
588 ASSERT_EQ(0, rval);
589 ASSERT_EQ(0, memcmp(read_bl.c_str(), buf, sizeof(buf)));
590 }
591
592 {
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());
601 ASSERT_EQ(0, rval1);
602 ASSERT_EQ(0, rval2);
603 ASSERT_EQ(0, memcmp(read_bl1.c_str(), buf, sizeof(buf)));
604 ASSERT_EQ(0, memcmp(read_bl2.c_str(), buf, sizeof(buf)));
605 }
606
607 // read into a preallocated buffer with a cached crc
608 {
609 bufferlist op_bl;
610 op_bl.append(std::string(sizeof(buf), 'x'));
611 ASSERT_NE(op_bl.crc32c(0), bl.crc32c(0)); // cache 'x' crc
612
613 ObjectReadOperation op;
614 op.read(0, sizeof(buf), NULL, NULL);
615 ASSERT_EQ(0, ioctx.operate("foo", &op, &op_bl));
616
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));
620 }
621}
622
623TEST_F(LibRadosIoECPP, SparseReadOpPP) {
1e59de90 624 SKIP_IF_CRIMSON();
11fdf7f2
TL
625 char buf[128];
626 memset(buf, 0xcc, sizeof(buf));
627 bufferlist bl;
628 bl.append(buf, sizeof(buf));
629 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
630
631 {
632 std::map<uint64_t, uint64_t> extents;
633 bufferlist read_bl;
634 int rval = -1;
635 ObjectReadOperation op;
636 op.sparse_read(0, sizeof(buf), &extents, &read_bl, &rval);
637 ASSERT_EQ(0, ioctx.operate("foo", &op, nullptr));
638 ASSERT_EQ(0, rval);
639 assert_eq_sparse(bl, extents, read_bl);
640 }
641}
642
643TEST_F(LibRadosIoECPP, RoundTripPP) {
1e59de90 644 SKIP_IF_CRIMSON();
11fdf7f2
TL
645 char buf[128];
646 Rados cluster;
647 memset(buf, 0xcc, sizeof(buf));
648 bufferlist bl;
649 bl.append(buf, sizeof(buf));
650 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
651 bufferlist cl;
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)));
654}
655
656TEST_F(LibRadosIoECPP, RoundTripPP2)
657{
1e59de90 658 SKIP_IF_CRIMSON();
11fdf7f2
TL
659 bufferlist bl;
660 bl.append("ceph");
661 ObjectWriteOperation write;
662 write.write(0, bl);
663 write.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
664 ASSERT_EQ(0, ioctx.operate("foo", &write));
665
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));
671}
672
673TEST_F(LibRadosIoECPP, OverlappingWriteRoundTripPP) {
1e59de90 674 SKIP_IF_CRIMSON();
11fdf7f2
TL
675 int bsize = alignment;
676 int dbsize = bsize * 2;
677 char *buf = (char *)new char[dbsize];
678 char *buf2 = (char *)new char[bsize];
679 auto cleanup = [&] {
680 delete[] buf;
681 delete[] buf2;
682 };
683 scope_guard<decltype(cleanup)> sg(std::move(cleanup));
684 memset(buf, 0xcc, dbsize);
685 bufferlist bl1;
686 bl1.append(buf, dbsize);
687 ASSERT_EQ(0, ioctx.write("foo", bl1, dbsize, 0));
688 memset(buf2, 0xdd, bsize);
689 bufferlist bl2;
690 bl2.append(buf2, bsize);
691 ASSERT_EQ(-EOPNOTSUPP, ioctx.write("foo", bl2, bsize, 0));
692 bufferlist bl3;
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));
696}
697
698TEST_F(LibRadosIoECPP, WriteFullRoundTripPP) {
1e59de90 699 SKIP_IF_CRIMSON();
11fdf7f2
TL
700 char buf[128];
701 char buf2[64];
702 memset(buf, 0xcc, sizeof(buf));
703 bufferlist bl1;
704 bl1.append(buf, sizeof(buf));
705 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
706 memset(buf2, 0xdd, sizeof(buf2));
707 bufferlist bl2;
708 bl2.append(buf2, sizeof(buf2));
709 ASSERT_EQ(0, ioctx.write_full("foo", bl2));
710 bufferlist bl3;
711 ASSERT_EQ((int)sizeof(buf2), ioctx.read("foo", bl3, sizeof(buf), 0));
712 ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2)));
713}
714
715TEST_F(LibRadosIoECPP, WriteFullRoundTripPP2)
716{
1e59de90 717 SKIP_IF_CRIMSON();
11fdf7f2
TL
718 bufferlist bl;
719 bl.append("ceph");
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));
724
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));
730}
731
732TEST_F(LibRadosIoECPP, AppendRoundTripPP) {
1e59de90 733 SKIP_IF_CRIMSON();
11fdf7f2
TL
734 char *buf = (char *)new char[alignment];
735 char *buf2 = (char *)new char[alignment];
736 auto cleanup = [&] {
737 delete[] buf;
738 delete[] buf2;
739 };
740 scope_guard<decltype(cleanup)> sg(std::move(cleanup));
741 memset(buf, 0xde, alignment);
742 bufferlist bl1;
743 bl1.append(buf, alignment);
744 ASSERT_EQ(0, ioctx.append("foo", bl1, alignment));
745 memset(buf2, 0xad, alignment);
746 bufferlist bl2;
747 bl2.append(buf2, alignment);
748 ASSERT_EQ(0, ioctx.append("foo", bl2, alignment));
749 bufferlist bl3;
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));
755}
756
757TEST_F(LibRadosIoECPP, TruncTestPP) {
1e59de90 758 SKIP_IF_CRIMSON();
11fdf7f2
TL
759 char buf[128];
760 memset(buf, 0xaa, sizeof(buf));
761 bufferlist bl;
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));
765 bufferlist bl2;
766 // Same size
767 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl2, sizeof(buf), 0));
768 // No change
769 ASSERT_EQ(0, memcmp(bl2.c_str(), buf, sizeof(buf)));
770}
771
772TEST_F(LibRadosIoECPP, RemoveTestPP) {
1e59de90 773 SKIP_IF_CRIMSON();
11fdf7f2
TL
774 char buf[128];
775 memset(buf, 0xaa, sizeof(buf));
776 bufferlist bl1;
777 bl1.append(buf, sizeof(buf));
778 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
779 ASSERT_EQ(0, ioctx.remove("foo"));
780 bufferlist bl2;
781 ASSERT_EQ(-ENOENT, ioctx.read("foo", bl2, sizeof(buf), 0));
782}
783
784TEST_F(LibRadosIoECPP, XattrsRoundTripPP) {
1e59de90 785 SKIP_IF_CRIMSON();
11fdf7f2
TL
786 char buf[128];
787 char attr1[] = "attr1";
788 char attr1_buf[] = "foo bar baz";
789 memset(buf, 0xaa, sizeof(buf));
790 bufferlist bl1;
791 bl1.append(buf, sizeof(buf));
792 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
793 bufferlist bl2;
794 ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl2));
795 bufferlist bl3;
796 bl3.append(attr1_buf, sizeof(attr1_buf));
797 ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl3));
798 bufferlist bl4;
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)));
802}
803
804TEST_F(LibRadosIoECPP, RmXattrPP) {
1e59de90 805 SKIP_IF_CRIMSON();
11fdf7f2
TL
806 char buf[128];
807 char attr1[] = "attr1";
808 char attr1_buf[] = "foo bar baz";
809 memset(buf, 0xaa, sizeof(buf));
810 bufferlist bl1;
811 bl1.append(buf, sizeof(buf));
812 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
813 bufferlist bl2;
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));
817 bufferlist bl3;
818 ASSERT_EQ(-ENODATA, ioctx.getxattr("foo", attr1, bl3));
819
820 // Test rmxattr on a removed object
821 char buf2[128];
822 char attr2[] = "attr2";
823 char attr2_buf[] = "foo bar baz";
824 memset(buf2, 0xbb, sizeof(buf2));
825 bufferlist bl21;
826 bl21.append(buf, sizeof(buf));
827 ASSERT_EQ(0, ioctx.write("foo_rmxattr", bl21, sizeof(buf2), 0));
828 bufferlist bl22;
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));
833}
834
835TEST_F(LibRadosIoECPP, XattrListPP) {
1e59de90 836 SKIP_IF_CRIMSON();
11fdf7f2
TL
837 char buf[128];
838 char attr1[] = "attr1";
839 char attr1_buf[] = "foo bar baz";
840 char attr2[] = "attr2";
841 char attr2_buf[256];
842 for (size_t j = 0; j < sizeof(attr2_buf); ++j) {
843 attr2_buf[j] = j % 0xff;
844 }
845 memset(buf, 0xaa, sizeof(buf));
846 bufferlist bl1;
847 bl1.append(buf, sizeof(buf));
848 ASSERT_EQ(0, ioctx.append("foo", bl1, sizeof(buf)));
849 bufferlist bl2;
850 bl2.append(attr1_buf, sizeof(attr1_buf));
851 ASSERT_EQ(0, ioctx.setxattr("foo", attr1, bl2));
852 bufferlist bl3;
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)));
861 }
862 else if (i->first == string(attr2)) {
863 ASSERT_EQ(0, memcmp(i->second.c_str(), attr2_buf, sizeof(attr2_buf)));
864 }
865 else {
866 ASSERT_EQ(0, 1);
867 }
868 }
869}
870
871TEST_F(LibRadosIoPP, CmpExtPP) {
872 bufferlist bl;
873 bl.append("ceph");
874 ObjectWriteOperation write1;
875 write1.write(0, bl);
876 ASSERT_EQ(0, ioctx.operate("foo", &write1));
877
878 bufferlist new_bl;
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));
884
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));
889}
890
891TEST_F(LibRadosIoPP, CmpExtDNEPP) {
892 bufferlist bl;
893 bl.append(std::string(4, '\0'));
894
895 bufferlist new_bl;
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));
901
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));
906}
907
908TEST_F(LibRadosIoPP, CmpExtMismatchPP) {
909 bufferlist bl;
910 bl.append("ceph");
911 ObjectWriteOperation write1;
912 write1.write(0, bl);
913 ASSERT_EQ(0, ioctx.operate("foo", &write1));
914
915 bufferlist new_bl;
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));
921
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));
926}
927
928TEST_F(LibRadosIoECPP, CmpExtPP) {
1e59de90 929 SKIP_IF_CRIMSON();
11fdf7f2
TL
930 bufferlist bl;
931 bl.append("ceph");
932 ObjectWriteOperation write1;
933 write1.write(0, bl);
934 ASSERT_EQ(0, ioctx.operate("foo", &write1));
935
936 bufferlist new_bl;
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));
942
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));
947}
948
949TEST_F(LibRadosIoECPP, CmpExtDNEPP) {
1e59de90 950 SKIP_IF_CRIMSON();
11fdf7f2
TL
951 bufferlist bl;
952 bl.append(std::string(4, '\0'));
953
954 bufferlist new_bl;
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));
960
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));
965}
966
967TEST_F(LibRadosIoECPP, CmpExtMismatchPP) {
1e59de90 968 SKIP_IF_CRIMSON();
11fdf7f2
TL
969 bufferlist bl;
970 bl.append("ceph");
971 ObjectWriteOperation write1;
972 write1.write(0, bl);
973 ASSERT_EQ(0, ioctx.operate("foo", &write1));
974
975 bufferlist new_bl;
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));
981
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));
986}