1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "test/librbd/test_mock_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "test/librbd/mock/MockImageCtx.h"
7 #include "test/journal/mock/MockJournaler.h"
8 #include "common/ceph_mutex.h"
9 #include "cls/journal/cls_journal_types.h"
10 #include "librbd/journal/OpenRequest.h"
11 #include "librbd/journal/Types.h"
17 struct MockTestImageCtx
: public MockImageCtx
{
18 explicit MockTestImageCtx(librbd::ImageCtx
& image_ctx
) : MockImageCtx(image_ctx
) {
22 } // anonymous namespace
27 struct TypeTraits
<MockTestImageCtx
> {
28 typedef ::journal::MockJournaler Journaler
;
31 } // namespace journal
34 // template definitions
35 #include "librbd/journal/OpenRequest.cc"
36 template class librbd::journal::OpenRequest
<librbd::MockTestImageCtx
>;
42 using ::testing::DoAll
;
43 using ::testing::InSequence
;
44 using ::testing::Return
;
45 using ::testing::SetArgPointee
;
46 using ::testing::WithArg
;
48 class TestMockJournalOpenRequest
: public TestMockFixture
{
50 typedef OpenRequest
<MockTestImageCtx
> MockOpenRequest
;
52 TestMockJournalOpenRequest() = default;
54 void expect_init_journaler(::journal::MockJournaler
&mock_journaler
, int r
) {
55 EXPECT_CALL(mock_journaler
, init(_
))
56 .WillOnce(CompleteContext(r
, static_cast<asio::ContextWQ
*>(NULL
)));
59 void expect_get_journaler_cached_client(::journal::MockJournaler
&mock_journaler
,
61 journal::ImageClientMeta image_client_meta
;
62 image_client_meta
.tag_class
= 345;
64 journal::ClientData client_data
;
65 client_data
.client_meta
= image_client_meta
;
67 cls::journal::Client client
;
68 encode(client_data
, client
.data
);
70 EXPECT_CALL(mock_journaler
, get_cached_client("", _
))
71 .WillOnce(DoAll(SetArgPointee
<1>(client
),
75 void expect_get_journaler_tags(MockImageCtx
&mock_image_ctx
,
76 ::journal::MockJournaler
&mock_journaler
,
78 journal::TagData tag_data
;
79 tag_data
.mirror_uuid
= "remote mirror";
81 bufferlist tag_data_bl
;
82 encode(tag_data
, tag_data_bl
);
84 ::journal::Journaler::Tags tags
= {{0, 345, {}}, {1, 345, tag_data_bl
}};
85 EXPECT_CALL(mock_journaler
, get_tags(345, _
, _
))
86 .WillOnce(DoAll(SetArgPointee
<1>(tags
),
87 WithArg
<2>(CompleteContext(r
, mock_image_ctx
.image_ctx
->op_work_queue
))));
90 ceph::mutex m_lock
= ceph::make_mutex("m_lock");
91 ImageClientMeta m_client_meta
;
92 uint64_t m_tag_tid
= 0;
96 TEST_F(TestMockJournalOpenRequest
, Success
) {
97 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
99 librbd::ImageCtx
*ictx
;
100 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
102 MockTestImageCtx
mock_image_ctx(*ictx
);
103 ::journal::MockJournaler mock_journaler
;
105 expect_op_work_queue(mock_image_ctx
);
108 expect_init_journaler(mock_journaler
, 0);
109 expect_get_journaler_cached_client(mock_journaler
, 0);
110 expect_get_journaler_tags(mock_image_ctx
, mock_journaler
, 0);
113 auto req
= MockOpenRequest::create(&mock_image_ctx
, &mock_journaler
,
114 &m_lock
, &m_client_meta
, &m_tag_tid
,
117 ASSERT_EQ(0, ctx
.wait());
118 ASSERT_EQ(345U, m_client_meta
.tag_class
);
119 ASSERT_EQ(1U, m_tag_tid
);
120 ASSERT_EQ("remote mirror", m_tag_data
.mirror_uuid
);
123 TEST_F(TestMockJournalOpenRequest
, InitError
) {
124 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
126 librbd::ImageCtx
*ictx
;
127 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
129 MockTestImageCtx
mock_image_ctx(*ictx
);
130 ::journal::MockJournaler mock_journaler
;
132 expect_op_work_queue(mock_image_ctx
);
135 expect_init_journaler(mock_journaler
, -ENOENT
);
138 auto req
= MockOpenRequest::create(&mock_image_ctx
, &mock_journaler
,
139 &m_lock
, &m_client_meta
, &m_tag_tid
,
142 ASSERT_EQ(-ENOENT
, ctx
.wait());
145 TEST_F(TestMockJournalOpenRequest
, GetCachedClientError
) {
146 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
148 librbd::ImageCtx
*ictx
;
149 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
151 MockTestImageCtx
mock_image_ctx(*ictx
);
152 ::journal::MockJournaler mock_journaler
;
154 expect_op_work_queue(mock_image_ctx
);
157 expect_init_journaler(mock_journaler
, 0);
158 expect_get_journaler_cached_client(mock_journaler
, -EINVAL
);
161 auto req
= MockOpenRequest::create(&mock_image_ctx
, &mock_journaler
,
162 &m_lock
, &m_client_meta
, &m_tag_tid
,
165 ASSERT_EQ(-EINVAL
, ctx
.wait());
168 TEST_F(TestMockJournalOpenRequest
, GetTagsError
) {
169 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
171 librbd::ImageCtx
*ictx
;
172 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
174 MockTestImageCtx
mock_image_ctx(*ictx
);
175 ::journal::MockJournaler mock_journaler
;
177 expect_op_work_queue(mock_image_ctx
);
180 expect_init_journaler(mock_journaler
, 0);
181 expect_get_journaler_cached_client(mock_journaler
, 0);
182 expect_get_journaler_tags(mock_image_ctx
, mock_journaler
, -EBADMSG
);
185 auto req
= MockOpenRequest::create(&mock_image_ctx
, &mock_journaler
,
186 &m_lock
, &m_client_meta
, &m_tag_tid
,
189 ASSERT_EQ(-EBADMSG
, ctx
.wait());
192 } // namespace journal
193 } // namespace librbd