]>
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/rbd_mirror/test_mock_fixture.h" | |
5 | #include "include/rbd/librbd.hpp" | |
6 | #include "librbd/journal/Types.h" | |
7 | #include "librbd/journal/TypeTraits.h" | |
8 | #include "test/journal/mock/MockJournaler.h" | |
9 | #include "test/librados_test_stub/MockTestMemIoCtxImpl.h" | |
10 | #include "test/librbd/mock/MockImageCtx.h" | |
11 | #include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.h" | |
12 | ||
13 | namespace librbd { | |
14 | ||
15 | namespace { | |
16 | ||
17 | struct MockTestImageCtx : public librbd::MockImageCtx { | |
11fdf7f2 | 18 | explicit MockTestImageCtx(librbd::ImageCtx &image_ctx) |
7c673cae FG |
19 | : librbd::MockImageCtx(image_ctx) { |
20 | } | |
21 | }; | |
22 | ||
23 | } // anonymous namespace | |
24 | ||
25 | namespace journal { | |
26 | ||
27 | template <> | |
28 | struct TypeTraits<librbd::MockTestImageCtx> { | |
29 | typedef ::journal::MockJournaler Journaler; | |
30 | }; | |
31 | ||
32 | } // namespace journal | |
33 | } // namespace librbd | |
34 | ||
35 | // template definitions | |
36 | #include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.cc" | |
37 | template class rbd::mirror::image_sync::SyncPointCreateRequest<librbd::MockTestImageCtx>; | |
38 | ||
39 | namespace rbd { | |
40 | namespace mirror { | |
41 | namespace image_sync { | |
42 | ||
43 | using ::testing::_; | |
44 | using ::testing::InSequence; | |
45 | using ::testing::WithArg; | |
46 | ||
47 | class TestMockImageSyncSyncPointCreateRequest : public TestMockFixture { | |
48 | public: | |
49 | typedef SyncPointCreateRequest<librbd::MockTestImageCtx> MockSyncPointCreateRequest; | |
50 | ||
51 | void SetUp() override { | |
52 | TestMockFixture::SetUp(); | |
53 | ||
54 | librbd::RBD rbd; | |
55 | ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size)); | |
56 | ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx)); | |
57 | } | |
58 | ||
59 | void expect_update_client(journal::MockJournaler &mock_journaler, int r) { | |
60 | EXPECT_CALL(mock_journaler, update_client(_, _)) | |
61 | .WillOnce(WithArg<1>(CompleteContext(r))); | |
62 | } | |
63 | ||
64 | void expect_image_refresh(librbd::MockTestImageCtx &mock_remote_image_ctx, int r) { | |
65 | EXPECT_CALL(*mock_remote_image_ctx.state, refresh(_)) | |
66 | .WillOnce(CompleteContext(r)); | |
67 | } | |
68 | ||
69 | void expect_snap_create(librbd::MockTestImageCtx &mock_remote_image_ctx, int r) { | |
70 | EXPECT_CALL(*mock_remote_image_ctx.operations, snap_create(_, _, _)) | |
71 | .WillOnce(WithArg<2>(CompleteContext(r))); | |
72 | } | |
73 | ||
74 | MockSyncPointCreateRequest *create_request(librbd::MockTestImageCtx &mock_remote_image_ctx, | |
75 | journal::MockJournaler &mock_journaler, | |
76 | Context *ctx) { | |
77 | return new MockSyncPointCreateRequest(&mock_remote_image_ctx, "uuid", | |
78 | &mock_journaler, &m_client_meta, ctx); | |
79 | } | |
80 | ||
81 | librbd::ImageCtx *m_remote_image_ctx; | |
82 | librbd::journal::MirrorPeerClientMeta m_client_meta; | |
83 | }; | |
84 | ||
85 | TEST_F(TestMockImageSyncSyncPointCreateRequest, Success) { | |
86 | librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx); | |
87 | journal::MockJournaler mock_journaler; | |
88 | ||
89 | InSequence seq; | |
90 | expect_update_client(mock_journaler, 0); | |
91 | expect_image_refresh(mock_remote_image_ctx, 0); | |
92 | expect_snap_create(mock_remote_image_ctx, 0); | |
93 | expect_image_refresh(mock_remote_image_ctx, 0); | |
94 | ||
95 | C_SaferCond ctx; | |
96 | MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx, | |
97 | mock_journaler, &ctx); | |
98 | req->send(); | |
99 | ASSERT_EQ(0, ctx.wait()); | |
100 | ||
101 | ASSERT_EQ(1U, m_client_meta.sync_points.size()); | |
102 | } | |
103 | ||
104 | TEST_F(TestMockImageSyncSyncPointCreateRequest, ResyncSuccess) { | |
105 | m_client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), | |
106 | "start snap", | |
107 | "", | |
108 | boost::none); | |
109 | auto sync_point = m_client_meta.sync_points.front(); | |
110 | ||
111 | librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx); | |
112 | journal::MockJournaler mock_journaler; | |
113 | ||
114 | InSequence seq; | |
115 | expect_update_client(mock_journaler, 0); | |
116 | expect_image_refresh(mock_remote_image_ctx, 0); | |
117 | expect_snap_create(mock_remote_image_ctx, 0); | |
118 | expect_image_refresh(mock_remote_image_ctx, 0); | |
119 | ||
120 | C_SaferCond ctx; | |
121 | MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx, | |
122 | mock_journaler, &ctx); | |
123 | req->send(); | |
124 | ASSERT_EQ(0, ctx.wait()); | |
125 | ||
126 | ASSERT_EQ(2U, m_client_meta.sync_points.size()); | |
127 | ASSERT_EQ(sync_point, m_client_meta.sync_points.front()); | |
128 | ASSERT_EQ("start snap", m_client_meta.sync_points.back().from_snap_name); | |
129 | } | |
130 | ||
131 | TEST_F(TestMockImageSyncSyncPointCreateRequest, SnapshotExists) { | |
132 | librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx); | |
133 | journal::MockJournaler mock_journaler; | |
134 | ||
135 | InSequence seq; | |
136 | expect_update_client(mock_journaler, 0); | |
137 | expect_image_refresh(mock_remote_image_ctx, 0); | |
138 | expect_snap_create(mock_remote_image_ctx, -EEXIST); | |
139 | expect_update_client(mock_journaler, 0); | |
140 | expect_image_refresh(mock_remote_image_ctx, 0); | |
141 | expect_snap_create(mock_remote_image_ctx, 0); | |
142 | expect_image_refresh(mock_remote_image_ctx, 0); | |
143 | ||
144 | C_SaferCond ctx; | |
145 | MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx, | |
146 | mock_journaler, &ctx); | |
147 | req->send(); | |
148 | ASSERT_EQ(0, ctx.wait()); | |
149 | ||
150 | ASSERT_EQ(1U, m_client_meta.sync_points.size()); | |
151 | } | |
152 | ||
153 | TEST_F(TestMockImageSyncSyncPointCreateRequest, ClientUpdateError) { | |
154 | librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx); | |
155 | journal::MockJournaler mock_journaler; | |
156 | ||
157 | InSequence seq; | |
158 | expect_update_client(mock_journaler, -EINVAL); | |
159 | ||
160 | C_SaferCond ctx; | |
161 | MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx, | |
162 | mock_journaler, &ctx); | |
163 | req->send(); | |
164 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
165 | ||
166 | ASSERT_TRUE(m_client_meta.sync_points.empty()); | |
167 | } | |
168 | ||
169 | } // namespace image_sync | |
170 | } // namespace mirror | |
171 | } // namespace rbd |