]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/librbd/migration/test_mock_RawSnapshot.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / test / librbd / migration / test_mock_RawSnapshot.cc
CommitLineData
f67539c2
TL
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/migration/MockStreamInterface.h"
7#include "include/rbd_types.h"
8#include "common/ceph_mutex.h"
9#include "librbd/migration/FileStream.h"
10#include "librbd/migration/RawSnapshot.h"
11#include "librbd/migration/SourceSpecBuilder.h"
12#include "gtest/gtest.h"
13#include "gmock/gmock.h"
14#include "json_spirit/json_spirit.h"
15
16namespace librbd {
17namespace {
18
19struct MockTestImageCtx : public MockImageCtx {
20 MockTestImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
21 }
22};
23
24} // anonymous namespace
25
26namespace migration {
27
28template<>
29struct SourceSpecBuilder<librbd::MockTestImageCtx> {
30
31 MOCK_CONST_METHOD2(build_stream, int(const json_spirit::mObject&,
32 std::shared_ptr<StreamInterface>*));
33
34};
35
36} // namespace migration
37} // namespace librbd
38
39#include "librbd/migration/RawSnapshot.cc"
40
41using ::testing::_;
42using ::testing::InSequence;
43using ::testing::Invoke;
44using ::testing::WithArgs;
45
46namespace librbd {
47namespace migration {
48
49using ::testing::Invoke;
50
51class TestMockMigrationRawSnapshot : public TestMockFixture {
52public:
53 typedef RawSnapshot<MockTestImageCtx> MockRawSnapshot;
54 typedef SourceSpecBuilder<MockTestImageCtx> MockSourceSpecBuilder;
55
56 librbd::ImageCtx *m_image_ctx;
57
58 void SetUp() override {
59 TestMockFixture::SetUp();
60
61 ASSERT_EQ(0, open_image(m_image_name, &m_image_ctx));
62
63 json_spirit::mObject stream_obj;
64 stream_obj["type"] = "file";
65 json_object["stream"] = stream_obj;
66 }
67
68 void expect_build_stream(MockSourceSpecBuilder& mock_source_spec_builder,
69 MockStreamInterface* mock_stream_interface, int r) {
70 EXPECT_CALL(mock_source_spec_builder, build_stream(_, _))
71 .WillOnce(WithArgs<1>(Invoke([mock_stream_interface, r]
72 (std::shared_ptr<StreamInterface>* ptr) {
73 ptr->reset(mock_stream_interface);
74 return r;
75 })));
76 }
77
78 void expect_stream_open(MockStreamInterface& mock_stream_interface, int r) {
79 EXPECT_CALL(mock_stream_interface, open(_))
80 .WillOnce(Invoke([r](Context* ctx) { ctx->complete(r); }));
81 }
82
83 void expect_stream_close(MockStreamInterface& mock_stream_interface, int r) {
84 EXPECT_CALL(mock_stream_interface, close(_))
85 .WillOnce(Invoke([r](Context* ctx) { ctx->complete(r); }));
86 }
87
88 void expect_stream_get_size(MockStreamInterface& mock_stream_interface,
89 uint64_t size, int r) {
90 EXPECT_CALL(mock_stream_interface, get_size(_, _))
91 .WillOnce(Invoke([size, r](uint64_t* out_size, Context* ctx) {
92 *out_size = size;
93 ctx->complete(r);
94 }));
95 }
96
97 void expect_stream_read(MockStreamInterface& mock_stream_interface,
98 const io::Extents& byte_extents,
99 const bufferlist& bl, int r) {
100 EXPECT_CALL(mock_stream_interface, read(byte_extents, _, _))
101 .WillOnce(WithArgs<1, 2>(Invoke([bl, r]
102 (bufferlist* out_bl, Context* ctx) {
103 *out_bl = bl;
104 ctx->complete(r);
105 })));
106 }
107
108 json_spirit::mObject json_object;
109};
110
111TEST_F(TestMockMigrationRawSnapshot, OpenClose) {
112 MockTestImageCtx mock_image_ctx(*m_image_ctx);
113
114 InSequence seq;
115 MockSourceSpecBuilder mock_source_spec_builder;
116
117 auto mock_stream_interface = new MockStreamInterface();
118 expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
119
120 expect_stream_open(*mock_stream_interface, 0);
121 expect_stream_get_size(*mock_stream_interface, 123, 0);
122
123 expect_stream_close(*mock_stream_interface, 0);
124
125 json_object["name"] = "snap1";
126 MockRawSnapshot mock_raw_snapshot(&mock_image_ctx, json_object,
127 &mock_source_spec_builder, 1);
128
129 C_SaferCond ctx1;
130 mock_raw_snapshot.open(nullptr, &ctx1);
131 ASSERT_EQ(0, ctx1.wait());
132
133 auto snap_info = mock_raw_snapshot.get_snap_info();
134 ASSERT_EQ("snap1", snap_info.name);
135 ASSERT_EQ(123, snap_info.size);
136
137 C_SaferCond ctx2;
138 mock_raw_snapshot.close(&ctx2);
139 ASSERT_EQ(0, ctx2.wait());
140}
141
142TEST_F(TestMockMigrationRawSnapshot, OpenError) {
143 MockTestImageCtx mock_image_ctx(*m_image_ctx);
144
145 InSequence seq;
146 MockSourceSpecBuilder mock_source_spec_builder;
147
148 auto mock_stream_interface = new MockStreamInterface();
149 expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
150
151 expect_stream_open(*mock_stream_interface, -ENOENT);
152
153 MockRawSnapshot mock_raw_snapshot(&mock_image_ctx, json_object,
154 &mock_source_spec_builder, 0);
155
156 C_SaferCond ctx;
157 mock_raw_snapshot.open(nullptr, &ctx);
158 ASSERT_EQ(-ENOENT, ctx.wait());
159}
160
161TEST_F(TestMockMigrationRawSnapshot, GetSizeError) {
162 MockTestImageCtx mock_image_ctx(*m_image_ctx);
163
164 InSequence seq;
165 MockSourceSpecBuilder mock_source_spec_builder;
166
167 auto mock_stream_interface = new MockStreamInterface();
168 expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
169
170 expect_stream_open(*mock_stream_interface, 0);
171 expect_stream_get_size(*mock_stream_interface, 0, -EINVAL);
172
173 expect_stream_close(*mock_stream_interface, 0);
174
175 MockRawSnapshot mock_raw_snapshot(&mock_image_ctx, json_object,
176 &mock_source_spec_builder, 0);
177
178 C_SaferCond ctx;
179 mock_raw_snapshot.open(nullptr, &ctx);
180 ASSERT_EQ(-EINVAL, ctx.wait());
181}
182
183TEST_F(TestMockMigrationRawSnapshot, Read) {
184 MockTestImageCtx mock_image_ctx(*m_image_ctx);
185
186 InSequence seq;
187 MockSourceSpecBuilder mock_source_spec_builder;
188
189 auto mock_stream_interface = new MockStreamInterface();
190 expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
191
192 expect_stream_open(*mock_stream_interface, 0);
193 expect_stream_get_size(*mock_stream_interface, 0, 0);
194
195 bufferlist expect_bl;
196 expect_bl.append(std::string(123, '1'));
197 expect_stream_read(*mock_stream_interface, {{123, 123}}, expect_bl, 0);
198
199 expect_stream_close(*mock_stream_interface, 0);
200
201 MockRawSnapshot mock_raw_snapshot(&mock_image_ctx, json_object,
202 &mock_source_spec_builder, 0);
203
204 C_SaferCond ctx1;
205 mock_raw_snapshot.open(nullptr, &ctx1);
206 ASSERT_EQ(0, ctx1.wait());
207
208 C_SaferCond ctx2;
209 auto aio_comp = io::AioCompletion::create_and_start(
210 &ctx2, m_image_ctx, io::AIO_TYPE_READ);
211 bufferlist bl;
212 io::ReadResult read_result{&bl};
213 mock_raw_snapshot.read(aio_comp, {{123, 123}}, std::move(read_result), 0, 0,
214 {});
215 ASSERT_EQ(123, ctx2.wait());
216 ASSERT_EQ(expect_bl, bl);
217
218 C_SaferCond ctx3;
219 mock_raw_snapshot.close(&ctx3);
220 ASSERT_EQ(0, ctx3.wait());
221}
222
223TEST_F(TestMockMigrationRawSnapshot, ListSnap) {
224 MockTestImageCtx mock_image_ctx(*m_image_ctx);
225
226 InSequence seq;
227 MockSourceSpecBuilder mock_source_spec_builder;
228
229 auto mock_stream_interface = new MockStreamInterface();
230 expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
231
232 expect_stream_open(*mock_stream_interface, 0);
233 expect_stream_get_size(*mock_stream_interface, 0, 0);
234
235 expect_stream_close(*mock_stream_interface, 0);
236
237 MockRawSnapshot mock_raw_snapshot(&mock_image_ctx, json_object,
238 &mock_source_spec_builder, 0);
239
240 C_SaferCond ctx1;
241 mock_raw_snapshot.open(nullptr, &ctx1);
242 ASSERT_EQ(0, ctx1.wait());
243
244 C_SaferCond ctx2;
245 io::SparseExtents sparse_extents;
246 mock_raw_snapshot.list_snap({{0, 123}}, 0, &sparse_extents, {}, &ctx2);
247 ASSERT_EQ(0, ctx2.wait());
248
249 C_SaferCond ctx3;
250 mock_raw_snapshot.close(&ctx3);
251 ASSERT_EQ(0, ctx3.wait());
252}
253
254} // namespace migration
255} // namespace librbd