]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/image/test_mock_ValidatePoolRequest.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / test / librbd / image / test_mock_ValidatePoolRequest.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/librbd/test_mock_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "test/librbd/mock/MockImageCtx.h"
7 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
8 #include "gmock/gmock.h"
9 #include "gtest/gtest.h"
10
11 namespace librbd {
12 namespace {
13
14 struct MockTestImageCtx : public MockImageCtx {
15 MockTestImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
16 }
17 };
18
19 } // anonymous namespace
20 } // namespace librbd
21
22 // template definitions
23 #include "librbd/image/ValidatePoolRequest.cc"
24
25 namespace librbd {
26 namespace image {
27
28 using ::testing::_;
29 using ::testing::DoDefault;
30 using ::testing::InSequence;
31 using ::testing::Invoke;
32 using ::testing::Return;
33 using ::testing::StrEq;
34 using ::testing::WithArg;
35
36 class TestMockImageValidatePoolRequest : public TestMockFixture {
37 public:
38 typedef ValidatePoolRequest<MockTestImageCtx> MockValidatePoolRequest;
39
40 void SetUp() override {
41 TestMockFixture::SetUp();
42 m_ioctx.remove(RBD_INFO);
43 ASSERT_EQ(0, open_image(m_image_name, &image_ctx));
44 }
45
46 void expect_clone(librados::MockTestMemIoCtxImpl &mock_io_ctx) {
47 EXPECT_CALL(mock_io_ctx, clone())
48 .WillOnce(Invoke([&mock_io_ctx]() {
49 mock_io_ctx.get();
50 return &mock_io_ctx;
51 }));
52 }
53
54 void expect_read_rbd_info(librados::MockTestMemIoCtxImpl &mock_io_ctx,
55 const std::string& data, int r) {
56 auto& expect = EXPECT_CALL(
57 mock_io_ctx, read(StrEq(RBD_INFO), 0, 0, _, _, _));
58 if (r < 0) {
59 expect.WillOnce(Return(r));
60 } else {
61 expect.WillOnce(WithArg<3>(Invoke([data](bufferlist* bl) {
62 bl->append(data);
63 return 0;
64 })));
65 }
66 }
67
68 void expect_write_rbd_info(librados::MockTestMemIoCtxImpl &mock_io_ctx,
69 const std::string& data, int r) {
70 bufferlist bl;
71 bl.append(data);
72
73 EXPECT_CALL(mock_io_ctx, write(StrEq(RBD_INFO), ContentsEqual(bl),
74 data.length(), 0, _))
75 .WillOnce(Return(r));
76 }
77
78 void expect_allocate_snap_id(librados::MockTestMemIoCtxImpl &mock_io_ctx,
79 int r) {
80 auto &expect = EXPECT_CALL(mock_io_ctx, selfmanaged_snap_create(_));
81 if (r < 0) {
82 expect.WillOnce(Return(r));
83 } else {
84 expect.WillOnce(DoDefault());
85 }
86 }
87
88 void expect_release_snap_id(librados::MockTestMemIoCtxImpl &mock_io_ctx,
89 int r) {
90 auto &expect = EXPECT_CALL(mock_io_ctx, selfmanaged_snap_remove(_));
91 if (r < 0) {
92 expect.WillOnce(Return(r));
93 } else {
94 expect.WillOnce(DoDefault());
95 }
96 }
97
98 librbd::ImageCtx *image_ctx;
99 };
100
101 TEST_F(TestMockImageValidatePoolRequest, Success) {
102 librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx));
103
104 InSequence seq;
105 expect_clone(mock_io_ctx);
106 expect_read_rbd_info(mock_io_ctx, "", -ENOENT);
107 expect_allocate_snap_id(mock_io_ctx, 0);
108 expect_write_rbd_info(mock_io_ctx, "validate", 0);
109 expect_release_snap_id(mock_io_ctx, 0);
110 expect_write_rbd_info(mock_io_ctx, "overwrite validated", 0);
111
112 C_SaferCond ctx;
113 auto req = new MockValidatePoolRequest(m_ioctx, image_ctx->op_work_queue,
114 &ctx);
115 req->send();
116 ASSERT_EQ(0, ctx.wait());
117 }
118
119 TEST_F(TestMockImageValidatePoolRequest, AlreadyValidated) {
120 librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx));
121
122 InSequence seq;
123 expect_clone(mock_io_ctx);
124 expect_read_rbd_info(mock_io_ctx, "overwrite validated", 0);
125
126 C_SaferCond ctx;
127 auto req = new MockValidatePoolRequest(m_ioctx, image_ctx->op_work_queue,
128 &ctx);
129 req->send();
130 ASSERT_EQ(0, ctx.wait());
131 }
132
133 TEST_F(TestMockImageValidatePoolRequest, SnapshotsValidated) {
134 librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx));
135
136 InSequence seq;
137 expect_clone(mock_io_ctx);
138 expect_read_rbd_info(mock_io_ctx, "validate", 0);
139 expect_write_rbd_info(mock_io_ctx, "overwrite validated", 0);
140
141 C_SaferCond ctx;
142 auto req = new MockValidatePoolRequest(m_ioctx, image_ctx->op_work_queue,
143 &ctx);
144 req->send();
145 ASSERT_EQ(0, ctx.wait());
146 }
147
148 TEST_F(TestMockImageValidatePoolRequest, ReadError) {
149 librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx));
150
151 InSequence seq;
152 expect_clone(mock_io_ctx);
153 expect_read_rbd_info(mock_io_ctx, "", -EPERM);
154
155 C_SaferCond ctx;
156 auto req = new MockValidatePoolRequest(m_ioctx, image_ctx->op_work_queue,
157 &ctx);
158 req->send();
159 ASSERT_EQ(-EPERM, ctx.wait());
160 }
161
162 TEST_F(TestMockImageValidatePoolRequest, CreateSnapshotError) {
163 librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx));
164
165 InSequence seq;
166 expect_clone(mock_io_ctx);
167 expect_read_rbd_info(mock_io_ctx, "", 0);
168 expect_allocate_snap_id(mock_io_ctx, -EPERM);
169
170 C_SaferCond ctx;
171 auto req = new MockValidatePoolRequest(m_ioctx, image_ctx->op_work_queue,
172 &ctx);
173 req->send();
174 ASSERT_EQ(-EPERM, ctx.wait());
175 }
176
177 TEST_F(TestMockImageValidatePoolRequest, WriteError) {
178 librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx));
179
180 InSequence seq;
181 expect_clone(mock_io_ctx);
182 expect_read_rbd_info(mock_io_ctx, "", -ENOENT);
183 expect_allocate_snap_id(mock_io_ctx, 0);
184 expect_write_rbd_info(mock_io_ctx, "validate", -EPERM);
185 expect_release_snap_id(mock_io_ctx, -EINVAL);
186
187 C_SaferCond ctx;
188 auto req = new MockValidatePoolRequest(m_ioctx, image_ctx->op_work_queue,
189 &ctx);
190 req->send();
191 ASSERT_EQ(-EPERM, ctx.wait());
192 }
193
194 TEST_F(TestMockImageValidatePoolRequest, RemoveSnapshotError) {
195 librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx));
196
197 InSequence seq;
198 expect_clone(mock_io_ctx);
199 expect_read_rbd_info(mock_io_ctx, "", -ENOENT);
200 expect_allocate_snap_id(mock_io_ctx, 0);
201 expect_write_rbd_info(mock_io_ctx, "validate", 0);
202 expect_release_snap_id(mock_io_ctx, -EPERM);
203 expect_write_rbd_info(mock_io_ctx, "overwrite validated", 0);
204
205 C_SaferCond ctx;
206 auto req = new MockValidatePoolRequest(m_ioctx, image_ctx->op_work_queue,
207 &ctx);
208 req->send();
209 ASSERT_EQ(0, ctx.wait());
210 }
211
212 TEST_F(TestMockImageValidatePoolRequest, OverwriteError) {
213 librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx));
214
215 InSequence seq;
216 expect_clone(mock_io_ctx);
217 expect_read_rbd_info(mock_io_ctx, "", -ENOENT);
218 expect_allocate_snap_id(mock_io_ctx, 0);
219 expect_write_rbd_info(mock_io_ctx, "validate", 0);
220 expect_release_snap_id(mock_io_ctx, 0);
221 expect_write_rbd_info(mock_io_ctx, "overwrite validated", -EOPNOTSUPP);
222
223 C_SaferCond ctx;
224 auto req = new MockValidatePoolRequest(m_ioctx, image_ctx->op_work_queue,
225 &ctx);
226 req->send();
227 ASSERT_EQ(-EINVAL, ctx.wait());
228 }
229
230 } // namespace image
231 } // namespace librbd