]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librados/snapshots.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / test / librados / snapshots.cc
1 #include "include/rados.h"
2 #include "test/librados/test.h"
3 #include "test/librados/TestCase.h"
4 #include "crimson_utils.h"
5
6 #include <algorithm>
7 #include <errno.h>
8 #include "gtest/gtest.h"
9 #include <string>
10
11 using std::string;
12
13 typedef RadosTest LibRadosSnapshots;
14 typedef RadosTest LibRadosSnapshotsSelfManaged;
15 typedef RadosTestEC LibRadosSnapshotsEC;
16 typedef RadosTestEC LibRadosSnapshotsSelfManagedEC;
17
18 const int bufsize = 128;
19
20 TEST_F(LibRadosSnapshots, SnapList) {
21 char buf[bufsize];
22 memset(buf, 0xcc, sizeof(buf));
23 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
24 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
25 rados_snap_t snaps[10];
26 EXPECT_EQ(1, rados_ioctx_snap_list(ioctx, snaps,
27 sizeof(snaps) / sizeof(snaps[0])));
28 rados_snap_t rid;
29 EXPECT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
30 EXPECT_EQ(rid, snaps[0]);
31 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
32 }
33
34 TEST_F(LibRadosSnapshots, SnapRemove) {
35 char buf[bufsize];
36 memset(buf, 0xcc, sizeof(buf));
37 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
38 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
39 rados_snap_t rid;
40 ASSERT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
41 ASSERT_EQ(-EEXIST, rados_ioctx_snap_create(ioctx, "snap1"));
42 ASSERT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
43 ASSERT_EQ(-ENOENT, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
44 }
45
46 TEST_F(LibRadosSnapshots, Rollback) {
47 char buf[bufsize];
48 memset(buf, 0xcc, sizeof(buf));
49 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
50 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
51 char buf2[sizeof(buf)];
52 memset(buf2, 0xdd, sizeof(buf2));
53 EXPECT_EQ(0, rados_write_full(ioctx, "foo", buf2, sizeof(buf2)));
54 EXPECT_EQ(0, rados_ioctx_snap_rollback(ioctx, "foo", "snap1"));
55 char buf3[sizeof(buf)];
56 EXPECT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
57 EXPECT_EQ(0, memcmp(buf, buf3, sizeof(buf)));
58 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
59 }
60
61 TEST_F(LibRadosSnapshots, SnapGetName) {
62 char buf[bufsize];
63 memset(buf, 0xcc, sizeof(buf));
64 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
65 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snapfoo"));
66 rados_snap_t rid;
67 EXPECT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snapfoo", &rid));
68 EXPECT_EQ(-ENOENT, rados_ioctx_snap_lookup(ioctx, "snapbar", &rid));
69 char name[128];
70 memset(name, 0, sizeof(name));
71 EXPECT_EQ(0, rados_ioctx_snap_get_name(ioctx, rid, name, sizeof(name)));
72 time_t snaptime;
73 EXPECT_EQ(0, rados_ioctx_snap_get_stamp(ioctx, rid, &snaptime));
74 EXPECT_EQ(0, strcmp(name, "snapfoo"));
75 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snapfoo"));
76 }
77
78 TEST_F(LibRadosSnapshotsSelfManaged, Snap) {
79 std::vector<uint64_t> my_snaps;
80 my_snaps.push_back(-2);
81 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
82 ::std::reverse(my_snaps.begin(), my_snaps.end());
83 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
84 &my_snaps[0], my_snaps.size()));
85 ::std::reverse(my_snaps.begin(), my_snaps.end());
86 char buf[bufsize];
87 memset(buf, 0xcc, sizeof(buf));
88 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
89
90 my_snaps.push_back(-2);
91 rados_completion_t completion;
92 ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr,
93 &completion));
94 rados_aio_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back(), completion);
95 ASSERT_EQ(0, rados_aio_wait_for_complete(completion));
96 rados_aio_release(completion);
97 ::std::reverse(my_snaps.begin(), my_snaps.end());
98 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
99 &my_snaps[0], my_snaps.size()));
100 ::std::reverse(my_snaps.begin(), my_snaps.end());
101 char buf2[sizeof(buf)];
102 memset(buf2, 0xdd, sizeof(buf2));
103 ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, sizeof(buf2), 0));
104 rados_ioctx_snap_set_read(ioctx, my_snaps[1]-1);
105 char buf3[sizeof(buf)];
106 ASSERT_EQ(-ENOENT, rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
107
108 rados_ioctx_snap_set_read(ioctx, my_snaps[1]);
109 ASSERT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
110 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
111
112 ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr,
113 &completion));
114 rados_aio_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back(), completion);
115 ASSERT_EQ(0, rados_aio_wait_for_complete(completion));
116 rados_aio_release(completion);
117 my_snaps.pop_back();
118 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
119 my_snaps.pop_back();
120 rados_ioctx_snap_set_read(ioctx, LIBRADOS_SNAP_HEAD);
121 ASSERT_EQ(0, rados_remove(ioctx, "foo"));
122 }
123
124 TEST_F(LibRadosSnapshotsSelfManaged, Rollback) {
125 std::vector<uint64_t> my_snaps;
126 my_snaps.push_back(-2);
127 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
128 ::std::reverse(my_snaps.begin(), my_snaps.end());
129 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
130 &my_snaps[0], my_snaps.size()));
131 ::std::reverse(my_snaps.begin(), my_snaps.end());
132 char buf[bufsize];
133 memset(buf, 0xcc, sizeof(buf));
134 // First write
135 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
136
137 my_snaps.push_back(-2);
138 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
139 ::std::reverse(my_snaps.begin(), my_snaps.end());
140 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
141 &my_snaps[0], my_snaps.size()));
142 ::std::reverse(my_snaps.begin(), my_snaps.end());
143 char buf2[sizeof(buf)];
144 memset(buf2, 0xdd, sizeof(buf2));
145 // Second write
146 ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, sizeof(buf2), 0));
147 // Rollback to my_snaps[1] - Object is expeceted to conatin the first write
148 rados_ioctx_selfmanaged_snap_rollback(ioctx, "foo", my_snaps[1]);
149 char buf3[sizeof(buf)];
150 ASSERT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
151 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
152
153 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
154 my_snaps.pop_back();
155 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
156 my_snaps.pop_back();
157 ASSERT_EQ(0, rados_remove(ioctx, "foo"));
158 }
159
160 TEST_F(LibRadosSnapshotsSelfManaged, FutureSnapRollback) {
161 std::vector<uint64_t> my_snaps;
162 // Snapshot 1
163 my_snaps.push_back(-2);
164 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
165 ::std::reverse(my_snaps.begin(), my_snaps.end());
166 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
167 &my_snaps[0], my_snaps.size()));
168 ::std::reverse(my_snaps.begin(), my_snaps.end());
169 char buf[bufsize];
170 memset(buf, 0xcc, sizeof(buf));
171 // First write
172 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
173
174 // Snapshot 2
175 my_snaps.push_back(-2);
176 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
177 ::std::reverse(my_snaps.begin(), my_snaps.end());
178 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
179 &my_snaps[0], my_snaps.size()));
180 ::std::reverse(my_snaps.begin(), my_snaps.end());
181 char buf2[sizeof(buf)];
182 memset(buf2, 0xdd, sizeof(buf2));
183 // Second write
184 ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, sizeof(buf2), 0));
185 // Snapshot 3
186 my_snaps.push_back(-2);
187 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
188
189 // Rollback to the last snap id - Object is expected to conatin
190 // latest write (head object)
191 rados_ioctx_selfmanaged_snap_rollback(ioctx, "foo", my_snaps[2]);
192 char buf3[sizeof(buf)];
193 ASSERT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
194 ASSERT_EQ(0, memcmp(buf3, buf2, sizeof(buf)));
195
196 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
197 my_snaps.pop_back();
198 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
199 my_snaps.pop_back();
200 ASSERT_EQ(0, rados_remove(ioctx, "foo"));
201 }
202
203
204
205 // EC testing
206 TEST_F(LibRadosSnapshotsEC, SnapList) {
207 SKIP_IF_CRIMSON();
208 char buf[bufsize];
209 memset(buf, 0xcc, sizeof(buf));
210 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
211 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
212 rados_snap_t snaps[10];
213 EXPECT_EQ(1, rados_ioctx_snap_list(ioctx, snaps,
214 sizeof(snaps) / sizeof(snaps[0])));
215 rados_snap_t rid;
216 EXPECT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
217 EXPECT_EQ(rid, snaps[0]);
218 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
219 }
220
221 TEST_F(LibRadosSnapshotsEC, SnapRemove) {
222 SKIP_IF_CRIMSON();
223 char buf[bufsize];
224 memset(buf, 0xcc, sizeof(buf));
225 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
226 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
227 rados_snap_t rid;
228 ASSERT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
229 ASSERT_EQ(-EEXIST, rados_ioctx_snap_create(ioctx, "snap1"));
230 ASSERT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
231 ASSERT_EQ(-ENOENT, rados_ioctx_snap_lookup(ioctx, "snap1", &rid));
232 }
233
234 TEST_F(LibRadosSnapshotsEC, Rollback) {
235 SKIP_IF_CRIMSON();
236 char buf[bufsize];
237 memset(buf, 0xcc, sizeof(buf));
238 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
239 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snap1"));
240 char buf2[sizeof(buf)];
241 memset(buf2, 0xdd, sizeof(buf2));
242 EXPECT_EQ(0, rados_write_full(ioctx, "foo", buf2, sizeof(buf2)));
243 EXPECT_EQ(0, rados_ioctx_snap_rollback(ioctx, "foo", "snap1"));
244 char buf3[sizeof(buf)];
245 EXPECT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0));
246 EXPECT_EQ(0, memcmp(buf, buf3, sizeof(buf)));
247 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snap1"));
248 }
249
250 TEST_F(LibRadosSnapshotsEC, SnapGetName) {
251 SKIP_IF_CRIMSON();
252 char buf[bufsize];
253 memset(buf, 0xcc, sizeof(buf));
254 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0));
255 ASSERT_EQ(0, rados_ioctx_snap_create(ioctx, "snapfoo"));
256 rados_snap_t rid;
257 EXPECT_EQ(0, rados_ioctx_snap_lookup(ioctx, "snapfoo", &rid));
258 EXPECT_EQ(-ENOENT, rados_ioctx_snap_lookup(ioctx, "snapbar", &rid));
259 char name[128];
260 memset(name, 0, sizeof(name));
261 EXPECT_EQ(0, rados_ioctx_snap_get_name(ioctx, rid, name, sizeof(name)));
262 time_t snaptime;
263 EXPECT_EQ(0, rados_ioctx_snap_get_stamp(ioctx, rid, &snaptime));
264 EXPECT_EQ(0, strcmp(name, "snapfoo"));
265 EXPECT_EQ(0, rados_ioctx_snap_remove(ioctx, "snapfoo"));
266 }
267
268 TEST_F(LibRadosSnapshotsSelfManagedEC, Snap) {
269 SKIP_IF_CRIMSON();
270 std::vector<uint64_t> my_snaps;
271 my_snaps.push_back(-2);
272 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
273 ::std::reverse(my_snaps.begin(), my_snaps.end());
274 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
275 &my_snaps[0], my_snaps.size()));
276 ::std::reverse(my_snaps.begin(), my_snaps.end());
277 int bsize = alignment;
278 char *buf = (char *)new char[bsize];
279 memset(buf, 0xcc, bsize);
280 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, bsize, 0));
281
282 my_snaps.push_back(-2);
283 rados_completion_t completion;
284 ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr,
285 &completion));
286 rados_aio_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back(), completion);
287 ASSERT_EQ(0, rados_aio_wait_for_complete(completion));
288 rados_aio_release(completion);
289 ::std::reverse(my_snaps.begin(), my_snaps.end());
290 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
291 &my_snaps[0], my_snaps.size()));
292 ::std::reverse(my_snaps.begin(), my_snaps.end());
293 char *buf2 = (char *)new char[bsize];
294 memset(buf2, 0xdd, bsize);
295 ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, bsize, bsize));
296 rados_ioctx_snap_set_read(ioctx, my_snaps[1]-1);
297 char *buf3 = (char *)new char[bsize*2];
298 ASSERT_EQ(-ENOENT, rados_read(ioctx, "foo", buf3, bsize*2, 0));
299
300 rados_ioctx_snap_set_read(ioctx, my_snaps[1]);
301 ASSERT_EQ(bsize, rados_read(ioctx, "foo", buf3, bsize*2, 0));
302 ASSERT_EQ(0, memcmp(buf3, buf, bsize));
303
304 ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr,
305 &completion));
306 rados_aio_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back(), completion);
307 ASSERT_EQ(0, rados_aio_wait_for_complete(completion));
308 rados_aio_release(completion);
309 my_snaps.pop_back();
310 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
311 my_snaps.pop_back();
312 rados_ioctx_snap_set_read(ioctx, LIBRADOS_SNAP_HEAD);
313 ASSERT_EQ(0, rados_remove(ioctx, "foo"));
314 delete[] buf;
315 delete[] buf2;
316 delete[] buf3;
317 }
318
319 TEST_F(LibRadosSnapshotsSelfManagedEC, Rollback) {
320 SKIP_IF_CRIMSON();
321 std::vector<uint64_t> my_snaps;
322 my_snaps.push_back(-2);
323 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
324 ::std::reverse(my_snaps.begin(), my_snaps.end());
325 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
326 &my_snaps[0], my_snaps.size()));
327 ::std::reverse(my_snaps.begin(), my_snaps.end());
328 int bsize = alignment;
329 char *buf = (char *)new char[bsize];
330 memset(buf, 0xcc, bsize);
331 ASSERT_EQ(0, rados_write(ioctx, "foo", buf, bsize, 0));
332
333 my_snaps.push_back(-2);
334 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_create(ioctx, &my_snaps.back()));
335 ::std::reverse(my_snaps.begin(), my_snaps.end());
336 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_set_write_ctx(ioctx, my_snaps[0],
337 &my_snaps[0], my_snaps.size()));
338 ::std::reverse(my_snaps.begin(), my_snaps.end());
339 char *buf2 = (char *)new char[bsize];
340 memset(buf2, 0xdd, bsize);
341
342 ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, bsize, bsize));
343 rados_ioctx_selfmanaged_snap_rollback(ioctx, "foo", my_snaps[1]);
344 char *buf3 = (char *)new char[bsize*2];
345 ASSERT_EQ(bsize, rados_read(ioctx, "foo", buf3, bsize*2, 0));
346 ASSERT_EQ(0, memcmp(buf3, buf, bsize));
347
348 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
349 my_snaps.pop_back();
350 ASSERT_EQ(0, rados_ioctx_selfmanaged_snap_remove(ioctx, my_snaps.back()));
351 my_snaps.pop_back();
352 ASSERT_EQ(0, rados_remove(ioctx, "foo"));
353 delete[] buf;
354 delete[] buf2;
355 delete[] buf3;
356 }