]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rbd_mirror/test_mock_InstanceReplayer.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / test / rbd_mirror / test_mock_InstanceReplayer.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/mock/MockImageCtx.h"
5 #include "test/rbd_mirror/test_mock_fixture.h"
6 #include "tools/rbd_mirror/ImageReplayer.h"
7 #include "tools/rbd_mirror/ImageSyncThrottler.h"
8 #include "tools/rbd_mirror/InstanceReplayer.h"
9 #include "tools/rbd_mirror/Threads.h"
10
11 namespace librbd {
12
13 namespace {
14
15 struct MockTestImageCtx : public MockImageCtx {
16 MockTestImageCtx(librbd::ImageCtx &image_ctx)
17 : librbd::MockImageCtx(image_ctx) {
18 }
19 };
20
21 } // anonymous namespace
22
23 } // namespace librbd
24
25 namespace rbd {
26 namespace mirror {
27
28 template <>
29 struct Threads<librbd::MockTestImageCtx> {
30 Mutex &timer_lock;
31 SafeTimer *timer;
32 ContextWQ *work_queue;
33
34 Threads(Threads<librbd::ImageCtx> *threads)
35 : timer_lock(threads->timer_lock), timer(threads->timer),
36 work_queue(threads->work_queue) {
37 }
38 };
39
40 template<>
41 struct ImageReplayer<librbd::MockTestImageCtx> {
42 static ImageReplayer* s_instance;
43 std::string global_image_id;
44
45 static ImageReplayer *create(
46 Threads<librbd::MockTestImageCtx> *threads,
47 std::shared_ptr<ImageDeleter> image_deleter,
48 ImageSyncThrottlerRef<librbd::MockTestImageCtx> image_sync_throttler,
49 RadosRef local, const std::string &local_mirror_uuid, int64_t local_pool_id,
50 const std::string &global_image_id) {
51 assert(s_instance != nullptr);
52 s_instance->global_image_id = global_image_id;
53 return s_instance;
54 }
55
56 ImageReplayer() {
57 assert(s_instance == nullptr);
58 s_instance = this;
59 }
60
61 virtual ~ImageReplayer() {
62 assert(s_instance == this);
63 s_instance = nullptr;
64 }
65
66 MOCK_METHOD0(destroy, void());
67 MOCK_METHOD2(start, void(Context *, bool));
68 MOCK_METHOD2(stop, void(Context *, bool));
69 MOCK_METHOD0(restart, void());
70 MOCK_METHOD0(flush, void());
71 MOCK_METHOD2(print_status, void(Formatter *, stringstream *));
72 MOCK_METHOD3(add_remote_image, void(const std::string &,
73 const std::string &,
74 librados::IoCtx &));
75 MOCK_METHOD3(remove_remote_image, void(const std::string &,
76 const std::string &,
77 bool));
78 MOCK_METHOD0(remote_images_empty, bool());
79 MOCK_METHOD0(get_global_image_id, const std::string &());
80 MOCK_METHOD0(get_local_image_id, const std::string &());
81 MOCK_METHOD0(is_running, bool());
82 MOCK_METHOD0(is_stopped, bool());
83 MOCK_METHOD0(is_blacklisted, bool());
84 };
85
86 template<>
87 struct ImageSyncThrottler<librbd::MockTestImageCtx> {
88 ImageSyncThrottler() {
89 }
90 virtual ~ImageSyncThrottler() {
91 }
92 };
93
94 ImageReplayer<librbd::MockTestImageCtx>* ImageReplayer<librbd::MockTestImageCtx>::s_instance = nullptr;
95
96 } // namespace mirror
97 } // namespace rbd
98
99 // template definitions
100 #include "tools/rbd_mirror/InstanceReplayer.cc"
101
102 namespace rbd {
103 namespace mirror {
104
105 using ::testing::_;
106 using ::testing::InSequence;
107 using ::testing::Invoke;
108 using ::testing::Return;
109 using ::testing::ReturnRef;
110
111 class TestMockInstanceReplayer : public TestMockFixture {
112 public:
113 typedef ImageReplayer<librbd::MockTestImageCtx> MockImageReplayer;
114 typedef InstanceReplayer<librbd::MockTestImageCtx> MockInstanceReplayer;
115 typedef Threads<librbd::MockTestImageCtx> MockThreads;
116
117 void SetUp() override {
118 TestMockFixture::SetUp();
119
120 m_mock_threads = new MockThreads(m_threads);
121
122 m_image_deleter.reset(
123 new rbd::mirror::ImageDeleter(m_threads->work_queue, m_threads->timer,
124 &m_threads->timer_lock));
125 m_image_sync_throttler.reset(
126 new rbd::mirror::ImageSyncThrottler<librbd::MockTestImageCtx>());
127 }
128
129 void TearDown() override {
130 delete m_mock_threads;
131 TestMockFixture::TearDown();
132 }
133
134 MockThreads *m_mock_threads;
135 std::shared_ptr<rbd::mirror::ImageDeleter> m_image_deleter;
136 std::shared_ptr<rbd::mirror::ImageSyncThrottler<librbd::MockTestImageCtx>>
137 m_image_sync_throttler;
138 };
139
140 TEST_F(TestMockInstanceReplayer, AcquireReleaseImage) {
141 MockImageReplayer mock_image_replayer;
142 MockInstanceReplayer instance_replayer(
143 m_mock_threads, m_image_deleter, m_image_sync_throttler,
144 rbd::mirror::RadosRef(new librados::Rados(m_local_io_ctx)),
145 "local_mirror_uuid", m_local_io_ctx.get_id());
146
147 std::string global_image_id("global_image_id");
148
149 EXPECT_CALL(mock_image_replayer, get_global_image_id())
150 .WillRepeatedly(ReturnRef(global_image_id));
151 EXPECT_CALL(mock_image_replayer, is_blacklisted())
152 .WillRepeatedly(Return(false));
153
154 InSequence seq;
155
156 instance_replayer.init();
157 instance_replayer.add_peer("remote_mirror_uuid", m_remote_io_ctx);
158
159 // Acquire
160
161 C_SaferCond on_acquire;
162
163 EXPECT_CALL(mock_image_replayer, add_remote_image("remote_mirror_uuid",
164 "remote_image_id", _));
165 EXPECT_CALL(mock_image_replayer, is_stopped())
166 .WillOnce(Return(true));
167 EXPECT_CALL(mock_image_replayer, start(nullptr, false));
168
169 instance_replayer.acquire_image(global_image_id, "remote_mirror_uuid",
170 "remote_image_id", &on_acquire);
171 ASSERT_EQ(0, on_acquire.wait());
172
173 // Release
174
175 C_SaferCond on_release;
176
177 EXPECT_CALL(mock_image_replayer,
178 remove_remote_image("remote_mirror_uuid", "remote_image_id",
179 false));
180 EXPECT_CALL(mock_image_replayer, remote_images_empty())
181 .WillOnce(Return(true));
182 EXPECT_CALL(mock_image_replayer, is_stopped())
183 .WillOnce(Return(false));
184 EXPECT_CALL(mock_image_replayer, is_running())
185 .WillOnce(Return(false));
186 EXPECT_CALL(mock_image_replayer, is_stopped())
187 .WillOnce(Return(false));
188 EXPECT_CALL(mock_image_replayer, is_running())
189 .WillOnce(Return(true));
190 EXPECT_CALL(mock_image_replayer, stop(_, false))
191 .WillOnce(CompleteContext(0));
192 EXPECT_CALL(mock_image_replayer, is_stopped())
193 .WillOnce(Return(true));
194 EXPECT_CALL(mock_image_replayer, destroy());
195
196 instance_replayer.release_image("global_image_id", "remote_mirror_uuid",
197 "remote_image_id", false, &on_release);
198 ASSERT_EQ(0, on_release.wait());
199
200 instance_replayer.shut_down();
201 }
202
203 } // namespace mirror
204 } // namespace rbd