#include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h"
#include "tools/rbd_mirror/image_replayer/StateBuilder.h"
#include "tools/rbd_mirror/image_replayer/journal/StateBuilder.h"
+#include "tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h"
#include "test/journal/mock/MockJournaler.h"
#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
#include "test/librbd/mock/MockImageCtx.h"
: public image_replayer::StateBuilder<librbd::MockTestImageCtx> {
static StateBuilder* s_instance;
+ cls::rbd::MirrorImageMode mirror_image_mode =
+ cls::rbd::MIRROR_IMAGE_MODE_JOURNAL;
+
::journal::MockJournalerProxy* remote_journaler = nullptr;
cls::journal::ClientState remote_client_state;
librbd::journal::MirrorPeerClientMeta remote_client_meta;
StateBuilder<librbd::MockTestImageCtx>* StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
} // namespace journal
+
+namespace snapshot {
+
+template<>
+struct StateBuilder<librbd::MockTestImageCtx>
+ : public image_replayer::StateBuilder<librbd::MockTestImageCtx> {
+ static StateBuilder* s_instance;
+
+ cls::rbd::MirrorImageMode mirror_image_mode =
+ cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT;
+
+ std::string remote_mirror_peer_uuid;
+
+ static StateBuilder* create(const std::string&) {
+ ceph_assert(s_instance != nullptr);
+ return s_instance;
+ }
+
+ StateBuilder() {
+ s_instance = this;
+ }
+};
+
+StateBuilder<librbd::MockTestImageCtx>* StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
+
+} // namespace snapshot
} // namespace image_replayer
} // namespace mirror
} // namespace rbd
typedef GetMirrorImageIdRequest<librbd::MockTestImageCtx> MockGetMirrorImageIdRequest;
typedef StateBuilder<librbd::MockTestImageCtx> MockStateBuilder;
typedef journal::StateBuilder<librbd::MockTestImageCtx> MockJournalStateBuilder;
+ typedef snapshot::StateBuilder<librbd::MockTestImageCtx> MockSnapshotStateBuilder;
typedef librbd::mirror::GetInfoRequest<librbd::MockTestImageCtx> MockGetMirrorInfoRequest;
void expect_get_mirror_image_mode(MockStateBuilder& mock_state_builder,
}
};
-TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, Success) {
+TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessJournal) {
::journal::MockJournaler mock_remote_journaler;
MockThreads mock_threads(m_threads);
ASSERT_EQ(0, ctx.wait());
ASSERT_TRUE(mock_state_builder != nullptr);
+ ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
+ mock_journal_state_builder.mirror_image_mode);
+ ASSERT_EQ(std::string("remote mirror uuid"),
+ mock_journal_state_builder.remote_mirror_uuid);
ASSERT_EQ(std::string("remote image id"),
mock_journal_state_builder.remote_image_id);
ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY,
mock_journal_state_builder.remote_client_state);
}
+TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessSnapshot) {
+ ::journal::MockJournaler mock_remote_journaler;
+ MockThreads mock_threads(m_threads);
+
+ InSequence seq;
+ MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
+ expect_get_mirror_image_id(mock_get_mirror_image_id_request,
+ "remote image id", 0);
+
+ MockGetMirrorInfoRequest mock_get_mirror_info_request;
+ expect_get_mirror_info(mock_get_mirror_info_request,
+ {cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
+ "global image id",
+ cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
+ librbd::mirror::PROMOTION_STATE_PRIMARY,
+ "remote mirror uuid", 0);
+
+ MockSnapshotStateBuilder mock_snapshot_state_builder;
+ MockStateBuilder* mock_state_builder = nullptr;
+ C_SaferCond ctx;
+ auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
+ m_local_io_ctx,
+ m_remote_io_ctx,
+ "global image id",
+ "local mirror uuid",
+ {"remote mirror uuid",
+ "remote mirror peer uuid"},
+ nullptr,
+ &mock_state_builder,
+ &ctx);
+ req->send();
+
+ ASSERT_EQ(0, ctx.wait());
+ ASSERT_TRUE(mock_state_builder != nullptr);
+ ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
+ mock_snapshot_state_builder.mirror_image_mode);
+ ASSERT_EQ(std::string("remote mirror uuid"),
+ mock_snapshot_state_builder.remote_mirror_uuid);
+ ASSERT_EQ(std::string("remote mirror peer uuid"),
+ mock_snapshot_state_builder.remote_mirror_peer_uuid);
+ ASSERT_EQ(std::string("remote image id"),
+ mock_snapshot_state_builder.remote_image_id);
+ ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY,
+ mock_snapshot_state_builder.remote_promotion_state);
+}
+
TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessNotRegistered) {
::journal::MockJournaler mock_remote_journaler;
MockThreads mock_threads(m_threads);
#include "tools/rbd_mirror/image_replayer/GetMirrorImageIdRequest.h"
#include "tools/rbd_mirror/image_replayer/Utils.h"
#include "tools/rbd_mirror/image_replayer/journal/StateBuilder.h"
+#include "tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h"
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_rbd_mirror
get_client();
break;
case cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT:
- // TODO
+ finalize_snapshot_state_builder();
+ finish(0);
+ break;
default:
derr << "unsupported mirror image mode " << m_mirror_image.mode << " "
<< "for image " << m_global_image_id << dendl;
state_builder->remote_client_meta = client_meta;
}
+template <typename I>
+void PrepareRemoteImageRequest<I>::finalize_snapshot_state_builder() {
+ snapshot::StateBuilder<I>* state_builder = nullptr;
+ if (*m_state_builder != nullptr) {
+ // already verified that it's a matching builder in
+ // 'handle_get_mirror_info'
+ state_builder = dynamic_cast<snapshot::StateBuilder<I>*>(*m_state_builder);
+ ceph_assert(state_builder != nullptr);
+ } else {
+ state_builder = snapshot::StateBuilder<I>::create(m_global_image_id);
+ *m_state_builder = state_builder;
+ }
+
+ state_builder->remote_mirror_uuid = m_remote_pool_meta.mirror_uuid;
+ state_builder->remote_mirror_peer_uuid = m_remote_pool_meta.mirror_peer_uuid;
+ state_builder->remote_image_id = m_remote_image_id;
+ state_builder->remote_promotion_state = m_promotion_state;
+}
+
template <typename I>
void PrepareRemoteImageRequest<I>::finish(int r) {
dout(10) << "r=" << r << dendl;