Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / librbd / object_map / test_mock_SnapshotRollbackRequest.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/librados_test_stub/MockTestMemIoCtxImpl.h"
7 #include "librbd/ImageState.h"
8 #include "librbd/internal.h"
9 #include "librbd/ObjectMap.h"
10 #include "librbd/object_map/SnapshotRollbackRequest.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13
14 namespace librbd {
15 namespace object_map {
16
17 using ::testing::_;
18 using ::testing::DoDefault;
19 using ::testing::Return;
20 using ::testing::StrEq;
21
22 class TestMockObjectMapSnapshotRollbackRequest : public TestMockFixture {
23 public:
24   void expect_read_map(librbd::ImageCtx *ictx, uint64_t snap_id, int r) {
25     if (r < 0) {
26       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
27                   read(ObjectMap<>::object_map_name(ictx->id, snap_id),
28                        0, 0, _)).WillOnce(Return(r));
29     } else {
30       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
31                   read(ObjectMap<>::object_map_name(ictx->id, snap_id),
32                        0, 0, _)).WillOnce(DoDefault());
33     }
34   }
35
36   void expect_write_map(librbd::ImageCtx *ictx, int r) {
37     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
38                 exec(ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP), _,
39                      StrEq("lock"), StrEq("assert_locked"), _, _, _))
40                   .WillOnce(DoDefault());
41     if (r < 0) {
42       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
43                   write_full(
44                     ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP), _, _))
45                   .WillOnce(Return(r));
46     } else {
47       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
48                   write_full(
49                     ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP), _, _))
50                   .WillOnce(DoDefault());
51     }
52   }
53
54   void expect_invalidate(librbd::ImageCtx *ictx, uint32_t times) {
55     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
56                 exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
57                   .Times(times)
58                   .WillRepeatedly(DoDefault());
59   }
60 };
61
62 TEST_F(TestMockObjectMapSnapshotRollbackRequest, Success) {
63   REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
64
65   librbd::ImageCtx *ictx;
66   ASSERT_EQ(0, open_image(m_image_name, &ictx));
67   ASSERT_EQ(0, snap_create(*ictx, "snap1"));
68   ASSERT_EQ(0, ictx->state->refresh_if_required());
69
70   uint64_t snap_id = ictx->snap_info.rbegin()->first;
71   expect_read_map(ictx, snap_id, 0);
72   expect_write_map(ictx, 0);
73
74   C_SaferCond cond_ctx;
75   AsyncRequest<> *request = new SnapshotRollbackRequest(
76     *ictx, snap_id, &cond_ctx);
77   request->send();
78   ASSERT_EQ(0, cond_ctx.wait());
79
80   expect_unlock_exclusive_lock(*ictx);
81 }
82
83 TEST_F(TestMockObjectMapSnapshotRollbackRequest, ReadMapError) {
84   REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
85
86   librbd::ImageCtx *ictx;
87   ASSERT_EQ(0, open_image(m_image_name, &ictx));
88   ASSERT_EQ(0, snap_create(*ictx, "snap1"));
89   ASSERT_EQ(0, ictx->state->refresh_if_required());
90
91   uint64_t snap_id = ictx->snap_info.rbegin()->first;
92   expect_read_map(ictx, snap_id, -ENOENT);
93   expect_invalidate(ictx, 2);
94
95   C_SaferCond cond_ctx;
96   AsyncRequest<> *request = new SnapshotRollbackRequest(
97     *ictx, snap_id, &cond_ctx);
98   request->send();
99   ASSERT_EQ(0, cond_ctx.wait());
100
101   {
102     RWLock::RLocker snap_locker(ictx->snap_lock);
103     uint64_t flags;
104     ASSERT_EQ(0, ictx->get_flags(snap_id, &flags));
105     ASSERT_NE(0U, flags & RBD_FLAG_OBJECT_MAP_INVALID);
106   }
107   bool flags_set;
108   ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
109   ASSERT_TRUE(flags_set);
110   expect_unlock_exclusive_lock(*ictx);
111 }
112
113 TEST_F(TestMockObjectMapSnapshotRollbackRequest, WriteMapError) {
114   REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
115
116   librbd::ImageCtx *ictx;
117   ASSERT_EQ(0, open_image(m_image_name, &ictx));
118   ASSERT_EQ(0, snap_create(*ictx, "snap1"));
119   ASSERT_EQ(0, ictx->state->refresh_if_required());
120
121   uint64_t snap_id = ictx->snap_info.rbegin()->first;
122   expect_read_map(ictx, snap_id, 0);
123   expect_write_map(ictx, -EINVAL);
124   expect_invalidate(ictx, 1);
125
126   C_SaferCond cond_ctx;
127   AsyncRequest<> *request = new SnapshotRollbackRequest(
128     *ictx, snap_id, &cond_ctx);
129   request->send();
130   ASSERT_EQ(0, cond_ctx.wait());
131
132   {
133     RWLock::RLocker snap_locker(ictx->snap_lock);
134     uint64_t flags;
135     ASSERT_EQ(0, ictx->get_flags(snap_id, &flags));
136     ASSERT_EQ(0U, flags & RBD_FLAG_OBJECT_MAP_INVALID);
137   }
138   bool flags_set;
139   ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
140   ASSERT_TRUE(flags_set);
141   expect_unlock_exclusive_lock(*ictx);
142 }
143
144 } // namespace object_map
145 } // namespace librbd