Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / librbd / operation / test_mock_SnapshotProtectRequest.cc
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_mock_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "test/librbd/mock/MockImageCtx.h"
7 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
8 #include "common/bit_vector.hpp"
9 #include "librbd/ImageState.h"
10 #include "librbd/internal.h"
11 #include "librbd/operation/SnapshotProtectRequest.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14
15 // template definitions
16 #include "librbd/operation/SnapshotProtectRequest.cc"
17
18 namespace librbd {
19 namespace operation {
20
21 using ::testing::_;
22 using ::testing::DoAll;
23 using ::testing::DoDefault;
24 using ::testing::Return;
25 using ::testing::SetArgPointee;
26 using ::testing::StrEq;
27 using ::testing::WithArg;
28
29 class TestMockOperationSnapshotProtectRequest : public TestMockFixture {
30 public:
31   typedef SnapshotProtectRequest<MockImageCtx> MockSnapshotProtectRequest;
32
33   void expect_get_snap_id(MockImageCtx &mock_image_ctx, uint64_t snap_id) {
34     EXPECT_CALL(mock_image_ctx, get_snap_id(_, _))
35                   .WillOnce(Return(snap_id));
36   }
37
38   void expect_is_snap_protected(MockImageCtx &mock_image_ctx, bool is_protected,
39                                 int r) {
40     auto &expect = EXPECT_CALL(mock_image_ctx, is_snap_protected(_, _));
41     if (r < 0) {
42       expect.WillOnce(Return(r));
43     } else {
44       expect.WillOnce(DoAll(SetArgPointee<1>(is_protected), Return(0)));
45     }
46   }
47
48   void expect_set_protection_status(MockImageCtx &mock_image_ctx, int r) {
49     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
50                                exec(mock_image_ctx.header_oid, _, StrEq("rbd"),
51                                     StrEq("set_protection_status"), _, _, _));
52     if (r < 0) {
53       expect.WillOnce(Return(r));
54     } else {
55       expect.WillOnce(DoDefault());
56     }
57   }
58 };
59
60 TEST_F(TestMockOperationSnapshotProtectRequest, Success) {
61   REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
62
63   librbd::ImageCtx *ictx;
64   ASSERT_EQ(0, open_image(m_image_name, &ictx));
65   ASSERT_EQ(0, snap_create(*ictx, "snap1"));
66   ASSERT_EQ(0, ictx->state->refresh_if_required());
67
68   MockImageCtx mock_image_ctx(*ictx);
69
70   expect_op_work_queue(mock_image_ctx);
71
72   ::testing::InSequence seq;
73   expect_get_snap_id(mock_image_ctx, ictx->snap_info.rbegin()->first);
74   expect_is_snap_protected(mock_image_ctx, false, 0);
75   expect_set_protection_status(mock_image_ctx, 0);
76
77   C_SaferCond cond_ctx;
78   MockSnapshotProtectRequest *req = new MockSnapshotProtectRequest(
79     mock_image_ctx, &cond_ctx, cls::rbd::UserSnapshotNamespace(), "snap1");
80   {
81     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
82     req->send();
83   }
84   ASSERT_EQ(0, cond_ctx.wait());
85 }
86
87 TEST_F(TestMockOperationSnapshotProtectRequest, GetSnapIdMissing) {
88   REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
89
90   librbd::ImageCtx *ictx;
91   ASSERT_EQ(0, open_image(m_image_name, &ictx));
92   ASSERT_EQ(0, snap_create(*ictx, "snap1"));
93   ASSERT_EQ(0, ictx->state->refresh_if_required());
94
95   MockImageCtx mock_image_ctx(*ictx);
96
97   expect_op_work_queue(mock_image_ctx);
98
99   ::testing::InSequence seq;
100   expect_get_snap_id(mock_image_ctx, CEPH_NOSNAP);
101
102   C_SaferCond cond_ctx;
103   MockSnapshotProtectRequest *req = new MockSnapshotProtectRequest(
104     mock_image_ctx, &cond_ctx, cls::rbd::UserSnapshotNamespace(), "snap1");
105   {
106     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
107     req->send();
108   }
109   ASSERT_EQ(-ENOENT, cond_ctx.wait());
110 }
111
112 TEST_F(TestMockOperationSnapshotProtectRequest, IsSnapProtectedError) {
113   REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
114
115   librbd::ImageCtx *ictx;
116   ASSERT_EQ(0, open_image(m_image_name, &ictx));
117   ASSERT_EQ(0, snap_create(*ictx, "snap1"));
118   ASSERT_EQ(0, ictx->state->refresh_if_required());
119
120   MockImageCtx mock_image_ctx(*ictx);
121
122   expect_op_work_queue(mock_image_ctx);
123
124   ::testing::InSequence seq;
125   expect_get_snap_id(mock_image_ctx, ictx->snap_info.rbegin()->first);
126   expect_is_snap_protected(mock_image_ctx, false, -EINVAL);
127
128   C_SaferCond cond_ctx;
129   MockSnapshotProtectRequest *req = new MockSnapshotProtectRequest(
130     mock_image_ctx, &cond_ctx, cls::rbd::UserSnapshotNamespace(), "snap1");
131   {
132     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
133     req->send();
134   }
135   ASSERT_EQ(-EINVAL, cond_ctx.wait());
136 }
137
138 TEST_F(TestMockOperationSnapshotProtectRequest, SnapAlreadyProtected) {
139   REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
140
141   librbd::ImageCtx *ictx;
142   ASSERT_EQ(0, open_image(m_image_name, &ictx));
143   ASSERT_EQ(0, snap_create(*ictx, "snap1"));
144   ASSERT_EQ(0, ictx->state->refresh_if_required());
145
146   MockImageCtx mock_image_ctx(*ictx);
147
148   expect_op_work_queue(mock_image_ctx);
149
150   ::testing::InSequence seq;
151   expect_get_snap_id(mock_image_ctx, ictx->snap_info.rbegin()->first);
152   expect_is_snap_protected(mock_image_ctx, true, 0);
153
154   C_SaferCond cond_ctx;
155   MockSnapshotProtectRequest *req = new MockSnapshotProtectRequest(
156     mock_image_ctx, &cond_ctx, cls::rbd::UserSnapshotNamespace(), "snap1");
157   {
158     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
159     req->send();
160   }
161   ASSERT_EQ(-EBUSY, cond_ctx.wait());
162 }
163
164 TEST_F(TestMockOperationSnapshotProtectRequest, SetProtectionStateError) {
165   REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
166
167   librbd::ImageCtx *ictx;
168   ASSERT_EQ(0, open_image(m_image_name, &ictx));
169   ASSERT_EQ(0, snap_create(*ictx, "snap1"));
170   ASSERT_EQ(0, ictx->state->refresh_if_required());
171
172   MockImageCtx mock_image_ctx(*ictx);
173
174   expect_op_work_queue(mock_image_ctx);
175
176   ::testing::InSequence seq;
177   expect_get_snap_id(mock_image_ctx, ictx->snap_info.rbegin()->first);
178   expect_is_snap_protected(mock_image_ctx, false, 0);
179   expect_set_protection_status(mock_image_ctx, -EINVAL);
180
181   C_SaferCond cond_ctx;
182   MockSnapshotProtectRequest *req = new MockSnapshotProtectRequest(
183     mock_image_ctx, &cond_ctx, cls::rbd::UserSnapshotNamespace(), "snap1");
184   {
185     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
186     req->send();
187   }
188   ASSERT_EQ(-EINVAL, cond_ctx.wait());
189 }
190
191 } // namespace operation
192 } // namespace librbd