struct Threads<librbd::MockTestImageCtx> {
ceph::mutex &timer_lock;
SafeTimer *timer;
- ContextWQ *work_queue;
+ librbd::asio::ContextWQ *work_queue;
Threads(Threads<librbd::ImageCtx> *threads)
: timer_lock(threads->timer_lock), timer(threads->timer),
static OpenLocalImageRequest* create(librados::IoCtx &local_io_ctx,
librbd::MockTestImageCtx **local_image_ctx,
const std::string &local_image_id,
- ContextWQ *work_queue,
+ librbd::asio::ContextWQ *work_queue,
Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->image_ctx = local_image_ctx;
const std::string &global_image_id,
std::string *local_image_name,
StateBuilder<librbd::MockTestImageCtx>** state_builder,
- ContextWQ *work_queue,
+ librbd::asio::ContextWQ *work_queue,
Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->local_image_name = local_image_name;
MOCK_CONST_METHOD0(is_disconnected, bool());
MOCK_CONST_METHOD0(is_local_primary, bool());
+ MOCK_CONST_METHOD0(is_remote_primary, bool());
MOCK_CONST_METHOD0(is_linked, bool());
MOCK_CONST_METHOD0(replay_requires_remote_image, bool());
.WillOnce(Return(is_primary));
}
+ void expect_is_remote_primary(MockStateBuilder& mock_state_builder,
+ bool is_primary) {
+ EXPECT_CALL(mock_state_builder, is_remote_primary())
+ .WillOnce(Return(is_primary));
+ }
+
+ void expect_is_linked(MockStateBuilder& mock_state_builder, bool is_linked) {
+ EXPECT_CALL(mock_state_builder, is_linked())
+ .WillOnce(Return(is_linked));
+ }
+
void expect_is_disconnected(MockStateBuilder& mock_state_builder,
bool is_disconnected) {
EXPECT_CALL(mock_state_builder, is_disconnected())
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
+
+ // open the remote image
+ librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+ MockOpenImageRequest mock_open_image_request;
+ expect_open_image(mock_open_image_request, m_remote_io_ctx,
+ mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
+
+ // open the local image
+ librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
+ MockOpenLocalImageRequest mock_open_local_image_request;
+ expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
+ mock_local_image_ctx.id, &mock_local_image_ctx, 0);
+
+ // prepare replay
+ expect_prepare_replay(mock_state_builder, false, false, 0);
+ expect_is_disconnected(mock_state_builder, false);
+
+ // close remote image
+ expect_replay_requires_remote_image(mock_state_builder, false);
+ expect_close_remote_image(mock_state_builder, 0);
+
+ C_SaferCond ctx;
+ MockThreads mock_threads(m_threads);
+ MockInstanceWatcher mock_instance_watcher;
+ MockBootstrapRequest *request = create_request(
+ &mock_threads, &mock_instance_watcher, "global image id",
+ "local mirror uuid", &ctx);
+ request->send();
+ ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageReplayerBootstrapRequest, PrepareRemoteImageNotPrimaryLocalDNE) {
+ InSequence seq;
+
+ // prepare local image
+ MockStateBuilder mock_state_builder;
+ MockPrepareLocalImageRequest mock_prepare_local_image_request;
+ expect_send(mock_prepare_local_image_request, mock_state_builder,
+ m_local_image_ctx->id, m_local_image_ctx->name, -ENOENT);
+
+ // prepare remote image
+ MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
+ expect_send(mock_prepare_remote_image_request, mock_state_builder,
+ "remote mirror uuid", m_remote_image_ctx->id, 0);
+ expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, false);
+
+ C_SaferCond ctx;
+ MockThreads mock_threads(m_threads);
+ MockInstanceWatcher mock_instance_watcher;
+ MockBootstrapRequest *request = create_request(
+ &mock_threads, &mock_instance_watcher, "global image id",
+ "local mirror uuid", &ctx);
+ request->send();
+ ASSERT_EQ(-EREMOTEIO, ctx.wait());
+}
+
+TEST_F(TestMockImageReplayerBootstrapRequest, PrepareRemoteImageNotPrimaryLocalUnlinked) {
+ InSequence seq;
+
+ // prepare local image
+ MockStateBuilder mock_state_builder;
+ MockPrepareLocalImageRequest mock_prepare_local_image_request;
+ expect_send(mock_prepare_local_image_request, mock_state_builder,
+ m_local_image_ctx->id, m_local_image_ctx->name, 0);
+
+ // prepare remote image
+ MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
+ expect_send(mock_prepare_remote_image_request, mock_state_builder,
+ "remote mirror uuid", m_remote_image_ctx->id, 0);
+ expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, false);
+ expect_is_linked(mock_state_builder, false);
+
+ C_SaferCond ctx;
+ MockThreads mock_threads(m_threads);
+ MockInstanceWatcher mock_instance_watcher;
+ MockBootstrapRequest *request = create_request(
+ &mock_threads, &mock_instance_watcher, "global image id",
+ "local mirror uuid", &ctx);
+ request->send();
+ ASSERT_EQ(-EREMOTEIO, ctx.wait());
+}
+
+TEST_F(TestMockImageReplayerBootstrapRequest, PrepareRemoteImageNotPrimaryLocalLinked) {
+ InSequence seq;
+
+ // prepare local image
+ MockStateBuilder mock_state_builder;
+ MockPrepareLocalImageRequest mock_prepare_local_image_request;
+ expect_send(mock_prepare_local_image_request, mock_state_builder,
+ m_local_image_ctx->id, m_local_image_ctx->name, 0);
+
+ // prepare remote image
+ MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
+ expect_send(mock_prepare_remote_image_request, mock_state_builder,
+ "remote mirror uuid", m_remote_image_ctx->id, 0);
+ expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, false);
+ expect_is_linked(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
// prepare replay
expect_prepare_replay(mock_state_builder, false, false, 0);
- expect_is_disconnected(mock_state_builder, false);
+ expect_is_disconnected(mock_state_builder, true);
// close remote image
expect_replay_requires_remote_image(mock_state_builder, false);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
expect_send(mock_prepare_remote_image_request, mock_state_builder,
"remote mirror uuid", m_remote_image_ctx->id, 0);
expect_is_local_primary(mock_state_builder, false);
+ expect_is_remote_primary(mock_state_builder, true);
// open the remote image
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);