1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "test/rbd_mirror/test_mock_fixture.h"
5 #include "cls/rbd/cls_rbd_types.h"
6 #include "librbd/journal/TypeTraits.h"
7 #include "tools/rbd_mirror/image_replayer/GetMirrorImageIdRequest.h"
8 #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.h"
9 #include "test/journal/mock/MockJournaler.h"
10 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
11 #include "test/librbd/mock/MockImageCtx.h"
12 #include "test/librbd/mock/MockJournal.h"
18 struct MockTestImageCtx
: public librbd::MockImageCtx
{
19 MockTestImageCtx(librbd::ImageCtx
&image_ctx
)
20 : librbd::MockImageCtx(image_ctx
) {
24 } // anonymous namespace
29 namespace image_replayer
{
32 struct GetMirrorImageIdRequest
<librbd::MockTestImageCtx
> {
33 static GetMirrorImageIdRequest
* s_instance
;
34 std::string
* image_id
= nullptr;
35 Context
* on_finish
= nullptr;
37 static GetMirrorImageIdRequest
* create(librados::IoCtx
& io_ctx
,
38 const std::string
& global_image_id
,
39 std::string
* image_id
,
41 assert(s_instance
!= nullptr);
42 s_instance
->image_id
= image_id
;
43 s_instance
->on_finish
= on_finish
;
47 GetMirrorImageIdRequest() {
51 MOCK_METHOD0(send
, void());
54 GetMirrorImageIdRequest
<librbd::MockTestImageCtx
>* GetMirrorImageIdRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
56 } // namespace image_replayer
60 // template definitions
61 #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc"
65 namespace image_replayer
{
68 using ::testing::DoAll
;
69 using ::testing::InSequence
;
70 using ::testing::Invoke
;
71 using ::testing::Return
;
72 using ::testing::StrEq
;
73 using ::testing::WithArg
;
74 using ::testing::WithArgs
;
76 class TestMockImageReplayerPrepareLocalImageRequest
: public TestMockFixture
{
78 typedef PrepareLocalImageRequest
<librbd::MockTestImageCtx
> MockPrepareLocalImageRequest
;
79 typedef GetMirrorImageIdRequest
<librbd::MockTestImageCtx
> MockGetMirrorImageIdRequest
;
81 void expect_get_mirror_image_id(MockGetMirrorImageIdRequest
& mock_get_mirror_image_id_request
,
82 const std::string
& image_id
, int r
) {
83 EXPECT_CALL(mock_get_mirror_image_id_request
, send())
84 .WillOnce(Invoke([&mock_get_mirror_image_id_request
, image_id
, r
]() {
85 *mock_get_mirror_image_id_request
.image_id
= image_id
;
86 mock_get_mirror_image_id_request
.on_finish
->complete(r
);
90 void expect_mirror_image_get(librados::IoCtx
&io_ctx
,
91 cls::rbd::MirrorImageState state
,
92 const std::string
&global_id
, int r
) {
93 cls::rbd::MirrorImage mirror_image
;
94 mirror_image
.state
= state
;
95 mirror_image
.global_image_id
= global_id
;
98 ::encode(mirror_image
, bl
);
100 EXPECT_CALL(get_mock_io_ctx(io_ctx
),
101 exec(RBD_MIRRORING
, _
, StrEq("rbd"), StrEq("mirror_image_get"), _
, _
, _
))
102 .WillOnce(DoAll(WithArg
<5>(Invoke([bl
](bufferlist
*out_bl
) {
108 void expect_get_tag_owner(librbd::MockJournal
&mock_journal
,
109 const std::string
&local_image_id
,
110 const std::string
&tag_owner
, int r
) {
111 EXPECT_CALL(mock_journal
, get_tag_owner(local_image_id
, _
, _
, _
))
112 .WillOnce(WithArgs
<1, 3>(Invoke([tag_owner
, r
](std::string
*owner
, Context
*on_finish
) {
114 on_finish
->complete(r
);
120 TEST_F(TestMockImageReplayerPrepareLocalImageRequest
, Success
) {
122 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request
;
123 expect_get_mirror_image_id(mock_get_mirror_image_id_request
, "local image id",
125 expect_mirror_image_get(m_local_io_ctx
, cls::rbd::MIRROR_IMAGE_STATE_ENABLED
,
126 "global image id", 0);
128 librbd::MockJournal mock_journal
;
129 expect_get_tag_owner(mock_journal
, "local image id", "remote mirror uuid", 0);
131 std::string local_image_id
;
132 std::string tag_owner
;
134 auto req
= MockPrepareLocalImageRequest::create(m_local_io_ctx
,
138 m_threads
->work_queue
,
142 ASSERT_EQ(0, ctx
.wait());
143 ASSERT_EQ(std::string("local image id"), local_image_id
);
144 ASSERT_EQ(std::string("remote mirror uuid"), tag_owner
);
147 TEST_F(TestMockImageReplayerPrepareLocalImageRequest
, MirrorImageIdError
) {
149 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request
;
150 expect_get_mirror_image_id(mock_get_mirror_image_id_request
, "", -EINVAL
);
152 std::string local_image_id
;
153 std::string tag_owner
;
155 auto req
= MockPrepareLocalImageRequest::create(m_local_io_ctx
,
159 m_threads
->work_queue
,
163 ASSERT_EQ(-EINVAL
, ctx
.wait());
166 TEST_F(TestMockImageReplayerPrepareLocalImageRequest
, MirrorImageError
) {
168 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request
;
169 expect_get_mirror_image_id(mock_get_mirror_image_id_request
, "local image id",
171 expect_mirror_image_get(m_local_io_ctx
, cls::rbd::MIRROR_IMAGE_STATE_DISABLED
,
174 std::string local_image_id
;
175 std::string tag_owner
;
177 auto req
= MockPrepareLocalImageRequest::create(m_local_io_ctx
,
181 m_threads
->work_queue
,
185 ASSERT_EQ(-EINVAL
, ctx
.wait());
188 TEST_F(TestMockImageReplayerPrepareLocalImageRequest
, TagOwnerError
) {
190 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request
;
191 expect_get_mirror_image_id(mock_get_mirror_image_id_request
, "local image id",
193 expect_mirror_image_get(m_local_io_ctx
, cls::rbd::MIRROR_IMAGE_STATE_ENABLED
,
194 "global image id", 0);
196 librbd::MockJournal mock_journal
;
197 expect_get_tag_owner(mock_journal
, "local image id", "remote mirror uuid",
200 std::string local_image_id
;
201 std::string tag_owner
;
203 auto req
= MockPrepareLocalImageRequest::create(m_local_io_ctx
,
207 m_threads
->work_queue
,
211 ASSERT_EQ(-ENOENT
, ctx
.wait());
214 } // namespace image_replayer
215 } // namespace mirror