Skip to content

Commit

Permalink
Merge pull request #9612 from dillaman/wip-16208
Browse files Browse the repository at this point in the history
jewel: rbd-mirror: support bootstrap canceling

Reviewed-by: Jason Dillaman <dillaman@redhat.com>
  • Loading branch information
Jason Dillaman committed Jun 10, 2016
2 parents 966186f + 03466f0 commit ac1b354
Show file tree
Hide file tree
Showing 18 changed files with 513 additions and 112 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
13 changes: 5 additions & 8 deletions src/test/rbd_mirror/test_ImageReplayer.cc
Expand Up @@ -395,20 +395,17 @@ TEST_F(TestImageReplayer, StartInterrupted)
m_replayer->stop(&stop_cond);
int r = start_cond.wait();
printf("start returned %d\n", r);
// TODO: improve the test to avoid this race // TODO: improve the test to avoid this race
ASSERT_TRUE(r == -EINTR || r == 0);
// TODO: improve the test to avoid this race
ASSERT_TRUE(r == -ECANCELED || r == 0);
ASSERT_EQ(0, stop_cond.wait());
}

TEST_F(TestImageReplayer, ErrorJournalReset)
TEST_F(TestImageReplayer, JournalReset)
{
bootstrap();

ASSERT_EQ(0, librbd::Journal<>::reset(m_remote_ioctx, m_remote_image_id));

C_SaferCond cond;
m_replayer->start(&cond);
ASSERT_EQ(-EEXIST, cond.wait());
// try to recover
bootstrap();
}

TEST_F(TestImageReplayer, ErrorNoJournal)
Expand Down
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

0 comments on commit ac1b354

Please sign in to comment.