};
} // namespace journal
+
+namespace util {
+
+static std::string s_image_id;
+
+template <>
+std::string generate_image_id<MockTestImageCtx>(librados::IoCtx&) {
+ assert(!s_image_id.empty());
+ return s_image_id;
+}
+
+} // namespace util
} // namespace librbd
namespace rbd {
template<>
struct CreateImageRequest<librbd::MockTestImageCtx> {
static CreateImageRequest* s_instance;
- std::string *local_image_id = nullptr;
Context *on_finish = nullptr;
static CreateImageRequest* create(librados::IoCtx &local_io_ctx,
const std::string &global_image_id,
const std::string &remote_mirror_uuid,
const std::string &local_image_name,
+ const std::string &local_image_id,
librbd::MockTestImageCtx *remote_image_ctx,
- std::string *local_image_id,
Context *on_finish) {
assert(s_instance != nullptr);
- s_instance->local_image_id = local_image_id;
s_instance->on_finish = on_finish;
+ s_instance->construct(local_image_id);
return s_instance;
}
s_instance = nullptr;
}
+ MOCK_METHOD1(construct, void(const std::string&));
MOCK_METHOD0(send, void());
};
})));
}
+ void expect_journaler_unregister_client(::journal::MockJournaler &mock_journaler,
+ int r) {
+ EXPECT_CALL(mock_journaler, unregister_client(_))
+ .WillOnce(Invoke([this, r](Context *on_finish) {
+ m_threads->work_queue->queue(on_finish, r);
+ }));
+ }
+
void expect_journaler_update_client(::journal::MockJournaler &mock_journaler,
const librbd::journal::ClientData &client_data,
int r) {
void expect_create_image(MockCreateImageRequest &mock_create_image_request,
const std::string &image_id, int r) {
+ EXPECT_CALL(mock_create_image_request, construct(image_id));
EXPECT_CALL(mock_create_image_request, send())
- .WillOnce(Invoke([this, &mock_create_image_request, image_id, r]() {
- *mock_create_image_request.local_image_id = image_id;
+ .WillOnce(Invoke([this, &mock_create_image_request, r]() {
m_threads->work_queue->queue(mock_create_image_request.on_finish, r);
}));
}
librbd::Journal<>::IMAGE_CLIENT_ID,
client, 0);
+ // open the remote image
+ librbd::MockJournal mock_journal;
+ 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);
+
// lookup local peer in remote journal
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
expect_journaler_get_client(mock_journaler, "local mirror uuid",
client, 0);
- // open the remote image
- librbd::MockJournal mock_journal;
- 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);
+ // test if remote image is primary
MockIsPrimaryRequest mock_is_primary_request;
expect_is_primary(mock_is_primary_request, false, 0);
librbd::Journal<>::IMAGE_CLIENT_ID,
client, 0);
+ // open the remote image
+ librbd::MockJournal mock_journal;
+ 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);
+
// lookup local peer in remote journal
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
expect_journaler_get_client(mock_journaler, "local mirror uuid",
client, 0);
- // open the remote image
- librbd::MockJournal mock_journal;
- 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);
+ // test if remote image is primary
MockIsPrimaryRequest mock_is_primary_request;
expect_is_primary(mock_is_primary_request, true, 0);
librbd::Journal<>::IMAGE_CLIENT_ID,
client, 0);
+ // open the remote image
+ librbd::MockJournal mock_journal;
+ 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);
+
// lookup local peer in remote journal
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
expect_journaler_get_client(mock_journaler, "local mirror uuid",
client, 0);
- // open the remote image
- librbd::MockJournal mock_journal;
- 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);
+ // test if remote image is primary
MockIsPrimaryRequest mock_is_primary_request;
expect_is_primary(mock_is_primary_request, true, 0);
librbd::Journal<>::IMAGE_CLIENT_ID,
client, 0);
+ // open the remote image
+ librbd::MockJournal mock_journal;
+ 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);
+
// lookup local peer in remote journal
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
expect_journaler_get_client(mock_journaler, "local mirror uuid",
client, 0);
- // open the remote image
- librbd::MockJournal mock_journal;
- 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);
+ // test if remote image is primary
MockIsPrimaryRequest mock_is_primary_request;
expect_is_primary(mock_is_primary_request, true, 0);
librbd::Journal<>::IMAGE_CLIENT_ID,
client, 0);
+ // open the remote image
+ librbd::MockJournal mock_journal;
+ 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);
+
// lookup local peer in remote journal
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
expect_journaler_get_client(mock_journaler, "local mirror uuid",
client, 0);
- // open the remote image
- librbd::MockJournal mock_journal;
- 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);
+ // test if remote image is primary
MockIsPrimaryRequest mock_is_primary_request;
expect_is_primary(mock_is_primary_request, true, 0);
librbd::Journal<>::IMAGE_CLIENT_ID,
client, 0);
+ // open the remote image
+ librbd::MockJournal mock_journal;
+ 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);
+
// lookup local peer in remote journal
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
expect_journaler_get_client(mock_journaler, "local mirror uuid",
client, 0);
- // open the remote image
- librbd::MockJournal mock_journal;
- 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);
+ // test if remote image is primary
MockIsPrimaryRequest mock_is_primary_request;
expect_is_primary(mock_is_primary_request, true, 0);
librbd::Journal<>::IMAGE_CLIENT_ID,
client, 0);
+ // open the remote image
+ librbd::MockJournal mock_journal;
+ 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);
+
// lookup local peer in remote journal
client = {};
expect_journaler_get_client(mock_journaler, "local mirror uuid",
client_data.client_meta = mirror_peer_client_meta;
expect_journaler_register_client(mock_journaler, client_data, 0);
- // open the remote image
- librbd::MockJournal mock_journal;
- 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);
+ // test if remote image is primary
MockIsPrimaryRequest mock_is_primary_request;
expect_is_primary(mock_is_primary_request, true, 0);
- // create the local image
+ // update client state back to syncing
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
mock_local_image_ctx.journal = &mock_journal;
+ librbd::util::s_image_id = mock_local_image_ctx.id;
+ mirror_peer_client_meta = {mock_local_image_ctx.id};
+ mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING;
+ client_data.client_meta = mirror_peer_client_meta;
+ client.data.clear();
+ ::encode(client_data, client.data);
+ expect_journaler_update_client(mock_journaler, client_data, 0);
+
+ // create the local image
MockCreateImageRequest mock_create_image_request;
expect_create_image(mock_create_image_request, mock_local_image_ctx.id, 0);
mock_local_image_ctx.id, &mock_local_image_ctx, 0);
expect_is_resync_requested(mock_journal, false, 0);
- // update client state back to syncing
- mirror_peer_client_meta = {mock_local_image_ctx.id};
- mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING;
- client_data.client_meta = mirror_peer_client_meta;
- client.data.clear();
- ::encode(client_data, client.data);
- expect_journaler_update_client(mock_journaler, client_data, 0);
-
// sync the remote image to the local image
MockImageSync mock_image_sync;
expect_image_sync(mock_image_sync, 0);
librbd::Journal<>::IMAGE_CLIENT_ID,
client, 0);
+ // open the remote image
+ librbd::MockJournal mock_journal;
+ 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);
+
// lookup local peer in remote journal
librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
"missing image id"};
expect_journaler_get_client(mock_journaler, "local mirror uuid",
client, 0);
- // open the remote image
- librbd::MockJournal mock_journal;
- 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);
+ // test if remote image is primary
MockIsPrimaryRequest mock_is_primary_request;
expect_is_primary(mock_is_primary_request, true, 0);
expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
"missing image id", nullptr, -ENOENT);
- // create the missing local image
+ // re-register the client
+ expect_journaler_unregister_client(mock_journaler, 0);
+ mirror_peer_client_meta = {};
+ client_data.client_meta = mirror_peer_client_meta;
+ expect_journaler_register_client(mock_journaler, client_data, 0);
+
+ // test if remote image is primary
+ expect_is_primary(mock_is_primary_request, true, 0);
+
+ // update client state back to syncing
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
mock_local_image_ctx.journal = &mock_journal;
+ librbd::util::s_image_id = mock_local_image_ctx.id;
+ mirror_peer_client_meta = {mock_local_image_ctx.id};
+ mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING;
+ client_data.client_meta = mirror_peer_client_meta;
+ client.data.clear();
+ ::encode(client_data, client.data);
+ expect_journaler_update_client(mock_journaler, client_data, 0);
+
+ // create the missing local image
MockCreateImageRequest mock_create_image_request;
expect_create_image(mock_create_image_request, mock_local_image_ctx.id, 0);
mock_local_image_ctx.id, &mock_local_image_ctx, 0);
expect_is_resync_requested(mock_journal, false, 0);
- // update client state back to syncing
- mirror_peer_client_meta = {mock_local_image_ctx.id};
- mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING;
- client_data.client_meta = mirror_peer_client_meta;
- client.data.clear();
- ::encode(client_data, client.data);
- expect_journaler_update_client(mock_journaler, client_data, 0);
-
// sync the remote image to the local image
MockImageSync mock_image_sync;
expect_image_sync(mock_image_sync, 0);