summaryrefslogtreecommitdiffstats
path: root/src/test/librados/aio_cxx.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/librados/aio_cxx.cc')
-rw-r--r--src/test/librados/aio_cxx.cc90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/test/librados/aio_cxx.cc b/src/test/librados/aio_cxx.cc
index 92326e4dbc0..5e35869b5c2 100644
--- a/src/test/librados/aio_cxx.cc
+++ b/src/test/librados/aio_cxx.cc
@@ -1,5 +1,6 @@
#include <errno.h>
#include <fcntl.h>
+#include <deque>
#include <sstream>
#include <string>
#include <utility>
@@ -2466,3 +2467,92 @@ TEST(LibRadosAio, MultiReads) {
ASSERT_EQ(0, memcmp(buf, bl.c_str(), sizeof(buf)));
}
}
+
+// cancellation test fixture for global setup/teardown
+// parameterized to test both IoCtx::aio_cancel() and AioCompletion::cancel()
+class Cancel : public ::testing::TestWithParam<bool> {
+ static constexpr auto pool_prefix = "ceph_test_rados_api_pp";
+ static Rados rados;
+ static std::string pool_name;
+ protected:
+ static IoCtx ioctx;
+ public:
+ static void SetUpTestCase() {
+ pool_name = get_temp_pool_name(pool_prefix);
+ ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
+ ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
+ }
+ static void TearDownTestCase() {
+ destroy_one_pool_pp(pool_name, rados);
+ }
+};
+Rados Cancel::rados;
+std::string Cancel::pool_name;
+IoCtx Cancel::ioctx;
+
+TEST_P(Cancel, BeforeSubmit)
+{
+ const bool use_completion = GetParam();
+
+ auto c = std::unique_ptr<AioCompletion>{Rados::aio_create_completion()};
+ if (use_completion) {
+ ASSERT_EQ(0, c->cancel());
+ } else {
+ ASSERT_EQ(0, ioctx.aio_cancel(c.get()));
+ }
+}
+
+TEST_P(Cancel, BeforeComplete)
+{
+ const bool use_completion = GetParam();
+
+ // cancellation tests are racy, so retry if completion beats the cancellation
+ int ret = 0;
+ int tries = 10;
+ do {
+ auto c = std::unique_ptr<AioCompletion>{Rados::aio_create_completion()};
+ ObjectReadOperation op;
+ op.assert_exists();
+ ioctx.aio_operate("nonexistent", c.get(), &op, nullptr);
+
+ if (use_completion) {
+ EXPECT_EQ(0, c->cancel());
+ } else {
+ EXPECT_EQ(0, ioctx.aio_cancel(c.get()));
+ }
+ {
+ TestAlarm alarm;
+ ASSERT_EQ(0, c->wait_for_complete());
+ }
+ ret = c->get_return_value();
+ } while (ret == -ENOENT && --tries);
+
+ EXPECT_EQ(-ECANCELED, ret);
+}
+
+TEST_P(Cancel, AfterComplete)
+{
+ const bool use_completion = GetParam();
+
+ auto c = std::unique_ptr<AioCompletion>{Rados::aio_create_completion()};
+ ObjectReadOperation op;
+ op.assert_exists();
+ ioctx.aio_operate("nonexistent", c.get(), &op, nullptr);
+ {
+ TestAlarm alarm;
+ ASSERT_EQ(0, c->wait_for_complete());
+ }
+ if (use_completion) {
+ EXPECT_EQ(0, c->cancel());
+ } else {
+ EXPECT_EQ(0, ioctx.aio_cancel(c.get()));
+ }
+ EXPECT_EQ(-ENOENT, c->get_return_value());
+}
+
+std::string cancel_test_name(const testing::TestParamInfo<Cancel::ParamType>& info)
+{
+ return info.param ? "cancel" : "aio_cancel";
+}
+
+INSTANTIATE_TEST_SUITE_P(LibRadosAio, Cancel, testing::Bool(), cancel_test_name);