X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Ftest%2Flibrbd%2Fimage%2Ftest_mock_RemoveRequest.cc;fp=src%2Fceph%2Fsrc%2Ftest%2Flibrbd%2Fimage%2Ftest_mock_RemoveRequest.cc;h=77c536d03a8712e46cc04c6797f9ad8a08f20042;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/test/librbd/image/test_mock_RemoveRequest.cc b/src/ceph/src/test/librbd/image/test_mock_RemoveRequest.cc new file mode 100644 index 0000000..77c536d --- /dev/null +++ b/src/ceph/src/test/librbd/image/test_mock_RemoveRequest.cc @@ -0,0 +1,352 @@ +// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "test/librbd/test_mock_fixture.h" +#include "test/librbd/test_support.h" +#include "test/librbd/mock/MockImageCtx.h" +#include "test/librbd/mock/MockContextWQ.h" +#include "test/librados_test_stub/MockTestMemIoCtxImpl.h" +#include "test/librados_test_stub/MockTestMemRadosClient.h" +#include "librbd/ImageState.h" +#include "librbd/internal.h" +#include "librbd/journal/RemoveRequest.h" +#include "librbd/Operations.h" +#include "librbd/operation/TrimRequest.h" +#include "librbd/image/TypeTraits.h" +#include "librbd/image/RemoveRequest.h" +#include "librbd/image/RefreshParentRequest.h" +#include "librbd/mirror/DisableRequest.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include +#include +#include + +namespace librbd { +namespace image { +template <> +struct TypeTraits { + typedef librbd::MockContextWQ ContextWQ; +}; +} + +namespace operation { + +template <> +class TrimRequest { +public: + static TrimRequest *s_instance; + static TrimRequest *create(MockImageCtx &image_ctx, Context *on_finish, + uint64_t original_size, uint64_t new_size, + ProgressContext &prog_ctx) { + assert(s_instance != nullptr); + s_instance->on_finish = on_finish; + return s_instance; + } + + Context *on_finish = nullptr; + + TrimRequest() { + s_instance = this; + } + + MOCK_METHOD0(send, void()); +}; + +} // namespace operation + +namespace journal { +template <> +class RemoveRequest { +private: + typedef ::librbd::image::TypeTraits TypeTraits; + typedef typename TypeTraits::ContextWQ ContextWQ; +public: + static RemoveRequest *s_instance; + static RemoveRequest *create(IoCtx &ioctx, const std::string &imageid, + const std::string &client_id, + ContextWQ *op_work_queue, Context *on_finish) { + assert(s_instance != nullptr); + s_instance->on_finish = on_finish; + return s_instance; + } + + Context *on_finish = nullptr; + + RemoveRequest() { + s_instance = this; + } + + MOCK_METHOD0(send, void()); +}; +RemoveRequest *RemoveRequest::s_instance = nullptr; +} // namespace journal + +namespace mirror { + +template<> +class DisableRequest { +public: + static DisableRequest *s_instance; + Context *on_finish = nullptr; + + static DisableRequest *create(MockImageCtx *image_ctx, bool force, + bool remove, Context *on_finish) { + assert(s_instance != nullptr); + s_instance->on_finish = on_finish; + return s_instance; + } + + DisableRequest() { + s_instance = this; + } + + MOCK_METHOD0(send, void()); +}; + +DisableRequest *DisableRequest::s_instance; + +} // namespace mirror +} // namespace librbd + +// template definitions +#include "librbd/image/RemoveRequest.cc" +template class librbd::image::RemoveRequest; + +namespace librbd { +namespace image { + +using ::testing::_; +using ::testing::DoAll; +using ::testing::DoDefault; +using ::testing::Invoke; +using ::testing::InSequence; +using ::testing::Return; +using ::testing::WithArg; +using ::testing::SetArgPointee; +using ::testing::StrEq; + +class TestMockImageRemoveRequest : public TestMockFixture { +public: + typedef ::librbd::image::TypeTraits TypeTraits; + typedef typename TypeTraits::ContextWQ ContextWQ; + typedef RemoveRequest MockRemoveRequest; + typedef librbd::operation::TrimRequest MockTrimRequest; + typedef librbd::journal::RemoveRequest MockJournalRemoveRequest; + typedef librbd::mirror::DisableRequest MockMirrorDisableRequest; + + librbd::ImageCtx *m_test_imctx = NULL; + MockImageCtx *m_mock_imctx = NULL; + + + void TestImageRemoveSetUp() { + ASSERT_EQ(0, open_image(m_image_name, &m_test_imctx)); + m_mock_imctx = new MockImageCtx(*m_test_imctx); + librbd::MockImageCtx::s_instance = m_mock_imctx; + } + void TestImageRemoveTearDown() { + librbd::MockImageCtx::s_instance = NULL; + delete m_mock_imctx; + } + + void expect_state_open(MockImageCtx &mock_image_ctx, int r) { + EXPECT_CALL(*mock_image_ctx.state, open(_, _)) + .WillOnce(Invoke([r](bool open_parent, Context *on_ready) { + on_ready->complete(r); + })); + if (r < 0) { + EXPECT_CALL(mock_image_ctx, destroy()); + } + } + + void expect_state_close(MockImageCtx &mock_image_ctx) { + EXPECT_CALL(*mock_image_ctx.state, close(_)) + .WillOnce(Invoke([](Context *on_ready) { + on_ready->complete(0); + })); + EXPECT_CALL(mock_image_ctx, destroy()); + } + + void expect_wq_queue(ContextWQ &wq, int r) { + EXPECT_CALL(wq, queue(_, r)) + .WillRepeatedly(Invoke([](Context *on_ready, int r) { + on_ready->complete(r); + })); + } + + void expect_get_group(MockImageCtx &mock_image_ctx, int r) { + auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), + exec(mock_image_ctx.header_oid, _, StrEq("rbd"), + StrEq("image_get_group"), _, _, _)); + if (r < 0) { + expect.WillOnce(Return(r)); + } else { + expect.WillOnce(DoDefault()); + } + } + + void expect_trim(MockImageCtx &mock_image_ctx, + MockTrimRequest &mock_trim_request, int r) { + EXPECT_CALL(mock_trim_request, send()) + .WillOnce(FinishRequest(&mock_trim_request, r, &mock_image_ctx)); + } + + void expect_journal_remove(MockImageCtx &mock_image_ctx, + MockJournalRemoveRequest &mock_journal_remove_request, int r) { + EXPECT_CALL(mock_journal_remove_request, send()) + .WillOnce(FinishRequest(&mock_journal_remove_request, r, &mock_image_ctx)); + } + + void expect_mirror_disable(MockImageCtx &mock_image_ctx, + MockMirrorDisableRequest &mock_mirror_disable_request, int r) { + EXPECT_CALL(mock_mirror_disable_request, send()) + .WillOnce(FinishRequest(&mock_mirror_disable_request, r, &mock_image_ctx)); + } + + void expect_remove_child(MockImageCtx &mock_image_ctx, int r) { + EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), + exec(RBD_CHILDREN, _, StrEq("rbd"), StrEq("remove_child"), _, + _, _)) + .WillOnce(Return(r)); + } + + void expect_remove_mirror_image(librados::IoCtx &ioctx, int r) { + EXPECT_CALL(get_mock_io_ctx(ioctx), + exec(StrEq("rbd_mirroring"), _, StrEq("rbd"), StrEq("mirror_image_remove"), + _, _, _)) + .WillOnce(Return(r)); + } + + void expect_mirror_image_get(MockImageCtx &mock_image_ctx, int r) { + EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), + exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_image_get"), + _, _, _)) + .WillOnce(Return(r)); + } + + void expect_dir_remove_image(librados::IoCtx &ioctx, int r) { + EXPECT_CALL(get_mock_io_ctx(ioctx), + exec(RBD_DIRECTORY, _, StrEq("rbd"), StrEq("dir_remove_image"), + _, _, _)) + .WillOnce(Return(r)); + } +}; + +TEST_F(TestMockImageRemoveRequest, SuccessV1) { + REQUIRE_FORMAT_V1(); + TestImageRemoveSetUp(); + + C_SaferCond ctx; + librbd::NoOpProgressContext no_op; + ContextWQ op_work_queue; + MockTrimRequest mock_trim_request; + MockJournalRemoveRequest mock_journal_remove_request; + + InSequence seq; + expect_state_open(*m_mock_imctx, 0); + expect_get_group(*m_mock_imctx, 0); + expect_trim(*m_mock_imctx, mock_trim_request, 0); + expect_op_work_queue(*m_mock_imctx); + expect_state_close(*m_mock_imctx); + expect_wq_queue(op_work_queue, 0); + + MockRemoveRequest *req = MockRemoveRequest::create(m_ioctx, m_image_name, "", + true, false, no_op, &op_work_queue, &ctx); + req->send(); + + ASSERT_EQ(0, ctx.wait()); + + TestImageRemoveTearDown(); +} + +TEST_F(TestMockImageRemoveRequest, OpenFailV1) { + REQUIRE_FORMAT_V1(); + TestImageRemoveSetUp(); + + C_SaferCond ctx; + librbd::NoOpProgressContext no_op; + ContextWQ op_work_queue; + MockTrimRequest mock_trim_request; + + InSequence seq; + expect_state_open(*m_mock_imctx, -ENOENT); + expect_wq_queue(op_work_queue, 0); + + MockRemoveRequest *req = MockRemoveRequest::create(m_ioctx, m_image_name, "", + true, false, no_op, &op_work_queue, &ctx); + req->send(); + + ASSERT_EQ(0, ctx.wait()); + + TestImageRemoveTearDown(); +} + +TEST_F(TestMockImageRemoveRequest, SuccessV2) { + REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); + TestImageRemoveSetUp(); + + C_SaferCond ctx; + librbd::NoOpProgressContext no_op; + ContextWQ op_work_queue; + MockTrimRequest mock_trim_request; + MockJournalRemoveRequest mock_journal_remove_request; + MockMirrorDisableRequest mock_mirror_disable_request; + + InSequence seq; + expect_state_open(*m_mock_imctx, 0); + expect_mirror_image_get(*m_mock_imctx, 0); + expect_get_group(*m_mock_imctx, 0); + expect_trim(*m_mock_imctx, mock_trim_request, 0); + expect_op_work_queue(*m_mock_imctx); + expect_remove_child(*m_mock_imctx, 0); + expect_mirror_disable(*m_mock_imctx, mock_mirror_disable_request, 0); + expect_state_close(*m_mock_imctx); + expect_wq_queue(op_work_queue, 0); + expect_journal_remove(*m_mock_imctx, mock_journal_remove_request, 0); + expect_remove_mirror_image(m_ioctx, 0); + expect_dir_remove_image(m_ioctx, 0); + + MockRemoveRequest *req = MockRemoveRequest::create(m_ioctx, m_image_name, "", + true, false, no_op, &op_work_queue, &ctx); + req->send(); + + ASSERT_EQ(0, ctx.wait()); + + TestImageRemoveTearDown(); +} + +TEST_F(TestMockImageRemoveRequest, NotExistsV2) { + REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); + TestImageRemoveSetUp(); + + C_SaferCond ctx; + librbd::NoOpProgressContext no_op; + ContextWQ op_work_queue; + MockTrimRequest mock_trim_request; + MockJournalRemoveRequest mock_journal_remove_request; + MockMirrorDisableRequest mock_mirror_disable_request; + + InSequence seq; + expect_state_open(*m_mock_imctx, 0); + expect_mirror_image_get(*m_mock_imctx, 0); + expect_get_group(*m_mock_imctx, 0); + expect_trim(*m_mock_imctx, mock_trim_request, 0); + expect_op_work_queue(*m_mock_imctx); + expect_remove_child(*m_mock_imctx, 0); + expect_mirror_disable(*m_mock_imctx, mock_mirror_disable_request, 0); + expect_state_close(*m_mock_imctx); + expect_wq_queue(op_work_queue, 0); + expect_journal_remove(*m_mock_imctx, mock_journal_remove_request, 0); + expect_remove_mirror_image(m_ioctx, 0); + expect_dir_remove_image(m_ioctx, -ENOENT); + + MockRemoveRequest *req = MockRemoveRequest::create(m_ioctx, m_image_name, "", + true, false, no_op, &op_work_queue, &ctx); + req->send(); + ASSERT_EQ(-ENOENT, ctx.wait()); + + TestImageRemoveTearDown(); +} + +} // namespace image +} // namespace librbd