]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/librbd/test_Groups.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / test / librbd / test_Groups.cc
CommitLineData
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_fixture.h"
5#include "test/librbd/test_support.h"
6#include "include/rbd/librbd.h"
7#include "include/rbd/librbd.hpp"
8#include "test/librados/test.h"
9#include "gtest/gtest.h"
10
11#include <boost/scope_exit.hpp>
f67539c2 12#include <chrono>
11fdf7f2
TL
13#include <vector>
14
15void register_test_groups() {
16}
17
18class TestGroup : public TestFixture {
19
20};
21
22TEST_F(TestGroup, group_create)
23{
24 rados_ioctx_t ioctx;
25 rados_ioctx_create(_cluster, _pool_name.c_str(), &ioctx);
26 BOOST_SCOPE_EXIT(ioctx) {
27 rados_ioctx_destroy(ioctx);
28 } BOOST_SCOPE_EXIT_END;
29
30 librbd::RBD rbd;
31 ASSERT_EQ(0, rbd_group_create(ioctx, "mygroup"));
32
33 size_t size = 0;
34 ASSERT_EQ(-ERANGE, rbd_group_list(ioctx, NULL, &size));
35 ASSERT_EQ(strlen("mygroup") + 1, size);
36
37 char groups[80];
38 ASSERT_EQ(static_cast<int>(strlen("mygroup") + 1),
39 rbd_group_list(ioctx, groups, &size));
40 ASSERT_STREQ("mygroup", groups);
41
42 ASSERT_EQ(0, rbd_group_remove(ioctx, "mygroup"));
43
44 ASSERT_EQ(0, rbd_group_list(ioctx, groups, &size));
45}
46
47TEST_F(TestGroup, group_createPP)
48{
49 librados::IoCtx ioctx;
50 ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
51
52 librbd::RBD rbd;
53 ASSERT_EQ(0, rbd.group_create(ioctx, "mygroup"));
54
55 vector<string> groups;
56 ASSERT_EQ(0, rbd.group_list(ioctx, &groups));
57 ASSERT_EQ(1U, groups.size());
58 ASSERT_EQ("mygroup", groups[0]);
59
60 groups.clear();
61 ASSERT_EQ(0, rbd.group_rename(ioctx, "mygroup", "newgroup"));
62 ASSERT_EQ(0, rbd.group_list(ioctx, &groups));
63 ASSERT_EQ(1U, groups.size());
64 ASSERT_EQ("newgroup", groups[0]);
65
66 ASSERT_EQ(0, rbd.group_remove(ioctx, "newgroup"));
67
68 groups.clear();
69 ASSERT_EQ(0, rbd.group_list(ioctx, &groups));
70 ASSERT_EQ(0U, groups.size());
71}
72
73TEST_F(TestGroup, add_image)
74{
75 REQUIRE_FORMAT_V2();
76
77 rados_ioctx_t ioctx;
78 rados_ioctx_create(_cluster, _pool_name.c_str(), &ioctx);
79 BOOST_SCOPE_EXIT(ioctx) {
80 rados_ioctx_destroy(ioctx);
81 } BOOST_SCOPE_EXIT_END;
82
83 const char *group_name = "mycg";
84 ASSERT_EQ(0, rbd_group_create(ioctx, group_name));
85
86 rbd_image_t image;
87 ASSERT_EQ(0, rbd_open(ioctx, m_image_name.c_str(), &image, NULL));
88 BOOST_SCOPE_EXIT(image) {
89 EXPECT_EQ(0, rbd_close(image));
90 } BOOST_SCOPE_EXIT_END;
91
92 uint64_t features;
93 ASSERT_EQ(0, rbd_get_features(image, &features));
94 ASSERT_TRUE((features & RBD_FEATURE_OPERATIONS) == 0ULL);
95
96 uint64_t op_features;
97 ASSERT_EQ(0, rbd_get_op_features(image, &op_features));
98 ASSERT_TRUE((op_features & RBD_OPERATION_FEATURE_GROUP) == 0ULL);
99
100 ASSERT_EQ(0, rbd_group_image_add(ioctx, group_name, ioctx,
101 m_image_name.c_str()));
102
103 ASSERT_EQ(0, rbd_get_features(image, &features));
104 ASSERT_TRUE((features & RBD_FEATURE_OPERATIONS) ==
105 RBD_FEATURE_OPERATIONS);
106 ASSERT_EQ(0, rbd_get_op_features(image, &op_features));
107 ASSERT_TRUE((op_features & RBD_OPERATION_FEATURE_GROUP) ==
108 RBD_OPERATION_FEATURE_GROUP);
109
110 size_t num_images = 0;
111 ASSERT_EQ(-ERANGE, rbd_group_image_list(ioctx, group_name, NULL,
112 sizeof(rbd_group_image_info_t),
113 &num_images));
114 ASSERT_EQ(1U, num_images);
115
116 rbd_group_image_info_t images[1];
117 ASSERT_EQ(1, rbd_group_image_list(ioctx, group_name, images,
118 sizeof(rbd_group_image_info_t),
119 &num_images));
120
121 ASSERT_EQ(m_image_name, images[0].name);
122 ASSERT_EQ(rados_ioctx_get_id(ioctx), images[0].pool);
123
124 ASSERT_EQ(0, rbd_group_image_list_cleanup(images,
125 sizeof(rbd_group_image_info_t),
126 num_images));
127 ASSERT_EQ(0, rbd_group_image_remove(ioctx, group_name, ioctx,
128 m_image_name.c_str()));
129
130 ASSERT_EQ(0, rbd_get_features(image, &features));
131 ASSERT_TRUE((features & RBD_FEATURE_OPERATIONS) == 0ULL);
132 ASSERT_EQ(0, rbd_get_op_features(image, &op_features));
133 ASSERT_TRUE((op_features & RBD_OPERATION_FEATURE_GROUP) == 0ULL);
134
135 ASSERT_EQ(0, rbd_group_image_list(ioctx, group_name, images,
136 sizeof(rbd_group_image_info_t),
137 &num_images));
138 ASSERT_EQ(0U, num_images);
139
140 ASSERT_EQ(0, rbd_group_remove(ioctx, group_name));
141}
142
143TEST_F(TestGroup, add_imagePP)
144{
145 REQUIRE_FORMAT_V2();
146
147 librados::IoCtx ioctx;
148 ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
149
150 const char *group_name = "mycg";
151 librbd::RBD rbd;
152 ASSERT_EQ(0, rbd.group_create(ioctx, group_name));
153
154 librbd::Image image;
155 ASSERT_EQ(0, rbd.open(ioctx, image, m_image_name.c_str(), NULL));
156
157 uint64_t features;
158 ASSERT_EQ(0, image.features(&features));
159 ASSERT_TRUE((features & RBD_FEATURE_OPERATIONS) == 0ULL);
160
161 uint64_t op_features;
162 ASSERT_EQ(0, image.get_op_features(&op_features));
163 ASSERT_TRUE((op_features & RBD_OPERATION_FEATURE_GROUP) == 0ULL);
164
165 ASSERT_EQ(0, rbd.group_image_add(ioctx, group_name, ioctx,
166 m_image_name.c_str()));
167
168 ASSERT_EQ(0, image.features(&features));
169 ASSERT_TRUE((features & RBD_FEATURE_OPERATIONS) ==
170 RBD_FEATURE_OPERATIONS);
171 ASSERT_EQ(0, image.get_op_features(&op_features));
172 ASSERT_TRUE((op_features & RBD_OPERATION_FEATURE_GROUP) ==
173 RBD_OPERATION_FEATURE_GROUP);
174
175 vector<librbd::group_image_info_t> images;
176 ASSERT_EQ(0, rbd.group_image_list(ioctx, group_name, &images,
177 sizeof(librbd::group_image_info_t)));
178 ASSERT_EQ(1U, images.size());
179 ASSERT_EQ(m_image_name, images[0].name);
180 ASSERT_EQ(ioctx.get_id(), images[0].pool);
181
182 ASSERT_EQ(0, rbd.group_image_remove(ioctx, group_name, ioctx,
183 m_image_name.c_str()));
184
185 ASSERT_EQ(0, image.features(&features));
186 ASSERT_TRUE((features & RBD_FEATURE_OPERATIONS) == 0ULL);
187 ASSERT_EQ(0, image.get_op_features(&op_features));
188 ASSERT_TRUE((op_features & RBD_OPERATION_FEATURE_GROUP) == 0ULL);
189
190 images.clear();
191 ASSERT_EQ(0, rbd.group_image_list(ioctx, group_name, &images,
192 sizeof(librbd::group_image_info_t)));
193 ASSERT_EQ(0U, images.size());
194
195 ASSERT_EQ(0, rbd.group_remove(ioctx, group_name));
196}
197
198TEST_F(TestGroup, add_snapshot)
199{
200 REQUIRE_FORMAT_V2();
201
202 rados_ioctx_t ioctx;
203 rados_ioctx_create(_cluster, _pool_name.c_str(), &ioctx);
204 BOOST_SCOPE_EXIT(ioctx) {
205 rados_ioctx_destroy(ioctx);
206 } BOOST_SCOPE_EXIT_END;
207
208 const char *group_name = "snap_group";
209 const char *snap_name = "snap_snapshot";
210
211 const char orig_data[] = "orig data";
212 const char test_data[] = "test data";
213 char read_data[10];
214
215 rbd_image_t image;
216 ASSERT_EQ(0, rbd_open(ioctx, m_image_name.c_str(), &image, NULL));
217 BOOST_SCOPE_EXIT(image) {
218 EXPECT_EQ(0, rbd_close(image));
219 } BOOST_SCOPE_EXIT_END;
220
221 ASSERT_EQ(10, rbd_write(image, 0, 10, orig_data));
222 ASSERT_EQ(10, rbd_read(image, 0, 10, read_data));
223 ASSERT_EQ(0, memcmp(orig_data, read_data, 10));
224
225 ASSERT_EQ(0, rbd_group_create(ioctx, group_name));
226
227 ASSERT_EQ(0, rbd_group_image_add(ioctx, group_name, ioctx,
228 m_image_name.c_str()));
229
f67539c2
TL
230 struct Watcher {
231 static void quiesce_cb(void *arg) {
232 Watcher *watcher = static_cast<Watcher *>(arg);
233 watcher->handle_quiesce();
234 }
235 static void unquiesce_cb(void *arg) {
236 Watcher *watcher = static_cast<Watcher *>(arg);
237 watcher->handle_unquiesce();
238 }
239
240 rbd_image_t &image;
241 uint64_t handle = 0;
242 size_t quiesce_count = 0;
243 size_t unquiesce_count = 0;
244 int r = 0;
245
246 ceph::mutex lock = ceph::make_mutex("lock");
247 ceph::condition_variable cv;
248
249 Watcher(rbd_image_t &image) : image(image) {
250 }
251
252 void handle_quiesce() {
253 ASSERT_EQ(quiesce_count, unquiesce_count);
254 quiesce_count++;
255 rbd_quiesce_complete(image, handle, r);
256 }
257 void handle_unquiesce() {
258 std::unique_lock locker(lock);
259 unquiesce_count++;
260 cv.notify_one();
261 }
262 bool wait_for_unquiesce(size_t c) {
263 std::unique_lock locker(lock);
264 return cv.wait_for(locker, std::chrono::seconds(60),
265 [this, c]() { return unquiesce_count >= c; });
266 }
267 } watcher(image);
268
269 ASSERT_EQ(0, rbd_quiesce_watch(image, Watcher::quiesce_cb,
270 Watcher::unquiesce_cb, &watcher,
271 &watcher.handle));
272
11fdf7f2 273 ASSERT_EQ(0, rbd_group_snap_create(ioctx, group_name, snap_name));
f67539c2
TL
274 ASSERT_TRUE(watcher.wait_for_unquiesce(1U));
275 ASSERT_EQ(1U, watcher.quiesce_count);
11fdf7f2
TL
276
277 size_t num_snaps = 0;
278 ASSERT_EQ(-ERANGE, rbd_group_snap_list(ioctx, group_name, NULL,
279 sizeof(rbd_group_snap_info_t),
280 &num_snaps));
281 ASSERT_EQ(1U, num_snaps);
282
283 rbd_group_snap_info_t snaps[1];
284 ASSERT_EQ(1, rbd_group_snap_list(ioctx, group_name, snaps,
285 sizeof(rbd_group_snap_info_t),
286 &num_snaps));
287
288 ASSERT_STREQ(snap_name, snaps[0].name);
289
290 ASSERT_EQ(10, rbd_write(image, 11, 10, test_data));
291 ASSERT_EQ(10, rbd_read(image, 11, 10, read_data));
292 ASSERT_EQ(0, memcmp(test_data, read_data, 10));
293
294 ASSERT_EQ(0, rbd_group_snap_rollback(ioctx, group_name, snap_name));
295 ASSERT_EQ(10, rbd_read(image, 0, 10, read_data));
296 ASSERT_EQ(0, memcmp(orig_data, read_data, 10));
297
298 ASSERT_EQ(0, rbd_group_snap_list_cleanup(snaps, sizeof(rbd_group_snap_info_t),
299 num_snaps));
300 ASSERT_EQ(0, rbd_group_snap_remove(ioctx, group_name, snap_name));
301
302 ASSERT_EQ(0, rbd_group_snap_list(ioctx, group_name, snaps,
303 sizeof(rbd_group_snap_info_t),
304 &num_snaps));
305 ASSERT_EQ(0U, num_snaps);
306
f67539c2
TL
307 ASSERT_EQ(-EINVAL, rbd_group_snap_create2(ioctx, group_name, snap_name,
308 RBD_SNAP_CREATE_SKIP_QUIESCE |
309 RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR));
310 watcher.r = -EINVAL;
311 ASSERT_EQ(-EINVAL, rbd_group_snap_create2(ioctx, group_name, snap_name, 0));
312
313 num_snaps = 1;
314 ASSERT_EQ(0, rbd_group_snap_list(ioctx, group_name, snaps,
315 sizeof(rbd_group_snap_info_t),
316 &num_snaps));
317
318 watcher.quiesce_count = 0;
319 watcher.unquiesce_count = 0;
320 ASSERT_EQ(0, rbd_group_snap_create2(ioctx, group_name, snap_name,
321 RBD_SNAP_CREATE_SKIP_QUIESCE));
322 ASSERT_EQ(0U, watcher.quiesce_count);
323 num_snaps = 1;
324 ASSERT_EQ(1, rbd_group_snap_list(ioctx, group_name, snaps,
325 sizeof(rbd_group_snap_info_t),
326 &num_snaps));
327 ASSERT_EQ(0, rbd_group_snap_list_cleanup(snaps, sizeof(rbd_group_snap_info_t),
328 num_snaps));
329 ASSERT_EQ(0, rbd_group_snap_remove(ioctx, group_name, snap_name));
330
331 ASSERT_EQ(0, rbd_group_snap_create2(ioctx, group_name, snap_name,
332 RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR));
333 ASSERT_EQ(1, rbd_group_snap_list(ioctx, group_name, snaps,
334 sizeof(rbd_group_snap_info_t),
335 &num_snaps));
336 ASSERT_EQ(0, rbd_group_snap_list_cleanup(snaps, sizeof(rbd_group_snap_info_t),
337 num_snaps));
338 ASSERT_EQ(0, rbd_group_snap_remove(ioctx, group_name, snap_name));
339
340 ASSERT_EQ(0, rbd_quiesce_unwatch(image, watcher.handle));
11fdf7f2
TL
341 ASSERT_EQ(0, rbd_group_remove(ioctx, group_name));
342}
343
344TEST_F(TestGroup, add_snapshotPP)
345{
346 REQUIRE_FORMAT_V2();
347
348 librados::IoCtx ioctx;
349 ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
350
351 const char *group_name = "snap_group";
352 const char *snap_name = "snap_snapshot";
353
354 librbd::RBD rbd;
355 ASSERT_EQ(0, rbd.group_create(ioctx, group_name));
356
357 ASSERT_EQ(0, rbd.group_image_add(ioctx, group_name, ioctx,
358 m_image_name.c_str()));
359
360 librbd::Image image;
361 ASSERT_EQ(0, rbd.open(ioctx, image, m_image_name.c_str(), NULL));
362 bufferlist expect_bl;
363 bufferlist read_bl;
364 expect_bl.append(std::string(512, '1'));
365 ASSERT_EQ((ssize_t)expect_bl.length(), image.write(0, expect_bl.length(), expect_bl));
366 ASSERT_EQ(512, image.read(0, 512, read_bl));
367 ASSERT_TRUE(expect_bl.contents_equal(read_bl));
368
369 ASSERT_EQ(0, rbd.group_snap_create(ioctx, group_name, snap_name));
370
371 std::vector<librbd::group_snap_info_t> snaps;
372 ASSERT_EQ(0, rbd.group_snap_list(ioctx, group_name, &snaps,
373 sizeof(librbd::group_snap_info_t)));
374 ASSERT_EQ(1U, snaps.size());
375
376 ASSERT_EQ(snap_name, snaps[0].name);
377
378 bufferlist write_bl;
379 write_bl.append(std::string(1024, '2'));
380 ASSERT_EQ(1024, image.write(513, write_bl.length(), write_bl));
381
382 read_bl.clear();
383 ASSERT_EQ(1024, image.read(513, 1024, read_bl));
384 ASSERT_TRUE(write_bl.contents_equal(read_bl));
385
386 ASSERT_EQ(0, rbd.group_snap_rollback(ioctx, group_name, snap_name));
387
388 ASSERT_EQ(512, image.read(0, 512, read_bl));
389 ASSERT_TRUE(expect_bl.contents_equal(read_bl));
390
391 ASSERT_EQ(0, image.close());
392
393 ASSERT_EQ(0, rbd.group_snap_remove(ioctx, group_name, snap_name));
394
395 snaps.clear();
396 ASSERT_EQ(0, rbd.group_snap_list(ioctx, group_name, &snaps,
397 sizeof(librbd::group_snap_info_t)));
398 ASSERT_EQ(0U, snaps.size());
399
f67539c2
TL
400 ASSERT_EQ(0, rbd.group_snap_create(ioctx, group_name, snap_name));
401 ASSERT_EQ(0, rbd.group_snap_list(ioctx, group_name, &snaps,
402 sizeof(librbd::group_snap_info_t)));
403 ASSERT_EQ(1U, snaps.size());
404 ASSERT_EQ(0, rbd.group_snap_remove(ioctx, group_name, snap_name));
405
406 ASSERT_EQ(-EINVAL, rbd.group_snap_create2(ioctx, group_name, snap_name,
407 RBD_SNAP_CREATE_SKIP_QUIESCE |
408 RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR));
409 snaps.clear();
410 ASSERT_EQ(0, rbd.group_snap_list(ioctx, group_name, &snaps,
411 sizeof(librbd::group_snap_info_t)));
412 ASSERT_EQ(0U, snaps.size());
413
414 ASSERT_EQ(0, rbd.group_snap_create2(ioctx, group_name, snap_name,
415 RBD_SNAP_CREATE_SKIP_QUIESCE));
416 snaps.clear();
417 ASSERT_EQ(0, rbd.group_snap_list(ioctx, group_name, &snaps,
418 sizeof(librbd::group_snap_info_t)));
419 ASSERT_EQ(1U, snaps.size());
420
421 ASSERT_EQ(0, rbd.group_snap_remove(ioctx, group_name, snap_name));
11fdf7f2
TL
422 ASSERT_EQ(0, rbd.group_remove(ioctx, group_name));
423}