5 #include "gtest/gtest.h"
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"
12 using namespace librados
;
14 typedef RadosTestPP LibRadosSnapshotsPP
;
15 typedef RadosTestPP LibRadosSnapshotsSelfManagedPP
;
16 typedef RadosTestECPP LibRadosSnapshotsECPP
;
17 typedef RadosTestECPP LibRadosSnapshotsSelfManagedECPP
;
19 const int bufsize
= 128;
21 TEST_F(LibRadosSnapshotsPP
, SnapListPP
) {
23 memset(buf
, 0xcc, sizeof(buf
));
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());
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
));
40 TEST_F(LibRadosSnapshotsPP
, SnapRemovePP
) {
42 memset(buf
, 0xcc, sizeof(buf
));
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"));
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
));
53 TEST_F(LibRadosSnapshotsPP
, RollbackPP
) {
55 memset(buf
, 0xcc, sizeof(buf
));
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
));
63 bl2
.append(buf2
, sizeof(buf2
));
64 EXPECT_EQ(0, ioctx
.write_full("foo", bl2
));
65 EXPECT_EQ(0, ioctx
.snap_rollback("foo", "snap1"));
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"));
72 TEST_F(LibRadosSnapshotsPP
, SnapGetNamePP
) {
74 memset(buf
, 0xcc, sizeof(buf
));
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"));
80 EXPECT_EQ(0, ioctx
.snap_lookup("snapfoo", &rid
));
81 EXPECT_EQ(-ENOENT
, ioctx
.snap_lookup("snapbar", &rid
));
83 EXPECT_EQ(0, ioctx
.snap_get_name(rid
, &name
));
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"));
90 TEST_F(LibRadosSnapshotsPP
, SnapCreateRemovePP
) {
91 // reproduces http://tracker.ceph.com/issues/10262
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"));
99 std::unique_ptr
<librados::ObjectWriteOperation
> op(new librados::ObjectWriteOperation());
102 ASSERT_EQ(0, ioctx
.operate("foo", op
.get()));
104 EXPECT_EQ(0, ioctx
.snap_remove("snapfoo"));
105 EXPECT_EQ(0, ioctx
.snap_remove("snapbar"));
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());
118 memset(buf
, 0xcc, sizeof(buf
));
120 bl1
.append(buf
, sizeof(buf
));
121 ASSERT_EQ(0, ioctx
.write("foo", bl1
, sizeof(buf
), 0));
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
));
134 bl2
.append(buf2
, sizeof(buf2
));
135 ASSERT_EQ(0, ioctx
.write("foo", bl2
, sizeof(buf2
), 0));
137 ioctx
.snap_set_read(my_snaps
[1]);
139 ASSERT_EQ((int)sizeof(buf
), ioctx
.read("foo", bl3
, sizeof(buf
), 0));
140 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, sizeof(buf
)));
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();
147 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.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"));
154 TEST_F(LibRadosSnapshotsSelfManagedPP
, RollbackPP
) {
155 std::vector
<uint64_t> my_snaps
;
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
);
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());
167 memset(buf
, 0xcc, sizeof(buf
));
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));
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
);
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
));
193 bl2
.append(buf2
, sizeof(buf2
));
194 //Change the middle buffer
195 ASSERT_EQ(0, ioctx
.write("foo", bl2
, sizeof(buf2
), bufsize
));
197 ASSERT_EQ(0, ioctx
.write("foo", bl2
, sizeof(buf2
), bufsize
*3));
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
));
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
);
220 ioctx
.selfmanaged_snap_rollback("foo", my_snaps
[1]);
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));
231 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
233 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
238 TEST_F(LibRadosSnapshotsSelfManagedPP
, SnapOverlapPP
) {
239 std::vector
<uint64_t> my_snaps
;
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
);
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());
251 memset(buf
, 0xcc, sizeof(buf
));
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));
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
);
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
));
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));
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
);
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());
312 char buf3
[sizeof(buf
)];
313 memset(buf3
, 0xee, sizeof(buf3
));
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));
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
);
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
);
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
);
358 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
360 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
362 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
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());
376 char *buf
= (char *)new char[bsize
];
377 memset(buf
, 0xcc, bsize
);
379 bl1
.append(buf
, bsize
);
380 ASSERT_EQ(0, ioctx
.write("foo", bl1
, bsize
, 0));
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());
388 std::unique_ptr
<librados::ObjectWriteOperation
> op(new librados::ObjectWriteOperation());
391 ASSERT_EQ(0, ioctx
.operate("foo", op
.get()));
393 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
395 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
397 ioctx
.snap_set_read(LIBRADOS_SNAP_HEAD
);
401 TEST_F(LibRadosSnapshotsSelfManagedPP
, OrderSnap
) {
402 std::vector
<uint64_t> my_snaps
;
404 memset(buf
, 0xcc, sizeof(buf
));
406 bl
.append(buf
, sizeof(buf
));
408 int flags
= librados::OPERATION_ORDERSNAP
;
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
;
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());
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
;
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());
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
;
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());
448 ObjectWriteOperation op4
;
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());
458 TEST_F(LibRadosSnapshotsECPP
, SnapListPP
) {
460 memset(buf
, 0xcc, sizeof(buf
));
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());
469 EXPECT_EQ(0, ioctx
.snap_lookup("snap1", &rid
));
470 EXPECT_EQ(rid
, snaps
[0]);
471 EXPECT_EQ(0, ioctx
.snap_remove("snap1"));
474 TEST_F(LibRadosSnapshotsECPP
, SnapRemovePP
) {
476 memset(buf
, 0xcc, sizeof(buf
));
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"));
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
));
487 TEST_F(LibRadosSnapshotsECPP
, RollbackPP
) {
489 memset(buf
, 0xcc, sizeof(buf
));
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
));
497 bl2
.append(buf2
, sizeof(buf2
));
498 EXPECT_EQ(0, ioctx
.write_full("foo", bl2
));
499 EXPECT_EQ(0, ioctx
.snap_rollback("foo", "snap1"));
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"));
506 TEST_F(LibRadosSnapshotsECPP
, SnapGetNamePP
) {
508 memset(buf
, 0xcc, sizeof(buf
));
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"));
514 EXPECT_EQ(0, ioctx
.snap_lookup("snapfoo", &rid
));
515 EXPECT_EQ(-ENOENT
, ioctx
.snap_lookup("snapbar", &rid
));
517 EXPECT_EQ(0, ioctx
.snap_get_name(rid
, &name
));
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"));
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
);
535 bl1
.append(buf
, bsize
);
536 ASSERT_EQ(0, ioctx
.write("foo", bl1
, bsize
, 0));
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
);
549 bl2
.append(buf2
, bsize
);
550 // Add another aligned buffer
551 ASSERT_EQ(0, ioctx
.write("foo", bl2
, bsize
, bsize
));
553 ioctx
.snap_set_read(my_snaps
[1]);
555 ASSERT_EQ(bsize
, ioctx
.read("foo", bl3
, bsize
*3, 0));
556 ASSERT_EQ(0, memcmp(bl3
.c_str(), buf
, bsize
));
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();
563 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
565 ioctx
.snap_set_read(LIBRADOS_SNAP_HEAD
);
566 ASSERT_EQ(0, ioctx
.remove("foo"));
571 TEST_F(LibRadosSnapshotsSelfManagedECPP
, RollbackPP
) {
572 std::vector
<uint64_t> my_snaps
;
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
);
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
);
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));
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
);
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
);
611 bl2
.append(buf2
, bsize
);
612 //Change the middle buffer
613 //ASSERT_EQ(0, ioctx.write("foo", bl2, sizeof(buf2), bufsize));
615 ASSERT_EQ(0, ioctx
.write("foo", bl2
, bsize
, bsize
*3));
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
));
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
);
636 ioctx
.selfmanaged_snap_rollback("foo", my_snaps
[1]);
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));
647 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
649 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
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());
665 int bsize
= alignment
;
666 char *buf
= (char *)new char[bsize
];
667 memset(buf
, 0xcc, bsize
);
669 bl1
.append(buf
, bsize
);
670 ASSERT_EQ(0, ioctx
.write("foo", bl1
, bsize
, 0));
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());
678 std::unique_ptr
<librados::ObjectWriteOperation
> op(new librados::ObjectWriteOperation());
681 ASSERT_EQ(0, ioctx
.operate("foo", op
.get()));
683 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
685 ASSERT_EQ(0, ioctx
.selfmanaged_snap_remove(my_snaps
.back()));
687 ioctx
.snap_set_read(LIBRADOS_SNAP_HEAD
);