static auto num = 1ull;
return fmt::format("{}{}-{}-{}", prefix, hostname, getpid(), num++);
}
+
+
+asio::awaitable<uint64_t> NeoRadosECTest::create_pool() {
+ // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110913
+ std::vector<std::string> profile_set = {
+ fmt::format(
+ R"({{"prefix": "osd erasure-code-profile set", "name": "testprofile-{}", )"
+ R"( "profile": [ "k=2", "m=1", "crush-failure-domain=osd"]}})",
+ pool_name())
+ };
+ co_await rados().mon_command(std::move(profile_set), {}, nullptr, nullptr,
+ asio::use_awaitable);
+ std::vector<std::string> pool_create = {
+ fmt::format(
+ R"({{"prefix": "osd pool create", "pool": "{}", "pool_type":"erasure", )"
+ R"("pg_num":8, "pgp_num":8, "erasure_code_profile":"testprofile-{}"}})",
+ pool_name(), pool_name())
+ };
+ auto c = rados().mon_command(std::move(pool_create), {}, nullptr, nullptr,
+ asio::use_awaitable);
+ co_await std::move(c);
+
+ co_return co_await rados().lookup_pool(pool_name(), asio::use_awaitable);
+}
+
+asio::awaitable<void> NeoRadosECTest::clean_pool() {
+ co_await rados().delete_pool(pool().get_pool(), asio::use_awaitable);
+ std::vector<std::string> profile_rm = {
+ fmt::format(
+ R"({{"prefix": "osd erasure-code-profile rm", "name": "testprofile-{}"}})",
+ pool_name())
+ };
+ co_await rados().mon_command(std::move(profile_rm), {}, nullptr, nullptr, asio::use_awaitable);
+ std::vector<std::string> rule_rm = {
+ fmt::format(
+ R"({{"prefix": "osd crush rule rm", "name":"{}"}})",
+ pool_name())
+ };
+ co_await rados().mon_command(std::move(rule_rm), {}, nullptr, nullptr,
+ asio::use_awaitable);
+ co_return;
+}
/// CoTestBody has access to `rados`, a `neorados::RADOS` handle, and
/// `pool`, a `neorados::IOContext` representing a pool that will be
/// destroyed when the test exits.
-class NeoRadosTest : public CoroTest {
+///
+/// Derived classes must define `create_pool()` and `clean_pool()`.
+class NeoRadosTestBase : public CoroTest {
private:
const std::string prefix_{std::string{"test framework "} +
testing::UnitTest::GetInstance()->
std::string{": "}};
std::optional<neorados::RADOS> rados_;
+ neorados::IOContext pool_;
const std::string pool_name_ = get_temp_pool_name(
testing::UnitTest::GetInstance()->current_test_info()->name());
- neorados::IOContext pool_;
std::unique_ptr<DoutPrefix> dpp_;
+ virtual boost::asio::awaitable<uint64_t> create_pool() = 0;
+ virtual boost::asio::awaitable<void> clean_pool() = 0;
+
protected:
/// \brief Return reference to RADOS
rados_ = co_await neorados::RADOS::Builder{}
.build(asio_context, boost::asio::use_awaitable);
dpp_ = std::make_unique<DoutPrefix>(rados().cct(), 0, prefix().data());
- pool_.set_pool(co_await create_pool(rados(), pool_name(),
- boost::asio::use_awaitable));
+ pool_.set_pool(co_await create_pool());
co_return;
}
- ~NeoRadosTest() override = default;
+ ~NeoRadosTestBase() override = default;
/// \brief Delete pool used for testing
boost::asio::awaitable<void> CoTearDown() override {
- co_await rados().delete_pool(pool().get_pool(),
- boost::asio::use_awaitable);
+ co_await clean_pool();
co_return;
}
};
+/// \brief C++20 coroutine test harness for NeoRados on normal pools
+///
+/// The supplied pool is not erasure coded.
+class NeoRadosTest : public NeoRadosTestBase {
+private:
+ boost::asio::awaitable<uint64_t> create_pool() override {
+ co_return co_await ::create_pool(rados(), pool_name(),
+ boost::asio::use_awaitable);
+ }
+
+ boost::asio::awaitable<void> clean_pool() override {
+ co_await rados().delete_pool(pool().get_pool(),
+ boost::asio::use_awaitable);
+ }
+};
+
+/// \brief C++20 coroutine test harness for NeoRados on erasure-coded
+/// pools
+///
+/// The supplied pool is erasure coded
+class NeoRadosECTest : public NeoRadosTestBase {
+private:
+ boost::asio::awaitable<uint64_t> create_pool() override;
+ boost::asio::awaitable<void> clean_pool() override;
+};
+
/// \brief Helper macro for defining coroutine tests with a fixture
///
/// Defines a test using a coroutine fixture for