Skip to content

Commit

Permalink
rbd-mirror: support bootstrap canceling
Browse files Browse the repository at this point in the history
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
  • Loading branch information
Mykola Golub committed Jun 5, 2016
1 parent f581dbc commit 21f895f
Show file tree
Hide file tree
Showing 17 changed files with 495 additions and 96 deletions.
Expand Up @@ -58,7 +58,14 @@ struct ImageSync<librbd::MockTestImageCtx> {
s_instance = this;
}

MOCK_METHOD0(start, void());
void put() {
}

void get() {
}

MOCK_METHOD0(send, void());
MOCK_METHOD0(cancel, void());
};

ImageSync<librbd::MockTestImageCtx>* ImageSync<librbd::MockTestImageCtx>::s_instance = nullptr;
Expand Down
35 changes: 33 additions & 2 deletions src/test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc
Expand Up @@ -77,6 +77,7 @@ using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::WithArg;
using ::testing::InvokeWithoutArgs;

class TestMockImageSyncImageCopyRequest : public TestMockFixture {
public:
Expand Down Expand Up @@ -379,7 +380,6 @@ TEST_F(TestMockImageSyncImageCopyRequest, Cancel) {
expect_get_object_count(mock_remote_image_ctx, 2);
expect_update_client(mock_journaler, 0);
expect_object_copy_send(mock_object_copy_request);
expect_update_client(mock_journaler, 0);

C_SaferCond ctx;
MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
Expand All @@ -393,7 +393,38 @@ TEST_F(TestMockImageSyncImageCopyRequest, Cancel) {
request->cancel();

ASSERT_TRUE(complete_object_copy(mock_object_copy_request, 0, 0));
ASSERT_EQ(0, ctx.wait());
ASSERT_EQ(-ECANCELED, ctx.wait());
}

TEST_F(TestMockImageSyncImageCopyRequest, Cancel1) {
ASSERT_EQ(0, create_snap("snap1"));
m_client_meta.sync_points = {{"snap1", boost::none}};

librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
journal::MockJournaler mock_journaler;
MockObjectCopyRequest mock_object_copy_request;

C_SaferCond ctx;
MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
mock_local_image_ctx,
mock_journaler,
m_client_meta.sync_points.front(),
&ctx);

expect_get_snap_id(mock_remote_image_ctx);

InSequence seq;
expect_get_object_count(mock_remote_image_ctx, 1);
expect_get_object_count(mock_remote_image_ctx, 0);
EXPECT_CALL(mock_journaler, update_client(_, _))
.WillOnce(DoAll(InvokeWithoutArgs([request]() {
request->cancel();
}),
WithArg<1>(CompleteContext(0))));

request->send();
ASSERT_EQ(-ECANCELED, ctx.wait());
}

TEST_F(TestMockImageSyncImageCopyRequest, MissingSnap) {
Expand Down
110 changes: 110 additions & 0 deletions src/test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc
Expand Up @@ -234,6 +234,26 @@ TEST_F(TestMockImageSyncSnapshotCopyRequest, UpdateClientError) {
ASSERT_EQ(-EINVAL, ctx.wait());
}

TEST_F(TestMockImageSyncSnapshotCopyRequest, UpdateClientCancel) {
librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
journal::MockJournaler mock_journaler;

C_SaferCond ctx;
MockSnapshotCopyRequest *request = create_request(mock_remote_image_ctx,
mock_local_image_ctx,
mock_journaler, &ctx);
InSequence seq;
EXPECT_CALL(mock_journaler, update_client(_, _))
.WillOnce(DoAll(InvokeWithoutArgs([request]() {
request->cancel();
}),
WithArg<1>(CompleteContext(0))));

request->send();
ASSERT_EQ(-ECANCELED, ctx.wait());
}

TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapCreate) {
ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap1"));
ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap2"));
Expand Down Expand Up @@ -283,6 +303,31 @@ TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapCreateError) {
ASSERT_EQ(-EINVAL, ctx.wait());
}

TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapCreateCancel) {
ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap1"));

librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
MockSnapshotCreateRequest mock_snapshot_create_request;
journal::MockJournaler mock_journaler;

C_SaferCond ctx;
MockSnapshotCopyRequest *request = create_request(mock_remote_image_ctx,
mock_local_image_ctx,
mock_journaler, &ctx);
InSequence seq;
EXPECT_CALL(mock_snapshot_create_request, send())
.WillOnce(DoAll(InvokeWithoutArgs([request]() {
request->cancel();
}),
Invoke([this, &mock_snapshot_create_request]() {
m_threads->work_queue->queue(mock_snapshot_create_request.on_finish, 0);
})));

request->send();
ASSERT_EQ(-ECANCELED, ctx.wait());
}

TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapRemoveAndCreate) {
ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap1"));
ASSERT_EQ(0, create_snap(m_local_image_ctx, "snap1"));
Expand Down Expand Up @@ -388,6 +433,38 @@ TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapUnprotectError) {
ASSERT_EQ(-EBUSY, ctx.wait());
}

TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapUnprotectCancel) {
ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap1", true));
ASSERT_EQ(0, create_snap(m_local_image_ctx, "snap1", true));

uint64_t remote_snap_id1 = m_remote_image_ctx->snap_ids["snap1"];
uint64_t local_snap_id1 = m_local_image_ctx->snap_ids["snap1"];
m_client_meta.snap_seqs[remote_snap_id1] = local_snap_id1;

librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
journal::MockJournaler mock_journaler;

C_SaferCond ctx;
MockSnapshotCopyRequest *request = create_request(mock_remote_image_ctx,
mock_local_image_ctx,
mock_journaler, &ctx);
InSequence seq;
expect_snap_is_unprotected(mock_local_image_ctx, local_snap_id1, false, 0);
expect_snap_is_unprotected(mock_remote_image_ctx, remote_snap_id1, true, 0);
EXPECT_CALL(*mock_local_image_ctx.operations,
execute_snap_unprotect(StrEq("snap1"), _))
.WillOnce(DoAll(InvokeWithoutArgs([request]() {
request->cancel();
}),
WithArg<1>(Invoke([this](Context *ctx) {
m_threads->work_queue->queue(ctx, 0);
}))));

request->send();
ASSERT_EQ(-ECANCELED, ctx.wait());
}

TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapUnprotectRemove) {
ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap1", true));
ASSERT_EQ(0, create_snap(m_local_image_ctx, "snap1", true));
Expand Down Expand Up @@ -503,6 +580,39 @@ TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapProtectError) {
ASSERT_EQ(-EINVAL, ctx.wait());
}

TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapProtectCancel) {
ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap1", true));
ASSERT_EQ(0, create_snap(m_local_image_ctx, "snap1", true));

uint64_t remote_snap_id1 = m_remote_image_ctx->snap_ids["snap1"];
uint64_t local_snap_id1 = m_local_image_ctx->snap_ids["snap1"];
m_client_meta.snap_seqs[remote_snap_id1] = local_snap_id1;

librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
journal::MockJournaler mock_journaler;

C_SaferCond ctx;
MockSnapshotCopyRequest *request = create_request(mock_remote_image_ctx,
mock_local_image_ctx,
mock_journaler, &ctx);
InSequence seq;
expect_snap_is_unprotected(mock_local_image_ctx, local_snap_id1, true, 0);
expect_snap_is_protected(mock_remote_image_ctx, remote_snap_id1, true, 0);
expect_snap_is_protected(mock_local_image_ctx, local_snap_id1, false, 0);
EXPECT_CALL(*mock_local_image_ctx.operations,
execute_snap_protect(StrEq("snap1"), _))
.WillOnce(DoAll(InvokeWithoutArgs([request]() {
request->cancel();
}),
WithArg<1>(Invoke([this](Context *ctx) {
m_threads->work_queue->queue(ctx, 0);
}))));

request->send();
ASSERT_EQ(-ECANCELED, ctx.wait());
}

} // namespace image_sync
} // namespace mirror
} // namespace rbd
6 changes: 3 additions & 3 deletions src/test/rbd_mirror/test_ImageSync.cc
Expand Up @@ -100,7 +100,7 @@ class TestImageSync : public TestFixture {
TEST_F(TestImageSync, Empty) {
C_SaferCond ctx;
ImageSync<> *request = create_request(&ctx);
request->start();
request->send();
ASSERT_EQ(0, ctx.wait());

ASSERT_EQ(0U, m_client_meta.sync_points.size());
Expand All @@ -115,7 +115,7 @@ TEST_F(TestImageSync, Simple) {

C_SaferCond ctx;
ImageSync<> *request = create_request(&ctx);
request->start();
request->send();
ASSERT_EQ(0, ctx.wait());

int64_t object_size = std::min<int64_t>(
Expand Down Expand Up @@ -159,7 +159,7 @@ TEST_F(TestImageSync, SnapshotStress) {

C_SaferCond ctx;
ImageSync<> *request = create_request(&ctx);
request->start();
request->send();
ASSERT_EQ(0, ctx.wait());

int64_t object_size = std::min<int64_t>(
Expand Down
7 changes: 7 additions & 0 deletions src/test/rbd_mirror/test_mock_ImageReplayer.cc
Expand Up @@ -80,7 +80,14 @@ struct BootstrapRequest<librbd::MockTestImageCtx> {
s_instance = this;
}

void put() {
}

void get() {
}

MOCK_METHOD0(send, void());
MOCK_METHOD0(cancel, void());
};

template<>
Expand Down
87 changes: 84 additions & 3 deletions src/test/rbd_mirror/test_mock_ImageSync.cc
Expand Up @@ -58,6 +58,13 @@ class ImageCopyRequest<librbd::MockImageCtx> {
ImageCopyRequest() {
s_instance = this;
}

void put() {
}

void get() {
}

MOCK_METHOD0(cancel, void());
MOCK_METHOD0(send, void());
};
Expand All @@ -83,7 +90,15 @@ class SnapshotCopyRequest<librbd::MockImageCtx> {
SnapshotCopyRequest() {
s_instance = this;
}

void put() {
}

void get() {
}

MOCK_METHOD0(send, void());
MOCK_METHOD0(cancel, void());
};

template <>
Expand Down Expand Up @@ -144,6 +159,7 @@ using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::WithArg;
using ::testing::InvokeWithoutArgs;

class TestMockImageSync : public TestMockFixture {
public:
Expand Down Expand Up @@ -273,7 +289,7 @@ TEST_F(TestMockImageSync, SimpleSync) {
MockImageSync *request = create_request(mock_remote_image_ctx,
mock_local_image_ctx,
mock_journaler, &ctx);
request->start();
request->send();
ASSERT_EQ(0, ctx.wait());
}

Expand Down Expand Up @@ -308,7 +324,7 @@ TEST_F(TestMockImageSync, RestartSync) {
MockImageSync *request = create_request(mock_remote_image_ctx,
mock_local_image_ctx,
mock_journaler, &ctx);
request->start();
request->send();
ASSERT_EQ(0, ctx.wait());
}

Expand Down Expand Up @@ -337,15 +353,80 @@ TEST_F(TestMockImageSync, CancelImageCopy) {
MockImageSync *request = create_request(mock_remote_image_ctx,
mock_local_image_ctx,
mock_journaler, &ctx);
request->start();
request->get();
request->send();

// cancel the image copy once it starts
ASSERT_EQ(0, image_copy_ctx.wait());
request->cancel();
request->put();
m_threads->work_queue->queue(mock_image_copy_request.on_finish, 0);

ASSERT_EQ(-ECANCELED, ctx.wait());
}

TEST_F(TestMockImageSync, CancelAfterCopySnapshots) {
librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
journal::MockJournaler mock_journaler;
MockSnapshotCopyRequest mock_snapshot_copy_request;
MockSyncPointCreateRequest mock_sync_point_create_request;

librbd::MockObjectMap *mock_object_map = new librbd::MockObjectMap();
mock_local_image_ctx.object_map = mock_object_map;
expect_test_features(mock_local_image_ctx);

C_SaferCond ctx;
MockImageSync *request = create_request(mock_remote_image_ctx,
mock_local_image_ctx,
mock_journaler, &ctx);
InSequence seq;
expect_create_sync_point(mock_local_image_ctx, mock_sync_point_create_request, 0);
EXPECT_CALL(mock_snapshot_copy_request, send())
.WillOnce((DoAll(InvokeWithoutArgs([request]() {
request->cancel();
}),
Invoke([this, &mock_snapshot_copy_request]() {
m_threads->work_queue->queue(mock_snapshot_copy_request.on_finish, 0);
}))));
EXPECT_CALL(mock_snapshot_copy_request, cancel());

request->send();
ASSERT_EQ(-ECANCELED, ctx.wait());
}

TEST_F(TestMockImageSync, CancelAfterCopyImage) {
librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
journal::MockJournaler mock_journaler;
MockImageCopyRequest mock_image_copy_request;
MockSnapshotCopyRequest mock_snapshot_copy_request;
MockSyncPointCreateRequest mock_sync_point_create_request;
MockSyncPointPruneRequest mock_sync_point_prune_request;

librbd::MockObjectMap *mock_object_map = new librbd::MockObjectMap();
mock_local_image_ctx.object_map = mock_object_map;
expect_test_features(mock_local_image_ctx);

C_SaferCond ctx;
MockImageSync *request = create_request(mock_remote_image_ctx,
mock_local_image_ctx,
mock_journaler, &ctx);
InSequence seq;
expect_create_sync_point(mock_local_image_ctx, mock_sync_point_create_request, 0);
expect_copy_snapshots(mock_snapshot_copy_request, 0);
EXPECT_CALL(mock_image_copy_request, send())
.WillOnce((DoAll(InvokeWithoutArgs([request]() {
request->cancel();
}),
Invoke([this, &mock_image_copy_request]() {
m_threads->work_queue->queue(mock_image_copy_request.on_finish, 0);
}))));
EXPECT_CALL(mock_image_copy_request, cancel());

request->send();
ASSERT_EQ(-ECANCELED, ctx.wait());
}

} // namespace mirror
} // namespace rbd
1 change: 1 addition & 0 deletions src/tools/Makefile-client.am
Expand Up @@ -112,6 +112,7 @@ librbd_mirror_internal_la_SOURCES = \
tools/rbd_mirror/image_sync/SyncPointPruneRequest.cc
noinst_LTLIBRARIES += librbd_mirror_internal.la
noinst_HEADERS += \
tools/rbd_mirror/BaseRequest.h \
tools/rbd_mirror/ClusterWatcher.h \
tools/rbd_mirror/ImageReplayer.h \
tools/rbd_mirror/ImageSync.h \
Expand Down

0 comments on commit 21f895f

Please sign in to comment.