1 #include "common/errno.h"
2 #include "include/err.h"
3 #include "include/rados/librados.h"
4 #include "test/librados/test.h"
5 #include "include/types.h"
6 #include "include/stringify.h"
8 #include "gtest/gtest.h"
11 #include <semaphore.h>
14 #include <boost/scoped_ptr.hpp>
17 using std::ostringstream
;
18 using namespace librados
;
36 rados_ioctx_destroy(m_ioctx
);
37 destroy_one_pool(m_pool_name
, &m_cluster
);
45 if (SEM_FAILED
== (m_sem
= sem_open("/test_aio_sem", O_CREAT
, 0644, 0))) {
48 oss
<< "sem_open failed: " << cpp_strerror(err
);
51 m_pool_name
= get_temp_pool_name();
52 std::string err
= create_one_pool(m_pool_name
, &m_cluster
);
56 oss
<< "create_one_pool(" << m_pool_name
<< ") failed: error " << err
;
59 ret
= rados_ioctx_create(m_cluster
, m_pool_name
.c_str(), &m_ioctx
);
62 destroy_one_pool(m_pool_name
, &m_cluster
);
64 oss
<< "rados_ioctx_create failed: error " << ret
;
73 rados_ioctx_t m_ioctx
;
74 std::string m_pool_name
;
94 destroy_one_pool_pp(m_pool_name
, m_cluster
);
104 std::string
init(const std::map
<std::string
, std::string
> &config
)
108 if (SEM_FAILED
== (m_sem
= sem_open("/test_aio_sem", O_CREAT
, 0644, 0))) {
111 oss
<< "sem_open failed: " << cpp_strerror(err
);
114 m_pool_name
= get_temp_pool_name();
115 std::string err
= create_one_pool_pp(m_pool_name
, m_cluster
, config
);
119 oss
<< "create_one_pool(" << m_pool_name
<< ") failed: error " << err
;
122 ret
= m_cluster
.ioctx_create(m_pool_name
.c_str(), m_ioctx
);
125 destroy_one_pool_pp(m_pool_name
, m_cluster
);
127 oss
<< "rados_ioctx_create failed: error " << ret
;
137 std::string m_pool_name
;
143 void set_completion_complete(rados_completion_t cb
, void *arg
)
145 AioTestData
*test
= static_cast<AioTestData
*>(arg
);
146 test
->m_complete
= true;
147 sem_post(test
->m_sem
);
150 void set_completion_safe(rados_completion_t cb
, void *arg
)
152 AioTestData
*test
= static_cast<AioTestData
*>(arg
);
154 sem_post(test
->m_sem
);
157 void set_completion_completePP(rados_completion_t cb
, void *arg
)
159 AioTestDataPP
*test
= static_cast<AioTestDataPP
*>(arg
);
160 test
->m_complete
= true;
161 sem_post(test
->m_sem
);
164 void set_completion_safePP(rados_completion_t cb
, void *arg
)
166 AioTestDataPP
*test
= static_cast<AioTestDataPP
*>(arg
);
168 sem_post(test
->m_sem
);
171 TEST(LibRadosAio
, TooBig
) {
172 AioTestData test_data
;
173 rados_completion_t my_completion
;
174 ASSERT_EQ("", test_data
.init());
175 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
176 set_completion_complete
, set_completion_safe
, &my_completion
));
178 memset(buf
, 0xcc, sizeof(buf
));
179 ASSERT_EQ(-E2BIG
, rados_aio_write(test_data
.m_ioctx
, "foo",
180 my_completion
, buf
, UINT_MAX
, 0));
181 ASSERT_EQ(-E2BIG
, rados_aio_write_full(test_data
.m_ioctx
, "foo",
182 my_completion
, buf
, UINT_MAX
));
183 ASSERT_EQ(-E2BIG
, rados_aio_append(test_data
.m_ioctx
, "foo",
184 my_completion
, buf
, UINT_MAX
));
185 rados_aio_release(my_completion
);
188 TEST(LibRadosAio
, TooBigPP
) {
189 AioTestDataPP test_data
;
190 ASSERT_EQ("", test_data
.init());
193 AioCompletion
*aio_completion
= test_data
.m_cluster
.aio_create_completion(
194 (void*)&test_data
, NULL
, NULL
);
195 ASSERT_EQ(-E2BIG
, test_data
.m_ioctx
.aio_write("foo", aio_completion
, bl
, UINT_MAX
, 0));
196 ASSERT_EQ(-E2BIG
, test_data
.m_ioctx
.aio_append("foo", aio_completion
, bl
, UINT_MAX
));
197 // ioctx.aio_write_full no way to overflow bl.length()
198 delete aio_completion
;
201 TEST(LibRadosAio
, PoolQuotaPP
) {
202 AioTestDataPP test_data
;
203 ASSERT_EQ("", test_data
.init());
204 string p
= get_temp_pool_name();
205 ASSERT_EQ(0, test_data
.m_cluster
.pool_create(p
.c_str()));
207 ASSERT_EQ(0, test_data
.m_cluster
.ioctx_create(p
.c_str(), ioctx
));
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 block without FULL_TRY
240 ObjectWriteOperation op
;
242 librados::AioCompletion
*completion
=
243 test_data
.m_cluster
.aio_create_completion();
244 ASSERT_EQ(0, ioctx
.aio_operate("bar", completion
, &op
, 0));
246 ASSERT_FALSE(completion
->is_safe());
247 completion
->release();
251 ASSERT_EQ(0, test_data
.m_cluster
.pool_delete(p
.c_str()));
254 TEST(LibRadosAio
, SimpleWrite
) {
255 AioTestData test_data
;
256 rados_completion_t my_completion
;
257 ASSERT_EQ("", test_data
.init());
258 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
259 set_completion_complete
, set_completion_safe
, &my_completion
));
261 memset(buf
, 0xcc, sizeof(buf
));
262 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
263 my_completion
, buf
, sizeof(buf
), 0));
266 sem_wait(test_data
.m_sem
);
267 sem_wait(test_data
.m_sem
);
269 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
271 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
272 rados_completion_t my_completion2
;
273 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
274 set_completion_complete
, set_completion_safe
, &my_completion2
));
275 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
276 my_completion2
, buf
, sizeof(buf
), 0));
279 sem_wait(test_data
.m_sem
);
280 sem_wait(test_data
.m_sem
);
282 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
283 rados_aio_release(my_completion
);
284 rados_aio_release(my_completion2
);
287 TEST(LibRadosAio
, SimpleWritePP
) {
289 memset(buf
, 0xcc, sizeof(buf
));
291 bl1
.append(buf
, sizeof(buf
));
293 AioTestDataPP test_data
;
294 ASSERT_EQ("", test_data
.init());
295 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
296 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
297 AioCompletion
*my_completion_null
= NULL
;
298 ASSERT_NE(my_completion
, my_completion_null
);
299 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
300 my_completion
, bl1
, sizeof(buf
), 0));
303 sem_wait(test_data
.m_sem
);
304 sem_wait(test_data
.m_sem
);
306 ASSERT_EQ(0, my_completion
->get_return_value());
307 delete my_completion
;
311 AioTestDataPP test_data
;
312 ASSERT_EQ("", test_data
.init());
313 test_data
.m_ioctx
.set_namespace("nspace");
314 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
315 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
316 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
317 my_completion
, bl1
, sizeof(buf
), 0));
320 sem_wait(test_data
.m_sem
);
321 sem_wait(test_data
.m_sem
);
323 ASSERT_EQ(0, my_completion
->get_return_value());
324 delete my_completion
;
328 TEST(LibRadosAio
, WaitForSafe
) {
329 AioTestData test_data
;
330 rados_completion_t my_completion
;
331 ASSERT_EQ("", test_data
.init());
332 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
333 set_completion_complete
, set_completion_safe
, &my_completion
));
335 memset(buf
, 0xcc, sizeof(buf
));
336 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
337 my_completion
, buf
, sizeof(buf
), 0));
339 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion
));
340 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
341 rados_aio_release(my_completion
);
344 TEST(LibRadosAio
, WaitForSafePP
) {
345 AioTestDataPP test_data
;
346 ASSERT_EQ("", test_data
.init());
347 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
348 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
349 AioCompletion
*my_completion_null
= NULL
;
350 ASSERT_NE(my_completion
, my_completion_null
);
352 memset(buf
, 0xcc, sizeof(buf
));
354 bl1
.append(buf
, sizeof(buf
));
355 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
356 my_completion
, bl1
, sizeof(buf
), 0));
358 ASSERT_EQ(0, my_completion
->wait_for_safe());
359 ASSERT_EQ(0, my_completion
->get_return_value());
360 delete my_completion
;
363 TEST(LibRadosAio
, RoundTrip
) {
364 AioTestData test_data
;
365 rados_completion_t my_completion
;
366 ASSERT_EQ("", test_data
.init());
367 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
368 set_completion_complete
, set_completion_safe
, &my_completion
));
370 memset(buf
, 0xcc, sizeof(buf
));
371 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
372 my_completion
, buf
, sizeof(buf
), 0));
375 sem_wait(test_data
.m_sem
);
376 sem_wait(test_data
.m_sem
);
378 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
380 memset(buf2
, 0, sizeof(buf2
));
381 rados_completion_t my_completion2
;
382 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
383 set_completion_complete
, set_completion_safe
, &my_completion2
));
384 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
385 my_completion2
, buf2
, sizeof(buf2
), 0));
388 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
390 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
391 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
392 rados_aio_release(my_completion
);
393 rados_aio_release(my_completion2
);
396 TEST(LibRadosAio
, RoundTrip2
) {
397 AioTestData test_data
;
398 rados_completion_t my_completion
;
399 ASSERT_EQ("", test_data
.init());
400 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
401 set_completion_complete
, set_completion_safe
, &my_completion
));
403 memset(buf
, 0xcc, sizeof(buf
));
404 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
405 my_completion
, buf
, sizeof(buf
), 0));
408 sem_wait(test_data
.m_sem
);
409 sem_wait(test_data
.m_sem
);
411 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
413 memset(buf2
, 0, sizeof(buf2
));
414 rados_completion_t my_completion2
;
415 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
416 set_completion_complete
, set_completion_safe
, &my_completion2
));
417 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
418 my_completion2
, buf2
, sizeof(buf2
), 0));
421 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
423 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
424 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
425 rados_aio_release(my_completion
);
426 rados_aio_release(my_completion2
);
429 TEST(LibRadosAio
, RoundTrip3
) {
430 AioTestData test_data
;
431 rados_completion_t my_completion
;
432 ASSERT_EQ("", test_data
.init());
433 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
434 set_completion_complete
, set_completion_safe
, &my_completion
));
436 memset(buf
, 0xcc, sizeof(buf
));
438 rados_write_op_t op1
= rados_create_write_op();
439 rados_write_op_write(op1
, buf
, sizeof(buf
), 0);
440 rados_write_op_set_alloc_hint2(op1
, 0, 0, LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
441 ASSERT_EQ(0, rados_aio_write_op_operate(op1
, test_data
.m_ioctx
, my_completion
,
443 rados_release_write_op(op1
);
447 sem_wait(test_data
.m_sem
);
448 sem_wait(test_data
.m_sem
);
451 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
452 rados_aio_release(my_completion
);
455 memset(buf2
, 0, sizeof(buf2
));
456 rados_completion_t my_completion2
;
457 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
458 set_completion_complete
, set_completion_safe
, &my_completion2
));
460 rados_read_op_t op2
= rados_create_read_op();
461 rados_read_op_read(op2
, 0, sizeof(buf2
), buf2
, NULL
, NULL
);
462 rados_read_op_set_flags(op2
, LIBRADOS_OP_FLAG_FADVISE_NOCACHE
|
463 LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
464 __le32 init_value
= -1;
466 rados_read_op_checksum(op2
, LIBRADOS_CHECKSUM_TYPE_CRC32C
,
467 reinterpret_cast<char *>(&init_value
),
468 sizeof(init_value
), 0, 0, 0,
469 reinterpret_cast<char *>(&checksum
),
470 sizeof(checksum
), NULL
);
471 ASSERT_EQ(0, rados_aio_read_op_operate(op2
, test_data
.m_ioctx
, my_completion2
,
473 rados_release_read_op(op2
);
477 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
479 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
480 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
481 rados_aio_release(my_completion2
);
484 bl
.append(buf
, sizeof(buf
));
485 ASSERT_EQ(1U, checksum
[0]);
486 ASSERT_EQ(bl
.crc32c(-1), checksum
[1]);
489 TEST(LibRadosAio
, RoundTripPP
) {
490 AioTestDataPP test_data
;
491 ASSERT_EQ("", test_data
.init());
492 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
493 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
494 AioCompletion
*my_completion_null
= NULL
;
495 ASSERT_NE(my_completion
, my_completion_null
);
497 memset(buf
, 0xcc, sizeof(buf
));
499 bl1
.append(buf
, sizeof(buf
));
500 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
501 bl1
, sizeof(buf
), 0));
504 sem_wait(test_data
.m_sem
);
505 sem_wait(test_data
.m_sem
);
507 ASSERT_EQ(0, my_completion
->get_return_value());
509 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
510 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
511 ASSERT_NE(my_completion2
, my_completion_null
);
512 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
513 my_completion2
, &bl2
, sizeof(buf
), 0));
516 ASSERT_EQ(0, my_completion2
->wait_for_complete());
518 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
519 ASSERT_EQ(sizeof(buf
), bl2
.length());
520 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
521 delete my_completion
;
522 delete my_completion2
;
525 TEST(LibRadosAio
, RoundTripPP2
) {
526 AioTestDataPP test_data
;
527 ASSERT_EQ("", test_data
.init());
528 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
529 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
530 AioCompletion
*my_completion_null
= NULL
;
531 ASSERT_NE(my_completion
, my_completion_null
);
533 memset(buf
, 0xcc, sizeof(buf
));
535 bl1
.append(buf
, sizeof(buf
));
536 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
537 bl1
, sizeof(buf
), 0));
540 sem_wait(test_data
.m_sem
);
541 sem_wait(test_data
.m_sem
);
543 ASSERT_EQ(0, my_completion
->get_return_value());
545 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
546 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
547 ASSERT_NE(my_completion2
, my_completion_null
);
548 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
549 my_completion2
, &bl2
, sizeof(buf
), 0));
552 ASSERT_EQ(0, my_completion2
->wait_for_safe());
553 ASSERT_EQ(0, my_completion2
->wait_for_complete());
555 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
556 ASSERT_EQ(sizeof(buf
), bl2
.length());
557 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
558 delete my_completion
;
559 delete my_completion2
;
562 //using ObjectWriteOperation/ObjectReadOperation with iohint
563 TEST(LibRadosAio
, RoundTripPP3
)
566 std::string pool_name
= get_temp_pool_name();
567 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
569 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
571 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
572 ObjectWriteOperation op
;
574 memset(buf
, 0xcc, sizeof(buf
));
576 bl
.append(buf
, sizeof(buf
));
579 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
580 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
583 ASSERT_EQ(0, my_completion1
->wait_for_complete());
585 EXPECT_EQ(0, my_completion1
->get_return_value());
587 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
589 ObjectReadOperation op1
;
590 op1
.read(0, sizeof(buf
), &bl
, NULL
);
591 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
592 bufferlist init_value_bl
;
593 ::encode(static_cast<int32_t>(-1), init_value_bl
);
595 op1
.checksum(LIBRADOS_CHECKSUM_TYPE_CRC32C
, init_value_bl
,
596 0, 0, 0, &csum_bl
, nullptr);
597 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
600 ASSERT_EQ(0, my_completion2
->wait_for_complete());
602 EXPECT_EQ(0, my_completion2
->get_return_value());
603 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
605 ASSERT_EQ(8U, csum_bl
.length());
606 auto csum_bl_it
= csum_bl
.begin();
609 ::decode(csum_count
, csum_bl_it
);
610 ASSERT_EQ(1U, csum_count
);
611 ::decode(csum
, csum_bl_it
);
612 ASSERT_EQ(bl
.crc32c(-1), csum
);
613 ioctx
.remove("test_obj");
614 destroy_one_pool_pp(pool_name
, cluster
);
617 TEST(LibRadosAio
, RoundTripSparseReadPP
) {
618 AioTestDataPP test_data
;
619 ASSERT_EQ("", test_data
.init());
620 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
621 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
622 AioCompletion
*my_completion_null
= NULL
;
623 ASSERT_NE(my_completion
, my_completion_null
);
625 memset(buf
, 0xcc, sizeof(buf
));
627 bl1
.append(buf
, sizeof(buf
));
628 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
629 bl1
, sizeof(buf
), 0));
632 sem_wait(test_data
.m_sem
);
633 sem_wait(test_data
.m_sem
);
635 ASSERT_EQ(0, my_completion
->get_return_value());
636 std::map
<uint64_t, uint64_t> extents
;
638 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
639 (void*)&test_data
, set_completion_completePP
, set_completion_safePP
);
640 ASSERT_NE(my_completion2
, my_completion_null
);
641 ASSERT_EQ(0, test_data
.m_ioctx
.aio_sparse_read("foo",
642 my_completion2
, &extents
, &bl2
, sizeof(buf
), 0));
645 ASSERT_EQ(0, my_completion2
->wait_for_complete());
647 ASSERT_EQ(0, my_completion2
->get_return_value());
648 assert_eq_sparse(bl1
, extents
, bl2
);
649 delete my_completion
;
650 delete my_completion2
;
653 TEST(LibRadosAio
, RoundTripAppend
) {
654 AioTestData test_data
;
655 rados_completion_t my_completion
, my_completion2
, my_completion3
;
656 ASSERT_EQ("", test_data
.init());
657 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
658 set_completion_complete
, set_completion_safe
, &my_completion
));
660 memset(buf
, 0xcc, sizeof(buf
));
661 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
662 my_completion
, buf
, sizeof(buf
)));
665 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
667 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
669 memset(buf2
, 0xdd, sizeof(buf2
));
670 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
671 set_completion_complete
, set_completion_safe
, &my_completion2
));
672 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
673 my_completion2
, buf2
, sizeof(buf2
)));
676 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
678 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
679 char buf3
[sizeof(buf
) + sizeof(buf2
)];
680 memset(buf3
, 0, sizeof(buf3
));
681 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
682 set_completion_complete
, set_completion_safe
, &my_completion3
));
683 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
684 my_completion3
, buf3
, sizeof(buf3
), 0));
687 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
689 ASSERT_EQ((int)sizeof(buf3
), rados_aio_get_return_value(my_completion3
));
690 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
691 ASSERT_EQ(0, memcmp(buf3
+ sizeof(buf
), buf2
, sizeof(buf2
)));
692 rados_aio_release(my_completion
);
693 rados_aio_release(my_completion2
);
694 rados_aio_release(my_completion3
);
697 TEST(LibRadosAio
, RoundTripAppendPP
) {
698 AioTestDataPP test_data
;
699 ASSERT_EQ("", test_data
.init());
700 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
701 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
702 AioCompletion
*my_completion_null
= NULL
;
703 ASSERT_NE(my_completion
, my_completion_null
);
705 memset(buf
, 0xcc, sizeof(buf
));
707 bl1
.append(buf
, sizeof(buf
));
708 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion
,
712 ASSERT_EQ(0, my_completion
->wait_for_complete());
714 ASSERT_EQ(0, my_completion
->get_return_value());
716 memset(buf2
, 0xdd, sizeof(buf2
));
718 bl2
.append(buf2
, sizeof(buf2
));
719 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
720 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
721 ASSERT_NE(my_completion2
, my_completion_null
);
722 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion2
,
726 ASSERT_EQ(0, my_completion2
->wait_for_complete());
728 ASSERT_EQ(0, my_completion2
->get_return_value());
730 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
731 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
732 ASSERT_NE(my_completion3
, my_completion_null
);
733 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
734 my_completion3
, &bl3
, 2 * sizeof(buf
), 0));
737 ASSERT_EQ(0, my_completion3
->wait_for_complete());
739 ASSERT_EQ((int)(sizeof(buf
) * 2), my_completion3
->get_return_value());
740 ASSERT_EQ(sizeof(buf
) * 2, bl3
.length());
741 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, sizeof(buf
)));
742 ASSERT_EQ(0, memcmp(bl3
.c_str() + sizeof(buf
), buf2
, sizeof(buf2
)));
743 delete my_completion
;
744 delete my_completion2
;
745 delete my_completion3
;
748 TEST(LibRadosAio
, RemoveTest
) {
750 char buf2
[sizeof(buf
)];
751 rados_completion_t my_completion
;
752 AioTestData test_data
;
753 ASSERT_EQ("", test_data
.init());
754 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
755 set_completion_complete
, set_completion_safe
, &my_completion
));
756 memset(buf
, 0xaa, sizeof(buf
));
757 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
758 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion
));
761 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
763 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
764 memset(buf2
, 0, sizeof(buf2
));
765 ASSERT_EQ(-ENOENT
, rados_read(test_data
.m_ioctx
, "foo", buf2
, sizeof(buf2
), 0));
766 rados_aio_release(my_completion
);
769 TEST(LibRadosAioPP
, RemoveTestPP
) {
771 memset(buf
, 0xaa, sizeof(buf
));
773 bl1
.append(buf
, sizeof(buf
));
774 AioTestDataPP test_data
;
775 ASSERT_EQ("", test_data
.init());
776 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
777 boost::scoped_ptr
<AioCompletion
> my_completion
778 (test_data
.m_cluster
.aio_create_completion
779 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
780 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion
.get()));
783 ASSERT_EQ(0, my_completion
->wait_for_complete());
785 ASSERT_EQ(0, my_completion
->get_return_value());
787 ASSERT_EQ(-ENOENT
, test_data
.m_ioctx
.read("foo", bl2
, sizeof(buf
), 0));
790 TEST(LibRadosAio
, XattrsRoundTrip
) {
792 char attr1
[] = "attr1";
793 char attr1_buf
[] = "foo bar baz";
795 AioTestData test_data
;
796 ASSERT_EQ("", test_data
.init());
797 memset(buf
, 0xaa, sizeof(buf
));
798 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
800 rados_completion_t my_completion
;
801 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
802 set_completion_complete
, set_completion_safe
, &my_completion
));
803 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion
, attr1
, buf
, sizeof(buf
)));
806 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
808 ASSERT_EQ(-ENODATA
, rados_aio_get_return_value(my_completion
));
809 rados_aio_release(my_completion
);
811 rados_completion_t my_completion2
;
812 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
813 set_completion_complete
, set_completion_safe
, &my_completion2
));
814 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo", my_completion2
, attr1
, attr1_buf
, sizeof(attr1_buf
)));
817 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
819 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
820 rados_aio_release(my_completion2
);
822 rados_completion_t my_completion3
;
823 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
824 set_completion_complete
, set_completion_safe
, &my_completion3
));
825 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion3
, attr1
, buf
, sizeof(buf
)));
828 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
830 ASSERT_EQ((int)sizeof(attr1_buf
), rados_aio_get_return_value(my_completion3
));
831 rados_aio_release(my_completion3
);
832 // check content of attribute
833 ASSERT_EQ(0, memcmp(attr1_buf
, buf
, sizeof(attr1_buf
)));
836 TEST(LibRadosAioPP
, XattrsRoundTripPP
) {
838 char attr1
[] = "attr1";
839 char attr1_buf
[] = "foo bar baz";
840 memset(buf
, 0xaa, sizeof(buf
));
842 bl1
.append(buf
, sizeof(buf
));
843 AioTestDataPP test_data
;
844 ASSERT_EQ("", test_data
.init());
845 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
848 boost::scoped_ptr
<AioCompletion
> my_completion
849 (test_data
.m_cluster
.aio_create_completion
850 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
851 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattr("foo", my_completion
.get(), attr1
, bl2
));
854 ASSERT_EQ(0, my_completion
->wait_for_complete());
856 ASSERT_EQ(-ENODATA
, my_completion
->get_return_value());
859 bl3
.append(attr1_buf
, sizeof(attr1_buf
));
861 AioTestDataPP test_data2
;
862 ASSERT_EQ("", test_data2
.init());
863 boost::scoped_ptr
<AioCompletion
> my_completion2
864 (test_data
.m_cluster
.aio_create_completion
865 ((void*)&test_data2
, set_completion_completePP
, set_completion_safePP
));
866 ASSERT_EQ(0, test_data
.m_ioctx
.aio_setxattr("foo", my_completion2
.get(), attr1
, bl3
));
869 ASSERT_EQ(0, my_completion2
->wait_for_complete());
871 ASSERT_EQ(0, my_completion2
->get_return_value());
874 AioTestDataPP test_data3
;
875 ASSERT_EQ("", test_data3
.init());
876 boost::scoped_ptr
<AioCompletion
> my_completion3
877 (test_data
.m_cluster
.aio_create_completion
878 ((void*)&test_data3
, set_completion_completePP
, set_completion_safePP
));
879 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattr("foo", my_completion3
.get(), attr1
, bl4
));
882 ASSERT_EQ(0, my_completion3
->wait_for_complete());
884 ASSERT_EQ((int)sizeof(attr1_buf
), my_completion3
->get_return_value());
885 // check content of attribute
886 ASSERT_EQ(0, memcmp(bl4
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
889 TEST(LibRadosAio
, RmXattr
) {
891 char attr1
[] = "attr1";
892 char attr1_buf
[] = "foo bar baz";
894 memset(buf
, 0xaa, sizeof(buf
));
895 AioTestData test_data
;
896 ASSERT_EQ("", test_data
.init());
897 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
899 rados_completion_t my_completion
;
900 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
901 set_completion_complete
, set_completion_safe
, &my_completion
));
902 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo", my_completion
, attr1
, attr1_buf
, sizeof(attr1_buf
)));
905 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
907 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
908 rados_aio_release(my_completion
);
910 rados_completion_t my_completion2
;
911 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
912 set_completion_complete
, set_completion_safe
, &my_completion2
));
913 ASSERT_EQ(0, rados_aio_rmxattr(test_data
.m_ioctx
, "foo", my_completion2
, attr1
));
916 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
918 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
919 rados_aio_release(my_completion2
);
920 // async getxattr after deletion
921 rados_completion_t my_completion3
;
922 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
923 set_completion_complete
, set_completion_safe
, &my_completion3
));
924 ASSERT_EQ(0, rados_aio_getxattr(test_data
.m_ioctx
, "foo", my_completion3
, attr1
, buf
, sizeof(buf
)));
927 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
929 ASSERT_EQ(-ENODATA
, rados_aio_get_return_value(my_completion3
));
930 rados_aio_release(my_completion3
);
931 // Test rmxattr on a removed object
933 char attr2
[] = "attr2";
934 char attr2_buf
[] = "foo bar baz";
935 memset(buf2
, 0xbb, sizeof(buf2
));
936 ASSERT_EQ(0, rados_write(test_data
.m_ioctx
, "foo_rmxattr", buf2
, sizeof(buf2
), 0));
938 rados_completion_t my_completion4
;
939 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
940 set_completion_complete
, set_completion_safe
, &my_completion4
));
941 ASSERT_EQ(0, rados_aio_setxattr(test_data
.m_ioctx
, "foo_rmxattr", my_completion4
, attr2
, attr2_buf
, sizeof(attr2_buf
)));
944 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
946 ASSERT_EQ(0, rados_aio_get_return_value(my_completion4
));
947 rados_aio_release(my_completion4
);
949 ASSERT_EQ(0, rados_remove(test_data
.m_ioctx
, "foo_rmxattr"));
950 // async rmxattr on non existing object
951 rados_completion_t my_completion5
;
952 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
953 set_completion_complete
, set_completion_safe
, &my_completion5
));
954 ASSERT_EQ(0, rados_aio_rmxattr(test_data
.m_ioctx
, "foo_rmxattr", my_completion5
, attr2
));
957 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion5
));
959 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion5
));
960 rados_aio_release(my_completion5
);
963 TEST(LibRadosAioPP
, RmXattrPP
) {
965 char attr1
[] = "attr1";
966 char attr1_buf
[] = "foo bar baz";
967 memset(buf
, 0xaa, sizeof(buf
));
969 bl1
.append(buf
, sizeof(buf
));
970 AioTestDataPP test_data
;
971 ASSERT_EQ("", test_data
.init());
972 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
975 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
976 boost::scoped_ptr
<AioCompletion
> my_completion
977 (test_data
.m_cluster
.aio_create_completion
978 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
979 ASSERT_EQ(0, test_data
.m_ioctx
.aio_setxattr("foo", my_completion
.get(), attr1
, bl2
));
982 ASSERT_EQ(0, my_completion
->wait_for_complete());
984 ASSERT_EQ(0, my_completion
->get_return_value());
986 AioTestDataPP test_data2
;
987 ASSERT_EQ("", test_data2
.init());
988 boost::scoped_ptr
<AioCompletion
> my_completion2
989 (test_data
.m_cluster
.aio_create_completion
990 ((void*)&test_data2
, set_completion_completePP
, set_completion_safePP
));
991 ASSERT_EQ(0, test_data
.m_ioctx
.aio_rmxattr("foo", my_completion2
.get(), attr1
));
994 ASSERT_EQ(0, my_completion2
->wait_for_complete());
996 ASSERT_EQ(0, my_completion2
->get_return_value());
998 AioTestDataPP test_data3
;
999 ASSERT_EQ("", test_data3
.init());
1000 boost::scoped_ptr
<AioCompletion
> my_completion3
1001 (test_data
.m_cluster
.aio_create_completion
1002 ((void*)&test_data3
, set_completion_completePP
, set_completion_safePP
));
1004 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattr("foo", my_completion3
.get(), attr1
, bl3
));
1007 ASSERT_EQ(0, my_completion3
->wait_for_complete());
1009 ASSERT_EQ(-ENODATA
, my_completion3
->get_return_value());
1010 // Test rmxattr on a removed object
1012 char attr2
[] = "attr2";
1013 char attr2_buf
[] = "foo bar baz";
1014 memset(buf2
, 0xbb, sizeof(buf2
));
1016 bl21
.append(buf
, sizeof(buf
));
1017 ASSERT_EQ(0, test_data
.m_ioctx
.write("foo_rmxattr", bl21
, sizeof(buf2
), 0));
1019 bl22
.append(attr2_buf
, sizeof(attr2_buf
));
1021 AioTestDataPP test_data4
;
1022 ASSERT_EQ("", test_data4
.init());
1023 boost::scoped_ptr
<AioCompletion
> my_completion4
1024 (test_data
.m_cluster
.aio_create_completion
1025 ((void*)&test_data4
, set_completion_completePP
, set_completion_safePP
));
1026 ASSERT_EQ(0, test_data
.m_ioctx
.aio_setxattr("foo_rmxattr", my_completion4
.get(), attr2
, bl22
));
1029 ASSERT_EQ(0, my_completion4
->wait_for_complete());
1031 ASSERT_EQ(0, my_completion4
->get_return_value());
1033 ASSERT_EQ(0, test_data
.m_ioctx
.remove("foo_rmxattr"));
1034 // async rmxattr on non existing object
1035 AioTestDataPP test_data5
;
1036 ASSERT_EQ("", test_data5
.init());
1037 boost::scoped_ptr
<AioCompletion
> my_completion5
1038 (test_data
.m_cluster
.aio_create_completion
1039 ((void*)&test_data5
, set_completion_completePP
, set_completion_safePP
));
1040 ASSERT_EQ(0, test_data
.m_ioctx
.aio_rmxattr("foo_rmxattr", my_completion5
.get(), attr2
));
1043 ASSERT_EQ(0, my_completion5
->wait_for_complete());
1045 ASSERT_EQ(-ENOENT
, my_completion5
->get_return_value());
1048 TEST(LibRadosAio
, XattrIter
) {
1049 AioTestData test_data
;
1050 ASSERT_EQ("", test_data
.init());
1051 // Create an object with 2 attributes
1053 char attr1
[] = "attr1";
1054 char attr1_buf
[] = "foo bar baz";
1055 char attr2
[] = "attr2";
1056 char attr2_buf
[256];
1057 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
1058 attr2_buf
[j
] = j
% 0xff;
1060 memset(buf
, 0xaa, sizeof(buf
));
1061 ASSERT_EQ(0, rados_append(test_data
.m_ioctx
, "foo", buf
, sizeof(buf
)));
1062 ASSERT_EQ(0, rados_setxattr(test_data
.m_ioctx
, "foo", attr1
, attr1_buf
, sizeof(attr1_buf
)));
1063 ASSERT_EQ(0, rados_setxattr(test_data
.m_ioctx
, "foo", attr2
, attr2_buf
, sizeof(attr2_buf
)));
1064 // call async version of getxattrs and wait for completion
1065 rados_completion_t my_completion
;
1066 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1067 set_completion_complete
, set_completion_safe
, &my_completion
));
1068 rados_xattrs_iter_t iter
;
1069 ASSERT_EQ(0, rados_aio_getxattrs(test_data
.m_ioctx
, "foo", my_completion
, &iter
));
1072 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1074 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1075 // loop over attributes
1081 ASSERT_EQ(0, rados_getxattrs_next(iter
, &name
, &val
, &len
));
1085 ASSERT_LT(num_seen
, 2);
1086 if ((strcmp(name
, attr1
) == 0) && (val
!= NULL
) && (memcmp(val
, attr1_buf
, len
) == 0)) {
1090 else if ((strcmp(name
, attr2
) == 0) && (val
!= NULL
) && (memcmp(val
, attr2_buf
, len
) == 0)) {
1098 rados_getxattrs_end(iter
);
1101 TEST(LibRadosIoPP
, XattrListPP
) {
1102 AioTestDataPP test_data
;
1103 ASSERT_EQ("", test_data
.init());
1104 // create an object with 2 attributes
1106 char attr1
[] = "attr1";
1107 char attr1_buf
[] = "foo bar baz";
1108 char attr2
[] = "attr2";
1109 char attr2_buf
[256];
1110 for (size_t j
= 0; j
< sizeof(attr2_buf
); ++j
) {
1111 attr2_buf
[j
] = j
% 0xff;
1113 memset(buf
, 0xaa, sizeof(buf
));
1115 bl1
.append(buf
, sizeof(buf
));
1116 ASSERT_EQ(0, test_data
.m_ioctx
.append("foo", bl1
, sizeof(buf
)));
1118 bl2
.append(attr1_buf
, sizeof(attr1_buf
));
1119 ASSERT_EQ(0, test_data
.m_ioctx
.setxattr("foo", attr1
, bl2
));
1121 bl3
.append(attr2_buf
, sizeof(attr2_buf
));
1122 ASSERT_EQ(0, test_data
.m_ioctx
.setxattr("foo", attr2
, bl3
));
1123 // call async version of getxattrs
1124 boost::scoped_ptr
<AioCompletion
> my_completion
1125 (test_data
.m_cluster
.aio_create_completion
1126 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
1127 std::map
<std::string
, bufferlist
> attrset
;
1128 ASSERT_EQ(0, test_data
.m_ioctx
.aio_getxattrs("foo", my_completion
.get(), attrset
));
1131 ASSERT_EQ(0, my_completion
->wait_for_complete());
1133 ASSERT_EQ(0, my_completion
->get_return_value());
1134 for (std::map
<std::string
, bufferlist
>::iterator i
= attrset
.begin();
1135 i
!= attrset
.end(); ++i
) {
1136 if (i
->first
== string(attr1
)) {
1137 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr1_buf
, sizeof(attr1_buf
)));
1139 else if (i
->first
== string(attr2
)) {
1140 ASSERT_EQ(0, memcmp(i
->second
.c_str(), attr2_buf
, sizeof(attr2_buf
)));
1148 TEST(LibRadosAio
, IsComplete
) {
1149 AioTestData test_data
;
1150 rados_completion_t my_completion
;
1151 ASSERT_EQ("", test_data
.init());
1152 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1153 set_completion_complete
, set_completion_safe
, &my_completion
));
1155 memset(buf
, 0xcc, sizeof(buf
));
1156 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1157 my_completion
, buf
, sizeof(buf
), 0));
1160 sem_wait(test_data
.m_sem
);
1161 sem_wait(test_data
.m_sem
);
1163 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1165 memset(buf2
, 0, sizeof(buf2
));
1166 rados_completion_t my_completion2
;
1167 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1168 set_completion_complete
, set_completion_safe
, &my_completion2
));
1169 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1170 my_completion2
, buf2
, sizeof(buf2
), 0));
1174 // Busy-wait until the AIO completes.
1175 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
1177 int is_complete
= rados_aio_is_complete(my_completion2
);
1182 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
1183 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1184 rados_aio_release(my_completion
);
1185 rados_aio_release(my_completion2
);
1188 TEST(LibRadosAio
, IsCompletePP
) {
1189 AioTestDataPP test_data
;
1190 ASSERT_EQ("", test_data
.init());
1191 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1192 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1193 AioCompletion
*my_completion_null
= NULL
;
1194 ASSERT_NE(my_completion
, my_completion_null
);
1196 memset(buf
, 0xcc, sizeof(buf
));
1198 bl1
.append(buf
, sizeof(buf
));
1199 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1200 bl1
, sizeof(buf
), 0));
1203 sem_wait(test_data
.m_sem
);
1204 sem_wait(test_data
.m_sem
);
1206 ASSERT_EQ(0, my_completion
->get_return_value());
1208 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1209 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1210 ASSERT_NE(my_completion2
, my_completion_null
);
1211 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1212 &bl2
, sizeof(buf
), 0));
1216 // Busy-wait until the AIO completes.
1217 // Normally we wouldn't do this, but we want to test is_complete.
1219 int is_complete
= my_completion2
->is_complete();
1224 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1225 ASSERT_EQ(sizeof(buf
), bl2
.length());
1226 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1227 delete my_completion
;
1228 delete my_completion2
;
1231 TEST(LibRadosAio
, IsSafe
) {
1232 AioTestData test_data
;
1233 rados_completion_t my_completion
;
1234 ASSERT_EQ("", test_data
.init());
1235 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1236 set_completion_complete
, set_completion_safe
, &my_completion
));
1238 memset(buf
, 0xcc, sizeof(buf
));
1239 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1240 my_completion
, buf
, sizeof(buf
), 0));
1244 // Busy-wait until the AIO completes.
1245 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1247 int is_safe
= rados_aio_is_safe(my_completion
);
1252 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1254 memset(buf2
, 0, sizeof(buf2
));
1255 rados_completion_t my_completion2
;
1256 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1257 set_completion_complete
, set_completion_safe
, &my_completion2
));
1258 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1259 my_completion2
, buf2
, sizeof(buf2
), 0));
1262 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1264 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
1265 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1266 rados_aio_release(my_completion
);
1267 rados_aio_release(my_completion2
);
1270 TEST(LibRadosAio
, IsSafePP
) {
1271 AioTestDataPP test_data
;
1272 ASSERT_EQ("", test_data
.init());
1273 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1274 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1275 AioCompletion
*my_completion_null
= NULL
;
1276 ASSERT_NE(my_completion
, my_completion_null
);
1278 memset(buf
, 0xcc, sizeof(buf
));
1280 bl1
.append(buf
, sizeof(buf
));
1281 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1282 bl1
, sizeof(buf
), 0));
1286 // Busy-wait until the AIO completes.
1287 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1289 int is_safe
= my_completion
->is_safe();
1294 ASSERT_EQ(0, my_completion
->get_return_value());
1295 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1296 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1298 ASSERT_NE(my_completion2
, my_completion_null
);
1299 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1300 &bl2
, sizeof(buf
), 0));
1303 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1305 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1306 ASSERT_EQ(sizeof(buf
), bl2
.length());
1307 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1308 delete my_completion
;
1309 delete my_completion2
;
1312 TEST(LibRadosAio
, ReturnValue
) {
1313 AioTestData test_data
;
1314 rados_completion_t my_completion
;
1315 ASSERT_EQ("", test_data
.init());
1316 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1317 set_completion_complete
, set_completion_safe
, &my_completion
));
1319 memset(buf
, 0, sizeof(buf
));
1320 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "nonexistent",
1321 my_completion
, buf
, sizeof(buf
), 0));
1324 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1326 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion
));
1327 rados_aio_release(my_completion
);
1330 TEST(LibRadosAio
, ReturnValuePP
) {
1331 AioTestDataPP test_data
;
1332 ASSERT_EQ("", test_data
.init());
1333 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1334 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1335 AioCompletion
*my_completion_null
= NULL
;
1336 ASSERT_NE(my_completion
, my_completion_null
);
1338 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("nonexistent",
1339 my_completion
, &bl1
, 128, 0));
1342 ASSERT_EQ(0, my_completion
->wait_for_complete());
1344 ASSERT_EQ(-ENOENT
, my_completion
->get_return_value());
1345 delete my_completion
;
1348 TEST(LibRadosAio
, Flush
) {
1349 AioTestData test_data
;
1350 rados_completion_t my_completion
;
1351 ASSERT_EQ("", test_data
.init());
1352 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1353 set_completion_complete
, set_completion_safe
, &my_completion
));
1355 memset(buf
, 0xee, sizeof(buf
));
1356 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1357 my_completion
, buf
, sizeof(buf
), 0));
1358 ASSERT_EQ(0, rados_aio_flush(test_data
.m_ioctx
));
1359 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1361 memset(buf2
, 0, sizeof(buf2
));
1362 rados_completion_t my_completion2
;
1363 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1364 set_completion_complete
, set_completion_safe
, &my_completion2
));
1365 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1366 my_completion2
, buf2
, sizeof(buf2
), 0));
1369 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1371 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
1372 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1373 rados_aio_release(my_completion
);
1374 rados_aio_release(my_completion2
);
1377 TEST(LibRadosAio
, FlushPP
) {
1378 AioTestDataPP test_data
;
1379 ASSERT_EQ("", test_data
.init());
1380 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1381 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1382 AioCompletion
*my_completion_null
= NULL
;
1383 ASSERT_NE(my_completion
, my_completion_null
);
1385 memset(buf
, 0xee, sizeof(buf
));
1387 bl1
.append(buf
, sizeof(buf
));
1388 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1389 bl1
, sizeof(buf
), 0));
1390 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush());
1391 ASSERT_EQ(0, my_completion
->get_return_value());
1393 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1394 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1395 ASSERT_NE(my_completion2
, my_completion_null
);
1396 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1397 &bl2
, sizeof(buf
), 0));
1400 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1402 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1403 ASSERT_EQ(sizeof(buf
), bl2
.length());
1404 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1405 delete my_completion
;
1406 delete my_completion2
;
1409 TEST(LibRadosAio
, FlushAsync
) {
1410 AioTestData test_data
;
1411 rados_completion_t my_completion
;
1412 ASSERT_EQ("", test_data
.init());
1413 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1414 set_completion_complete
, set_completion_safe
, &my_completion
));
1415 rados_completion_t flush_completion
;
1416 ASSERT_EQ(0, rados_aio_create_completion(NULL
, NULL
, NULL
, &flush_completion
));
1418 memset(buf
, 0xee, sizeof(buf
));
1419 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1420 my_completion
, buf
, sizeof(buf
), 0));
1421 ASSERT_EQ(0, rados_aio_flush_async(test_data
.m_ioctx
, flush_completion
));
1424 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion
));
1425 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion
));
1427 ASSERT_EQ(1, rados_aio_is_complete(my_completion
));
1428 ASSERT_EQ(1, rados_aio_is_safe(my_completion
));
1429 ASSERT_EQ(1, rados_aio_is_complete(flush_completion
));
1430 ASSERT_EQ(1, rados_aio_is_safe(flush_completion
));
1431 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1433 memset(buf2
, 0, sizeof(buf2
));
1434 rados_completion_t my_completion2
;
1435 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1436 set_completion_complete
, set_completion_safe
, &my_completion2
));
1437 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1438 my_completion2
, buf2
, sizeof(buf2
), 0));
1441 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1443 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
1444 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
1445 rados_aio_release(my_completion
);
1446 rados_aio_release(my_completion2
);
1447 rados_aio_release(flush_completion
);
1450 TEST(LibRadosAio
, FlushAsyncPP
) {
1451 AioTestDataPP test_data
;
1452 ASSERT_EQ("", test_data
.init());
1453 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1454 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1455 AioCompletion
*flush_completion
=
1456 test_data
.m_cluster
.aio_create_completion(NULL
, NULL
, NULL
);
1457 AioCompletion
*my_completion_null
= NULL
;
1458 ASSERT_NE(my_completion
, my_completion_null
);
1460 memset(buf
, 0xee, sizeof(buf
));
1462 bl1
.append(buf
, sizeof(buf
));
1463 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1464 bl1
, sizeof(buf
), 0));
1465 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush_async(flush_completion
));
1468 ASSERT_EQ(0, flush_completion
->wait_for_complete());
1469 ASSERT_EQ(0, flush_completion
->wait_for_safe());
1471 ASSERT_EQ(1, my_completion
->is_complete());
1472 ASSERT_EQ(1, my_completion
->is_safe());
1473 ASSERT_EQ(1, flush_completion
->is_complete());
1474 ASSERT_EQ(1, flush_completion
->is_safe());
1475 ASSERT_EQ(0, my_completion
->get_return_value());
1477 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1478 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1479 ASSERT_NE(my_completion2
, my_completion_null
);
1480 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
1481 &bl2
, sizeof(buf
), 0));
1484 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1486 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
1487 ASSERT_EQ(sizeof(buf
), bl2
.length());
1488 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
1489 delete my_completion
;
1490 delete my_completion2
;
1491 delete flush_completion
;
1494 TEST(LibRadosAio
, RoundTripWriteFull
) {
1495 AioTestData test_data
;
1496 rados_completion_t my_completion
, my_completion2
, my_completion3
;
1497 ASSERT_EQ("", test_data
.init());
1498 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1499 set_completion_complete
, set_completion_safe
, &my_completion
));
1501 memset(buf
, 0xcc, sizeof(buf
));
1502 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1503 my_completion
, buf
, sizeof(buf
), 0));
1506 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1508 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1510 memset(buf2
, 0xdd, sizeof(buf2
));
1511 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1512 set_completion_complete
, set_completion_safe
, &my_completion2
));
1513 ASSERT_EQ(0, rados_aio_write_full(test_data
.m_ioctx
, "foo",
1514 my_completion2
, buf2
, sizeof(buf2
)));
1517 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1519 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1520 char buf3
[sizeof(buf
) + sizeof(buf2
)];
1521 memset(buf3
, 0, sizeof(buf3
));
1522 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1523 set_completion_complete
, set_completion_safe
, &my_completion3
));
1524 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1525 my_completion3
, buf3
, sizeof(buf3
), 0));
1528 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1530 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion3
));
1531 ASSERT_EQ(0, memcmp(buf3
, buf2
, sizeof(buf2
)));
1532 rados_aio_release(my_completion
);
1533 rados_aio_release(my_completion2
);
1534 rados_aio_release(my_completion3
);
1537 TEST(LibRadosAio
, RoundTripWriteFullPP
) {
1538 AioTestDataPP test_data
;
1539 ASSERT_EQ("", test_data
.init());
1540 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1541 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1542 AioCompletion
*my_completion_null
= NULL
;
1543 ASSERT_NE(my_completion
, my_completion_null
);
1545 memset(buf
, 0xcc, sizeof(buf
));
1547 bl1
.append(buf
, sizeof(buf
));
1548 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1549 bl1
, sizeof(buf
), 0));
1552 ASSERT_EQ(0, my_completion
->wait_for_complete());
1554 ASSERT_EQ(0, my_completion
->get_return_value());
1556 memset(buf2
, 0xdd, sizeof(buf2
));
1558 bl2
.append(buf2
, sizeof(buf2
));
1559 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1560 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1561 ASSERT_NE(my_completion2
, my_completion_null
);
1562 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write_full("foo", my_completion2
, bl2
));
1565 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1567 ASSERT_EQ(0, my_completion2
->get_return_value());
1569 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
1570 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1571 ASSERT_NE(my_completion3
, my_completion_null
);
1572 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
1573 &bl3
, sizeof(buf
), 0));
1576 ASSERT_EQ(0, my_completion3
->wait_for_complete());
1578 ASSERT_EQ((int)sizeof(buf2
), my_completion3
->get_return_value());
1579 ASSERT_EQ(sizeof(buf2
), bl3
.length());
1580 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
1581 delete my_completion
;
1582 delete my_completion2
;
1583 delete my_completion3
;
1586 //using ObjectWriteOperation/ObjectReadOperation with iohint
1587 TEST(LibRadosAio
, RoundTripWriteFullPP2
)
1590 std::string pool_name
= get_temp_pool_name();
1591 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
1593 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
1595 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
1596 ObjectWriteOperation op
;
1598 memset(buf
, 0xcc, sizeof(buf
));
1603 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
1604 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
1607 ASSERT_EQ(0, my_completion1
->wait_for_complete());
1609 EXPECT_EQ(0, my_completion1
->get_return_value());
1611 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
1613 ObjectReadOperation op1
;
1614 op1
.read(0, sizeof(buf
), &bl
, NULL
);
1615 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
1616 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
1619 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1621 EXPECT_EQ(0, my_completion2
->get_return_value());
1622 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
1624 ioctx
.remove("test_obj");
1625 destroy_one_pool_pp(pool_name
, cluster
);
1628 TEST(LibRadosAio
, RoundTripWriteSame
) {
1629 AioTestData test_data
;
1630 rados_completion_t my_completion
, my_completion2
, my_completion3
;
1631 ASSERT_EQ("", test_data
.init());
1632 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1633 set_completion_complete
, set_completion_safe
, &my_completion
));
1635 memset(full
, 0xcc, sizeof(full
));
1636 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1637 my_completion
, full
, sizeof(full
), 0));
1640 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
1642 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1643 /* write the same buf four times */
1645 size_t ws_write_len
= sizeof(full
);
1646 memset(buf
, 0xdd, sizeof(buf
));
1647 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1648 set_completion_complete
, set_completion_safe
, &my_completion2
));
1649 ASSERT_EQ(0, rados_aio_writesame(test_data
.m_ioctx
, "foo",
1650 my_completion2
, buf
, sizeof(buf
),
1654 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1656 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1657 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1658 set_completion_complete
, set_completion_safe
, &my_completion3
));
1659 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
1660 my_completion3
, full
, sizeof(full
), 0));
1663 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1665 ASSERT_EQ((int)sizeof(full
), rados_aio_get_return_value(my_completion3
));
1666 for (char *cmp
= full
; cmp
< full
+ sizeof(full
); cmp
+= sizeof(buf
)) {
1667 ASSERT_EQ(0, memcmp(cmp
, buf
, sizeof(buf
)));
1669 rados_aio_release(my_completion
);
1670 rados_aio_release(my_completion2
);
1671 rados_aio_release(my_completion3
);
1674 TEST(LibRadosAio
, RoundTripWriteSamePP
) {
1675 AioTestDataPP test_data
;
1676 ASSERT_EQ("", test_data
.init());
1677 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1678 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1679 AioCompletion
*my_completion_null
= NULL
;
1680 ASSERT_NE(my_completion
, my_completion_null
);
1682 memset(full
, 0xcc, sizeof(full
));
1684 bl1
.append(full
, sizeof(full
));
1685 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1686 bl1
, sizeof(full
), 0));
1689 ASSERT_EQ(0, my_completion
->wait_for_complete());
1691 ASSERT_EQ(0, my_completion
->get_return_value());
1692 /* write the same buf four times */
1694 size_t ws_write_len
= sizeof(full
);
1695 memset(buf
, 0xdd, sizeof(buf
));
1697 bl2
.append(buf
, sizeof(buf
));
1698 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1699 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1700 ASSERT_NE(my_completion2
, my_completion_null
);
1701 ASSERT_EQ(0, test_data
.m_ioctx
.aio_writesame("foo", my_completion2
, bl2
,
1705 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1707 ASSERT_EQ(0, my_completion2
->get_return_value());
1709 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
1710 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1711 ASSERT_NE(my_completion3
, my_completion_null
);
1712 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
1713 &bl3
, sizeof(full
), 0));
1716 ASSERT_EQ(0, my_completion3
->wait_for_complete());
1718 ASSERT_EQ((int)sizeof(full
), my_completion3
->get_return_value());
1719 ASSERT_EQ(sizeof(full
), bl3
.length());
1720 for (char *cmp
= bl3
.c_str(); cmp
< bl3
.c_str() + bl3
.length();
1721 cmp
+= sizeof(buf
)) {
1722 ASSERT_EQ(0, memcmp(cmp
, buf
, sizeof(buf
)));
1724 delete my_completion
;
1725 delete my_completion2
;
1726 delete my_completion3
;
1729 TEST(LibRadosAio
, RoundTripWriteSamePP2
)
1732 std::string pool_name
= get_temp_pool_name();
1733 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
1735 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
1737 boost::scoped_ptr
<AioCompletion
>
1738 wr_cmpl(cluster
.aio_create_completion(0, 0, 0));
1739 ObjectWriteOperation op
;
1741 memset(buf
, 0xcc, sizeof(buf
));
1743 bl
.append(buf
, sizeof(buf
));
1745 op
.writesame(0, sizeof(buf
) * 4, bl
);
1746 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
1747 ioctx
.aio_operate("test_obj", wr_cmpl
.get(), &op
);
1750 ASSERT_EQ(0, wr_cmpl
->wait_for_complete());
1752 EXPECT_EQ(0, wr_cmpl
->get_return_value());
1754 boost::scoped_ptr
<AioCompletion
>
1755 rd_cmpl(cluster
.aio_create_completion(0, 0, 0));
1757 char full
[sizeof(buf
) * 4];
1758 memset(full
, 0, sizeof(full
));
1760 fl
.append(full
, sizeof(full
));
1761 ObjectReadOperation op1
;
1762 op1
.read(0, sizeof(full
), &fl
, NULL
);
1763 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
1764 ioctx
.aio_operate("test_obj", rd_cmpl
.get(), &op1
, 0);
1767 ASSERT_EQ(0, rd_cmpl
->wait_for_complete());
1769 EXPECT_EQ(0, rd_cmpl
->get_return_value());
1770 for (cmp
= fl
.c_str(); cmp
< fl
.c_str() + fl
.length(); cmp
+= sizeof(buf
)) {
1771 ASSERT_EQ(0, memcmp(cmp
, buf
, sizeof(buf
)));
1774 ioctx
.remove("test_obj");
1775 destroy_one_pool_pp(pool_name
, cluster
);
1778 TEST(LibRadosAio
, SimpleStat
) {
1779 AioTestData test_data
;
1780 rados_completion_t my_completion
;
1781 ASSERT_EQ("", test_data
.init());
1782 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1783 set_completion_complete
, set_completion_safe
, &my_completion
));
1785 memset(buf
, 0xcc, sizeof(buf
));
1786 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1787 my_completion
, buf
, sizeof(buf
), 0));
1790 sem_wait(test_data
.m_sem
);
1791 sem_wait(test_data
.m_sem
);
1793 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1796 rados_completion_t my_completion2
;
1797 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1798 set_completion_complete
, set_completion_safe
, &my_completion2
));
1799 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1800 my_completion2
, &psize
, &pmtime
));
1803 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1805 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1806 ASSERT_EQ(sizeof(buf
), psize
);
1807 rados_aio_release(my_completion
);
1808 rados_aio_release(my_completion2
);
1811 TEST(LibRadosAio
, SimpleStatPP
) {
1812 AioTestDataPP test_data
;
1813 ASSERT_EQ("", test_data
.init());
1814 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1815 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1816 AioCompletion
*my_completion_null
= NULL
;
1817 ASSERT_NE(my_completion
, my_completion_null
);
1819 memset(buf
, 0xcc, sizeof(buf
));
1821 bl1
.append(buf
, sizeof(buf
));
1822 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1823 bl1
, sizeof(buf
), 0));
1826 sem_wait(test_data
.m_sem
);
1827 sem_wait(test_data
.m_sem
);
1829 ASSERT_EQ(0, my_completion
->get_return_value());
1832 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1833 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1834 ASSERT_NE(my_completion2
, my_completion_null
);
1835 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
1839 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1841 ASSERT_EQ(0, my_completion2
->get_return_value());
1842 ASSERT_EQ(sizeof(buf
), psize
);
1843 delete my_completion
;
1844 delete my_completion2
;
1847 TEST(LibRadosAio
, SimpleStatNS
) {
1848 AioTestData test_data
;
1849 rados_completion_t my_completion
;
1850 ASSERT_EQ("", test_data
.init());
1851 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1852 set_completion_complete
, set_completion_safe
, &my_completion
));
1854 memset(buf
, 0xcc, sizeof(buf
));
1855 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1856 my_completion
, buf
, sizeof(buf
), 0));
1859 sem_wait(test_data
.m_sem
);
1860 sem_wait(test_data
.m_sem
);
1862 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1863 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
1865 memset(buf2
, 0xbb, sizeof(buf2
));
1866 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1867 set_completion_complete
, set_completion_safe
, &my_completion
));
1868 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1869 my_completion
, buf2
, sizeof(buf2
), 0));
1872 sem_wait(test_data
.m_sem
);
1873 sem_wait(test_data
.m_sem
);
1875 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1878 rados_completion_t my_completion2
;
1879 rados_ioctx_set_namespace(test_data
.m_ioctx
, "");
1880 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1881 set_completion_complete
, set_completion_safe
, &my_completion2
));
1882 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1883 my_completion2
, &psize
, &pmtime
));
1886 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1888 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1889 ASSERT_EQ(sizeof(buf
), psize
);
1891 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
1892 rados_completion_t my_completion3
;
1893 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1894 set_completion_complete
, set_completion_safe
, &my_completion3
));
1895 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1896 my_completion3
, &psize
, &pmtime
));
1899 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1901 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
1902 ASSERT_EQ(sizeof(buf2
), psize
);
1904 rados_aio_release(my_completion
);
1905 rados_aio_release(my_completion2
);
1906 rados_aio_release(my_completion3
);
1909 TEST(LibRadosAio
, SimpleStatPPNS
) {
1910 AioTestDataPP test_data
;
1911 ASSERT_EQ("", test_data
.init());
1912 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
1913 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1914 AioCompletion
*my_completion_null
= NULL
;
1915 ASSERT_NE(my_completion
, my_completion_null
);
1917 memset(buf
, 0xcc, sizeof(buf
));
1919 bl1
.append(buf
, sizeof(buf
));
1920 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
1921 bl1
, sizeof(buf
), 0));
1924 sem_wait(test_data
.m_sem
);
1925 sem_wait(test_data
.m_sem
);
1927 ASSERT_EQ(0, my_completion
->get_return_value());
1930 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
1931 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
1932 ASSERT_NE(my_completion2
, my_completion_null
);
1933 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
1937 ASSERT_EQ(0, my_completion2
->wait_for_complete());
1939 ASSERT_EQ(0, my_completion2
->get_return_value());
1940 ASSERT_EQ(sizeof(buf
), psize
);
1941 delete my_completion
;
1942 delete my_completion2
;
1945 TEST(LibRadosAio
, StatRemove
) {
1946 AioTestData test_data
;
1947 rados_completion_t my_completion
;
1948 ASSERT_EQ("", test_data
.init());
1949 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1950 set_completion_complete
, set_completion_safe
, &my_completion
));
1952 memset(buf
, 0xcc, sizeof(buf
));
1953 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
1954 my_completion
, buf
, sizeof(buf
), 0));
1957 sem_wait(test_data
.m_sem
);
1958 sem_wait(test_data
.m_sem
);
1960 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
1963 rados_completion_t my_completion2
;
1964 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1965 set_completion_complete
, set_completion_safe
, &my_completion2
));
1966 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1967 my_completion2
, &psize
, &pmtime
));
1970 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
1972 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
1973 ASSERT_EQ(sizeof(buf
), psize
);
1974 rados_completion_t my_completion3
;
1975 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1976 set_completion_complete
, set_completion_safe
, &my_completion3
));
1977 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion3
));
1980 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
1982 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
1985 rados_completion_t my_completion4
;
1986 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
1987 set_completion_complete
, set_completion_safe
, &my_completion4
));
1988 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
1989 my_completion4
, &psize2
, &pmtime2
));
1992 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
1994 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion4
));
1995 rados_aio_release(my_completion
);
1996 rados_aio_release(my_completion2
);
1997 rados_aio_release(my_completion3
);
1998 rados_aio_release(my_completion4
);
2001 TEST(LibRadosAio
, StatRemovePP
) {
2002 AioTestDataPP test_data
;
2003 ASSERT_EQ("", test_data
.init());
2004 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2005 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2006 AioCompletion
*my_completion_null
= NULL
;
2007 ASSERT_NE(my_completion
, my_completion_null
);
2009 memset(buf
, 0xcc, sizeof(buf
));
2011 bl1
.append(buf
, sizeof(buf
));
2012 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2013 bl1
, sizeof(buf
), 0));
2016 sem_wait(test_data
.m_sem
);
2017 sem_wait(test_data
.m_sem
);
2019 ASSERT_EQ(0, my_completion
->get_return_value());
2022 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2023 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2024 ASSERT_NE(my_completion2
, my_completion_null
);
2025 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
2029 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2031 ASSERT_EQ(0, my_completion2
->get_return_value());
2032 ASSERT_EQ(sizeof(buf
), psize
);
2035 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
2036 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2037 ASSERT_NE(my_completion3
, my_completion_null
);
2038 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion3
));
2041 ASSERT_EQ(0, my_completion3
->wait_for_complete());
2043 ASSERT_EQ(0, my_completion3
->get_return_value());
2045 AioCompletion
*my_completion4
= test_data
.m_cluster
.aio_create_completion(
2046 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2047 ASSERT_NE(my_completion4
, my_completion_null
);
2048 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion4
,
2049 &psize2
, &pmtime2
));
2052 ASSERT_EQ(0, my_completion4
->wait_for_complete());
2054 ASSERT_EQ(-ENOENT
, my_completion4
->get_return_value());
2055 delete my_completion
;
2056 delete my_completion2
;
2057 delete my_completion3
;
2058 delete my_completion4
;
2061 TEST(LibRadosAio
, ExecuteClass
) {
2062 AioTestData test_data
;
2063 rados_completion_t my_completion
;
2064 ASSERT_EQ("", test_data
.init());
2065 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2066 set_completion_complete
, set_completion_safe
, &my_completion
));
2068 memset(buf
, 0xcc, sizeof(buf
));
2069 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2070 my_completion
, buf
, sizeof(buf
), 0));
2073 sem_wait(test_data
.m_sem
);
2074 sem_wait(test_data
.m_sem
);
2076 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2077 rados_completion_t my_completion2
;
2078 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2079 set_completion_complete
, set_completion_safe
, &my_completion2
));
2081 ASSERT_EQ(0, rados_aio_exec(test_data
.m_ioctx
, "foo", my_completion2
,
2082 "hello", "say_hello", NULL
, 0, out
, sizeof(out
)));
2085 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2087 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2
));
2088 ASSERT_EQ(0, strncmp("Hello, world!", out
, 13));
2089 rados_aio_release(my_completion
);
2090 rados_aio_release(my_completion2
);
2093 TEST(LibRadosAio
, ExecuteClassPP
) {
2094 AioTestDataPP test_data
;
2095 ASSERT_EQ("", test_data
.init());
2096 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2097 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2098 AioCompletion
*my_completion_null
= NULL
;
2099 ASSERT_NE(my_completion
, my_completion_null
);
2101 memset(buf
, 0xcc, sizeof(buf
));
2103 bl1
.append(buf
, sizeof(buf
));
2104 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2105 bl1
, sizeof(buf
), 0));
2108 sem_wait(test_data
.m_sem
);
2109 sem_wait(test_data
.m_sem
);
2111 ASSERT_EQ(0, my_completion
->get_return_value());
2112 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2113 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2114 ASSERT_NE(my_completion2
, my_completion_null
);
2116 ASSERT_EQ(0, test_data
.m_ioctx
.aio_exec("foo", my_completion2
,
2117 "hello", "say_hello", in
, &out
));
2120 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2122 ASSERT_EQ(0, my_completion2
->get_return_value());
2123 ASSERT_EQ(std::string("Hello, world!"), std::string(out
.c_str(), out
.length()));
2124 delete my_completion
;
2125 delete my_completion2
;
2132 TEST(LibRadosAio
, OmapPP
) {
2134 std::string pool_name
= get_temp_pool_name();
2135 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
2137 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
2139 string header_str
= "baz";
2140 bufferptr
bp(header_str
.c_str(), header_str
.size() + 1);
2141 bufferlist header_to_set
;
2142 header_to_set
.push_back(bp
);
2143 map
<string
, bufferlist
> to_set
;
2145 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2146 ObjectWriteOperation op
;
2147 to_set
["foo"] = header_to_set
;
2148 to_set
["foo2"] = header_to_set
;
2149 to_set
["qfoo3"] = header_to_set
;
2150 op
.omap_set(to_set
);
2152 op
.omap_set_header(header_to_set
);
2154 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
2157 ASSERT_EQ(0, my_completion
->wait_for_complete());
2159 EXPECT_EQ(0, my_completion
->get_return_value());
2163 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2164 ObjectReadOperation op
;
2165 map
<string
, pair
<bufferlist
, int> > assertions
;
2167 val
.append(string("bar"));
2168 assertions
["foo"] = pair
<bufferlist
, int>(val
, CEPH_OSD_CMPXATTR_OP_EQ
);
2171 op
.omap_cmp(assertions
, &r
);
2173 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2176 ASSERT_EQ(0, my_completion
->wait_for_complete());
2178 EXPECT_EQ(-ECANCELED
, my_completion
->get_return_value());
2179 ASSERT_EQ(-ECANCELED
, r
);
2183 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2184 ObjectReadOperation op
;
2186 set
<string
> set_got
;
2187 map
<string
, bufferlist
> map_got
;
2190 map
<string
, bufferlist
> got3
;
2192 map
<string
, bufferlist
> got4
;
2196 op
.omap_get_keys2("", 1, &set_got
, nullptr, 0);
2197 op
.omap_get_vals2("foo", 1, &map_got
, nullptr, 0);
2199 to_get
.insert("foo");
2200 to_get
.insert("qfoo3");
2201 op
.omap_get_vals_by_keys(to_get
, &got3
, 0);
2203 op
.omap_get_header(&header
, 0);
2205 op
.omap_get_vals2("foo2", "q", 1, &got4
, nullptr, 0);
2207 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2210 ASSERT_EQ(0, my_completion
->wait_for_complete());
2212 EXPECT_EQ(0, my_completion
->get_return_value());
2214 ASSERT_EQ(header
.length(), header_to_set
.length());
2215 ASSERT_EQ(set_got
.size(), (unsigned)1);
2216 ASSERT_EQ(*set_got
.begin(), "foo");
2217 ASSERT_EQ(map_got
.size(), (unsigned)1);
2218 ASSERT_EQ(map_got
.begin()->first
, "foo2");
2219 ASSERT_EQ(got3
.size(), (unsigned)2);
2220 ASSERT_EQ(got3
.begin()->first
, "foo");
2221 ASSERT_EQ(got3
.rbegin()->first
, "qfoo3");
2222 ASSERT_EQ(got4
.size(), (unsigned)1);
2223 ASSERT_EQ(got4
.begin()->first
, "qfoo3");
2227 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2228 ObjectWriteOperation op
;
2229 set
<string
> to_remove
;
2230 to_remove
.insert("foo2");
2231 op
.omap_rm_keys(to_remove
);
2232 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
2235 ASSERT_EQ(0, my_completion
->wait_for_complete());
2237 EXPECT_EQ(0, my_completion
->get_return_value());
2241 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2242 ObjectReadOperation op
;
2244 set
<string
> set_got
;
2245 op
.omap_get_keys2("", -1, &set_got
, nullptr, 0);
2246 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2249 ASSERT_EQ(0, my_completion
->wait_for_complete());
2251 EXPECT_EQ(0, my_completion
->get_return_value());
2252 ASSERT_EQ(set_got
.size(), (unsigned)2);
2256 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2257 ObjectWriteOperation op
;
2259 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
2262 ASSERT_EQ(0, my_completion
->wait_for_complete());
2264 EXPECT_EQ(0, my_completion
->get_return_value());
2268 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2269 ObjectReadOperation op
;
2271 set
<string
> set_got
;
2272 op
.omap_get_keys2("", -1, &set_got
, nullptr, 0);
2273 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
, 0);
2276 ASSERT_EQ(0, my_completion
->wait_for_complete());
2278 EXPECT_EQ(0, my_completion
->get_return_value());
2279 ASSERT_EQ(set_got
.size(), (unsigned)0);
2282 // omap_clear clears header *and* keys
2284 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2285 ObjectWriteOperation op
;
2287 bl
.append("some data");
2288 map
<string
,bufferlist
> to_set
;
2290 to_set
["foo2"] = bl
;
2291 to_set
["qfoo3"] = bl
;
2292 op
.omap_set(to_set
);
2293 op
.omap_set_header(bl
);
2294 ioctx
.aio_operate("foo3", my_completion
.get(), &op
);
2297 ASSERT_EQ(0, my_completion
->wait_for_complete());
2299 EXPECT_EQ(0, my_completion
->get_return_value());
2302 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2303 ObjectWriteOperation op
;
2305 ioctx
.aio_operate("foo3", my_completion
.get(), &op
);
2308 ASSERT_EQ(0, my_completion
->wait_for_complete());
2310 EXPECT_EQ(0, my_completion
->get_return_value());
2313 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
2314 ObjectReadOperation op
;
2315 set
<string
> set_got
;
2317 op
.omap_get_keys2("", -1, &set_got
, nullptr, 0);
2318 op
.omap_get_header(&hdr
, NULL
);
2319 ioctx
.aio_operate("foo3", my_completion
.get(), &op
, 0);
2322 ASSERT_EQ(0, my_completion
->wait_for_complete());
2324 EXPECT_EQ(0, my_completion
->get_return_value());
2325 ASSERT_EQ(set_got
.size(), (unsigned)0);
2326 ASSERT_EQ(hdr
.length(), 0u);
2329 ioctx
.remove("test_obj");
2330 destroy_one_pool_pp(pool_name
, cluster
);
2333 TEST(LibRadosAio
, MultiWrite
) {
2334 AioTestData test_data
;
2335 rados_completion_t my_completion
, my_completion2
, my_completion3
;
2336 ASSERT_EQ("", test_data
.init());
2337 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2338 set_completion_complete
, set_completion_safe
, &my_completion
));
2340 memset(buf
, 0xcc, sizeof(buf
));
2341 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2342 my_completion
, buf
, sizeof(buf
), 0));
2345 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
2347 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2350 memset(buf2
, 0xdd, sizeof(buf2
));
2351 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2352 set_completion_complete
, set_completion_safe
, &my_completion2
));
2353 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2354 my_completion2
, buf2
, sizeof(buf2
), sizeof(buf
)));
2357 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2359 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
2361 char buf3
[(sizeof(buf
) + sizeof(buf2
)) * 3];
2362 memset(buf3
, 0, sizeof(buf3
));
2363 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2364 set_completion_complete
, set_completion_safe
, &my_completion3
));
2365 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2366 my_completion3
, buf3
, sizeof(buf3
), 0));
2369 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
2371 ASSERT_EQ((int)(sizeof(buf
) + sizeof(buf2
)), rados_aio_get_return_value(my_completion3
));
2372 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
2373 ASSERT_EQ(0, memcmp(buf3
+ sizeof(buf
), buf2
, sizeof(buf2
)));
2374 rados_aio_release(my_completion
);
2375 rados_aio_release(my_completion2
);
2376 rados_aio_release(my_completion3
);
2379 TEST(LibRadosAio
, MultiWritePP
) {
2380 AioTestDataPP test_data
;
2381 ASSERT_EQ("", test_data
.init());
2382 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2383 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2384 AioCompletion
*my_completion_null
= NULL
;
2385 ASSERT_NE(my_completion
, my_completion_null
);
2387 memset(buf
, 0xcc, sizeof(buf
));
2389 bl1
.append(buf
, sizeof(buf
));
2390 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2391 bl1
, sizeof(buf
), 0));
2394 ASSERT_EQ(0, my_completion
->wait_for_complete());
2396 ASSERT_EQ(0, my_completion
->get_return_value());
2399 memset(buf2
, 0xdd, sizeof(buf2
));
2401 bl2
.append(buf2
, sizeof(buf2
));
2402 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2403 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2404 ASSERT_NE(my_completion2
, my_completion_null
);
2405 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion2
,
2406 bl2
, sizeof(buf2
), sizeof(buf
)));
2409 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2411 ASSERT_EQ(0, my_completion2
->get_return_value());
2414 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
2415 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
2416 ASSERT_NE(my_completion3
, my_completion_null
);
2417 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
2418 &bl3
, (sizeof(buf
) + sizeof(buf2
) * 3), 0));
2421 ASSERT_EQ(0, my_completion3
->wait_for_complete());
2423 ASSERT_EQ((int)(sizeof(buf
) + sizeof(buf2
)), my_completion3
->get_return_value());
2424 ASSERT_EQ(sizeof(buf
) + sizeof(buf2
), bl3
.length());
2425 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, sizeof(buf
)));
2426 ASSERT_EQ(0, memcmp(bl3
.c_str() + sizeof(buf
), buf2
, sizeof(buf2
)));
2427 delete my_completion
;
2428 delete my_completion2
;
2429 delete my_completion3
;
2432 TEST(LibRadosAio
, AioUnlock
) {
2433 AioTestData test_data
;
2434 ASSERT_EQ("", test_data
.init());
2435 ASSERT_EQ(0, rados_lock_exclusive(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", "", NULL
, 0));
2436 rados_completion_t my_completion
;
2437 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2438 set_completion_complete
, set_completion_safe
, &my_completion
));
2439 ASSERT_EQ(0, rados_aio_unlock(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", my_completion
));
2442 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
2444 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2445 ASSERT_EQ(0, rados_lock_exclusive(test_data
.m_ioctx
, "foo", "TestLock", "Cookie", "", NULL
, 0));
2448 TEST(LibRadosAio
, AioUnlockPP
) {
2449 AioTestDataPP test_data
;
2450 ASSERT_EQ("", test_data
.init());
2451 ASSERT_EQ(0, test_data
.m_ioctx
.lock_exclusive("foo", "TestLock", "Cookie", "", NULL
, 0));
2452 boost::scoped_ptr
<AioCompletion
> my_completion
2453 (test_data
.m_cluster
.aio_create_completion
2454 ((void*)&test_data
, set_completion_completePP
, set_completion_safePP
));
2455 ASSERT_EQ(0, test_data
.m_ioctx
.aio_unlock("foo", "TestLock", "Cookie", my_completion
.get()));
2458 ASSERT_EQ(0, my_completion
->wait_for_complete());
2460 ASSERT_EQ(0, my_completion
->get_return_value());
2462 ASSERT_EQ(0, test_data
.m_ioctx
.lock_exclusive("foo", "TestLock", "Cookie", "", NULL
, 0));
2481 rados_ioctx_destroy(m_ioctx
);
2482 destroy_one_ec_pool(m_pool_name
, &m_cluster
);
2490 if (SEM_FAILED
== (m_sem
= sem_open("/test_aio_sem", O_CREAT
, 0644, 0))) {
2493 oss
<< "sem_open failed: " << cpp_strerror(err
);
2496 m_pool_name
= get_temp_pool_name();
2497 std::string err
= create_one_ec_pool(m_pool_name
, &m_cluster
);
2501 oss
<< "create_one_ec_pool(" << m_pool_name
<< ") failed: error " << err
;
2504 ret
= rados_ioctx_create(m_cluster
, m_pool_name
.c_str(), &m_ioctx
);
2507 destroy_one_ec_pool(m_pool_name
, &m_cluster
);
2509 oss
<< "rados_ioctx_create failed: error " << ret
;
2518 rados_ioctx_t m_ioctx
;
2519 std::string m_pool_name
;
2525 class AioTestDataECPP
2539 destroy_one_ec_pool_pp(m_pool_name
, m_cluster
);
2547 if (SEM_FAILED
== (m_sem
= sem_open("/test_aio_sem", O_CREAT
, 0644, 0))) {
2550 oss
<< "sem_open failed: " << cpp_strerror(err
);
2553 m_pool_name
= get_temp_pool_name();
2554 std::string err
= create_one_ec_pool_pp(m_pool_name
, m_cluster
);
2558 oss
<< "create_one_ec_pool(" << m_pool_name
<< ") failed: error " << err
;
2561 ret
= m_cluster
.ioctx_create(m_pool_name
.c_str(), m_ioctx
);
2564 destroy_one_ec_pool_pp(m_pool_name
, m_cluster
);
2566 oss
<< "rados_ioctx_create failed: error " << ret
;
2576 std::string m_pool_name
;
2582 void set_completion_completeEC(rados_completion_t cb
, void *arg
)
2584 AioTestDataEC
*test
= static_cast<AioTestDataEC
*>(arg
);
2585 test
->m_complete
= true;
2586 sem_post(test
->m_sem
);
2589 void set_completion_safeEC(rados_completion_t cb
, void *arg
)
2591 AioTestDataEC
*test
= static_cast<AioTestDataEC
*>(arg
);
2592 test
->m_safe
= true;
2593 sem_post(test
->m_sem
);
2596 void set_completion_completeECPP(rados_completion_t cb
, void *arg
)
2598 AioTestDataECPP
*test
= static_cast<AioTestDataECPP
*>(arg
);
2599 test
->m_complete
= true;
2600 sem_post(test
->m_sem
);
2603 void set_completion_safeECPP(rados_completion_t cb
, void *arg
)
2605 AioTestDataECPP
*test
= static_cast<AioTestDataECPP
*>(arg
);
2606 test
->m_safe
= true;
2607 sem_post(test
->m_sem
);
2610 TEST(LibRadosAioEC
, SimpleWrite
) {
2611 AioTestDataEC test_data
;
2612 rados_completion_t my_completion
;
2613 ASSERT_EQ("", test_data
.init());
2614 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2615 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2617 memset(buf
, 0xcc, sizeof(buf
));
2618 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2619 my_completion
, buf
, sizeof(buf
), 0));
2622 sem_wait(test_data
.m_sem
);
2623 sem_wait(test_data
.m_sem
);
2625 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2627 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
2628 rados_completion_t my_completion2
;
2629 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2630 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2631 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2632 my_completion2
, buf
, sizeof(buf
), 0));
2635 sem_wait(test_data
.m_sem
);
2636 sem_wait(test_data
.m_sem
);
2638 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
2639 rados_aio_release(my_completion
);
2640 rados_aio_release(my_completion2
);
2643 TEST(LibRadosAioEC
, SimpleWritePP
) {
2645 memset(buf
, 0xcc, sizeof(buf
));
2647 bl1
.append(buf
, sizeof(buf
));
2649 AioTestDataECPP test_data
;
2650 ASSERT_EQ("", test_data
.init());
2651 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2652 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2653 AioCompletion
*my_completion_null
= NULL
;
2654 ASSERT_NE(my_completion
, my_completion_null
);
2655 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
2656 my_completion
, bl1
, sizeof(buf
), 0));
2659 sem_wait(test_data
.m_sem
);
2660 sem_wait(test_data
.m_sem
);
2662 ASSERT_EQ(0, my_completion
->get_return_value());
2663 delete my_completion
;
2667 AioTestDataECPP test_data
;
2668 ASSERT_EQ("", test_data
.init());
2669 test_data
.m_ioctx
.set_namespace("nspace");
2670 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2671 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2672 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
2673 my_completion
, bl1
, sizeof(buf
), 0));
2676 sem_wait(test_data
.m_sem
);
2677 sem_wait(test_data
.m_sem
);
2679 ASSERT_EQ(0, my_completion
->get_return_value());
2680 delete my_completion
;
2684 TEST(LibRadosAioEC
, WaitForSafe
) {
2685 AioTestDataEC test_data
;
2686 rados_completion_t my_completion
;
2687 ASSERT_EQ("", test_data
.init());
2688 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2689 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2691 memset(buf
, 0xcc, sizeof(buf
));
2692 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2693 my_completion
, buf
, sizeof(buf
), 0));
2695 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion
));
2696 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2697 rados_aio_release(my_completion
);
2700 TEST(LibRadosAioEC
, WaitForSafePP
) {
2701 AioTestDataECPP test_data
;
2702 ASSERT_EQ("", test_data
.init());
2703 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2704 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2705 AioCompletion
*my_completion_null
= NULL
;
2706 ASSERT_NE(my_completion
, my_completion_null
);
2708 memset(buf
, 0xcc, sizeof(buf
));
2710 bl1
.append(buf
, sizeof(buf
));
2711 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo",
2712 my_completion
, bl1
, sizeof(buf
), 0));
2714 ASSERT_EQ(0, my_completion
->wait_for_safe());
2715 ASSERT_EQ(0, my_completion
->get_return_value());
2716 delete my_completion
;
2719 TEST(LibRadosAioEC
, RoundTrip
) {
2720 AioTestDataEC test_data
;
2721 rados_completion_t my_completion
;
2722 ASSERT_EQ("", test_data
.init());
2723 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2724 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2726 memset(buf
, 0xcc, sizeof(buf
));
2727 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2728 my_completion
, buf
, sizeof(buf
), 0));
2731 sem_wait(test_data
.m_sem
);
2732 sem_wait(test_data
.m_sem
);
2734 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2736 memset(buf2
, 0, sizeof(buf2
));
2737 rados_completion_t my_completion2
;
2738 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2739 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2740 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2741 my_completion2
, buf2
, sizeof(buf2
), 0));
2744 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2746 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
2747 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
2748 rados_aio_release(my_completion
);
2749 rados_aio_release(my_completion2
);
2752 TEST(LibRadosAioEC
, RoundTrip2
) {
2753 AioTestDataEC test_data
;
2754 rados_completion_t my_completion
;
2755 ASSERT_EQ("", test_data
.init());
2756 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2757 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2759 memset(buf
, 0xcc, sizeof(buf
));
2760 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
2761 my_completion
, buf
, sizeof(buf
), 0));
2764 sem_wait(test_data
.m_sem
);
2765 sem_wait(test_data
.m_sem
);
2767 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2769 memset(buf2
, 0, sizeof(buf2
));
2770 rados_completion_t my_completion2
;
2771 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2772 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2773 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2774 my_completion2
, buf2
, sizeof(buf2
), 0));
2777 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2779 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
2780 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
2781 rados_aio_release(my_completion
);
2782 rados_aio_release(my_completion2
);
2785 TEST(LibRadosAioEC
, RoundTripPP
) {
2786 AioTestDataECPP test_data
;
2787 ASSERT_EQ("", test_data
.init());
2788 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2789 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2790 AioCompletion
*my_completion_null
= NULL
;
2791 ASSERT_NE(my_completion
, my_completion_null
);
2793 memset(buf
, 0xcc, sizeof(buf
));
2795 bl1
.append(buf
, sizeof(buf
));
2796 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2797 bl1
, sizeof(buf
), 0));
2800 sem_wait(test_data
.m_sem
);
2801 sem_wait(test_data
.m_sem
);
2803 ASSERT_EQ(0, my_completion
->get_return_value());
2805 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2806 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2807 ASSERT_NE(my_completion2
, my_completion_null
);
2808 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
2809 my_completion2
, &bl2
, sizeof(buf
), 0));
2812 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2814 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
2815 ASSERT_EQ(sizeof(buf
), bl2
.length());
2816 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
2817 delete my_completion
;
2818 delete my_completion2
;
2821 TEST(LibRadosAioEC
, RoundTripPP2
) {
2822 AioTestDataECPP test_data
;
2823 ASSERT_EQ("", test_data
.init());
2824 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2825 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2826 AioCompletion
*my_completion_null
= NULL
;
2827 ASSERT_NE(my_completion
, my_completion_null
);
2829 memset(buf
, 0xcc, sizeof(buf
));
2831 bl1
.append(buf
, sizeof(buf
));
2832 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2833 bl1
, sizeof(buf
), 0));
2836 sem_wait(test_data
.m_sem
);
2837 sem_wait(test_data
.m_sem
);
2839 ASSERT_EQ(0, my_completion
->get_return_value());
2841 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2842 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2843 ASSERT_NE(my_completion2
, my_completion_null
);
2844 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
2845 my_completion2
, &bl2
, sizeof(buf
), 0));
2848 ASSERT_EQ(0, my_completion2
->wait_for_safe());
2849 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2851 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
2852 ASSERT_EQ(sizeof(buf
), bl2
.length());
2853 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
2854 delete my_completion
;
2855 delete my_completion2
;
2858 //using ObjectWriteOperation/ObjectReadOperation with iohint
2859 TEST(LibRadosAioEC
, RoundTripPP3
)
2862 std::string pool_name
= get_temp_pool_name();
2863 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
2865 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
2867 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
2868 ObjectWriteOperation op
;
2870 memset(buf
, 0xcc, sizeof(buf
));
2875 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
2876 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
2879 ASSERT_EQ(0, my_completion1
->wait_for_complete());
2881 EXPECT_EQ(0, my_completion1
->get_return_value());
2883 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
2885 ObjectReadOperation op1
;
2886 op1
.read(0, sizeof(buf
), &bl
, NULL
);
2887 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
2888 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
2891 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2893 EXPECT_EQ(0, my_completion2
->get_return_value());
2894 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
2896 ioctx
.remove("test_obj");
2897 destroy_one_pool_pp(pool_name
, cluster
);
2900 TEST(LibRadosAioEC
, RoundTripSparseReadPP
) {
2901 AioTestDataECPP test_data
;
2902 ASSERT_EQ("", test_data
.init());
2903 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
2904 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2905 AioCompletion
*my_completion_null
= NULL
;
2906 ASSERT_NE(my_completion
, my_completion_null
);
2908 memset(buf
, 0xcc, sizeof(buf
));
2910 bl1
.append(buf
, sizeof(buf
));
2911 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
2912 bl1
, sizeof(buf
), 0));
2915 sem_wait(test_data
.m_sem
);
2916 sem_wait(test_data
.m_sem
);
2918 ASSERT_EQ(0, my_completion
->get_return_value());
2920 map
<uint64_t, uint64_t> extents
;
2922 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
2923 (void*)&test_data
, set_completion_completeECPP
, set_completion_safeECPP
);
2924 ASSERT_NE(my_completion2
, my_completion_null
);
2925 ASSERT_EQ(0, test_data
.m_ioctx
.aio_sparse_read("foo",
2926 my_completion2
, &extents
, &bl2
, sizeof(buf
), 0));
2929 ASSERT_EQ(0, my_completion2
->wait_for_complete());
2931 ASSERT_EQ(0, my_completion2
->get_return_value());
2932 assert_eq_sparse(bl1
, extents
, bl2
);
2933 delete my_completion
;
2934 delete my_completion2
;
2937 TEST(LibRadosAioEC
, RoundTripAppend
) {
2938 AioTestDataEC test_data
;
2939 rados_completion_t my_completion
, my_completion2
, my_completion3
, my_completion4
;
2940 ASSERT_EQ("", test_data
.init());
2941 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2942 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
2944 ASSERT_EQ(0, rados_ioctx_pool_requires_alignment2(test_data
.m_ioctx
, &requires
));
2945 ASSERT_NE(0, requires
);
2947 ASSERT_EQ(0, rados_ioctx_pool_required_alignment2(test_data
.m_ioctx
, &alignment
));
2948 ASSERT_NE(0U, alignment
);
2950 int bsize
= alignment
;
2951 char *buf
= (char *)new char[bsize
];
2952 memset(buf
, 0xcc, bsize
);
2953 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
2954 my_completion
, buf
, bsize
));
2957 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
2959 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
2961 int hbsize
= bsize
/ 2;
2962 char *buf2
= (char *)new char[hbsize
];
2963 memset(buf2
, 0xdd, hbsize
);
2964 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2965 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
2966 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
2967 my_completion2
, buf2
, hbsize
));
2970 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
2972 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
2974 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2975 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
2976 ASSERT_EQ(0, rados_aio_append(test_data
.m_ioctx
, "foo",
2977 my_completion3
, buf2
, hbsize
));
2980 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
2982 EXPECT_EQ(-EOPNOTSUPP
, rados_aio_get_return_value(my_completion3
));
2984 int tbsize
= bsize
+ hbsize
;
2985 char *buf3
= (char *)new char[tbsize
];
2986 memset(buf3
, 0, tbsize
);
2987 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
2988 set_completion_completeEC
, set_completion_safeEC
, &my_completion4
));
2989 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
2990 my_completion4
, buf3
, bsize
* 3, 0));
2993 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
2995 ASSERT_EQ(tbsize
, rados_aio_get_return_value(my_completion4
));
2996 ASSERT_EQ(0, memcmp(buf3
, buf
, bsize
));
2997 ASSERT_EQ(0, memcmp(buf3
+ bsize
, buf2
, hbsize
));
2998 rados_aio_release(my_completion
);
2999 rados_aio_release(my_completion2
);
3000 rados_aio_release(my_completion3
);
3001 rados_aio_release(my_completion4
);
3007 TEST(LibRadosAioEC
, RoundTripAppendPP
) {
3008 AioTestDataECPP test_data
;
3009 ASSERT_EQ("", test_data
.init());
3010 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3011 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3012 AioCompletion
*my_completion_null
= NULL
;
3013 ASSERT_NE(my_completion
, my_completion_null
);
3015 ASSERT_EQ(0, test_data
.m_ioctx
.pool_requires_alignment2(&requires
));
3016 ASSERT_TRUE(requires
);
3018 ASSERT_EQ(0, test_data
.m_ioctx
.pool_required_alignment2(&alignment
));
3019 ASSERT_NE((unsigned)0, alignment
);
3020 int bsize
= alignment
;
3021 char *buf
= (char *)new char[bsize
];
3022 memset(buf
, 0xcc, bsize
);
3024 bl1
.append(buf
, bsize
);
3025 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion
,
3029 ASSERT_EQ(0, my_completion
->wait_for_complete());
3031 ASSERT_EQ(0, my_completion
->get_return_value());
3033 int hbsize
= bsize
/ 2;
3034 char *buf2
= (char *)new char[hbsize
];
3035 memset(buf2
, 0xdd, hbsize
);
3037 bl2
.append(buf2
, hbsize
);
3038 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3039 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3040 ASSERT_NE(my_completion2
, my_completion_null
);
3041 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion2
,
3045 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3047 ASSERT_EQ(0, my_completion2
->get_return_value());
3049 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
3050 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3051 ASSERT_NE(my_completion3
, my_completion_null
);
3052 ASSERT_EQ(0, test_data
.m_ioctx
.aio_append("foo", my_completion3
,
3056 ASSERT_EQ(0, my_completion3
->wait_for_complete());
3058 EXPECT_EQ(-EOPNOTSUPP
, my_completion3
->get_return_value());
3061 AioCompletion
*my_completion4
= test_data
.m_cluster
.aio_create_completion(
3062 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3063 ASSERT_NE(my_completion4
, my_completion_null
);
3064 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo",
3065 my_completion4
, &bl3
, bsize
* 3, 0));
3068 ASSERT_EQ(0, my_completion4
->wait_for_complete());
3070 int tbsize
= bsize
+ hbsize
;
3071 ASSERT_EQ(tbsize
, my_completion4
->get_return_value());
3072 ASSERT_EQ((unsigned)tbsize
, bl3
.length());
3073 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, bsize
));
3074 ASSERT_EQ(0, memcmp(bl3
.c_str() + bsize
, buf2
, hbsize
));
3075 delete my_completion
;
3076 delete my_completion2
;
3077 delete my_completion3
;
3082 TEST(LibRadosAioEC
, IsComplete
) {
3083 AioTestDataEC test_data
;
3084 rados_completion_t my_completion
;
3085 ASSERT_EQ("", test_data
.init());
3086 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3087 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3089 memset(buf
, 0xcc, sizeof(buf
));
3090 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3091 my_completion
, buf
, sizeof(buf
), 0));
3094 sem_wait(test_data
.m_sem
);
3095 sem_wait(test_data
.m_sem
);
3097 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3099 memset(buf2
, 0, sizeof(buf2
));
3100 rados_completion_t my_completion2
;
3101 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3102 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3103 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3104 my_completion2
, buf2
, sizeof(buf2
), 0));
3108 // Busy-wait until the AIO completes.
3109 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
3111 int is_complete
= rados_aio_is_complete(my_completion2
);
3116 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
3117 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3118 rados_aio_release(my_completion
);
3119 rados_aio_release(my_completion2
);
3122 TEST(LibRadosAioEC
, IsCompletePP
) {
3123 AioTestDataECPP test_data
;
3124 ASSERT_EQ("", test_data
.init());
3125 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3126 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3127 AioCompletion
*my_completion_null
= NULL
;
3128 ASSERT_NE(my_completion
, my_completion_null
);
3130 memset(buf
, 0xcc, sizeof(buf
));
3132 bl1
.append(buf
, sizeof(buf
));
3133 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3134 bl1
, sizeof(buf
), 0));
3137 sem_wait(test_data
.m_sem
);
3138 sem_wait(test_data
.m_sem
);
3140 ASSERT_EQ(0, my_completion
->get_return_value());
3142 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3143 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3144 ASSERT_NE(my_completion2
, my_completion_null
);
3145 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3146 &bl2
, sizeof(buf
), 0));
3150 // Busy-wait until the AIO completes.
3151 // Normally we wouldn't do this, but we want to test is_complete.
3153 int is_complete
= my_completion2
->is_complete();
3158 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3159 ASSERT_EQ(sizeof(buf
), bl2
.length());
3160 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3161 delete my_completion
;
3162 delete my_completion2
;
3165 TEST(LibRadosAioEC
, IsSafe
) {
3166 AioTestDataEC test_data
;
3167 rados_completion_t my_completion
;
3168 ASSERT_EQ("", test_data
.init());
3169 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3170 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3172 memset(buf
, 0xcc, sizeof(buf
));
3173 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3174 my_completion
, buf
, sizeof(buf
), 0));
3178 // Busy-wait until the AIO completes.
3179 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
3181 int is_safe
= rados_aio_is_safe(my_completion
);
3186 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3188 memset(buf2
, 0, sizeof(buf2
));
3189 rados_completion_t my_completion2
;
3190 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3191 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3192 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3193 my_completion2
, buf2
, sizeof(buf2
), 0));
3196 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3198 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion2
));
3199 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3200 rados_aio_release(my_completion
);
3201 rados_aio_release(my_completion2
);
3204 TEST(LibRadosAioEC
, IsSafePP
) {
3205 AioTestDataECPP test_data
;
3206 ASSERT_EQ("", test_data
.init());
3207 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3208 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3209 AioCompletion
*my_completion_null
= NULL
;
3210 ASSERT_NE(my_completion
, my_completion_null
);
3212 memset(buf
, 0xcc, sizeof(buf
));
3214 bl1
.append(buf
, sizeof(buf
));
3215 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3216 bl1
, sizeof(buf
), 0));
3220 // Busy-wait until the AIO completes.
3221 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
3223 int is_safe
= my_completion
->is_safe();
3228 ASSERT_EQ(0, my_completion
->get_return_value());
3229 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3230 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3232 ASSERT_NE(my_completion2
, my_completion_null
);
3233 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3234 &bl2
, sizeof(buf
), 0));
3237 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3239 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3240 ASSERT_EQ(sizeof(buf
), bl2
.length());
3241 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3242 delete my_completion
;
3243 delete my_completion2
;
3246 TEST(LibRadosAioEC
, ReturnValue
) {
3247 AioTestDataEC test_data
;
3248 rados_completion_t my_completion
;
3249 ASSERT_EQ("", test_data
.init());
3250 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3251 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3253 memset(buf
, 0, sizeof(buf
));
3254 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "nonexistent",
3255 my_completion
, buf
, sizeof(buf
), 0));
3258 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
3260 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion
));
3261 rados_aio_release(my_completion
);
3264 TEST(LibRadosAioEC
, ReturnValuePP
) {
3265 AioTestDataECPP test_data
;
3266 ASSERT_EQ("", test_data
.init());
3267 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3268 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3269 AioCompletion
*my_completion_null
= NULL
;
3270 ASSERT_NE(my_completion
, my_completion_null
);
3272 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("nonexistent",
3273 my_completion
, &bl1
, 128, 0));
3276 ASSERT_EQ(0, my_completion
->wait_for_complete());
3278 ASSERT_EQ(-ENOENT
, my_completion
->get_return_value());
3279 delete my_completion
;
3282 TEST(LibRadosAioEC
, Flush
) {
3283 AioTestDataEC test_data
;
3284 rados_completion_t my_completion
;
3285 ASSERT_EQ("", test_data
.init());
3286 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3287 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3289 memset(buf
, 0xee, sizeof(buf
));
3290 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3291 my_completion
, buf
, sizeof(buf
), 0));
3292 ASSERT_EQ(0, rados_aio_flush(test_data
.m_ioctx
));
3293 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3295 memset(buf2
, 0, sizeof(buf2
));
3296 rados_completion_t my_completion2
;
3297 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3298 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3299 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3300 my_completion2
, buf2
, sizeof(buf2
), 0));
3303 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3305 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
3306 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3307 rados_aio_release(my_completion
);
3308 rados_aio_release(my_completion2
);
3311 TEST(LibRadosAioEC
, FlushPP
) {
3312 AioTestDataECPP test_data
;
3313 ASSERT_EQ("", test_data
.init());
3314 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3315 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3316 AioCompletion
*my_completion_null
= NULL
;
3317 ASSERT_NE(my_completion
, my_completion_null
);
3319 memset(buf
, 0xee, sizeof(buf
));
3321 bl1
.append(buf
, sizeof(buf
));
3322 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3323 bl1
, sizeof(buf
), 0));
3324 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush());
3325 ASSERT_EQ(0, my_completion
->get_return_value());
3327 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3328 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3329 ASSERT_NE(my_completion2
, my_completion_null
);
3330 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3331 &bl2
, sizeof(buf
), 0));
3334 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3336 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3337 ASSERT_EQ(sizeof(buf
), bl2
.length());
3338 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3339 delete my_completion
;
3340 delete my_completion2
;
3343 TEST(LibRadosAioEC
, FlushAsync
) {
3344 AioTestDataEC test_data
;
3345 rados_completion_t my_completion
;
3346 ASSERT_EQ("", test_data
.init());
3347 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3348 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3349 rados_completion_t flush_completion
;
3350 ASSERT_EQ(0, rados_aio_create_completion(NULL
, NULL
, NULL
, &flush_completion
));
3352 memset(buf
, 0xee, sizeof(buf
));
3353 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3354 my_completion
, buf
, sizeof(buf
), 0));
3355 ASSERT_EQ(0, rados_aio_flush_async(test_data
.m_ioctx
, flush_completion
));
3358 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion
));
3359 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion
));
3361 ASSERT_EQ(1, rados_aio_is_complete(my_completion
));
3362 ASSERT_EQ(1, rados_aio_is_safe(my_completion
));
3363 ASSERT_EQ(1, rados_aio_is_complete(flush_completion
));
3364 ASSERT_EQ(1, rados_aio_is_safe(flush_completion
));
3365 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3367 memset(buf2
, 0, sizeof(buf2
));
3368 rados_completion_t my_completion2
;
3369 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3370 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3371 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3372 my_completion2
, buf2
, sizeof(buf2
), 0));
3375 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3377 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion2
));
3378 ASSERT_EQ(0, memcmp(buf
, buf2
, sizeof(buf
)));
3379 rados_aio_release(my_completion
);
3380 rados_aio_release(my_completion2
);
3381 rados_aio_release(flush_completion
);
3384 TEST(LibRadosAioEC
, FlushAsyncPP
) {
3385 AioTestDataECPP test_data
;
3386 ASSERT_EQ("", test_data
.init());
3387 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3388 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3389 AioCompletion
*flush_completion
=
3390 test_data
.m_cluster
.aio_create_completion(NULL
, NULL
, NULL
);
3391 AioCompletion
*my_completion_null
= NULL
;
3392 ASSERT_NE(my_completion
, my_completion_null
);
3394 memset(buf
, 0xee, sizeof(buf
));
3396 bl1
.append(buf
, sizeof(buf
));
3397 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3398 bl1
, sizeof(buf
), 0));
3399 ASSERT_EQ(0, test_data
.m_ioctx
.aio_flush_async(flush_completion
));
3402 ASSERT_EQ(0, flush_completion
->wait_for_complete());
3403 ASSERT_EQ(0, flush_completion
->wait_for_safe());
3405 ASSERT_EQ(1, my_completion
->is_complete());
3406 ASSERT_EQ(1, my_completion
->is_safe());
3407 ASSERT_EQ(1, flush_completion
->is_complete());
3408 ASSERT_EQ(1, flush_completion
->is_safe());
3409 ASSERT_EQ(0, my_completion
->get_return_value());
3411 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3412 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3413 ASSERT_NE(my_completion2
, my_completion_null
);
3414 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion2
,
3415 &bl2
, sizeof(buf
), 0));
3418 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3420 ASSERT_EQ((int)sizeof(buf
), my_completion2
->get_return_value());
3421 ASSERT_EQ(sizeof(buf
), bl2
.length());
3422 ASSERT_EQ(0, memcmp(buf
, bl2
.c_str(), sizeof(buf
)));
3423 delete my_completion
;
3424 delete my_completion2
;
3425 delete flush_completion
;
3428 TEST(LibRadosAioEC
, RoundTripWriteFull
) {
3429 AioTestDataEC test_data
;
3430 rados_completion_t my_completion
, my_completion2
, my_completion3
;
3431 ASSERT_EQ("", test_data
.init());
3432 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3433 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3435 memset(buf
, 0xcc, sizeof(buf
));
3436 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3437 my_completion
, buf
, sizeof(buf
), 0));
3440 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
3442 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3444 memset(buf2
, 0xdd, sizeof(buf2
));
3445 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3446 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3447 ASSERT_EQ(0, rados_aio_write_full(test_data
.m_ioctx
, "foo",
3448 my_completion2
, buf2
, sizeof(buf2
)));
3451 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3453 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3454 char buf3
[sizeof(buf
) + sizeof(buf2
)];
3455 memset(buf3
, 0, sizeof(buf3
));
3456 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3457 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3458 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3459 my_completion3
, buf3
, sizeof(buf3
), 0));
3462 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3464 ASSERT_EQ((int)sizeof(buf2
), rados_aio_get_return_value(my_completion3
));
3465 ASSERT_EQ(0, memcmp(buf3
, buf2
, sizeof(buf2
)));
3466 rados_aio_release(my_completion
);
3467 rados_aio_release(my_completion2
);
3468 rados_aio_release(my_completion3
);
3471 TEST(LibRadosAioEC
, RoundTripWriteFullPP
) {
3472 AioTestDataECPP test_data
;
3473 ASSERT_EQ("", test_data
.init());
3474 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3475 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3476 AioCompletion
*my_completion_null
= NULL
;
3477 ASSERT_NE(my_completion
, my_completion_null
);
3479 memset(buf
, 0xcc, sizeof(buf
));
3481 bl1
.append(buf
, sizeof(buf
));
3482 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3483 bl1
, sizeof(buf
), 0));
3486 ASSERT_EQ(0, my_completion
->wait_for_complete());
3488 ASSERT_EQ(0, my_completion
->get_return_value());
3490 memset(buf2
, 0xdd, sizeof(buf2
));
3492 bl2
.append(buf2
, sizeof(buf2
));
3493 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3494 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3495 ASSERT_NE(my_completion2
, my_completion_null
);
3496 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write_full("foo", my_completion2
, bl2
));
3499 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3501 ASSERT_EQ(0, my_completion2
->get_return_value());
3503 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
3504 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3505 ASSERT_NE(my_completion3
, my_completion_null
);
3506 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
3507 &bl3
, sizeof(buf
), 0));
3510 ASSERT_EQ(0, my_completion3
->wait_for_complete());
3512 ASSERT_EQ((int)sizeof(buf2
), my_completion3
->get_return_value());
3513 ASSERT_EQ(sizeof(buf2
), bl3
.length());
3514 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf2
, sizeof(buf2
)));
3515 delete my_completion
;
3516 delete my_completion2
;
3517 delete my_completion3
;
3520 //using ObjectWriteOperation/ObjectReadOperation with iohint
3521 TEST(LibRadosAioEC
, RoundTripWriteFullPP2
)
3524 std::string pool_name
= get_temp_pool_name();
3525 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
3527 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
3529 boost::scoped_ptr
<AioCompletion
> my_completion1(cluster
.aio_create_completion(0, 0, 0));
3530 ObjectWriteOperation op
;
3532 memset(buf
, 0xcc, sizeof(buf
));
3537 op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE
);
3538 ioctx
.aio_operate("test_obj", my_completion1
.get(), &op
);
3541 ASSERT_EQ(0, my_completion1
->wait_for_complete());
3543 EXPECT_EQ(0, my_completion1
->get_return_value());
3545 boost::scoped_ptr
<AioCompletion
> my_completion2(cluster
.aio_create_completion(0, 0, 0));
3547 ObjectReadOperation op1
;
3548 op1
.read(0, sizeof(buf
), &bl
, NULL
);
3549 op1
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE
|LIBRADOS_OP_FLAG_FADVISE_RANDOM
);
3550 ioctx
.aio_operate("test_obj", my_completion2
.get(), &op1
, 0);
3553 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3555 EXPECT_EQ(0, my_completion2
->get_return_value());
3556 ASSERT_EQ(0, memcmp(buf
, bl
.c_str(), sizeof(buf
)));
3558 ioctx
.remove("test_obj");
3559 destroy_one_pool_pp(pool_name
, cluster
);
3562 TEST(LibRadosAioEC
, SimpleStat
) {
3563 AioTestDataEC test_data
;
3564 rados_completion_t my_completion
;
3565 ASSERT_EQ("", test_data
.init());
3566 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3567 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3569 memset(buf
, 0xcc, sizeof(buf
));
3570 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3571 my_completion
, buf
, sizeof(buf
), 0));
3574 sem_wait(test_data
.m_sem
);
3575 sem_wait(test_data
.m_sem
);
3577 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3580 rados_completion_t my_completion2
;
3581 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3582 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3583 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3584 my_completion2
, &psize
, &pmtime
));
3587 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3589 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3590 ASSERT_EQ(sizeof(buf
), psize
);
3591 rados_aio_release(my_completion
);
3592 rados_aio_release(my_completion2
);
3595 TEST(LibRadosAioEC
, SimpleStatPP
) {
3596 AioTestDataECPP test_data
;
3597 ASSERT_EQ("", test_data
.init());
3598 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3599 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3600 AioCompletion
*my_completion_null
= NULL
;
3601 ASSERT_NE(my_completion
, my_completion_null
);
3603 memset(buf
, 0xcc, sizeof(buf
));
3605 bl1
.append(buf
, sizeof(buf
));
3606 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3607 bl1
, sizeof(buf
), 0));
3610 sem_wait(test_data
.m_sem
);
3611 sem_wait(test_data
.m_sem
);
3613 ASSERT_EQ(0, my_completion
->get_return_value());
3616 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3617 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3618 ASSERT_NE(my_completion2
, my_completion_null
);
3619 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
3623 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3625 ASSERT_EQ(0, my_completion2
->get_return_value());
3626 ASSERT_EQ(sizeof(buf
), psize
);
3627 delete my_completion
;
3628 delete my_completion2
;
3631 TEST(LibRadosAioEC
, SimpleStatNS
) {
3632 AioTestDataEC test_data
;
3633 rados_completion_t my_completion
;
3634 ASSERT_EQ("", test_data
.init());
3635 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3636 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3638 memset(buf
, 0xcc, sizeof(buf
));
3639 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3640 my_completion
, buf
, sizeof(buf
), 0));
3643 sem_wait(test_data
.m_sem
);
3644 sem_wait(test_data
.m_sem
);
3646 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3647 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
3649 memset(buf2
, 0xbb, sizeof(buf2
));
3650 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3651 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3652 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3653 my_completion
, buf2
, sizeof(buf2
), 0));
3656 sem_wait(test_data
.m_sem
);
3657 sem_wait(test_data
.m_sem
);
3659 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3662 rados_completion_t my_completion2
;
3663 rados_ioctx_set_namespace(test_data
.m_ioctx
, "");
3664 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3665 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3666 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3667 my_completion2
, &psize
, &pmtime
));
3670 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3672 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3673 ASSERT_EQ(sizeof(buf
), psize
);
3675 rados_ioctx_set_namespace(test_data
.m_ioctx
, "nspace");
3676 rados_completion_t my_completion3
;
3677 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3678 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3679 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3680 my_completion3
, &psize
, &pmtime
));
3683 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3685 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
3686 ASSERT_EQ(sizeof(buf2
), psize
);
3688 rados_aio_release(my_completion
);
3689 rados_aio_release(my_completion2
);
3690 rados_aio_release(my_completion3
);
3693 TEST(LibRadosAioEC
, SimpleStatPPNS
) {
3694 AioTestDataECPP test_data
;
3695 ASSERT_EQ("", test_data
.init());
3696 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3697 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3698 AioCompletion
*my_completion_null
= NULL
;
3699 ASSERT_NE(my_completion
, my_completion_null
);
3701 memset(buf
, 0xcc, sizeof(buf
));
3703 bl1
.append(buf
, sizeof(buf
));
3704 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3705 bl1
, sizeof(buf
), 0));
3708 sem_wait(test_data
.m_sem
);
3709 sem_wait(test_data
.m_sem
);
3711 ASSERT_EQ(0, my_completion
->get_return_value());
3714 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3715 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3716 ASSERT_NE(my_completion2
, my_completion_null
);
3717 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
3721 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3723 ASSERT_EQ(0, my_completion2
->get_return_value());
3724 ASSERT_EQ(sizeof(buf
), psize
);
3725 delete my_completion
;
3726 delete my_completion2
;
3729 TEST(LibRadosAioEC
, StatRemove
) {
3730 AioTestDataEC test_data
;
3731 rados_completion_t my_completion
;
3732 ASSERT_EQ("", test_data
.init());
3733 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3734 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3736 memset(buf
, 0xcc, sizeof(buf
));
3737 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3738 my_completion
, buf
, sizeof(buf
), 0));
3741 sem_wait(test_data
.m_sem
);
3742 sem_wait(test_data
.m_sem
);
3744 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3747 rados_completion_t my_completion2
;
3748 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3749 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3750 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3751 my_completion2
, &psize
, &pmtime
));
3754 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3756 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2
));
3757 ASSERT_EQ(sizeof(buf
), psize
);
3758 rados_completion_t my_completion3
;
3759 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3760 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3761 ASSERT_EQ(0, rados_aio_remove(test_data
.m_ioctx
, "foo", my_completion3
));
3764 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3766 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3
));
3769 rados_completion_t my_completion4
;
3770 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3771 set_completion_completeEC
, set_completion_safeEC
, &my_completion4
));
3772 ASSERT_EQ(0, rados_aio_stat(test_data
.m_ioctx
, "foo",
3773 my_completion4
, &psize2
, &pmtime2
));
3776 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4
));
3778 ASSERT_EQ(-ENOENT
, rados_aio_get_return_value(my_completion4
));
3779 rados_aio_release(my_completion
);
3780 rados_aio_release(my_completion2
);
3781 rados_aio_release(my_completion3
);
3782 rados_aio_release(my_completion4
);
3785 TEST(LibRadosAioEC
, StatRemovePP
) {
3786 AioTestDataECPP test_data
;
3787 ASSERT_EQ("", test_data
.init());
3788 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3789 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3790 AioCompletion
*my_completion_null
= NULL
;
3791 ASSERT_NE(my_completion
, my_completion_null
);
3793 memset(buf
, 0xcc, sizeof(buf
));
3795 bl1
.append(buf
, sizeof(buf
));
3796 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3797 bl1
, sizeof(buf
), 0));
3800 sem_wait(test_data
.m_sem
);
3801 sem_wait(test_data
.m_sem
);
3803 ASSERT_EQ(0, my_completion
->get_return_value());
3806 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3807 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3808 ASSERT_NE(my_completion2
, my_completion_null
);
3809 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion2
,
3813 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3815 ASSERT_EQ(0, my_completion2
->get_return_value());
3816 ASSERT_EQ(sizeof(buf
), psize
);
3819 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
3820 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3821 ASSERT_NE(my_completion3
, my_completion_null
);
3822 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion3
));
3825 ASSERT_EQ(0, my_completion3
->wait_for_complete());
3827 ASSERT_EQ(0, my_completion3
->get_return_value());
3829 AioCompletion
*my_completion4
= test_data
.m_cluster
.aio_create_completion(
3830 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3831 ASSERT_NE(my_completion4
, my_completion_null
);
3832 ASSERT_EQ(0, test_data
.m_ioctx
.aio_stat("foo", my_completion4
,
3833 &psize2
, &pmtime2
));
3836 ASSERT_EQ(0, my_completion4
->wait_for_complete());
3838 ASSERT_EQ(-ENOENT
, my_completion4
->get_return_value());
3839 delete my_completion
;
3840 delete my_completion2
;
3841 delete my_completion3
;
3842 delete my_completion4
;
3845 TEST(LibRadosAioEC
, ExecuteClass
) {
3846 AioTestDataEC test_data
;
3847 rados_completion_t my_completion
;
3848 ASSERT_EQ("", test_data
.init());
3849 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3850 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3852 memset(buf
, 0xcc, sizeof(buf
));
3853 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3854 my_completion
, buf
, sizeof(buf
), 0));
3857 sem_wait(test_data
.m_sem
);
3858 sem_wait(test_data
.m_sem
);
3860 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3861 rados_completion_t my_completion2
;
3862 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3863 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3865 ASSERT_EQ(0, rados_aio_exec(test_data
.m_ioctx
, "foo", my_completion2
,
3866 "hello", "say_hello", NULL
, 0, out
, sizeof(out
)));
3869 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3871 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2
));
3872 ASSERT_EQ(0, strncmp("Hello, world!", out
, 13));
3873 rados_aio_release(my_completion
);
3874 rados_aio_release(my_completion2
);
3877 TEST(LibRadosAioEC
, ExecuteClassPP
) {
3878 AioTestDataECPP test_data
;
3879 ASSERT_EQ("", test_data
.init());
3880 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3881 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3882 AioCompletion
*my_completion_null
= NULL
;
3883 ASSERT_NE(my_completion
, my_completion_null
);
3885 memset(buf
, 0xcc, sizeof(buf
));
3887 bl1
.append(buf
, sizeof(buf
));
3888 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
3889 bl1
, sizeof(buf
), 0));
3892 sem_wait(test_data
.m_sem
);
3893 sem_wait(test_data
.m_sem
);
3895 ASSERT_EQ(0, my_completion
->get_return_value());
3896 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
3897 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3898 ASSERT_NE(my_completion2
, my_completion_null
);
3900 ASSERT_EQ(0, test_data
.m_ioctx
.aio_exec("foo", my_completion2
,
3901 "hello", "say_hello", in
, &out
));
3904 ASSERT_EQ(0, my_completion2
->wait_for_complete());
3906 ASSERT_EQ(0, my_completion2
->get_return_value());
3907 ASSERT_EQ(std::string("Hello, world!"), std::string(out
.c_str(), out
.length()));
3908 delete my_completion
;
3909 delete my_completion2
;
3912 TEST(LibRadosAioEC
, OmapPP
) {
3914 std::string pool_name
= get_temp_pool_name();
3915 ASSERT_EQ("", create_one_ec_pool_pp(pool_name
, cluster
));
3917 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
3919 string header_str
= "baz";
3920 bufferptr
bp(header_str
.c_str(), header_str
.size() + 1);
3921 bufferlist header_to_set
;
3922 header_to_set
.push_back(bp
);
3923 map
<string
, bufferlist
> to_set
;
3925 boost::scoped_ptr
<AioCompletion
> my_completion(cluster
.aio_create_completion(0, 0, 0));
3926 ObjectWriteOperation op
;
3927 to_set
["foo"] = header_to_set
;
3928 to_set
["foo2"] = header_to_set
;
3929 to_set
["qfoo3"] = header_to_set
;
3930 op
.omap_set(to_set
);
3932 op
.omap_set_header(header_to_set
);
3934 ioctx
.aio_operate("test_obj", my_completion
.get(), &op
);
3937 ASSERT_EQ(0, my_completion
->wait_for_complete());
3939 EXPECT_EQ(-EOPNOTSUPP
, my_completion
->get_return_value());
3941 ioctx
.remove("test_obj");
3942 destroy_one_pool_pp(pool_name
, cluster
);
3945 TEST(LibRadosAioEC
, MultiWrite
) {
3946 AioTestDataEC test_data
;
3947 rados_completion_t my_completion
, my_completion2
, my_completion3
;
3948 ASSERT_EQ("", test_data
.init());
3949 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3950 set_completion_completeEC
, set_completion_safeEC
, &my_completion
));
3952 memset(buf
, 0xcc, sizeof(buf
));
3953 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3954 my_completion
, buf
, sizeof(buf
), 0));
3957 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion
));
3959 ASSERT_EQ(0, rados_aio_get_return_value(my_completion
));
3962 memset(buf2
, 0xdd, sizeof(buf2
));
3963 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3964 set_completion_completeEC
, set_completion_safeEC
, &my_completion2
));
3965 ASSERT_EQ(0, rados_aio_write(test_data
.m_ioctx
, "foo",
3966 my_completion2
, buf2
, sizeof(buf2
), sizeof(buf
)));
3969 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2
));
3971 ASSERT_EQ(-EOPNOTSUPP
, rados_aio_get_return_value(my_completion2
));
3973 char buf3
[(sizeof(buf
) + sizeof(buf2
)) * 3];
3974 memset(buf3
, 0, sizeof(buf3
));
3975 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data
,
3976 set_completion_completeEC
, set_completion_safeEC
, &my_completion3
));
3977 ASSERT_EQ(0, rados_aio_read(test_data
.m_ioctx
, "foo",
3978 my_completion3
, buf3
, sizeof(buf3
), 0));
3981 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3
));
3983 ASSERT_EQ((int)sizeof(buf
), rados_aio_get_return_value(my_completion3
));
3984 ASSERT_EQ(0, memcmp(buf3
, buf
, sizeof(buf
)));
3985 rados_aio_release(my_completion
);
3986 rados_aio_release(my_completion2
);
3987 rados_aio_release(my_completion3
);
3990 TEST(LibRadosAioEC
, MultiWritePP
) {
3991 AioTestDataECPP test_data
;
3992 ASSERT_EQ("", test_data
.init());
3993 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
3994 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
3995 AioCompletion
*my_completion_null
= NULL
;
3996 ASSERT_NE(my_completion
, my_completion_null
);
3998 memset(buf
, 0xcc, sizeof(buf
));
4000 bl1
.append(buf
, sizeof(buf
));
4001 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
4002 bl1
, sizeof(buf
), 0));
4005 ASSERT_EQ(0, my_completion
->wait_for_complete());
4007 ASSERT_EQ(0, my_completion
->get_return_value());
4010 memset(buf2
, 0xdd, sizeof(buf2
));
4012 bl2
.append(buf2
, sizeof(buf2
));
4013 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
4014 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
4015 ASSERT_NE(my_completion2
, my_completion_null
);
4016 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion2
,
4017 bl2
, sizeof(buf2
), sizeof(buf
)));
4020 ASSERT_EQ(0, my_completion2
->wait_for_complete());
4022 ASSERT_EQ(-EOPNOTSUPP
, my_completion2
->get_return_value());
4025 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
4026 (void*)&test_data
, set_completion_completeEC
, set_completion_safeEC
);
4027 ASSERT_NE(my_completion3
, my_completion_null
);
4028 ASSERT_EQ(0, test_data
.m_ioctx
.aio_read("foo", my_completion3
,
4029 &bl3
, (sizeof(buf
) + sizeof(buf2
) * 3), 0));
4032 ASSERT_EQ(0, my_completion3
->wait_for_complete());
4034 ASSERT_EQ((int)sizeof(buf
), my_completion3
->get_return_value());
4035 ASSERT_EQ(sizeof(buf
), bl3
.length());
4036 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, sizeof(buf
)));
4037 delete my_completion
;
4038 delete my_completion2
;
4039 delete my_completion3
;
4042 TEST(LibRadosAio
, RacingRemovePP
) {
4043 AioTestDataPP test_data
;
4044 ASSERT_EQ("", test_data
.init({{"objecter_retry_writes_after_first_reply", "true"}}));
4045 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
4046 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4047 ASSERT_NE(my_completion
, nullptr);
4049 memset(buf
, 0xcc, sizeof(buf
));
4051 bl
.append(buf
, sizeof(buf
));
4052 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
4053 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4054 ASSERT_NE(my_completion2
, nullptr);
4055 ASSERT_EQ(0, test_data
.m_ioctx
.aio_remove("foo", my_completion2
));
4056 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
4057 bl
, sizeof(buf
), 0));
4060 sem_wait(test_data
.m_sem
);
4061 sem_wait(test_data
.m_sem
);
4062 my_completion2
->wait_for_complete();
4063 my_completion
->wait_for_complete();
4065 ASSERT_EQ(-ENOENT
, my_completion2
->get_return_value());
4066 ASSERT_EQ(0, my_completion
->get_return_value());
4067 ASSERT_EQ(0, test_data
.m_ioctx
.stat("foo", nullptr, nullptr));
4068 delete my_completion
;
4069 delete my_completion2
;
4072 TEST(LibRadosAio
, RoundTripCmpExtPP
) {
4073 AioTestDataPP test_data
;
4074 ASSERT_EQ("", test_data
.init());
4075 AioCompletion
*my_completion
= test_data
.m_cluster
.aio_create_completion(
4076 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4077 AioCompletion
*my_completion_null
= NULL
;
4078 ASSERT_NE(my_completion
, my_completion_null
);
4080 memset(full
, 0xcc, sizeof(full
));
4082 bl1
.append(full
, sizeof(full
));
4083 ASSERT_EQ(0, test_data
.m_ioctx
.aio_write("foo", my_completion
,
4084 bl1
, sizeof(full
), 0));
4087 ASSERT_EQ(0, my_completion
->wait_for_complete());
4089 ASSERT_EQ(0, my_completion
->get_return_value());
4091 /* compare with match */
4093 cbl
.append(full
, sizeof(full
));
4094 AioCompletion
*my_completion2
= test_data
.m_cluster
.aio_create_completion(
4095 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4096 ASSERT_EQ(0, test_data
.m_ioctx
.aio_cmpext("foo", my_completion2
, 0, cbl
));
4100 ASSERT_EQ(0, my_completion2
->wait_for_complete());
4102 ASSERT_EQ(0, my_completion2
->get_return_value());
4104 /* compare with mismatch */
4105 memset(full
, 0xdd, sizeof(full
));
4107 cbl
.append(full
, sizeof(full
));
4108 AioCompletion
*my_completion3
= test_data
.m_cluster
.aio_create_completion(
4109 (void*)&test_data
, set_completion_complete
, set_completion_safe
);
4110 ASSERT_EQ(0, test_data
.m_ioctx
.aio_cmpext("foo", my_completion3
, 0, cbl
));
4114 ASSERT_EQ(0, my_completion3
->wait_for_complete());
4116 ASSERT_EQ(-MAX_ERRNO
, my_completion3
->get_return_value());
4118 delete my_completion
;
4119 delete my_completion2
;
4120 delete my_completion3
;
4123 TEST(LibRadosAio
, RoundTripCmpExtPP2
)
4127 char miscmp_buf
[128];
4130 std::string pool_name
= get_temp_pool_name();
4131 ASSERT_EQ("", create_one_pool_pp(pool_name
, cluster
));
4133 cluster
.ioctx_create(pool_name
.c_str(), ioctx
);
4135 boost::scoped_ptr
<AioCompletion
>
4136 wr_cmpl(cluster
.aio_create_completion(0, 0, 0));
4137 ObjectWriteOperation wr_op
;
4138 memset(buf
, 0xcc, sizeof(buf
));
4139 memset(miscmp_buf
, 0xdd, sizeof(miscmp_buf
));
4141 bl
.append(buf
, sizeof(buf
));
4143 wr_op
.write_full(bl
);
4144 wr_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4145 ioctx
.aio_operate("test_obj", wr_cmpl
.get(), &wr_op
);
4148 ASSERT_EQ(0, wr_cmpl
->wait_for_complete());
4150 EXPECT_EQ(0, wr_cmpl
->get_return_value());
4152 /* cmpext as write op. first match then mismatch */
4153 boost::scoped_ptr
<AioCompletion
>
4154 wr_cmpext_cmpl(cluster
.aio_create_completion(0, 0, 0));
4155 cbl
.append(buf
, sizeof(buf
));
4158 wr_op
.cmpext(0, cbl
, &ret
);
4159 wr_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4160 ioctx
.aio_operate("test_obj", wr_cmpext_cmpl
.get(), &wr_op
);
4163 ASSERT_EQ(0, wr_cmpext_cmpl
->wait_for_complete());
4165 EXPECT_EQ(0, wr_cmpext_cmpl
->get_return_value());
4168 boost::scoped_ptr
<AioCompletion
>
4169 wr_cmpext_cmpl2(cluster
.aio_create_completion(0, 0, 0));
4171 cbl
.append(miscmp_buf
, sizeof(miscmp_buf
));
4174 wr_op
.cmpext(0, cbl
, &ret
);
4175 wr_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4176 ioctx
.aio_operate("test_obj", wr_cmpext_cmpl2
.get(), &wr_op
);
4179 ASSERT_EQ(0, wr_cmpext_cmpl2
->wait_for_complete());
4181 EXPECT_EQ(-MAX_ERRNO
, wr_cmpext_cmpl2
->get_return_value());
4182 EXPECT_EQ(-MAX_ERRNO
, ret
);
4184 /* cmpext as read op */
4185 boost::scoped_ptr
<AioCompletion
>
4186 rd_cmpext_cmpl(cluster
.aio_create_completion(0, 0, 0));
4187 ObjectReadOperation rd_op
;
4189 cbl
.append(buf
, sizeof(buf
));
4191 rd_op
.cmpext(0, cbl
, &ret
);
4192 rd_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4193 ioctx
.aio_operate("test_obj", rd_cmpext_cmpl
.get(), &rd_op
, 0);
4196 ASSERT_EQ(0, rd_cmpext_cmpl
->wait_for_complete());
4198 EXPECT_EQ(0, rd_cmpext_cmpl
->get_return_value());
4201 boost::scoped_ptr
<AioCompletion
>
4202 rd_cmpext_cmpl2(cluster
.aio_create_completion(0, 0, 0));
4204 cbl
.append(miscmp_buf
, sizeof(miscmp_buf
));
4207 rd_op
.cmpext(0, cbl
, &ret
);
4208 rd_op
.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED
);
4209 ioctx
.aio_operate("test_obj", rd_cmpext_cmpl2
.get(), &rd_op
, 0);
4212 ASSERT_EQ(0, rd_cmpext_cmpl2
->wait_for_complete());
4214 EXPECT_EQ(-MAX_ERRNO
, rd_cmpext_cmpl2
->get_return_value());
4215 EXPECT_EQ(-MAX_ERRNO
, ret
);
4217 ioctx
.remove("test_obj");
4218 destroy_one_pool_pp(pool_name
, cluster
);