]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
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/Mutex.h" | |
9 | #include "cls/journal/cls_journal_types.h" | |
10 | #include "librbd/journal/OpenRequest.h" | |
11 | #include "librbd/journal/Types.h" | |
12 | ||
13 | namespace librbd { | |
14 | ||
15 | namespace { | |
16 | ||
17 | struct MockTestImageCtx : public MockImageCtx { | |
18 | MockTestImageCtx(librbd::ImageCtx& image_ctx) : MockImageCtx(image_ctx) { | |
19 | } | |
20 | }; | |
21 | ||
22 | } // anonymous namespace | |
23 | ||
24 | namespace journal { | |
25 | ||
26 | template <> | |
27 | struct TypeTraits<MockTestImageCtx> { | |
28 | typedef ::journal::MockJournaler Journaler; | |
29 | }; | |
30 | ||
31 | } // namespace journal | |
32 | } // namespace librbd | |
33 | ||
34 | // template definitions | |
35 | #include "librbd/journal/OpenRequest.cc" | |
36 | template class librbd::journal::OpenRequest<librbd::MockTestImageCtx>; | |
37 | ||
38 | namespace librbd { | |
39 | namespace journal { | |
40 | ||
41 | using ::testing::_; | |
42 | using ::testing::DoAll; | |
43 | using ::testing::InSequence; | |
44 | using ::testing::Return; | |
45 | using ::testing::SetArgPointee; | |
46 | using ::testing::WithArg; | |
47 | ||
48 | class TestMockJournalOpenRequest : public TestMockFixture { | |
49 | public: | |
50 | typedef OpenRequest<MockTestImageCtx> MockOpenRequest; | |
51 | ||
52 | TestMockJournalOpenRequest() : m_lock("m_lock") { | |
53 | } | |
54 | ||
55 | void expect_init_journaler(::journal::MockJournaler &mock_journaler, int r) { | |
56 | EXPECT_CALL(mock_journaler, init(_)) | |
57 | .WillOnce(CompleteContext(r, static_cast<ContextWQ*>(NULL))); | |
58 | } | |
59 | ||
60 | void expect_get_journaler_cached_client(::journal::MockJournaler &mock_journaler, | |
61 | int r) { | |
62 | journal::ImageClientMeta image_client_meta; | |
63 | image_client_meta.tag_class = 345; | |
64 | ||
65 | journal::ClientData client_data; | |
66 | client_data.client_meta = image_client_meta; | |
67 | ||
68 | cls::journal::Client client; | |
69 | ::encode(client_data, client.data); | |
70 | ||
71 | EXPECT_CALL(mock_journaler, get_cached_client("", _)) | |
72 | .WillOnce(DoAll(SetArgPointee<1>(client), | |
73 | Return(r))); | |
74 | } | |
75 | ||
76 | void expect_get_journaler_tags(MockImageCtx &mock_image_ctx, | |
77 | ::journal::MockJournaler &mock_journaler, | |
78 | int r) { | |
79 | journal::TagData tag_data; | |
80 | tag_data.mirror_uuid = "remote mirror"; | |
81 | ||
82 | bufferlist tag_data_bl; | |
83 | ::encode(tag_data, tag_data_bl); | |
84 | ||
85 | ::journal::Journaler::Tags tags = {{0, 345, {}}, {1, 345, tag_data_bl}}; | |
86 | EXPECT_CALL(mock_journaler, get_tags(345, _, _)) | |
87 | .WillOnce(DoAll(SetArgPointee<1>(tags), | |
88 | WithArg<2>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)))); | |
89 | } | |
90 | ||
91 | Mutex m_lock; | |
92 | ImageClientMeta m_client_meta; | |
93 | uint64_t m_tag_tid = 0; | |
94 | TagData m_tag_data; | |
95 | }; | |
96 | ||
97 | TEST_F(TestMockJournalOpenRequest, Success) { | |
98 | REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); | |
99 | ||
100 | librbd::ImageCtx *ictx; | |
101 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
102 | ||
103 | MockTestImageCtx mock_image_ctx(*ictx); | |
104 | ::journal::MockJournaler mock_journaler; | |
105 | ||
106 | expect_op_work_queue(mock_image_ctx); | |
107 | ||
108 | InSequence seq; | |
109 | expect_init_journaler(mock_journaler, 0); | |
110 | expect_get_journaler_cached_client(mock_journaler, 0); | |
111 | expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); | |
112 | ||
113 | C_SaferCond ctx; | |
114 | auto req = MockOpenRequest::create(&mock_image_ctx, &mock_journaler, | |
115 | &m_lock, &m_client_meta, &m_tag_tid, | |
116 | &m_tag_data, &ctx); | |
117 | req->send(); | |
118 | ASSERT_EQ(0, ctx.wait()); | |
119 | ASSERT_EQ(345U, m_client_meta.tag_class); | |
120 | ASSERT_EQ(1U, m_tag_tid); | |
121 | ASSERT_EQ("remote mirror", m_tag_data.mirror_uuid); | |
122 | } | |
123 | ||
124 | TEST_F(TestMockJournalOpenRequest, InitError) { | |
125 | REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); | |
126 | ||
127 | librbd::ImageCtx *ictx; | |
128 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
129 | ||
130 | MockTestImageCtx mock_image_ctx(*ictx); | |
131 | ::journal::MockJournaler mock_journaler; | |
132 | ||
133 | expect_op_work_queue(mock_image_ctx); | |
134 | ||
135 | InSequence seq; | |
136 | expect_init_journaler(mock_journaler, -ENOENT); | |
137 | ||
138 | C_SaferCond ctx; | |
139 | auto req = MockOpenRequest::create(&mock_image_ctx, &mock_journaler, | |
140 | &m_lock, &m_client_meta, &m_tag_tid, | |
141 | &m_tag_data, &ctx); | |
142 | req->send(); | |
143 | ASSERT_EQ(-ENOENT, ctx.wait()); | |
144 | } | |
145 | ||
146 | TEST_F(TestMockJournalOpenRequest, GetCachedClientError) { | |
147 | REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); | |
148 | ||
149 | librbd::ImageCtx *ictx; | |
150 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
151 | ||
152 | MockTestImageCtx mock_image_ctx(*ictx); | |
153 | ::journal::MockJournaler mock_journaler; | |
154 | ||
155 | expect_op_work_queue(mock_image_ctx); | |
156 | ||
157 | InSequence seq; | |
158 | expect_init_journaler(mock_journaler, 0); | |
159 | expect_get_journaler_cached_client(mock_journaler, -EINVAL); | |
160 | ||
161 | C_SaferCond ctx; | |
162 | auto req = MockOpenRequest::create(&mock_image_ctx, &mock_journaler, | |
163 | &m_lock, &m_client_meta, &m_tag_tid, | |
164 | &m_tag_data, &ctx); | |
165 | req->send(); | |
166 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
167 | } | |
168 | ||
169 | TEST_F(TestMockJournalOpenRequest, GetTagsError) { | |
170 | REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); | |
171 | ||
172 | librbd::ImageCtx *ictx; | |
173 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
174 | ||
175 | MockTestImageCtx mock_image_ctx(*ictx); | |
176 | ::journal::MockJournaler mock_journaler; | |
177 | ||
178 | expect_op_work_queue(mock_image_ctx); | |
179 | ||
180 | InSequence seq; | |
181 | expect_init_journaler(mock_journaler, 0); | |
182 | expect_get_journaler_cached_client(mock_journaler, 0); | |
183 | expect_get_journaler_tags(mock_image_ctx, mock_journaler, -EBADMSG); | |
184 | ||
185 | C_SaferCond ctx; | |
186 | auto req = MockOpenRequest::create(&mock_image_ctx, &mock_journaler, | |
187 | &m_lock, &m_client_meta, &m_tag_tid, | |
188 | &m_tag_data, &ctx); | |
189 | req->send(); | |
190 | ASSERT_EQ(-EBADMSG, ctx.wait()); | |
191 | } | |
192 | ||
193 | } // namespace journal | |
194 | } // namespace librbd |