1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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"
18 struct MockTestImageCtx
: public librbd::MockImageCtx
{
19 MockTestImageCtx(librbd::ImageCtx
&image_ctx
)
20 : librbd::MockImageCtx(image_ctx
) {
24 } // anonymous namespace
29 struct GetMetadataRequest
<MockTestImageCtx
> {
30 std::map
<std::string
, bufferlist
>* pairs
= nullptr;
31 Context
* on_finish
= nullptr;
33 static GetMetadataRequest
* s_instance
;
34 static GetMetadataRequest
* create(librados::IoCtx
&,
35 const std::string
& oid
,
37 const std::string
& filter_key_prefix
,
38 const std::string
& last_key
,
40 std::map
<std::string
, bufferlist
>* pairs
,
42 ceph_assert(s_instance
!= nullptr);
43 s_instance
->pairs
= pairs
;
44 s_instance
->on_finish
= on_finish
;
48 GetMetadataRequest() {
52 MOCK_METHOD0(send
, void());
55 GetMetadataRequest
<MockTestImageCtx
>* GetMetadataRequest
<MockTestImageCtx
>::s_instance
= nullptr;
60 // template definitions
61 #include "librbd/deep_copy/MetadataCopyRequest.cc"
67 using ::testing::DoAll
;
68 using ::testing::InSequence
;
69 using ::testing::Invoke
;
70 using ::testing::Return
;
71 using ::testing::StrEq
;
72 using ::testing::WithArg
;
74 class TestMockDeepCopyMetadataCopyRequest
: public TestMockFixture
{
76 typedef MetadataCopyRequest
<librbd::MockTestImageCtx
> MockMetadataCopyRequest
;
77 typedef image::GetMetadataRequest
<MockTestImageCtx
> MockGetMetadataRequest
;
78 typedef std::map
<std::string
, bufferlist
> Metadata
;
80 librbd::ImageCtx
*m_src_image_ctx
;
81 librbd::ImageCtx
*m_dst_image_ctx
;
82 ThreadPool
*m_thread_pool
;
83 ContextWQ
*m_work_queue
;
85 void SetUp() override
{
86 TestMockFixture::SetUp();
88 ASSERT_EQ(0, open_image(m_image_name
, &m_src_image_ctx
));
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
));
95 librbd::ImageCtx::get_thread_pool_instance(m_src_image_ctx
->cct
,
96 &m_thread_pool
, &m_work_queue
);
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
);
108 void expect_metadata_set(librbd::MockTestImageCtx
&mock_image_ctx
,
109 const Metadata
& metadata
, int r
) {
111 encode(metadata
, in_bl
);
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
));
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
);
125 Metadata key_values_1
;
126 for (; idx
<= 128; ++idx
) {
128 bl
.append("value" + stringify(idx
));
129 key_values_1
.emplace("key" + stringify(idx
), bl
);
132 Metadata key_values_2
;
133 for (; idx
<= 255; ++idx
) {
135 bl
.append("value" + stringify(idx
));
136 key_values_2
.emplace("key" + stringify(idx
), bl
);
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);
147 auto request
= MockMetadataCopyRequest::create(&mock_src_image_ctx
,
152 ASSERT_EQ(0, ctx
.wait());
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
);
162 MockGetMetadataRequest mock_request
;
163 expect_get_metadata(mock_request
, key_values
, 0);
166 auto request
= MockMetadataCopyRequest::create(&mock_src_image_ctx
,
171 ASSERT_EQ(0, ctx
.wait());
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
);
181 MockGetMetadataRequest mock_request
;
182 expect_get_metadata(mock_request
, key_values
, -EINVAL
);
185 auto request
= MockMetadataCopyRequest::create(&mock_src_image_ctx
,
190 ASSERT_EQ(-EINVAL
, ctx
.wait());
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
);
200 key_values
.emplace("key", bl
);
203 MockGetMetadataRequest mock_request
;
204 expect_get_metadata(mock_request
, key_values
, 0);
205 expect_metadata_set(mock_dst_image_ctx
, key_values
, -EINVAL
);
208 auto request
= MockMetadataCopyRequest::create(&mock_src_image_ctx
,
213 ASSERT_EQ(-EINVAL
, ctx
.wait());
216 } // namespace deep_sync
217 } // namespace librbd