]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/object_map/test_mock_SnapshotRollbackRequest.cc
import 15.2.0 Octopus source
[ceph.git] / 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 std::shared_lock image_locker{ictx->image_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(CEPH_NOSNAP,
109 RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
110 ASSERT_TRUE(flags_set);
111 expect_unlock_exclusive_lock(*ictx);
112 }
113
114 TEST_F(TestMockObjectMapSnapshotRollbackRequest, WriteMapError) {
115 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
116
117 librbd::ImageCtx *ictx;
118 ASSERT_EQ(0, open_image(m_image_name, &ictx));
119 ASSERT_EQ(0, snap_create(*ictx, "snap1"));
120 ASSERT_EQ(0, ictx->state->refresh_if_required());
121
122 uint64_t snap_id = ictx->snap_info.rbegin()->first;
123 expect_read_map(ictx, snap_id, 0);
124 expect_write_map(ictx, -EINVAL);
125 expect_invalidate(ictx, 1);
126
127 C_SaferCond cond_ctx;
128 AsyncRequest<> *request = new SnapshotRollbackRequest(
129 *ictx, snap_id, &cond_ctx);
130 request->send();
131 ASSERT_EQ(0, cond_ctx.wait());
132
133 {
134 std::shared_lock image_locker{ictx->image_lock};
135 uint64_t flags;
136 ASSERT_EQ(0, ictx->get_flags(snap_id, &flags));
137 ASSERT_EQ(0U, flags & RBD_FLAG_OBJECT_MAP_INVALID);
138 }
139 bool flags_set;
140 ASSERT_EQ(0, ictx->test_flags(CEPH_NOSNAP,
141 RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
142 ASSERT_TRUE(flags_set);
143 expect_unlock_exclusive_lock(*ictx);
144 }
145
146 } // namespace object_map
147 } // namespace librbd