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