diff options
Diffstat (limited to 'src/test/librbd/test_fixture.cc')
-rw-r--r-- | src/test/librbd/test_fixture.cc | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/src/test/librbd/test_fixture.cc b/src/test/librbd/test_fixture.cc new file mode 100644 index 000000000..9ddebec48 --- /dev/null +++ b/src/test/librbd/test_fixture.cc @@ -0,0 +1,165 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +#include "common/Cond.h" +#include "test/librbd/test_fixture.h" +#include "test/librbd/test_support.h" +#include "include/stringify.h" +#include "librbd/ExclusiveLock.h" +#include "librbd/ImageState.h" +#include "librbd/ImageWatcher.h" +#include "librbd/io/ImageDispatchSpec.h" +#include "librbd/Operations.h" +#include "librbd/api/Io.h" +#include "cls/lock/cls_lock_client.h" +#include "cls/lock/cls_lock_types.h" +#include "cls/rbd/cls_rbd_types.h" +#include "librbd/internal.h" +#include "test/librados/test.h" +#include "test/librados/test_cxx.h" +#include <iostream> +#include <sstream> +#include <stdlib.h> + +std::string TestFixture::_pool_name; +librados::Rados TestFixture::_rados; +rados_t TestFixture::_cluster; +uint64_t TestFixture::_image_number = 0; +std::string TestFixture::_data_pool; + +TestFixture::TestFixture() : m_image_size(0) { +} + +void TestFixture::SetUpTestCase() { + ASSERT_EQ("", connect_cluster(&_cluster)); + _pool_name = get_temp_pool_name("test-librbd-"); + ASSERT_EQ("", create_one_pool_pp(_pool_name, _rados)); + + bool created = false; + ASSERT_EQ(0, create_image_data_pool(_rados, _data_pool, &created)); + if (!_data_pool.empty()) { + printf("using image data pool: %s\n", _data_pool.c_str()); + if (!created) { + _data_pool.clear(); + } + } +} + +void TestFixture::TearDownTestCase() { + rados_shutdown(_cluster); + if (!_data_pool.empty()) { + ASSERT_EQ(0, _rados.pool_delete(_data_pool.c_str())); + } + + ASSERT_EQ(0, destroy_one_pool_pp(_pool_name, _rados)); +} + +std::string TestFixture::get_temp_image_name() { + ++_image_number; + return "image" + stringify(_image_number); +} + +void TestFixture::SetUp() { + ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), m_ioctx)); + m_cct = reinterpret_cast<CephContext*>(m_ioctx.cct()); + librados::Rados rados(m_ioctx); + rados.conf_set("rbd_persistent_cache_path", "."); + + m_image_name = get_temp_image_name(); + m_image_size = 2 << 20; + ASSERT_EQ(0, create_image_pp(m_rbd, m_ioctx, m_image_name, m_image_size)); +} + +void TestFixture::TearDown() { + unlock_image(); + for (std::set<librbd::ImageCtx *>::iterator iter = m_ictxs.begin(); + iter != m_ictxs.end(); ++iter) { + (*iter)->state->close(); + } + m_ioctx.close(); +} + +int TestFixture::open_image(const std::string &image_name, + librbd::ImageCtx **ictx) { + *ictx = new librbd::ImageCtx(image_name.c_str(), "", nullptr, m_ioctx, false); + m_ictxs.insert(*ictx); + + return (*ictx)->state->open(0); +} + +int TestFixture::snap_create(librbd::ImageCtx &ictx, + const std::string &snap_name) { + librbd::NoOpProgressContext prog_ctx; + return ictx.operations->snap_create(cls::rbd::UserSnapshotNamespace(), + snap_name.c_str(), 0, prog_ctx); +} + +int TestFixture::snap_protect(librbd::ImageCtx &ictx, + const std::string &snap_name) { + return ictx.operations->snap_protect(cls::rbd::UserSnapshotNamespace(), + snap_name.c_str()); +} + +int TestFixture::flatten(librbd::ImageCtx &ictx, + librbd::ProgressContext &prog_ctx) { + return ictx.operations->flatten(prog_ctx); +} + +int TestFixture::resize(librbd::ImageCtx *ictx, uint64_t size){ + librbd::NoOpProgressContext prog_ctx; + return ictx->operations->resize(size, true, prog_ctx); +} + +void TestFixture::close_image(librbd::ImageCtx *ictx) { + m_ictxs.erase(ictx); + + ictx->state->close(); +} + +int TestFixture::lock_image(librbd::ImageCtx &ictx, ClsLockType lock_type, + const std::string &cookie) { + int r = rados::cls::lock::lock(&ictx.md_ctx, ictx.header_oid, RBD_LOCK_NAME, + lock_type, cookie, "internal", "", utime_t(), + 0); + if (r == 0) { + m_lock_object = ictx.header_oid; + m_lock_cookie = cookie; + } + return r; +} + +int TestFixture::unlock_image() { + int r = 0; + if (!m_lock_cookie.empty()) { + r = rados::cls::lock::unlock(&m_ioctx, m_lock_object, RBD_LOCK_NAME, + m_lock_cookie); + m_lock_cookie = ""; + } + return r; +} + +int TestFixture::acquire_exclusive_lock(librbd::ImageCtx &ictx) { + int r = librbd::api::Io<>::write(ictx, 0, 0, {}, 0); + if (r != 0) { + return r; + } + + std::shared_lock owner_locker{ictx.owner_lock}; + ceph_assert(ictx.exclusive_lock != nullptr); + return ictx.exclusive_lock->is_lock_owner() ? 0 : -EINVAL; +} + +int TestFixture::flush_writeback_cache(librbd::ImageCtx *image_ctx) { + if (image_ctx->test_features(RBD_FEATURE_DIRTY_CACHE)) { + // cache exists. Close to flush data + C_SaferCond ctx; + auto aio_comp = librbd::io::AioCompletion::create_and_start( + &ctx, image_ctx, librbd::io::AIO_TYPE_FLUSH); + auto req = librbd::io::ImageDispatchSpec::create_flush( + *image_ctx, librbd::io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp, + librbd::io::FLUSH_SOURCE_INTERNAL, {}); + req->send(); + return ctx.wait(); + } else { + return librbd::api::Io<>::flush(*image_ctx); + } +} |