]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librados/snapshots_cxx.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / test / librados / snapshots_cxx.cc
1 #include <algorithm>
2 #include <errno.h>
3 #include <string>
4
5 #include "gtest/gtest.h"
6
7 #include "include/rados.h"
8 #include "include/rados/librados.hpp"
9 #include "test/librados/test_cxx.h"
10 #include "test/librados/testcase_cxx.h"
11
12 using namespace librados;
13
14 typedef RadosTestPP LibRadosSnapshotsPP;
15 typedef RadosTestPP LibRadosSnapshotsSelfManagedPP;
16 typedef RadosTestECPP LibRadosSnapshotsECPP;
17 typedef RadosTestECPP LibRadosSnapshotsSelfManagedECPP;
18
19 const int bufsize = 128;
20
21 TEST_F(LibRadosSnapshotsPP, SnapListPP) {
22 char buf[bufsize];
23 memset(buf, 0xcc, sizeof(buf));
24 bufferlist bl1;
25 bl1.append(buf, sizeof(buf));
26 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
27 ASSERT_FALSE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
28 ASSERT_EQ(0, ioctx.snap_create("snap1"));
29 ASSERT_FALSE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
30 std::vector<snap_t> snaps;
31 EXPECT_EQ(0, ioctx.snap_list(&snaps));
32 EXPECT_EQ(1U, snaps.size());
33 snap_t rid;
34 EXPECT_EQ(0, ioctx.snap_lookup("snap1", &rid));
35 EXPECT_EQ(rid, snaps[0]);
36 EXPECT_EQ(0, ioctx.snap_remove("snap1"));
37 ASSERT_FALSE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
38 }
39
40 TEST_F(LibRadosSnapshotsPP, SnapRemovePP) {
41 char buf[bufsize];
42 memset(buf, 0xcc, sizeof(buf));
43 bufferlist bl1;
44 bl1.append(buf, sizeof(buf));
45 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
46 ASSERT_EQ(0, ioctx.snap_create("snap1"));
47 rados_snap_t rid;
48 ASSERT_EQ(0, ioctx.snap_lookup("snap1", &rid));
49 ASSERT_EQ(0, ioctx.snap_remove("snap1"));
50 ASSERT_EQ(-ENOENT, ioctx.snap_lookup("snap1", &rid));
51 }
52
53 TEST_F(LibRadosSnapshotsPP, RollbackPP) {
54 char buf[bufsize];
55 memset(buf, 0xcc, sizeof(buf));
56 bufferlist bl1;
57 bl1.append(buf, sizeof(buf));
58 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
59 ASSERT_EQ(0, ioctx.snap_create("snap1"));
60 char buf2[sizeof(buf)];
61 memset(buf2, 0xdd, sizeof(buf2));
62 bufferlist bl2;
63 bl2.append(buf2, sizeof(buf2));
64 EXPECT_EQ(0, ioctx.write_full("foo", bl2));
65 EXPECT_EQ(0, ioctx.snap_rollback("foo", "snap1"));
66 bufferlist bl3;
67 EXPECT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), 0));
68 EXPECT_EQ(0, memcmp(buf, bl3.c_str(), sizeof(buf)));
69 EXPECT_EQ(0, ioctx.snap_remove("snap1"));
70 }
71
72 TEST_F(LibRadosSnapshotsPP, SnapGetNamePP) {
73 char buf[bufsize];
74 memset(buf, 0xcc, sizeof(buf));
75 bufferlist bl;
76 bl.append(buf, sizeof(buf));
77 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
78 ASSERT_EQ(0, ioctx.snap_create("snapfoo"));
79 rados_snap_t rid;
80 EXPECT_EQ(0, ioctx.snap_lookup("snapfoo", &rid));
81 EXPECT_EQ(-ENOENT, ioctx.snap_lookup("snapbar", &rid));
82 std::string name;
83 EXPECT_EQ(0, ioctx.snap_get_name(rid, &name));
84 time_t snaptime;
85 EXPECT_EQ(0, ioctx.snap_get_stamp(rid, &snaptime));
86 EXPECT_EQ(0, strcmp(name.c_str(), "snapfoo"));
87 EXPECT_EQ(0, ioctx.snap_remove("snapfoo"));
88 }
89
90 TEST_F(LibRadosSnapshotsPP, SnapCreateRemovePP) {
91 // reproduces http://tracker.ceph.com/issues/10262
92 bufferlist bl;
93 bl.append("foo");
94 ASSERT_EQ(0, ioctx.write("foo", bl, bl.length(), 0));
95 ASSERT_EQ(0, ioctx.snap_create("snapfoo"));
96 ASSERT_EQ(0, ioctx.remove("foo"));
97 ASSERT_EQ(0, ioctx.snap_create("snapbar"));
98
99 std::unique_ptr<librados::ObjectWriteOperation> op(new librados::ObjectWriteOperation());
100 op->create(false);
101 op->remove();
102 ASSERT_EQ(0, ioctx.operate("foo", op.get()));
103
104 EXPECT_EQ(0, ioctx.snap_remove("snapfoo"));
105 EXPECT_EQ(0, ioctx.snap_remove("snapbar"));
106 }
107
108 TEST_F(LibRadosSnapshotsSelfManagedPP, SnapPP) {
109 std::vector<uint64_t> my_snaps;
110 my_snaps.push_back(-2);
111 ASSERT_FALSE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
112 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
113 ASSERT_TRUE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
114 ::std::reverse(my_snaps.begin(), my_snaps.end());
115 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
116 ::std::reverse(my_snaps.begin(), my_snaps.end());
117 char buf[bufsize];
118 memset(buf, 0xcc, sizeof(buf));
119 bufferlist bl1;
120 bl1.append(buf, sizeof(buf));
121 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
122
123 my_snaps.push_back(-2);
124 librados::AioCompletion *completion = cluster.aio_create_completion();
125 ioctx.aio_selfmanaged_snap_create(&my_snaps.back(), completion);
126 ASSERT_EQ(0, completion->wait_for_complete());
127 completion->release();
128 ::std::reverse(my_snaps.begin(), my_snaps.end());
129 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
130 ::std::reverse(my_snaps.begin(), my_snaps.end());
131 char buf2[sizeof(buf)];
132 memset(buf2, 0xdd, sizeof(buf2));
133 bufferlist bl2;
134 bl2.append(buf2, sizeof(buf2));
135 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), 0));
136
137 ioctx.snap_set_read(my_snaps[1]);
138 bufferlist bl3;
139 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), 0));
140 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
141
142 completion = cluster.aio_create_completion();
143 ioctx.aio_selfmanaged_snap_remove(my_snaps.back(), completion);
144 ASSERT_EQ(0, completion->wait_for_complete());
145 completion->release();
146 my_snaps.pop_back();
147 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
148 my_snaps.pop_back();
149 ioctx.snap_set_read(LIBRADOS_SNAP_HEAD);
150 ASSERT_TRUE(cluster.get_pool_is_selfmanaged_snaps_mode(pool_name));
151 ASSERT_EQ(0, ioctx.remove("foo"));
152 }
153
154 TEST_F(LibRadosSnapshotsSelfManagedPP, RollbackPP) {
155 std::vector<uint64_t> my_snaps;
156 IoCtx readioctx;
157 ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), readioctx));
158 readioctx.set_namespace(nspace);
159 readioctx.snap_set_read(LIBRADOS_SNAP_DIR);
160
161 my_snaps.push_back(-2);
162 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
163 ::std::reverse(my_snaps.begin(), my_snaps.end());
164 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
165 ::std::reverse(my_snaps.begin(), my_snaps.end());
166 char buf[bufsize];
167 memset(buf, 0xcc, sizeof(buf));
168 bufferlist bl1;
169 bl1.append(buf, sizeof(buf));
170 //Write 3 consecutive buffers
171 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
172 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize));
173 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize*2));
174
175 snap_set_t ss;
176
177 snap_t head = SNAP_HEAD;
178 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
179 ASSERT_EQ(1u, ss.clones.size());
180 ASSERT_EQ(head, ss.clones[0].cloneid);
181 ASSERT_EQ(0u, ss.clones[0].snaps.size());
182 ASSERT_EQ(0u, ss.clones[0].overlap.size());
183 ASSERT_EQ(384u, ss.clones[0].size);
184
185 my_snaps.push_back(-2);
186 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
187 ::std::reverse(my_snaps.begin(), my_snaps.end());
188 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
189 ::std::reverse(my_snaps.begin(), my_snaps.end());
190 char buf2[sizeof(buf)];
191 memset(buf2, 0xdd, sizeof(buf2));
192 bufferlist bl2;
193 bl2.append(buf2, sizeof(buf2));
194 //Change the middle buffer
195 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize));
196 //Add another after
197 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*3));
198
199 ASSERT_EQ(-EINVAL, ioctx.list_snaps("foo", &ss));
200 ObjectReadOperation o;
201 o.list_snaps(&ss, NULL);
202 ASSERT_EQ(-EINVAL, ioctx.operate("foo", &o, NULL));
203
204 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
205 ASSERT_EQ(2u, ss.clones.size());
206 ASSERT_EQ(my_snaps[1], ss.clones[0].cloneid);
207 ASSERT_EQ(1u, ss.clones[0].snaps.size());
208 ASSERT_EQ(my_snaps[1], ss.clones[0].snaps[0]);
209 ASSERT_EQ(2u, ss.clones[0].overlap.size());
210 ASSERT_EQ(0u, ss.clones[0].overlap[0].first);
211 ASSERT_EQ(128u, ss.clones[0].overlap[0].second);
212 ASSERT_EQ(256u, ss.clones[0].overlap[1].first);
213 ASSERT_EQ(128u, ss.clones[0].overlap[1].second);
214 ASSERT_EQ(384u, ss.clones[0].size);
215 ASSERT_EQ(head, ss.clones[1].cloneid);
216 ASSERT_EQ(0u, ss.clones[1].snaps.size());
217 ASSERT_EQ(0u, ss.clones[1].overlap.size());
218 ASSERT_EQ(512u, ss.clones[1].size);
219
220 ioctx.selfmanaged_snap_rollback("foo", my_snaps[1]);
221
222 bufferlist bl3;
223 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), 0));
224 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
225 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), bufsize));
226 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
227 ASSERT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), bufsize*2));
228 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
229 ASSERT_EQ((int)0, ioctx.read("foo", bl3, sizeof(buf), bufsize*3));
230
231 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
232 my_snaps.pop_back();
233 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
234 my_snaps.pop_back();
235 readioctx.close();
236 }
237
238 TEST_F(LibRadosSnapshotsSelfManagedPP, SnapOverlapPP) {
239 std::vector<uint64_t> my_snaps;
240 IoCtx readioctx;
241 ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), readioctx));
242 readioctx.set_namespace(nspace);
243 readioctx.snap_set_read(LIBRADOS_SNAP_DIR);
244
245 my_snaps.push_back(-2);
246 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
247 ::std::reverse(my_snaps.begin(), my_snaps.end());
248 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
249 ::std::reverse(my_snaps.begin(), my_snaps.end());
250 char buf[bufsize];
251 memset(buf, 0xcc, sizeof(buf));
252 bufferlist bl1;
253 bl1.append(buf, sizeof(buf));
254 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
255 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize*2));
256 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize*4));
257 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize*6));
258 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), bufsize*8));
259
260 snap_set_t ss;
261 snap_t head = SNAP_HEAD;
262 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
263 ASSERT_EQ(1u, ss.clones.size());
264 ASSERT_EQ(head, ss.clones[0].cloneid);
265 ASSERT_EQ(0u, ss.clones[0].snaps.size());
266 ASSERT_EQ(0u, ss.clones[0].overlap.size());
267 ASSERT_EQ(1152u, ss.clones[0].size);
268
269 my_snaps.push_back(-2);
270 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
271 ::std::reverse(my_snaps.begin(), my_snaps.end());
272 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
273 ::std::reverse(my_snaps.begin(), my_snaps.end());
274 char buf2[sizeof(buf)];
275 memset(buf2, 0xdd, sizeof(buf2));
276 bufferlist bl2;
277 bl2.append(buf2, sizeof(buf2));
278 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*1));
279 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*3));
280 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*5));
281 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*7));
282 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize*9));
283
284 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
285 ASSERT_EQ(2u, ss.clones.size());
286 ASSERT_EQ(my_snaps[1], ss.clones[0].cloneid);
287 ASSERT_EQ(1u, ss.clones[0].snaps.size());
288 ASSERT_EQ(my_snaps[1], ss.clones[0].snaps[0]);
289 ASSERT_EQ(5u, ss.clones[0].overlap.size());
290 ASSERT_EQ(0u, ss.clones[0].overlap[0].first);
291 ASSERT_EQ(128u, ss.clones[0].overlap[0].second);
292 ASSERT_EQ(256u, ss.clones[0].overlap[1].first);
293 ASSERT_EQ(128u, ss.clones[0].overlap[1].second);
294 ASSERT_EQ(512u, ss.clones[0].overlap[2].first);
295 ASSERT_EQ(128u, ss.clones[0].overlap[2].second);
296 ASSERT_EQ(768u, ss.clones[0].overlap[3].first);
297 ASSERT_EQ(128u, ss.clones[0].overlap[3].second);
298 ASSERT_EQ(1024u, ss.clones[0].overlap[4].first);
299 ASSERT_EQ(128u, ss.clones[0].overlap[4].second);
300 ASSERT_EQ(1152u, ss.clones[0].size);
301 ASSERT_EQ(head, ss.clones[1].cloneid);
302 ASSERT_EQ(0u, ss.clones[1].snaps.size());
303 ASSERT_EQ(0u, ss.clones[1].overlap.size());
304 ASSERT_EQ(1280u, ss.clones[1].size);
305
306 my_snaps.push_back(-2);
307 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
308 ::std::reverse(my_snaps.begin(), my_snaps.end());
309 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
310 ::std::reverse(my_snaps.begin(), my_snaps.end());
311
312 char buf3[sizeof(buf)];
313 memset(buf3, 0xee, sizeof(buf3));
314 bufferlist bl4;
315 bl4.append(buf3, sizeof(buf3));
316 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf3), bufsize*1));
317 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf3), bufsize*4));
318 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf3), bufsize*5));
319 ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf3), bufsize*8));
320
321 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
322 ASSERT_EQ(3u, ss.clones.size());
323 ASSERT_EQ(my_snaps[1], ss.clones[0].cloneid);
324 ASSERT_EQ(1u, ss.clones[0].snaps.size());
325 ASSERT_EQ(my_snaps[1], ss.clones[0].snaps[0]);
326 ASSERT_EQ(5u, ss.clones[0].overlap.size());
327 ASSERT_EQ(0u, ss.clones[0].overlap[0].first);
328 ASSERT_EQ(128u, ss.clones[0].overlap[0].second);
329 ASSERT_EQ(256u, ss.clones[0].overlap[1].first);
330 ASSERT_EQ(128u, ss.clones[0].overlap[1].second);
331 ASSERT_EQ(512u, ss.clones[0].overlap[2].first);
332 ASSERT_EQ(128u, ss.clones[0].overlap[2].second);
333 ASSERT_EQ(768u, ss.clones[0].overlap[3].first);
334 ASSERT_EQ(128u, ss.clones[0].overlap[3].second);
335 ASSERT_EQ(1024u, ss.clones[0].overlap[4].first);
336 ASSERT_EQ(128u, ss.clones[0].overlap[4].second);
337 ASSERT_EQ(1152u, ss.clones[0].size);
338
339 ASSERT_EQ(my_snaps[2], ss.clones[1].cloneid);
340 ASSERT_EQ(1u, ss.clones[1].snaps.size());
341 ASSERT_EQ(my_snaps[2], ss.clones[1].snaps[0]);
342 ASSERT_EQ(4u, ss.clones[1].overlap.size());
343 ASSERT_EQ(0u, ss.clones[1].overlap[0].first);
344 ASSERT_EQ(128u, ss.clones[1].overlap[0].second);
345 ASSERT_EQ(256u, ss.clones[1].overlap[1].first);
346 ASSERT_EQ(256u, ss.clones[1].overlap[1].second);
347 ASSERT_EQ(768u, ss.clones[1].overlap[2].first);
348 ASSERT_EQ(256u, ss.clones[1].overlap[2].second);
349 ASSERT_EQ(1152u, ss.clones[1].overlap[3].first);
350 ASSERT_EQ(128u, ss.clones[1].overlap[3].second);
351 ASSERT_EQ(1280u, ss.clones[1].size);
352
353 ASSERT_EQ(head, ss.clones[2].cloneid);
354 ASSERT_EQ(0u, ss.clones[2].snaps.size());
355 ASSERT_EQ(0u, ss.clones[2].overlap.size());
356 ASSERT_EQ(1280u, ss.clones[2].size);
357
358 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
359 my_snaps.pop_back();
360 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
361 my_snaps.pop_back();
362 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
363 my_snaps.pop_back();
364 readioctx.close();
365 }
366
367 TEST_F(LibRadosSnapshotsSelfManagedPP, Bug11677) {
368 std::vector<uint64_t> my_snaps;
369 my_snaps.push_back(-2);
370 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
371 ::std::reverse(my_snaps.begin(), my_snaps.end());
372 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
373 ::std::reverse(my_snaps.begin(), my_snaps.end());
374
375 int bsize = 1<<20;
376 char *buf = (char *)new char[bsize];
377 memset(buf, 0xcc, bsize);
378 bufferlist bl1;
379 bl1.append(buf, bsize);
380 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, 0));
381
382 my_snaps.push_back(-2);
383 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
384 ::std::reverse(my_snaps.begin(), my_snaps.end());
385 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
386 ::std::reverse(my_snaps.begin(), my_snaps.end());
387
388 std::unique_ptr<librados::ObjectWriteOperation> op(new librados::ObjectWriteOperation());
389 op->assert_exists();
390 op->remove();
391 ASSERT_EQ(0, ioctx.operate("foo", op.get()));
392
393 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
394 my_snaps.pop_back();
395 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
396 my_snaps.pop_back();
397 ioctx.snap_set_read(LIBRADOS_SNAP_HEAD);
398 delete[] buf;
399 }
400
401 TEST_F(LibRadosSnapshotsSelfManagedPP, OrderSnap) {
402 std::vector<uint64_t> my_snaps;
403 char buf[bufsize];
404 memset(buf, 0xcc, sizeof(buf));
405 bufferlist bl;
406 bl.append(buf, sizeof(buf));
407
408 int flags = librados::OPERATION_ORDERSNAP;
409
410 my_snaps.push_back(-2);
411 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
412 ::std::reverse(my_snaps.begin(), my_snaps.end());
413 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
414 ::std::reverse(my_snaps.begin(), my_snaps.end());
415 ObjectWriteOperation op1;
416 op1.write(0, bl);
417 librados::AioCompletion *comp1 = cluster.aio_create_completion();
418 ASSERT_EQ(0, ioctx.aio_operate("foo", comp1, &op1, flags));
419 ASSERT_EQ(0, comp1->wait_for_complete());
420 ASSERT_EQ(0, comp1->get_return_value());
421 comp1->release();
422
423 my_snaps.push_back(-2);
424 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
425 ::std::reverse(my_snaps.begin(), my_snaps.end());
426 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
427 ::std::reverse(my_snaps.begin(), my_snaps.end());
428 ObjectWriteOperation op2;
429 op2.write(0, bl);
430 librados::AioCompletion *comp2 = cluster.aio_create_completion();
431 ASSERT_EQ(0, ioctx.aio_operate("foo", comp2, &op2, flags));
432 ASSERT_EQ(0, comp2->wait_for_complete());
433 ASSERT_EQ(0, comp2->get_return_value());
434 comp2->release();
435
436 my_snaps.pop_back();
437 ::std::reverse(my_snaps.begin(), my_snaps.end());
438 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
439 ::std::reverse(my_snaps.begin(), my_snaps.end());
440 ObjectWriteOperation op3;
441 op3.write(0, bl);
442 librados::AioCompletion *comp3 = cluster.aio_create_completion();
443 ASSERT_EQ(0, ioctx.aio_operate("foo", comp3, &op3, flags));
444 ASSERT_EQ(0, comp3->wait_for_complete());
445 ASSERT_EQ(-EOLDSNAPC, comp3->get_return_value());
446 comp3->release();
447
448 ObjectWriteOperation op4;
449 op4.write(0, bl);
450 librados::AioCompletion *comp4 = cluster.aio_create_completion();
451 ASSERT_EQ(0, ioctx.aio_operate("foo", comp4, &op4, 0));
452 ASSERT_EQ(0, comp4->wait_for_complete());
453 ASSERT_EQ(0, comp4->get_return_value());
454 comp4->release();
455 }
456
457 // EC testing
458 TEST_F(LibRadosSnapshotsECPP, SnapListPP) {
459 char buf[bufsize];
460 memset(buf, 0xcc, sizeof(buf));
461 bufferlist bl1;
462 bl1.append(buf, sizeof(buf));
463 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
464 ASSERT_EQ(0, ioctx.snap_create("snap1"));
465 std::vector<snap_t> snaps;
466 EXPECT_EQ(0, ioctx.snap_list(&snaps));
467 EXPECT_EQ(1U, snaps.size());
468 snap_t rid;
469 EXPECT_EQ(0, ioctx.snap_lookup("snap1", &rid));
470 EXPECT_EQ(rid, snaps[0]);
471 EXPECT_EQ(0, ioctx.snap_remove("snap1"));
472 }
473
474 TEST_F(LibRadosSnapshotsECPP, SnapRemovePP) {
475 char buf[bufsize];
476 memset(buf, 0xcc, sizeof(buf));
477 bufferlist bl1;
478 bl1.append(buf, sizeof(buf));
479 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
480 ASSERT_EQ(0, ioctx.snap_create("snap1"));
481 rados_snap_t rid;
482 ASSERT_EQ(0, ioctx.snap_lookup("snap1", &rid));
483 ASSERT_EQ(0, ioctx.snap_remove("snap1"));
484 ASSERT_EQ(-ENOENT, ioctx.snap_lookup("snap1", &rid));
485 }
486
487 TEST_F(LibRadosSnapshotsECPP, RollbackPP) {
488 char buf[bufsize];
489 memset(buf, 0xcc, sizeof(buf));
490 bufferlist bl1;
491 bl1.append(buf, sizeof(buf));
492 ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0));
493 ASSERT_EQ(0, ioctx.snap_create("snap1"));
494 char buf2[sizeof(buf)];
495 memset(buf2, 0xdd, sizeof(buf2));
496 bufferlist bl2;
497 bl2.append(buf2, sizeof(buf2));
498 EXPECT_EQ(0, ioctx.write_full("foo", bl2));
499 EXPECT_EQ(0, ioctx.snap_rollback("foo", "snap1"));
500 bufferlist bl3;
501 EXPECT_EQ((int)sizeof(buf), ioctx.read("foo", bl3, sizeof(buf), 0));
502 EXPECT_EQ(0, memcmp(buf, bl3.c_str(), sizeof(buf)));
503 EXPECT_EQ(0, ioctx.snap_remove("snap1"));
504 }
505
506 TEST_F(LibRadosSnapshotsECPP, SnapGetNamePP) {
507 char buf[bufsize];
508 memset(buf, 0xcc, sizeof(buf));
509 bufferlist bl;
510 bl.append(buf, sizeof(buf));
511 ASSERT_EQ(0, ioctx.write("foo", bl, sizeof(buf), 0));
512 ASSERT_EQ(0, ioctx.snap_create("snapfoo"));
513 rados_snap_t rid;
514 EXPECT_EQ(0, ioctx.snap_lookup("snapfoo", &rid));
515 EXPECT_EQ(-ENOENT, ioctx.snap_lookup("snapbar", &rid));
516 std::string name;
517 EXPECT_EQ(0, ioctx.snap_get_name(rid, &name));
518 time_t snaptime;
519 EXPECT_EQ(0, ioctx.snap_get_stamp(rid, &snaptime));
520 EXPECT_EQ(0, strcmp(name.c_str(), "snapfoo"));
521 EXPECT_EQ(0, ioctx.snap_remove("snapfoo"));
522 }
523
524 TEST_F(LibRadosSnapshotsSelfManagedECPP, SnapPP) {
525 std::vector<uint64_t> my_snaps;
526 my_snaps.push_back(-2);
527 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
528 ::std::reverse(my_snaps.begin(), my_snaps.end());
529 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
530 ::std::reverse(my_snaps.begin(), my_snaps.end());
531 int bsize = alignment;
532 char *buf = (char *)new char[bsize];
533 memset(buf, 0xcc, bsize);
534 bufferlist bl1;
535 bl1.append(buf, bsize);
536 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, 0));
537
538 my_snaps.push_back(-2);
539 librados::AioCompletion *completion = cluster.aio_create_completion();
540 ioctx.aio_selfmanaged_snap_create(&my_snaps.back(), completion);
541 ASSERT_EQ(0, completion->wait_for_complete());
542 completion->release();
543 ::std::reverse(my_snaps.begin(), my_snaps.end());
544 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
545 ::std::reverse(my_snaps.begin(), my_snaps.end());
546 char *buf2 = (char *)new char[bsize];
547 memset(buf2, 0xdd, bsize);
548 bufferlist bl2;
549 bl2.append(buf2, bsize);
550 // Add another aligned buffer
551 ASSERT_EQ(0, ioctx.write("foo", bl2, bsize, bsize));
552
553 ioctx.snap_set_read(my_snaps[1]);
554 bufferlist bl3;
555 ASSERT_EQ(bsize, ioctx.read("foo", bl3, bsize*3, 0));
556 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, bsize));
557
558 completion = cluster.aio_create_completion();
559 ioctx.aio_selfmanaged_snap_remove(my_snaps.back(), completion);
560 ASSERT_EQ(0, completion->wait_for_complete());
561 completion->release();
562 my_snaps.pop_back();
563 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
564 my_snaps.pop_back();
565 ioctx.snap_set_read(LIBRADOS_SNAP_HEAD);
566 ASSERT_EQ(0, ioctx.remove("foo"));
567 delete[] buf;
568 delete[] buf2;
569 }
570
571 TEST_F(LibRadosSnapshotsSelfManagedECPP, RollbackPP) {
572 std::vector<uint64_t> my_snaps;
573 IoCtx readioctx;
574 ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), readioctx));
575 readioctx.set_namespace(nspace);
576 readioctx.snap_set_read(LIBRADOS_SNAP_DIR);
577
578 my_snaps.push_back(-2);
579 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
580 ::std::reverse(my_snaps.begin(), my_snaps.end());
581 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
582 ::std::reverse(my_snaps.begin(), my_snaps.end());
583 int bsize = alignment;
584 char *buf = (char *)new char[bsize];
585 memset(buf, 0xcc, bsize);
586 bufferlist bl1;
587 bl1.append(buf, bsize);
588 //Write 3 consecutive buffers
589 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, 0));
590 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, bsize));
591 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, bsize*2));
592
593 snap_set_t ss;
594
595 snap_t head = SNAP_HEAD;
596 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
597 ASSERT_EQ(1u, ss.clones.size());
598 ASSERT_EQ(head, ss.clones[0].cloneid);
599 ASSERT_EQ(0u, ss.clones[0].snaps.size());
600 ASSERT_EQ(0u, ss.clones[0].overlap.size());
601 ASSERT_EQ((unsigned)(bsize*3), ss.clones[0].size);
602
603 my_snaps.push_back(-2);
604 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
605 ::std::reverse(my_snaps.begin(), my_snaps.end());
606 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
607 ::std::reverse(my_snaps.begin(), my_snaps.end());
608 char *buf2 = (char *)new char[bsize];
609 memset(buf2, 0xdd, bsize);
610 bufferlist bl2;
611 bl2.append(buf2, bsize);
612 //Change the middle buffer
613 //ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize));
614 //Add another after
615 ASSERT_EQ(0, ioctx.write("foo", bl2, bsize, bsize*3));
616
617 ASSERT_EQ(-EINVAL, ioctx.list_snaps("foo", &ss));
618 ObjectReadOperation o;
619 o.list_snaps(&ss, NULL);
620 ASSERT_EQ(-EINVAL, ioctx.operate("foo", &o, NULL));
621
622 ASSERT_EQ(0, readioctx.list_snaps("foo", &ss));
623 ASSERT_EQ(2u, ss.clones.size());
624 ASSERT_EQ(my_snaps[1], ss.clones[0].cloneid);
625 ASSERT_EQ(1u, ss.clones[0].snaps.size());
626 ASSERT_EQ(my_snaps[1], ss.clones[0].snaps[0]);
627 ASSERT_EQ(1u, ss.clones[0].overlap.size());
628 ASSERT_EQ(0u, ss.clones[0].overlap[0].first);
629 ASSERT_EQ((unsigned)bsize*3, ss.clones[0].overlap[0].second);
630 ASSERT_EQ((unsigned)bsize*3, ss.clones[0].size);
631 ASSERT_EQ(head, ss.clones[1].cloneid);
632 ASSERT_EQ(0u, ss.clones[1].snaps.size());
633 ASSERT_EQ(0u, ss.clones[1].overlap.size());
634 ASSERT_EQ((unsigned)bsize*4, ss.clones[1].size);
635
636 ioctx.selfmanaged_snap_rollback("foo", my_snaps[1]);
637
638 bufferlist bl3;
639 ASSERT_EQ(bsize, ioctx.read("foo", bl3, bsize, 0));
640 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, bsize));
641 ASSERT_EQ(bsize, ioctx.read("foo", bl3, bsize, bsize));
642 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, bsize));
643 ASSERT_EQ(bsize, ioctx.read("foo", bl3, bsize, bsize*2));
644 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, bsize));
645 ASSERT_EQ(0, ioctx.read("foo", bl3, bsize, bsize*3));
646
647 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
648 my_snaps.pop_back();
649 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
650 my_snaps.pop_back();
651 readioctx.close();
652
653 delete[] buf;
654 delete[] buf2;
655 }
656
657 TEST_F(LibRadosSnapshotsSelfManagedECPP, Bug11677) {
658 std::vector<uint64_t> my_snaps;
659 my_snaps.push_back(-2);
660 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
661 ::std::reverse(my_snaps.begin(), my_snaps.end());
662 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
663 ::std::reverse(my_snaps.begin(), my_snaps.end());
664
665 int bsize = alignment;
666 char *buf = (char *)new char[bsize];
667 memset(buf, 0xcc, bsize);
668 bufferlist bl1;
669 bl1.append(buf, bsize);
670 ASSERT_EQ(0, ioctx.write("foo", bl1, bsize, 0));
671
672 my_snaps.push_back(-2);
673 ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps.back()));
674 ::std::reverse(my_snaps.begin(), my_snaps.end());
675 ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], my_snaps));
676 ::std::reverse(my_snaps.begin(), my_snaps.end());
677
678 std::unique_ptr<librados::ObjectWriteOperation> op(new librados::ObjectWriteOperation());
679 op->assert_exists();
680 op->remove();
681 ASSERT_EQ(0, ioctx.operate("foo", op.get()));
682
683 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
684 my_snaps.pop_back();
685 ASSERT_EQ(0, ioctx.selfmanaged_snap_remove(my_snaps.back()));
686 my_snaps.pop_back();
687 ioctx.snap_set_read(LIBRADOS_SNAP_HEAD);
688 delete[] buf;
689 }