1 #include "common/errno.h"
2 #include "include/err.h"
3 #include "include/rados/librados.h"
4 #include "test/librados/test.h"
5 #include "include/types.h"
6 #include "include/stringify.h"
8 #include "gtest/gtest.h"
11 #include <semaphore.h>
14 #include <boost/scoped_ptr.hpp>
17 using std::ostringstream
;
18 using namespace librados
;
36 rados_ioctx_destroy(m_ioctx
);
37 destroy_one_pool(m_pool_name
, &m_cluster
);
45 if (SEM_FAILED
== (m_sem
= sem_open("/test_aio_sem", O_CREAT
, 0644, 0))) {
48 oss
<< "sem_open failed: " << cpp_strerror(err
);
51 m_pool_name
= get_temp_pool_name();
52 std::string err
= create_one_pool(m_pool_name
, &m_cluster
);
56 oss
<< "create_one_pool(" << m_pool_name
<< ") failed: error " << err
;
59 ret
= rados_ioctx_create(m_cluster
, m_pool_name
.c_str(), &m_ioctx
);
62 destroy_one_pool(m_pool_name
, &m_cluster
);
64 oss
<< "rados_ioctx_create failed: error " << ret
;
73 rados_ioctx_t m_ioctx
;
74 std::string m_pool_name
;
94 destroy_one_pool_pp(m_pool_name
, m_cluster
);
104 std::string
init(const std::map
<std::string
, std::string
> &config
)
108 if (SEM_FAILED
== (m_sem
= sem_open("/test_aio_sem", O_CREAT
, 0644, 0))) {
111 oss
<< "sem_open failed: " << cpp_strerror(err
);
114 m_pool_name
= get_temp_pool_name();
115 std::string err
= create_one_pool_pp(m_pool_name
, m_cluster
, config
);
119 oss
<< "create_one_pool(" << m_pool_name
<< ") failed: error " << err
;
122 ret
= m_cluster
.ioctx_create(m_pool_name
.c_str(), m_ioctx
);
125 destroy_one_pool_pp(m_pool_name
, m_cluster
);
127 oss
<< "rados_ioctx_create failed: error " << ret
;
137 std::string m_pool_name
;
143 void set_completion_complete(rados_completion_t cb
, void *arg
)
145 AioTestData
*test
= static_cast<AioTestData
*>(arg
);
146 test
->m_complete
= true;
147 sem_post(test
->m_sem
);
150 void set_completion_safe(rados_completion_t cb
, void *arg
)
152 AioTestData
*test
= static_cast<AioTestData
*>(arg
);
154 sem_post(test
->m_sem
);
157 void set_completion_completePP(rados_completion_t cb
, void *arg
)
159 AioTestDataPP
*test
= static_cast<AioTestDataPP
*>(arg
);
160 test
->m_complete
= true;
161 sem_post(test
->m_sem
);
164 void set_completion_safePP(rados_completion_t cb
, void *arg
)
166 AioTestDataPP
*test
= static_cast<AioTestDataPP
*>(arg
);
168 sem_post(test
->m_sem
);
171 TEST(LibRadosAio
, TooBig
) {
172 AioTestData test_data
;
173 rados_completion_t my_completion
;
174 ASSERT_EQ("", test_data
.init());
175 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
176 set_completion_complete
, set_completion_safe
, &my_completion
));
178 memset(buf
, 0xcc, sizeof(buf
));
179 ASSERT_EQ(-E2BIG
, rados_aio_write(test_data
.m_ioctx
, "foo",
180 my_completion
, buf
, UINT_MAX
, 0));
181 ASSERT_EQ(-E2BIG
, rados_aio_write_full(test_data
.m_ioctx
, "foo",
182 my_completion
, buf
, UINT_MAX
));
183 ASSERT_EQ(-E2BIG
, rados_aio_append(test_data
.m_ioctx
, "foo",
184 my_completion
, buf
, UINT_MAX
));
185 rados_aio_release(my_completion
);
188 TEST(LibRadosAio
, TooBigPP
) {
189 AioTestDataPP test_data
;
190 ASSERT_EQ("", test_data
.init());
193 AioCompletion
*aio_completion
= test_data
.m_cluster
.aio_create_completion(
194 (void*)&test_data
, NULL
, NULL
);
195 ASSERT_EQ(-E2BIG
, test_data
.m_ioctx
.aio_write("foo", aio_completion
, bl
, UINT_MAX
, 0));
196 ASSERT_EQ(-E2BIG
, test_data
.m_ioctx
.aio_append("foo", aio_completion
, bl
, UINT_MAX
));
197 // ioctx.aio_write_full no way to overflow bl.length()
198 delete aio_completion
;
201 TEST(LibRadosAio
, PoolQuotaPP
) {
202 AioTestDataPP test_data
;
203 ASSERT_EQ("", test_data
.init());
204 string p
= get_temp_pool_name();
205 ASSERT_EQ(0, test_data
.m_cluster
.pool_create(p
.c_str()));
207 ASSERT_EQ(0, test_data
.m_cluster
.ioctx_create(p
.c_str(), ioctx
));
210 ASSERT_EQ(0, test_data
.m_cluster
.mon_command(
211 "{\"prefix\": \"osd pool set-quota\", \"pool\": \"" + p
+
212 "\", \"field\": \"max_bytes\", \"val\": \"4096\"}",
219 for (n
= 0; n
< 1024; ++n
) {
220 ObjectWriteOperation op
;
222 librados::AioCompletion
*completion
=
223 test_data
.m_cluster
.aio_create_completion();
224 ASSERT_EQ(0, ioctx
.aio_operate(
225 "foo" + stringify(n
), completion
, &op
,
226 librados::OPERATION_FULL_TRY
));
227 completion
->wait_for_safe();
228 int r
= completion
->get_return_value();
229 completion
->release();
237 // make sure we block without FULL_TRY
239 ObjectWriteOperation op
;
241 librados::AioCompletion
*completion
=
242 test_data
.m_cluster
.aio_create_completion();
243 ASSERT_EQ(0, ioctx
.aio_operate("bar", completion
, &op
, 0));
245 ASSERT_FALSE(completion
->is_safe());
246 completion
->release();
250 ASSERT_EQ(0, test_data
.m_cluster
.pool_delete(p
.c_str()));
253 TEST(LibRadosAio
, SimpleWrite
) {
254 AioTestData test_data
;
255 rados_completion_t my_completion
;
256 ASSERT_EQ("", test_data
.init());
257 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
258 set_completion_complete
, set_completion_safe
, &my_completion
));
260 memset(buf
, 0xcc, sizeof(buf
));
261 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
262 my_completion
, buf
, sizeof(buf
), 0));
265 sem_wait(test_data
.m_sem
);
266 sem_wait(test_data
.m_sem
);
268 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
270 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
271 rados_completion_t my_completion2
;
272 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
273 set_completion_complete
, set_completion_safe
, &my_completion2
));
274 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
275 my_completion2
, buf
, sizeof(buf
), 0));
278 sem_wait(test_data
.m_sem
);
279 sem_wait(test_data
.m_sem
);
281 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
282 rados_aio_release(my_completion
);
283 rados_aio_release(my_completion2
);
286 TEST(LibRadosAio
, SimpleWritePP
) {
288 memset(buf
, 0xcc, sizeof(buf
));
290 bl1
.append(buf
, sizeof(buf
));
292 AioTestDataPP test_data
;
293 ASSERT_EQ("", test_data
.init());
294 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
295 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
296 AioCompletion
*my_completion_null
= NULL
;
297 ASSERT_NE(my_completion
, my_completion_null
);
298 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
299 my_completion
, bl1
, sizeof(buf
), 0));
302 sem_wait(test_data
.m_sem
);
303 sem_wait(test_data
.m_sem
);
305 ASSERT_EQ(0, my_completion
->get_return_value());
306 delete my_completion
;
310 AioTestDataPP test_data
;
311 ASSERT_EQ("", test_data
.init());
312 test_data
.m_ioctx
.set_namespace("nspace");
313 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
314 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
315 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
316 my_completion
, bl1
, sizeof(buf
), 0));
319 sem_wait(test_data
.m_sem
);
320 sem_wait(test_data
.m_sem
);
322 ASSERT_EQ(0, my_completion
->get_return_value());
323 delete my_completion
;
327 TEST(LibRadosAio
, WaitForSafe
) {
328 AioTestData test_data
;
329 rados_completion_t my_completion
;
330 ASSERT_EQ("", test_data
.init());
331 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
332 set_completion_complete
, set_completion_safe
, &my_completion
));
334 memset(buf
, 0xcc, sizeof(buf
));
335 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
336 my_completion
, buf
, sizeof(buf
), 0));
338 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion
));
339 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
340 rados_aio_release(my_completion
);
343 TEST(LibRadosAio
, WaitForSafePP
) {
344 AioTestDataPP test_data
;
345 ASSERT_EQ("", test_data
.init());
346 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
347 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
348 AioCompletion
*my_completion_null
= NULL
;
349 ASSERT_NE(my_completion
, my_completion_null
);
351 memset(buf
, 0xcc, sizeof(buf
));
353 bl1
.append(buf
, sizeof(buf
));
354 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
355 my_completion
, bl1
, sizeof(buf
), 0));
357 ASSERT_EQ(0, my_completion
->wait_for_safe());
358 ASSERT_EQ(0, my_completion
->get_return_value());
359 delete my_completion
;
362 TEST(LibRadosAio
, RoundTrip
) {
363 AioTestData test_data
;
364 rados_completion_t my_completion
;
365 ASSERT_EQ("", test_data
.init());
366 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
367 set_completion_complete
, set_completion_safe
, &my_completion
));
369 memset(buf
, 0xcc, sizeof(buf
));
370 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
371 my_completion
, buf
, sizeof(buf
), 0));
374 sem_wait(test_data
.m_sem
);
375 sem_wait(test_data
.m_sem
);
377 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
379 memset(buf2
, 0, sizeof(buf2
));
380 rados_completion_t my_completion2
;
381 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
382 set_completion_complete
, set_completion_safe
, &my_completion2
));
383 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
384 my_completion2
, buf2
, sizeof(buf2
), 0));
387 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
389 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
390 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
391 rados_aio_release(my_completion
);
392 rados_aio_release(my_completion2
);
395 TEST(LibRadosAio
, RoundTrip2
) {
396 AioTestData test_data
;
397 rados_completion_t my_completion
;
398 ASSERT_EQ("", test_data
.init());
399 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
400 set_completion_complete
, set_completion_safe
, &my_completion
));
402 memset(buf
, 0xcc, sizeof(buf
));
403 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
404 my_completion
, buf
, sizeof(buf
), 0));
407 sem_wait(test_data
.m_sem
);
408 sem_wait(test_data
.m_sem
);
410 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
412 memset(buf2
, 0, sizeof(buf2
));
413 rados_completion_t my_completion2
;
414 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
415 set_completion_complete
, set_completion_safe
, &my_completion2
));
416 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
417 my_completion2
, buf2
, sizeof(buf2
), 0));
420 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
422 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
423 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
424 rados_aio_release(my_completion
);
425 rados_aio_release(my_completion2
);
428 TEST(LibRadosAio
, RoundTrip3
) {
429 AioTestData test_data
;
430 rados_completion_t my_completion
;
431 ASSERT_EQ("", test_data
.init());
432 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
433 set_completion_complete
, set_completion_safe
, &my_completion
));
435 memset(buf
, 0xcc, sizeof(buf
));
437 rados_write_op_t op1
= rados_create_write_op();
438 rados_write_op_write(op1
, buf
, sizeof(buf
), 0);
439 rados_write_op_set_alloc_hint2(op1
, 0, 0, LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
440 ASSERT_EQ(0, rados_aio_write_op_operate(op1
, test_data
.m_ioctx
, my_completion
,
442 rados_release_write_op(op1
);
446 sem_wait(test_data
.m_sem
);
447 sem_wait(test_data
.m_sem
);
450 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
451 rados_aio_release(my_completion
);
454 memset(buf2
, 0, sizeof(buf2
));
455 rados_completion_t my_completion2
;
456 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
457 set_completion_complete
, set_completion_safe
, &my_completion2
));
459 rados_read_op_t op2
= rados_create_read_op();
460 rados_read_op_read(op2
, 0, sizeof(buf2
), buf2
, NULL
, NULL
);
461 rados_read_op_set_flags(op2
, LIBRADOS_OP_FLAG_FADVISE_NOCACHE
|
462 LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
463 __le32 init_value
= -1;
465 rados_read_op_checksum(op2
, LIBRADOS_CHECKSUM_TYPE_CRC32C
,
466 reinterpret_cast<char *>(&init_value
),
467 sizeof(init_value
), 0, 0, 0,
468 reinterpret_cast<char *>(&checksum
),
469 sizeof(checksum
), NULL
);
470 ASSERT_EQ(0, rados_aio_read_op_operate(op2
, test_data
.m_ioctx
, my_completion2
,
472 rados_release_read_op(op2
);
476 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
478 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
479 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
480 rados_aio_release(my_completion2
);
483 bl
.append(buf
, sizeof(buf
));
484 ASSERT_EQ(1U, checksum
[0]);
485 ASSERT_EQ(bl
.crc32c(-1), checksum
[1]);
488 TEST(LibRadosAio
, RoundTripPP
) {
489 AioTestDataPP test_data
;
490 ASSERT_EQ("", test_data
.init());
491 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
492 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
493 AioCompletion
*my_completion_null
= NULL
;
494 ASSERT_NE(my_completion
, my_completion_null
);
496 memset(buf
, 0xcc, sizeof(buf
));
498 bl1
.append(buf
, sizeof(buf
));
499 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
500 bl1
, sizeof(buf
), 0));
503 sem_wait(test_data
.m_sem
);
504 sem_wait(test_data
.m_sem
);
506 ASSERT_EQ(0, my_completion
->get_return_value());
508 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
509 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
510 ASSERT_NE(my_completion2
, my_completion_null
);
511 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
512 my_completion2
, &bl2
, sizeof(buf
), 0));
515 ASSERT_EQ(0, my_completion2
->wait_for_complete());
517 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
518 ASSERT_EQ(sizeof(buf
), bl2
.length());
519 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
520 delete my_completion
;
521 delete my_completion2
;
524 TEST(LibRadosAio
, RoundTripPP2
) {
525 AioTestDataPP test_data
;
526 ASSERT_EQ("", test_data
.init());
527 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
528 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
529 AioCompletion
*my_completion_null
= NULL
;
530 ASSERT_NE(my_completion
, my_completion_null
);
532 memset(buf
, 0xcc, sizeof(buf
));
534 bl1
.append(buf
, sizeof(buf
));
535 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
536 bl1
, sizeof(buf
), 0));
539 sem_wait(test_data
.m_sem
);
540 sem_wait(test_data
.m_sem
);
542 ASSERT_EQ(0, my_completion
->get_return_value());
544 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
545 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
546 ASSERT_NE(my_completion2
, my_completion_null
);
547 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
548 my_completion2
, &bl2
, sizeof(buf
), 0));
551 ASSERT_EQ(0, my_completion2
->wait_for_safe());
552 ASSERT_EQ(0, my_completion2
->wait_for_complete());
554 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
555 ASSERT_EQ(sizeof(buf
), bl2
.length());
556 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
557 delete my_completion
;
558 delete my_completion2
;
561 //using ObjectWriteOperation/ObjectReadOperation with iohint
562 TEST(LibRadosAio
, RoundTripPP3
)
565 std::string pool_name
= get_temp_pool_name();
566 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
568 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
570 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
571 ObjectWriteOperation op
;
573 memset(buf
, 0xcc, sizeof(buf
));
575 bl
.append(buf
, sizeof(buf
));
578 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
579 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
582 ASSERT_EQ(0, my_completion1
->wait_for_complete());
584 EXPECT_EQ(0, my_completion1
->get_return_value());
586 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
588 ObjectReadOperation op1
;
589 op1
.read(0, sizeof(buf
), &bl
, NULL
);
590 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
591 bufferlist init_value_bl
;
592 ::encode(static_cast<int32_t>(-1), init_value_bl
);
594 op1
.checksum(LIBRADOS_CHECKSUM_TYPE_CRC32C
, init_value_bl
,
595 0, 0, 0, &csum_bl
, nullptr);
596 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
599 ASSERT_EQ(0, my_completion2
->wait_for_complete());
601 EXPECT_EQ(0, my_completion2
->get_return_value());
602 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
604 ASSERT_EQ(8U, csum_bl
.length());
605 auto csum_bl_it
= csum_bl
.begin();
608 ::decode(csum_count
, csum_bl_it
);
609 ASSERT_EQ(1U, csum_count
);
610 ::decode(csum
, csum_bl_it
);
611 ASSERT_EQ(bl
.crc32c(-1), csum
);
612 ioctx
.remove("test_obj");
613 destroy_one_pool_pp(pool_name
, cluster
);
616 TEST(LibRadosAio
, RoundTripSparseReadPP
) {
617 AioTestDataPP test_data
;
618 ASSERT_EQ("", test_data
.init());
619 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
620 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
621 AioCompletion
*my_completion_null
= NULL
;
622 ASSERT_NE(my_completion
, my_completion_null
);
624 memset(buf
, 0xcc, sizeof(buf
));
626 bl1
.append(buf
, sizeof(buf
));
627 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
628 bl1
, sizeof(buf
), 0));
631 sem_wait(test_data
.m_sem
);
632 sem_wait(test_data
.m_sem
);
634 ASSERT_EQ(0, my_completion
->get_return_value());
635 std::map
<uint64_t, uint64_t> extents
;
637 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
638 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
639 ASSERT_NE(my_completion2
, my_completion_null
);
640 ASSERT_EQ(0, test_data
.m_ioctx
.aio_sparse_read("foo",
641 my_completion2
, &extents
, &bl2
, sizeof(buf
), 0));
644 ASSERT_EQ(0, my_completion2
->wait_for_complete());
646 ASSERT_EQ(0, my_completion2
->get_return_value());
647 assert_eq_sparse(bl1
, extents
, bl2
);
648 delete my_completion
;
649 delete my_completion2
;
652 TEST(LibRadosAio
, RoundTripAppend
) {
653 AioTestData test_data
;
654 rados_completion_t my_completion
, my_completion2
, my_completion3
;
655 ASSERT_EQ("", test_data
.init());
656 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
657 set_completion_complete
, set_completion_safe
, &my_completion
));
659 memset(buf
, 0xcc, sizeof(buf
));
660 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
661 my_completion
, buf
, sizeof(buf
)));
664 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
666 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
668 memset(buf2
, 0xdd, sizeof(buf2
));
669 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
670 set_completion_complete
, set_completion_safe
, &my_completion2
));
671 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
672 my_completion2
, buf2
, sizeof(buf2
)));
675 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
677 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
678 char buf3
[sizeof(buf
) + sizeof(buf2
)];
679 memset(buf3
, 0, sizeof(buf3
));
680 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
681 set_completion_complete
, set_completion_safe
, &my_completion3
));
682 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
683 my_completion3
, buf3
, sizeof(buf3
), 0));
686 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
688 ASSERT_EQ((int)sizeof(buf3
), rados_aio_get_return_value(my_completion3
));
689 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
690 ASSERT_EQ(0, memcmp(buf3
+ sizeof(buf
), buf2
, sizeof(buf2
)));
691 rados_aio_release(my_completion
);
692 rados_aio_release(my_completion2
);
693 rados_aio_release(my_completion3
);
696 TEST(LibRadosAio
, RoundTripAppendPP
) {
697 AioTestDataPP test_data
;
698 ASSERT_EQ("", test_data
.init());
699 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
700 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
701 AioCompletion
*my_completion_null
= NULL
;
702 ASSERT_NE(my_completion
, my_completion_null
);
704 memset(buf
, 0xcc, sizeof(buf
));
706 bl1
.append(buf
, sizeof(buf
));
707 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion
,
711 ASSERT_EQ(0, my_completion
->wait_for_complete());
713 ASSERT_EQ(0, my_completion
->get_return_value());
715 memset(buf2
, 0xdd, sizeof(buf2
));
717 bl2
.append(buf2
, sizeof(buf2
));
718 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
719 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
720 ASSERT_NE(my_completion2
, my_completion_null
);
721 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion2
,
725 ASSERT_EQ(0, my_completion2
->wait_for_complete());
727 ASSERT_EQ(0, my_completion2
->get_return_value());
729 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
730 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
731 ASSERT_NE(my_completion3
, my_completion_null
);
732 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
733 my_completion3
, &bl3
, 2 * sizeof(buf
), 0));
736 ASSERT_EQ(0, my_completion3
->wait_for_complete());
738 ASSERT_EQ((int)(sizeof(buf
) * 2), my_completion3
->get_return_value());
739 ASSERT_EQ(sizeof(buf
) * 2, bl3
.length());
740 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, sizeof(buf
)));
741 ASSERT_EQ(0, memcmp(bl3
.c_str() + sizeof(buf
), buf2
, sizeof(buf2
)));
742 delete my_completion
;
743 delete my_completion2
;
744 delete my_completion3
;
747 TEST(LibRadosAio
, RemoveTest
) {
749 char buf2
[sizeof(buf
)];
750 rados_completion_t my_completion
;
751 AioTestData test_data
;
752 ASSERT_EQ("", test_data
.init());
753 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
754 set_completion_complete
, set_completion_safe
, &my_completion
));
755 memset(buf
, 0xaa, sizeof(buf
));
756 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
757 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion
));
760 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
762 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
763 memset(buf2
, 0, sizeof(buf2
));
764 ASSERT_EQ(-ENOENT
, rados_read(test_data
.m_ioctx
, "foo", buf2
, sizeof(buf2
), 0));
765 rados_aio_release(my_completion
);
768 TEST(LibRadosAioPP
, RemoveTestPP
) {
770 memset(buf
, 0xaa, sizeof(buf
));
772 bl1
.append(buf
, sizeof(buf
));
773 AioTestDataPP test_data
;
774 ASSERT_EQ("", test_data
.init());
775 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
776 boost::scoped_ptr
<AioCompletion
> my_completion
777 (test_data
.m_cluster
.aio_create_completion
778 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
779 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion
.get()));
782 ASSERT_EQ(0, my_completion
->wait_for_complete());
784 ASSERT_EQ(0, my_completion
->get_return_value());
786 ASSERT_EQ(-ENOENT
, test_data
.m_ioctx
.read("foo", bl2
, sizeof(buf
), 0));
789 TEST(LibRadosAio
, XattrsRoundTrip
) {
791 char attr1
[] = "attr1";
792 char attr1_buf
[] = "foo bar baz";
794 AioTestData test_data
;
795 ASSERT_EQ("", test_data
.init());
796 memset(buf
, 0xaa, sizeof(buf
));
797 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
799 rados_completion_t my_completion
;
800 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
801 set_completion_complete
, set_completion_safe
, &my_completion
));
802 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion
, attr1
, buf
, sizeof(buf
)));
805 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
807 ASSERT_EQ(-ENODATA
, rados_aio_get_return_value(my_completion
));
808 rados_aio_release(my_completion
);
810 rados_completion_t my_completion2
;
811 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
812 set_completion_complete
, set_completion_safe
, &my_completion2
));
813 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo", my_completion2
, attr1
, attr1_buf
, sizeof(attr1_buf
)));
816 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
818 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
819 rados_aio_release(my_completion2
);
821 rados_completion_t my_completion3
;
822 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
823 set_completion_complete
, set_completion_safe
, &my_completion3
));
824 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion3
, attr1
, buf
, sizeof(buf
)));
827 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
829 ASSERT_EQ((int)sizeof(attr1_buf
), rados_aio_get_return_value(my_completion3
));
830 rados_aio_release(my_completion3
);
831 // check content of attribute
832 ASSERT_EQ(0, memcmp(attr1_buf
, buf
, sizeof(attr1_buf
)));
835 TEST(LibRadosAioPP
, XattrsRoundTripPP
) {
837 char attr1
[] = "attr1";
838 char attr1_buf
[] = "foo bar baz";
839 memset(buf
, 0xaa, sizeof(buf
));
841 bl1
.append(buf
, sizeof(buf
));
842 AioTestDataPP test_data
;
843 ASSERT_EQ("", test_data
.init());
844 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
847 boost::scoped_ptr
<AioCompletion
> my_completion
848 (test_data
.m_cluster
.aio_create_completion
849 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
850 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattr("foo", my_completion
.get(), attr1
, bl2
));
853 ASSERT_EQ(0, my_completion
->wait_for_complete());
855 ASSERT_EQ(-ENODATA
, my_completion
->get_return_value());
858 bl3
.append(attr1_buf
, sizeof(attr1_buf
));
860 AioTestDataPP test_data2
;
861 ASSERT_EQ("", test_data2
.init());
862 boost::scoped_ptr
<AioCompletion
> my_completion2
863 (test_data
.m_cluster
.aio_create_completion
864 ((void*)&test_data2
, set_completion_completePP
, set_completion_safePP
));
865 ASSERT_EQ(0, test_data
.m_ioctx
.aio_setxattr("foo", my_completion2
.get(), attr1
, bl3
));
868 ASSERT_EQ(0, my_completion2
->wait_for_complete());
870 ASSERT_EQ(0, my_completion2
->get_return_value());
873 AioTestDataPP test_data3
;
874 ASSERT_EQ("", test_data3
.init());
875 boost::scoped_ptr
<AioCompletion
> my_completion3
876 (test_data
.m_cluster
.aio_create_completion
877 ((void*)&test_data3
, set_completion_completePP
, set_completion_safePP
));
878 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattr("foo", my_completion3
.get(), attr1
, bl4
));
881 ASSERT_EQ(0, my_completion3
->wait_for_complete());
883 ASSERT_EQ((int)sizeof(attr1_buf
), my_completion3
->get_return_value());
884 // check content of attribute
885 ASSERT_EQ(0, memcmp(bl4
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
888 TEST(LibRadosAio
, RmXattr
) {
890 char attr1
[] = "attr1";
891 char attr1_buf
[] = "foo bar baz";
893 memset(buf
, 0xaa, sizeof(buf
));
894 AioTestData test_data
;
895 ASSERT_EQ("", test_data
.init());
896 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
898 rados_completion_t my_completion
;
899 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
900 set_completion_complete
, set_completion_safe
, &my_completion
));
901 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo", my_completion
, attr1
, attr1_buf
, sizeof(attr1_buf
)));
904 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
906 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
907 rados_aio_release(my_completion
);
909 rados_completion_t my_completion2
;
910 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
911 set_completion_complete
, set_completion_safe
, &my_completion2
));
912 ASSERT_EQ(0, rados_aio_rmxattr(test_data
.m_ioctx
, "foo", my_completion2
, attr1
));
915 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
917 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
918 rados_aio_release(my_completion2
);
919 // async getxattr after deletion
920 rados_completion_t my_completion3
;
921 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
922 set_completion_complete
, set_completion_safe
, &my_completion3
));
923 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion3
, attr1
, buf
, sizeof(buf
)));
926 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
928 ASSERT_EQ(-ENODATA
, rados_aio_get_return_value(my_completion3
));
929 rados_aio_release(my_completion3
);
930 // Test rmxattr on a removed object
932 char attr2
[] = "attr2";
933 char attr2_buf
[] = "foo bar baz";
934 memset(buf2
, 0xbb, sizeof(buf2
));
935 ASSERT_EQ(0, rados_write(test_data
.m_ioctx
, "foo_rmxattr", buf2
, sizeof(buf2
), 0));
937 rados_completion_t my_completion4
;
938 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
939 set_completion_complete
, set_completion_safe
, &my_completion4
));
940 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo_rmxattr", my_completion4
, attr2
, attr2_buf
, sizeof(attr2_buf
)));
943 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
945 ASSERT_EQ(0, rados_aio_get_return_value(my_completion4
));
946 rados_aio_release(my_completion4
);
948 ASSERT_EQ(0, rados_remove(test_data
.m_ioctx
, "foo_rmxattr"));
949 // async rmxattr on non existing object
950 rados_completion_t my_completion5
;
951 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
952 set_completion_complete
, set_completion_safe
, &my_completion5
));
953 ASSERT_EQ(0, rados_aio_rmxattr(test_data
.m_ioctx
, "foo_rmxattr", my_completion5
, attr2
));
956 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion5
));
958 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion5
));
959 rados_aio_release(my_completion5
);
962 TEST(LibRadosAioPP
, RmXattrPP
) {
964 char attr1
[] = "attr1";
965 char attr1_buf
[] = "foo bar baz";
966 memset(buf
, 0xaa, sizeof(buf
));
968 bl1
.append(buf
, sizeof(buf
));
969 AioTestDataPP test_data
;
970 ASSERT_EQ("", test_data
.init());
971 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
974 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
975 boost::scoped_ptr
<AioCompletion
> my_completion
976 (test_data
.m_cluster
.aio_create_completion
977 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
978 ASSERT_EQ(0, test_data
.m_ioctx
.aio_setxattr("foo", my_completion
.get(), attr1
, bl2
));
981 ASSERT_EQ(0, my_completion
->wait_for_complete());
983 ASSERT_EQ(0, my_completion
->get_return_value());
985 AioTestDataPP test_data2
;
986 ASSERT_EQ("", test_data2
.init());
987 boost::scoped_ptr
<AioCompletion
> my_completion2
988 (test_data
.m_cluster
.aio_create_completion
989 ((void*)&test_data2
, set_completion_completePP
, set_completion_safePP
));
990 ASSERT_EQ(0, test_data
.m_ioctx
.aio_rmxattr("foo", my_completion2
.get(), attr1
));
993 ASSERT_EQ(0, my_completion2
->wait_for_complete());
995 ASSERT_EQ(0, my_completion2
->get_return_value());
997 AioTestDataPP test_data3
;
998 ASSERT_EQ("", test_data3
.init());
999 boost::scoped_ptr
<AioCompletion
> my_completion3
1000 (test_data
.m_cluster
.aio_create_completion
1001 ((void*)&test_data3
, set_completion_completePP
, set_completion_safePP
));
1003 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattr("foo", my_completion3
.get(), attr1
, bl3
));
1006 ASSERT_EQ(0, my_completion3
->wait_for_complete());
1008 ASSERT_EQ(-ENODATA
, my_completion3
->get_return_value());
1009 // Test rmxattr on a removed object
1011 char attr2
[] = "attr2";
1012 char attr2_buf
[] = "foo bar baz";
1013 memset(buf2
, 0xbb, sizeof(buf2
));
1015 bl21
.append(buf
, sizeof(buf
));
1016 ASSERT_EQ(0, test_data
.m_ioctx
.write("foo_rmxattr", bl21
, sizeof(buf2
), 0));
1018 bl22
.append(attr2_buf
, sizeof(attr2_buf
));
1020 AioTestDataPP test_data4
;
1021 ASSERT_EQ("", test_data4
.init());
1022 boost::scoped_ptr
<AioCompletion
> my_completion4
1023 (test_data
.m_cluster
.aio_create_completion
1024 ((void*)&test_data4
, set_completion_completePP
, set_completion_safePP
));
1025 ASSERT_EQ(0, test_data
.m_ioctx
.aio_setxattr("foo_rmxattr", my_completion4
.get(), attr2
, bl22
));
1028 ASSERT_EQ(0, my_completion4
->wait_for_complete());
1030 ASSERT_EQ(0, my_completion4
->get_return_value());
1032 ASSERT_EQ(0, test_data
.m_ioctx
.remove("foo_rmxattr"));
1033 // async rmxattr on non existing object
1034 AioTestDataPP test_data5
;
1035 ASSERT_EQ("", test_data5
.init());
1036 boost::scoped_ptr
<AioCompletion
> my_completion5
1037 (test_data
.m_cluster
.aio_create_completion
1038 ((void*)&test_data5
, set_completion_completePP
, set_completion_safePP
));
1039 ASSERT_EQ(0, test_data
.m_ioctx
.aio_rmxattr("foo_rmxattr", my_completion5
.get(), attr2
));
1042 ASSERT_EQ(0, my_completion5
->wait_for_complete());
1044 ASSERT_EQ(-ENOENT
, my_completion5
->get_return_value());
1047 TEST(LibRadosAio
, XattrIter
) {
1048 AioTestData test_data
;
1049 ASSERT_EQ("", test_data
.init());
1050 // Create an object with 2 attributes
1052 char attr1
[] = "attr1";
1053 char attr1_buf
[] = "foo bar baz";
1054 char attr2
[] = "attr2";
1055 char attr2_buf
[256];
1056 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
1057 attr2_buf
[j
] = j
% 0xff;
1059 memset(buf
, 0xaa, sizeof(buf
));
1060 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
1061 ASSERT_EQ(0, rados_setxattr(test_data
.m_ioctx
, "foo", attr1
, attr1_buf
, sizeof(attr1_buf
)));
1062 ASSERT_EQ(0, rados_setxattr(test_data
.m_ioctx
, "foo", attr2
, attr2_buf
, sizeof(attr2_buf
)));
1063 // call async version of getxattrs and wait for completion
1064 rados_completion_t my_completion
;
1065 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1066 set_completion_complete
, set_completion_safe
, &my_completion
));
1067 rados_xattrs_iter_t iter
;
1068 ASSERT_EQ(0, rados_aio_getxattrs(test_data
.m_ioctx
, "foo", my_completion
, &iter
));
1071 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1073 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1074 // loop over attributes
1080 ASSERT_EQ(0, rados_getxattrs_next(iter
, &name
, &val
, &len
));
1084 ASSERT_LT(num_seen
, 2);
1085 if ((strcmp(name
, attr1
) == 0) && (val
!= NULL
) && (memcmp(val
, attr1_buf
, len
) == 0)) {
1089 else if ((strcmp(name
, attr2
) == 0) && (val
!= NULL
) && (memcmp(val
, attr2_buf
, len
) == 0)) {
1097 rados_getxattrs_end(iter
);
1100 TEST(LibRadosIoPP
, XattrListPP
) {
1101 AioTestDataPP test_data
;
1102 ASSERT_EQ("", test_data
.init());
1103 // create an object with 2 attributes
1105 char attr1
[] = "attr1";
1106 char attr1_buf
[] = "foo bar baz";
1107 char attr2
[] = "attr2";
1108 char attr2_buf
[256];
1109 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
1110 attr2_buf
[j
] = j
% 0xff;
1112 memset(buf
, 0xaa, sizeof(buf
));
1114 bl1
.append(buf
, sizeof(buf
));
1115 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
1117 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
1118 ASSERT_EQ(0, test_data
.m_ioctx
.setxattr("foo", attr1
, bl2
));
1120 bl3
.append(attr2_buf
, sizeof(attr2_buf
));
1121 ASSERT_EQ(0, test_data
.m_ioctx
.setxattr("foo", attr2
, bl3
));
1122 // call async version of getxattrs
1123 boost::scoped_ptr
<AioCompletion
> my_completion
1124 (test_data
.m_cluster
.aio_create_completion
1125 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
1126 std::map
<std::string
, bufferlist
> attrset
;
1127 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattrs("foo", my_completion
.get(), attrset
));
1130 ASSERT_EQ(0, my_completion
->wait_for_complete());
1132 ASSERT_EQ(0, my_completion
->get_return_value());
1133 for (std::map
<std::string
, bufferlist
>::iterator i
= attrset
.begin();
1134 i
!= attrset
.end(); ++i
) {
1135 if (i
->first
== string(attr1
)) {
1136 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
1138 else if (i
->first
== string(attr2
)) {
1139 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr2_buf
, sizeof(attr2_buf
)));
1147 TEST(LibRadosAio
, IsComplete
) {
1148 AioTestData test_data
;
1149 rados_completion_t my_completion
;
1150 ASSERT_EQ("", test_data
.init());
1151 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1152 set_completion_complete
, set_completion_safe
, &my_completion
));
1154 memset(buf
, 0xcc, sizeof(buf
));
1155 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1156 my_completion
, buf
, sizeof(buf
), 0));
1159 sem_wait(test_data
.m_sem
);
1160 sem_wait(test_data
.m_sem
);
1162 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1164 memset(buf2
, 0, sizeof(buf2
));
1165 rados_completion_t my_completion2
;
1166 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1167 set_completion_complete
, set_completion_safe
, &my_completion2
));
1168 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1169 my_completion2
, buf2
, sizeof(buf2
), 0));
1173 // Busy-wait until the AIO completes.
1174 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
1176 int is_complete
= rados_aio_is_complete(my_completion2
);
1181 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
1182 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1183 rados_aio_release(my_completion
);
1184 rados_aio_release(my_completion2
);
1187 TEST(LibRadosAio
, IsCompletePP
) {
1188 AioTestDataPP test_data
;
1189 ASSERT_EQ("", test_data
.init());
1190 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1191 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1192 AioCompletion
*my_completion_null
= NULL
;
1193 ASSERT_NE(my_completion
, my_completion_null
);
1195 memset(buf
, 0xcc, sizeof(buf
));
1197 bl1
.append(buf
, sizeof(buf
));
1198 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1199 bl1
, sizeof(buf
), 0));
1202 sem_wait(test_data
.m_sem
);
1203 sem_wait(test_data
.m_sem
);
1205 ASSERT_EQ(0, my_completion
->get_return_value());
1207 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1208 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1209 ASSERT_NE(my_completion2
, my_completion_null
);
1210 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1211 &bl2
, sizeof(buf
), 0));
1215 // Busy-wait until the AIO completes.
1216 // Normally we wouldn't do this, but we want to test is_complete.
1218 int is_complete
= my_completion2
->is_complete();
1223 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1224 ASSERT_EQ(sizeof(buf
), bl2
.length());
1225 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1226 delete my_completion
;
1227 delete my_completion2
;
1230 TEST(LibRadosAio
, IsSafe
) {
1231 AioTestData test_data
;
1232 rados_completion_t my_completion
;
1233 ASSERT_EQ("", test_data
.init());
1234 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1235 set_completion_complete
, set_completion_safe
, &my_completion
));
1237 memset(buf
, 0xcc, sizeof(buf
));
1238 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1239 my_completion
, buf
, sizeof(buf
), 0));
1243 // Busy-wait until the AIO completes.
1244 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1246 int is_safe
= rados_aio_is_safe(my_completion
);
1251 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1253 memset(buf2
, 0, sizeof(buf2
));
1254 rados_completion_t my_completion2
;
1255 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1256 set_completion_complete
, set_completion_safe
, &my_completion2
));
1257 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1258 my_completion2
, buf2
, sizeof(buf2
), 0));
1261 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1263 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
1264 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1265 rados_aio_release(my_completion
);
1266 rados_aio_release(my_completion2
);
1269 TEST(LibRadosAio
, IsSafePP
) {
1270 AioTestDataPP test_data
;
1271 ASSERT_EQ("", test_data
.init());
1272 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1273 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1274 AioCompletion
*my_completion_null
= NULL
;
1275 ASSERT_NE(my_completion
, my_completion_null
);
1277 memset(buf
, 0xcc, sizeof(buf
));
1279 bl1
.append(buf
, sizeof(buf
));
1280 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1281 bl1
, sizeof(buf
), 0));
1285 // Busy-wait until the AIO completes.
1286 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1288 int is_safe
= my_completion
->is_safe();
1293 ASSERT_EQ(0, my_completion
->get_return_value());
1294 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1295 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1297 ASSERT_NE(my_completion2
, my_completion_null
);
1298 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1299 &bl2
, sizeof(buf
), 0));
1302 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1304 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1305 ASSERT_EQ(sizeof(buf
), bl2
.length());
1306 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1307 delete my_completion
;
1308 delete my_completion2
;
1311 TEST(LibRadosAio
, ReturnValue
) {
1312 AioTestData test_data
;
1313 rados_completion_t my_completion
;
1314 ASSERT_EQ("", test_data
.init());
1315 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1316 set_completion_complete
, set_completion_safe
, &my_completion
));
1318 memset(buf
, 0, sizeof(buf
));
1319 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "nonexistent",
1320 my_completion
, buf
, sizeof(buf
), 0));
1323 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1325 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion
));
1326 rados_aio_release(my_completion
);
1329 TEST(LibRadosAio
, ReturnValuePP
) {
1330 AioTestDataPP test_data
;
1331 ASSERT_EQ("", test_data
.init());
1332 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1333 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1334 AioCompletion
*my_completion_null
= NULL
;
1335 ASSERT_NE(my_completion
, my_completion_null
);
1337 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("nonexistent",
1338 my_completion
, &bl1
, 128, 0));
1341 ASSERT_EQ(0, my_completion
->wait_for_complete());
1343 ASSERT_EQ(-ENOENT
, my_completion
->get_return_value());
1344 delete my_completion
;
1347 TEST(LibRadosAio
, Flush
) {
1348 AioTestData test_data
;
1349 rados_completion_t my_completion
;
1350 ASSERT_EQ("", test_data
.init());
1351 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1352 set_completion_complete
, set_completion_safe
, &my_completion
));
1354 memset(buf
, 0xee, sizeof(buf
));
1355 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1356 my_completion
, buf
, sizeof(buf
), 0));
1357 ASSERT_EQ(0, rados_aio_flush(test_data
.m_ioctx
));
1358 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1360 memset(buf2
, 0, sizeof(buf2
));
1361 rados_completion_t my_completion2
;
1362 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1363 set_completion_complete
, set_completion_safe
, &my_completion2
));
1364 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1365 my_completion2
, buf2
, sizeof(buf2
), 0));
1368 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1370 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
1371 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1372 rados_aio_release(my_completion
);
1373 rados_aio_release(my_completion2
);
1376 TEST(LibRadosAio
, FlushPP
) {
1377 AioTestDataPP test_data
;
1378 ASSERT_EQ("", test_data
.init());
1379 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1380 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1381 AioCompletion
*my_completion_null
= NULL
;
1382 ASSERT_NE(my_completion
, my_completion_null
);
1384 memset(buf
, 0xee, sizeof(buf
));
1386 bl1
.append(buf
, sizeof(buf
));
1387 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1388 bl1
, sizeof(buf
), 0));
1389 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush());
1390 ASSERT_EQ(0, my_completion
->get_return_value());
1392 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1393 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1394 ASSERT_NE(my_completion2
, my_completion_null
);
1395 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1396 &bl2
, sizeof(buf
), 0));
1399 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1401 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1402 ASSERT_EQ(sizeof(buf
), bl2
.length());
1403 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1404 delete my_completion
;
1405 delete my_completion2
;
1408 TEST(LibRadosAio
, FlushAsync
) {
1409 AioTestData test_data
;
1410 rados_completion_t my_completion
;
1411 ASSERT_EQ("", test_data
.init());
1412 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1413 set_completion_complete
, set_completion_safe
, &my_completion
));
1414 rados_completion_t flush_completion
;
1415 ASSERT_EQ(0, rados_aio_create_completion(NULL
, NULL
, NULL
, &flush_completion
));
1417 memset(buf
, 0xee, sizeof(buf
));
1418 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1419 my_completion
, buf
, sizeof(buf
), 0));
1420 ASSERT_EQ(0, rados_aio_flush_async(test_data
.m_ioctx
, flush_completion
));
1423 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion
));
1424 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion
));
1426 ASSERT_EQ(1, rados_aio_is_complete(my_completion
));
1427 ASSERT_EQ(1, rados_aio_is_safe(my_completion
));
1428 ASSERT_EQ(1, rados_aio_is_complete(flush_completion
));
1429 ASSERT_EQ(1, rados_aio_is_safe(flush_completion
));
1430 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1432 memset(buf2
, 0, sizeof(buf2
));
1433 rados_completion_t my_completion2
;
1434 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1435 set_completion_complete
, set_completion_safe
, &my_completion2
));
1436 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1437 my_completion2
, buf2
, sizeof(buf2
), 0));
1440 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1442 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
1443 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1444 rados_aio_release(my_completion
);
1445 rados_aio_release(my_completion2
);
1446 rados_aio_release(flush_completion
);
1449 TEST(LibRadosAio
, FlushAsyncPP
) {
1450 AioTestDataPP test_data
;
1451 ASSERT_EQ("", test_data
.init());
1452 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1453 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1454 AioCompletion
*flush_completion
=
1455 test_data
.m_cluster
.aio_create_completion(NULL
, NULL
, NULL
);
1456 AioCompletion
*my_completion_null
= NULL
;
1457 ASSERT_NE(my_completion
, my_completion_null
);
1459 memset(buf
, 0xee, sizeof(buf
));
1461 bl1
.append(buf
, sizeof(buf
));
1462 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1463 bl1
, sizeof(buf
), 0));
1464 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush_async(flush_completion
));
1467 ASSERT_EQ(0, flush_completion
->wait_for_complete());
1468 ASSERT_EQ(0, flush_completion
->wait_for_safe());
1470 ASSERT_EQ(1, my_completion
->is_complete());
1471 ASSERT_EQ(1, my_completion
->is_safe());
1472 ASSERT_EQ(1, flush_completion
->is_complete());
1473 ASSERT_EQ(1, flush_completion
->is_safe());
1474 ASSERT_EQ(0, my_completion
->get_return_value());
1476 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1477 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1478 ASSERT_NE(my_completion2
, my_completion_null
);
1479 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1480 &bl2
, sizeof(buf
), 0));
1483 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1485 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1486 ASSERT_EQ(sizeof(buf
), bl2
.length());
1487 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1488 delete my_completion
;
1489 delete my_completion2
;
1490 delete flush_completion
;
1493 TEST(LibRadosAio
, RoundTripWriteFull
) {
1494 AioTestData test_data
;
1495 rados_completion_t my_completion
, my_completion2
, my_completion3
;
1496 ASSERT_EQ("", test_data
.init());
1497 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1498 set_completion_complete
, set_completion_safe
, &my_completion
));
1500 memset(buf
, 0xcc, sizeof(buf
));
1501 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1502 my_completion
, buf
, sizeof(buf
), 0));
1505 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1507 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1509 memset(buf2
, 0xdd, sizeof(buf2
));
1510 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1511 set_completion_complete
, set_completion_safe
, &my_completion2
));
1512 ASSERT_EQ(0, rados_aio_write_full(test_data
.m_ioctx
, "foo",
1513 my_completion2
, buf2
, sizeof(buf2
)));
1516 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1518 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1519 char buf3
[sizeof(buf
) + sizeof(buf2
)];
1520 memset(buf3
, 0, sizeof(buf3
));
1521 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1522 set_completion_complete
, set_completion_safe
, &my_completion3
));
1523 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1524 my_completion3
, buf3
, sizeof(buf3
), 0));
1527 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1529 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion3
));
1530 ASSERT_EQ(0, memcmp(buf3
, buf2
, sizeof(buf2
)));
1531 rados_aio_release(my_completion
);
1532 rados_aio_release(my_completion2
);
1533 rados_aio_release(my_completion3
);
1536 TEST(LibRadosAio
, RoundTripWriteFullPP
) {
1537 AioTestDataPP test_data
;
1538 ASSERT_EQ("", test_data
.init());
1539 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1540 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1541 AioCompletion
*my_completion_null
= NULL
;
1542 ASSERT_NE(my_completion
, my_completion_null
);
1544 memset(buf
, 0xcc, sizeof(buf
));
1546 bl1
.append(buf
, sizeof(buf
));
1547 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1548 bl1
, sizeof(buf
), 0));
1551 ASSERT_EQ(0, my_completion
->wait_for_complete());
1553 ASSERT_EQ(0, my_completion
->get_return_value());
1555 memset(buf2
, 0xdd, sizeof(buf2
));
1557 bl2
.append(buf2
, sizeof(buf2
));
1558 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1559 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1560 ASSERT_NE(my_completion2
, my_completion_null
);
1561 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write_full("foo", my_completion2
, bl2
));
1564 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1566 ASSERT_EQ(0, my_completion2
->get_return_value());
1568 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
1569 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1570 ASSERT_NE(my_completion3
, my_completion_null
);
1571 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
1572 &bl3
, sizeof(buf
), 0));
1575 ASSERT_EQ(0, my_completion3
->wait_for_complete());
1577 ASSERT_EQ((int)sizeof(buf2
), my_completion3
->get_return_value());
1578 ASSERT_EQ(sizeof(buf2
), bl3
.length());
1579 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
1580 delete my_completion
;
1581 delete my_completion2
;
1582 delete my_completion3
;
1585 //using ObjectWriteOperation/ObjectReadOperation with iohint
1586 TEST(LibRadosAio
, RoundTripWriteFullPP2
)
1589 std::string pool_name
= get_temp_pool_name();
1590 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
1592 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
1594 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
1595 ObjectWriteOperation op
;
1597 memset(buf
, 0xcc, sizeof(buf
));
1602 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
1603 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
1606 ASSERT_EQ(0, my_completion1
->wait_for_complete());
1608 EXPECT_EQ(0, my_completion1
->get_return_value());
1610 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
1612 ObjectReadOperation op1
;
1613 op1
.read(0, sizeof(buf
), &bl
, NULL
);
1614 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
1615 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
1618 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1620 EXPECT_EQ(0, my_completion2
->get_return_value());
1621 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
1623 ioctx
.remove("test_obj");
1624 destroy_one_pool_pp(pool_name
, cluster
);
1627 TEST(LibRadosAio
, RoundTripWriteSame
) {
1628 AioTestData test_data
;
1629 rados_completion_t my_completion
, my_completion2
, my_completion3
;
1630 ASSERT_EQ("", test_data
.init());
1631 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1632 set_completion_complete
, set_completion_safe
, &my_completion
));
1634 memset(full
, 0xcc, sizeof(full
));
1635 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1636 my_completion
, full
, sizeof(full
), 0));
1639 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1641 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1642 /* write the same buf four times */
1644 size_t ws_write_len
= sizeof(full
);
1645 memset(buf
, 0xdd, sizeof(buf
));
1646 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1647 set_completion_complete
, set_completion_safe
, &my_completion2
));
1648 ASSERT_EQ(0, rados_aio_writesame(test_data
.m_ioctx
, "foo",
1649 my_completion2
, buf
, sizeof(buf
),
1653 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1655 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1656 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1657 set_completion_complete
, set_completion_safe
, &my_completion3
));
1658 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1659 my_completion3
, full
, sizeof(full
), 0));
1662 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1664 ASSERT_EQ((int)sizeof(full
), rados_aio_get_return_value(my_completion3
));
1665 for (char *cmp
= full
; cmp
< full
+ sizeof(full
); cmp
+= sizeof(buf
)) {
1666 ASSERT_EQ(0, memcmp(cmp
, buf
, sizeof(buf
)));
1668 rados_aio_release(my_completion
);
1669 rados_aio_release(my_completion2
);
1670 rados_aio_release(my_completion3
);
1673 TEST(LibRadosAio
, RoundTripWriteSamePP
) {
1674 AioTestDataPP test_data
;
1675 ASSERT_EQ("", test_data
.init());
1676 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1677 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1678 AioCompletion
*my_completion_null
= NULL
;
1679 ASSERT_NE(my_completion
, my_completion_null
);
1681 memset(full
, 0xcc, sizeof(full
));
1683 bl1
.append(full
, sizeof(full
));
1684 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1685 bl1
, sizeof(full
), 0));
1688 ASSERT_EQ(0, my_completion
->wait_for_complete());
1690 ASSERT_EQ(0, my_completion
->get_return_value());
1691 /* write the same buf four times */
1693 size_t ws_write_len
= sizeof(full
);
1694 memset(buf
, 0xdd, sizeof(buf
));
1696 bl2
.append(buf
, sizeof(buf
));
1697 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1698 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1699 ASSERT_NE(my_completion2
, my_completion_null
);
1700 ASSERT_EQ(0, test_data
.m_ioctx
.aio_writesame("foo", my_completion2
, bl2
,
1704 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1706 ASSERT_EQ(0, my_completion2
->get_return_value());
1708 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
1709 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1710 ASSERT_NE(my_completion3
, my_completion_null
);
1711 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
1712 &bl3
, sizeof(full
), 0));
1715 ASSERT_EQ(0, my_completion3
->wait_for_complete());
1717 ASSERT_EQ((int)sizeof(full
), my_completion3
->get_return_value());
1718 ASSERT_EQ(sizeof(full
), bl3
.length());
1719 for (char *cmp
= bl3
.c_str(); cmp
< bl3
.c_str() + bl3
.length();
1720 cmp
+= sizeof(buf
)) {
1721 ASSERT_EQ(0, memcmp(cmp
, buf
, sizeof(buf
)));
1723 delete my_completion
;
1724 delete my_completion2
;
1725 delete my_completion3
;
1728 TEST(LibRadosAio
, RoundTripWriteSamePP2
)
1731 std::string pool_name
= get_temp_pool_name();
1732 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
1734 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
1736 boost::scoped_ptr
<AioCompletion
>
1737 wr_cmpl(cluster
.aio_create_completion(0, 0, 0));
1738 ObjectWriteOperation op
;
1740 memset(buf
, 0xcc, sizeof(buf
));
1742 bl
.append(buf
, sizeof(buf
));
1744 op
.writesame(0, sizeof(buf
) * 4, bl
);
1745 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
1746 ioctx
.aio_operate("test_obj", wr_cmpl
.get(), &op
);
1749 ASSERT_EQ(0, wr_cmpl
->wait_for_complete());
1751 EXPECT_EQ(0, wr_cmpl
->get_return_value());
1753 boost::scoped_ptr
<AioCompletion
>
1754 rd_cmpl(cluster
.aio_create_completion(0, 0, 0));
1756 char full
[sizeof(buf
) * 4];
1757 memset(full
, 0, sizeof(full
));
1759 fl
.append(full
, sizeof(full
));
1760 ObjectReadOperation op1
;
1761 op1
.read(0, sizeof(full
), &fl
, NULL
);
1762 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
1763 ioctx
.aio_operate("test_obj", rd_cmpl
.get(), &op1
, 0);
1766 ASSERT_EQ(0, rd_cmpl
->wait_for_complete());
1768 EXPECT_EQ(0, rd_cmpl
->get_return_value());
1769 for (cmp
= fl
.c_str(); cmp
< fl
.c_str() + fl
.length(); cmp
+= sizeof(buf
)) {
1770 ASSERT_EQ(0, memcmp(cmp
, buf
, sizeof(buf
)));
1773 ioctx
.remove("test_obj");
1774 destroy_one_pool_pp(pool_name
, cluster
);
1777 TEST(LibRadosAio
, SimpleStat
) {
1778 AioTestData test_data
;
1779 rados_completion_t my_completion
;
1780 ASSERT_EQ("", test_data
.init());
1781 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1782 set_completion_complete
, set_completion_safe
, &my_completion
));
1784 memset(buf
, 0xcc, sizeof(buf
));
1785 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1786 my_completion
, buf
, sizeof(buf
), 0));
1789 sem_wait(test_data
.m_sem
);
1790 sem_wait(test_data
.m_sem
);
1792 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1795 rados_completion_t my_completion2
;
1796 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1797 set_completion_complete
, set_completion_safe
, &my_completion2
));
1798 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1799 my_completion2
, &psize
, &pmtime
));
1802 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1804 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1805 ASSERT_EQ(sizeof(buf
), psize
);
1806 rados_aio_release(my_completion
);
1807 rados_aio_release(my_completion2
);
1810 TEST(LibRadosAio
, SimpleStatPP
) {
1811 AioTestDataPP test_data
;
1812 ASSERT_EQ("", test_data
.init());
1813 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1814 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1815 AioCompletion
*my_completion_null
= NULL
;
1816 ASSERT_NE(my_completion
, my_completion_null
);
1818 memset(buf
, 0xcc, sizeof(buf
));
1820 bl1
.append(buf
, sizeof(buf
));
1821 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1822 bl1
, sizeof(buf
), 0));
1825 sem_wait(test_data
.m_sem
);
1826 sem_wait(test_data
.m_sem
);
1828 ASSERT_EQ(0, my_completion
->get_return_value());
1831 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1832 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1833 ASSERT_NE(my_completion2
, my_completion_null
);
1834 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
1838 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1840 ASSERT_EQ(0, my_completion2
->get_return_value());
1841 ASSERT_EQ(sizeof(buf
), psize
);
1842 delete my_completion
;
1843 delete my_completion2
;
1846 TEST(LibRadosAio
, SimpleStatNS
) {
1847 AioTestData test_data
;
1848 rados_completion_t my_completion
;
1849 ASSERT_EQ("", test_data
.init());
1850 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1851 set_completion_complete
, set_completion_safe
, &my_completion
));
1853 memset(buf
, 0xcc, sizeof(buf
));
1854 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1855 my_completion
, buf
, sizeof(buf
), 0));
1858 sem_wait(test_data
.m_sem
);
1859 sem_wait(test_data
.m_sem
);
1861 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1862 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
1864 memset(buf2
, 0xbb, sizeof(buf2
));
1865 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1866 set_completion_complete
, set_completion_safe
, &my_completion
));
1867 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1868 my_completion
, buf2
, sizeof(buf2
), 0));
1871 sem_wait(test_data
.m_sem
);
1872 sem_wait(test_data
.m_sem
);
1874 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1877 rados_completion_t my_completion2
;
1878 rados_ioctx_set_namespace(test_data
.m_ioctx
, "");
1879 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1880 set_completion_complete
, set_completion_safe
, &my_completion2
));
1881 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1882 my_completion2
, &psize
, &pmtime
));
1885 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1887 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1888 ASSERT_EQ(sizeof(buf
), psize
);
1890 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
1891 rados_completion_t my_completion3
;
1892 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1893 set_completion_complete
, set_completion_safe
, &my_completion3
));
1894 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1895 my_completion3
, &psize
, &pmtime
));
1898 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1900 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
1901 ASSERT_EQ(sizeof(buf2
), psize
);
1903 rados_aio_release(my_completion
);
1904 rados_aio_release(my_completion2
);
1905 rados_aio_release(my_completion3
);
1908 TEST(LibRadosAio
, SimpleStatPPNS
) {
1909 AioTestDataPP test_data
;
1910 ASSERT_EQ("", test_data
.init());
1911 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1912 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1913 AioCompletion
*my_completion_null
= NULL
;
1914 ASSERT_NE(my_completion
, my_completion_null
);
1916 memset(buf
, 0xcc, sizeof(buf
));
1918 bl1
.append(buf
, sizeof(buf
));
1919 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1920 bl1
, sizeof(buf
), 0));
1923 sem_wait(test_data
.m_sem
);
1924 sem_wait(test_data
.m_sem
);
1926 ASSERT_EQ(0, my_completion
->get_return_value());
1929 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1930 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1931 ASSERT_NE(my_completion2
, my_completion_null
);
1932 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
1936 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1938 ASSERT_EQ(0, my_completion2
->get_return_value());
1939 ASSERT_EQ(sizeof(buf
), psize
);
1940 delete my_completion
;
1941 delete my_completion2
;
1944 TEST(LibRadosAio
, StatRemove
) {
1945 AioTestData test_data
;
1946 rados_completion_t my_completion
;
1947 ASSERT_EQ("", test_data
.init());
1948 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1949 set_completion_complete
, set_completion_safe
, &my_completion
));
1951 memset(buf
, 0xcc, sizeof(buf
));
1952 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1953 my_completion
, buf
, sizeof(buf
), 0));
1956 sem_wait(test_data
.m_sem
);
1957 sem_wait(test_data
.m_sem
);
1959 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1962 rados_completion_t my_completion2
;
1963 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1964 set_completion_complete
, set_completion_safe
, &my_completion2
));
1965 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1966 my_completion2
, &psize
, &pmtime
));
1969 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1971 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1972 ASSERT_EQ(sizeof(buf
), psize
);
1973 rados_completion_t my_completion3
;
1974 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1975 set_completion_complete
, set_completion_safe
, &my_completion3
));
1976 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion3
));
1979 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1981 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
1984 rados_completion_t my_completion4
;
1985 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1986 set_completion_complete
, set_completion_safe
, &my_completion4
));
1987 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1988 my_completion4
, &psize2
, &pmtime2
));
1991 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
1993 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion4
));
1994 rados_aio_release(my_completion
);
1995 rados_aio_release(my_completion2
);
1996 rados_aio_release(my_completion3
);
1997 rados_aio_release(my_completion4
);
2000 TEST(LibRadosAio
, StatRemovePP
) {
2001 AioTestDataPP test_data
;
2002 ASSERT_EQ("", test_data
.init());
2003 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2004 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2005 AioCompletion
*my_completion_null
= NULL
;
2006 ASSERT_NE(my_completion
, my_completion_null
);
2008 memset(buf
, 0xcc, sizeof(buf
));
2010 bl1
.append(buf
, sizeof(buf
));
2011 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2012 bl1
, sizeof(buf
), 0));
2015 sem_wait(test_data
.m_sem
);
2016 sem_wait(test_data
.m_sem
);
2018 ASSERT_EQ(0, my_completion
->get_return_value());
2021 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2022 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2023 ASSERT_NE(my_completion2
, my_completion_null
);
2024 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
2028 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2030 ASSERT_EQ(0, my_completion2
->get_return_value());
2031 ASSERT_EQ(sizeof(buf
), psize
);
2034 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
2035 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2036 ASSERT_NE(my_completion3
, my_completion_null
);
2037 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion3
));
2040 ASSERT_EQ(0, my_completion3
->wait_for_complete());
2042 ASSERT_EQ(0, my_completion3
->get_return_value());
2044 AioCompletion
*my_completion4
= test_data
.m_cluster
.aio_create_completion(
2045 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2046 ASSERT_NE(my_completion4
, my_completion_null
);
2047 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion4
,
2048 &psize2
, &pmtime2
));
2051 ASSERT_EQ(0, my_completion4
->wait_for_complete());
2053 ASSERT_EQ(-ENOENT
, my_completion4
->get_return_value());
2054 delete my_completion
;
2055 delete my_completion2
;
2056 delete my_completion3
;
2057 delete my_completion4
;
2060 TEST(LibRadosAio
, ExecuteClass
) {
2061 AioTestData test_data
;
2062 rados_completion_t my_completion
;
2063 ASSERT_EQ("", test_data
.init());
2064 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2065 set_completion_complete
, set_completion_safe
, &my_completion
));
2067 memset(buf
, 0xcc, sizeof(buf
));
2068 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2069 my_completion
, buf
, sizeof(buf
), 0));
2072 sem_wait(test_data
.m_sem
);
2073 sem_wait(test_data
.m_sem
);
2075 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2076 rados_completion_t my_completion2
;
2077 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2078 set_completion_complete
, set_completion_safe
, &my_completion2
));
2080 ASSERT_EQ(0, rados_aio_exec(test_data
.m_ioctx
, "foo", my_completion2
,
2081 "hello", "say_hello", NULL
, 0, out
, sizeof(out
)));
2084 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2086 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2
));
2087 ASSERT_EQ(0, strncmp("Hello, world!", out
, 13));
2088 rados_aio_release(my_completion
);
2089 rados_aio_release(my_completion2
);
2092 TEST(LibRadosAio
, ExecuteClassPP
) {
2093 AioTestDataPP test_data
;
2094 ASSERT_EQ("", test_data
.init());
2095 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2096 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2097 AioCompletion
*my_completion_null
= NULL
;
2098 ASSERT_NE(my_completion
, my_completion_null
);
2100 memset(buf
, 0xcc, sizeof(buf
));
2102 bl1
.append(buf
, sizeof(buf
));
2103 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2104 bl1
, sizeof(buf
), 0));
2107 sem_wait(test_data
.m_sem
);
2108 sem_wait(test_data
.m_sem
);
2110 ASSERT_EQ(0, my_completion
->get_return_value());
2111 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2112 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2113 ASSERT_NE(my_completion2
, my_completion_null
);
2115 ASSERT_EQ(0, test_data
.m_ioctx
.aio_exec("foo", my_completion2
,
2116 "hello", "say_hello", in
, &out
));
2119 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2121 ASSERT_EQ(0, my_completion2
->get_return_value());
2122 ASSERT_EQ(std::string("Hello, world!"), std::string(out
.c_str(), out
.length()));
2123 delete my_completion
;
2124 delete my_completion2
;
2131 TEST(LibRadosAio
, OmapPP
) {
2133 std::string pool_name
= get_temp_pool_name();
2134 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
2136 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
2138 string header_str
= "baz";
2139 bufferptr
bp(header_str
.c_str(), header_str
.size() + 1);
2140 bufferlist header_to_set
;
2141 header_to_set
.push_back(bp
);
2142 map
<string
, bufferlist
> to_set
;
2144 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2145 ObjectWriteOperation op
;
2146 to_set
["foo"] = header_to_set
;
2147 to_set
["foo2"] = header_to_set
;
2148 to_set
["qfoo3"] = header_to_set
;
2149 op
.omap_set(to_set
);
2151 op
.omap_set_header(header_to_set
);
2153 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
2156 ASSERT_EQ(0, my_completion
->wait_for_complete());
2158 EXPECT_EQ(0, my_completion
->get_return_value());
2162 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2163 ObjectReadOperation op
;
2164 map
<string
, pair
<bufferlist
, int> > assertions
;
2166 val
.append(string("bar"));
2167 assertions
["foo"] = pair
<bufferlist
, int>(val
, CEPH_OSD_CMPXATTR_OP_EQ
);
2170 op
.omap_cmp(assertions
, &r
);
2172 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2175 ASSERT_EQ(0, my_completion
->wait_for_complete());
2177 EXPECT_EQ(-ECANCELED
, my_completion
->get_return_value());
2178 ASSERT_EQ(-ECANCELED
, r
);
2182 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2183 ObjectReadOperation op
;
2185 set
<string
> set_got
;
2186 map
<string
, bufferlist
> map_got
;
2189 map
<string
, bufferlist
> got3
;
2191 map
<string
, bufferlist
> got4
;
2195 op
.omap_get_keys2("", 1, &set_got
, nullptr, 0);
2196 op
.omap_get_vals2("foo", 1, &map_got
, nullptr, 0);
2198 to_get
.insert("foo");
2199 to_get
.insert("qfoo3");
2200 op
.omap_get_vals_by_keys(to_get
, &got3
, 0);
2202 op
.omap_get_header(&header
, 0);
2204 op
.omap_get_vals2("foo2", "q", 1, &got4
, nullptr, 0);
2206 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2209 ASSERT_EQ(0, my_completion
->wait_for_complete());
2211 EXPECT_EQ(0, my_completion
->get_return_value());
2213 ASSERT_EQ(header
.length(), header_to_set
.length());
2214 ASSERT_EQ(set_got
.size(), (unsigned)1);
2215 ASSERT_EQ(*set_got
.begin(), "foo");
2216 ASSERT_EQ(map_got
.size(), (unsigned)1);
2217 ASSERT_EQ(map_got
.begin()->first
, "foo2");
2218 ASSERT_EQ(got3
.size(), (unsigned)2);
2219 ASSERT_EQ(got3
.begin()->first
, "foo");
2220 ASSERT_EQ(got3
.rbegin()->first
, "qfoo3");
2221 ASSERT_EQ(got4
.size(), (unsigned)1);
2222 ASSERT_EQ(got4
.begin()->first
, "qfoo3");
2226 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2227 ObjectWriteOperation op
;
2228 set
<string
> to_remove
;
2229 to_remove
.insert("foo2");
2230 op
.omap_rm_keys(to_remove
);
2231 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
2234 ASSERT_EQ(0, my_completion
->wait_for_complete());
2236 EXPECT_EQ(0, my_completion
->get_return_value());
2240 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2241 ObjectReadOperation op
;
2243 set
<string
> set_got
;
2244 op
.omap_get_keys2("", -1, &set_got
, nullptr, 0);
2245 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2248 ASSERT_EQ(0, my_completion
->wait_for_complete());
2250 EXPECT_EQ(0, my_completion
->get_return_value());
2251 ASSERT_EQ(set_got
.size(), (unsigned)2);
2255 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2256 ObjectWriteOperation op
;
2258 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
2261 ASSERT_EQ(0, my_completion
->wait_for_complete());
2263 EXPECT_EQ(0, my_completion
->get_return_value());
2267 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2268 ObjectReadOperation op
;
2270 set
<string
> set_got
;
2271 op
.omap_get_keys2("", -1, &set_got
, nullptr, 0);
2272 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2275 ASSERT_EQ(0, my_completion
->wait_for_complete());
2277 EXPECT_EQ(0, my_completion
->get_return_value());
2278 ASSERT_EQ(set_got
.size(), (unsigned)0);
2281 // omap_clear clears header *and* keys
2283 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2284 ObjectWriteOperation op
;
2286 bl
.append("some data");
2287 map
<string
,bufferlist
> to_set
;
2289 to_set
["foo2"] = bl
;
2290 to_set
["qfoo3"] = bl
;
2291 op
.omap_set(to_set
);
2292 op
.omap_set_header(bl
);
2293 ioctx
.aio_operate("foo3", my_completion
.get(), &op
);
2296 ASSERT_EQ(0, my_completion
->wait_for_complete());
2298 EXPECT_EQ(0, my_completion
->get_return_value());
2301 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2302 ObjectWriteOperation op
;
2304 ioctx
.aio_operate("foo3", my_completion
.get(), &op
);
2307 ASSERT_EQ(0, my_completion
->wait_for_complete());
2309 EXPECT_EQ(0, my_completion
->get_return_value());
2312 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2313 ObjectReadOperation op
;
2314 set
<string
> set_got
;
2316 op
.omap_get_keys2("", -1, &set_got
, nullptr, 0);
2317 op
.omap_get_header(&hdr
, NULL
);
2318 ioctx
.aio_operate("foo3", my_completion
.get(), &op
, 0);
2321 ASSERT_EQ(0, my_completion
->wait_for_complete());
2323 EXPECT_EQ(0, my_completion
->get_return_value());
2324 ASSERT_EQ(set_got
.size(), (unsigned)0);
2325 ASSERT_EQ(hdr
.length(), 0u);
2328 ioctx
.remove("test_obj");
2329 destroy_one_pool_pp(pool_name
, cluster
);
2332 TEST(LibRadosAio
, MultiWrite
) {
2333 AioTestData test_data
;
2334 rados_completion_t my_completion
, my_completion2
, my_completion3
;
2335 ASSERT_EQ("", test_data
.init());
2336 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2337 set_completion_complete
, set_completion_safe
, &my_completion
));
2339 memset(buf
, 0xcc, sizeof(buf
));
2340 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2341 my_completion
, buf
, sizeof(buf
), 0));
2344 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
2346 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2349 memset(buf2
, 0xdd, sizeof(buf2
));
2350 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2351 set_completion_complete
, set_completion_safe
, &my_completion2
));
2352 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2353 my_completion2
, buf2
, sizeof(buf2
), sizeof(buf
)));
2356 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2358 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
2360 char buf3
[(sizeof(buf
) + sizeof(buf2
)) * 3];
2361 memset(buf3
, 0, sizeof(buf3
));
2362 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2363 set_completion_complete
, set_completion_safe
, &my_completion3
));
2364 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2365 my_completion3
, buf3
, sizeof(buf3
), 0));
2368 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
2370 ASSERT_EQ((int)(sizeof(buf
) + sizeof(buf2
)), rados_aio_get_return_value(my_completion3
));
2371 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
2372 ASSERT_EQ(0, memcmp(buf3
+ sizeof(buf
), buf2
, sizeof(buf2
)));
2373 rados_aio_release(my_completion
);
2374 rados_aio_release(my_completion2
);
2375 rados_aio_release(my_completion3
);
2378 TEST(LibRadosAio
, MultiWritePP
) {
2379 AioTestDataPP test_data
;
2380 ASSERT_EQ("", test_data
.init());
2381 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2382 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2383 AioCompletion
*my_completion_null
= NULL
;
2384 ASSERT_NE(my_completion
, my_completion_null
);
2386 memset(buf
, 0xcc, sizeof(buf
));
2388 bl1
.append(buf
, sizeof(buf
));
2389 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2390 bl1
, sizeof(buf
), 0));
2393 ASSERT_EQ(0, my_completion
->wait_for_complete());
2395 ASSERT_EQ(0, my_completion
->get_return_value());
2398 memset(buf2
, 0xdd, sizeof(buf2
));
2400 bl2
.append(buf2
, sizeof(buf2
));
2401 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2402 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2403 ASSERT_NE(my_completion2
, my_completion_null
);
2404 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion2
,
2405 bl2
, sizeof(buf2
), sizeof(buf
)));
2408 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2410 ASSERT_EQ(0, my_completion2
->get_return_value());
2413 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
2414 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2415 ASSERT_NE(my_completion3
, my_completion_null
);
2416 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
2417 &bl3
, (sizeof(buf
) + sizeof(buf2
) * 3), 0));
2420 ASSERT_EQ(0, my_completion3
->wait_for_complete());
2422 ASSERT_EQ((int)(sizeof(buf
) + sizeof(buf2
)), my_completion3
->get_return_value());
2423 ASSERT_EQ(sizeof(buf
) + sizeof(buf2
), bl3
.length());
2424 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, sizeof(buf
)));
2425 ASSERT_EQ(0, memcmp(bl3
.c_str() + sizeof(buf
), buf2
, sizeof(buf2
)));
2426 delete my_completion
;
2427 delete my_completion2
;
2428 delete my_completion3
;
2431 TEST(LibRadosAio
, AioUnlock
) {
2432 AioTestData test_data
;
2433 ASSERT_EQ("", test_data
.init());
2434 ASSERT_EQ(0, rados_lock_exclusive(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", "", NULL
, 0));
2435 rados_completion_t my_completion
;
2436 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2437 set_completion_complete
, set_completion_safe
, &my_completion
));
2438 ASSERT_EQ(0, rados_aio_unlock(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", my_completion
));
2441 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
2443 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2444 ASSERT_EQ(0, rados_lock_exclusive(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", "", NULL
, 0));
2447 TEST(LibRadosAio
, AioUnlockPP
) {
2448 AioTestDataPP test_data
;
2449 ASSERT_EQ("", test_data
.init());
2450 ASSERT_EQ(0, test_data
.m_ioctx
.lock_exclusive("foo", "TestLock", "Cookie", "", NULL
, 0));
2451 boost::scoped_ptr
<AioCompletion
> my_completion
2452 (test_data
.m_cluster
.aio_create_completion
2453 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
2454 ASSERT_EQ(0, test_data
.m_ioctx
.aio_unlock("foo", "TestLock", "Cookie", my_completion
.get()));
2457 ASSERT_EQ(0, my_completion
->wait_for_complete());
2459 ASSERT_EQ(0, my_completion
->get_return_value());
2461 ASSERT_EQ(0, test_data
.m_ioctx
.lock_exclusive("foo", "TestLock", "Cookie", "", NULL
, 0));
2480 rados_ioctx_destroy(m_ioctx
);
2481 destroy_one_ec_pool(m_pool_name
, &m_cluster
);
2489 if (SEM_FAILED
== (m_sem
= sem_open("/test_aio_sem", O_CREAT
, 0644, 0))) {
2492 oss
<< "sem_open failed: " << cpp_strerror(err
);
2495 m_pool_name
= get_temp_pool_name();
2496 std::string err
= create_one_ec_pool(m_pool_name
, &m_cluster
);
2500 oss
<< "create_one_ec_pool(" << m_pool_name
<< ") failed: error " << err
;
2503 ret
= rados_ioctx_create(m_cluster
, m_pool_name
.c_str(), &m_ioctx
);
2506 destroy_one_ec_pool(m_pool_name
, &m_cluster
);
2508 oss
<< "rados_ioctx_create failed: error " << ret
;
2517 rados_ioctx_t m_ioctx
;
2518 std::string m_pool_name
;
2524 class AioTestDataECPP
2538 destroy_one_ec_pool_pp(m_pool_name
, m_cluster
);
2546 if (SEM_FAILED
== (m_sem
= sem_open("/test_aio_sem", O_CREAT
, 0644, 0))) {
2549 oss
<< "sem_open failed: " << cpp_strerror(err
);
2552 m_pool_name
= get_temp_pool_name();
2553 std::string err
= create_one_ec_pool_pp(m_pool_name
, m_cluster
);
2557 oss
<< "create_one_ec_pool(" << m_pool_name
<< ") failed: error " << err
;
2560 ret
= m_cluster
.ioctx_create(m_pool_name
.c_str(), m_ioctx
);
2563 destroy_one_ec_pool_pp(m_pool_name
, m_cluster
);
2565 oss
<< "rados_ioctx_create failed: error " << ret
;
2575 std::string m_pool_name
;
2581 void set_completion_completeEC(rados_completion_t cb
, void *arg
)
2583 AioTestDataEC
*test
= static_cast<AioTestDataEC
*>(arg
);
2584 test
->m_complete
= true;
2585 sem_post(test
->m_sem
);
2588 void set_completion_safeEC(rados_completion_t cb
, void *arg
)
2590 AioTestDataEC
*test
= static_cast<AioTestDataEC
*>(arg
);
2591 test
->m_safe
= true;
2592 sem_post(test
->m_sem
);
2595 void set_completion_completeECPP(rados_completion_t cb
, void *arg
)
2597 AioTestDataECPP
*test
= static_cast<AioTestDataECPP
*>(arg
);
2598 test
->m_complete
= true;
2599 sem_post(test
->m_sem
);
2602 void set_completion_safeECPP(rados_completion_t cb
, void *arg
)
2604 AioTestDataECPP
*test
= static_cast<AioTestDataECPP
*>(arg
);
2605 test
->m_safe
= true;
2606 sem_post(test
->m_sem
);
2609 TEST(LibRadosAioEC
, SimpleWrite
) {
2610 AioTestDataEC test_data
;
2611 rados_completion_t my_completion
;
2612 ASSERT_EQ("", test_data
.init());
2613 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2614 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2616 memset(buf
, 0xcc, sizeof(buf
));
2617 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2618 my_completion
, buf
, sizeof(buf
), 0));
2621 sem_wait(test_data
.m_sem
);
2622 sem_wait(test_data
.m_sem
);
2624 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2626 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
2627 rados_completion_t my_completion2
;
2628 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2629 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2630 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2631 my_completion2
, buf
, sizeof(buf
), 0));
2634 sem_wait(test_data
.m_sem
);
2635 sem_wait(test_data
.m_sem
);
2637 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
2638 rados_aio_release(my_completion
);
2639 rados_aio_release(my_completion2
);
2642 TEST(LibRadosAioEC
, SimpleWritePP
) {
2644 memset(buf
, 0xcc, sizeof(buf
));
2646 bl1
.append(buf
, sizeof(buf
));
2648 AioTestDataECPP test_data
;
2649 ASSERT_EQ("", test_data
.init());
2650 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2651 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2652 AioCompletion
*my_completion_null
= NULL
;
2653 ASSERT_NE(my_completion
, my_completion_null
);
2654 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
2655 my_completion
, bl1
, sizeof(buf
), 0));
2658 sem_wait(test_data
.m_sem
);
2659 sem_wait(test_data
.m_sem
);
2661 ASSERT_EQ(0, my_completion
->get_return_value());
2662 delete my_completion
;
2666 AioTestDataECPP test_data
;
2667 ASSERT_EQ("", test_data
.init());
2668 test_data
.m_ioctx
.set_namespace("nspace");
2669 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2670 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2671 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
2672 my_completion
, bl1
, sizeof(buf
), 0));
2675 sem_wait(test_data
.m_sem
);
2676 sem_wait(test_data
.m_sem
);
2678 ASSERT_EQ(0, my_completion
->get_return_value());
2679 delete my_completion
;
2683 TEST(LibRadosAioEC
, WaitForSafe
) {
2684 AioTestDataEC test_data
;
2685 rados_completion_t my_completion
;
2686 ASSERT_EQ("", test_data
.init());
2687 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2688 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2690 memset(buf
, 0xcc, sizeof(buf
));
2691 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2692 my_completion
, buf
, sizeof(buf
), 0));
2694 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion
));
2695 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2696 rados_aio_release(my_completion
);
2699 TEST(LibRadosAioEC
, WaitForSafePP
) {
2700 AioTestDataECPP test_data
;
2701 ASSERT_EQ("", test_data
.init());
2702 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2703 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2704 AioCompletion
*my_completion_null
= NULL
;
2705 ASSERT_NE(my_completion
, my_completion_null
);
2707 memset(buf
, 0xcc, sizeof(buf
));
2709 bl1
.append(buf
, sizeof(buf
));
2710 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
2711 my_completion
, bl1
, sizeof(buf
), 0));
2713 ASSERT_EQ(0, my_completion
->wait_for_safe());
2714 ASSERT_EQ(0, my_completion
->get_return_value());
2715 delete my_completion
;
2718 TEST(LibRadosAioEC
, RoundTrip
) {
2719 AioTestDataEC test_data
;
2720 rados_completion_t my_completion
;
2721 ASSERT_EQ("", test_data
.init());
2722 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2723 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2725 memset(buf
, 0xcc, sizeof(buf
));
2726 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2727 my_completion
, buf
, sizeof(buf
), 0));
2730 sem_wait(test_data
.m_sem
);
2731 sem_wait(test_data
.m_sem
);
2733 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2735 memset(buf2
, 0, sizeof(buf2
));
2736 rados_completion_t my_completion2
;
2737 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2738 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2739 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2740 my_completion2
, buf2
, sizeof(buf2
), 0));
2743 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2745 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
2746 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
2747 rados_aio_release(my_completion
);
2748 rados_aio_release(my_completion2
);
2751 TEST(LibRadosAioEC
, RoundTrip2
) {
2752 AioTestDataEC test_data
;
2753 rados_completion_t my_completion
;
2754 ASSERT_EQ("", test_data
.init());
2755 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2756 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2758 memset(buf
, 0xcc, sizeof(buf
));
2759 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2760 my_completion
, buf
, sizeof(buf
), 0));
2763 sem_wait(test_data
.m_sem
);
2764 sem_wait(test_data
.m_sem
);
2766 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2768 memset(buf2
, 0, sizeof(buf2
));
2769 rados_completion_t my_completion2
;
2770 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2771 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2772 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2773 my_completion2
, buf2
, sizeof(buf2
), 0));
2776 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2778 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
2779 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
2780 rados_aio_release(my_completion
);
2781 rados_aio_release(my_completion2
);
2784 TEST(LibRadosAioEC
, RoundTripPP
) {
2785 AioTestDataECPP test_data
;
2786 ASSERT_EQ("", test_data
.init());
2787 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2788 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2789 AioCompletion
*my_completion_null
= NULL
;
2790 ASSERT_NE(my_completion
, my_completion_null
);
2792 memset(buf
, 0xcc, sizeof(buf
));
2794 bl1
.append(buf
, sizeof(buf
));
2795 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2796 bl1
, sizeof(buf
), 0));
2799 sem_wait(test_data
.m_sem
);
2800 sem_wait(test_data
.m_sem
);
2802 ASSERT_EQ(0, my_completion
->get_return_value());
2804 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2805 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2806 ASSERT_NE(my_completion2
, my_completion_null
);
2807 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
2808 my_completion2
, &bl2
, sizeof(buf
), 0));
2811 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2813 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
2814 ASSERT_EQ(sizeof(buf
), bl2
.length());
2815 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
2816 delete my_completion
;
2817 delete my_completion2
;
2820 TEST(LibRadosAioEC
, RoundTripPP2
) {
2821 AioTestDataECPP test_data
;
2822 ASSERT_EQ("", test_data
.init());
2823 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2824 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2825 AioCompletion
*my_completion_null
= NULL
;
2826 ASSERT_NE(my_completion
, my_completion_null
);
2828 memset(buf
, 0xcc, sizeof(buf
));
2830 bl1
.append(buf
, sizeof(buf
));
2831 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2832 bl1
, sizeof(buf
), 0));
2835 sem_wait(test_data
.m_sem
);
2836 sem_wait(test_data
.m_sem
);
2838 ASSERT_EQ(0, my_completion
->get_return_value());
2840 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2841 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2842 ASSERT_NE(my_completion2
, my_completion_null
);
2843 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
2844 my_completion2
, &bl2
, sizeof(buf
), 0));
2847 ASSERT_EQ(0, my_completion2
->wait_for_safe());
2848 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2850 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
2851 ASSERT_EQ(sizeof(buf
), bl2
.length());
2852 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
2853 delete my_completion
;
2854 delete my_completion2
;
2857 //using ObjectWriteOperation/ObjectReadOperation with iohint
2858 TEST(LibRadosAioEC
, RoundTripPP3
)
2861 std::string pool_name
= get_temp_pool_name();
2862 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
2864 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
2866 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
2867 ObjectWriteOperation op
;
2869 memset(buf
, 0xcc, sizeof(buf
));
2874 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
2875 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
2878 ASSERT_EQ(0, my_completion1
->wait_for_complete());
2880 EXPECT_EQ(0, my_completion1
->get_return_value());
2882 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
2884 ObjectReadOperation op1
;
2885 op1
.read(0, sizeof(buf
), &bl
, NULL
);
2886 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
2887 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
2890 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2892 EXPECT_EQ(0, my_completion2
->get_return_value());
2893 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
2895 ioctx
.remove("test_obj");
2896 destroy_one_pool_pp(pool_name
, cluster
);
2899 TEST(LibRadosAioEC
, RoundTripSparseReadPP
) {
2900 AioTestDataECPP test_data
;
2901 ASSERT_EQ("", test_data
.init());
2902 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2903 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2904 AioCompletion
*my_completion_null
= NULL
;
2905 ASSERT_NE(my_completion
, my_completion_null
);
2907 memset(buf
, 0xcc, sizeof(buf
));
2909 bl1
.append(buf
, sizeof(buf
));
2910 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2911 bl1
, sizeof(buf
), 0));
2914 sem_wait(test_data
.m_sem
);
2915 sem_wait(test_data
.m_sem
);
2917 ASSERT_EQ(0, my_completion
->get_return_value());
2919 map
<uint64_t, uint64_t> extents
;
2921 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2922 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2923 ASSERT_NE(my_completion2
, my_completion_null
);
2924 ASSERT_EQ(0, test_data
.m_ioctx
.aio_sparse_read("foo",
2925 my_completion2
, &extents
, &bl2
, sizeof(buf
), 0));
2928 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2930 ASSERT_EQ(0, my_completion2
->get_return_value());
2931 assert_eq_sparse(bl1
, extents
, bl2
);
2932 delete my_completion
;
2933 delete my_completion2
;
2936 TEST(LibRadosAioEC
, RoundTripAppend
) {
2937 AioTestDataEC test_data
;
2938 rados_completion_t my_completion
, my_completion2
, my_completion3
, my_completion4
;
2939 ASSERT_EQ("", test_data
.init());
2940 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2941 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2943 ASSERT_EQ(0, rados_ioctx_pool_requires_alignment2(test_data
.m_ioctx
, &requires
));
2944 ASSERT_NE(0, requires
);
2946 ASSERT_EQ(0, rados_ioctx_pool_required_alignment2(test_data
.m_ioctx
, &alignment
));
2947 ASSERT_NE(0U, alignment
);
2949 int bsize
= alignment
;
2950 char *buf
= (char *)new char[bsize
];
2951 memset(buf
, 0xcc, bsize
);
2952 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
2953 my_completion
, buf
, bsize
));
2956 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
2958 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2960 int hbsize
= bsize
/ 2;
2961 char *buf2
= (char *)new char[hbsize
];
2962 memset(buf2
, 0xdd, hbsize
);
2963 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2964 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2965 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
2966 my_completion2
, buf2
, hbsize
));
2969 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2971 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
2973 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2974 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
2975 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
2976 my_completion3
, buf2
, hbsize
));
2979 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
2981 EXPECT_EQ(-EOPNOTSUPP
, rados_aio_get_return_value(my_completion3
));
2983 int tbsize
= bsize
+ hbsize
;
2984 char *buf3
= (char *)new char[tbsize
];
2985 memset(buf3
, 0, tbsize
);
2986 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2987 set_completion_completeEC
, set_completion_safeEC
, &my_completion4
));
2988 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2989 my_completion4
, buf3
, bsize
* 3, 0));
2992 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
2994 ASSERT_EQ(tbsize
, rados_aio_get_return_value(my_completion4
));
2995 ASSERT_EQ(0, memcmp(buf3
, buf
, bsize
));
2996 ASSERT_EQ(0, memcmp(buf3
+ bsize
, buf2
, hbsize
));
2997 rados_aio_release(my_completion
);
2998 rados_aio_release(my_completion2
);
2999 rados_aio_release(my_completion3
);
3000 rados_aio_release(my_completion4
);
3006 TEST(LibRadosAioEC
, RoundTripAppendPP
) {
3007 AioTestDataECPP test_data
;
3008 ASSERT_EQ("", test_data
.init());
3009 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3010 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3011 AioCompletion
*my_completion_null
= NULL
;
3012 ASSERT_NE(my_completion
, my_completion_null
);
3014 ASSERT_EQ(0, test_data
.m_ioctx
.pool_requires_alignment2(&requires
));
3015 ASSERT_TRUE(requires
);
3017 ASSERT_EQ(0, test_data
.m_ioctx
.pool_required_alignment2(&alignment
));
3018 ASSERT_NE((unsigned)0, alignment
);
3019 int bsize
= alignment
;
3020 char *buf
= (char *)new char[bsize
];
3021 memset(buf
, 0xcc, bsize
);
3023 bl1
.append(buf
, bsize
);
3024 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion
,
3028 ASSERT_EQ(0, my_completion
->wait_for_complete());
3030 ASSERT_EQ(0, my_completion
->get_return_value());
3032 int hbsize
= bsize
/ 2;
3033 char *buf2
= (char *)new char[hbsize
];
3034 memset(buf2
, 0xdd, hbsize
);
3036 bl2
.append(buf2
, hbsize
);
3037 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3038 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3039 ASSERT_NE(my_completion2
, my_completion_null
);
3040 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion2
,
3044 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3046 ASSERT_EQ(0, my_completion2
->get_return_value());
3048 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
3049 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3050 ASSERT_NE(my_completion3
, my_completion_null
);
3051 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion3
,
3055 ASSERT_EQ(0, my_completion3
->wait_for_complete());
3057 EXPECT_EQ(-EOPNOTSUPP
, my_completion3
->get_return_value());
3060 AioCompletion
*my_completion4
= test_data
.m_cluster
.aio_create_completion(
3061 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3062 ASSERT_NE(my_completion4
, my_completion_null
);
3063 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
3064 my_completion4
, &bl3
, bsize
* 3, 0));
3067 ASSERT_EQ(0, my_completion4
->wait_for_complete());
3069 int tbsize
= bsize
+ hbsize
;
3070 ASSERT_EQ(tbsize
, my_completion4
->get_return_value());
3071 ASSERT_EQ((unsigned)tbsize
, bl3
.length());
3072 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, bsize
));
3073 ASSERT_EQ(0, memcmp(bl3
.c_str() + bsize
, buf2
, hbsize
));
3074 delete my_completion
;
3075 delete my_completion2
;
3076 delete my_completion3
;
3081 TEST(LibRadosAioEC
, IsComplete
) {
3082 AioTestDataEC test_data
;
3083 rados_completion_t my_completion
;
3084 ASSERT_EQ("", test_data
.init());
3085 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3086 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3088 memset(buf
, 0xcc, sizeof(buf
));
3089 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3090 my_completion
, buf
, sizeof(buf
), 0));
3093 sem_wait(test_data
.m_sem
);
3094 sem_wait(test_data
.m_sem
);
3096 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3098 memset(buf2
, 0, sizeof(buf2
));
3099 rados_completion_t my_completion2
;
3100 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3101 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3102 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3103 my_completion2
, buf2
, sizeof(buf2
), 0));
3107 // Busy-wait until the AIO completes.
3108 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
3110 int is_complete
= rados_aio_is_complete(my_completion2
);
3115 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
3116 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3117 rados_aio_release(my_completion
);
3118 rados_aio_release(my_completion2
);
3121 TEST(LibRadosAioEC
, IsCompletePP
) {
3122 AioTestDataECPP test_data
;
3123 ASSERT_EQ("", test_data
.init());
3124 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3125 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3126 AioCompletion
*my_completion_null
= NULL
;
3127 ASSERT_NE(my_completion
, my_completion_null
);
3129 memset(buf
, 0xcc, sizeof(buf
));
3131 bl1
.append(buf
, sizeof(buf
));
3132 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3133 bl1
, sizeof(buf
), 0));
3136 sem_wait(test_data
.m_sem
);
3137 sem_wait(test_data
.m_sem
);
3139 ASSERT_EQ(0, my_completion
->get_return_value());
3141 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3142 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3143 ASSERT_NE(my_completion2
, my_completion_null
);
3144 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3145 &bl2
, sizeof(buf
), 0));
3149 // Busy-wait until the AIO completes.
3150 // Normally we wouldn't do this, but we want to test is_complete.
3152 int is_complete
= my_completion2
->is_complete();
3157 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3158 ASSERT_EQ(sizeof(buf
), bl2
.length());
3159 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3160 delete my_completion
;
3161 delete my_completion2
;
3164 TEST(LibRadosAioEC
, IsSafe
) {
3165 AioTestDataEC test_data
;
3166 rados_completion_t my_completion
;
3167 ASSERT_EQ("", test_data
.init());
3168 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3169 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3171 memset(buf
, 0xcc, sizeof(buf
));
3172 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3173 my_completion
, buf
, sizeof(buf
), 0));
3177 // Busy-wait until the AIO completes.
3178 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
3180 int is_safe
= rados_aio_is_safe(my_completion
);
3185 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3187 memset(buf2
, 0, sizeof(buf2
));
3188 rados_completion_t my_completion2
;
3189 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3190 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3191 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3192 my_completion2
, buf2
, sizeof(buf2
), 0));
3195 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3197 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
3198 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3199 rados_aio_release(my_completion
);
3200 rados_aio_release(my_completion2
);
3203 TEST(LibRadosAioEC
, IsSafePP
) {
3204 AioTestDataECPP test_data
;
3205 ASSERT_EQ("", test_data
.init());
3206 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3207 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3208 AioCompletion
*my_completion_null
= NULL
;
3209 ASSERT_NE(my_completion
, my_completion_null
);
3211 memset(buf
, 0xcc, sizeof(buf
));
3213 bl1
.append(buf
, sizeof(buf
));
3214 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3215 bl1
, sizeof(buf
), 0));
3219 // Busy-wait until the AIO completes.
3220 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
3222 int is_safe
= my_completion
->is_safe();
3227 ASSERT_EQ(0, my_completion
->get_return_value());
3228 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3229 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3231 ASSERT_NE(my_completion2
, my_completion_null
);
3232 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3233 &bl2
, sizeof(buf
), 0));
3236 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3238 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3239 ASSERT_EQ(sizeof(buf
), bl2
.length());
3240 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3241 delete my_completion
;
3242 delete my_completion2
;
3245 TEST(LibRadosAioEC
, ReturnValue
) {
3246 AioTestDataEC test_data
;
3247 rados_completion_t my_completion
;
3248 ASSERT_EQ("", test_data
.init());
3249 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3250 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3252 memset(buf
, 0, sizeof(buf
));
3253 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "nonexistent",
3254 my_completion
, buf
, sizeof(buf
), 0));
3257 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
3259 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion
));
3260 rados_aio_release(my_completion
);
3263 TEST(LibRadosAioEC
, ReturnValuePP
) {
3264 AioTestDataECPP test_data
;
3265 ASSERT_EQ("", test_data
.init());
3266 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3267 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3268 AioCompletion
*my_completion_null
= NULL
;
3269 ASSERT_NE(my_completion
, my_completion_null
);
3271 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("nonexistent",
3272 my_completion
, &bl1
, 128, 0));
3275 ASSERT_EQ(0, my_completion
->wait_for_complete());
3277 ASSERT_EQ(-ENOENT
, my_completion
->get_return_value());
3278 delete my_completion
;
3281 TEST(LibRadosAioEC
, Flush
) {
3282 AioTestDataEC test_data
;
3283 rados_completion_t my_completion
;
3284 ASSERT_EQ("", test_data
.init());
3285 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3286 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3288 memset(buf
, 0xee, sizeof(buf
));
3289 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3290 my_completion
, buf
, sizeof(buf
), 0));
3291 ASSERT_EQ(0, rados_aio_flush(test_data
.m_ioctx
));
3292 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3294 memset(buf2
, 0, sizeof(buf2
));
3295 rados_completion_t my_completion2
;
3296 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3297 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3298 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3299 my_completion2
, buf2
, sizeof(buf2
), 0));
3302 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3304 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
3305 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3306 rados_aio_release(my_completion
);
3307 rados_aio_release(my_completion2
);
3310 TEST(LibRadosAioEC
, FlushPP
) {
3311 AioTestDataECPP test_data
;
3312 ASSERT_EQ("", test_data
.init());
3313 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3314 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3315 AioCompletion
*my_completion_null
= NULL
;
3316 ASSERT_NE(my_completion
, my_completion_null
);
3318 memset(buf
, 0xee, sizeof(buf
));
3320 bl1
.append(buf
, sizeof(buf
));
3321 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3322 bl1
, sizeof(buf
), 0));
3323 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush());
3324 ASSERT_EQ(0, my_completion
->get_return_value());
3326 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3327 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3328 ASSERT_NE(my_completion2
, my_completion_null
);
3329 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3330 &bl2
, sizeof(buf
), 0));
3333 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3335 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3336 ASSERT_EQ(sizeof(buf
), bl2
.length());
3337 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3338 delete my_completion
;
3339 delete my_completion2
;
3342 TEST(LibRadosAioEC
, FlushAsync
) {
3343 AioTestDataEC test_data
;
3344 rados_completion_t my_completion
;
3345 ASSERT_EQ("", test_data
.init());
3346 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3347 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3348 rados_completion_t flush_completion
;
3349 ASSERT_EQ(0, rados_aio_create_completion(NULL
, NULL
, NULL
, &flush_completion
));
3351 memset(buf
, 0xee, sizeof(buf
));
3352 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3353 my_completion
, buf
, sizeof(buf
), 0));
3354 ASSERT_EQ(0, rados_aio_flush_async(test_data
.m_ioctx
, flush_completion
));
3357 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion
));
3358 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion
));
3360 ASSERT_EQ(1, rados_aio_is_complete(my_completion
));
3361 ASSERT_EQ(1, rados_aio_is_safe(my_completion
));
3362 ASSERT_EQ(1, rados_aio_is_complete(flush_completion
));
3363 ASSERT_EQ(1, rados_aio_is_safe(flush_completion
));
3364 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3366 memset(buf2
, 0, sizeof(buf2
));
3367 rados_completion_t my_completion2
;
3368 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3369 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3370 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3371 my_completion2
, buf2
, sizeof(buf2
), 0));
3374 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3376 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
3377 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3378 rados_aio_release(my_completion
);
3379 rados_aio_release(my_completion2
);
3380 rados_aio_release(flush_completion
);
3383 TEST(LibRadosAioEC
, FlushAsyncPP
) {
3384 AioTestDataECPP test_data
;
3385 ASSERT_EQ("", test_data
.init());
3386 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3387 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3388 AioCompletion
*flush_completion
=
3389 test_data
.m_cluster
.aio_create_completion(NULL
, NULL
, NULL
);
3390 AioCompletion
*my_completion_null
= NULL
;
3391 ASSERT_NE(my_completion
, my_completion_null
);
3393 memset(buf
, 0xee, sizeof(buf
));
3395 bl1
.append(buf
, sizeof(buf
));
3396 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3397 bl1
, sizeof(buf
), 0));
3398 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush_async(flush_completion
));
3401 ASSERT_EQ(0, flush_completion
->wait_for_complete());
3402 ASSERT_EQ(0, flush_completion
->wait_for_safe());
3404 ASSERT_EQ(1, my_completion
->is_complete());
3405 ASSERT_EQ(1, my_completion
->is_safe());
3406 ASSERT_EQ(1, flush_completion
->is_complete());
3407 ASSERT_EQ(1, flush_completion
->is_safe());
3408 ASSERT_EQ(0, my_completion
->get_return_value());
3410 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3411 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3412 ASSERT_NE(my_completion2
, my_completion_null
);
3413 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3414 &bl2
, sizeof(buf
), 0));
3417 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3419 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3420 ASSERT_EQ(sizeof(buf
), bl2
.length());
3421 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3422 delete my_completion
;
3423 delete my_completion2
;
3424 delete flush_completion
;
3427 TEST(LibRadosAioEC
, RoundTripWriteFull
) {
3428 AioTestDataEC test_data
;
3429 rados_completion_t my_completion
, my_completion2
, my_completion3
;
3430 ASSERT_EQ("", test_data
.init());
3431 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3432 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3434 memset(buf
, 0xcc, sizeof(buf
));
3435 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3436 my_completion
, buf
, sizeof(buf
), 0));
3439 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
3441 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3443 memset(buf2
, 0xdd, sizeof(buf2
));
3444 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3445 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3446 ASSERT_EQ(0, rados_aio_write_full(test_data
.m_ioctx
, "foo",
3447 my_completion2
, buf2
, sizeof(buf2
)));
3450 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3452 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3453 char buf3
[sizeof(buf
) + sizeof(buf2
)];
3454 memset(buf3
, 0, sizeof(buf3
));
3455 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3456 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3457 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3458 my_completion3
, buf3
, sizeof(buf3
), 0));
3461 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3463 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion3
));
3464 ASSERT_EQ(0, memcmp(buf3
, buf2
, sizeof(buf2
)));
3465 rados_aio_release(my_completion
);
3466 rados_aio_release(my_completion2
);
3467 rados_aio_release(my_completion3
);
3470 TEST(LibRadosAioEC
, RoundTripWriteFullPP
) {
3471 AioTestDataECPP test_data
;
3472 ASSERT_EQ("", test_data
.init());
3473 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3474 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3475 AioCompletion
*my_completion_null
= NULL
;
3476 ASSERT_NE(my_completion
, my_completion_null
);
3478 memset(buf
, 0xcc, sizeof(buf
));
3480 bl1
.append(buf
, sizeof(buf
));
3481 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3482 bl1
, sizeof(buf
), 0));
3485 ASSERT_EQ(0, my_completion
->wait_for_complete());
3487 ASSERT_EQ(0, my_completion
->get_return_value());
3489 memset(buf2
, 0xdd, sizeof(buf2
));
3491 bl2
.append(buf2
, sizeof(buf2
));
3492 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3493 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3494 ASSERT_NE(my_completion2
, my_completion_null
);
3495 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write_full("foo", my_completion2
, bl2
));
3498 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3500 ASSERT_EQ(0, my_completion2
->get_return_value());
3502 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
3503 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3504 ASSERT_NE(my_completion3
, my_completion_null
);
3505 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
3506 &bl3
, sizeof(buf
), 0));
3509 ASSERT_EQ(0, my_completion3
->wait_for_complete());
3511 ASSERT_EQ((int)sizeof(buf2
), my_completion3
->get_return_value());
3512 ASSERT_EQ(sizeof(buf2
), bl3
.length());
3513 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
3514 delete my_completion
;
3515 delete my_completion2
;
3516 delete my_completion3
;
3519 //using ObjectWriteOperation/ObjectReadOperation with iohint
3520 TEST(LibRadosAioEC
, RoundTripWriteFullPP2
)
3523 std::string pool_name
= get_temp_pool_name();
3524 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
3526 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
3528 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
3529 ObjectWriteOperation op
;
3531 memset(buf
, 0xcc, sizeof(buf
));
3536 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE
);
3537 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
3540 ASSERT_EQ(0, my_completion1
->wait_for_complete());
3542 EXPECT_EQ(0, my_completion1
->get_return_value());
3544 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
3546 ObjectReadOperation op1
;
3547 op1
.read(0, sizeof(buf
), &bl
, NULL
);
3548 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
3549 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
3552 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3554 EXPECT_EQ(0, my_completion2
->get_return_value());
3555 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
3557 ioctx
.remove("test_obj");
3558 destroy_one_pool_pp(pool_name
, cluster
);
3561 TEST(LibRadosAioEC
, SimpleStat
) {
3562 AioTestDataEC test_data
;
3563 rados_completion_t my_completion
;
3564 ASSERT_EQ("", test_data
.init());
3565 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3566 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3568 memset(buf
, 0xcc, sizeof(buf
));
3569 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3570 my_completion
, buf
, sizeof(buf
), 0));
3573 sem_wait(test_data
.m_sem
);
3574 sem_wait(test_data
.m_sem
);
3576 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3579 rados_completion_t my_completion2
;
3580 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3581 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3582 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3583 my_completion2
, &psize
, &pmtime
));
3586 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3588 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3589 ASSERT_EQ(sizeof(buf
), psize
);
3590 rados_aio_release(my_completion
);
3591 rados_aio_release(my_completion2
);
3594 TEST(LibRadosAioEC
, SimpleStatPP
) {
3595 AioTestDataECPP test_data
;
3596 ASSERT_EQ("", test_data
.init());
3597 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3598 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3599 AioCompletion
*my_completion_null
= NULL
;
3600 ASSERT_NE(my_completion
, my_completion_null
);
3602 memset(buf
, 0xcc, sizeof(buf
));
3604 bl1
.append(buf
, sizeof(buf
));
3605 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3606 bl1
, sizeof(buf
), 0));
3609 sem_wait(test_data
.m_sem
);
3610 sem_wait(test_data
.m_sem
);
3612 ASSERT_EQ(0, my_completion
->get_return_value());
3615 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3616 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3617 ASSERT_NE(my_completion2
, my_completion_null
);
3618 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
3622 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3624 ASSERT_EQ(0, my_completion2
->get_return_value());
3625 ASSERT_EQ(sizeof(buf
), psize
);
3626 delete my_completion
;
3627 delete my_completion2
;
3630 TEST(LibRadosAioEC
, SimpleStatNS
) {
3631 AioTestDataEC test_data
;
3632 rados_completion_t my_completion
;
3633 ASSERT_EQ("", test_data
.init());
3634 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3635 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3637 memset(buf
, 0xcc, sizeof(buf
));
3638 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3639 my_completion
, buf
, sizeof(buf
), 0));
3642 sem_wait(test_data
.m_sem
);
3643 sem_wait(test_data
.m_sem
);
3645 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3646 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
3648 memset(buf2
, 0xbb, sizeof(buf2
));
3649 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3650 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3651 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3652 my_completion
, buf2
, sizeof(buf2
), 0));
3655 sem_wait(test_data
.m_sem
);
3656 sem_wait(test_data
.m_sem
);
3658 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3661 rados_completion_t my_completion2
;
3662 rados_ioctx_set_namespace(test_data
.m_ioctx
, "");
3663 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3664 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3665 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3666 my_completion2
, &psize
, &pmtime
));
3669 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3671 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3672 ASSERT_EQ(sizeof(buf
), psize
);
3674 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
3675 rados_completion_t my_completion3
;
3676 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3677 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3678 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3679 my_completion3
, &psize
, &pmtime
));
3682 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3684 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
3685 ASSERT_EQ(sizeof(buf2
), psize
);
3687 rados_aio_release(my_completion
);
3688 rados_aio_release(my_completion2
);
3689 rados_aio_release(my_completion3
);
3692 TEST(LibRadosAioEC
, SimpleStatPPNS
) {
3693 AioTestDataECPP test_data
;
3694 ASSERT_EQ("", test_data
.init());
3695 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3696 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3697 AioCompletion
*my_completion_null
= NULL
;
3698 ASSERT_NE(my_completion
, my_completion_null
);
3700 memset(buf
, 0xcc, sizeof(buf
));
3702 bl1
.append(buf
, sizeof(buf
));
3703 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3704 bl1
, sizeof(buf
), 0));
3707 sem_wait(test_data
.m_sem
);
3708 sem_wait(test_data
.m_sem
);
3710 ASSERT_EQ(0, my_completion
->get_return_value());
3713 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3714 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3715 ASSERT_NE(my_completion2
, my_completion_null
);
3716 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
3720 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3722 ASSERT_EQ(0, my_completion2
->get_return_value());
3723 ASSERT_EQ(sizeof(buf
), psize
);
3724 delete my_completion
;
3725 delete my_completion2
;
3728 TEST(LibRadosAioEC
, StatRemove
) {
3729 AioTestDataEC test_data
;
3730 rados_completion_t my_completion
;
3731 ASSERT_EQ("", test_data
.init());
3732 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3733 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3735 memset(buf
, 0xcc, sizeof(buf
));
3736 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3737 my_completion
, buf
, sizeof(buf
), 0));
3740 sem_wait(test_data
.m_sem
);
3741 sem_wait(test_data
.m_sem
);
3743 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3746 rados_completion_t my_completion2
;
3747 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3748 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3749 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3750 my_completion2
, &psize
, &pmtime
));
3753 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3755 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3756 ASSERT_EQ(sizeof(buf
), psize
);
3757 rados_completion_t my_completion3
;
3758 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3759 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3760 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion3
));
3763 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3765 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
3768 rados_completion_t my_completion4
;
3769 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3770 set_completion_completeEC
, set_completion_safeEC
, &my_completion4
));
3771 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3772 my_completion4
, &psize2
, &pmtime2
));
3775 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
3777 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion4
));
3778 rados_aio_release(my_completion
);
3779 rados_aio_release(my_completion2
);
3780 rados_aio_release(my_completion3
);
3781 rados_aio_release(my_completion4
);
3784 TEST(LibRadosAioEC
, StatRemovePP
) {
3785 AioTestDataECPP test_data
;
3786 ASSERT_EQ("", test_data
.init());
3787 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3788 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3789 AioCompletion
*my_completion_null
= NULL
;
3790 ASSERT_NE(my_completion
, my_completion_null
);
3792 memset(buf
, 0xcc, sizeof(buf
));
3794 bl1
.append(buf
, sizeof(buf
));
3795 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3796 bl1
, sizeof(buf
), 0));
3799 sem_wait(test_data
.m_sem
);
3800 sem_wait(test_data
.m_sem
);
3802 ASSERT_EQ(0, my_completion
->get_return_value());
3805 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3806 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3807 ASSERT_NE(my_completion2
, my_completion_null
);
3808 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
3812 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3814 ASSERT_EQ(0, my_completion2
->get_return_value());
3815 ASSERT_EQ(sizeof(buf
), psize
);
3818 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
3819 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3820 ASSERT_NE(my_completion3
, my_completion_null
);
3821 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion3
));
3824 ASSERT_EQ(0, my_completion3
->wait_for_complete());
3826 ASSERT_EQ(0, my_completion3
->get_return_value());
3828 AioCompletion
*my_completion4
= test_data
.m_cluster
.aio_create_completion(
3829 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3830 ASSERT_NE(my_completion4
, my_completion_null
);
3831 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion4
,
3832 &psize2
, &pmtime2
));
3835 ASSERT_EQ(0, my_completion4
->wait_for_complete());
3837 ASSERT_EQ(-ENOENT
, my_completion4
->get_return_value());
3838 delete my_completion
;
3839 delete my_completion2
;
3840 delete my_completion3
;
3841 delete my_completion4
;
3844 TEST(LibRadosAioEC
, ExecuteClass
) {
3845 AioTestDataEC test_data
;
3846 rados_completion_t my_completion
;
3847 ASSERT_EQ("", test_data
.init());
3848 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3849 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3851 memset(buf
, 0xcc, sizeof(buf
));
3852 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3853 my_completion
, buf
, sizeof(buf
), 0));
3856 sem_wait(test_data
.m_sem
);
3857 sem_wait(test_data
.m_sem
);
3859 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3860 rados_completion_t my_completion2
;
3861 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3862 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3864 ASSERT_EQ(0, rados_aio_exec(test_data
.m_ioctx
, "foo", my_completion2
,
3865 "hello", "say_hello", NULL
, 0, out
, sizeof(out
)));
3868 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3870 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2
));
3871 ASSERT_EQ(0, strncmp("Hello, world!", out
, 13));
3872 rados_aio_release(my_completion
);
3873 rados_aio_release(my_completion2
);
3876 TEST(LibRadosAioEC
, ExecuteClassPP
) {
3877 AioTestDataECPP test_data
;
3878 ASSERT_EQ("", test_data
.init());
3879 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3880 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3881 AioCompletion
*my_completion_null
= NULL
;
3882 ASSERT_NE(my_completion
, my_completion_null
);
3884 memset(buf
, 0xcc, sizeof(buf
));
3886 bl1
.append(buf
, sizeof(buf
));
3887 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3888 bl1
, sizeof(buf
), 0));
3891 sem_wait(test_data
.m_sem
);
3892 sem_wait(test_data
.m_sem
);
3894 ASSERT_EQ(0, my_completion
->get_return_value());
3895 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3896 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3897 ASSERT_NE(my_completion2
, my_completion_null
);
3899 ASSERT_EQ(0, test_data
.m_ioctx
.aio_exec("foo", my_completion2
,
3900 "hello", "say_hello", in
, &out
));
3903 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3905 ASSERT_EQ(0, my_completion2
->get_return_value());
3906 ASSERT_EQ(std::string("Hello, world!"), std::string(out
.c_str(), out
.length()));
3907 delete my_completion
;
3908 delete my_completion2
;
3911 TEST(LibRadosAioEC
, OmapPP
) {
3913 std::string pool_name
= get_temp_pool_name();
3914 ASSERT_EQ("", create_one_ec_pool_pp(pool_name
, cluster
));
3916 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
3918 string header_str
= "baz";
3919 bufferptr
bp(header_str
.c_str(), header_str
.size() + 1);
3920 bufferlist header_to_set
;
3921 header_to_set
.push_back(bp
);
3922 map
<string
, bufferlist
> to_set
;
3924 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
3925 ObjectWriteOperation op
;
3926 to_set
["foo"] = header_to_set
;
3927 to_set
["foo2"] = header_to_set
;
3928 to_set
["qfoo3"] = header_to_set
;
3929 op
.omap_set(to_set
);
3931 op
.omap_set_header(header_to_set
);
3933 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
3936 ASSERT_EQ(0, my_completion
->wait_for_complete());
3938 EXPECT_EQ(-EOPNOTSUPP
, my_completion
->get_return_value());
3940 ioctx
.remove("test_obj");
3941 destroy_one_pool_pp(pool_name
, cluster
);
3944 TEST(LibRadosAioEC
, MultiWrite
) {
3945 AioTestDataEC test_data
;
3946 rados_completion_t my_completion
, my_completion2
, my_completion3
;
3947 ASSERT_EQ("", test_data
.init());
3948 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3949 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3951 memset(buf
, 0xcc, sizeof(buf
));
3952 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3953 my_completion
, buf
, sizeof(buf
), 0));
3956 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
3958 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3961 memset(buf2
, 0xdd, sizeof(buf2
));
3962 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3963 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3964 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3965 my_completion2
, buf2
, sizeof(buf2
), sizeof(buf
)));
3968 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3970 ASSERT_EQ(-EOPNOTSUPP
, rados_aio_get_return_value(my_completion2
));
3972 char buf3
[(sizeof(buf
) + sizeof(buf2
)) * 3];
3973 memset(buf3
, 0, sizeof(buf3
));
3974 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3975 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3976 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3977 my_completion3
, buf3
, sizeof(buf3
), 0));
3980 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3982 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion3
));
3983 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
3984 rados_aio_release(my_completion
);
3985 rados_aio_release(my_completion2
);
3986 rados_aio_release(my_completion3
);
3989 TEST(LibRadosAioEC
, MultiWritePP
) {
3990 AioTestDataECPP test_data
;
3991 ASSERT_EQ("", test_data
.init());
3992 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3993 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3994 AioCompletion
*my_completion_null
= NULL
;
3995 ASSERT_NE(my_completion
, my_completion_null
);
3997 memset(buf
, 0xcc, sizeof(buf
));
3999 bl1
.append(buf
, sizeof(buf
));
4000 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
4001 bl1
, sizeof(buf
), 0));
4004 ASSERT_EQ(0, my_completion
->wait_for_complete());
4006 ASSERT_EQ(0, my_completion
->get_return_value());
4009 memset(buf2
, 0xdd, sizeof(buf2
));
4011 bl2
.append(buf2
, sizeof(buf2
));
4012 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
4013 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
4014 ASSERT_NE(my_completion2
, my_completion_null
);
4015 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion2
,
4016 bl2
, sizeof(buf2
), sizeof(buf
)));
4019 ASSERT_EQ(0, my_completion2
->wait_for_complete());
4021 ASSERT_EQ(-EOPNOTSUPP
, my_completion2
->get_return_value());
4024 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
4025 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
4026 ASSERT_NE(my_completion3
, my_completion_null
);
4027 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
4028 &bl3
, (sizeof(buf
) + sizeof(buf2
) * 3), 0));
4031 ASSERT_EQ(0, my_completion3
->wait_for_complete());
4033 ASSERT_EQ((int)sizeof(buf
), my_completion3
->get_return_value());
4034 ASSERT_EQ(sizeof(buf
), bl3
.length());
4035 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, sizeof(buf
)));
4036 delete my_completion
;
4037 delete my_completion2
;
4038 delete my_completion3
;
4041 TEST(LibRadosAio
, RacingRemovePP
) {
4042 AioTestDataPP test_data
;
4043 ASSERT_EQ("", test_data
.init({{"objecter_retry_writes_after_first_reply", "true"}}));
4044 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
4045 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4046 ASSERT_NE(my_completion
, nullptr);
4048 memset(buf
, 0xcc, sizeof(buf
));
4050 bl
.append(buf
, sizeof(buf
));
4051 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
4052 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4053 ASSERT_NE(my_completion2
, nullptr);
4054 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion2
));
4055 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
4056 bl
, sizeof(buf
), 0));
4059 sem_wait(test_data
.m_sem
);
4060 sem_wait(test_data
.m_sem
);
4061 my_completion2
->wait_for_complete();
4062 my_completion
->wait_for_complete();
4064 ASSERT_EQ(-ENOENT
, my_completion2
->get_return_value());
4065 ASSERT_EQ(0, my_completion
->get_return_value());
4066 ASSERT_EQ(0, test_data
.m_ioctx
.stat("foo", nullptr, nullptr));
4067 delete my_completion
;
4068 delete my_completion2
;
4071 TEST(LibRadosAio
, RoundTripCmpExtPP
) {
4072 AioTestDataPP test_data
;
4073 ASSERT_EQ("", test_data
.init());
4074 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
4075 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4076 AioCompletion
*my_completion_null
= NULL
;
4077 ASSERT_NE(my_completion
, my_completion_null
);
4079 memset(full
, 0xcc, sizeof(full
));
4081 bl1
.append(full
, sizeof(full
));
4082 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
4083 bl1
, sizeof(full
), 0));
4086 ASSERT_EQ(0, my_completion
->wait_for_complete());
4088 ASSERT_EQ(0, my_completion
->get_return_value());
4090 /* compare with match */
4092 cbl
.append(full
, sizeof(full
));
4093 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
4094 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4095 ASSERT_EQ(0, test_data
.m_ioctx
.aio_cmpext("foo", my_completion2
, 0, cbl
));
4099 ASSERT_EQ(0, my_completion2
->wait_for_complete());
4101 ASSERT_EQ(0, my_completion2
->get_return_value());
4103 /* compare with mismatch */
4104 memset(full
, 0xdd, sizeof(full
));
4106 cbl
.append(full
, sizeof(full
));
4107 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
4108 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4109 ASSERT_EQ(0, test_data
.m_ioctx
.aio_cmpext("foo", my_completion3
, 0, cbl
));
4113 ASSERT_EQ(0, my_completion3
->wait_for_complete());
4115 ASSERT_EQ(-MAX_ERRNO
, my_completion3
->get_return_value());
4117 delete my_completion
;
4118 delete my_completion2
;
4119 delete my_completion3
;
4122 TEST(LibRadosAio
, RoundTripCmpExtPP2
)
4126 char miscmp_buf
[128];
4129 std::string pool_name
= get_temp_pool_name();
4130 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
4132 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
4134 boost::scoped_ptr
<AioCompletion
>
4135 wr_cmpl(cluster
.aio_create_completion(0, 0, 0));
4136 ObjectWriteOperation wr_op
;
4137 memset(buf
, 0xcc, sizeof(buf
));
4138 memset(miscmp_buf
, 0xdd, sizeof(miscmp_buf
));
4140 bl
.append(buf
, sizeof(buf
));
4142 wr_op
.write_full(bl
);
4143 wr_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4144 ioctx
.aio_operate("test_obj", wr_cmpl
.get(), &wr_op
);
4147 ASSERT_EQ(0, wr_cmpl
->wait_for_complete());
4149 EXPECT_EQ(0, wr_cmpl
->get_return_value());
4151 /* cmpext as write op. first match then mismatch */
4152 boost::scoped_ptr
<AioCompletion
>
4153 wr_cmpext_cmpl(cluster
.aio_create_completion(0, 0, 0));
4154 cbl
.append(buf
, sizeof(buf
));
4157 wr_op
.cmpext(0, cbl
, &ret
);
4158 wr_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4159 ioctx
.aio_operate("test_obj", wr_cmpext_cmpl
.get(), &wr_op
);
4162 ASSERT_EQ(0, wr_cmpext_cmpl
->wait_for_complete());
4164 EXPECT_EQ(0, wr_cmpext_cmpl
->get_return_value());
4167 boost::scoped_ptr
<AioCompletion
>
4168 wr_cmpext_cmpl2(cluster
.aio_create_completion(0, 0, 0));
4170 cbl
.append(miscmp_buf
, sizeof(miscmp_buf
));
4173 wr_op
.cmpext(0, cbl
, &ret
);
4174 wr_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4175 ioctx
.aio_operate("test_obj", wr_cmpext_cmpl2
.get(), &wr_op
);
4178 ASSERT_EQ(0, wr_cmpext_cmpl2
->wait_for_complete());
4180 EXPECT_EQ(-MAX_ERRNO
, wr_cmpext_cmpl2
->get_return_value());
4181 EXPECT_EQ(-MAX_ERRNO
, ret
);
4183 /* cmpext as read op */
4184 boost::scoped_ptr
<AioCompletion
>
4185 rd_cmpext_cmpl(cluster
.aio_create_completion(0, 0, 0));
4186 ObjectReadOperation rd_op
;
4188 cbl
.append(buf
, sizeof(buf
));
4190 rd_op
.cmpext(0, cbl
, &ret
);
4191 rd_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4192 ioctx
.aio_operate("test_obj", rd_cmpext_cmpl
.get(), &rd_op
, 0);
4195 ASSERT_EQ(0, rd_cmpext_cmpl
->wait_for_complete());
4197 EXPECT_EQ(0, rd_cmpext_cmpl
->get_return_value());
4200 boost::scoped_ptr
<AioCompletion
>
4201 rd_cmpext_cmpl2(cluster
.aio_create_completion(0, 0, 0));
4203 cbl
.append(miscmp_buf
, sizeof(miscmp_buf
));
4206 rd_op
.cmpext(0, cbl
, &ret
);
4207 rd_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4208 ioctx
.aio_operate("test_obj", rd_cmpext_cmpl2
.get(), &rd_op
, 0);
4211 ASSERT_EQ(0, rd_cmpext_cmpl2
->wait_for_complete());
4213 EXPECT_EQ(-MAX_ERRNO
, rd_cmpext_cmpl2
->get_return_value());
4214 EXPECT_EQ(-MAX_ERRNO
, ret
);
4216 ioctx
.remove("test_obj");
4217 destroy_one_pool_pp(pool_name
, cluster
);