]>
Commit | Line | Data |
---|---|---|
11fdf7f2 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/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(); | |
f67539c2 | 42 | m_ioctx.remove(RBD_INFO); |
11fdf7f2 TL |
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) { | |
f67539c2 TL |
56 | auto& expect = EXPECT_CALL( |
57 | mock_io_ctx, read(StrEq(RBD_INFO), 0, 0, _, _, _)); | |
11fdf7f2 TL |
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; | |
a4b75251 | 113 | auto req = new MockValidatePoolRequest(m_ioctx, &ctx); |
11fdf7f2 TL |
114 | req->send(); |
115 | ASSERT_EQ(0, ctx.wait()); | |
116 | } | |
117 | ||
118 | TEST_F(TestMockImageValidatePoolRequest, AlreadyValidated) { | |
119 | librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx)); | |
120 | ||
121 | InSequence seq; | |
122 | expect_clone(mock_io_ctx); | |
123 | expect_read_rbd_info(mock_io_ctx, "overwrite validated", 0); | |
124 | ||
125 | C_SaferCond ctx; | |
a4b75251 | 126 | auto req = new MockValidatePoolRequest(m_ioctx, &ctx); |
11fdf7f2 TL |
127 | req->send(); |
128 | ASSERT_EQ(0, ctx.wait()); | |
129 | } | |
130 | ||
131 | TEST_F(TestMockImageValidatePoolRequest, SnapshotsValidated) { | |
132 | librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx)); | |
133 | ||
134 | InSequence seq; | |
135 | expect_clone(mock_io_ctx); | |
136 | expect_read_rbd_info(mock_io_ctx, "validate", 0); | |
137 | expect_write_rbd_info(mock_io_ctx, "overwrite validated", 0); | |
138 | ||
139 | C_SaferCond ctx; | |
a4b75251 | 140 | auto req = new MockValidatePoolRequest(m_ioctx, &ctx); |
11fdf7f2 TL |
141 | req->send(); |
142 | ASSERT_EQ(0, ctx.wait()); | |
143 | } | |
144 | ||
145 | TEST_F(TestMockImageValidatePoolRequest, ReadError) { | |
146 | librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx)); | |
147 | ||
148 | InSequence seq; | |
149 | expect_clone(mock_io_ctx); | |
150 | expect_read_rbd_info(mock_io_ctx, "", -EPERM); | |
151 | ||
152 | C_SaferCond ctx; | |
a4b75251 | 153 | auto req = new MockValidatePoolRequest(m_ioctx, &ctx); |
11fdf7f2 TL |
154 | req->send(); |
155 | ASSERT_EQ(-EPERM, ctx.wait()); | |
156 | } | |
157 | ||
158 | TEST_F(TestMockImageValidatePoolRequest, CreateSnapshotError) { | |
159 | librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx)); | |
160 | ||
161 | InSequence seq; | |
162 | expect_clone(mock_io_ctx); | |
163 | expect_read_rbd_info(mock_io_ctx, "", 0); | |
164 | expect_allocate_snap_id(mock_io_ctx, -EPERM); | |
165 | ||
166 | C_SaferCond ctx; | |
a4b75251 | 167 | auto req = new MockValidatePoolRequest(m_ioctx, &ctx); |
11fdf7f2 TL |
168 | req->send(); |
169 | ASSERT_EQ(-EPERM, ctx.wait()); | |
170 | } | |
171 | ||
172 | TEST_F(TestMockImageValidatePoolRequest, WriteError) { | |
173 | librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx)); | |
174 | ||
175 | InSequence seq; | |
176 | expect_clone(mock_io_ctx); | |
177 | expect_read_rbd_info(mock_io_ctx, "", -ENOENT); | |
178 | expect_allocate_snap_id(mock_io_ctx, 0); | |
179 | expect_write_rbd_info(mock_io_ctx, "validate", -EPERM); | |
180 | expect_release_snap_id(mock_io_ctx, -EINVAL); | |
181 | ||
182 | C_SaferCond ctx; | |
a4b75251 | 183 | auto req = new MockValidatePoolRequest(m_ioctx, &ctx); |
11fdf7f2 TL |
184 | req->send(); |
185 | ASSERT_EQ(-EPERM, ctx.wait()); | |
186 | } | |
187 | ||
188 | TEST_F(TestMockImageValidatePoolRequest, RemoveSnapshotError) { | |
189 | librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx)); | |
190 | ||
191 | InSequence seq; | |
192 | expect_clone(mock_io_ctx); | |
193 | expect_read_rbd_info(mock_io_ctx, "", -ENOENT); | |
194 | expect_allocate_snap_id(mock_io_ctx, 0); | |
195 | expect_write_rbd_info(mock_io_ctx, "validate", 0); | |
196 | expect_release_snap_id(mock_io_ctx, -EPERM); | |
197 | expect_write_rbd_info(mock_io_ctx, "overwrite validated", 0); | |
198 | ||
199 | C_SaferCond ctx; | |
a4b75251 | 200 | auto req = new MockValidatePoolRequest(m_ioctx, &ctx); |
11fdf7f2 TL |
201 | req->send(); |
202 | ASSERT_EQ(0, ctx.wait()); | |
203 | } | |
204 | ||
205 | TEST_F(TestMockImageValidatePoolRequest, OverwriteError) { | |
206 | librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_ioctx)); | |
207 | ||
208 | InSequence seq; | |
209 | expect_clone(mock_io_ctx); | |
210 | expect_read_rbd_info(mock_io_ctx, "", -ENOENT); | |
211 | expect_allocate_snap_id(mock_io_ctx, 0); | |
212 | expect_write_rbd_info(mock_io_ctx, "validate", 0); | |
213 | expect_release_snap_id(mock_io_ctx, 0); | |
214 | expect_write_rbd_info(mock_io_ctx, "overwrite validated", -EOPNOTSUPP); | |
215 | ||
216 | C_SaferCond ctx; | |
a4b75251 | 217 | auto req = new MockValidatePoolRequest(m_ioctx, &ctx); |
11fdf7f2 TL |
218 | req->send(); |
219 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
220 | } | |
221 | ||
222 | } // namespace image | |
223 | } // namespace librbd |