template <>
struct Threads<librbd::MockTestImageCtx> {
MockSafeTimer *timer;
- Mutex &timer_lock;
+ ceph::mutex &timer_lock;
MockContextWQ *work_queue;
}
};
- TestMockPoolWatcher() : m_lock("TestMockPoolWatcher::m_lock") {
- }
+ TestMockPoolWatcher() = default;
void expect_work_queue(MockThreads &mock_threads) {
EXPECT_CALL(*mock_threads.work_queue, queue(_, _))
EXPECT_CALL(mock_listener, mock_handle_update(mirror_uuid, added_image_ids,
removed_image_ids))
.WillOnce(WithoutArgs(Invoke([this]() {
- Mutex::Locker locker(m_lock);
+ std::lock_guard locker{m_lock};
++m_update_count;
- m_cond.Signal();
+ m_cond.notify_all();
})));
}
- void expect_mirror_uuid_get(librados::IoCtx &io_ctx,
- const std::string &uuid, int r) {
- bufferlist out_bl;
- encode(uuid, out_bl);
-
- EXPECT_CALL(get_mock_io_ctx(io_ctx),
- exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_uuid_get"),
- _, _, _))
- .WillOnce(DoAll(WithArg<5>(Invoke([out_bl](bufferlist *bl) {
- *bl = out_bl;
- })),
- Return(r)));
- }
-
void expect_timer_add_event(MockThreads &mock_threads) {
EXPECT_CALL(*mock_threads.timer, add_event_after(_, _))
.WillOnce(DoAll(WithArg<1>(Invoke([this](Context *ctx) {
auto wrapped_ctx =
- new FunctionContext([this, ctx](int r) {
- Mutex::Locker timer_locker(m_threads->timer_lock);
+ new LambdaContext([this, ctx](int r) {
+ std::lock_guard timer_locker{m_threads->timer_lock};
ctx->complete(r);
});
m_threads->work_queue->queue(wrapped_ctx, 0);
}
bool wait_for_update(uint32_t count) {
- Mutex::Locker locker(m_lock);
- while (m_update_count < count) {
- if (m_cond.WaitInterval(m_lock, utime_t(10, 0)) != 0) {
- break;
- }
- }
- if (m_update_count < count) {
+ std::unique_lock locker{m_lock};
+ if (m_cond.wait_for(locker, 10s,
+ [count, this] { return m_update_count >= count; })) {
+ m_update_count -= count;
+ return true;
+ } else {
return false;
}
-
- m_update_count -= count;
- return true;
}
- Mutex m_lock;
- Cond m_cond;
+ ceph::mutex m_lock = ceph::make_mutex("TestMockPoolWatcher::m_lock");
+ ceph::condition_variable m_cond;
uint32_t m_update_count = 0;
};
MockRefreshImagesRequest mock_refresh_images_request;
expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(0, ctx.wait());
{"global id 2", "remote id 2"}};
MockRefreshImagesRequest mock_refresh_images_request;
expect_refresh_images(mock_refresh_images_request, image_ids, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
expect_listener_handle_update(mock_listener, "remote uuid", image_ids, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(0, ctx.wait());
&refresh_sent]() {
*mock_refresh_images_request.image_ids = image_ids;
- Mutex::Locker locker(m_lock);
+ std::lock_guard locker{m_lock};
refresh_sent = true;
- m_cond.Signal();
+ m_cond.notify_all();
}));
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
image_ids = {
expect_listener_handle_update(mock_listener, "remote uuid", image_ids, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
mock_pool_watcher.init(nullptr);
{
- Mutex::Locker locker(m_lock);
- while (!refresh_sent) {
- m_cond.Wait(m_lock);
- }
+ std::unique_lock locker{m_lock};
+ m_cond.wait(locker, [&] { return refresh_sent; });
}
MirroringWatcher::get_instance().handle_image_updated(
{"global id 2", "remote id 2"}};
MockRefreshImagesRequest mock_refresh_images_request;
expect_refresh_images(mock_refresh_images_request, image_ids, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
EXPECT_CALL(*mock_threads.work_queue, queue(_, _))
.WillOnce(Invoke([this](Context *ctx, int r) {
Context *notify_ctx = nullptr;
EXPECT_CALL(*mock_threads.work_queue, queue(_, _))
.WillOnce(Invoke([this, ¬ify_ctx](Context *ctx, int r) {
- Mutex::Locker locker(m_lock);
+ std::lock_guard locker{m_lock};
ASSERT_EQ(nullptr, notify_ctx);
notify_ctx = ctx;
- m_cond.Signal();
+ m_cond.notify_all();
}));
expect_listener_handle_update(
mock_listener, "remote uuid",
{{"global id 1", "remote id 1"}, {"global id 2", "remote id 2"}});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(0, ctx.wait());
MockListener mock_listener(this);
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(-EBLACKLISTED, ctx.wait());
MockRefreshImagesRequest mock_refresh_images_request;
expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(-ENOENT, ctx.wait());
MockRefreshImagesRequest mock_refresh_images_request;
expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(0, ctx.wait());
MockListener mock_listener(this);
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(-EBLACKLISTED, ctx.wait());
MockRefreshImagesRequest mock_refresh_images_request;
expect_refresh_images(mock_refresh_images_request, {}, -ENOENT);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(0, ctx.wait());
expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, false);
expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
- C_SaferCond ctx;
- mock_pool_watcher.init(&ctx);
- ASSERT_EQ(0, ctx.wait());
-
- ASSERT_TRUE(wait_for_update(1));
- expect_mirroring_watcher_unregister(mock_mirroring_watcher, 0);
- ASSERT_EQ(0, when_shut_down(mock_pool_watcher));
-}
-
-TEST_F(TestMockPoolWatcher, GetMirrorUuidBlacklist) {
- MockThreads mock_threads(m_threads);
- expect_work_queue(mock_threads);
-
- InSequence seq;
- MockMirroringWatcher mock_mirroring_watcher;
- expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, true);
- expect_mirroring_watcher_register(mock_mirroring_watcher, 0);
-
- MockRefreshImagesRequest mock_refresh_images_request;
- expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", -EBLACKLISTED);
-
- MockListener mock_listener(this);
- MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
- C_SaferCond ctx;
- mock_pool_watcher.init(&ctx);
- ASSERT_EQ(-EBLACKLISTED, ctx.wait());
- ASSERT_TRUE(mock_pool_watcher.is_blacklisted());
-
- expect_mirroring_watcher_unregister(mock_mirroring_watcher, 0);
- ASSERT_EQ(0, when_shut_down(mock_pool_watcher));
-}
-
-TEST_F(TestMockPoolWatcher, GetMirrorUuidMissing) {
- MockThreads mock_threads(m_threads);
- expect_work_queue(mock_threads);
-
- InSequence seq;
- MockMirroringWatcher mock_mirroring_watcher;
- expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, true);
- expect_mirroring_watcher_register(mock_mirroring_watcher, 0);
-
- MockRefreshImagesRequest mock_refresh_images_request;
- expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "", -ENOENT);
- expect_timer_add_event(mock_threads);
-
- expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, false);
- expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
-
- MockListener mock_listener(this);
- expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
-
- MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
- C_SaferCond ctx;
- mock_pool_watcher.init(&ctx);
- ASSERT_EQ(-ENOENT, ctx.wait());
-
- ASSERT_TRUE(wait_for_update(1));
- expect_mirroring_watcher_unregister(mock_mirroring_watcher, 0);
- ASSERT_EQ(0, when_shut_down(mock_pool_watcher));
-}
-
-TEST_F(TestMockPoolWatcher, GetMirrorUuidError) {
- MockThreads mock_threads(m_threads);
- expect_work_queue(mock_threads);
-
- InSequence seq;
- MockMirroringWatcher mock_mirroring_watcher;
- expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, true);
- expect_mirroring_watcher_register(mock_mirroring_watcher, 0);
-
- MockRefreshImagesRequest mock_refresh_images_request;
- expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", -EINVAL);
- expect_timer_add_event(mock_threads);
-
- expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, false);
- expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
-
- MockListener mock_listener(this);
- expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
-
- MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(0, ctx.wait());
MockRefreshImagesRequest mock_refresh_images_request;
expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
expect_timer_add_event(mock_threads);
expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, false);
expect_refresh_images(mock_refresh_images_request, {{"global id", "image id"}}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
expect_listener_handle_update(mock_listener, "remote uuid",
{{"global id", "image id"}}, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(0, ctx.wait());
MockRefreshImagesRequest mock_refresh_images_request;
expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(0, ctx.wait());
MockRefreshImagesRequest mock_refresh_images_request;
expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
expect_timer_add_event(mock_threads);
expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, false);
expect_refresh_images(mock_refresh_images_request, {{"global id", "image id"}}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
expect_listener_handle_update(mock_listener, "remote uuid",
{{"global id", "image id"}}, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(0, ctx.wait());
MirroringWatcher::get_instance().handle_rewatch_complete(0);
mock_refresh_images_request.on_finish->complete(0);
}));
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
expect_timer_add_event(mock_threads);
expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, false);
expect_refresh_images(mock_refresh_images_request, {}, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
MockListener mock_listener(this);
expect_listener_handle_update(mock_listener, "remote uuid", {}, {});
MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
- C_SaferCond ctx;
- mock_pool_watcher.init(&ctx);
- ASSERT_EQ(0, ctx.wait());
- ASSERT_TRUE(wait_for_update(1));
-
- expect_mirroring_watcher_unregister(mock_mirroring_watcher, 0);
- ASSERT_EQ(0, when_shut_down(mock_pool_watcher));
-}
-
-TEST_F(TestMockPoolWatcher, MirrorUuidUpdated) {
- MockThreads mock_threads(m_threads);
- expect_work_queue(mock_threads);
-
- InSequence seq;
- MockMirroringWatcher mock_mirroring_watcher;
- expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, true);
- expect_mirroring_watcher_register(mock_mirroring_watcher, 0);
-
- ImageIds image_ids{
- {"global id 1", "remote id 1"},
- {"global id 2", "remote id 2"}};
- MockRefreshImagesRequest mock_refresh_images_request;
- expect_refresh_images(mock_refresh_images_request, image_ids, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "remote uuid", 0);
-
- MockListener mock_listener(this);
- expect_listener_handle_update(mock_listener, "remote uuid", image_ids, {});
-
- MockPoolWatcher mock_pool_watcher(&mock_threads, m_remote_io_ctx,
- mock_listener);
+ "remote uuid", mock_listener);
C_SaferCond ctx;
mock_pool_watcher.init(&ctx);
ASSERT_EQ(0, ctx.wait());
-
ASSERT_TRUE(wait_for_update(1));
- expect_timer_add_event(mock_threads);
- ImageIds new_image_ids{
- {"global id 1", "remote id 1"}};
- expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher, false);
- expect_refresh_images(mock_refresh_images_request, new_image_ids, 0);
- expect_mirror_uuid_get(m_remote_io_ctx, "updated uuid", 0);
- expect_listener_handle_update(mock_listener, "remote uuid", {}, image_ids);
- expect_listener_handle_update(mock_listener, "updated uuid", new_image_ids,
- {});
-
- MirroringWatcher::get_instance().handle_rewatch_complete(0);
- ASSERT_TRUE(wait_for_update(2));
-
expect_mirroring_watcher_unregister(mock_mirroring_watcher, 0);
ASSERT_EQ(0, when_shut_down(mock_pool_watcher));
}