Skip to content

Commit 5fd7d2a

Browse files
committed
test/librados: add test cases for aio_cancel()
Signed-off-by: Casey Bodley <[email protected]>
1 parent c5eacfc commit 5fd7d2a

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed

src/test/librados/aio.cc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,3 +1722,59 @@ TEST(LibRadosAioEC, MultiWrite) {
17221722
rados_aio_release(my_completion2);
17231723
rados_aio_release(my_completion3);
17241724
}
1725+
1726+
TEST(LibRadosAio, CancelBeforeSubmit) {
1727+
AioTestData test_data;
1728+
ASSERT_EQ("", test_data.init());
1729+
1730+
rados_completion_t completion;
1731+
ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr, &completion));
1732+
1733+
ASSERT_EQ(0, rados_aio_cancel(test_data.m_ioctx, completion));
1734+
rados_aio_release(completion);
1735+
}
1736+
1737+
TEST(LibRadosAio, CancelBeforeComplete) {
1738+
AioTestData test_data;
1739+
ASSERT_EQ("", test_data.init());
1740+
1741+
// cancellation tests are racy, so retry if completion beats the cancellation
1742+
int ret = 0;
1743+
int tries = 10;
1744+
do {
1745+
rados_completion_t completion;
1746+
ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr, &completion));
1747+
char buf[128];
1748+
ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "nonexistent",
1749+
completion, buf, sizeof(buf), 0));
1750+
1751+
ASSERT_EQ(0, rados_aio_cancel(test_data.m_ioctx, completion));
1752+
{
1753+
TestAlarm alarm;
1754+
ASSERT_EQ(0, rados_aio_wait_for_complete(completion));
1755+
}
1756+
ret = rados_aio_get_return_value(completion);
1757+
rados_aio_release(completion);
1758+
} while (ret == -ENOENT && --tries);
1759+
1760+
ASSERT_EQ(-ECANCELED, ret);
1761+
}
1762+
1763+
TEST(LibRadosAio, CancelAfterComplete) {
1764+
AioTestData test_data;
1765+
rados_completion_t completion;
1766+
ASSERT_EQ("", test_data.init());
1767+
1768+
ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr, &completion));
1769+
char buf[128];
1770+
ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "nonexistent",
1771+
completion, buf, sizeof(buf), 0));
1772+
1773+
{
1774+
TestAlarm alarm;
1775+
ASSERT_EQ(0, rados_aio_wait_for_complete(completion));
1776+
}
1777+
ASSERT_EQ(0, rados_aio_cancel(test_data.m_ioctx, completion));
1778+
ASSERT_EQ(-ENOENT, rados_aio_get_return_value(completion));
1779+
rados_aio_release(completion);
1780+
}

src/test/librados/aio_cxx.cc

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2466,3 +2466,92 @@ TEST(LibRadosAio, MultiReads) {
24662466
ASSERT_EQ(0, memcmp(buf, bl.c_str(), sizeof(buf)));
24672467
}
24682468
}
2469+
2470+
// cancellation test fixture for global setup/teardown
2471+
// parameterized to test both IoCtx::aio_cancel() and AioCompletion::cancel()
2472+
class Cancel : public ::testing::TestWithParam<bool> {
2473+
static constexpr auto pool_prefix = "ceph_test_rados_api_pp";
2474+
static Rados rados;
2475+
static std::string pool_name;
2476+
protected:
2477+
static IoCtx ioctx;
2478+
public:
2479+
static void SetUpTestCase() {
2480+
pool_name = get_temp_pool_name(pool_prefix);
2481+
ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
2482+
ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
2483+
}
2484+
static void TearDownTestCase() {
2485+
destroy_one_pool_pp(pool_name, rados);
2486+
}
2487+
};
2488+
Rados Cancel::rados;
2489+
std::string Cancel::pool_name;
2490+
IoCtx Cancel::ioctx;
2491+
2492+
TEST_P(Cancel, BeforeSubmit)
2493+
{
2494+
const bool use_completion = GetParam();
2495+
2496+
auto c = std::unique_ptr<AioCompletion>{Rados::aio_create_completion()};
2497+
if (use_completion) {
2498+
ASSERT_EQ(0, c->cancel());
2499+
} else {
2500+
ASSERT_EQ(0, ioctx.aio_cancel(c.get()));
2501+
}
2502+
}
2503+
2504+
TEST_P(Cancel, BeforeComplete)
2505+
{
2506+
const bool use_completion = GetParam();
2507+
2508+
// cancellation tests are racy, so retry if completion beats the cancellation
2509+
int ret = 0;
2510+
int tries = 10;
2511+
do {
2512+
auto c = std::unique_ptr<AioCompletion>{Rados::aio_create_completion()};
2513+
ObjectReadOperation op;
2514+
op.assert_exists();
2515+
ioctx.aio_operate("nonexistent", c.get(), &op, nullptr);
2516+
2517+
if (use_completion) {
2518+
EXPECT_EQ(0, c->cancel());
2519+
} else {
2520+
EXPECT_EQ(0, ioctx.aio_cancel(c.get()));
2521+
}
2522+
{
2523+
TestAlarm alarm;
2524+
ASSERT_EQ(0, c->wait_for_complete());
2525+
}
2526+
ret = c->get_return_value();
2527+
} while (ret == -ENOENT && --tries);
2528+
2529+
EXPECT_EQ(-ECANCELED, ret);
2530+
}
2531+
2532+
TEST_P(Cancel, AfterComplete)
2533+
{
2534+
const bool use_completion = GetParam();
2535+
2536+
auto c = std::unique_ptr<AioCompletion>{Rados::aio_create_completion()};
2537+
ObjectReadOperation op;
2538+
op.assert_exists();
2539+
ioctx.aio_operate("nonexistent", c.get(), &op, nullptr);
2540+
{
2541+
TestAlarm alarm;
2542+
ASSERT_EQ(0, c->wait_for_complete());
2543+
}
2544+
if (use_completion) {
2545+
EXPECT_EQ(0, c->cancel());
2546+
} else {
2547+
EXPECT_EQ(0, ioctx.aio_cancel(c.get()));
2548+
}
2549+
EXPECT_EQ(-ENOENT, c->get_return_value());
2550+
}
2551+
2552+
std::string cancel_test_name(const testing::TestParamInfo<Cancel::ParamType>& info)
2553+
{
2554+
return info.param ? "cancel" : "aio_cancel";
2555+
}
2556+
2557+
INSTANTIATE_TEST_SUITE_P(LibRadosAio, Cancel, testing::Bool(), cancel_test_name);

0 commit comments

Comments
 (0)