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