]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / test / rbd_mirror / image_sync / test_mock_SyncPointCreateRequest.cc
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 "test/librados_test_stub/MockTestMemIoCtxImpl.h"
7 #include "test/librbd/mock/MockImageCtx.h"
8 #include "test/rbd_mirror/mock/image_sync/MockSyncPointHandler.h"
9 #include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.h"
10
11 namespace librbd {
12
13 namespace {
14
15 struct MockTestImageCtx : public librbd::MockImageCtx {
16 explicit MockTestImageCtx(librbd::ImageCtx &image_ctx)
17 : librbd::MockImageCtx(image_ctx) {
18 }
19 };
20
21 } // anonymous namespace
22
23 } // namespace librbd
24
25 // template definitions
26 #include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.cc"
27
28 namespace rbd {
29 namespace mirror {
30 namespace image_sync {
31
32 using ::testing::_;
33 using ::testing::DoAll;
34 using ::testing::InSequence;
35 using ::testing::Invoke;
36 using ::testing::Return;
37 using ::testing::WithArg;
38
39 class TestMockImageSyncSyncPointCreateRequest : public TestMockFixture {
40 public:
41 typedef SyncPointCreateRequest<librbd::MockTestImageCtx> MockSyncPointCreateRequest;
42
43 void SetUp() override {
44 TestMockFixture::SetUp();
45
46 librbd::RBD rbd;
47 ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
48 ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
49 }
50
51 void expect_get_snap_seqs(MockSyncPointHandler& mock_sync_point_handler) {
52 EXPECT_CALL(mock_sync_point_handler, get_snap_seqs())
53 .WillRepeatedly(Return(librbd::SnapSeqs{}));
54 }
55
56 void expect_get_sync_points(MockSyncPointHandler& mock_sync_point_handler) {
57 EXPECT_CALL(mock_sync_point_handler, get_sync_points())
58 .WillRepeatedly(Invoke([this]() {
59 return m_sync_points;
60 }));
61 }
62
63 void expect_update_sync_points(MockSyncPointHandler& mock_sync_point_handler,
64 int r) {
65 EXPECT_CALL(mock_sync_point_handler, update_sync_points(_, _, false, _))
66 .WillOnce(DoAll(WithArg<1>(Invoke([this, r](const SyncPoints& sync_points) {
67 if (r >= 0) {
68 m_sync_points = sync_points;
69 }
70 })),
71 WithArg<3>(CompleteContext(r))));
72 }
73
74 void expect_image_refresh(librbd::MockTestImageCtx &mock_remote_image_ctx, int r) {
75 EXPECT_CALL(*mock_remote_image_ctx.state, refresh(_))
76 .WillOnce(CompleteContext(r));
77 }
78
79 void expect_snap_create(librbd::MockTestImageCtx &mock_remote_image_ctx, int r) {
80 EXPECT_CALL(*mock_remote_image_ctx.operations, snap_create(_, _, _, _, _))
81 .WillOnce(WithArg<4>(CompleteContext(r)));
82 }
83
84 MockSyncPointCreateRequest *create_request(librbd::MockTestImageCtx &mock_remote_image_ctx,
85 MockSyncPointHandler& mock_sync_point_handler,
86 Context *ctx) {
87 return new MockSyncPointCreateRequest(&mock_remote_image_ctx, "uuid",
88 &mock_sync_point_handler, ctx);
89 }
90
91 librbd::ImageCtx *m_remote_image_ctx;
92 SyncPoints m_sync_points;
93 };
94
95 TEST_F(TestMockImageSyncSyncPointCreateRequest, Success) {
96 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
97 MockSyncPointHandler mock_sync_point_handler;
98
99 expect_get_snap_seqs(mock_sync_point_handler);
100 expect_get_sync_points(mock_sync_point_handler);
101
102 InSequence seq;
103 expect_update_sync_points(mock_sync_point_handler, 0);
104 expect_image_refresh(mock_remote_image_ctx, 0);
105 expect_snap_create(mock_remote_image_ctx, 0);
106 expect_image_refresh(mock_remote_image_ctx, 0);
107
108 C_SaferCond ctx;
109 MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
110 mock_sync_point_handler,
111 &ctx);
112 req->send();
113 ASSERT_EQ(0, ctx.wait());
114
115 ASSERT_EQ(1U, m_sync_points.size());
116 }
117
118 TEST_F(TestMockImageSyncSyncPointCreateRequest, ResyncSuccess) {
119 m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "start snap",
120 "", boost::none);
121 auto sync_point = m_sync_points.front();
122
123 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
124 MockSyncPointHandler mock_sync_point_handler;
125
126 expect_get_snap_seqs(mock_sync_point_handler);
127 expect_get_sync_points(mock_sync_point_handler);
128
129 InSequence seq;
130 expect_update_sync_points(mock_sync_point_handler, 0);
131 expect_image_refresh(mock_remote_image_ctx, 0);
132 expect_snap_create(mock_remote_image_ctx, 0);
133 expect_image_refresh(mock_remote_image_ctx, 0);
134
135 C_SaferCond ctx;
136 MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
137 mock_sync_point_handler,
138 &ctx);
139 req->send();
140 ASSERT_EQ(0, ctx.wait());
141
142 ASSERT_EQ(2U, m_sync_points.size());
143 ASSERT_EQ(sync_point, m_sync_points.front());
144 ASSERT_EQ("start snap", m_sync_points.back().from_snap_name);
145 }
146
147 TEST_F(TestMockImageSyncSyncPointCreateRequest, SnapshotExists) {
148 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
149 MockSyncPointHandler mock_sync_point_handler;
150
151 expect_get_snap_seqs(mock_sync_point_handler);
152 expect_get_sync_points(mock_sync_point_handler);
153
154 InSequence seq;
155 expect_update_sync_points(mock_sync_point_handler, 0);
156 expect_image_refresh(mock_remote_image_ctx, 0);
157 expect_snap_create(mock_remote_image_ctx, -EEXIST);
158 expect_update_sync_points(mock_sync_point_handler, 0);
159 expect_image_refresh(mock_remote_image_ctx, 0);
160 expect_snap_create(mock_remote_image_ctx, 0);
161 expect_image_refresh(mock_remote_image_ctx, 0);
162
163 C_SaferCond ctx;
164 MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
165 mock_sync_point_handler,
166 &ctx);
167 req->send();
168 ASSERT_EQ(0, ctx.wait());
169
170 ASSERT_EQ(1U, m_sync_points.size());
171 }
172
173 TEST_F(TestMockImageSyncSyncPointCreateRequest, ClientUpdateError) {
174 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
175 MockSyncPointHandler mock_sync_point_handler;
176
177 expect_get_snap_seqs(mock_sync_point_handler);
178 expect_get_sync_points(mock_sync_point_handler);
179
180 InSequence seq;
181 expect_update_sync_points(mock_sync_point_handler, -EINVAL);
182
183 C_SaferCond ctx;
184 MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
185 mock_sync_point_handler,
186 &ctx);
187 req->send();
188 ASSERT_EQ(-EINVAL, ctx.wait());
189
190 ASSERT_TRUE(m_sync_points.empty());
191 }
192
193 } // namespace image_sync
194 } // namespace mirror
195 } // namespace rbd