Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / rbd_mirror / test_ImageDeleter.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2016 SUSE LINUX GmbH
7  *
8  * This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License version 2.1, as published by the Free Software
11  * Foundation.  See file COPYING.
12  *
13  */
14 #include "include/rados/librados.hpp"
15 #include "include/rbd/librbd.hpp"
16 #include "include/stringify.h"
17 #include "cls/rbd/cls_rbd_types.h"
18 #include "cls/rbd/cls_rbd_client.h"
19 #include "tools/rbd_mirror/ImageDeleter.h"
20 #include "tools/rbd_mirror/ServiceDaemon.h"
21 #include "tools/rbd_mirror/Threads.h"
22 #include "librbd/ImageCtx.h"
23 #include "librbd/ImageState.h"
24 #include "librbd/Operations.h"
25 #include "librbd/Journal.h"
26 #include "librbd/internal.h"
27 #include "librbd/Utils.h"
28 #include "librbd/api/Mirror.h"
29 #include "librbd/journal/DisabledPolicy.h"
30 #include "test/rbd_mirror/test_fixture.h"
31
32 #include "test/librados/test.h"
33 #include "gtest/gtest.h"
34
35 #define GLOBAL_IMAGE_ID "global_image_id"
36 #define GLOBAL_CLONE_IMAGE_ID "global_image_id_clone"
37
38 #define dout_subsys ceph_subsys_rbd_mirror
39
40 using rbd::mirror::RadosRef;
41 using rbd::mirror::TestFixture;
42 using namespace librbd;
43 using cls::rbd::MirrorImageState;
44
45
46 void register_test_rbd_mirror_image_deleter() {
47 }
48
49 class TestImageDeleter : public TestFixture {
50 public:
51
52   static int64_t m_local_pool_id;
53
54   const std::string m_local_mirror_uuid = "local mirror uuid";
55   const std::string m_remote_mirror_uuid = "remote mirror uuid";
56
57   static void SetUpTestCase() {
58     TestFixture::SetUpTestCase();
59
60     m_local_pool_id = _rados->pool_lookup(_local_pool_name.c_str());
61   }
62
63   void SetUp() override {
64     TestFixture::SetUp();
65     m_service_daemon.reset(new rbd::mirror::ServiceDaemon<>(g_ceph_context,
66                                                             _rados, m_threads));
67
68     librbd::api::Mirror<>::mode_set(m_local_io_ctx, RBD_MIRROR_MODE_IMAGE);
69
70     m_deleter = new rbd::mirror::ImageDeleter<>(m_threads->work_queue,
71                                                 m_threads->timer,
72                                                 &m_threads->timer_lock,
73                                                 m_service_daemon.get());
74
75     m_local_image_id = librbd::util::generate_image_id(m_local_io_ctx);
76     librbd::ImageOptions image_opts;
77     image_opts.set(RBD_IMAGE_OPTION_FEATURES, RBD_FEATURES_ALL);
78     EXPECT_EQ(0, librbd::create(m_local_io_ctx, m_image_name, m_local_image_id,
79                                 1 << 20, image_opts, GLOBAL_IMAGE_ID,
80                                 m_remote_mirror_uuid, true));
81
82     cls::rbd::MirrorImage mirror_image(
83       GLOBAL_IMAGE_ID, MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
84     EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, m_local_image_id,
85                                               mirror_image));
86   }
87
88   void TearDown() override {
89     remove_image();
90     delete m_deleter;
91     m_service_daemon.reset();
92
93     TestFixture::TearDown();
94   }
95
96   void remove_image(bool force=false) {
97     if (!force) {
98       cls::rbd::MirrorImage mirror_image;
99       int r = cls_client::mirror_image_get(&m_local_io_ctx, m_local_image_id,
100                                            &mirror_image);
101       EXPECT_EQ(1, r == 0 || r == -ENOENT);
102       if (r != -ENOENT) {
103         mirror_image.state = MirrorImageState::MIRROR_IMAGE_STATE_ENABLED;
104         EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx,
105                                                   m_local_image_id,
106                                                   mirror_image));
107       }
108       promote_image();
109     }
110     NoOpProgressContext ctx;
111     int r = remove(m_local_io_ctx, m_image_name, "", ctx, force);
112     EXPECT_EQ(1, r == 0 || r == -ENOENT);
113   }
114
115   void promote_image(ImageCtx *ictx=nullptr) {
116     bool close = false;
117     int r = 0;
118     if (!ictx) {
119       ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
120                           false);
121       r = ictx->state->open(false);
122       close = (r == 0);
123     }
124
125     EXPECT_EQ(1, r == 0 || r == -ENOENT);
126
127     if (r == 0) {
128         int r2 = librbd::api::Mirror<>::image_promote(ictx, true);
129         EXPECT_EQ(1, r2 == 0 || r2 == -EINVAL);
130     }
131
132     if (close) {
133       EXPECT_EQ(0, ictx->state->close());
134     }
135   }
136
137   void demote_image(ImageCtx *ictx=nullptr) {
138     bool close = false;
139     if (!ictx) {
140       ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
141                           false);
142       EXPECT_EQ(0, ictx->state->open(false));
143       close = true;
144     }
145
146     EXPECT_EQ(0, librbd::api::Mirror<>::image_demote(ictx));
147
148     if (close) {
149       EXPECT_EQ(0, ictx->state->close());
150     }
151   }
152
153   void create_snapshot(std::string snap_name="snap1", bool protect=false) {
154     ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
155                                   false);
156     EXPECT_EQ(0, ictx->state->open(false));
157     {
158       RWLock::WLocker snap_locker(ictx->snap_lock);
159       ictx->set_journal_policy(new librbd::journal::DisabledPolicy());
160     }
161
162     EXPECT_EQ(0, ictx->operations->snap_create(
163                    cls::rbd::UserSnapshotNamespace(), snap_name.c_str()));
164
165     if (protect) {
166       EXPECT_EQ(0, ictx->operations->snap_protect(
167                      cls::rbd::UserSnapshotNamespace(), snap_name.c_str()));
168     }
169
170     EXPECT_EQ(0, ictx->state->close());
171   }
172
173   std::string create_clone() {
174     ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
175                                   false);
176     EXPECT_EQ(0, ictx->state->open(false));
177     {
178       RWLock::WLocker snap_locker(ictx->snap_lock);
179       ictx->set_journal_policy(new librbd::journal::DisabledPolicy());
180     }
181
182     EXPECT_EQ(0, ictx->operations->snap_create(
183                    cls::rbd::UserSnapshotNamespace(), "snap1"));
184     EXPECT_EQ(0, ictx->operations->snap_protect(
185                    cls::rbd::UserSnapshotNamespace(), "snap1"));
186     EXPECT_EQ(0, librbd::snap_set(ictx, cls::rbd::UserSnapshotNamespace(),
187                                   "snap1"));
188
189     std::string clone_id = librbd::util::generate_image_id(m_local_io_ctx);
190     librbd::ImageOptions clone_opts;
191     clone_opts.set(RBD_IMAGE_OPTION_FEATURES, ictx->features);
192     EXPECT_EQ(0, librbd::clone(ictx, m_local_io_ctx, "clone1", clone_id,
193                                clone_opts, GLOBAL_CLONE_IMAGE_ID,
194                                m_remote_mirror_uuid));
195
196     cls::rbd::MirrorImage mirror_image(
197       GLOBAL_CLONE_IMAGE_ID, MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
198     EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, clone_id,
199                                               mirror_image));
200     EXPECT_EQ(0, ictx->state->close());
201     return clone_id;
202   }
203
204   void check_image_deleted() {
205     ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
206                                   false);
207     EXPECT_EQ(-ENOENT, ictx->state->open(false));
208
209     cls::rbd::MirrorImage mirror_image;
210     EXPECT_EQ(-ENOENT, cls_client::mirror_image_get(&m_local_io_ctx,
211                                                     m_local_image_id,
212                                                     &mirror_image));
213   }
214
215
216   librbd::RBD rbd;
217   std::string m_local_image_id;
218   std::unique_ptr<rbd::mirror::ServiceDaemon<>> m_service_daemon;
219   rbd::mirror::ImageDeleter<> *m_deleter;
220 };
221
222 int64_t TestImageDeleter::m_local_pool_id;
223
224
225 TEST_F(TestImageDeleter, Delete_NonPrimary_Image) {
226   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
227                                    false);
228
229   C_SaferCond ctx;
230   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
231                                          &ctx);
232   EXPECT_EQ(0, ctx.wait());
233
234   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
235   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
236
237   check_image_deleted();
238 }
239
240 TEST_F(TestImageDeleter, Delete_Split_Brain_Image) {
241   promote_image();
242   demote_image();
243
244   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
245                                    true);
246
247   C_SaferCond ctx;
248   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
249                                          &ctx);
250   EXPECT_EQ(0, ctx.wait());
251
252   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
253   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
254
255   check_image_deleted();
256 }
257
258 TEST_F(TestImageDeleter, Fail_Delete_Primary_Image) {
259   promote_image();
260
261   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
262                                    false);
263
264   C_SaferCond ctx;
265   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
266                                          &ctx);
267   EXPECT_EQ(-rbd::mirror::ImageDeleter<>::EISPRM, ctx.wait());
268
269   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
270   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
271 }
272
273 TEST_F(TestImageDeleter, Fail_Delete_Orphan_Image) {
274   promote_image();
275   demote_image();
276
277   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
278                                    false);
279
280   C_SaferCond ctx;
281   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
282                                          &ctx);
283   EXPECT_EQ(-rbd::mirror::ImageDeleter<>::EISPRM, ctx.wait());
284
285   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
286   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
287 }
288
289 TEST_F(TestImageDeleter, Delete_Image_With_Child) {
290   create_snapshot();
291
292   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
293                                    false);
294
295   C_SaferCond ctx;
296   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
297                                          &ctx);
298   EXPECT_EQ(0, ctx.wait());
299
300   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
301   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
302 }
303
304 TEST_F(TestImageDeleter, Delete_Image_With_Children) {
305   create_snapshot("snap1");
306   create_snapshot("snap2");
307
308   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
309                                    false);
310
311   C_SaferCond ctx;
312   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
313                                          &ctx);
314   EXPECT_EQ(0, ctx.wait());
315
316   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
317   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
318 }
319
320 TEST_F(TestImageDeleter, Delete_Image_With_ProtectedChild) {
321   create_snapshot("snap1", true);
322
323   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
324                                    false);
325
326   C_SaferCond ctx;
327   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
328                                          &ctx);
329   EXPECT_EQ(0, ctx.wait());
330
331   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
332   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
333 }
334
335 TEST_F(TestImageDeleter, Delete_Image_With_ProtectedChildren) {
336   create_snapshot("snap1", true);
337   create_snapshot("snap2", true);
338
339   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
340                                    false);
341
342   C_SaferCond ctx;
343   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
344                                          &ctx);
345   EXPECT_EQ(0, ctx.wait());
346
347   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
348   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
349 }
350
351 TEST_F(TestImageDeleter, Delete_Image_With_Clone) {
352   std::string clone_id = create_clone();
353
354   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
355                                    false);
356
357   C_SaferCond ctx;
358   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
359                                          &ctx);
360   EXPECT_EQ(-EBUSY, ctx.wait());
361
362   ASSERT_EQ(1u, m_deleter->get_delete_queue_items().size());
363   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
364
365   m_deleter->schedule_image_delete(_rados, m_local_pool_id,
366                                    GLOBAL_CLONE_IMAGE_ID, false);
367
368   C_SaferCond ctx2;
369   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_CLONE_IMAGE_ID,
370                                          &ctx2);
371   EXPECT_EQ(0, ctx2.wait());
372
373   C_SaferCond ctx3;
374   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
375                                          &ctx3);
376   EXPECT_EQ(0, ctx3.wait());
377
378   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
379   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
380 }
381
382 TEST_F(TestImageDeleter, Delete_NonExistent_Image) {
383   remove_image();
384
385   cls::rbd::MirrorImage mirror_image(GLOBAL_IMAGE_ID,
386                               MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
387   EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, m_local_image_id,
388                                             mirror_image));
389
390   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
391                                    false);
392
393   C_SaferCond ctx;
394   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
395                                          &ctx);
396   EXPECT_EQ(0, ctx.wait());
397
398   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
399   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
400
401   check_image_deleted();
402 }
403
404 TEST_F(TestImageDeleter, Delete_NonExistent_Image_With_MirroringState) {
405   remove_image(true);
406
407   cls::rbd::MirrorImage mirror_image(GLOBAL_IMAGE_ID,
408                               MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
409   EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, m_local_image_id,
410                                             mirror_image));
411   mirror_image.state = MirrorImageState::MIRROR_IMAGE_STATE_DISABLING;
412   EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, m_local_image_id,
413                                             mirror_image));
414
415   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
416                                    false);
417
418   C_SaferCond ctx;
419   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
420                                          &ctx);
421   EXPECT_EQ(0, ctx.wait());
422
423   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
424   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
425
426   check_image_deleted();
427 }
428
429 TEST_F(TestImageDeleter, Delete_NonExistent_Image_Without_MirroringState) {
430   remove_image();
431
432   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
433                                    false);
434
435   C_SaferCond ctx;
436   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
437                                          &ctx);
438   EXPECT_EQ(-ENOENT, ctx.wait());
439
440   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
441   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
442
443   check_image_deleted();
444 }
445
446 TEST_F(TestImageDeleter, Fail_Delete_NonPrimary_Image) {
447   ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
448                                 false);
449   EXPECT_EQ(0, ictx->state->open(false));
450
451   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
452                                    false);
453
454   C_SaferCond ctx;
455   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
456                                          &ctx);
457   EXPECT_EQ(-EBUSY, ctx.wait());
458
459   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
460   ASSERT_EQ(1u, m_deleter->get_failed_queue_items().size());
461
462   EXPECT_EQ(0, ictx->state->close());
463 }
464
465 TEST_F(TestImageDeleter, Retry_Failed_Deletes) {
466   ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
467                                 false);
468   EXPECT_EQ(0, ictx->state->open(false));
469
470   m_deleter->set_failed_timer_interval(2);
471
472   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
473                                    false);
474
475   C_SaferCond ctx;
476   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
477                                          &ctx);
478   EXPECT_EQ(-EBUSY, ctx.wait());
479
480   EXPECT_EQ(0, ictx->state->close());
481
482   C_SaferCond ctx2;
483   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
484                                          &ctx2);
485   EXPECT_EQ(0, ctx2.wait());
486
487   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
488   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
489
490   check_image_deleted();
491 }
492
493 TEST_F(TestImageDeleter, Delete_Is_Idempotent) {
494   ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
495                                 false);
496   EXPECT_EQ(0, ictx->state->open(false));
497
498   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
499                                    false);
500
501   C_SaferCond ctx;
502   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
503                                          &ctx);
504   EXPECT_EQ(-EBUSY, ctx.wait());
505
506   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
507   ASSERT_EQ(1u, m_deleter->get_failed_queue_items().size());
508
509   m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
510                                    false);
511
512   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
513   ASSERT_EQ(1u, m_deleter->get_failed_queue_items().size());
514
515   EXPECT_EQ(0, ictx->state->close());
516 }
517
518