]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/deep_copy/test_mock_MetadataCopyRequest.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / test / librbd / deep_copy / test_mock_MetadataCopyRequest.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 "include/rbd/librbd.hpp"
6 #include "include/stringify.h"
7 #include "librbd/ImageCtx.h"
8 #include "librbd/deep_copy/MetadataCopyRequest.h"
9 #include "librbd/image/GetMetadataRequest.h"
10 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
11 #include "test/librbd/mock/MockImageCtx.h"
12 #include "test/librbd/test_support.h"
13 #include <map>
14
15 namespace librbd {
16 namespace {
17
18 struct MockTestImageCtx : public librbd::MockImageCtx {
19 MockTestImageCtx(librbd::ImageCtx &image_ctx)
20 : librbd::MockImageCtx(image_ctx) {
21 }
22 };
23
24 } // anonymous namespace
25
26 namespace image {
27
28 template <>
29 struct GetMetadataRequest<MockTestImageCtx> {
30 std::map<std::string, bufferlist>* pairs = nullptr;
31 Context* on_finish = nullptr;
32
33 static GetMetadataRequest* s_instance;
34 static GetMetadataRequest* create(librados::IoCtx&,
35 const std::string& oid,
36 bool filter_internal,
37 const std::string& filter_key_prefix,
38 const std::string& last_key,
39 uint32_t max_results,
40 std::map<std::string, bufferlist>* pairs,
41 Context* on_finish) {
42 ceph_assert(s_instance != nullptr);
43 s_instance->pairs = pairs;
44 s_instance->on_finish = on_finish;
45 return s_instance;
46 }
47
48 GetMetadataRequest() {
49 s_instance = this;
50 }
51
52 MOCK_METHOD0(send, void());
53 };
54
55 GetMetadataRequest<MockTestImageCtx>* GetMetadataRequest<MockTestImageCtx>::s_instance = nullptr;
56
57 } // namspace image
58 } // namespace librbd
59
60 // template definitions
61 #include "librbd/deep_copy/MetadataCopyRequest.cc"
62
63 namespace librbd {
64 namespace deep_copy {
65
66 using ::testing::_;
67 using ::testing::DoAll;
68 using ::testing::InSequence;
69 using ::testing::Invoke;
70 using ::testing::Return;
71 using ::testing::StrEq;
72 using ::testing::WithArg;
73
74 class TestMockDeepCopyMetadataCopyRequest : public TestMockFixture {
75 public:
76 typedef MetadataCopyRequest<librbd::MockTestImageCtx> MockMetadataCopyRequest;
77 typedef image::GetMetadataRequest<MockTestImageCtx> MockGetMetadataRequest;
78 typedef std::map<std::string, bufferlist> Metadata;
79
80 librbd::ImageCtx *m_src_image_ctx;
81 librbd::ImageCtx *m_dst_image_ctx;
82 ThreadPool *m_thread_pool;
83 ContextWQ *m_work_queue;
84
85 void SetUp() override {
86 TestMockFixture::SetUp();
87
88 ASSERT_EQ(0, open_image(m_image_name, &m_src_image_ctx));
89
90 librbd::RBD rbd;
91 std::string dst_image_name = get_temp_image_name();
92 ASSERT_EQ(0, create_image_pp(rbd, m_ioctx, dst_image_name, m_image_size));
93 ASSERT_EQ(0, open_image(dst_image_name, &m_dst_image_ctx));
94
95 librbd::ImageCtx::get_thread_pool_instance(m_src_image_ctx->cct,
96 &m_thread_pool, &m_work_queue);
97 }
98
99 void expect_get_metadata(MockGetMetadataRequest& mock_request,
100 const Metadata& metadata, int r) {
101 EXPECT_CALL(mock_request, send())
102 .WillOnce(Invoke([this, &mock_request, metadata, r]() {
103 *mock_request.pairs = metadata;
104 m_work_queue->queue(mock_request.on_finish, r);
105 }));
106 }
107
108 void expect_metadata_set(librbd::MockTestImageCtx &mock_image_ctx,
109 const Metadata& metadata, int r) {
110 bufferlist in_bl;
111 encode(metadata, in_bl);
112
113 EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
114 exec(mock_image_ctx.header_oid, _, StrEq("rbd"),
115 StrEq("metadata_set"), ContentsEqual(in_bl), _, _))
116 .WillOnce(Return(r));
117 }
118 };
119
120 TEST_F(TestMockDeepCopyMetadataCopyRequest, Success) {
121 librbd::MockTestImageCtx mock_src_image_ctx(*m_src_image_ctx);
122 librbd::MockTestImageCtx mock_dst_image_ctx(*m_dst_image_ctx);
123
124 size_t idx = 1;
125 Metadata key_values_1;
126 for (; idx <= 128; ++idx) {
127 bufferlist bl;
128 bl.append("value" + stringify(idx));
129 key_values_1.emplace("key" + stringify(idx), bl);
130 }
131
132 Metadata key_values_2;
133 for (; idx <= 255; ++idx) {
134 bufferlist bl;
135 bl.append("value" + stringify(idx));
136 key_values_2.emplace("key" + stringify(idx), bl);
137 }
138
139 InSequence seq;
140 MockGetMetadataRequest mock_request;
141 expect_get_metadata(mock_request, key_values_1, 0);
142 expect_metadata_set(mock_dst_image_ctx, key_values_1, 0);
143 expect_get_metadata(mock_request, key_values_2, 0);
144 expect_metadata_set(mock_dst_image_ctx, key_values_2, 0);
145
146 C_SaferCond ctx;
147 auto request = MockMetadataCopyRequest::create(&mock_src_image_ctx,
148 &mock_dst_image_ctx,
149 &ctx);
150 request->send();
151
152 ASSERT_EQ(0, ctx.wait());
153 }
154
155 TEST_F(TestMockDeepCopyMetadataCopyRequest, Empty) {
156 librbd::MockTestImageCtx mock_src_image_ctx(*m_src_image_ctx);
157 librbd::MockTestImageCtx mock_dst_image_ctx(*m_dst_image_ctx);
158
159 Metadata key_values;
160
161 InSequence seq;
162 MockGetMetadataRequest mock_request;
163 expect_get_metadata(mock_request, key_values, 0);
164
165 C_SaferCond ctx;
166 auto request = MockMetadataCopyRequest::create(&mock_src_image_ctx,
167 &mock_dst_image_ctx,
168 &ctx);
169 request->send();
170
171 ASSERT_EQ(0, ctx.wait());
172 }
173
174 TEST_F(TestMockDeepCopyMetadataCopyRequest, MetadataListError) {
175 librbd::MockTestImageCtx mock_src_image_ctx(*m_src_image_ctx);
176 librbd::MockTestImageCtx mock_dst_image_ctx(*m_dst_image_ctx);
177
178 Metadata key_values;
179
180 InSequence seq;
181 MockGetMetadataRequest mock_request;
182 expect_get_metadata(mock_request, key_values, -EINVAL);
183
184 C_SaferCond ctx;
185 auto request = MockMetadataCopyRequest::create(&mock_src_image_ctx,
186 &mock_dst_image_ctx,
187 &ctx);
188 request->send();
189
190 ASSERT_EQ(-EINVAL, ctx.wait());
191 }
192
193 TEST_F(TestMockDeepCopyMetadataCopyRequest, MetadataSetError) {
194 librbd::MockTestImageCtx mock_src_image_ctx(*m_src_image_ctx);
195 librbd::MockTestImageCtx mock_dst_image_ctx(*m_dst_image_ctx);
196
197 Metadata key_values;
198 bufferlist bl;
199 bl.append("value");
200 key_values.emplace("key", bl);
201
202 InSequence seq;
203 MockGetMetadataRequest mock_request;
204 expect_get_metadata(mock_request, key_values, 0);
205 expect_metadata_set(mock_dst_image_ctx, key_values, -EINVAL);
206
207 C_SaferCond ctx;
208 auto request = MockMetadataCopyRequest::create(&mock_src_image_ctx,
209 &mock_dst_image_ctx,
210 &ctx);
211 request->send();
212
213 ASSERT_EQ(-EINVAL, ctx.wait());
214 }
215
216 } // namespace deep_sync
217 } // namespace librbd