X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Ftest%2Flibrbd%2Ftest_mock_ObjectMap.cc;fp=src%2Fceph%2Fsrc%2Ftest%2Flibrbd%2Ftest_mock_ObjectMap.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=7deaef03bb8ea6cf587ccd6851394ada9d9d22a1;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/test/librbd/test_mock_ObjectMap.cc b/src/ceph/src/test/librbd/test_mock_ObjectMap.cc deleted file mode 100644 index 7deaef0..0000000 --- a/src/ceph/src/test/librbd/test_mock_ObjectMap.cc +++ /dev/null @@ -1,273 +0,0 @@ -// -*- 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 "librbd/ObjectMap.h" -#include "librbd/object_map/RefreshRequest.h" -#include "librbd/object_map/UnlockRequest.h" -#include "librbd/object_map/UpdateRequest.h" - -namespace librbd { - -namespace { - -struct MockTestImageCtx : public MockImageCtx { - MockTestImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) { - } -}; - -} // anonymous namespace - -namespace object_map { - -template <> -struct RefreshRequest { - Context *on_finish = nullptr; - ceph::BitVector<2u> *object_map = nullptr; - static RefreshRequest *s_instance; - static RefreshRequest *create(MockTestImageCtx &image_ctx, - ceph::BitVector<2u> *object_map, - uint64_t snap_id, Context *on_finish) { - assert(s_instance != nullptr); - s_instance->on_finish = on_finish; - s_instance->object_map = object_map; - return s_instance; - } - - MOCK_METHOD0(send, void()); - - RefreshRequest() { - s_instance = this; - } -}; - -template <> -struct UnlockRequest { - Context *on_finish = nullptr; - static UnlockRequest *s_instance; - static UnlockRequest *create(MockTestImageCtx &image_ctx, - Context *on_finish) { - assert(s_instance != nullptr); - s_instance->on_finish = on_finish; - return s_instance; - } - - MOCK_METHOD0(send, void()); - UnlockRequest() { - s_instance = this; - } -}; - -template <> -struct UpdateRequest { - Context *on_finish = nullptr; - static UpdateRequest *s_instance; - static UpdateRequest *create(MockTestImageCtx &image_ctx, - ceph::BitVector<2u> *object_map, - uint64_t snap_id, - uint64_t start_object_no, uint64_t end_object_no, - uint8_t new_state, - const boost::optional ¤t_state, - const ZTracer::Trace &parent_trace, - Context *on_finish) { - assert(s_instance != nullptr); - s_instance->on_finish = on_finish; - s_instance->construct(snap_id, start_object_no, end_object_no, new_state, - current_state); - return s_instance; - } - - MOCK_METHOD5(construct, void(uint64_t snap_id, uint64_t start_object_no, - uint64_t end_object_no, uint8_t new_state, - const boost::optional ¤t_state)); - MOCK_METHOD0(send, void()); - UpdateRequest() { - s_instance = this; - } -}; - -RefreshRequest *RefreshRequest::s_instance = nullptr; -UnlockRequest *UnlockRequest::s_instance = nullptr; -UpdateRequest *UpdateRequest::s_instance = nullptr; - -} // namespace object_map -} // namespace librbd - -#include "librbd/ObjectMap.cc" - -namespace librbd { - -using testing::_; -using testing::InSequence; -using testing::Invoke; - -class TestMockObjectMap : public TestMockFixture { -public: - typedef ObjectMap MockObjectMap; - typedef object_map::RefreshRequest MockRefreshRequest; - typedef object_map::UnlockRequest MockUnlockRequest; - typedef object_map::UpdateRequest MockUpdateRequest; - - void expect_refresh(MockTestImageCtx &mock_image_ctx, - MockRefreshRequest &mock_refresh_request, - const ceph::BitVector<2u> &object_map, int r) { - EXPECT_CALL(mock_refresh_request, send()) - .WillOnce(Invoke([&mock_image_ctx, &mock_refresh_request, &object_map, r]() { - *mock_refresh_request.object_map = object_map; - mock_image_ctx.image_ctx->op_work_queue->queue(mock_refresh_request.on_finish, r); - })); - } - - void expect_unlock(MockTestImageCtx &mock_image_ctx, - MockUnlockRequest &mock_unlock_request, int r) { - EXPECT_CALL(mock_unlock_request, send()) - .WillOnce(Invoke([&mock_image_ctx, &mock_unlock_request, r]() { - mock_image_ctx.image_ctx->op_work_queue->queue(mock_unlock_request.on_finish, r); - })); - } - - void expect_update(MockTestImageCtx &mock_image_ctx, - MockUpdateRequest &mock_update_request, - uint64_t snap_id, uint64_t start_object_no, - uint64_t end_object_no, uint8_t new_state, - const boost::optional ¤t_state, - Context **on_finish) { - EXPECT_CALL(mock_update_request, construct(snap_id, start_object_no, - end_object_no, new_state, - current_state)) - .Times(1); - EXPECT_CALL(mock_update_request, send()) - .WillOnce(Invoke([&mock_image_ctx, &mock_update_request, on_finish]() { - *on_finish = mock_update_request.on_finish; - })); - } - -}; - -TEST_F(TestMockObjectMap, NonDetainedUpdate) { - REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP); - - librbd::ImageCtx *ictx; - ASSERT_EQ(0, open_image(m_image_name, &ictx)); - - MockTestImageCtx mock_image_ctx(*ictx); - - InSequence seq; - ceph::BitVector<2u> object_map; - object_map.resize(4); - MockRefreshRequest mock_refresh_request; - expect_refresh(mock_image_ctx, mock_refresh_request, object_map, 0); - - MockUpdateRequest mock_update_request; - Context *finish_update_1; - expect_update(mock_image_ctx, mock_update_request, CEPH_NOSNAP, - 0, 1, 1, {}, &finish_update_1); - Context *finish_update_2; - expect_update(mock_image_ctx, mock_update_request, CEPH_NOSNAP, - 1, 2, 1, {}, &finish_update_2); - - MockUnlockRequest mock_unlock_request; - expect_unlock(mock_image_ctx, mock_unlock_request, 0); - - MockObjectMap mock_object_map(mock_image_ctx, CEPH_NOSNAP); - C_SaferCond open_ctx; - mock_object_map.open(&open_ctx); - ASSERT_EQ(0, open_ctx.wait()); - - C_SaferCond update_ctx1; - C_SaferCond update_ctx2; - { - RWLock::RLocker snap_locker(mock_image_ctx.snap_lock); - RWLock::WLocker object_map_locker(mock_image_ctx.object_map_lock); - mock_object_map.aio_update(CEPH_NOSNAP, 0, 1, {}, {}, &update_ctx1); - mock_object_map.aio_update(CEPH_NOSNAP, 1, 1, {}, {}, &update_ctx2); - } - - finish_update_2->complete(0); - ASSERT_EQ(0, update_ctx2.wait()); - - finish_update_1->complete(0); - ASSERT_EQ(0, update_ctx1.wait()); - - C_SaferCond close_ctx; - mock_object_map.close(&close_ctx); - ASSERT_EQ(0, close_ctx.wait()); -} - -TEST_F(TestMockObjectMap, DetainedUpdate) { - REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP); - - librbd::ImageCtx *ictx; - ASSERT_EQ(0, open_image(m_image_name, &ictx)); - - MockTestImageCtx mock_image_ctx(*ictx); - - InSequence seq; - ceph::BitVector<2u> object_map; - object_map.resize(4); - MockRefreshRequest mock_refresh_request; - expect_refresh(mock_image_ctx, mock_refresh_request, object_map, 0); - - MockUpdateRequest mock_update_request; - Context *finish_update_1; - expect_update(mock_image_ctx, mock_update_request, CEPH_NOSNAP, - 1, 4, 1, {}, &finish_update_1); - Context *finish_update_2 = nullptr; - expect_update(mock_image_ctx, mock_update_request, CEPH_NOSNAP, - 1, 3, 1, {}, &finish_update_2); - Context *finish_update_3 = nullptr; - expect_update(mock_image_ctx, mock_update_request, CEPH_NOSNAP, - 2, 3, 1, {}, &finish_update_3); - Context *finish_update_4 = nullptr; - expect_update(mock_image_ctx, mock_update_request, CEPH_NOSNAP, - 0, 2, 1, {}, &finish_update_4); - - MockUnlockRequest mock_unlock_request; - expect_unlock(mock_image_ctx, mock_unlock_request, 0); - - MockObjectMap mock_object_map(mock_image_ctx, CEPH_NOSNAP); - C_SaferCond open_ctx; - mock_object_map.open(&open_ctx); - ASSERT_EQ(0, open_ctx.wait()); - - C_SaferCond update_ctx1; - C_SaferCond update_ctx2; - C_SaferCond update_ctx3; - C_SaferCond update_ctx4; - { - RWLock::RLocker snap_locker(mock_image_ctx.snap_lock); - RWLock::WLocker object_map_locker(mock_image_ctx.object_map_lock); - mock_object_map.aio_update(CEPH_NOSNAP, 1, 4, 1, {}, {}, &update_ctx1); - mock_object_map.aio_update(CEPH_NOSNAP, 1, 3, 1, {}, {}, &update_ctx2); - mock_object_map.aio_update(CEPH_NOSNAP, 2, 3, 1, {}, {}, &update_ctx3); - mock_object_map.aio_update(CEPH_NOSNAP, 0, 2, 1, {}, {}, &update_ctx4); - } - - // updates 2, 3, and 4 are blocked on update 1 - ASSERT_EQ(nullptr, finish_update_2); - finish_update_1->complete(0); - ASSERT_EQ(0, update_ctx1.wait()); - - // updates 3 and 4 are blocked on update 2 - ASSERT_NE(nullptr, finish_update_2); - ASSERT_EQ(nullptr, finish_update_3); - ASSERT_EQ(nullptr, finish_update_4); - finish_update_2->complete(0); - ASSERT_EQ(0, update_ctx2.wait()); - - ASSERT_NE(nullptr, finish_update_3); - ASSERT_NE(nullptr, finish_update_4); - finish_update_3->complete(0); - finish_update_4->complete(0); - ASSERT_EQ(0, update_ctx3.wait()); - ASSERT_EQ(0, update_ctx4.wait()); - - C_SaferCond close_ctx; - mock_object_map.close(&close_ctx); - ASSERT_EQ(0, close_ctx.wait()); -} - -} // namespace librbd -