diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/test/librbd/trash/test_mock_RemoveRequest.cc | |
parent | Initial commit. (diff) | |
download | ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/librbd/trash/test_mock_RemoveRequest.cc')
-rw-r--r-- | src/test/librbd/trash/test_mock_RemoveRequest.cc | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/src/test/librbd/trash/test_mock_RemoveRequest.cc b/src/test/librbd/trash/test_mock_RemoveRequest.cc new file mode 100644 index 000000000..51d6123de --- /dev/null +++ b/src/test/librbd/trash/test_mock_RemoveRequest.cc @@ -0,0 +1,230 @@ +// -*- 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/MockExclusiveLock.h" +#include "test/librbd/mock/MockImageCtx.h" +#include "test/librbd/mock/MockImageState.h" +#include "test/librados_test_stub/MockTestMemIoCtxImpl.h" +#include "test/librados_test_stub/MockTestMemRadosClient.h" +#include "include/rbd/librbd.hpp" +#include "librbd/Utils.h" +#include "librbd/image/TypeTraits.h" +#include "librbd/image/RemoveRequest.h" +#include "librbd/internal.h" +#include "librbd/trash/RemoveRequest.h" + +namespace librbd { +namespace { + +struct MockTestImageCtx : public MockImageCtx { + MockTestImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) { + } +}; + +} // anonymous namespace + +namespace image { + +// template <> +// struct TypeTraits<MockTestImageCtx> { +// typedef librbd::MockContextWQ ContextWQ; +// }; + +template <> +class RemoveRequest<MockTestImageCtx> { +private: + typedef ::librbd::image::TypeTraits<MockTestImageCtx> TypeTraits; + typedef typename TypeTraits::ContextWQ ContextWQ; +public: + static RemoveRequest *s_instance; + static RemoveRequest *create(librados::IoCtx &ioctx, + const std::string &image_name, + const std::string &image_id, + bool force, bool from_trash_remove, + ProgressContext &prog_ctx, + ContextWQ *op_work_queue, + Context *on_finish) { + ceph_assert(s_instance != nullptr); + s_instance->on_finish = on_finish; + return s_instance; + } + + static RemoveRequest *create(librados::IoCtx &ioctx, MockTestImageCtx *image_ctx, + bool force, bool from_trash_remove, + ProgressContext &prog_ctx, + ContextWQ *op_work_queue, + Context *on_finish) { + ceph_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<MockTestImageCtx> *RemoveRequest<MockTestImageCtx>::s_instance; + +} // namespace image +} // namespace librbd + +#include "librbd/trash/RemoveRequest.cc" + +namespace librbd { +namespace trash { + +using ::testing::_; +using ::testing::InSequence; +using ::testing::Invoke; +using ::testing::Return; +using ::testing::StrEq; + +struct TestMockTrashRemoveRequest : public TestMockFixture { + typedef RemoveRequest<librbd::MockTestImageCtx> MockRemoveRequest; + typedef image::RemoveRequest<librbd::MockTestImageCtx> MockImageRemoveRequest; + + NoOpProgressContext m_prog_ctx; + + void expect_set_state(MockTestImageCtx& mock_image_ctx, + cls::rbd::TrashImageState trash_set_state, + cls::rbd::TrashImageState trash_expect_state, + int r) { + bufferlist in_bl; + encode(mock_image_ctx.id, in_bl); + encode(trash_set_state, in_bl); + encode(trash_expect_state, in_bl); + + EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), + exec(StrEq("rbd_trash"), _, StrEq("rbd"), StrEq("trash_state_set"), + ContentsEqual(in_bl), _, _, _)) + .WillOnce(Return(r)); + } + + void expect_set_deleting_state(MockTestImageCtx& mock_image_ctx, int r) { + expect_set_state(mock_image_ctx, cls::rbd::TRASH_IMAGE_STATE_REMOVING, + cls::rbd::TRASH_IMAGE_STATE_NORMAL, r); + } + + void expect_restore_normal_state(MockTestImageCtx& mock_image_ctx, int r) { + expect_set_state(mock_image_ctx, cls::rbd::TRASH_IMAGE_STATE_NORMAL, + cls::rbd::TRASH_IMAGE_STATE_REMOVING, r); + } + + void expect_close_image(MockTestImageCtx &mock_image_ctx, int r) { + EXPECT_CALL(*mock_image_ctx.state, close(_)) + .WillOnce(Invoke([r](Context *on_finish) { + on_finish->complete(r); + })); + } + + void expect_remove_image(MockImageRemoveRequest& mock_image_remove_request, + int r) { + EXPECT_CALL(mock_image_remove_request, send()) + .WillOnce(Invoke([&mock_image_remove_request, r]() { + mock_image_remove_request.on_finish->complete(r); + })); + } + + void expect_remove_trash_entry(MockTestImageCtx& mock_image_ctx, + int r) { + bufferlist in_bl; + encode(mock_image_ctx.id, in_bl); + + EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), + exec(StrEq("rbd_trash"), _, StrEq("rbd"), StrEq("trash_remove"), + ContentsEqual(in_bl), _, _, _)) + .WillOnce(Return(r)); + } +}; + +TEST_F(TestMockTrashRemoveRequest, Success) { + REQUIRE_FORMAT_V2(); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + MockImageRemoveRequest mock_image_remove_request; + + InSequence seq; + expect_set_deleting_state(mock_image_ctx, 0); + expect_remove_image(mock_image_remove_request, 0); + expect_remove_trash_entry(mock_image_ctx, 0); + + C_SaferCond ctx; + auto req = MockRemoveRequest::create(mock_image_ctx.md_ctx, &mock_image_ctx, + nullptr, false, m_prog_ctx, &ctx); + req->send(); + ASSERT_EQ(0, ctx.wait()); +} +TEST_F(TestMockTrashRemoveRequest, SetDeletingStateError) { + REQUIRE_FORMAT_V2(); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + MockImageRemoveRequest mock_image_remove_request; + + InSequence seq; + expect_set_deleting_state(mock_image_ctx, -EINVAL); + expect_close_image(mock_image_ctx, 0); + + C_SaferCond ctx; + auto req = MockRemoveRequest::create(mock_image_ctx.md_ctx, &mock_image_ctx, + nullptr, false, m_prog_ctx, &ctx); + req->send(); + ASSERT_EQ(-EINVAL, ctx.wait()); +} + +TEST_F(TestMockTrashRemoveRequest, RemoveImageError) { + REQUIRE_FORMAT_V2(); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + MockImageRemoveRequest mock_image_remove_request; + + InSequence seq; + expect_set_deleting_state(mock_image_ctx, 0); + expect_remove_image(mock_image_remove_request, -EINVAL); + expect_restore_normal_state(mock_image_ctx, 0); + + C_SaferCond ctx; + auto req = MockRemoveRequest::create(mock_image_ctx.md_ctx, &mock_image_ctx, + nullptr, false, m_prog_ctx, &ctx); + req->send(); + ASSERT_EQ(-EINVAL, ctx.wait()); +} + +TEST_F(TestMockTrashRemoveRequest, RemoveTrashEntryError) { + REQUIRE_FORMAT_V2(); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + MockImageRemoveRequest mock_image_remove_request; + + InSequence seq; + expect_set_deleting_state(mock_image_ctx, 0); + expect_remove_image(mock_image_remove_request, 0); + expect_remove_trash_entry(mock_image_ctx, -EINVAL); + + C_SaferCond ctx; + auto req = MockRemoveRequest::create(mock_image_ctx.md_ctx, &mock_image_ctx, + nullptr, false, m_prog_ctx, &ctx); + req->send(); + ASSERT_EQ(0, ctx.wait()); +} + +} // namespace trash +} // namespace librbd |