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 "librbd/journal/Types.h"
6 #include "librbd/journal/TypeTraits.h"
7 #include "tools/rbd_mirror/Threads.h"
8 #include "tools/rbd_mirror/image_replayer/journal/EventPreprocessor.h"
9 #include "test/journal/mock/MockJournaler.h"
10 #include "test/librbd/mock/MockImageCtx.h"
16 struct MockTestImageCtx
: public librbd::MockImageCtx
{
17 explicit MockTestImageCtx(librbd::ImageCtx
&image_ctx
)
18 : librbd::MockImageCtx(image_ctx
) {
22 } // anonymous namespace
27 struct TypeTraits
<librbd::MockTestImageCtx
> {
28 typedef ::journal::MockJournaler Journaler
;
31 } // namespace journal
34 // template definitions
35 #include "tools/rbd_mirror/image_replayer/journal/EventPreprocessor.cc"
39 namespace image_replayer
{
43 using testing::WithArg
;
45 class TestMockImageReplayerJournalEventPreprocessor
: public TestMockFixture
{
47 typedef EventPreprocessor
<librbd::MockTestImageCtx
> MockEventPreprocessor
;
49 void SetUp() override
{
50 TestMockFixture::SetUp();
53 ASSERT_EQ(0, create_image(rbd
, m_local_io_ctx
, m_image_name
, m_image_size
));
54 ASSERT_EQ(0, open_image(m_local_io_ctx
, m_image_name
, &m_local_image_ctx
));
57 void expect_image_refresh(librbd::MockTestImageCtx
&mock_remote_image_ctx
, int r
) {
58 EXPECT_CALL(*mock_remote_image_ctx
.state
, refresh(_
))
59 .WillOnce(CompleteContext(r
));
62 void expect_update_client(::journal::MockJournaler
&mock_journaler
, int r
) {
63 EXPECT_CALL(mock_journaler
, update_client(_
, _
))
64 .WillOnce(WithArg
<1>(CompleteContext(r
)));
67 librbd::ImageCtx
*m_local_image_ctx
;
68 librbd::journal::MirrorPeerClientMeta m_client_meta
;
72 TEST_F(TestMockImageReplayerJournalEventPreprocessor
, IsNotRequired
) {
73 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
74 ::journal::MockJournaler mock_remote_journaler
;
76 MockEventPreprocessor
event_preprocessor(mock_local_image_ctx
,
77 mock_remote_journaler
,
80 m_threads
->work_queue
);
82 librbd::journal::EventEntry event_entry
{librbd::journal::RenameEvent
{}};
83 ASSERT_FALSE(event_preprocessor
.is_required(event_entry
));
86 TEST_F(TestMockImageReplayerJournalEventPreprocessor
, IsRequiredSnapMapPrune
) {
87 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
88 ::journal::MockJournaler mock_remote_journaler
;
90 m_client_meta
.snap_seqs
= {{1, 2}, {3, 4}};
91 MockEventPreprocessor
event_preprocessor(mock_local_image_ctx
,
92 mock_remote_journaler
,
95 m_threads
->work_queue
);
97 librbd::journal::EventEntry event_entry
{librbd::journal::RenameEvent
{}};
98 ASSERT_TRUE(event_preprocessor
.is_required(event_entry
));
101 TEST_F(TestMockImageReplayerJournalEventPreprocessor
, IsRequiredSnapRename
) {
102 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
103 ::journal::MockJournaler mock_remote_journaler
;
105 MockEventPreprocessor
event_preprocessor(mock_local_image_ctx
,
106 mock_remote_journaler
,
109 m_threads
->work_queue
);
111 librbd::journal::EventEntry event_entry
{librbd::journal::SnapRenameEvent
{}};
112 ASSERT_TRUE(event_preprocessor
.is_required(event_entry
));
115 TEST_F(TestMockImageReplayerJournalEventPreprocessor
, PreprocessSnapMapPrune
) {
116 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
117 ::journal::MockJournaler mock_remote_journaler
;
119 expect_image_refresh(mock_local_image_ctx
, 0);
120 expect_update_client(mock_remote_journaler
, 0);
122 mock_local_image_ctx
.snap_info
= {
123 {6, librbd::SnapInfo
{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}};
124 m_client_meta
.snap_seqs
= {{1, 2}, {3, 4}, {5, 6}};
125 MockEventPreprocessor
event_preprocessor(mock_local_image_ctx
,
126 mock_remote_journaler
,
129 m_threads
->work_queue
);
131 librbd::journal::EventEntry event_entry
{librbd::journal::RenameEvent
{}};
133 event_preprocessor
.preprocess(&event_entry
, &ctx
);
134 ASSERT_EQ(0, ctx
.wait());
136 librbd::SnapSeqs expected_snap_seqs
= {{5, 6}};
137 ASSERT_EQ(expected_snap_seqs
, m_client_meta
.snap_seqs
);
140 TEST_F(TestMockImageReplayerJournalEventPreprocessor
, PreprocessSnapRename
) {
141 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
142 ::journal::MockJournaler mock_remote_journaler
;
144 expect_image_refresh(mock_local_image_ctx
, 0);
145 expect_update_client(mock_remote_journaler
, 0);
147 mock_local_image_ctx
.snap_ids
= {{{cls::rbd::UserSnapshotNamespace(), "snap"}, 6}};
148 mock_local_image_ctx
.snap_info
= {
149 {6, librbd::SnapInfo
{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}};
150 MockEventPreprocessor
event_preprocessor(mock_local_image_ctx
,
151 mock_remote_journaler
,
154 m_threads
->work_queue
);
156 librbd::journal::EventEntry event_entry
{
157 librbd::journal::SnapRenameEvent
{0, 5, "snap", "new_snap"}};
159 event_preprocessor
.preprocess(&event_entry
, &ctx
);
160 ASSERT_EQ(0, ctx
.wait());
162 librbd::SnapSeqs expected_snap_seqs
= {{5, 6}};
163 ASSERT_EQ(expected_snap_seqs
, m_client_meta
.snap_seqs
);
165 librbd::journal::SnapRenameEvent
*event
=
166 boost::get
<librbd::journal::SnapRenameEvent
>(&event_entry
.event
);
167 ASSERT_EQ(6U, event
->snap_id
);
170 TEST_F(TestMockImageReplayerJournalEventPreprocessor
, PreprocessSnapRenameMissing
) {
171 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
172 ::journal::MockJournaler mock_remote_journaler
;
174 expect_image_refresh(mock_local_image_ctx
, 0);
176 MockEventPreprocessor
event_preprocessor(mock_local_image_ctx
,
177 mock_remote_journaler
,
180 m_threads
->work_queue
);
182 librbd::journal::EventEntry event_entry
{
183 librbd::journal::SnapRenameEvent
{0, 5, "snap", "new_snap"}};
185 event_preprocessor
.preprocess(&event_entry
, &ctx
);
186 ASSERT_EQ(-ENOENT
, ctx
.wait());
188 librbd::journal::SnapRenameEvent
*event
=
189 boost::get
<librbd::journal::SnapRenameEvent
>(&event_entry
.event
);
190 ASSERT_EQ(CEPH_NOSNAP
, event
->snap_id
);
193 TEST_F(TestMockImageReplayerJournalEventPreprocessor
, PreprocessSnapRenameKnown
) {
194 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
195 ::journal::MockJournaler mock_remote_journaler
;
197 expect_image_refresh(mock_local_image_ctx
, 0);
199 mock_local_image_ctx
.snap_info
= {
200 {6, librbd::SnapInfo
{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}};
201 m_client_meta
.snap_seqs
= {{5, 6}};
202 MockEventPreprocessor
event_preprocessor(mock_local_image_ctx
,
203 mock_remote_journaler
,
206 m_threads
->work_queue
);
208 librbd::journal::EventEntry event_entry
{
209 librbd::journal::SnapRenameEvent
{0, 5, "snap", "new_snap"}};
211 event_preprocessor
.preprocess(&event_entry
, &ctx
);
212 ASSERT_EQ(0, ctx
.wait());
214 librbd::SnapSeqs expected_snap_seqs
= {{5, 6}};
215 ASSERT_EQ(expected_snap_seqs
, m_client_meta
.snap_seqs
);
217 librbd::journal::SnapRenameEvent
*event
=
218 boost::get
<librbd::journal::SnapRenameEvent
>(&event_entry
.event
);
219 ASSERT_EQ(6U, event
->snap_id
);
222 TEST_F(TestMockImageReplayerJournalEventPreprocessor
, PreprocessRefreshError
) {
223 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
224 ::journal::MockJournaler mock_remote_journaler
;
226 expect_image_refresh(mock_local_image_ctx
, -EINVAL
);
228 MockEventPreprocessor
event_preprocessor(mock_local_image_ctx
,
229 mock_remote_journaler
,
232 m_threads
->work_queue
);
234 librbd::journal::EventEntry event_entry
{librbd::journal::RenameEvent
{}};
236 event_preprocessor
.preprocess(&event_entry
, &ctx
);
237 ASSERT_EQ(-EINVAL
, ctx
.wait());
240 TEST_F(TestMockImageReplayerJournalEventPreprocessor
, PreprocessClientUpdateError
) {
241 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
242 ::journal::MockJournaler mock_remote_journaler
;
244 expect_image_refresh(mock_local_image_ctx
, 0);
245 expect_update_client(mock_remote_journaler
, -EINVAL
);
247 mock_local_image_ctx
.snap_ids
= {{{cls::rbd::UserSnapshotNamespace(), "snap"}, 6}};
248 mock_local_image_ctx
.snap_info
= {
249 {6, librbd::SnapInfo
{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}};
250 MockEventPreprocessor
event_preprocessor(mock_local_image_ctx
,
251 mock_remote_journaler
,
254 m_threads
->work_queue
);
256 librbd::journal::EventEntry event_entry
{
257 librbd::journal::SnapRenameEvent
{0, 5, "snap", "new_snap"}};
259 event_preprocessor
.preprocess(&event_entry
, &ctx
);
260 ASSERT_EQ(-EINVAL
, ctx
.wait());
263 } // namespace journal
264 } // namespace image_replayer
265 } // namespace mirror