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
;
71 sem_t
*m_sem
= nullptr;
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
;
134 sem_t
*m_sem
= nullptr;
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
));
208 ioctx
.application_enable("rados", true);
211 ASSERT_EQ(0, test_data
.m_cluster
.mon_command(
212 "{\"prefix\": \"osd pool set-quota\", \"pool\": \"" + p
+
213 "\", \"field\": \"max_bytes\", \"val\": \"4096\"}",
220 for (n
= 0; n
< 1024; ++n
) {
221 ObjectWriteOperation op
;
223 librados::AioCompletion
*completion
=
224 test_data
.m_cluster
.aio_create_completion();
225 ASSERT_EQ(0, ioctx
.aio_operate(
226 "foo" + stringify(n
), completion
, &op
,
227 librados::OPERATION_FULL_TRY
));
228 completion
->wait_for_safe();
229 int r
= completion
->get_return_value();
230 completion
->release();
238 // make sure we have latest map that marked the pool full
239 test_data
.m_cluster
.wait_for_latest_osdmap();
241 // make sure we block without FULL_TRY
243 ObjectWriteOperation op
;
245 librados::AioCompletion
*completion
=
246 test_data
.m_cluster
.aio_create_completion();
247 ASSERT_EQ(0, ioctx
.aio_operate("bar", completion
, &op
, 0));
249 ASSERT_FALSE(completion
->is_safe());
250 completion
->release();
254 ASSERT_EQ(0, test_data
.m_cluster
.pool_delete(p
.c_str()));
257 TEST(LibRadosAio
, SimpleWrite
) {
258 AioTestData test_data
;
259 rados_completion_t my_completion
;
260 ASSERT_EQ("", test_data
.init());
261 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
262 set_completion_complete
, set_completion_safe
, &my_completion
));
264 memset(buf
, 0xcc, sizeof(buf
));
265 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
266 my_completion
, buf
, sizeof(buf
), 0));
269 sem_wait(test_data
.m_sem
);
270 sem_wait(test_data
.m_sem
);
272 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
274 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
275 rados_completion_t my_completion2
;
276 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
277 set_completion_complete
, set_completion_safe
, &my_completion2
));
278 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
279 my_completion2
, buf
, sizeof(buf
), 0));
282 sem_wait(test_data
.m_sem
);
283 sem_wait(test_data
.m_sem
);
285 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
286 rados_aio_release(my_completion
);
287 rados_aio_release(my_completion2
);
290 TEST(LibRadosAio
, SimpleWritePP
) {
292 memset(buf
, 0xcc, sizeof(buf
));
294 bl1
.append(buf
, sizeof(buf
));
296 AioTestDataPP test_data
;
297 ASSERT_EQ("", test_data
.init());
298 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
299 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
300 AioCompletion
*my_completion_null
= NULL
;
301 ASSERT_NE(my_completion
, my_completion_null
);
302 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
303 my_completion
, bl1
, sizeof(buf
), 0));
306 sem_wait(test_data
.m_sem
);
307 sem_wait(test_data
.m_sem
);
309 ASSERT_EQ(0, my_completion
->get_return_value());
310 delete my_completion
;
314 AioTestDataPP test_data
;
315 ASSERT_EQ("", test_data
.init());
316 test_data
.m_ioctx
.set_namespace("nspace");
317 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
318 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
319 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
320 my_completion
, bl1
, sizeof(buf
), 0));
323 sem_wait(test_data
.m_sem
);
324 sem_wait(test_data
.m_sem
);
326 ASSERT_EQ(0, my_completion
->get_return_value());
327 delete my_completion
;
331 TEST(LibRadosAio
, WaitForSafe
) {
332 AioTestData test_data
;
333 rados_completion_t my_completion
;
334 ASSERT_EQ("", test_data
.init());
335 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
336 set_completion_complete
, set_completion_safe
, &my_completion
));
338 memset(buf
, 0xcc, sizeof(buf
));
339 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
340 my_completion
, buf
, sizeof(buf
), 0));
342 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion
));
343 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
344 rados_aio_release(my_completion
);
347 TEST(LibRadosAio
, WaitForSafePP
) {
348 AioTestDataPP test_data
;
349 ASSERT_EQ("", test_data
.init());
350 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
351 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
352 AioCompletion
*my_completion_null
= NULL
;
353 ASSERT_NE(my_completion
, my_completion_null
);
355 memset(buf
, 0xcc, sizeof(buf
));
357 bl1
.append(buf
, sizeof(buf
));
358 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
359 my_completion
, bl1
, sizeof(buf
), 0));
361 ASSERT_EQ(0, my_completion
->wait_for_safe());
362 ASSERT_EQ(0, my_completion
->get_return_value());
363 delete my_completion
;
366 TEST(LibRadosAio
, RoundTrip
) {
367 AioTestData test_data
;
368 rados_completion_t my_completion
;
369 ASSERT_EQ("", test_data
.init());
370 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
371 set_completion_complete
, set_completion_safe
, &my_completion
));
373 memset(buf
, 0xcc, sizeof(buf
));
374 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
375 my_completion
, buf
, sizeof(buf
), 0));
378 sem_wait(test_data
.m_sem
);
379 sem_wait(test_data
.m_sem
);
381 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
383 memset(buf2
, 0, sizeof(buf2
));
384 rados_completion_t my_completion2
;
385 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
386 set_completion_complete
, set_completion_safe
, &my_completion2
));
387 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
388 my_completion2
, buf2
, sizeof(buf2
), 0));
391 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
393 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
394 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
395 rados_aio_release(my_completion
);
396 rados_aio_release(my_completion2
);
399 TEST(LibRadosAio
, RoundTrip2
) {
400 AioTestData test_data
;
401 rados_completion_t my_completion
;
402 ASSERT_EQ("", test_data
.init());
403 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
404 set_completion_complete
, set_completion_safe
, &my_completion
));
406 memset(buf
, 0xcc, sizeof(buf
));
407 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
408 my_completion
, buf
, sizeof(buf
), 0));
411 sem_wait(test_data
.m_sem
);
412 sem_wait(test_data
.m_sem
);
414 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
416 memset(buf2
, 0, sizeof(buf2
));
417 rados_completion_t my_completion2
;
418 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
419 set_completion_complete
, set_completion_safe
, &my_completion2
));
420 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
421 my_completion2
, buf2
, sizeof(buf2
), 0));
424 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
426 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
427 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
428 rados_aio_release(my_completion
);
429 rados_aio_release(my_completion2
);
432 TEST(LibRadosAio
, RoundTrip3
) {
433 AioTestData test_data
;
434 rados_completion_t my_completion
;
435 ASSERT_EQ("", test_data
.init());
436 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
437 set_completion_complete
, set_completion_safe
, &my_completion
));
439 memset(buf
, 0xcc, sizeof(buf
));
441 rados_write_op_t op1
= rados_create_write_op();
442 rados_write_op_write(op1
, buf
, sizeof(buf
), 0);
443 rados_write_op_set_alloc_hint2(op1
, 0, 0, LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
444 ASSERT_EQ(0, rados_aio_write_op_operate(op1
, test_data
.m_ioctx
, my_completion
,
446 rados_release_write_op(op1
);
450 sem_wait(test_data
.m_sem
);
451 sem_wait(test_data
.m_sem
);
454 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
455 rados_aio_release(my_completion
);
458 memset(buf2
, 0, sizeof(buf2
));
459 rados_completion_t my_completion2
;
460 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
461 set_completion_complete
, set_completion_safe
, &my_completion2
));
463 rados_read_op_t op2
= rados_create_read_op();
464 rados_read_op_read(op2
, 0, sizeof(buf2
), buf2
, NULL
, NULL
);
465 rados_read_op_set_flags(op2
, LIBRADOS_OP_FLAG_FADVISE_NOCACHE
|
466 LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
467 __le32 init_value
= -1;
469 rados_read_op_checksum(op2
, LIBRADOS_CHECKSUM_TYPE_CRC32C
,
470 reinterpret_cast<char *>(&init_value
),
471 sizeof(init_value
), 0, 0, 0,
472 reinterpret_cast<char *>(&checksum
),
473 sizeof(checksum
), NULL
);
474 ASSERT_EQ(0, rados_aio_read_op_operate(op2
, test_data
.m_ioctx
, my_completion2
,
476 rados_release_read_op(op2
);
480 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
482 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
483 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
484 rados_aio_release(my_completion2
);
487 bl
.append(buf
, sizeof(buf
));
488 ASSERT_EQ(1U, checksum
[0]);
489 ASSERT_EQ(bl
.crc32c(-1), checksum
[1]);
492 TEST(LibRadosAio
, RoundTripPP
) {
493 AioTestDataPP test_data
;
494 ASSERT_EQ("", test_data
.init());
495 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
496 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
497 AioCompletion
*my_completion_null
= NULL
;
498 ASSERT_NE(my_completion
, my_completion_null
);
500 memset(buf
, 0xcc, sizeof(buf
));
502 bl1
.append(buf
, sizeof(buf
));
503 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
504 bl1
, sizeof(buf
), 0));
507 sem_wait(test_data
.m_sem
);
508 sem_wait(test_data
.m_sem
);
510 ASSERT_EQ(0, my_completion
->get_return_value());
512 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
513 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
514 ASSERT_NE(my_completion2
, my_completion_null
);
515 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
516 my_completion2
, &bl2
, sizeof(buf
), 0));
519 ASSERT_EQ(0, my_completion2
->wait_for_complete());
521 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
522 ASSERT_EQ(sizeof(buf
), bl2
.length());
523 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
524 delete my_completion
;
525 delete my_completion2
;
528 TEST(LibRadosAio
, RoundTripPP2
) {
529 AioTestDataPP test_data
;
530 ASSERT_EQ("", test_data
.init());
531 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
532 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
533 AioCompletion
*my_completion_null
= NULL
;
534 ASSERT_NE(my_completion
, my_completion_null
);
536 memset(buf
, 0xcc, sizeof(buf
));
538 bl1
.append(buf
, sizeof(buf
));
539 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
540 bl1
, sizeof(buf
), 0));
543 sem_wait(test_data
.m_sem
);
544 sem_wait(test_data
.m_sem
);
546 ASSERT_EQ(0, my_completion
->get_return_value());
548 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
549 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
550 ASSERT_NE(my_completion2
, my_completion_null
);
551 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
552 my_completion2
, &bl2
, sizeof(buf
), 0));
555 ASSERT_EQ(0, my_completion2
->wait_for_safe());
556 ASSERT_EQ(0, my_completion2
->wait_for_complete());
558 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
559 ASSERT_EQ(sizeof(buf
), bl2
.length());
560 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
561 delete my_completion
;
562 delete my_completion2
;
565 //using ObjectWriteOperation/ObjectReadOperation with iohint
566 TEST(LibRadosAio
, RoundTripPP3
)
569 std::string pool_name
= get_temp_pool_name();
570 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
572 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
574 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
575 ObjectWriteOperation op
;
577 memset(buf
, 0xcc, sizeof(buf
));
579 bl
.append(buf
, sizeof(buf
));
582 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
583 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
586 ASSERT_EQ(0, my_completion1
->wait_for_complete());
588 EXPECT_EQ(0, my_completion1
->get_return_value());
590 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
592 ObjectReadOperation op1
;
593 op1
.read(0, sizeof(buf
), &bl
, NULL
);
594 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
595 bufferlist init_value_bl
;
596 ::encode(static_cast<int32_t>(-1), init_value_bl
);
598 op1
.checksum(LIBRADOS_CHECKSUM_TYPE_CRC32C
, init_value_bl
,
599 0, 0, 0, &csum_bl
, nullptr);
600 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
603 ASSERT_EQ(0, my_completion2
->wait_for_complete());
605 EXPECT_EQ(0, my_completion2
->get_return_value());
606 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
608 ASSERT_EQ(8U, csum_bl
.length());
609 auto csum_bl_it
= csum_bl
.begin();
612 ::decode(csum_count
, csum_bl_it
);
613 ASSERT_EQ(1U, csum_count
);
614 ::decode(csum
, csum_bl_it
);
615 ASSERT_EQ(bl
.crc32c(-1), csum
);
616 ioctx
.remove("test_obj");
617 destroy_one_pool_pp(pool_name
, cluster
);
620 TEST(LibRadosAio
, RoundTripSparseReadPP
) {
621 AioTestDataPP test_data
;
622 ASSERT_EQ("", test_data
.init());
623 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
624 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
625 AioCompletion
*my_completion_null
= NULL
;
626 ASSERT_NE(my_completion
, my_completion_null
);
628 memset(buf
, 0xcc, sizeof(buf
));
630 bl1
.append(buf
, sizeof(buf
));
631 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
632 bl1
, sizeof(buf
), 0));
635 sem_wait(test_data
.m_sem
);
636 sem_wait(test_data
.m_sem
);
638 ASSERT_EQ(0, my_completion
->get_return_value());
639 std::map
<uint64_t, uint64_t> extents
;
641 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
642 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
643 ASSERT_NE(my_completion2
, my_completion_null
);
644 ASSERT_EQ(0, test_data
.m_ioctx
.aio_sparse_read("foo",
645 my_completion2
, &extents
, &bl2
, sizeof(buf
), 0));
648 ASSERT_EQ(0, my_completion2
->wait_for_complete());
650 ASSERT_EQ(0, my_completion2
->get_return_value());
651 assert_eq_sparse(bl1
, extents
, bl2
);
652 delete my_completion
;
653 delete my_completion2
;
656 TEST(LibRadosAio
, RoundTripAppend
) {
657 AioTestData test_data
;
658 rados_completion_t my_completion
, my_completion2
, my_completion3
;
659 ASSERT_EQ("", test_data
.init());
660 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
661 set_completion_complete
, set_completion_safe
, &my_completion
));
663 memset(buf
, 0xcc, sizeof(buf
));
664 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
665 my_completion
, buf
, sizeof(buf
)));
668 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
670 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
672 memset(buf2
, 0xdd, sizeof(buf2
));
673 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
674 set_completion_complete
, set_completion_safe
, &my_completion2
));
675 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
676 my_completion2
, buf2
, sizeof(buf2
)));
679 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
681 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
682 char buf3
[sizeof(buf
) + sizeof(buf2
)];
683 memset(buf3
, 0, sizeof(buf3
));
684 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
685 set_completion_complete
, set_completion_safe
, &my_completion3
));
686 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
687 my_completion3
, buf3
, sizeof(buf3
), 0));
690 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
692 ASSERT_EQ((int)sizeof(buf3
), rados_aio_get_return_value(my_completion3
));
693 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
694 ASSERT_EQ(0, memcmp(buf3
+ sizeof(buf
), buf2
, sizeof(buf2
)));
695 rados_aio_release(my_completion
);
696 rados_aio_release(my_completion2
);
697 rados_aio_release(my_completion3
);
700 TEST(LibRadosAio
, RoundTripAppendPP
) {
701 AioTestDataPP test_data
;
702 ASSERT_EQ("", test_data
.init());
703 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
704 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
705 AioCompletion
*my_completion_null
= NULL
;
706 ASSERT_NE(my_completion
, my_completion_null
);
708 memset(buf
, 0xcc, sizeof(buf
));
710 bl1
.append(buf
, sizeof(buf
));
711 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion
,
715 ASSERT_EQ(0, my_completion
->wait_for_complete());
717 ASSERT_EQ(0, my_completion
->get_return_value());
719 memset(buf2
, 0xdd, sizeof(buf2
));
721 bl2
.append(buf2
, sizeof(buf2
));
722 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
723 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
724 ASSERT_NE(my_completion2
, my_completion_null
);
725 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion2
,
729 ASSERT_EQ(0, my_completion2
->wait_for_complete());
731 ASSERT_EQ(0, my_completion2
->get_return_value());
733 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
734 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
735 ASSERT_NE(my_completion3
, my_completion_null
);
736 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
737 my_completion3
, &bl3
, 2 * sizeof(buf
), 0));
740 ASSERT_EQ(0, my_completion3
->wait_for_complete());
742 ASSERT_EQ((int)(sizeof(buf
) * 2), my_completion3
->get_return_value());
743 ASSERT_EQ(sizeof(buf
) * 2, bl3
.length());
744 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, sizeof(buf
)));
745 ASSERT_EQ(0, memcmp(bl3
.c_str() + sizeof(buf
), buf2
, sizeof(buf2
)));
746 delete my_completion
;
747 delete my_completion2
;
748 delete my_completion3
;
751 TEST(LibRadosAio
, RemoveTest
) {
753 char buf2
[sizeof(buf
)];
754 rados_completion_t my_completion
;
755 AioTestData test_data
;
756 ASSERT_EQ("", test_data
.init());
757 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
758 set_completion_complete
, set_completion_safe
, &my_completion
));
759 memset(buf
, 0xaa, sizeof(buf
));
760 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
761 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion
));
764 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
766 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
767 memset(buf2
, 0, sizeof(buf2
));
768 ASSERT_EQ(-ENOENT
, rados_read(test_data
.m_ioctx
, "foo", buf2
, sizeof(buf2
), 0));
769 rados_aio_release(my_completion
);
772 TEST(LibRadosAioPP
, RemoveTestPP
) {
774 memset(buf
, 0xaa, sizeof(buf
));
776 bl1
.append(buf
, sizeof(buf
));
777 AioTestDataPP test_data
;
778 ASSERT_EQ("", test_data
.init());
779 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
780 boost::scoped_ptr
<AioCompletion
> my_completion
781 (test_data
.m_cluster
.aio_create_completion
782 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
783 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion
.get()));
786 ASSERT_EQ(0, my_completion
->wait_for_complete());
788 ASSERT_EQ(0, my_completion
->get_return_value());
790 ASSERT_EQ(-ENOENT
, test_data
.m_ioctx
.read("foo", bl2
, sizeof(buf
), 0));
793 TEST(LibRadosAio
, XattrsRoundTrip
) {
795 char attr1
[] = "attr1";
796 char attr1_buf
[] = "foo bar baz";
798 AioTestData test_data
;
799 ASSERT_EQ("", test_data
.init());
800 memset(buf
, 0xaa, sizeof(buf
));
801 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
803 rados_completion_t my_completion
;
804 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
805 set_completion_complete
, set_completion_safe
, &my_completion
));
806 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion
, attr1
, buf
, sizeof(buf
)));
809 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
811 ASSERT_EQ(-ENODATA
, rados_aio_get_return_value(my_completion
));
812 rados_aio_release(my_completion
);
814 rados_completion_t my_completion2
;
815 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
816 set_completion_complete
, set_completion_safe
, &my_completion2
));
817 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo", my_completion2
, attr1
, attr1_buf
, sizeof(attr1_buf
)));
820 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
822 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
823 rados_aio_release(my_completion2
);
825 rados_completion_t my_completion3
;
826 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
827 set_completion_complete
, set_completion_safe
, &my_completion3
));
828 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion3
, attr1
, buf
, sizeof(buf
)));
831 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
833 ASSERT_EQ((int)sizeof(attr1_buf
), rados_aio_get_return_value(my_completion3
));
834 rados_aio_release(my_completion3
);
835 // check content of attribute
836 ASSERT_EQ(0, memcmp(attr1_buf
, buf
, sizeof(attr1_buf
)));
839 TEST(LibRadosAioPP
, XattrsRoundTripPP
) {
841 char attr1
[] = "attr1";
842 char attr1_buf
[] = "foo bar baz";
843 memset(buf
, 0xaa, sizeof(buf
));
845 bl1
.append(buf
, sizeof(buf
));
846 AioTestDataPP test_data
;
847 ASSERT_EQ("", test_data
.init());
848 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
851 boost::scoped_ptr
<AioCompletion
> my_completion
852 (test_data
.m_cluster
.aio_create_completion
853 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
854 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattr("foo", my_completion
.get(), attr1
, bl2
));
857 ASSERT_EQ(0, my_completion
->wait_for_complete());
859 ASSERT_EQ(-ENODATA
, my_completion
->get_return_value());
862 bl3
.append(attr1_buf
, sizeof(attr1_buf
));
864 AioTestDataPP test_data2
;
865 ASSERT_EQ("", test_data2
.init());
866 boost::scoped_ptr
<AioCompletion
> my_completion2
867 (test_data
.m_cluster
.aio_create_completion
868 ((void*)&test_data2
, set_completion_completePP
, set_completion_safePP
));
869 ASSERT_EQ(0, test_data
.m_ioctx
.aio_setxattr("foo", my_completion2
.get(), attr1
, bl3
));
872 ASSERT_EQ(0, my_completion2
->wait_for_complete());
874 ASSERT_EQ(0, my_completion2
->get_return_value());
877 AioTestDataPP test_data3
;
878 ASSERT_EQ("", test_data3
.init());
879 boost::scoped_ptr
<AioCompletion
> my_completion3
880 (test_data
.m_cluster
.aio_create_completion
881 ((void*)&test_data3
, set_completion_completePP
, set_completion_safePP
));
882 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattr("foo", my_completion3
.get(), attr1
, bl4
));
885 ASSERT_EQ(0, my_completion3
->wait_for_complete());
887 ASSERT_EQ((int)sizeof(attr1_buf
), my_completion3
->get_return_value());
888 // check content of attribute
889 ASSERT_EQ(0, memcmp(bl4
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
892 TEST(LibRadosAio
, RmXattr
) {
894 char attr1
[] = "attr1";
895 char attr1_buf
[] = "foo bar baz";
897 memset(buf
, 0xaa, sizeof(buf
));
898 AioTestData test_data
;
899 ASSERT_EQ("", test_data
.init());
900 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
902 rados_completion_t my_completion
;
903 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
904 set_completion_complete
, set_completion_safe
, &my_completion
));
905 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo", my_completion
, attr1
, attr1_buf
, sizeof(attr1_buf
)));
908 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
910 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
911 rados_aio_release(my_completion
);
913 rados_completion_t my_completion2
;
914 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
915 set_completion_complete
, set_completion_safe
, &my_completion2
));
916 ASSERT_EQ(0, rados_aio_rmxattr(test_data
.m_ioctx
, "foo", my_completion2
, attr1
));
919 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
921 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
922 rados_aio_release(my_completion2
);
923 // async getxattr after deletion
924 rados_completion_t my_completion3
;
925 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
926 set_completion_complete
, set_completion_safe
, &my_completion3
));
927 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion3
, attr1
, buf
, sizeof(buf
)));
930 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
932 ASSERT_EQ(-ENODATA
, rados_aio_get_return_value(my_completion3
));
933 rados_aio_release(my_completion3
);
934 // Test rmxattr on a removed object
936 char attr2
[] = "attr2";
937 char attr2_buf
[] = "foo bar baz";
938 memset(buf2
, 0xbb, sizeof(buf2
));
939 ASSERT_EQ(0, rados_write(test_data
.m_ioctx
, "foo_rmxattr", buf2
, sizeof(buf2
), 0));
941 rados_completion_t my_completion4
;
942 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
943 set_completion_complete
, set_completion_safe
, &my_completion4
));
944 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo_rmxattr", my_completion4
, attr2
, attr2_buf
, sizeof(attr2_buf
)));
947 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
949 ASSERT_EQ(0, rados_aio_get_return_value(my_completion4
));
950 rados_aio_release(my_completion4
);
952 ASSERT_EQ(0, rados_remove(test_data
.m_ioctx
, "foo_rmxattr"));
953 // async rmxattr on non existing object
954 rados_completion_t my_completion5
;
955 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
956 set_completion_complete
, set_completion_safe
, &my_completion5
));
957 ASSERT_EQ(0, rados_aio_rmxattr(test_data
.m_ioctx
, "foo_rmxattr", my_completion5
, attr2
));
960 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion5
));
962 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion5
));
963 rados_aio_release(my_completion5
);
966 TEST(LibRadosAioPP
, RmXattrPP
) {
968 char attr1
[] = "attr1";
969 char attr1_buf
[] = "foo bar baz";
970 memset(buf
, 0xaa, sizeof(buf
));
972 bl1
.append(buf
, sizeof(buf
));
973 AioTestDataPP test_data
;
974 ASSERT_EQ("", test_data
.init());
975 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
978 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
979 boost::scoped_ptr
<AioCompletion
> my_completion
980 (test_data
.m_cluster
.aio_create_completion
981 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
982 ASSERT_EQ(0, test_data
.m_ioctx
.aio_setxattr("foo", my_completion
.get(), attr1
, bl2
));
985 ASSERT_EQ(0, my_completion
->wait_for_complete());
987 ASSERT_EQ(0, my_completion
->get_return_value());
989 AioTestDataPP test_data2
;
990 ASSERT_EQ("", test_data2
.init());
991 boost::scoped_ptr
<AioCompletion
> my_completion2
992 (test_data
.m_cluster
.aio_create_completion
993 ((void*)&test_data2
, set_completion_completePP
, set_completion_safePP
));
994 ASSERT_EQ(0, test_data
.m_ioctx
.aio_rmxattr("foo", my_completion2
.get(), attr1
));
997 ASSERT_EQ(0, my_completion2
->wait_for_complete());
999 ASSERT_EQ(0, my_completion2
->get_return_value());
1001 AioTestDataPP test_data3
;
1002 ASSERT_EQ("", test_data3
.init());
1003 boost::scoped_ptr
<AioCompletion
> my_completion3
1004 (test_data
.m_cluster
.aio_create_completion
1005 ((void*)&test_data3
, set_completion_completePP
, set_completion_safePP
));
1007 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattr("foo", my_completion3
.get(), attr1
, bl3
));
1010 ASSERT_EQ(0, my_completion3
->wait_for_complete());
1012 ASSERT_EQ(-ENODATA
, my_completion3
->get_return_value());
1013 // Test rmxattr on a removed object
1015 char attr2
[] = "attr2";
1016 char attr2_buf
[] = "foo bar baz";
1017 memset(buf2
, 0xbb, sizeof(buf2
));
1019 bl21
.append(buf
, sizeof(buf
));
1020 ASSERT_EQ(0, test_data
.m_ioctx
.write("foo_rmxattr", bl21
, sizeof(buf2
), 0));
1022 bl22
.append(attr2_buf
, sizeof(attr2_buf
));
1024 AioTestDataPP test_data4
;
1025 ASSERT_EQ("", test_data4
.init());
1026 boost::scoped_ptr
<AioCompletion
> my_completion4
1027 (test_data
.m_cluster
.aio_create_completion
1028 ((void*)&test_data4
, set_completion_completePP
, set_completion_safePP
));
1029 ASSERT_EQ(0, test_data
.m_ioctx
.aio_setxattr("foo_rmxattr", my_completion4
.get(), attr2
, bl22
));
1032 ASSERT_EQ(0, my_completion4
->wait_for_complete());
1034 ASSERT_EQ(0, my_completion4
->get_return_value());
1036 ASSERT_EQ(0, test_data
.m_ioctx
.remove("foo_rmxattr"));
1037 // async rmxattr on non existing object
1038 AioTestDataPP test_data5
;
1039 ASSERT_EQ("", test_data5
.init());
1040 boost::scoped_ptr
<AioCompletion
> my_completion5
1041 (test_data
.m_cluster
.aio_create_completion
1042 ((void*)&test_data5
, set_completion_completePP
, set_completion_safePP
));
1043 ASSERT_EQ(0, test_data
.m_ioctx
.aio_rmxattr("foo_rmxattr", my_completion5
.get(), attr2
));
1046 ASSERT_EQ(0, my_completion5
->wait_for_complete());
1048 ASSERT_EQ(-ENOENT
, my_completion5
->get_return_value());
1051 TEST(LibRadosAio
, XattrIter
) {
1052 AioTestData test_data
;
1053 ASSERT_EQ("", test_data
.init());
1054 // Create an object with 2 attributes
1056 char attr1
[] = "attr1";
1057 char attr1_buf
[] = "foo bar baz";
1058 char attr2
[] = "attr2";
1059 char attr2_buf
[256];
1060 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
1061 attr2_buf
[j
] = j
% 0xff;
1063 memset(buf
, 0xaa, sizeof(buf
));
1064 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
1065 ASSERT_EQ(0, rados_setxattr(test_data
.m_ioctx
, "foo", attr1
, attr1_buf
, sizeof(attr1_buf
)));
1066 ASSERT_EQ(0, rados_setxattr(test_data
.m_ioctx
, "foo", attr2
, attr2_buf
, sizeof(attr2_buf
)));
1067 // call async version of getxattrs and wait for completion
1068 rados_completion_t my_completion
;
1069 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1070 set_completion_complete
, set_completion_safe
, &my_completion
));
1071 rados_xattrs_iter_t iter
;
1072 ASSERT_EQ(0, rados_aio_getxattrs(test_data
.m_ioctx
, "foo", my_completion
, &iter
));
1075 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1077 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1078 // loop over attributes
1084 ASSERT_EQ(0, rados_getxattrs_next(iter
, &name
, &val
, &len
));
1088 ASSERT_LT(num_seen
, 2);
1089 if ((strcmp(name
, attr1
) == 0) && (val
!= NULL
) && (memcmp(val
, attr1_buf
, len
) == 0)) {
1093 else if ((strcmp(name
, attr2
) == 0) && (val
!= NULL
) && (memcmp(val
, attr2_buf
, len
) == 0)) {
1101 rados_getxattrs_end(iter
);
1104 TEST(LibRadosIoPP
, XattrListPP
) {
1105 AioTestDataPP test_data
;
1106 ASSERT_EQ("", test_data
.init());
1107 // create an object with 2 attributes
1109 char attr1
[] = "attr1";
1110 char attr1_buf
[] = "foo bar baz";
1111 char attr2
[] = "attr2";
1112 char attr2_buf
[256];
1113 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
1114 attr2_buf
[j
] = j
% 0xff;
1116 memset(buf
, 0xaa, sizeof(buf
));
1118 bl1
.append(buf
, sizeof(buf
));
1119 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
1121 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
1122 ASSERT_EQ(0, test_data
.m_ioctx
.setxattr("foo", attr1
, bl2
));
1124 bl3
.append(attr2_buf
, sizeof(attr2_buf
));
1125 ASSERT_EQ(0, test_data
.m_ioctx
.setxattr("foo", attr2
, bl3
));
1126 // call async version of getxattrs
1127 boost::scoped_ptr
<AioCompletion
> my_completion
1128 (test_data
.m_cluster
.aio_create_completion
1129 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
1130 std::map
<std::string
, bufferlist
> attrset
;
1131 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattrs("foo", my_completion
.get(), attrset
));
1134 ASSERT_EQ(0, my_completion
->wait_for_complete());
1136 ASSERT_EQ(0, my_completion
->get_return_value());
1137 for (std::map
<std::string
, bufferlist
>::iterator i
= attrset
.begin();
1138 i
!= attrset
.end(); ++i
) {
1139 if (i
->first
== string(attr1
)) {
1140 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
1142 else if (i
->first
== string(attr2
)) {
1143 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr2_buf
, sizeof(attr2_buf
)));
1151 TEST(LibRadosAio
, IsComplete
) {
1152 AioTestData test_data
;
1153 rados_completion_t my_completion
;
1154 ASSERT_EQ("", test_data
.init());
1155 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1156 set_completion_complete
, set_completion_safe
, &my_completion
));
1158 memset(buf
, 0xcc, sizeof(buf
));
1159 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1160 my_completion
, buf
, sizeof(buf
), 0));
1163 sem_wait(test_data
.m_sem
);
1164 sem_wait(test_data
.m_sem
);
1166 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1168 memset(buf2
, 0, sizeof(buf2
));
1169 rados_completion_t my_completion2
;
1170 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1171 set_completion_complete
, set_completion_safe
, &my_completion2
));
1172 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1173 my_completion2
, buf2
, sizeof(buf2
), 0));
1177 // Busy-wait until the AIO completes.
1178 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
1180 int is_complete
= rados_aio_is_complete(my_completion2
);
1185 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
1186 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1187 rados_aio_release(my_completion
);
1188 rados_aio_release(my_completion2
);
1191 TEST(LibRadosAio
, IsCompletePP
) {
1192 AioTestDataPP test_data
;
1193 ASSERT_EQ("", test_data
.init());
1194 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1195 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1196 AioCompletion
*my_completion_null
= NULL
;
1197 ASSERT_NE(my_completion
, my_completion_null
);
1199 memset(buf
, 0xcc, sizeof(buf
));
1201 bl1
.append(buf
, sizeof(buf
));
1202 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1203 bl1
, sizeof(buf
), 0));
1206 sem_wait(test_data
.m_sem
);
1207 sem_wait(test_data
.m_sem
);
1209 ASSERT_EQ(0, my_completion
->get_return_value());
1211 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1212 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1213 ASSERT_NE(my_completion2
, my_completion_null
);
1214 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1215 &bl2
, sizeof(buf
), 0));
1219 // Busy-wait until the AIO completes.
1220 // Normally we wouldn't do this, but we want to test is_complete.
1222 int is_complete
= my_completion2
->is_complete();
1227 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1228 ASSERT_EQ(sizeof(buf
), bl2
.length());
1229 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1230 delete my_completion
;
1231 delete my_completion2
;
1234 TEST(LibRadosAio
, IsSafe
) {
1235 AioTestData test_data
;
1236 rados_completion_t my_completion
;
1237 ASSERT_EQ("", test_data
.init());
1238 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1239 set_completion_complete
, set_completion_safe
, &my_completion
));
1241 memset(buf
, 0xcc, sizeof(buf
));
1242 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1243 my_completion
, buf
, sizeof(buf
), 0));
1247 // Busy-wait until the AIO completes.
1248 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1250 int is_safe
= rados_aio_is_safe(my_completion
);
1255 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1257 memset(buf2
, 0, sizeof(buf2
));
1258 rados_completion_t my_completion2
;
1259 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1260 set_completion_complete
, set_completion_safe
, &my_completion2
));
1261 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1262 my_completion2
, buf2
, sizeof(buf2
), 0));
1265 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1267 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
1268 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1269 rados_aio_release(my_completion
);
1270 rados_aio_release(my_completion2
);
1273 TEST(LibRadosAio
, IsSafePP
) {
1274 AioTestDataPP test_data
;
1275 ASSERT_EQ("", test_data
.init());
1276 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1277 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1278 AioCompletion
*my_completion_null
= NULL
;
1279 ASSERT_NE(my_completion
, my_completion_null
);
1281 memset(buf
, 0xcc, sizeof(buf
));
1283 bl1
.append(buf
, sizeof(buf
));
1284 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1285 bl1
, sizeof(buf
), 0));
1289 // Busy-wait until the AIO completes.
1290 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1292 int is_safe
= my_completion
->is_safe();
1297 ASSERT_EQ(0, my_completion
->get_return_value());
1298 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1299 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1301 ASSERT_NE(my_completion2
, my_completion_null
);
1302 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1303 &bl2
, sizeof(buf
), 0));
1306 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1308 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1309 ASSERT_EQ(sizeof(buf
), bl2
.length());
1310 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1311 delete my_completion
;
1312 delete my_completion2
;
1315 TEST(LibRadosAio
, ReturnValue
) {
1316 AioTestData test_data
;
1317 rados_completion_t my_completion
;
1318 ASSERT_EQ("", test_data
.init());
1319 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1320 set_completion_complete
, set_completion_safe
, &my_completion
));
1322 memset(buf
, 0, sizeof(buf
));
1323 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "nonexistent",
1324 my_completion
, buf
, sizeof(buf
), 0));
1327 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1329 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion
));
1330 rados_aio_release(my_completion
);
1333 TEST(LibRadosAio
, ReturnValuePP
) {
1334 AioTestDataPP test_data
;
1335 ASSERT_EQ("", test_data
.init());
1336 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1337 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1338 AioCompletion
*my_completion_null
= NULL
;
1339 ASSERT_NE(my_completion
, my_completion_null
);
1341 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("nonexistent",
1342 my_completion
, &bl1
, 128, 0));
1345 ASSERT_EQ(0, my_completion
->wait_for_complete());
1347 ASSERT_EQ(-ENOENT
, my_completion
->get_return_value());
1348 delete my_completion
;
1351 TEST(LibRadosAio
, Flush
) {
1352 AioTestData test_data
;
1353 rados_completion_t my_completion
;
1354 ASSERT_EQ("", test_data
.init());
1355 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1356 set_completion_complete
, set_completion_safe
, &my_completion
));
1358 memset(buf
, 0xee, sizeof(buf
));
1359 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1360 my_completion
, buf
, sizeof(buf
), 0));
1361 ASSERT_EQ(0, rados_aio_flush(test_data
.m_ioctx
));
1362 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1364 memset(buf2
, 0, sizeof(buf2
));
1365 rados_completion_t my_completion2
;
1366 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1367 set_completion_complete
, set_completion_safe
, &my_completion2
));
1368 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1369 my_completion2
, buf2
, sizeof(buf2
), 0));
1372 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1374 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
1375 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1376 rados_aio_release(my_completion
);
1377 rados_aio_release(my_completion2
);
1380 TEST(LibRadosAio
, FlushPP
) {
1381 AioTestDataPP test_data
;
1382 ASSERT_EQ("", test_data
.init());
1383 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1384 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1385 AioCompletion
*my_completion_null
= NULL
;
1386 ASSERT_NE(my_completion
, my_completion_null
);
1388 memset(buf
, 0xee, sizeof(buf
));
1390 bl1
.append(buf
, sizeof(buf
));
1391 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1392 bl1
, sizeof(buf
), 0));
1393 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush());
1394 ASSERT_EQ(0, my_completion
->get_return_value());
1396 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1397 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1398 ASSERT_NE(my_completion2
, my_completion_null
);
1399 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1400 &bl2
, sizeof(buf
), 0));
1403 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1405 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1406 ASSERT_EQ(sizeof(buf
), bl2
.length());
1407 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1408 delete my_completion
;
1409 delete my_completion2
;
1412 TEST(LibRadosAio
, FlushAsync
) {
1413 AioTestData test_data
;
1414 rados_completion_t my_completion
;
1415 ASSERT_EQ("", test_data
.init());
1416 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1417 set_completion_complete
, set_completion_safe
, &my_completion
));
1418 rados_completion_t flush_completion
;
1419 ASSERT_EQ(0, rados_aio_create_completion(NULL
, NULL
, NULL
, &flush_completion
));
1421 memset(buf
, 0xee, sizeof(buf
));
1422 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1423 my_completion
, buf
, sizeof(buf
), 0));
1424 ASSERT_EQ(0, rados_aio_flush_async(test_data
.m_ioctx
, flush_completion
));
1427 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion
));
1428 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion
));
1430 ASSERT_EQ(1, rados_aio_is_complete(my_completion
));
1431 ASSERT_EQ(1, rados_aio_is_safe(my_completion
));
1432 ASSERT_EQ(1, rados_aio_is_complete(flush_completion
));
1433 ASSERT_EQ(1, rados_aio_is_safe(flush_completion
));
1434 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1436 memset(buf2
, 0, sizeof(buf2
));
1437 rados_completion_t my_completion2
;
1438 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1439 set_completion_complete
, set_completion_safe
, &my_completion2
));
1440 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1441 my_completion2
, buf2
, sizeof(buf2
), 0));
1444 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1446 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
1447 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1448 rados_aio_release(my_completion
);
1449 rados_aio_release(my_completion2
);
1450 rados_aio_release(flush_completion
);
1453 TEST(LibRadosAio
, FlushAsyncPP
) {
1454 AioTestDataPP test_data
;
1455 ASSERT_EQ("", test_data
.init());
1456 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1457 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1458 AioCompletion
*flush_completion
=
1459 test_data
.m_cluster
.aio_create_completion(NULL
, NULL
, NULL
);
1460 AioCompletion
*my_completion_null
= NULL
;
1461 ASSERT_NE(my_completion
, my_completion_null
);
1463 memset(buf
, 0xee, sizeof(buf
));
1465 bl1
.append(buf
, sizeof(buf
));
1466 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1467 bl1
, sizeof(buf
), 0));
1468 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush_async(flush_completion
));
1471 ASSERT_EQ(0, flush_completion
->wait_for_complete());
1472 ASSERT_EQ(0, flush_completion
->wait_for_safe());
1474 ASSERT_EQ(1, my_completion
->is_complete());
1475 ASSERT_EQ(1, my_completion
->is_safe());
1476 ASSERT_EQ(1, flush_completion
->is_complete());
1477 ASSERT_EQ(1, flush_completion
->is_safe());
1478 ASSERT_EQ(0, my_completion
->get_return_value());
1480 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1481 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1482 ASSERT_NE(my_completion2
, my_completion_null
);
1483 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1484 &bl2
, sizeof(buf
), 0));
1487 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1489 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1490 ASSERT_EQ(sizeof(buf
), bl2
.length());
1491 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1492 delete my_completion
;
1493 delete my_completion2
;
1494 delete flush_completion
;
1497 TEST(LibRadosAio
, RoundTripWriteFull
) {
1498 AioTestData test_data
;
1499 rados_completion_t my_completion
, my_completion2
, my_completion3
;
1500 ASSERT_EQ("", test_data
.init());
1501 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1502 set_completion_complete
, set_completion_safe
, &my_completion
));
1504 memset(buf
, 0xcc, sizeof(buf
));
1505 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1506 my_completion
, buf
, sizeof(buf
), 0));
1509 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1511 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1513 memset(buf2
, 0xdd, sizeof(buf2
));
1514 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1515 set_completion_complete
, set_completion_safe
, &my_completion2
));
1516 ASSERT_EQ(0, rados_aio_write_full(test_data
.m_ioctx
, "foo",
1517 my_completion2
, buf2
, sizeof(buf2
)));
1520 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1522 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1523 char buf3
[sizeof(buf
) + sizeof(buf2
)];
1524 memset(buf3
, 0, sizeof(buf3
));
1525 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1526 set_completion_complete
, set_completion_safe
, &my_completion3
));
1527 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1528 my_completion3
, buf3
, sizeof(buf3
), 0));
1531 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1533 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion3
));
1534 ASSERT_EQ(0, memcmp(buf3
, buf2
, sizeof(buf2
)));
1535 rados_aio_release(my_completion
);
1536 rados_aio_release(my_completion2
);
1537 rados_aio_release(my_completion3
);
1540 TEST(LibRadosAio
, RoundTripWriteFullPP
) {
1541 AioTestDataPP test_data
;
1542 ASSERT_EQ("", test_data
.init());
1543 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1544 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1545 AioCompletion
*my_completion_null
= NULL
;
1546 ASSERT_NE(my_completion
, my_completion_null
);
1548 memset(buf
, 0xcc, sizeof(buf
));
1550 bl1
.append(buf
, sizeof(buf
));
1551 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1552 bl1
, sizeof(buf
), 0));
1555 ASSERT_EQ(0, my_completion
->wait_for_complete());
1557 ASSERT_EQ(0, my_completion
->get_return_value());
1559 memset(buf2
, 0xdd, sizeof(buf2
));
1561 bl2
.append(buf2
, sizeof(buf2
));
1562 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1563 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1564 ASSERT_NE(my_completion2
, my_completion_null
);
1565 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write_full("foo", my_completion2
, bl2
));
1568 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1570 ASSERT_EQ(0, my_completion2
->get_return_value());
1572 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
1573 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1574 ASSERT_NE(my_completion3
, my_completion_null
);
1575 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
1576 &bl3
, sizeof(buf
), 0));
1579 ASSERT_EQ(0, my_completion3
->wait_for_complete());
1581 ASSERT_EQ((int)sizeof(buf2
), my_completion3
->get_return_value());
1582 ASSERT_EQ(sizeof(buf2
), bl3
.length());
1583 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
1584 delete my_completion
;
1585 delete my_completion2
;
1586 delete my_completion3
;
1589 //using ObjectWriteOperation/ObjectReadOperation with iohint
1590 TEST(LibRadosAio
, RoundTripWriteFullPP2
)
1593 std::string pool_name
= get_temp_pool_name();
1594 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
1596 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
1598 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
1599 ObjectWriteOperation op
;
1601 memset(buf
, 0xcc, sizeof(buf
));
1606 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
1607 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
1610 ASSERT_EQ(0, my_completion1
->wait_for_complete());
1612 EXPECT_EQ(0, my_completion1
->get_return_value());
1614 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
1616 ObjectReadOperation op1
;
1617 op1
.read(0, sizeof(buf
), &bl
, NULL
);
1618 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
1619 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
1622 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1624 EXPECT_EQ(0, my_completion2
->get_return_value());
1625 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
1627 ioctx
.remove("test_obj");
1628 destroy_one_pool_pp(pool_name
, cluster
);
1631 TEST(LibRadosAio
, RoundTripWriteSame
) {
1632 AioTestData test_data
;
1633 rados_completion_t my_completion
, my_completion2
, my_completion3
;
1634 ASSERT_EQ("", test_data
.init());
1635 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1636 set_completion_complete
, set_completion_safe
, &my_completion
));
1638 memset(full
, 0xcc, sizeof(full
));
1639 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1640 my_completion
, full
, sizeof(full
), 0));
1643 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1645 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1646 /* write the same buf four times */
1648 size_t ws_write_len
= sizeof(full
);
1649 memset(buf
, 0xdd, sizeof(buf
));
1650 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1651 set_completion_complete
, set_completion_safe
, &my_completion2
));
1652 ASSERT_EQ(0, rados_aio_writesame(test_data
.m_ioctx
, "foo",
1653 my_completion2
, buf
, sizeof(buf
),
1657 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1659 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1660 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1661 set_completion_complete
, set_completion_safe
, &my_completion3
));
1662 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1663 my_completion3
, full
, sizeof(full
), 0));
1666 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1668 ASSERT_EQ((int)sizeof(full
), rados_aio_get_return_value(my_completion3
));
1669 for (char *cmp
= full
; cmp
< full
+ sizeof(full
); cmp
+= sizeof(buf
)) {
1670 ASSERT_EQ(0, memcmp(cmp
, buf
, sizeof(buf
)));
1672 rados_aio_release(my_completion
);
1673 rados_aio_release(my_completion2
);
1674 rados_aio_release(my_completion3
);
1677 TEST(LibRadosAio
, RoundTripWriteSamePP
) {
1678 AioTestDataPP test_data
;
1679 ASSERT_EQ("", test_data
.init());
1680 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1681 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1682 AioCompletion
*my_completion_null
= NULL
;
1683 ASSERT_NE(my_completion
, my_completion_null
);
1685 memset(full
, 0xcc, sizeof(full
));
1687 bl1
.append(full
, sizeof(full
));
1688 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1689 bl1
, sizeof(full
), 0));
1692 ASSERT_EQ(0, my_completion
->wait_for_complete());
1694 ASSERT_EQ(0, my_completion
->get_return_value());
1695 /* write the same buf four times */
1697 size_t ws_write_len
= sizeof(full
);
1698 memset(buf
, 0xdd, sizeof(buf
));
1700 bl2
.append(buf
, sizeof(buf
));
1701 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1702 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1703 ASSERT_NE(my_completion2
, my_completion_null
);
1704 ASSERT_EQ(0, test_data
.m_ioctx
.aio_writesame("foo", my_completion2
, bl2
,
1708 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1710 ASSERT_EQ(0, my_completion2
->get_return_value());
1712 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
1713 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1714 ASSERT_NE(my_completion3
, my_completion_null
);
1715 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
1716 &bl3
, sizeof(full
), 0));
1719 ASSERT_EQ(0, my_completion3
->wait_for_complete());
1721 ASSERT_EQ((int)sizeof(full
), my_completion3
->get_return_value());
1722 ASSERT_EQ(sizeof(full
), bl3
.length());
1723 for (char *cmp
= bl3
.c_str(); cmp
< bl3
.c_str() + bl3
.length();
1724 cmp
+= sizeof(buf
)) {
1725 ASSERT_EQ(0, memcmp(cmp
, buf
, sizeof(buf
)));
1727 delete my_completion
;
1728 delete my_completion2
;
1729 delete my_completion3
;
1732 TEST(LibRadosAio
, RoundTripWriteSamePP2
)
1735 std::string pool_name
= get_temp_pool_name();
1736 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
1738 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
1740 boost::scoped_ptr
<AioCompletion
>
1741 wr_cmpl(cluster
.aio_create_completion(0, 0, 0));
1742 ObjectWriteOperation op
;
1744 memset(buf
, 0xcc, sizeof(buf
));
1746 bl
.append(buf
, sizeof(buf
));
1748 op
.writesame(0, sizeof(buf
) * 4, bl
);
1749 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
1750 ioctx
.aio_operate("test_obj", wr_cmpl
.get(), &op
);
1753 ASSERT_EQ(0, wr_cmpl
->wait_for_complete());
1755 EXPECT_EQ(0, wr_cmpl
->get_return_value());
1757 boost::scoped_ptr
<AioCompletion
>
1758 rd_cmpl(cluster
.aio_create_completion(0, 0, 0));
1760 char full
[sizeof(buf
) * 4];
1761 memset(full
, 0, sizeof(full
));
1763 fl
.append(full
, sizeof(full
));
1764 ObjectReadOperation op1
;
1765 op1
.read(0, sizeof(full
), &fl
, NULL
);
1766 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
1767 ioctx
.aio_operate("test_obj", rd_cmpl
.get(), &op1
, 0);
1770 ASSERT_EQ(0, rd_cmpl
->wait_for_complete());
1772 EXPECT_EQ(0, rd_cmpl
->get_return_value());
1773 for (cmp
= fl
.c_str(); cmp
< fl
.c_str() + fl
.length(); cmp
+= sizeof(buf
)) {
1774 ASSERT_EQ(0, memcmp(cmp
, buf
, sizeof(buf
)));
1777 ioctx
.remove("test_obj");
1778 destroy_one_pool_pp(pool_name
, cluster
);
1781 TEST(LibRadosAio
, SimpleStat
) {
1782 AioTestData test_data
;
1783 rados_completion_t my_completion
;
1784 ASSERT_EQ("", test_data
.init());
1785 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1786 set_completion_complete
, set_completion_safe
, &my_completion
));
1788 memset(buf
, 0xcc, sizeof(buf
));
1789 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1790 my_completion
, buf
, sizeof(buf
), 0));
1793 sem_wait(test_data
.m_sem
);
1794 sem_wait(test_data
.m_sem
);
1796 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1799 rados_completion_t my_completion2
;
1800 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1801 set_completion_complete
, set_completion_safe
, &my_completion2
));
1802 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1803 my_completion2
, &psize
, &pmtime
));
1806 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1808 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1809 ASSERT_EQ(sizeof(buf
), psize
);
1810 rados_aio_release(my_completion
);
1811 rados_aio_release(my_completion2
);
1814 TEST(LibRadosAio
, SimpleStatPP
) {
1815 AioTestDataPP test_data
;
1816 ASSERT_EQ("", test_data
.init());
1817 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1818 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1819 AioCompletion
*my_completion_null
= NULL
;
1820 ASSERT_NE(my_completion
, my_completion_null
);
1822 memset(buf
, 0xcc, sizeof(buf
));
1824 bl1
.append(buf
, sizeof(buf
));
1825 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1826 bl1
, sizeof(buf
), 0));
1829 sem_wait(test_data
.m_sem
);
1830 sem_wait(test_data
.m_sem
);
1832 ASSERT_EQ(0, my_completion
->get_return_value());
1835 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1836 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1837 ASSERT_NE(my_completion2
, my_completion_null
);
1838 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
1842 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1844 ASSERT_EQ(0, my_completion2
->get_return_value());
1845 ASSERT_EQ(sizeof(buf
), psize
);
1846 delete my_completion
;
1847 delete my_completion2
;
1850 TEST(LibRadosAio
, SimpleStatNS
) {
1851 AioTestData test_data
;
1852 rados_completion_t my_completion
;
1853 ASSERT_EQ("", test_data
.init());
1854 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1855 set_completion_complete
, set_completion_safe
, &my_completion
));
1857 memset(buf
, 0xcc, sizeof(buf
));
1858 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1859 my_completion
, buf
, sizeof(buf
), 0));
1862 sem_wait(test_data
.m_sem
);
1863 sem_wait(test_data
.m_sem
);
1865 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1866 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
1868 memset(buf2
, 0xbb, sizeof(buf2
));
1869 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1870 set_completion_complete
, set_completion_safe
, &my_completion
));
1871 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1872 my_completion
, buf2
, sizeof(buf2
), 0));
1875 sem_wait(test_data
.m_sem
);
1876 sem_wait(test_data
.m_sem
);
1878 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1881 rados_completion_t my_completion2
;
1882 rados_ioctx_set_namespace(test_data
.m_ioctx
, "");
1883 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1884 set_completion_complete
, set_completion_safe
, &my_completion2
));
1885 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1886 my_completion2
, &psize
, &pmtime
));
1889 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1891 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1892 ASSERT_EQ(sizeof(buf
), psize
);
1894 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
1895 rados_completion_t my_completion3
;
1896 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1897 set_completion_complete
, set_completion_safe
, &my_completion3
));
1898 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1899 my_completion3
, &psize
, &pmtime
));
1902 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1904 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
1905 ASSERT_EQ(sizeof(buf2
), psize
);
1907 rados_aio_release(my_completion
);
1908 rados_aio_release(my_completion2
);
1909 rados_aio_release(my_completion3
);
1912 TEST(LibRadosAio
, SimpleStatPPNS
) {
1913 AioTestDataPP test_data
;
1914 ASSERT_EQ("", test_data
.init());
1915 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1916 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1917 AioCompletion
*my_completion_null
= NULL
;
1918 ASSERT_NE(my_completion
, my_completion_null
);
1920 memset(buf
, 0xcc, sizeof(buf
));
1922 bl1
.append(buf
, sizeof(buf
));
1923 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1924 bl1
, sizeof(buf
), 0));
1927 sem_wait(test_data
.m_sem
);
1928 sem_wait(test_data
.m_sem
);
1930 ASSERT_EQ(0, my_completion
->get_return_value());
1933 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1934 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1935 ASSERT_NE(my_completion2
, my_completion_null
);
1936 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
1940 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1942 ASSERT_EQ(0, my_completion2
->get_return_value());
1943 ASSERT_EQ(sizeof(buf
), psize
);
1944 delete my_completion
;
1945 delete my_completion2
;
1948 TEST(LibRadosAio
, StatRemove
) {
1949 AioTestData test_data
;
1950 rados_completion_t my_completion
;
1951 ASSERT_EQ("", test_data
.init());
1952 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1953 set_completion_complete
, set_completion_safe
, &my_completion
));
1955 memset(buf
, 0xcc, sizeof(buf
));
1956 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1957 my_completion
, buf
, sizeof(buf
), 0));
1960 sem_wait(test_data
.m_sem
);
1961 sem_wait(test_data
.m_sem
);
1963 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1966 rados_completion_t my_completion2
;
1967 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1968 set_completion_complete
, set_completion_safe
, &my_completion2
));
1969 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1970 my_completion2
, &psize
, &pmtime
));
1973 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1975 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1976 ASSERT_EQ(sizeof(buf
), psize
);
1977 rados_completion_t my_completion3
;
1978 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1979 set_completion_complete
, set_completion_safe
, &my_completion3
));
1980 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion3
));
1983 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1985 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
1988 rados_completion_t my_completion4
;
1989 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1990 set_completion_complete
, set_completion_safe
, &my_completion4
));
1991 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1992 my_completion4
, &psize2
, &pmtime2
));
1995 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
1997 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion4
));
1998 rados_aio_release(my_completion
);
1999 rados_aio_release(my_completion2
);
2000 rados_aio_release(my_completion3
);
2001 rados_aio_release(my_completion4
);
2004 TEST(LibRadosAio
, StatRemovePP
) {
2005 AioTestDataPP test_data
;
2006 ASSERT_EQ("", test_data
.init());
2007 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2008 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2009 AioCompletion
*my_completion_null
= NULL
;
2010 ASSERT_NE(my_completion
, my_completion_null
);
2012 memset(buf
, 0xcc, sizeof(buf
));
2014 bl1
.append(buf
, sizeof(buf
));
2015 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2016 bl1
, sizeof(buf
), 0));
2019 sem_wait(test_data
.m_sem
);
2020 sem_wait(test_data
.m_sem
);
2022 ASSERT_EQ(0, my_completion
->get_return_value());
2025 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2026 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2027 ASSERT_NE(my_completion2
, my_completion_null
);
2028 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
2032 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2034 ASSERT_EQ(0, my_completion2
->get_return_value());
2035 ASSERT_EQ(sizeof(buf
), psize
);
2038 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
2039 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2040 ASSERT_NE(my_completion3
, my_completion_null
);
2041 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion3
));
2044 ASSERT_EQ(0, my_completion3
->wait_for_complete());
2046 ASSERT_EQ(0, my_completion3
->get_return_value());
2048 AioCompletion
*my_completion4
= test_data
.m_cluster
.aio_create_completion(
2049 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2050 ASSERT_NE(my_completion4
, my_completion_null
);
2051 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion4
,
2052 &psize2
, &pmtime2
));
2055 ASSERT_EQ(0, my_completion4
->wait_for_complete());
2057 ASSERT_EQ(-ENOENT
, my_completion4
->get_return_value());
2058 delete my_completion
;
2059 delete my_completion2
;
2060 delete my_completion3
;
2061 delete my_completion4
;
2064 TEST(LibRadosAio
, ExecuteClass
) {
2065 AioTestData test_data
;
2066 rados_completion_t my_completion
;
2067 ASSERT_EQ("", test_data
.init());
2068 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2069 set_completion_complete
, set_completion_safe
, &my_completion
));
2071 memset(buf
, 0xcc, sizeof(buf
));
2072 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2073 my_completion
, buf
, sizeof(buf
), 0));
2076 sem_wait(test_data
.m_sem
);
2077 sem_wait(test_data
.m_sem
);
2079 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2080 rados_completion_t my_completion2
;
2081 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2082 set_completion_complete
, set_completion_safe
, &my_completion2
));
2084 ASSERT_EQ(0, rados_aio_exec(test_data
.m_ioctx
, "foo", my_completion2
,
2085 "hello", "say_hello", NULL
, 0, out
, sizeof(out
)));
2088 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2090 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2
));
2091 ASSERT_EQ(0, strncmp("Hello, world!", out
, 13));
2092 rados_aio_release(my_completion
);
2093 rados_aio_release(my_completion2
);
2096 TEST(LibRadosAio
, ExecuteClassPP
) {
2097 AioTestDataPP test_data
;
2098 ASSERT_EQ("", test_data
.init());
2099 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2100 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2101 AioCompletion
*my_completion_null
= NULL
;
2102 ASSERT_NE(my_completion
, my_completion_null
);
2104 memset(buf
, 0xcc, sizeof(buf
));
2106 bl1
.append(buf
, sizeof(buf
));
2107 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2108 bl1
, sizeof(buf
), 0));
2111 sem_wait(test_data
.m_sem
);
2112 sem_wait(test_data
.m_sem
);
2114 ASSERT_EQ(0, my_completion
->get_return_value());
2115 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2116 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2117 ASSERT_NE(my_completion2
, my_completion_null
);
2119 ASSERT_EQ(0, test_data
.m_ioctx
.aio_exec("foo", my_completion2
,
2120 "hello", "say_hello", in
, &out
));
2123 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2125 ASSERT_EQ(0, my_completion2
->get_return_value());
2126 ASSERT_EQ(std::string("Hello, world!"), std::string(out
.c_str(), out
.length()));
2127 delete my_completion
;
2128 delete my_completion2
;
2135 TEST(LibRadosAio
, OmapPP
) {
2137 std::string pool_name
= get_temp_pool_name();
2138 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
2140 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
2142 string header_str
= "baz";
2143 bufferptr
bp(header_str
.c_str(), header_str
.size() + 1);
2144 bufferlist header_to_set
;
2145 header_to_set
.push_back(bp
);
2146 map
<string
, bufferlist
> to_set
;
2148 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2149 ObjectWriteOperation op
;
2150 to_set
["foo"] = header_to_set
;
2151 to_set
["foo2"] = header_to_set
;
2152 to_set
["qfoo3"] = header_to_set
;
2153 op
.omap_set(to_set
);
2155 op
.omap_set_header(header_to_set
);
2157 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
2160 ASSERT_EQ(0, my_completion
->wait_for_complete());
2162 EXPECT_EQ(0, my_completion
->get_return_value());
2166 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2167 ObjectReadOperation op
;
2168 map
<string
, pair
<bufferlist
, int> > assertions
;
2170 val
.append(string("bar"));
2171 assertions
["foo"] = pair
<bufferlist
, int>(val
, CEPH_OSD_CMPXATTR_OP_EQ
);
2174 op
.omap_cmp(assertions
, &r
);
2176 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2179 ASSERT_EQ(0, my_completion
->wait_for_complete());
2181 EXPECT_EQ(-ECANCELED
, my_completion
->get_return_value());
2182 ASSERT_EQ(-ECANCELED
, r
);
2186 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2187 ObjectReadOperation op
;
2189 set
<string
> set_got
;
2190 map
<string
, bufferlist
> map_got
;
2193 map
<string
, bufferlist
> got3
;
2195 map
<string
, bufferlist
> got4
;
2199 op
.omap_get_keys2("", 1, &set_got
, nullptr, 0);
2200 op
.omap_get_vals2("foo", 1, &map_got
, nullptr, 0);
2202 to_get
.insert("foo");
2203 to_get
.insert("qfoo3");
2204 op
.omap_get_vals_by_keys(to_get
, &got3
, 0);
2206 op
.omap_get_header(&header
, 0);
2208 op
.omap_get_vals2("foo2", "q", 1, &got4
, nullptr, 0);
2210 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2213 ASSERT_EQ(0, my_completion
->wait_for_complete());
2215 EXPECT_EQ(0, my_completion
->get_return_value());
2217 ASSERT_EQ(header
.length(), header_to_set
.length());
2218 ASSERT_EQ(set_got
.size(), (unsigned)1);
2219 ASSERT_EQ(*set_got
.begin(), "foo");
2220 ASSERT_EQ(map_got
.size(), (unsigned)1);
2221 ASSERT_EQ(map_got
.begin()->first
, "foo2");
2222 ASSERT_EQ(got3
.size(), (unsigned)2);
2223 ASSERT_EQ(got3
.begin()->first
, "foo");
2224 ASSERT_EQ(got3
.rbegin()->first
, "qfoo3");
2225 ASSERT_EQ(got4
.size(), (unsigned)1);
2226 ASSERT_EQ(got4
.begin()->first
, "qfoo3");
2230 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2231 ObjectWriteOperation op
;
2232 set
<string
> to_remove
;
2233 to_remove
.insert("foo2");
2234 op
.omap_rm_keys(to_remove
);
2235 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
2238 ASSERT_EQ(0, my_completion
->wait_for_complete());
2240 EXPECT_EQ(0, my_completion
->get_return_value());
2244 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2245 ObjectReadOperation op
;
2247 set
<string
> set_got
;
2248 op
.omap_get_keys2("", -1, &set_got
, nullptr, 0);
2249 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2252 ASSERT_EQ(0, my_completion
->wait_for_complete());
2254 EXPECT_EQ(0, my_completion
->get_return_value());
2255 ASSERT_EQ(set_got
.size(), (unsigned)2);
2259 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2260 ObjectWriteOperation op
;
2262 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
2265 ASSERT_EQ(0, my_completion
->wait_for_complete());
2267 EXPECT_EQ(0, my_completion
->get_return_value());
2271 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2272 ObjectReadOperation op
;
2274 set
<string
> set_got
;
2275 op
.omap_get_keys2("", -1, &set_got
, nullptr, 0);
2276 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2279 ASSERT_EQ(0, my_completion
->wait_for_complete());
2281 EXPECT_EQ(0, my_completion
->get_return_value());
2282 ASSERT_EQ(set_got
.size(), (unsigned)0);
2285 // omap_clear clears header *and* keys
2287 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2288 ObjectWriteOperation op
;
2290 bl
.append("some data");
2291 map
<string
,bufferlist
> to_set
;
2293 to_set
["foo2"] = bl
;
2294 to_set
["qfoo3"] = bl
;
2295 op
.omap_set(to_set
);
2296 op
.omap_set_header(bl
);
2297 ioctx
.aio_operate("foo3", my_completion
.get(), &op
);
2300 ASSERT_EQ(0, my_completion
->wait_for_complete());
2302 EXPECT_EQ(0, my_completion
->get_return_value());
2305 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2306 ObjectWriteOperation op
;
2308 ioctx
.aio_operate("foo3", my_completion
.get(), &op
);
2311 ASSERT_EQ(0, my_completion
->wait_for_complete());
2313 EXPECT_EQ(0, my_completion
->get_return_value());
2316 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2317 ObjectReadOperation op
;
2318 set
<string
> set_got
;
2320 op
.omap_get_keys2("", -1, &set_got
, nullptr, 0);
2321 op
.omap_get_header(&hdr
, NULL
);
2322 ioctx
.aio_operate("foo3", my_completion
.get(), &op
, 0);
2325 ASSERT_EQ(0, my_completion
->wait_for_complete());
2327 EXPECT_EQ(0, my_completion
->get_return_value());
2328 ASSERT_EQ(set_got
.size(), (unsigned)0);
2329 ASSERT_EQ(hdr
.length(), 0u);
2332 ioctx
.remove("test_obj");
2333 destroy_one_pool_pp(pool_name
, cluster
);
2336 TEST(LibRadosAio
, MultiWrite
) {
2337 AioTestData test_data
;
2338 rados_completion_t my_completion
, my_completion2
, my_completion3
;
2339 ASSERT_EQ("", test_data
.init());
2340 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2341 set_completion_complete
, set_completion_safe
, &my_completion
));
2343 memset(buf
, 0xcc, sizeof(buf
));
2344 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2345 my_completion
, buf
, sizeof(buf
), 0));
2348 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
2350 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2353 memset(buf2
, 0xdd, sizeof(buf2
));
2354 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2355 set_completion_complete
, set_completion_safe
, &my_completion2
));
2356 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2357 my_completion2
, buf2
, sizeof(buf2
), sizeof(buf
)));
2360 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2362 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
2364 char buf3
[(sizeof(buf
) + sizeof(buf2
)) * 3];
2365 memset(buf3
, 0, sizeof(buf3
));
2366 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2367 set_completion_complete
, set_completion_safe
, &my_completion3
));
2368 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2369 my_completion3
, buf3
, sizeof(buf3
), 0));
2372 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
2374 ASSERT_EQ((int)(sizeof(buf
) + sizeof(buf2
)), rados_aio_get_return_value(my_completion3
));
2375 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
2376 ASSERT_EQ(0, memcmp(buf3
+ sizeof(buf
), buf2
, sizeof(buf2
)));
2377 rados_aio_release(my_completion
);
2378 rados_aio_release(my_completion2
);
2379 rados_aio_release(my_completion3
);
2382 TEST(LibRadosAio
, MultiWritePP
) {
2383 AioTestDataPP test_data
;
2384 ASSERT_EQ("", test_data
.init());
2385 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2386 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2387 AioCompletion
*my_completion_null
= NULL
;
2388 ASSERT_NE(my_completion
, my_completion_null
);
2390 memset(buf
, 0xcc, sizeof(buf
));
2392 bl1
.append(buf
, sizeof(buf
));
2393 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2394 bl1
, sizeof(buf
), 0));
2397 ASSERT_EQ(0, my_completion
->wait_for_complete());
2399 ASSERT_EQ(0, my_completion
->get_return_value());
2402 memset(buf2
, 0xdd, sizeof(buf2
));
2404 bl2
.append(buf2
, sizeof(buf2
));
2405 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2406 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2407 ASSERT_NE(my_completion2
, my_completion_null
);
2408 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion2
,
2409 bl2
, sizeof(buf2
), sizeof(buf
)));
2412 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2414 ASSERT_EQ(0, my_completion2
->get_return_value());
2417 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
2418 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2419 ASSERT_NE(my_completion3
, my_completion_null
);
2420 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
2421 &bl3
, (sizeof(buf
) + sizeof(buf2
) * 3), 0));
2424 ASSERT_EQ(0, my_completion3
->wait_for_complete());
2426 ASSERT_EQ((int)(sizeof(buf
) + sizeof(buf2
)), my_completion3
->get_return_value());
2427 ASSERT_EQ(sizeof(buf
) + sizeof(buf2
), bl3
.length());
2428 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, sizeof(buf
)));
2429 ASSERT_EQ(0, memcmp(bl3
.c_str() + sizeof(buf
), buf2
, sizeof(buf2
)));
2430 delete my_completion
;
2431 delete my_completion2
;
2432 delete my_completion3
;
2435 TEST(LibRadosAio
, AioUnlock
) {
2436 AioTestData test_data
;
2437 ASSERT_EQ("", test_data
.init());
2438 ASSERT_EQ(0, rados_lock_exclusive(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", "", NULL
, 0));
2439 rados_completion_t my_completion
;
2440 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2441 set_completion_complete
, set_completion_safe
, &my_completion
));
2442 ASSERT_EQ(0, rados_aio_unlock(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", my_completion
));
2445 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
2447 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2448 ASSERT_EQ(0, rados_lock_exclusive(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", "", NULL
, 0));
2451 TEST(LibRadosAio
, AioUnlockPP
) {
2452 AioTestDataPP test_data
;
2453 ASSERT_EQ("", test_data
.init());
2454 ASSERT_EQ(0, test_data
.m_ioctx
.lock_exclusive("foo", "TestLock", "Cookie", "", NULL
, 0));
2455 boost::scoped_ptr
<AioCompletion
> my_completion
2456 (test_data
.m_cluster
.aio_create_completion
2457 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
2458 ASSERT_EQ(0, test_data
.m_ioctx
.aio_unlock("foo", "TestLock", "Cookie", my_completion
.get()));
2461 ASSERT_EQ(0, my_completion
->wait_for_complete());
2463 ASSERT_EQ(0, my_completion
->get_return_value());
2465 ASSERT_EQ(0, test_data
.m_ioctx
.lock_exclusive("foo", "TestLock", "Cookie", "", NULL
, 0));
2484 rados_ioctx_destroy(m_ioctx
);
2485 destroy_one_ec_pool(m_pool_name
, &m_cluster
);
2493 if (SEM_FAILED
== (m_sem
= sem_open("/test_aio_sem", O_CREAT
, 0644, 0))) {
2496 oss
<< "sem_open failed: " << cpp_strerror(err
);
2499 m_pool_name
= get_temp_pool_name();
2500 std::string err
= create_one_ec_pool(m_pool_name
, &m_cluster
);
2504 oss
<< "create_one_ec_pool(" << m_pool_name
<< ") failed: error " << err
;
2507 ret
= rados_ioctx_create(m_cluster
, m_pool_name
.c_str(), &m_ioctx
);
2510 destroy_one_ec_pool(m_pool_name
, &m_cluster
);
2512 oss
<< "rados_ioctx_create failed: error " << ret
;
2521 rados_ioctx_t m_ioctx
;
2522 std::string m_pool_name
;
2528 class AioTestDataECPP
2542 destroy_one_ec_pool_pp(m_pool_name
, m_cluster
);
2550 if (SEM_FAILED
== (m_sem
= sem_open("/test_aio_sem", O_CREAT
, 0644, 0))) {
2553 oss
<< "sem_open failed: " << cpp_strerror(err
);
2556 m_pool_name
= get_temp_pool_name();
2557 std::string err
= create_one_ec_pool_pp(m_pool_name
, m_cluster
);
2561 oss
<< "create_one_ec_pool(" << m_pool_name
<< ") failed: error " << err
;
2564 ret
= m_cluster
.ioctx_create(m_pool_name
.c_str(), m_ioctx
);
2567 destroy_one_ec_pool_pp(m_pool_name
, m_cluster
);
2569 oss
<< "rados_ioctx_create failed: error " << ret
;
2576 sem_t
*m_sem
= nullptr;
2579 std::string m_pool_name
;
2585 void set_completion_completeEC(rados_completion_t cb
, void *arg
)
2587 AioTestDataEC
*test
= static_cast<AioTestDataEC
*>(arg
);
2588 test
->m_complete
= true;
2589 sem_post(test
->m_sem
);
2592 void set_completion_safeEC(rados_completion_t cb
, void *arg
)
2594 AioTestDataEC
*test
= static_cast<AioTestDataEC
*>(arg
);
2595 test
->m_safe
= true;
2596 sem_post(test
->m_sem
);
2599 void set_completion_completeECPP(rados_completion_t cb
, void *arg
)
2601 AioTestDataECPP
*test
= static_cast<AioTestDataECPP
*>(arg
);
2602 test
->m_complete
= true;
2603 sem_post(test
->m_sem
);
2606 void set_completion_safeECPP(rados_completion_t cb
, void *arg
)
2608 AioTestDataECPP
*test
= static_cast<AioTestDataECPP
*>(arg
);
2609 test
->m_safe
= true;
2610 sem_post(test
->m_sem
);
2613 TEST(LibRadosAioEC
, SimpleWrite
) {
2614 AioTestDataEC test_data
;
2615 rados_completion_t my_completion
;
2616 ASSERT_EQ("", test_data
.init());
2617 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2618 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2620 memset(buf
, 0xcc, sizeof(buf
));
2621 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2622 my_completion
, buf
, sizeof(buf
), 0));
2625 sem_wait(test_data
.m_sem
);
2626 sem_wait(test_data
.m_sem
);
2628 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2630 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
2631 rados_completion_t my_completion2
;
2632 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2633 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2634 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2635 my_completion2
, buf
, sizeof(buf
), 0));
2638 sem_wait(test_data
.m_sem
);
2639 sem_wait(test_data
.m_sem
);
2641 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
2642 rados_aio_release(my_completion
);
2643 rados_aio_release(my_completion2
);
2646 TEST(LibRadosAioEC
, SimpleWritePP
) {
2648 memset(buf
, 0xcc, sizeof(buf
));
2650 bl1
.append(buf
, sizeof(buf
));
2652 AioTestDataECPP test_data
;
2653 ASSERT_EQ("", test_data
.init());
2654 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2655 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2656 AioCompletion
*my_completion_null
= NULL
;
2657 ASSERT_NE(my_completion
, my_completion_null
);
2658 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
2659 my_completion
, bl1
, sizeof(buf
), 0));
2662 sem_wait(test_data
.m_sem
);
2663 sem_wait(test_data
.m_sem
);
2665 ASSERT_EQ(0, my_completion
->get_return_value());
2666 delete my_completion
;
2670 AioTestDataECPP test_data
;
2671 ASSERT_EQ("", test_data
.init());
2672 test_data
.m_ioctx
.set_namespace("nspace");
2673 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2674 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2675 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
2676 my_completion
, bl1
, sizeof(buf
), 0));
2679 sem_wait(test_data
.m_sem
);
2680 sem_wait(test_data
.m_sem
);
2682 ASSERT_EQ(0, my_completion
->get_return_value());
2683 delete my_completion
;
2687 TEST(LibRadosAioEC
, WaitForSafe
) {
2688 AioTestDataEC test_data
;
2689 rados_completion_t my_completion
;
2690 ASSERT_EQ("", test_data
.init());
2691 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2692 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2694 memset(buf
, 0xcc, sizeof(buf
));
2695 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2696 my_completion
, buf
, sizeof(buf
), 0));
2698 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion
));
2699 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2700 rados_aio_release(my_completion
);
2703 TEST(LibRadosAioEC
, WaitForSafePP
) {
2704 AioTestDataECPP test_data
;
2705 ASSERT_EQ("", test_data
.init());
2706 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2707 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2708 AioCompletion
*my_completion_null
= NULL
;
2709 ASSERT_NE(my_completion
, my_completion_null
);
2711 memset(buf
, 0xcc, sizeof(buf
));
2713 bl1
.append(buf
, sizeof(buf
));
2714 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
2715 my_completion
, bl1
, sizeof(buf
), 0));
2717 ASSERT_EQ(0, my_completion
->wait_for_safe());
2718 ASSERT_EQ(0, my_completion
->get_return_value());
2719 delete my_completion
;
2722 TEST(LibRadosAioEC
, RoundTrip
) {
2723 AioTestDataEC test_data
;
2724 rados_completion_t my_completion
;
2725 ASSERT_EQ("", test_data
.init());
2726 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2727 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2729 memset(buf
, 0xcc, sizeof(buf
));
2730 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2731 my_completion
, buf
, sizeof(buf
), 0));
2734 sem_wait(test_data
.m_sem
);
2735 sem_wait(test_data
.m_sem
);
2737 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2739 memset(buf2
, 0, sizeof(buf2
));
2740 rados_completion_t my_completion2
;
2741 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2742 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2743 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2744 my_completion2
, buf2
, sizeof(buf2
), 0));
2747 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2749 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
2750 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
2751 rados_aio_release(my_completion
);
2752 rados_aio_release(my_completion2
);
2755 TEST(LibRadosAioEC
, RoundTrip2
) {
2756 AioTestDataEC test_data
;
2757 rados_completion_t my_completion
;
2758 ASSERT_EQ("", test_data
.init());
2759 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2760 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2762 memset(buf
, 0xcc, sizeof(buf
));
2763 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2764 my_completion
, buf
, sizeof(buf
), 0));
2767 sem_wait(test_data
.m_sem
);
2768 sem_wait(test_data
.m_sem
);
2770 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2772 memset(buf2
, 0, sizeof(buf2
));
2773 rados_completion_t my_completion2
;
2774 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2775 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2776 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2777 my_completion2
, buf2
, sizeof(buf2
), 0));
2780 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2782 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
2783 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
2784 rados_aio_release(my_completion
);
2785 rados_aio_release(my_completion2
);
2788 TEST(LibRadosAioEC
, RoundTripPP
) {
2789 AioTestDataECPP test_data
;
2790 ASSERT_EQ("", test_data
.init());
2791 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2792 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2793 AioCompletion
*my_completion_null
= NULL
;
2794 ASSERT_NE(my_completion
, my_completion_null
);
2796 memset(buf
, 0xcc, sizeof(buf
));
2798 bl1
.append(buf
, sizeof(buf
));
2799 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2800 bl1
, sizeof(buf
), 0));
2803 sem_wait(test_data
.m_sem
);
2804 sem_wait(test_data
.m_sem
);
2806 ASSERT_EQ(0, my_completion
->get_return_value());
2808 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2809 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2810 ASSERT_NE(my_completion2
, my_completion_null
);
2811 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
2812 my_completion2
, &bl2
, sizeof(buf
), 0));
2815 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2817 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
2818 ASSERT_EQ(sizeof(buf
), bl2
.length());
2819 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
2820 delete my_completion
;
2821 delete my_completion2
;
2824 TEST(LibRadosAioEC
, RoundTripPP2
) {
2825 AioTestDataECPP test_data
;
2826 ASSERT_EQ("", test_data
.init());
2827 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2828 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2829 AioCompletion
*my_completion_null
= NULL
;
2830 ASSERT_NE(my_completion
, my_completion_null
);
2832 memset(buf
, 0xcc, sizeof(buf
));
2834 bl1
.append(buf
, sizeof(buf
));
2835 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2836 bl1
, sizeof(buf
), 0));
2839 sem_wait(test_data
.m_sem
);
2840 sem_wait(test_data
.m_sem
);
2842 ASSERT_EQ(0, my_completion
->get_return_value());
2844 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2845 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2846 ASSERT_NE(my_completion2
, my_completion_null
);
2847 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
2848 my_completion2
, &bl2
, sizeof(buf
), 0));
2851 ASSERT_EQ(0, my_completion2
->wait_for_safe());
2852 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2854 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
2855 ASSERT_EQ(sizeof(buf
), bl2
.length());
2856 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
2857 delete my_completion
;
2858 delete my_completion2
;
2861 //using ObjectWriteOperation/ObjectReadOperation with iohint
2862 TEST(LibRadosAioEC
, RoundTripPP3
)
2865 std::string pool_name
= get_temp_pool_name();
2866 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
2868 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
2870 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
2871 ObjectWriteOperation op
;
2873 memset(buf
, 0xcc, sizeof(buf
));
2878 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
2879 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
2882 ASSERT_EQ(0, my_completion1
->wait_for_complete());
2884 EXPECT_EQ(0, my_completion1
->get_return_value());
2886 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
2888 ObjectReadOperation op1
;
2889 op1
.read(0, sizeof(buf
), &bl
, NULL
);
2890 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
2891 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
2894 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2896 EXPECT_EQ(0, my_completion2
->get_return_value());
2897 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
2899 ioctx
.remove("test_obj");
2900 destroy_one_pool_pp(pool_name
, cluster
);
2903 TEST(LibRadosAioEC
, RoundTripSparseReadPP
) {
2904 AioTestDataECPP test_data
;
2905 ASSERT_EQ("", test_data
.init());
2906 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2907 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2908 AioCompletion
*my_completion_null
= NULL
;
2909 ASSERT_NE(my_completion
, my_completion_null
);
2911 memset(buf
, 0xcc, sizeof(buf
));
2913 bl1
.append(buf
, sizeof(buf
));
2914 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2915 bl1
, sizeof(buf
), 0));
2918 sem_wait(test_data
.m_sem
);
2919 sem_wait(test_data
.m_sem
);
2921 ASSERT_EQ(0, my_completion
->get_return_value());
2923 map
<uint64_t, uint64_t> extents
;
2925 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2926 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2927 ASSERT_NE(my_completion2
, my_completion_null
);
2928 ASSERT_EQ(0, test_data
.m_ioctx
.aio_sparse_read("foo",
2929 my_completion2
, &extents
, &bl2
, sizeof(buf
), 0));
2932 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2934 ASSERT_EQ(0, my_completion2
->get_return_value());
2935 assert_eq_sparse(bl1
, extents
, bl2
);
2936 delete my_completion
;
2937 delete my_completion2
;
2940 TEST(LibRadosAioEC
, RoundTripAppend
) {
2941 AioTestDataEC test_data
;
2942 rados_completion_t my_completion
, my_completion2
, my_completion3
, my_completion4
;
2943 ASSERT_EQ("", test_data
.init());
2944 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2945 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2947 ASSERT_EQ(0, rados_ioctx_pool_requires_alignment2(test_data
.m_ioctx
, &requires
));
2948 ASSERT_NE(0, requires
);
2950 ASSERT_EQ(0, rados_ioctx_pool_required_alignment2(test_data
.m_ioctx
, &alignment
));
2951 ASSERT_NE(0U, alignment
);
2953 int bsize
= alignment
;
2954 char *buf
= (char *)new char[bsize
];
2955 memset(buf
, 0xcc, bsize
);
2956 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
2957 my_completion
, buf
, bsize
));
2960 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
2962 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2964 int hbsize
= bsize
/ 2;
2965 char *buf2
= (char *)new char[hbsize
];
2966 memset(buf2
, 0xdd, hbsize
);
2967 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2968 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2969 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
2970 my_completion2
, buf2
, hbsize
));
2973 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2975 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
2977 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2978 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
2979 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
2980 my_completion3
, buf2
, hbsize
));
2983 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
2985 EXPECT_EQ(-EOPNOTSUPP
, rados_aio_get_return_value(my_completion3
));
2987 int tbsize
= bsize
+ hbsize
;
2988 char *buf3
= (char *)new char[tbsize
];
2989 memset(buf3
, 0, tbsize
);
2990 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2991 set_completion_completeEC
, set_completion_safeEC
, &my_completion4
));
2992 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2993 my_completion4
, buf3
, bsize
* 3, 0));
2996 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
2998 ASSERT_EQ(tbsize
, rados_aio_get_return_value(my_completion4
));
2999 ASSERT_EQ(0, memcmp(buf3
, buf
, bsize
));
3000 ASSERT_EQ(0, memcmp(buf3
+ bsize
, buf2
, hbsize
));
3001 rados_aio_release(my_completion
);
3002 rados_aio_release(my_completion2
);
3003 rados_aio_release(my_completion3
);
3004 rados_aio_release(my_completion4
);
3010 TEST(LibRadosAioEC
, RoundTripAppendPP
) {
3011 AioTestDataECPP test_data
;
3012 ASSERT_EQ("", test_data
.init());
3013 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3014 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3015 AioCompletion
*my_completion_null
= NULL
;
3016 ASSERT_NE(my_completion
, my_completion_null
);
3018 ASSERT_EQ(0, test_data
.m_ioctx
.pool_requires_alignment2(&requires
));
3019 ASSERT_TRUE(requires
);
3021 ASSERT_EQ(0, test_data
.m_ioctx
.pool_required_alignment2(&alignment
));
3022 ASSERT_NE((unsigned)0, alignment
);
3023 int bsize
= alignment
;
3024 char *buf
= (char *)new char[bsize
];
3025 memset(buf
, 0xcc, bsize
);
3027 bl1
.append(buf
, bsize
);
3028 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion
,
3032 ASSERT_EQ(0, my_completion
->wait_for_complete());
3034 ASSERT_EQ(0, my_completion
->get_return_value());
3036 int hbsize
= bsize
/ 2;
3037 char *buf2
= (char *)new char[hbsize
];
3038 memset(buf2
, 0xdd, hbsize
);
3040 bl2
.append(buf2
, hbsize
);
3041 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3042 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3043 ASSERT_NE(my_completion2
, my_completion_null
);
3044 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion2
,
3048 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3050 ASSERT_EQ(0, my_completion2
->get_return_value());
3052 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
3053 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3054 ASSERT_NE(my_completion3
, my_completion_null
);
3055 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion3
,
3059 ASSERT_EQ(0, my_completion3
->wait_for_complete());
3061 EXPECT_EQ(-EOPNOTSUPP
, my_completion3
->get_return_value());
3064 AioCompletion
*my_completion4
= test_data
.m_cluster
.aio_create_completion(
3065 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3066 ASSERT_NE(my_completion4
, my_completion_null
);
3067 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
3068 my_completion4
, &bl3
, bsize
* 3, 0));
3071 ASSERT_EQ(0, my_completion4
->wait_for_complete());
3073 int tbsize
= bsize
+ hbsize
;
3074 ASSERT_EQ(tbsize
, my_completion4
->get_return_value());
3075 ASSERT_EQ((unsigned)tbsize
, bl3
.length());
3076 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, bsize
));
3077 ASSERT_EQ(0, memcmp(bl3
.c_str() + bsize
, buf2
, hbsize
));
3078 delete my_completion
;
3079 delete my_completion2
;
3080 delete my_completion3
;
3085 TEST(LibRadosAioEC
, IsComplete
) {
3086 AioTestDataEC test_data
;
3087 rados_completion_t my_completion
;
3088 ASSERT_EQ("", test_data
.init());
3089 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3090 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3092 memset(buf
, 0xcc, sizeof(buf
));
3093 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3094 my_completion
, buf
, sizeof(buf
), 0));
3097 sem_wait(test_data
.m_sem
);
3098 sem_wait(test_data
.m_sem
);
3100 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3102 memset(buf2
, 0, sizeof(buf2
));
3103 rados_completion_t my_completion2
;
3104 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3105 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3106 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3107 my_completion2
, buf2
, sizeof(buf2
), 0));
3111 // Busy-wait until the AIO completes.
3112 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
3114 int is_complete
= rados_aio_is_complete(my_completion2
);
3119 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
3120 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3121 rados_aio_release(my_completion
);
3122 rados_aio_release(my_completion2
);
3125 TEST(LibRadosAioEC
, IsCompletePP
) {
3126 AioTestDataECPP test_data
;
3127 ASSERT_EQ("", test_data
.init());
3128 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3129 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3130 AioCompletion
*my_completion_null
= NULL
;
3131 ASSERT_NE(my_completion
, my_completion_null
);
3133 memset(buf
, 0xcc, sizeof(buf
));
3135 bl1
.append(buf
, sizeof(buf
));
3136 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3137 bl1
, sizeof(buf
), 0));
3140 sem_wait(test_data
.m_sem
);
3141 sem_wait(test_data
.m_sem
);
3143 ASSERT_EQ(0, my_completion
->get_return_value());
3145 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3146 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3147 ASSERT_NE(my_completion2
, my_completion_null
);
3148 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3149 &bl2
, sizeof(buf
), 0));
3153 // Busy-wait until the AIO completes.
3154 // Normally we wouldn't do this, but we want to test is_complete.
3156 int is_complete
= my_completion2
->is_complete();
3161 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3162 ASSERT_EQ(sizeof(buf
), bl2
.length());
3163 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3164 delete my_completion
;
3165 delete my_completion2
;
3168 TEST(LibRadosAioEC
, IsSafe
) {
3169 AioTestDataEC test_data
;
3170 rados_completion_t my_completion
;
3171 ASSERT_EQ("", test_data
.init());
3172 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3173 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3175 memset(buf
, 0xcc, sizeof(buf
));
3176 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3177 my_completion
, buf
, sizeof(buf
), 0));
3181 // Busy-wait until the AIO completes.
3182 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
3184 int is_safe
= rados_aio_is_safe(my_completion
);
3189 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3191 memset(buf2
, 0, sizeof(buf2
));
3192 rados_completion_t my_completion2
;
3193 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3194 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3195 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3196 my_completion2
, buf2
, sizeof(buf2
), 0));
3199 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3201 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
3202 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3203 rados_aio_release(my_completion
);
3204 rados_aio_release(my_completion2
);
3207 TEST(LibRadosAioEC
, IsSafePP
) {
3208 AioTestDataECPP test_data
;
3209 ASSERT_EQ("", test_data
.init());
3210 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3211 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3212 AioCompletion
*my_completion_null
= NULL
;
3213 ASSERT_NE(my_completion
, my_completion_null
);
3215 memset(buf
, 0xcc, sizeof(buf
));
3217 bl1
.append(buf
, sizeof(buf
));
3218 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3219 bl1
, sizeof(buf
), 0));
3223 // Busy-wait until the AIO completes.
3224 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
3226 int is_safe
= my_completion
->is_safe();
3231 ASSERT_EQ(0, my_completion
->get_return_value());
3232 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3233 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3235 ASSERT_NE(my_completion2
, my_completion_null
);
3236 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3237 &bl2
, sizeof(buf
), 0));
3240 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3242 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3243 ASSERT_EQ(sizeof(buf
), bl2
.length());
3244 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3245 delete my_completion
;
3246 delete my_completion2
;
3249 TEST(LibRadosAioEC
, ReturnValue
) {
3250 AioTestDataEC test_data
;
3251 rados_completion_t my_completion
;
3252 ASSERT_EQ("", test_data
.init());
3253 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3254 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3256 memset(buf
, 0, sizeof(buf
));
3257 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "nonexistent",
3258 my_completion
, buf
, sizeof(buf
), 0));
3261 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
3263 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion
));
3264 rados_aio_release(my_completion
);
3267 TEST(LibRadosAioEC
, ReturnValuePP
) {
3268 AioTestDataECPP test_data
;
3269 ASSERT_EQ("", test_data
.init());
3270 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3271 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3272 AioCompletion
*my_completion_null
= NULL
;
3273 ASSERT_NE(my_completion
, my_completion_null
);
3275 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("nonexistent",
3276 my_completion
, &bl1
, 128, 0));
3279 ASSERT_EQ(0, my_completion
->wait_for_complete());
3281 ASSERT_EQ(-ENOENT
, my_completion
->get_return_value());
3282 delete my_completion
;
3285 TEST(LibRadosAioEC
, Flush
) {
3286 AioTestDataEC test_data
;
3287 rados_completion_t my_completion
;
3288 ASSERT_EQ("", test_data
.init());
3289 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3290 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3292 memset(buf
, 0xee, sizeof(buf
));
3293 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3294 my_completion
, buf
, sizeof(buf
), 0));
3295 ASSERT_EQ(0, rados_aio_flush(test_data
.m_ioctx
));
3296 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3298 memset(buf2
, 0, sizeof(buf2
));
3299 rados_completion_t my_completion2
;
3300 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3301 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3302 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3303 my_completion2
, buf2
, sizeof(buf2
), 0));
3306 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3308 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
3309 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3310 rados_aio_release(my_completion
);
3311 rados_aio_release(my_completion2
);
3314 TEST(LibRadosAioEC
, FlushPP
) {
3315 AioTestDataECPP test_data
;
3316 ASSERT_EQ("", test_data
.init());
3317 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3318 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3319 AioCompletion
*my_completion_null
= NULL
;
3320 ASSERT_NE(my_completion
, my_completion_null
);
3322 memset(buf
, 0xee, sizeof(buf
));
3324 bl1
.append(buf
, sizeof(buf
));
3325 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3326 bl1
, sizeof(buf
), 0));
3327 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush());
3328 ASSERT_EQ(0, my_completion
->get_return_value());
3330 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3331 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3332 ASSERT_NE(my_completion2
, my_completion_null
);
3333 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3334 &bl2
, sizeof(buf
), 0));
3337 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3339 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3340 ASSERT_EQ(sizeof(buf
), bl2
.length());
3341 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3342 delete my_completion
;
3343 delete my_completion2
;
3346 TEST(LibRadosAioEC
, FlushAsync
) {
3347 AioTestDataEC test_data
;
3348 rados_completion_t my_completion
;
3349 ASSERT_EQ("", test_data
.init());
3350 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3351 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3352 rados_completion_t flush_completion
;
3353 ASSERT_EQ(0, rados_aio_create_completion(NULL
, NULL
, NULL
, &flush_completion
));
3355 memset(buf
, 0xee, sizeof(buf
));
3356 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3357 my_completion
, buf
, sizeof(buf
), 0));
3358 ASSERT_EQ(0, rados_aio_flush_async(test_data
.m_ioctx
, flush_completion
));
3361 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion
));
3362 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion
));
3364 ASSERT_EQ(1, rados_aio_is_complete(my_completion
));
3365 ASSERT_EQ(1, rados_aio_is_safe(my_completion
));
3366 ASSERT_EQ(1, rados_aio_is_complete(flush_completion
));
3367 ASSERT_EQ(1, rados_aio_is_safe(flush_completion
));
3368 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3370 memset(buf2
, 0, sizeof(buf2
));
3371 rados_completion_t my_completion2
;
3372 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3373 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3374 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3375 my_completion2
, buf2
, sizeof(buf2
), 0));
3378 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3380 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
3381 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3382 rados_aio_release(my_completion
);
3383 rados_aio_release(my_completion2
);
3384 rados_aio_release(flush_completion
);
3387 TEST(LibRadosAioEC
, FlushAsyncPP
) {
3388 AioTestDataECPP test_data
;
3389 ASSERT_EQ("", test_data
.init());
3390 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3391 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3392 AioCompletion
*flush_completion
=
3393 test_data
.m_cluster
.aio_create_completion(NULL
, NULL
, NULL
);
3394 AioCompletion
*my_completion_null
= NULL
;
3395 ASSERT_NE(my_completion
, my_completion_null
);
3397 memset(buf
, 0xee, sizeof(buf
));
3399 bl1
.append(buf
, sizeof(buf
));
3400 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3401 bl1
, sizeof(buf
), 0));
3402 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush_async(flush_completion
));
3405 ASSERT_EQ(0, flush_completion
->wait_for_complete());
3406 ASSERT_EQ(0, flush_completion
->wait_for_safe());
3408 ASSERT_EQ(1, my_completion
->is_complete());
3409 ASSERT_EQ(1, my_completion
->is_safe());
3410 ASSERT_EQ(1, flush_completion
->is_complete());
3411 ASSERT_EQ(1, flush_completion
->is_safe());
3412 ASSERT_EQ(0, my_completion
->get_return_value());
3414 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3415 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3416 ASSERT_NE(my_completion2
, my_completion_null
);
3417 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3418 &bl2
, sizeof(buf
), 0));
3421 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3423 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3424 ASSERT_EQ(sizeof(buf
), bl2
.length());
3425 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3426 delete my_completion
;
3427 delete my_completion2
;
3428 delete flush_completion
;
3431 TEST(LibRadosAioEC
, RoundTripWriteFull
) {
3432 AioTestDataEC test_data
;
3433 rados_completion_t my_completion
, my_completion2
, my_completion3
;
3434 ASSERT_EQ("", test_data
.init());
3435 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3436 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3438 memset(buf
, 0xcc, sizeof(buf
));
3439 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3440 my_completion
, buf
, sizeof(buf
), 0));
3443 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
3445 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3447 memset(buf2
, 0xdd, sizeof(buf2
));
3448 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3449 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3450 ASSERT_EQ(0, rados_aio_write_full(test_data
.m_ioctx
, "foo",
3451 my_completion2
, buf2
, sizeof(buf2
)));
3454 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3456 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3457 char buf3
[sizeof(buf
) + sizeof(buf2
)];
3458 memset(buf3
, 0, sizeof(buf3
));
3459 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3460 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3461 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3462 my_completion3
, buf3
, sizeof(buf3
), 0));
3465 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3467 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion3
));
3468 ASSERT_EQ(0, memcmp(buf3
, buf2
, sizeof(buf2
)));
3469 rados_aio_release(my_completion
);
3470 rados_aio_release(my_completion2
);
3471 rados_aio_release(my_completion3
);
3474 TEST(LibRadosAioEC
, RoundTripWriteFullPP
) {
3475 AioTestDataECPP test_data
;
3476 ASSERT_EQ("", test_data
.init());
3477 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3478 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3479 AioCompletion
*my_completion_null
= NULL
;
3480 ASSERT_NE(my_completion
, my_completion_null
);
3482 memset(buf
, 0xcc, sizeof(buf
));
3484 bl1
.append(buf
, sizeof(buf
));
3485 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3486 bl1
, sizeof(buf
), 0));
3489 ASSERT_EQ(0, my_completion
->wait_for_complete());
3491 ASSERT_EQ(0, my_completion
->get_return_value());
3493 memset(buf2
, 0xdd, sizeof(buf2
));
3495 bl2
.append(buf2
, sizeof(buf2
));
3496 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3497 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3498 ASSERT_NE(my_completion2
, my_completion_null
);
3499 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write_full("foo", my_completion2
, bl2
));
3502 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3504 ASSERT_EQ(0, my_completion2
->get_return_value());
3506 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
3507 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3508 ASSERT_NE(my_completion3
, my_completion_null
);
3509 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
3510 &bl3
, sizeof(buf
), 0));
3513 ASSERT_EQ(0, my_completion3
->wait_for_complete());
3515 ASSERT_EQ((int)sizeof(buf2
), my_completion3
->get_return_value());
3516 ASSERT_EQ(sizeof(buf2
), bl3
.length());
3517 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
3518 delete my_completion
;
3519 delete my_completion2
;
3520 delete my_completion3
;
3523 //using ObjectWriteOperation/ObjectReadOperation with iohint
3524 TEST(LibRadosAioEC
, RoundTripWriteFullPP2
)
3527 std::string pool_name
= get_temp_pool_name();
3528 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
3530 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
3532 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
3533 ObjectWriteOperation op
;
3535 memset(buf
, 0xcc, sizeof(buf
));
3540 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE
);
3541 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
3544 ASSERT_EQ(0, my_completion1
->wait_for_complete());
3546 EXPECT_EQ(0, my_completion1
->get_return_value());
3548 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
3550 ObjectReadOperation op1
;
3551 op1
.read(0, sizeof(buf
), &bl
, NULL
);
3552 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
3553 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
3556 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3558 EXPECT_EQ(0, my_completion2
->get_return_value());
3559 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
3561 ioctx
.remove("test_obj");
3562 destroy_one_pool_pp(pool_name
, cluster
);
3565 TEST(LibRadosAioEC
, SimpleStat
) {
3566 AioTestDataEC test_data
;
3567 rados_completion_t my_completion
;
3568 ASSERT_EQ("", test_data
.init());
3569 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3570 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3572 memset(buf
, 0xcc, sizeof(buf
));
3573 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3574 my_completion
, buf
, sizeof(buf
), 0));
3577 sem_wait(test_data
.m_sem
);
3578 sem_wait(test_data
.m_sem
);
3580 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3583 rados_completion_t my_completion2
;
3584 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3585 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3586 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3587 my_completion2
, &psize
, &pmtime
));
3590 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3592 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3593 ASSERT_EQ(sizeof(buf
), psize
);
3594 rados_aio_release(my_completion
);
3595 rados_aio_release(my_completion2
);
3598 TEST(LibRadosAioEC
, SimpleStatPP
) {
3599 AioTestDataECPP test_data
;
3600 ASSERT_EQ("", test_data
.init());
3601 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3602 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3603 AioCompletion
*my_completion_null
= NULL
;
3604 ASSERT_NE(my_completion
, my_completion_null
);
3606 memset(buf
, 0xcc, sizeof(buf
));
3608 bl1
.append(buf
, sizeof(buf
));
3609 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3610 bl1
, sizeof(buf
), 0));
3613 sem_wait(test_data
.m_sem
);
3614 sem_wait(test_data
.m_sem
);
3616 ASSERT_EQ(0, my_completion
->get_return_value());
3619 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3620 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3621 ASSERT_NE(my_completion2
, my_completion_null
);
3622 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
3626 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3628 ASSERT_EQ(0, my_completion2
->get_return_value());
3629 ASSERT_EQ(sizeof(buf
), psize
);
3630 delete my_completion
;
3631 delete my_completion2
;
3634 TEST(LibRadosAioEC
, SimpleStatNS
) {
3635 AioTestDataEC test_data
;
3636 rados_completion_t my_completion
;
3637 ASSERT_EQ("", test_data
.init());
3638 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3639 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3641 memset(buf
, 0xcc, sizeof(buf
));
3642 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3643 my_completion
, buf
, sizeof(buf
), 0));
3646 sem_wait(test_data
.m_sem
);
3647 sem_wait(test_data
.m_sem
);
3649 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3650 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
3652 memset(buf2
, 0xbb, sizeof(buf2
));
3653 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3654 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3655 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3656 my_completion
, buf2
, sizeof(buf2
), 0));
3659 sem_wait(test_data
.m_sem
);
3660 sem_wait(test_data
.m_sem
);
3662 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3665 rados_completion_t my_completion2
;
3666 rados_ioctx_set_namespace(test_data
.m_ioctx
, "");
3667 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3668 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3669 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3670 my_completion2
, &psize
, &pmtime
));
3673 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3675 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3676 ASSERT_EQ(sizeof(buf
), psize
);
3678 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
3679 rados_completion_t my_completion3
;
3680 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3681 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3682 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3683 my_completion3
, &psize
, &pmtime
));
3686 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3688 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
3689 ASSERT_EQ(sizeof(buf2
), psize
);
3691 rados_aio_release(my_completion
);
3692 rados_aio_release(my_completion2
);
3693 rados_aio_release(my_completion3
);
3696 TEST(LibRadosAioEC
, SimpleStatPPNS
) {
3697 AioTestDataECPP test_data
;
3698 ASSERT_EQ("", test_data
.init());
3699 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3700 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3701 AioCompletion
*my_completion_null
= NULL
;
3702 ASSERT_NE(my_completion
, my_completion_null
);
3704 memset(buf
, 0xcc, sizeof(buf
));
3706 bl1
.append(buf
, sizeof(buf
));
3707 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3708 bl1
, sizeof(buf
), 0));
3711 sem_wait(test_data
.m_sem
);
3712 sem_wait(test_data
.m_sem
);
3714 ASSERT_EQ(0, my_completion
->get_return_value());
3717 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3718 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3719 ASSERT_NE(my_completion2
, my_completion_null
);
3720 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
3724 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3726 ASSERT_EQ(0, my_completion2
->get_return_value());
3727 ASSERT_EQ(sizeof(buf
), psize
);
3728 delete my_completion
;
3729 delete my_completion2
;
3732 TEST(LibRadosAioEC
, StatRemove
) {
3733 AioTestDataEC test_data
;
3734 rados_completion_t my_completion
;
3735 ASSERT_EQ("", test_data
.init());
3736 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3737 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3739 memset(buf
, 0xcc, sizeof(buf
));
3740 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3741 my_completion
, buf
, sizeof(buf
), 0));
3744 sem_wait(test_data
.m_sem
);
3745 sem_wait(test_data
.m_sem
);
3747 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3750 rados_completion_t my_completion2
;
3751 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3752 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3753 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3754 my_completion2
, &psize
, &pmtime
));
3757 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3759 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3760 ASSERT_EQ(sizeof(buf
), psize
);
3761 rados_completion_t my_completion3
;
3762 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3763 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3764 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion3
));
3767 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3769 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
3772 rados_completion_t my_completion4
;
3773 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3774 set_completion_completeEC
, set_completion_safeEC
, &my_completion4
));
3775 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3776 my_completion4
, &psize2
, &pmtime2
));
3779 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
3781 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion4
));
3782 rados_aio_release(my_completion
);
3783 rados_aio_release(my_completion2
);
3784 rados_aio_release(my_completion3
);
3785 rados_aio_release(my_completion4
);
3788 TEST(LibRadosAioEC
, StatRemovePP
) {
3789 AioTestDataECPP test_data
;
3790 ASSERT_EQ("", test_data
.init());
3791 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3792 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3793 AioCompletion
*my_completion_null
= NULL
;
3794 ASSERT_NE(my_completion
, my_completion_null
);
3796 memset(buf
, 0xcc, sizeof(buf
));
3798 bl1
.append(buf
, sizeof(buf
));
3799 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3800 bl1
, sizeof(buf
), 0));
3803 sem_wait(test_data
.m_sem
);
3804 sem_wait(test_data
.m_sem
);
3806 ASSERT_EQ(0, my_completion
->get_return_value());
3809 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3810 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3811 ASSERT_NE(my_completion2
, my_completion_null
);
3812 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
3816 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3818 ASSERT_EQ(0, my_completion2
->get_return_value());
3819 ASSERT_EQ(sizeof(buf
), psize
);
3822 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
3823 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3824 ASSERT_NE(my_completion3
, my_completion_null
);
3825 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion3
));
3828 ASSERT_EQ(0, my_completion3
->wait_for_complete());
3830 ASSERT_EQ(0, my_completion3
->get_return_value());
3832 AioCompletion
*my_completion4
= test_data
.m_cluster
.aio_create_completion(
3833 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3834 ASSERT_NE(my_completion4
, my_completion_null
);
3835 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion4
,
3836 &psize2
, &pmtime2
));
3839 ASSERT_EQ(0, my_completion4
->wait_for_complete());
3841 ASSERT_EQ(-ENOENT
, my_completion4
->get_return_value());
3842 delete my_completion
;
3843 delete my_completion2
;
3844 delete my_completion3
;
3845 delete my_completion4
;
3848 TEST(LibRadosAioEC
, ExecuteClass
) {
3849 AioTestDataEC test_data
;
3850 rados_completion_t my_completion
;
3851 ASSERT_EQ("", test_data
.init());
3852 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3853 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3855 memset(buf
, 0xcc, sizeof(buf
));
3856 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3857 my_completion
, buf
, sizeof(buf
), 0));
3860 sem_wait(test_data
.m_sem
);
3861 sem_wait(test_data
.m_sem
);
3863 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3864 rados_completion_t my_completion2
;
3865 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3866 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3868 ASSERT_EQ(0, rados_aio_exec(test_data
.m_ioctx
, "foo", my_completion2
,
3869 "hello", "say_hello", NULL
, 0, out
, sizeof(out
)));
3872 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3874 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2
));
3875 ASSERT_EQ(0, strncmp("Hello, world!", out
, 13));
3876 rados_aio_release(my_completion
);
3877 rados_aio_release(my_completion2
);
3880 TEST(LibRadosAioEC
, ExecuteClassPP
) {
3881 AioTestDataECPP test_data
;
3882 ASSERT_EQ("", test_data
.init());
3883 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3884 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3885 AioCompletion
*my_completion_null
= NULL
;
3886 ASSERT_NE(my_completion
, my_completion_null
);
3888 memset(buf
, 0xcc, sizeof(buf
));
3890 bl1
.append(buf
, sizeof(buf
));
3891 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3892 bl1
, sizeof(buf
), 0));
3895 sem_wait(test_data
.m_sem
);
3896 sem_wait(test_data
.m_sem
);
3898 ASSERT_EQ(0, my_completion
->get_return_value());
3899 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3900 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3901 ASSERT_NE(my_completion2
, my_completion_null
);
3903 ASSERT_EQ(0, test_data
.m_ioctx
.aio_exec("foo", my_completion2
,
3904 "hello", "say_hello", in
, &out
));
3907 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3909 ASSERT_EQ(0, my_completion2
->get_return_value());
3910 ASSERT_EQ(std::string("Hello, world!"), std::string(out
.c_str(), out
.length()));
3911 delete my_completion
;
3912 delete my_completion2
;
3915 TEST(LibRadosAioEC
, OmapPP
) {
3917 std::string pool_name
= get_temp_pool_name();
3918 ASSERT_EQ("", create_one_ec_pool_pp(pool_name
, cluster
));
3920 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
3922 string header_str
= "baz";
3923 bufferptr
bp(header_str
.c_str(), header_str
.size() + 1);
3924 bufferlist header_to_set
;
3925 header_to_set
.push_back(bp
);
3926 map
<string
, bufferlist
> to_set
;
3928 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
3929 ObjectWriteOperation op
;
3930 to_set
["foo"] = header_to_set
;
3931 to_set
["foo2"] = header_to_set
;
3932 to_set
["qfoo3"] = header_to_set
;
3933 op
.omap_set(to_set
);
3935 op
.omap_set_header(header_to_set
);
3937 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
3940 ASSERT_EQ(0, my_completion
->wait_for_complete());
3942 EXPECT_EQ(-EOPNOTSUPP
, my_completion
->get_return_value());
3944 ioctx
.remove("test_obj");
3945 destroy_one_pool_pp(pool_name
, cluster
);
3948 TEST(LibRadosAioEC
, MultiWrite
) {
3949 AioTestDataEC test_data
;
3950 rados_completion_t my_completion
, my_completion2
, my_completion3
;
3951 ASSERT_EQ("", test_data
.init());
3952 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3953 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3955 memset(buf
, 0xcc, sizeof(buf
));
3956 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3957 my_completion
, buf
, sizeof(buf
), 0));
3960 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
3962 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3965 memset(buf2
, 0xdd, sizeof(buf2
));
3966 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3967 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3968 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3969 my_completion2
, buf2
, sizeof(buf2
), sizeof(buf
)));
3972 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3974 ASSERT_EQ(-EOPNOTSUPP
, rados_aio_get_return_value(my_completion2
));
3976 char buf3
[(sizeof(buf
) + sizeof(buf2
)) * 3];
3977 memset(buf3
, 0, sizeof(buf3
));
3978 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3979 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3980 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3981 my_completion3
, buf3
, sizeof(buf3
), 0));
3984 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3986 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion3
));
3987 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
3988 rados_aio_release(my_completion
);
3989 rados_aio_release(my_completion2
);
3990 rados_aio_release(my_completion3
);
3993 TEST(LibRadosAioEC
, MultiWritePP
) {
3994 AioTestDataECPP test_data
;
3995 ASSERT_EQ("", test_data
.init());
3996 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3997 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3998 AioCompletion
*my_completion_null
= NULL
;
3999 ASSERT_NE(my_completion
, my_completion_null
);
4001 memset(buf
, 0xcc, sizeof(buf
));
4003 bl1
.append(buf
, sizeof(buf
));
4004 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
4005 bl1
, sizeof(buf
), 0));
4008 ASSERT_EQ(0, my_completion
->wait_for_complete());
4010 ASSERT_EQ(0, my_completion
->get_return_value());
4013 memset(buf2
, 0xdd, sizeof(buf2
));
4015 bl2
.append(buf2
, sizeof(buf2
));
4016 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
4017 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
4018 ASSERT_NE(my_completion2
, my_completion_null
);
4019 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion2
,
4020 bl2
, sizeof(buf2
), sizeof(buf
)));
4023 ASSERT_EQ(0, my_completion2
->wait_for_complete());
4025 ASSERT_EQ(-EOPNOTSUPP
, my_completion2
->get_return_value());
4028 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
4029 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
4030 ASSERT_NE(my_completion3
, my_completion_null
);
4031 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
4032 &bl3
, (sizeof(buf
) + sizeof(buf2
) * 3), 0));
4035 ASSERT_EQ(0, my_completion3
->wait_for_complete());
4037 ASSERT_EQ((int)sizeof(buf
), my_completion3
->get_return_value());
4038 ASSERT_EQ(sizeof(buf
), bl3
.length());
4039 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, sizeof(buf
)));
4040 delete my_completion
;
4041 delete my_completion2
;
4042 delete my_completion3
;
4045 TEST(LibRadosAio
, RacingRemovePP
) {
4046 AioTestDataPP test_data
;
4047 ASSERT_EQ("", test_data
.init({{"objecter_retry_writes_after_first_reply", "true"}}));
4048 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
4049 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4050 ASSERT_NE(my_completion
, nullptr);
4052 memset(buf
, 0xcc, sizeof(buf
));
4054 bl
.append(buf
, sizeof(buf
));
4055 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
4056 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4057 ASSERT_NE(my_completion2
, nullptr);
4058 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion2
));
4059 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
4060 bl
, sizeof(buf
), 0));
4063 sem_wait(test_data
.m_sem
);
4064 sem_wait(test_data
.m_sem
);
4065 my_completion2
->wait_for_complete();
4066 my_completion
->wait_for_complete();
4068 ASSERT_EQ(-ENOENT
, my_completion2
->get_return_value());
4069 ASSERT_EQ(0, my_completion
->get_return_value());
4070 ASSERT_EQ(0, test_data
.m_ioctx
.stat("foo", nullptr, nullptr));
4071 delete my_completion
;
4072 delete my_completion2
;
4075 TEST(LibRadosAio
, RoundTripCmpExtPP
) {
4076 AioTestDataPP test_data
;
4077 ASSERT_EQ("", test_data
.init());
4078 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
4079 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4080 AioCompletion
*my_completion_null
= NULL
;
4081 ASSERT_NE(my_completion
, my_completion_null
);
4083 memset(full
, 0xcc, sizeof(full
));
4085 bl1
.append(full
, sizeof(full
));
4086 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
4087 bl1
, sizeof(full
), 0));
4090 ASSERT_EQ(0, my_completion
->wait_for_complete());
4092 ASSERT_EQ(0, my_completion
->get_return_value());
4094 /* compare with match */
4096 cbl
.append(full
, sizeof(full
));
4097 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
4098 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4099 ASSERT_EQ(0, test_data
.m_ioctx
.aio_cmpext("foo", my_completion2
, 0, cbl
));
4103 ASSERT_EQ(0, my_completion2
->wait_for_complete());
4105 ASSERT_EQ(0, my_completion2
->get_return_value());
4107 /* compare with mismatch */
4108 memset(full
, 0xdd, sizeof(full
));
4110 cbl
.append(full
, sizeof(full
));
4111 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
4112 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4113 ASSERT_EQ(0, test_data
.m_ioctx
.aio_cmpext("foo", my_completion3
, 0, cbl
));
4117 ASSERT_EQ(0, my_completion3
->wait_for_complete());
4119 ASSERT_EQ(-MAX_ERRNO
, my_completion3
->get_return_value());
4121 delete my_completion
;
4122 delete my_completion2
;
4123 delete my_completion3
;
4126 TEST(LibRadosAio
, RoundTripCmpExtPP2
)
4130 char miscmp_buf
[128];
4133 std::string pool_name
= get_temp_pool_name();
4134 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
4136 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
4138 boost::scoped_ptr
<AioCompletion
>
4139 wr_cmpl(cluster
.aio_create_completion(0, 0, 0));
4140 ObjectWriteOperation wr_op
;
4141 memset(buf
, 0xcc, sizeof(buf
));
4142 memset(miscmp_buf
, 0xdd, sizeof(miscmp_buf
));
4144 bl
.append(buf
, sizeof(buf
));
4146 wr_op
.write_full(bl
);
4147 wr_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4148 ioctx
.aio_operate("test_obj", wr_cmpl
.get(), &wr_op
);
4151 ASSERT_EQ(0, wr_cmpl
->wait_for_complete());
4153 EXPECT_EQ(0, wr_cmpl
->get_return_value());
4155 /* cmpext as write op. first match then mismatch */
4156 boost::scoped_ptr
<AioCompletion
>
4157 wr_cmpext_cmpl(cluster
.aio_create_completion(0, 0, 0));
4158 cbl
.append(buf
, sizeof(buf
));
4161 wr_op
.cmpext(0, cbl
, &ret
);
4162 wr_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4163 ioctx
.aio_operate("test_obj", wr_cmpext_cmpl
.get(), &wr_op
);
4166 ASSERT_EQ(0, wr_cmpext_cmpl
->wait_for_complete());
4168 EXPECT_EQ(0, wr_cmpext_cmpl
->get_return_value());
4171 boost::scoped_ptr
<AioCompletion
>
4172 wr_cmpext_cmpl2(cluster
.aio_create_completion(0, 0, 0));
4174 cbl
.append(miscmp_buf
, sizeof(miscmp_buf
));
4177 wr_op
.cmpext(0, cbl
, &ret
);
4178 wr_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4179 ioctx
.aio_operate("test_obj", wr_cmpext_cmpl2
.get(), &wr_op
);
4182 ASSERT_EQ(0, wr_cmpext_cmpl2
->wait_for_complete());
4184 EXPECT_EQ(-MAX_ERRNO
, wr_cmpext_cmpl2
->get_return_value());
4185 EXPECT_EQ(-MAX_ERRNO
, ret
);
4187 /* cmpext as read op */
4188 boost::scoped_ptr
<AioCompletion
>
4189 rd_cmpext_cmpl(cluster
.aio_create_completion(0, 0, 0));
4190 ObjectReadOperation rd_op
;
4192 cbl
.append(buf
, sizeof(buf
));
4194 rd_op
.cmpext(0, cbl
, &ret
);
4195 rd_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4196 ioctx
.aio_operate("test_obj", rd_cmpext_cmpl
.get(), &rd_op
, 0);
4199 ASSERT_EQ(0, rd_cmpext_cmpl
->wait_for_complete());
4201 EXPECT_EQ(0, rd_cmpext_cmpl
->get_return_value());
4204 boost::scoped_ptr
<AioCompletion
>
4205 rd_cmpext_cmpl2(cluster
.aio_create_completion(0, 0, 0));
4207 cbl
.append(miscmp_buf
, sizeof(miscmp_buf
));
4210 rd_op
.cmpext(0, cbl
, &ret
);
4211 rd_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4212 ioctx
.aio_operate("test_obj", rd_cmpext_cmpl2
.get(), &rd_op
, 0);
4215 ASSERT_EQ(0, rd_cmpext_cmpl2
->wait_for_complete());
4217 EXPECT_EQ(-MAX_ERRNO
, rd_cmpext_cmpl2
->get_return_value());
4218 EXPECT_EQ(-MAX_ERRNO
, ret
);
4220 ioctx
.remove("test_obj");
4221 destroy_one_pool_pp(pool_name
, cluster
);