1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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"
15 struct MockTestImageCtx
: public MockImageCtx
{
16 MockTestImageCtx(librbd::ImageCtx
&image_ctx
)
17 : librbd::MockImageCtx(image_ctx
) {
21 } // anonymous namespace
29 struct Threads
<librbd::MockTestImageCtx
> {
32 ContextWQ
*work_queue
;
34 Threads(Threads
<librbd::ImageCtx
> *threads
)
35 : timer_lock(threads
->timer_lock
), timer(threads
->timer
),
36 work_queue(threads
->work_queue
) {
41 struct ImageReplayer
<librbd::MockTestImageCtx
> {
42 static ImageReplayer
* s_instance
;
43 std::string global_image_id
;
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
;
57 assert(s_instance
== nullptr);
61 virtual ~ImageReplayer() {
62 assert(s_instance
== this);
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
&,
75 MOCK_METHOD3(remove_remote_image
, void(const std::string
&,
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());
87 struct ImageSyncThrottler
<librbd::MockTestImageCtx
> {
88 ImageSyncThrottler() {
90 virtual ~ImageSyncThrottler() {
94 ImageReplayer
<librbd::MockTestImageCtx
>* ImageReplayer
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
99 // template definitions
100 #include "tools/rbd_mirror/InstanceReplayer.cc"
106 using ::testing::InSequence
;
107 using ::testing::Invoke
;
108 using ::testing::Return
;
109 using ::testing::ReturnRef
;
111 class TestMockInstanceReplayer
: public TestMockFixture
{
113 typedef ImageReplayer
<librbd::MockTestImageCtx
> MockImageReplayer
;
114 typedef InstanceReplayer
<librbd::MockTestImageCtx
> MockInstanceReplayer
;
115 typedef Threads
<librbd::MockTestImageCtx
> MockThreads
;
117 void SetUp() override
{
118 TestMockFixture::SetUp();
120 m_mock_threads
= new MockThreads(m_threads
);
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
>());
129 void TearDown() override
{
130 delete m_mock_threads
;
131 TestMockFixture::TearDown();
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
;
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());
147 std::string
global_image_id("global_image_id");
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));
156 instance_replayer
.init();
157 instance_replayer
.add_peer("remote_mirror_uuid", m_remote_io_ctx
);
161 C_SaferCond on_acquire
;
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));
169 instance_replayer
.acquire_image(global_image_id
, "remote_mirror_uuid",
170 "remote_image_id", &on_acquire
);
171 ASSERT_EQ(0, on_acquire
.wait());
175 C_SaferCond on_release
;
177 EXPECT_CALL(mock_image_replayer
,
178 remove_remote_image("remote_mirror_uuid", "remote_image_id",
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());
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());
200 instance_replayer
.shut_down();
203 } // namespace mirror