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 "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"
14 struct MockTestImageCtx
: public MockImageCtx
{
15 MockTestImageCtx(ImageCtx
&image_ctx
) : MockImageCtx(image_ctx
) {
19 } // anonymous namespace
22 // template definitions
23 #include "librbd/image/ValidatePoolRequest.cc"
29 using ::testing::DoDefault
;
30 using ::testing::InSequence
;
31 using ::testing::Invoke
;
32 using ::testing::Return
;
33 using ::testing::StrEq
;
34 using ::testing::WithArg
;
36 class TestMockImageValidatePoolRequest
: public TestMockFixture
{
38 typedef ValidatePoolRequest
<MockTestImageCtx
> MockValidatePoolRequest
;
40 void SetUp() override
{
41 TestMockFixture::SetUp();
42 m_ioctx
.remove(RBD_INFO
);
43 ASSERT_EQ(0, open_image(m_image_name
, &image_ctx
));
46 void expect_clone(librados::MockTestMemIoCtxImpl
&mock_io_ctx
) {
47 EXPECT_CALL(mock_io_ctx
, clone())
48 .WillOnce(Invoke([&mock_io_ctx
]() {
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, _
, _
, _
));
59 expect
.WillOnce(Return(r
));
61 expect
.WillOnce(WithArg
<3>(Invoke([data
](bufferlist
* bl
) {
68 void expect_write_rbd_info(librados::MockTestMemIoCtxImpl
&mock_io_ctx
,
69 const std::string
& data
, int r
) {
73 EXPECT_CALL(mock_io_ctx
, write(StrEq(RBD_INFO
), ContentsEqual(bl
),
78 void expect_allocate_snap_id(librados::MockTestMemIoCtxImpl
&mock_io_ctx
,
80 auto &expect
= EXPECT_CALL(mock_io_ctx
, selfmanaged_snap_create(_
));
82 expect
.WillOnce(Return(r
));
84 expect
.WillOnce(DoDefault());
88 void expect_release_snap_id(librados::MockTestMemIoCtxImpl
&mock_io_ctx
,
90 auto &expect
= EXPECT_CALL(mock_io_ctx
, selfmanaged_snap_remove(_
));
92 expect
.WillOnce(Return(r
));
94 expect
.WillOnce(DoDefault());
98 librbd::ImageCtx
*image_ctx
;
101 TEST_F(TestMockImageValidatePoolRequest
, Success
) {
102 librados::MockTestMemIoCtxImpl
&mock_io_ctx(get_mock_io_ctx(m_ioctx
));
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);
113 auto req
= new MockValidatePoolRequest(m_ioctx
, image_ctx
->op_work_queue
,
116 ASSERT_EQ(0, ctx
.wait());
119 TEST_F(TestMockImageValidatePoolRequest
, AlreadyValidated
) {
120 librados::MockTestMemIoCtxImpl
&mock_io_ctx(get_mock_io_ctx(m_ioctx
));
123 expect_clone(mock_io_ctx
);
124 expect_read_rbd_info(mock_io_ctx
, "overwrite validated", 0);
127 auto req
= new MockValidatePoolRequest(m_ioctx
, image_ctx
->op_work_queue
,
130 ASSERT_EQ(0, ctx
.wait());
133 TEST_F(TestMockImageValidatePoolRequest
, SnapshotsValidated
) {
134 librados::MockTestMemIoCtxImpl
&mock_io_ctx(get_mock_io_ctx(m_ioctx
));
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);
142 auto req
= new MockValidatePoolRequest(m_ioctx
, image_ctx
->op_work_queue
,
145 ASSERT_EQ(0, ctx
.wait());
148 TEST_F(TestMockImageValidatePoolRequest
, ReadError
) {
149 librados::MockTestMemIoCtxImpl
&mock_io_ctx(get_mock_io_ctx(m_ioctx
));
152 expect_clone(mock_io_ctx
);
153 expect_read_rbd_info(mock_io_ctx
, "", -EPERM
);
156 auto req
= new MockValidatePoolRequest(m_ioctx
, image_ctx
->op_work_queue
,
159 ASSERT_EQ(-EPERM
, ctx
.wait());
162 TEST_F(TestMockImageValidatePoolRequest
, CreateSnapshotError
) {
163 librados::MockTestMemIoCtxImpl
&mock_io_ctx(get_mock_io_ctx(m_ioctx
));
166 expect_clone(mock_io_ctx
);
167 expect_read_rbd_info(mock_io_ctx
, "", 0);
168 expect_allocate_snap_id(mock_io_ctx
, -EPERM
);
171 auto req
= new MockValidatePoolRequest(m_ioctx
, image_ctx
->op_work_queue
,
174 ASSERT_EQ(-EPERM
, ctx
.wait());
177 TEST_F(TestMockImageValidatePoolRequest
, WriteError
) {
178 librados::MockTestMemIoCtxImpl
&mock_io_ctx(get_mock_io_ctx(m_ioctx
));
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
);
188 auto req
= new MockValidatePoolRequest(m_ioctx
, image_ctx
->op_work_queue
,
191 ASSERT_EQ(-EPERM
, ctx
.wait());
194 TEST_F(TestMockImageValidatePoolRequest
, RemoveSnapshotError
) {
195 librados::MockTestMemIoCtxImpl
&mock_io_ctx(get_mock_io_ctx(m_ioctx
));
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);
206 auto req
= new MockValidatePoolRequest(m_ioctx
, image_ctx
->op_work_queue
,
209 ASSERT_EQ(0, ctx
.wait());
212 TEST_F(TestMockImageValidatePoolRequest
, OverwriteError
) {
213 librados::MockTestMemIoCtxImpl
&mock_io_ctx(get_mock_io_ctx(m_ioctx
));
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
);
224 auto req
= new MockValidatePoolRequest(m_ioctx
, image_ctx
->op_work_queue
,
227 ASSERT_EQ(-EINVAL
, ctx
.wait());
231 } // namespace librbd