6 #include <boost/scoped_ptr.hpp>
8 #include "include/err.h"
9 #include "include/rados/librados.h"
10 #include "include/types.h"
11 #include "include/stringify.h"
12 #include "include/scope_guard.h"
14 #include "common/errno.h"
16 #include "gtest/gtest.h"
20 using std::ostringstream
;
35 rados_ioctx_destroy(m_ioctx
);
36 destroy_one_pool(m_pool_name
, &m_cluster
);
43 m_pool_name
= get_temp_pool_name();
44 std::string err
= create_one_pool(m_pool_name
, &m_cluster
);
47 oss
<< "create_one_pool(" << m_pool_name
<< ") failed: error " << err
;
50 ret
= rados_ioctx_create(m_cluster
, m_pool_name
.c_str(), &m_ioctx
);
52 destroy_one_pool(m_pool_name
, &m_cluster
);
54 oss
<< "rados_ioctx_create failed: error " << ret
;
62 rados_ioctx_t m_ioctx
;
63 std::string m_pool_name
;
67 TEST(LibRadosAio
, TooBig
) {
68 AioTestData test_data
;
69 rados_completion_t my_completion
;
70 ASSERT_EQ("", test_data
.init());
71 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
72 nullptr, nullptr, &my_completion
));
74 memset(buf
, 0xcc, sizeof(buf
));
75 ASSERT_EQ(-E2BIG
, rados_aio_write(test_data
.m_ioctx
, "foo",
76 my_completion
, buf
, UINT_MAX
, 0));
77 ASSERT_EQ(-E2BIG
, rados_aio_write_full(test_data
.m_ioctx
, "foo",
78 my_completion
, buf
, UINT_MAX
));
79 ASSERT_EQ(-E2BIG
, rados_aio_append(test_data
.m_ioctx
, "foo",
80 my_completion
, buf
, UINT_MAX
));
81 rados_aio_release(my_completion
);
84 TEST(LibRadosAio
, SimpleWrite
) {
85 AioTestData test_data
;
86 rados_completion_t my_completion
;
87 ASSERT_EQ("", test_data
.init());
88 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
89 nullptr, nullptr, &my_completion
));
90 auto sg
= make_scope_guard([&] { rados_aio_release(my_completion
); });
92 memset(buf
, 0xcc, sizeof(buf
));
93 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
94 my_completion
, buf
, sizeof(buf
), 0));
97 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
99 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
101 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
102 rados_completion_t my_completion2
;
103 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
104 nullptr, nullptr, &my_completion2
));
105 auto sg2
= make_scope_guard([&] { rados_aio_release(my_completion2
); });
106 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
107 my_completion2
, buf
, sizeof(buf
), 0));
110 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
112 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
115 TEST(LibRadosAio
, WaitForSafe
) {
116 AioTestData test_data
;
117 rados_completion_t my_completion
;
118 ASSERT_EQ("", test_data
.init());
119 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
120 nullptr, nullptr, &my_completion
));
122 memset(buf
, 0xcc, sizeof(buf
));
123 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
124 my_completion
, buf
, sizeof(buf
), 0));
126 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion
));
127 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
128 rados_aio_release(my_completion
);
131 TEST(LibRadosAio
, RoundTrip
) {
132 AioTestData test_data
;
133 rados_completion_t my_completion
;
134 ASSERT_EQ("", test_data
.init());
135 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
136 nullptr, nullptr, &my_completion
));
138 memset(buf
, 0xcc, sizeof(buf
));
139 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
140 my_completion
, buf
, sizeof(buf
), 0));
143 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
145 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
147 memset(buf2
, 0, sizeof(buf2
));
148 rados_completion_t my_completion2
;
149 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
150 nullptr, nullptr, &my_completion2
));
151 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
152 my_completion2
, buf2
, sizeof(buf2
), 0));
155 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
157 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
158 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
159 rados_aio_release(my_completion
);
160 rados_aio_release(my_completion2
);
163 TEST(LibRadosAio
, RoundTrip2
) {
164 AioTestData test_data
;
165 rados_completion_t my_completion
;
166 ASSERT_EQ("", test_data
.init());
167 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
168 nullptr, nullptr, &my_completion
));
170 memset(buf
, 0xcc, sizeof(buf
));
171 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
172 my_completion
, buf
, sizeof(buf
), 0));
175 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
177 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
179 memset(buf2
, 0, sizeof(buf2
));
180 rados_completion_t my_completion2
;
181 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
182 nullptr, nullptr, &my_completion2
));
183 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
184 my_completion2
, buf2
, sizeof(buf2
), 0));
187 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
189 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
190 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
191 rados_aio_release(my_completion
);
192 rados_aio_release(my_completion2
);
195 TEST(LibRadosAio
, RoundTrip3
) {
196 AioTestData test_data
;
197 rados_completion_t my_completion
;
198 ASSERT_EQ("", test_data
.init());
199 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
200 nullptr, nullptr, &my_completion
));
202 memset(buf
, 0xcc, sizeof(buf
));
204 rados_write_op_t op1
= rados_create_write_op();
205 rados_write_op_write(op1
, buf
, sizeof(buf
), 0);
206 rados_write_op_set_alloc_hint2(op1
, 0, 0, LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
207 ASSERT_EQ(0, rados_aio_write_op_operate(op1
, test_data
.m_ioctx
, my_completion
,
209 rados_release_write_op(op1
);
213 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
216 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
217 rados_aio_release(my_completion
);
220 memset(buf2
, 0, sizeof(buf2
));
221 rados_completion_t my_completion2
;
222 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
223 nullptr, nullptr, &my_completion2
));
225 rados_read_op_t op2
= rados_create_read_op();
226 rados_read_op_read(op2
, 0, sizeof(buf2
), buf2
, NULL
, NULL
);
227 rados_read_op_set_flags(op2
, LIBRADOS_OP_FLAG_FADVISE_NOCACHE
|
228 LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
229 ceph_le32 init_value
= init_le32(-1);
230 ceph_le32 checksum
[2];
231 rados_read_op_checksum(op2
, LIBRADOS_CHECKSUM_TYPE_CRC32C
,
232 reinterpret_cast<char *>(&init_value
),
233 sizeof(init_value
), 0, 0, 0,
234 reinterpret_cast<char *>(&checksum
),
235 sizeof(checksum
), NULL
);
236 ASSERT_EQ(0, rados_aio_read_op_operate(op2
, test_data
.m_ioctx
, my_completion2
,
238 rados_release_read_op(op2
);
242 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
244 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
245 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
246 rados_aio_release(my_completion2
);
249 bl
.append(buf
, sizeof(buf
));
250 ASSERT_EQ(1U, checksum
[0]);
251 ASSERT_EQ(bl
.crc32c(-1), checksum
[1]);
254 TEST(LibRadosAio
, RoundTripAppend
) {
255 AioTestData test_data
;
256 rados_completion_t my_completion
, my_completion2
, my_completion3
;
257 ASSERT_EQ("", test_data
.init());
258 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
259 nullptr, nullptr, &my_completion
));
261 memset(buf
, 0xcc, sizeof(buf
));
262 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
263 my_completion
, buf
, sizeof(buf
)));
266 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
268 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
270 memset(buf2
, 0xdd, sizeof(buf2
));
271 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
272 nullptr, nullptr, &my_completion2
));
273 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
274 my_completion2
, buf2
, sizeof(buf2
)));
277 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
279 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
280 char buf3
[sizeof(buf
) + sizeof(buf2
)];
281 memset(buf3
, 0, sizeof(buf3
));
282 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
283 nullptr, nullptr, &my_completion3
));
284 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
285 my_completion3
, buf3
, sizeof(buf3
), 0));
288 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
290 ASSERT_EQ((int)sizeof(buf3
), rados_aio_get_return_value(my_completion3
));
291 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
292 ASSERT_EQ(0, memcmp(buf3
+ sizeof(buf
), buf2
, sizeof(buf2
)));
293 rados_aio_release(my_completion
);
294 rados_aio_release(my_completion2
);
295 rados_aio_release(my_completion3
);
298 TEST(LibRadosAio
, RemoveTest
) {
300 char buf2
[sizeof(buf
)];
301 rados_completion_t my_completion
;
302 AioTestData test_data
;
303 ASSERT_EQ("", test_data
.init());
304 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
305 nullptr, nullptr, &my_completion
));
306 memset(buf
, 0xaa, sizeof(buf
));
307 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
308 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion
));
311 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
313 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
314 memset(buf2
, 0, sizeof(buf2
));
315 ASSERT_EQ(-ENOENT
, rados_read(test_data
.m_ioctx
, "foo", buf2
, sizeof(buf2
), 0));
316 rados_aio_release(my_completion
);
319 TEST(LibRadosAio
, XattrsRoundTrip
) {
321 char attr1
[] = "attr1";
322 char attr1_buf
[] = "foo bar baz";
324 AioTestData test_data
;
325 ASSERT_EQ("", test_data
.init());
326 memset(buf
, 0xaa, sizeof(buf
));
327 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
329 rados_completion_t my_completion
;
330 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
331 nullptr, nullptr, &my_completion
));
332 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion
, attr1
, buf
, sizeof(buf
)));
335 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
337 ASSERT_EQ(-ENODATA
, rados_aio_get_return_value(my_completion
));
338 rados_aio_release(my_completion
);
340 rados_completion_t my_completion2
;
341 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
342 nullptr, nullptr, &my_completion2
));
343 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo", my_completion2
, attr1
, attr1_buf
, sizeof(attr1_buf
)));
346 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
348 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
349 rados_aio_release(my_completion2
);
351 rados_completion_t my_completion3
;
352 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
353 nullptr, nullptr, &my_completion3
));
354 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion3
, attr1
, buf
, sizeof(buf
)));
357 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
359 ASSERT_EQ((int)sizeof(attr1_buf
), rados_aio_get_return_value(my_completion3
));
360 rados_aio_release(my_completion3
);
361 // check content of attribute
362 ASSERT_EQ(0, memcmp(attr1_buf
, buf
, sizeof(attr1_buf
)));
365 TEST(LibRadosAio
, RmXattr
) {
367 char attr1
[] = "attr1";
368 char attr1_buf
[] = "foo bar baz";
370 memset(buf
, 0xaa, sizeof(buf
));
371 AioTestData test_data
;
372 ASSERT_EQ("", test_data
.init());
373 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
375 rados_completion_t my_completion
;
376 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
377 nullptr, nullptr, &my_completion
));
378 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo", my_completion
, attr1
, attr1_buf
, sizeof(attr1_buf
)));
381 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
383 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
384 rados_aio_release(my_completion
);
386 rados_completion_t my_completion2
;
387 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
388 nullptr, nullptr, &my_completion2
));
389 ASSERT_EQ(0, rados_aio_rmxattr(test_data
.m_ioctx
, "foo", my_completion2
, attr1
));
392 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
394 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
395 rados_aio_release(my_completion2
);
396 // async getxattr after deletion
397 rados_completion_t my_completion3
;
398 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
399 nullptr, nullptr, &my_completion3
));
400 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion3
, attr1
, buf
, sizeof(buf
)));
403 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
405 ASSERT_EQ(-ENODATA
, rados_aio_get_return_value(my_completion3
));
406 rados_aio_release(my_completion3
);
407 // Test rmxattr on a removed object
409 char attr2
[] = "attr2";
410 char attr2_buf
[] = "foo bar baz";
411 memset(buf2
, 0xbb, sizeof(buf2
));
412 ASSERT_EQ(0, rados_write(test_data
.m_ioctx
, "foo_rmxattr", buf2
, sizeof(buf2
), 0));
414 rados_completion_t my_completion4
;
415 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
416 nullptr, nullptr, &my_completion4
));
417 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo_rmxattr", my_completion4
, attr2
, attr2_buf
, sizeof(attr2_buf
)));
420 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
422 ASSERT_EQ(0, rados_aio_get_return_value(my_completion4
));
423 rados_aio_release(my_completion4
);
425 ASSERT_EQ(0, rados_remove(test_data
.m_ioctx
, "foo_rmxattr"));
426 // async rmxattr on non existing object
427 rados_completion_t my_completion5
;
428 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
429 nullptr, nullptr, &my_completion5
));
430 ASSERT_EQ(0, rados_aio_rmxattr(test_data
.m_ioctx
, "foo_rmxattr", my_completion5
, attr2
));
433 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion5
));
435 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion5
));
436 rados_aio_release(my_completion5
);
439 TEST(LibRadosAio
, XattrIter
) {
440 AioTestData test_data
;
441 ASSERT_EQ("", test_data
.init());
442 // Create an object with 2 attributes
444 char attr1
[] = "attr1";
445 char attr1_buf
[] = "foo bar baz";
446 char attr2
[] = "attr2";
448 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
449 attr2_buf
[j
] = j
% 0xff;
451 memset(buf
, 0xaa, sizeof(buf
));
452 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
453 ASSERT_EQ(0, rados_setxattr(test_data
.m_ioctx
, "foo", attr1
, attr1_buf
, sizeof(attr1_buf
)));
454 ASSERT_EQ(0, rados_setxattr(test_data
.m_ioctx
, "foo", attr2
, attr2_buf
, sizeof(attr2_buf
)));
455 // call async version of getxattrs and wait for completion
456 rados_completion_t my_completion
;
457 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
458 nullptr, nullptr, &my_completion
));
459 rados_xattrs_iter_t iter
;
460 ASSERT_EQ(0, rados_aio_getxattrs(test_data
.m_ioctx
, "foo", my_completion
, &iter
));
463 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
465 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
466 // loop over attributes
472 ASSERT_EQ(0, rados_getxattrs_next(iter
, &name
, &val
, &len
));
476 ASSERT_LT(num_seen
, 2);
477 if ((strcmp(name
, attr1
) == 0) && (val
!= NULL
) && (memcmp(val
, attr1_buf
, len
) == 0)) {
481 else if ((strcmp(name
, attr2
) == 0) && (val
!= NULL
) && (memcmp(val
, attr2_buf
, len
) == 0)) {
489 rados_getxattrs_end(iter
);
492 TEST(LibRadosAio
, IsComplete
) {
493 AioTestData test_data
;
494 rados_completion_t my_completion
;
495 ASSERT_EQ("", test_data
.init());
496 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
497 nullptr, nullptr, &my_completion
));
499 memset(buf
, 0xcc, sizeof(buf
));
500 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
501 my_completion
, buf
, sizeof(buf
), 0));
504 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
506 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
508 memset(buf2
, 0, sizeof(buf2
));
509 rados_completion_t my_completion2
;
510 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
511 nullptr, nullptr, &my_completion2
));
512 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
513 my_completion2
, buf2
, sizeof(buf2
), 0));
517 // Busy-wait until the AIO completes.
518 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
520 int is_complete
= rados_aio_is_complete(my_completion2
);
525 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
526 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
527 rados_aio_release(my_completion
);
528 rados_aio_release(my_completion2
);
531 TEST(LibRadosAio
, IsSafe
) {
532 AioTestData test_data
;
533 rados_completion_t my_completion
;
534 ASSERT_EQ("", test_data
.init());
535 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
536 nullptr, nullptr, &my_completion
));
538 memset(buf
, 0xcc, sizeof(buf
));
539 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
540 my_completion
, buf
, sizeof(buf
), 0));
544 // Busy-wait until the AIO completes.
545 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
547 int is_safe
= rados_aio_is_safe(my_completion
);
552 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
554 memset(buf2
, 0, sizeof(buf2
));
555 rados_completion_t my_completion2
;
556 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
557 nullptr, nullptr, &my_completion2
));
558 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
559 my_completion2
, buf2
, sizeof(buf2
), 0));
562 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
564 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
565 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
566 rados_aio_release(my_completion
);
567 rados_aio_release(my_completion2
);
570 TEST(LibRadosAio
, ReturnValue
) {
571 AioTestData test_data
;
572 rados_completion_t my_completion
;
573 ASSERT_EQ("", test_data
.init());
574 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
575 nullptr, nullptr, &my_completion
));
577 memset(buf
, 0, sizeof(buf
));
578 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "nonexistent",
579 my_completion
, buf
, sizeof(buf
), 0));
582 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
584 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion
));
585 rados_aio_release(my_completion
);
588 TEST(LibRadosAio
, Flush
) {
589 AioTestData test_data
;
590 rados_completion_t my_completion
;
591 ASSERT_EQ("", test_data
.init());
592 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
593 nullptr, nullptr, &my_completion
));
595 memset(buf
, 0xee, sizeof(buf
));
596 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
597 my_completion
, buf
, sizeof(buf
), 0));
598 ASSERT_EQ(0, rados_aio_flush(test_data
.m_ioctx
));
599 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
601 memset(buf2
, 0, sizeof(buf2
));
602 rados_completion_t my_completion2
;
603 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
604 nullptr, nullptr, &my_completion2
));
605 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
606 my_completion2
, buf2
, sizeof(buf2
), 0));
609 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
611 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
612 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
613 rados_aio_release(my_completion
);
614 rados_aio_release(my_completion2
);
617 TEST(LibRadosAio
, FlushAsync
) {
618 AioTestData test_data
;
619 rados_completion_t my_completion
;
620 ASSERT_EQ("", test_data
.init());
621 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
622 nullptr, nullptr, &my_completion
));
623 rados_completion_t flush_completion
;
624 ASSERT_EQ(0, rados_aio_create_completion(NULL
, NULL
, NULL
, &flush_completion
));
626 memset(buf
, 0xee, sizeof(buf
));
627 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
628 my_completion
, buf
, sizeof(buf
), 0));
629 ASSERT_EQ(0, rados_aio_flush_async(test_data
.m_ioctx
, flush_completion
));
632 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion
));
633 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion
));
635 ASSERT_EQ(1, rados_aio_is_complete(my_completion
));
636 ASSERT_EQ(1, rados_aio_is_safe(my_completion
));
637 ASSERT_EQ(1, rados_aio_is_complete(flush_completion
));
638 ASSERT_EQ(1, rados_aio_is_safe(flush_completion
));
639 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
641 memset(buf2
, 0, sizeof(buf2
));
642 rados_completion_t my_completion2
;
643 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
644 nullptr, nullptr, &my_completion2
));
645 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
646 my_completion2
, buf2
, sizeof(buf2
), 0));
649 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
651 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
652 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
653 rados_aio_release(my_completion
);
654 rados_aio_release(my_completion2
);
655 rados_aio_release(flush_completion
);
658 TEST(LibRadosAio
, RoundTripWriteFull
) {
659 AioTestData test_data
;
660 rados_completion_t my_completion
, my_completion2
, my_completion3
;
661 ASSERT_EQ("", test_data
.init());
662 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
663 nullptr, nullptr, &my_completion
));
665 memset(buf
, 0xcc, sizeof(buf
));
666 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
667 my_completion
, buf
, sizeof(buf
), 0));
670 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
672 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
674 memset(buf2
, 0xdd, sizeof(buf2
));
675 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
676 nullptr, nullptr, &my_completion2
));
677 ASSERT_EQ(0, rados_aio_write_full(test_data
.m_ioctx
, "foo",
678 my_completion2
, buf2
, sizeof(buf2
)));
681 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
683 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
684 char buf3
[sizeof(buf
) + sizeof(buf2
)];
685 memset(buf3
, 0, sizeof(buf3
));
686 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
687 nullptr, nullptr, &my_completion3
));
688 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
689 my_completion3
, buf3
, sizeof(buf3
), 0));
692 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
694 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion3
));
695 ASSERT_EQ(0, memcmp(buf3
, buf2
, sizeof(buf2
)));
696 rados_aio_release(my_completion
);
697 rados_aio_release(my_completion2
);
698 rados_aio_release(my_completion3
);
701 TEST(LibRadosAio
, RoundTripWriteSame
) {
702 AioTestData test_data
;
703 rados_completion_t my_completion
, my_completion2
, my_completion3
;
704 ASSERT_EQ("", test_data
.init());
705 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
706 nullptr, nullptr, &my_completion
));
708 memset(full
, 0xcc, sizeof(full
));
709 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
710 my_completion
, full
, sizeof(full
), 0));
713 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
715 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
716 /* write the same buf four times */
718 size_t ws_write_len
= sizeof(full
);
719 memset(buf
, 0xdd, sizeof(buf
));
720 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
721 nullptr, nullptr, &my_completion2
));
722 ASSERT_EQ(0, rados_aio_writesame(test_data
.m_ioctx
, "foo",
723 my_completion2
, buf
, sizeof(buf
),
727 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
729 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
730 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
731 nullptr, nullptr, &my_completion3
));
732 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
733 my_completion3
, full
, sizeof(full
), 0));
736 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
738 ASSERT_EQ((int)sizeof(full
), rados_aio_get_return_value(my_completion3
));
739 for (char *cmp
= full
; cmp
< full
+ sizeof(full
); cmp
+= sizeof(buf
)) {
740 ASSERT_EQ(0, memcmp(cmp
, buf
, sizeof(buf
)));
742 rados_aio_release(my_completion
);
743 rados_aio_release(my_completion2
);
744 rados_aio_release(my_completion3
);
747 TEST(LibRadosAio
, SimpleStat
) {
748 AioTestData test_data
;
749 rados_completion_t my_completion
;
750 ASSERT_EQ("", test_data
.init());
751 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
752 nullptr, nullptr, &my_completion
));
754 memset(buf
, 0xcc, sizeof(buf
));
755 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
756 my_completion
, buf
, sizeof(buf
), 0));
759 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
761 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
764 rados_completion_t my_completion2
;
765 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
766 nullptr, nullptr, &my_completion2
));
767 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
768 my_completion2
, &psize
, &pmtime
));
771 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
773 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
774 ASSERT_EQ(sizeof(buf
), psize
);
775 rados_aio_release(my_completion
);
776 rados_aio_release(my_completion2
);
779 TEST(LibRadosAio
, SimpleStatNS
) {
780 AioTestData test_data
;
781 rados_completion_t my_completion
;
782 ASSERT_EQ("", test_data
.init());
783 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
784 nullptr, nullptr, &my_completion
));
786 memset(buf
, 0xcc, sizeof(buf
));
787 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
788 my_completion
, buf
, sizeof(buf
), 0));
791 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
793 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
794 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
796 memset(buf2
, 0xbb, sizeof(buf2
));
797 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
798 nullptr, nullptr, &my_completion
));
799 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
800 my_completion
, buf2
, sizeof(buf2
), 0));
803 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
805 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
808 rados_completion_t my_completion2
;
809 rados_ioctx_set_namespace(test_data
.m_ioctx
, "");
810 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
811 nullptr, nullptr, &my_completion2
));
812 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
813 my_completion2
, &psize
, &pmtime
));
816 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
818 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
819 ASSERT_EQ(sizeof(buf
), psize
);
821 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
822 rados_completion_t my_completion3
;
823 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
824 nullptr, nullptr, &my_completion3
));
825 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
826 my_completion3
, &psize
, &pmtime
));
829 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
831 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
832 ASSERT_EQ(sizeof(buf2
), psize
);
834 rados_aio_release(my_completion
);
835 rados_aio_release(my_completion2
);
836 rados_aio_release(my_completion3
);
839 TEST(LibRadosAio
, StatRemove
) {
840 AioTestData test_data
;
841 rados_completion_t my_completion
;
842 ASSERT_EQ("", test_data
.init());
843 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
844 nullptr, nullptr, &my_completion
));
846 memset(buf
, 0xcc, sizeof(buf
));
847 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
848 my_completion
, buf
, sizeof(buf
), 0));
851 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
853 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
856 rados_completion_t my_completion2
;
857 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
858 nullptr, nullptr, &my_completion2
));
859 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
860 my_completion2
, &psize
, &pmtime
));
863 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
865 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
866 ASSERT_EQ(sizeof(buf
), psize
);
867 rados_completion_t my_completion3
;
868 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
869 nullptr, nullptr, &my_completion3
));
870 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion3
));
873 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
875 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
878 rados_completion_t my_completion4
;
879 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
880 nullptr, nullptr, &my_completion4
));
881 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
882 my_completion4
, &psize2
, &pmtime2
));
885 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
887 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion4
));
888 rados_aio_release(my_completion
);
889 rados_aio_release(my_completion2
);
890 rados_aio_release(my_completion3
);
891 rados_aio_release(my_completion4
);
894 TEST(LibRadosAio
, ExecuteClass
) {
895 AioTestData test_data
;
896 rados_completion_t my_completion
;
897 ASSERT_EQ("", test_data
.init());
898 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
899 nullptr, nullptr, &my_completion
));
901 memset(buf
, 0xcc, sizeof(buf
));
902 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
903 my_completion
, buf
, sizeof(buf
), 0));
906 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
908 rados_completion_t my_completion2
;
909 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
910 nullptr, nullptr, &my_completion2
));
912 ASSERT_EQ(0, rados_aio_exec(test_data
.m_ioctx
, "foo", my_completion2
,
913 "hello", "say_hello", NULL
, 0, out
, sizeof(out
)));
916 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
918 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2
));
919 ASSERT_EQ(0, strncmp("Hello, world!", out
, 13));
920 rados_aio_release(my_completion
);
921 rados_aio_release(my_completion2
);
928 TEST(LibRadosAio
, MultiWrite
) {
929 AioTestData test_data
;
930 rados_completion_t my_completion
, my_completion2
, my_completion3
;
931 ASSERT_EQ("", test_data
.init());
932 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
933 nullptr, nullptr, &my_completion
));
935 memset(buf
, 0xcc, sizeof(buf
));
936 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
937 my_completion
, buf
, sizeof(buf
), 0));
940 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
942 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
945 memset(buf2
, 0xdd, sizeof(buf2
));
946 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
947 nullptr, nullptr, &my_completion2
));
948 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
949 my_completion2
, buf2
, sizeof(buf2
), sizeof(buf
)));
952 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
954 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
956 char buf3
[(sizeof(buf
) + sizeof(buf2
)) * 3];
957 memset(buf3
, 0, sizeof(buf3
));
958 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
959 nullptr, nullptr, &my_completion3
));
960 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
961 my_completion3
, buf3
, sizeof(buf3
), 0));
964 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
966 ASSERT_EQ((int)(sizeof(buf
) + sizeof(buf2
)), rados_aio_get_return_value(my_completion3
));
967 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
968 ASSERT_EQ(0, memcmp(buf3
+ sizeof(buf
), buf2
, sizeof(buf2
)));
969 rados_aio_release(my_completion
);
970 rados_aio_release(my_completion2
);
971 rados_aio_release(my_completion3
);
974 TEST(LibRadosAio
, AioUnlock
) {
975 AioTestData test_data
;
976 ASSERT_EQ("", test_data
.init());
977 ASSERT_EQ(0, rados_lock_exclusive(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", "", NULL
, 0));
978 rados_completion_t my_completion
;
979 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
980 nullptr, nullptr, &my_completion
));
981 ASSERT_EQ(0, rados_aio_unlock(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", my_completion
));
984 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
986 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
987 ASSERT_EQ(0, rados_lock_exclusive(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", "", NULL
, 0));
1004 rados_ioctx_destroy(m_ioctx
);
1005 destroy_one_ec_pool(m_pool_name
, &m_cluster
);
1012 m_pool_name
= get_temp_pool_name();
1013 std::string err
= create_one_ec_pool(m_pool_name
, &m_cluster
);
1016 oss
<< "create_one_ec_pool(" << m_pool_name
<< ") failed: error " << err
;
1019 ret
= rados_ioctx_create(m_cluster
, m_pool_name
.c_str(), &m_ioctx
);
1021 destroy_one_ec_pool(m_pool_name
, &m_cluster
);
1023 oss
<< "rados_ioctx_create failed: error " << ret
;
1031 rados_ioctx_t m_ioctx
;
1032 std::string m_pool_name
;
1036 TEST(LibRadosAioEC
, SimpleWrite
) {
1037 AioTestDataEC test_data
;
1038 rados_completion_t my_completion
;
1039 ASSERT_EQ("", test_data
.init());
1040 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1041 nullptr, nullptr, &my_completion
));
1042 auto sg
= make_scope_guard([&] { rados_aio_release(my_completion
); });
1044 memset(buf
, 0xcc, sizeof(buf
));
1045 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1046 my_completion
, buf
, sizeof(buf
), 0));
1049 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1051 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1053 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
1054 rados_completion_t my_completion2
;
1055 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1056 nullptr, nullptr, &my_completion2
));
1057 auto sg2
= make_scope_guard([&] { rados_aio_release(my_completion2
); });
1058 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1059 my_completion2
, buf
, sizeof(buf
), 0));
1062 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1064 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1067 TEST(LibRadosAioEC
, WaitForSafe
) {
1068 AioTestDataEC test_data
;
1069 rados_completion_t my_completion
;
1070 ASSERT_EQ("", test_data
.init());
1071 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1072 nullptr, nullptr, &my_completion
));
1074 memset(buf
, 0xcc, sizeof(buf
));
1075 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1076 my_completion
, buf
, sizeof(buf
), 0));
1078 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion
));
1079 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1080 rados_aio_release(my_completion
);
1083 TEST(LibRadosAioEC
, RoundTrip
) {
1084 AioTestDataEC test_data
;
1085 rados_completion_t my_completion
;
1086 ASSERT_EQ("", test_data
.init());
1087 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1088 nullptr, nullptr, &my_completion
));
1090 memset(buf
, 0xcc, sizeof(buf
));
1091 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1092 my_completion
, buf
, sizeof(buf
), 0));
1095 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1097 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1099 memset(buf2
, 0, sizeof(buf2
));
1100 rados_completion_t my_completion2
;
1101 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1102 nullptr, nullptr, &my_completion2
));
1103 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1104 my_completion2
, buf2
, sizeof(buf2
), 0));
1107 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1109 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
1110 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1111 rados_aio_release(my_completion
);
1112 rados_aio_release(my_completion2
);
1115 TEST(LibRadosAioEC
, RoundTrip2
) {
1116 AioTestDataEC test_data
;
1117 rados_completion_t my_completion
;
1118 ASSERT_EQ("", test_data
.init());
1119 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1120 nullptr, nullptr, &my_completion
));
1122 memset(buf
, 0xcc, sizeof(buf
));
1123 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1124 my_completion
, buf
, sizeof(buf
), 0));
1127 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1129 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1131 memset(buf2
, 0, sizeof(buf2
));
1132 rados_completion_t my_completion2
;
1133 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1134 nullptr, nullptr, &my_completion2
));
1135 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1136 my_completion2
, buf2
, sizeof(buf2
), 0));
1139 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1141 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
1142 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1143 rados_aio_release(my_completion
);
1144 rados_aio_release(my_completion2
);
1147 TEST(LibRadosAioEC
, RoundTripAppend
) {
1148 AioTestDataEC test_data
;
1149 rados_completion_t my_completion
, my_completion2
, my_completion3
, my_completion4
;
1150 ASSERT_EQ("", test_data
.init());
1151 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1152 nullptr, nullptr, &my_completion
));
1154 ASSERT_EQ(0, rados_ioctx_pool_requires_alignment2(test_data
.m_ioctx
, &requires
));
1155 ASSERT_NE(0, requires
);
1157 ASSERT_EQ(0, rados_ioctx_pool_required_alignment2(test_data
.m_ioctx
, &alignment
));
1158 ASSERT_NE(0U, alignment
);
1160 int bsize
= alignment
;
1161 char *buf
= (char *)new char[bsize
];
1162 memset(buf
, 0xcc, bsize
);
1163 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
1164 my_completion
, buf
, bsize
));
1167 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1169 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1171 int hbsize
= bsize
/ 2;
1172 char *buf2
= (char *)new char[hbsize
];
1173 memset(buf2
, 0xdd, hbsize
);
1174 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1175 nullptr, nullptr, &my_completion2
));
1176 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
1177 my_completion2
, buf2
, hbsize
));
1180 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1182 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1184 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1185 nullptr, nullptr, &my_completion3
));
1186 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
1187 my_completion3
, buf2
, hbsize
));
1190 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1192 EXPECT_EQ(-EOPNOTSUPP
, rados_aio_get_return_value(my_completion3
));
1194 int tbsize
= bsize
+ hbsize
;
1195 char *buf3
= (char *)new char[tbsize
];
1196 memset(buf3
, 0, tbsize
);
1197 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1198 nullptr, nullptr, &my_completion4
));
1199 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1200 my_completion4
, buf3
, bsize
* 3, 0));
1203 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
1205 ASSERT_EQ(tbsize
, rados_aio_get_return_value(my_completion4
));
1206 ASSERT_EQ(0, memcmp(buf3
, buf
, bsize
));
1207 ASSERT_EQ(0, memcmp(buf3
+ bsize
, buf2
, hbsize
));
1208 rados_aio_release(my_completion
);
1209 rados_aio_release(my_completion2
);
1210 rados_aio_release(my_completion3
);
1211 rados_aio_release(my_completion4
);
1217 TEST(LibRadosAioEC
, IsComplete
) {
1218 AioTestDataEC test_data
;
1219 rados_completion_t my_completion
;
1220 ASSERT_EQ("", test_data
.init());
1221 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1222 nullptr, nullptr, &my_completion
));
1224 memset(buf
, 0xcc, sizeof(buf
));
1225 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1226 my_completion
, buf
, sizeof(buf
), 0));
1229 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1231 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1233 memset(buf2
, 0, sizeof(buf2
));
1234 rados_completion_t my_completion2
;
1235 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1236 nullptr, nullptr, &my_completion2
));
1237 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1238 my_completion2
, buf2
, sizeof(buf2
), 0));
1242 // Busy-wait until the AIO completes.
1243 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
1245 int is_complete
= rados_aio_is_complete(my_completion2
);
1250 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
1251 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1252 rados_aio_release(my_completion
);
1253 rados_aio_release(my_completion2
);
1256 TEST(LibRadosAioEC
, IsSafe
) {
1257 AioTestDataEC test_data
;
1258 rados_completion_t my_completion
;
1259 ASSERT_EQ("", test_data
.init());
1260 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1261 nullptr, nullptr, &my_completion
));
1263 memset(buf
, 0xcc, sizeof(buf
));
1264 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1265 my_completion
, buf
, sizeof(buf
), 0));
1269 // Busy-wait until the AIO completes.
1270 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1272 int is_safe
= rados_aio_is_safe(my_completion
);
1277 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1279 memset(buf2
, 0, sizeof(buf2
));
1280 rados_completion_t my_completion2
;
1281 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1282 nullptr, nullptr, &my_completion2
));
1283 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1284 my_completion2
, buf2
, sizeof(buf2
), 0));
1287 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1289 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
1290 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1291 rados_aio_release(my_completion
);
1292 rados_aio_release(my_completion2
);
1295 TEST(LibRadosAioEC
, ReturnValue
) {
1296 AioTestDataEC test_data
;
1297 rados_completion_t my_completion
;
1298 ASSERT_EQ("", test_data
.init());
1299 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1300 nullptr, nullptr, &my_completion
));
1302 memset(buf
, 0, sizeof(buf
));
1303 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "nonexistent",
1304 my_completion
, buf
, sizeof(buf
), 0));
1307 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1309 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion
));
1310 rados_aio_release(my_completion
);
1313 TEST(LibRadosAioEC
, Flush
) {
1314 AioTestDataEC test_data
;
1315 rados_completion_t my_completion
;
1316 ASSERT_EQ("", test_data
.init());
1317 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1318 nullptr, nullptr, &my_completion
));
1320 memset(buf
, 0xee, sizeof(buf
));
1321 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1322 my_completion
, buf
, sizeof(buf
), 0));
1323 ASSERT_EQ(0, rados_aio_flush(test_data
.m_ioctx
));
1324 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1326 memset(buf2
, 0, sizeof(buf2
));
1327 rados_completion_t my_completion2
;
1328 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1329 nullptr, nullptr, &my_completion2
));
1330 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1331 my_completion2
, buf2
, sizeof(buf2
), 0));
1334 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1336 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
1337 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1338 rados_aio_release(my_completion
);
1339 rados_aio_release(my_completion2
);
1342 TEST(LibRadosAioEC
, FlushAsync
) {
1343 AioTestDataEC test_data
;
1344 rados_completion_t my_completion
;
1345 ASSERT_EQ("", test_data
.init());
1346 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1347 nullptr, nullptr, &my_completion
));
1348 rados_completion_t flush_completion
;
1349 ASSERT_EQ(0, rados_aio_create_completion(NULL
, NULL
, NULL
, &flush_completion
));
1351 memset(buf
, 0xee, sizeof(buf
));
1352 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1353 my_completion
, buf
, sizeof(buf
), 0));
1354 ASSERT_EQ(0, rados_aio_flush_async(test_data
.m_ioctx
, flush_completion
));
1357 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion
));
1358 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion
));
1360 ASSERT_EQ(1, rados_aio_is_complete(my_completion
));
1361 ASSERT_EQ(1, rados_aio_is_safe(my_completion
));
1362 ASSERT_EQ(1, rados_aio_is_complete(flush_completion
));
1363 ASSERT_EQ(1, rados_aio_is_safe(flush_completion
));
1364 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1366 memset(buf2
, 0, sizeof(buf2
));
1367 rados_completion_t my_completion2
;
1368 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1369 nullptr, nullptr, &my_completion2
));
1370 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1371 my_completion2
, buf2
, sizeof(buf2
), 0));
1374 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1376 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
1377 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1378 rados_aio_release(my_completion
);
1379 rados_aio_release(my_completion2
);
1380 rados_aio_release(flush_completion
);
1383 TEST(LibRadosAioEC
, RoundTripWriteFull
) {
1384 AioTestDataEC test_data
;
1385 rados_completion_t my_completion
, my_completion2
, my_completion3
;
1386 ASSERT_EQ("", test_data
.init());
1387 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1388 nullptr, nullptr, &my_completion
));
1390 memset(buf
, 0xcc, sizeof(buf
));
1391 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1392 my_completion
, buf
, sizeof(buf
), 0));
1395 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1397 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1399 memset(buf2
, 0xdd, sizeof(buf2
));
1400 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1401 nullptr, nullptr, &my_completion2
));
1402 ASSERT_EQ(0, rados_aio_write_full(test_data
.m_ioctx
, "foo",
1403 my_completion2
, buf2
, sizeof(buf2
)));
1406 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1408 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1409 char buf3
[sizeof(buf
) + sizeof(buf2
)];
1410 memset(buf3
, 0, sizeof(buf3
));
1411 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1412 nullptr, nullptr, &my_completion3
));
1413 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1414 my_completion3
, buf3
, sizeof(buf3
), 0));
1417 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1419 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion3
));
1420 ASSERT_EQ(0, memcmp(buf3
, buf2
, sizeof(buf2
)));
1421 rados_aio_release(my_completion
);
1422 rados_aio_release(my_completion2
);
1423 rados_aio_release(my_completion3
);
1426 TEST(LibRadosAioEC
, SimpleStat
) {
1427 AioTestDataEC test_data
;
1428 rados_completion_t my_completion
;
1429 ASSERT_EQ("", test_data
.init());
1430 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1431 nullptr, nullptr, &my_completion
));
1433 memset(buf
, 0xcc, sizeof(buf
));
1434 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1435 my_completion
, buf
, sizeof(buf
), 0));
1438 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1440 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1443 rados_completion_t my_completion2
;
1444 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1445 nullptr, nullptr, &my_completion2
));
1446 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1447 my_completion2
, &psize
, &pmtime
));
1450 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1452 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1453 ASSERT_EQ(sizeof(buf
), psize
);
1454 rados_aio_release(my_completion
);
1455 rados_aio_release(my_completion2
);
1459 TEST(LibRadosAioEC
, SimpleStatNS
) {
1460 AioTestDataEC test_data
;
1461 rados_completion_t my_completion
;
1462 ASSERT_EQ("", test_data
.init());
1463 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1464 nullptr, nullptr, &my_completion
));
1466 memset(buf
, 0xcc, sizeof(buf
));
1467 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1468 my_completion
, buf
, sizeof(buf
), 0));
1471 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1473 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1474 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
1476 memset(buf2
, 0xbb, sizeof(buf2
));
1477 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1478 nullptr, nullptr, &my_completion
));
1479 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1480 my_completion
, buf2
, sizeof(buf2
), 0));
1483 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1485 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1488 rados_completion_t my_completion2
;
1489 rados_ioctx_set_namespace(test_data
.m_ioctx
, "");
1490 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1491 nullptr, nullptr, &my_completion2
));
1492 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1493 my_completion2
, &psize
, &pmtime
));
1496 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1498 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1499 ASSERT_EQ(sizeof(buf
), psize
);
1501 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
1502 rados_completion_t my_completion3
;
1503 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1504 nullptr, nullptr, &my_completion3
));
1505 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1506 my_completion3
, &psize
, &pmtime
));
1509 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1511 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
1512 ASSERT_EQ(sizeof(buf2
), psize
);
1514 rados_aio_release(my_completion
);
1515 rados_aio_release(my_completion2
);
1516 rados_aio_release(my_completion3
);
1519 TEST(LibRadosAioEC
, StatRemove
) {
1520 AioTestDataEC test_data
;
1521 rados_completion_t my_completion
;
1522 ASSERT_EQ("", test_data
.init());
1523 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1524 nullptr, nullptr, &my_completion
));
1526 memset(buf
, 0xcc, sizeof(buf
));
1527 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1528 my_completion
, buf
, sizeof(buf
), 0));
1531 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1533 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1536 rados_completion_t my_completion2
;
1537 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1538 nullptr, nullptr, &my_completion2
));
1539 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1540 my_completion2
, &psize
, &pmtime
));
1543 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1545 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1546 ASSERT_EQ(sizeof(buf
), psize
);
1547 rados_completion_t my_completion3
;
1548 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1549 nullptr, nullptr, &my_completion3
));
1550 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion3
));
1553 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1555 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
1558 rados_completion_t my_completion4
;
1559 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1560 nullptr, nullptr, &my_completion4
));
1561 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1562 my_completion4
, &psize2
, &pmtime2
));
1565 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
1567 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion4
));
1568 rados_aio_release(my_completion
);
1569 rados_aio_release(my_completion2
);
1570 rados_aio_release(my_completion3
);
1571 rados_aio_release(my_completion4
);
1574 TEST(LibRadosAioEC
, ExecuteClass
) {
1575 AioTestDataEC test_data
;
1576 rados_completion_t my_completion
;
1577 ASSERT_EQ("", test_data
.init());
1578 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1579 nullptr, nullptr, &my_completion
));
1581 memset(buf
, 0xcc, sizeof(buf
));
1582 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1583 my_completion
, buf
, sizeof(buf
), 0));
1586 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1588 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1589 rados_completion_t my_completion2
;
1590 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1591 nullptr, nullptr, &my_completion2
));
1593 ASSERT_EQ(0, rados_aio_exec(test_data
.m_ioctx
, "foo", my_completion2
,
1594 "hello", "say_hello", NULL
, 0, out
, sizeof(out
)));
1597 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1599 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2
));
1600 ASSERT_EQ(0, strncmp("Hello, world!", out
, 13));
1601 rados_aio_release(my_completion
);
1602 rados_aio_release(my_completion2
);
1605 TEST(LibRadosAioEC
, MultiWrite
) {
1606 AioTestDataEC test_data
;
1607 rados_completion_t my_completion
, my_completion2
, my_completion3
;
1608 ASSERT_EQ("", test_data
.init());
1609 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1610 nullptr, nullptr, &my_completion
));
1612 memset(buf
, 0xcc, sizeof(buf
));
1613 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1614 my_completion
, buf
, sizeof(buf
), 0));
1617 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1619 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1622 memset(buf2
, 0xdd, sizeof(buf2
));
1623 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1624 nullptr, nullptr, &my_completion2
));
1625 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1626 my_completion2
, buf2
, sizeof(buf2
), sizeof(buf
)));
1629 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1631 ASSERT_EQ(-EOPNOTSUPP
, rados_aio_get_return_value(my_completion2
));
1633 char buf3
[(sizeof(buf
) + sizeof(buf2
)) * 3];
1634 memset(buf3
, 0, sizeof(buf3
));
1635 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1636 nullptr, nullptr, &my_completion3
));
1637 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1638 my_completion3
, buf3
, sizeof(buf3
), 0));
1641 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1643 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion3
));
1644 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
1645 rados_aio_release(my_completion
);
1646 rados_aio_release(my_completion2
);
1647 rados_aio_release(my_completion3
);