From: Jason Dillaman Date: Fri, 26 Feb 2016 17:33:32 +0000 (-0500) Subject: tests: updated test cases for librbd journal tag allocation X-Git-Tag: v10.1.0~187^2~3 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=b71037400190d2dd87e5d243813c4a45646803c8;p=ceph-ci.git tests: updated test cases for librbd journal tag allocation Signed-off-by: Jason Dillaman --- diff --git a/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc b/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc index 60b4c5a5e6a..363a022c0d1 100644 --- a/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc +++ b/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc @@ -80,6 +80,22 @@ public: .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)); } + void expect_close_journal(MockImageCtx &mock_image_ctx, + MockJournal &mock_journal) { + EXPECT_CALL(mock_journal, close(_)) + .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue)); + } + + void expect_is_journal_tag_owner(MockJournal &mock_journal, bool owner) { + EXPECT_CALL(mock_journal, is_tag_owner()).WillOnce(Return(owner)); + } + + void expect_allocate_journal_tag(MockImageCtx &mock_image_ctx, + MockJournal &mock_journal, int r) { + EXPECT_CALL(mock_journal, allocate_tag("", _)) + .WillOnce(WithArg<1>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue))); + } + void expect_get_lock_info(MockImageCtx &mock_image_ctx, int r, const entity_name_t &locker_entity, const std::string &locker_address, @@ -171,6 +187,8 @@ TEST_F(TestMockExclusiveLockAcquireRequest, Success) { expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true); expect_create_journal(mock_image_ctx, &mock_journal); expect_open_journal(mock_image_ctx, mock_journal, 0); + expect_is_journal_tag_owner(mock_journal, true); + expect_allocate_journal_tag(mock_image_ctx, mock_journal, 0); C_SaferCond acquire_ctx; C_SaferCond ctx; @@ -231,6 +249,8 @@ TEST_F(TestMockExclusiveLockAcquireRequest, SuccessObjectMapDisabled) { expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true); expect_create_journal(mock_image_ctx, &mock_journal); expect_open_journal(mock_image_ctx, mock_journal, 0); + expect_is_journal_tag_owner(mock_journal, true); + expect_allocate_journal_tag(mock_image_ctx, mock_journal, 0); C_SaferCond acquire_ctx; C_SaferCond ctx; @@ -264,6 +284,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, JournalError) { expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true); expect_create_journal(mock_image_ctx, mock_journal); expect_open_journal(mock_image_ctx, *mock_journal, -EINVAL); + expect_close_journal(mock_image_ctx, *mock_journal); expect_close_object_map(mock_image_ctx, *mock_object_map); C_SaferCond acquire_ctx; @@ -275,6 +296,77 @@ TEST_F(TestMockExclusiveLockAcquireRequest, JournalError) { ASSERT_EQ(-EINVAL, ctx.wait()); } +TEST_F(TestMockExclusiveLockAcquireRequest, NotJournalTagOwner) { + REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockImageCtx mock_image_ctx(*ictx); + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + expect_flush_notifies(mock_image_ctx); + expect_lock(mock_image_ctx, 0); + + MockObjectMap *mock_object_map = new MockObjectMap(); + expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true); + expect_create_object_map(mock_image_ctx, mock_object_map); + expect_open_object_map(mock_image_ctx, *mock_object_map); + + MockJournal *mock_journal = new MockJournal(); + expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true); + expect_create_journal(mock_image_ctx, mock_journal); + expect_open_journal(mock_image_ctx, *mock_journal, 0); + expect_is_journal_tag_owner(*mock_journal, false); + expect_close_journal(mock_image_ctx, *mock_journal); + expect_close_object_map(mock_image_ctx, *mock_object_map); + + C_SaferCond acquire_ctx; + C_SaferCond ctx; + MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx, + TEST_COOKIE, + &acquire_ctx, &ctx); + req->send(); + ASSERT_EQ(-EPERM, ctx.wait()); +} + +TEST_F(TestMockExclusiveLockAcquireRequest, AllocateJournalTagError) { + REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockImageCtx mock_image_ctx(*ictx); + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + expect_flush_notifies(mock_image_ctx); + expect_lock(mock_image_ctx, 0); + + MockObjectMap *mock_object_map = new MockObjectMap(); + expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true); + expect_create_object_map(mock_image_ctx, mock_object_map); + expect_open_object_map(mock_image_ctx, *mock_object_map); + + MockJournal *mock_journal = new MockJournal(); + expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true); + expect_create_journal(mock_image_ctx, mock_journal); + expect_open_journal(mock_image_ctx, *mock_journal, 0); + expect_is_journal_tag_owner(*mock_journal, true); + expect_allocate_journal_tag(mock_image_ctx, *mock_journal, -ESTALE); + expect_close_journal(mock_image_ctx, *mock_journal); + expect_close_object_map(mock_image_ctx, *mock_object_map); + + C_SaferCond acquire_ctx; + C_SaferCond ctx; + MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx, + TEST_COOKIE, + &acquire_ctx, &ctx); + req->send(); + ASSERT_EQ(-ESTALE, ctx.wait()); +} + TEST_F(TestMockExclusiveLockAcquireRequest, LockBusy) { REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); diff --git a/src/test/librbd/journal/test_Replay.cc b/src/test/librbd/journal/test_Replay.cc index 7e048a04e55..49fd479a250 100644 --- a/src/test/librbd/journal/test_Replay.cc +++ b/src/test/librbd/journal/test_Replay.cc @@ -44,7 +44,8 @@ public: } } - void get_journal_commit_position(librbd::ImageCtx *ictx, int64_t *tid) + void get_journal_commit_position(librbd::ImageCtx *ictx, int64_t *tag, + int64_t *entry) { const std::string client_id = ""; std::string journal_id = ictx->id; @@ -69,19 +70,16 @@ public: break; } } - if (c == registered_clients.end()) { - *tid = -1; - return; + if (c == registered_clients.end() || + c->commit_position.object_positions.empty()) { + *tag = 0; + *entry = -1; + } else { + const cls::journal::ObjectPosition &object_position = + *c->commit_position.object_positions.begin(); + *tag = object_position.tag_tid; + *entry = object_position.entry_tid; } - cls::journal::ObjectPositions object_positions = - c->commit_position.object_positions; - cls::journal::ObjectPositions::const_iterator p; - for (p = object_positions.begin(); p != object_positions.end(); p++) { - if (p->tag_tid == 0) { - break; - } - } - *tid = p == object_positions.end() ? -1 : p->entry_tid; C_SaferCond open_cond; ictx->journal = new librbd::Journal<>(*ictx); @@ -123,8 +121,9 @@ TEST_F(TestJournalReplay, AioDiscardEvent) { ASSERT_EQ(0, when_acquired_lock(ictx)); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject a discard operation into the journal inject_into_journal(ictx, @@ -142,9 +141,11 @@ TEST_F(TestJournalReplay, AioDiscardEvent) { ASSERT_EQ(std::string(read_payload.size(), '\0'), read_payload); // check the commit position is properly updated - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 1); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 1, current_tag); + ASSERT_EQ(0, current_entry); // replay several envents and check the commit position inject_into_journal(ictx, @@ -153,8 +154,9 @@ TEST_F(TestJournalReplay, AioDiscardEvent) { librbd::journal::AioDiscardEvent(0, payload.size())); ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 3); + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 2, current_tag); + ASSERT_EQ(1, current_entry); // verify lock ordering constraints aio_comp = new librbd::AioCompletion(); @@ -171,8 +173,9 @@ TEST_F(TestJournalReplay, AioWriteEvent) { ASSERT_EQ(0, when_acquired_lock(ictx)); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject a write operation into the journal std::string payload(4096, '1'); @@ -194,9 +197,11 @@ TEST_F(TestJournalReplay, AioWriteEvent) { ASSERT_EQ(payload, read_payload); // check the commit position is properly updated - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 1); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 1, current_tag); + ASSERT_EQ(0, current_entry); // replay several events and check the commit position inject_into_journal(ictx, @@ -205,8 +210,9 @@ TEST_F(TestJournalReplay, AioWriteEvent) { librbd::journal::AioWriteEvent(0, payload.size(), payload_bl)); ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 3); + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 2, current_tag); + ASSERT_EQ(1, current_entry); // verify lock ordering constraints aio_comp = new librbd::AioCompletion(); @@ -225,8 +231,9 @@ TEST_F(TestJournalReplay, AioFlushEvent) { ASSERT_EQ(0, when_acquired_lock(ictx)); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject a flush operation into the journal inject_into_journal(ictx, librbd::journal::AioFlushEvent()); @@ -261,17 +268,20 @@ TEST_F(TestJournalReplay, AioFlushEvent) { ASSERT_EQ(payload, read_payload); // check the commit position is properly updated - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 1); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 1, current_tag); + ASSERT_EQ(0, current_entry); // replay several events and check the commit position inject_into_journal(ictx, librbd::journal::AioFlushEvent()); inject_into_journal(ictx, librbd::journal::AioFlushEvent()); ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 3); + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 2, current_tag); + ASSERT_EQ(1, current_entry); // verify lock ordering constraints aio_comp = new librbd::AioCompletion(); @@ -289,8 +299,9 @@ TEST_F(TestJournalReplay, SnapCreate) { ASSERT_EQ(0, when_acquired_lock(ictx)); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject snapshot ops into journal inject_into_journal(ictx, librbd::journal::SnapCreateEvent(1, "snap")); @@ -300,9 +311,11 @@ TEST_F(TestJournalReplay, SnapCreate) { ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 2); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 1, current_tag); + ASSERT_EQ(1, current_entry); { RWLock::RLocker snap_locker(ictx->snap_lock); @@ -324,8 +337,9 @@ TEST_F(TestJournalReplay, SnapProtect) { ASSERT_EQ(0, ictx->operations->snap_create("snap")); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject snapshot ops into journal inject_into_journal(ictx, librbd::journal::SnapProtectEvent(1, "snap")); @@ -335,9 +349,11 @@ TEST_F(TestJournalReplay, SnapProtect) { ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 2); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag, current_tag); + ASSERT_EQ(initial_entry + 2, current_entry); bool is_protected; ASSERT_EQ(0, librbd::snap_is_protected(ictx, "snap", &is_protected)); @@ -366,8 +382,9 @@ TEST_F(TestJournalReplay, SnapUnprotect) { ASSERT_EQ(0, ictx->operations->snap_protect("snap")); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject snapshot ops into journal inject_into_journal(ictx, librbd::journal::SnapUnprotectEvent(1, "snap")); @@ -377,9 +394,11 @@ TEST_F(TestJournalReplay, SnapUnprotect) { ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 2); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag, current_tag); + ASSERT_EQ(initial_entry + 2, current_entry); bool is_protected; ASSERT_EQ(0, librbd::snap_is_protected(ictx, "snap", &is_protected)); @@ -408,8 +427,9 @@ TEST_F(TestJournalReplay, SnapRename) { } // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject snapshot ops into journal inject_into_journal(ictx, librbd::journal::SnapRenameEvent(1, snap_id, "snap2")); @@ -419,9 +439,11 @@ TEST_F(TestJournalReplay, SnapRename) { ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 2); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag, current_tag); + ASSERT_EQ(initial_entry + 2, current_entry); { RWLock::RLocker snap_locker(ictx->snap_lock); @@ -444,8 +466,9 @@ TEST_F(TestJournalReplay, SnapRollback) { ASSERT_EQ(0, ictx->operations->snap_create("snap")); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject snapshot ops into journal inject_into_journal(ictx, librbd::journal::SnapRollbackEvent(1, "snap")); @@ -455,9 +478,11 @@ TEST_F(TestJournalReplay, SnapRollback) { ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 2); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag, current_tag); + ASSERT_EQ(initial_entry + 2, current_entry); // verify lock ordering constraints librbd::NoOpProgressContext no_op_progress; @@ -475,8 +500,9 @@ TEST_F(TestJournalReplay, SnapRemove) { ASSERT_EQ(0, ictx->operations->snap_create("snap")); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject snapshot ops into journal inject_into_journal(ictx, librbd::journal::SnapRemoveEvent(1, "snap")); @@ -486,9 +512,11 @@ TEST_F(TestJournalReplay, SnapRemove) { ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 2); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag, current_tag); + ASSERT_EQ(initial_entry + 2, current_entry); { RWLock::RLocker snap_locker(ictx->snap_lock); @@ -510,8 +538,9 @@ TEST_F(TestJournalReplay, Rename) { ASSERT_EQ(0, when_acquired_lock(ictx)); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject snapshot ops into journal std::string new_image_name(get_temp_image_name()); @@ -522,9 +551,11 @@ TEST_F(TestJournalReplay, Rename) { ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 2); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 1, current_tag); + ASSERT_EQ(1, current_entry); // verify lock ordering constraints librbd::RBD rbd; @@ -540,8 +571,9 @@ TEST_F(TestJournalReplay, Resize) { ASSERT_EQ(0, when_acquired_lock(ictx)); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); // inject snapshot ops into journal inject_into_journal(ictx, librbd::journal::ResizeEvent(1, 16)); @@ -551,9 +583,11 @@ TEST_F(TestJournalReplay, Resize) { ASSERT_EQ(0, open_image(m_image_name, &ictx)); ASSERT_EQ(0, when_acquired_lock(ictx)); - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 2); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 1, current_tag); + ASSERT_EQ(1, current_entry); // verify lock ordering constraints librbd::NoOpProgressContext no_op_progress; @@ -578,8 +612,9 @@ TEST_F(TestJournalReplay, Flatten) { ASSERT_EQ(0, when_acquired_lock(ictx2)); // get current commit position - int64_t initial; - get_journal_commit_position(ictx2, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx2, &initial_tag, &initial_entry); // inject snapshot ops into journal inject_into_journal(ictx2, librbd::journal::FlattenEvent(1)); @@ -589,9 +624,11 @@ TEST_F(TestJournalReplay, Flatten) { ASSERT_EQ(0, open_image(clone_name, &ictx2)); ASSERT_EQ(0, when_acquired_lock(ictx2)); - int64_t current; - get_journal_commit_position(ictx2, ¤t); - ASSERT_EQ(current, initial + 2); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx2, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 1, current_tag); + ASSERT_EQ(1, current_entry); ASSERT_EQ(0, ictx->operations->snap_unprotect("snap")); // verify lock ordering constraints @@ -607,8 +644,9 @@ TEST_F(TestJournalReplay, ObjectPosition) { ASSERT_EQ(0, when_acquired_lock(ictx)); // get current commit position - int64_t initial; - get_journal_commit_position(ictx, &initial); + int64_t initial_tag; + int64_t initial_entry; + get_journal_commit_position(ictx, &initial_tag, &initial_entry); std::string payload(4096, '1'); librbd::AioCompletion *aio_comp = new librbd::AioCompletion(); @@ -623,9 +661,11 @@ TEST_F(TestJournalReplay, ObjectPosition) { aio_comp->release(); // check the commit position updated - int64_t current; - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 2); + int64_t current_tag; + int64_t current_entry; + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 1, current_tag); + ASSERT_EQ(1, current_entry); // write again @@ -641,6 +681,7 @@ TEST_F(TestJournalReplay, ObjectPosition) { aio_comp->release(); // check the commit position updated - get_journal_commit_position(ictx, ¤t); - ASSERT_EQ(current, initial + 4); + get_journal_commit_position(ictx, ¤t_tag, ¤t_entry); + ASSERT_EQ(initial_tag + 1, current_tag); + ASSERT_EQ(3, current_entry); } diff --git a/src/test/librbd/mock/MockJournal.h b/src/test/librbd/mock/MockJournal.h index 9fe35185060..1393399d555 100644 --- a/src/test/librbd/mock/MockJournal.h +++ b/src/test/librbd/mock/MockJournal.h @@ -16,6 +16,9 @@ struct MockJournal { MOCK_METHOD1(wait_for_journal_ready, void(Context *)); + MOCK_CONST_METHOD0(is_tag_owner, bool()); + MOCK_METHOD2(allocate_tag, void(const std::string &, Context *)); + MOCK_METHOD1(open, void(Context *)); MOCK_METHOD1(close, void(Context *)); diff --git a/src/test/librbd/test_mock_Journal.cc b/src/test/librbd/test_mock_Journal.cc index 5c506199d57..dea29efb0f6 100644 --- a/src/test/librbd/test_mock_Journal.cc +++ b/src/test/librbd/test_mock_Journal.cc @@ -7,6 +7,7 @@ #include "common/Cond.h" #include "common/Mutex.h" #include "cls/journal/cls_journal_types.h" +#include "journal/Journaler.h" #include "librbd/Journal.h" #include "librbd/Utils.h" #include "librbd/journal/Replay.h" @@ -87,6 +88,9 @@ struct MockJournaler { MOCK_METHOD1(init, void(Context*)); MOCK_METHOD1(flush_commit_position, void(Context*)); + MOCK_METHOD2(get_cached_client, int(const std::string&, cls::journal::Client*)); + MOCK_METHOD3(get_tags, void(uint64_t, journal::Journaler::Tags*, Context*)); + MOCK_METHOD1(start_replay, void(::journal::ReplayHandler *replay_handler)); MOCK_METHOD1(try_pop_front, bool(MockReplayEntryProxy *replay_entry)); MOCK_METHOD0(stop_replay, void()); @@ -134,6 +138,16 @@ struct MockJournalerProxy { MockJournaler::get_instance().init(on_finish); } + int get_cached_client(const std::string& client_id, + cls::journal::Client* client) { + return MockJournaler::get_instance().get_cached_client(client_id, client); + } + + void get_tags(uint64_t tag_class, journal::Journaler::Tags *tags, + Context *on_finish) { + MockJournaler::get_instance().get_tags(tag_class, tags, on_finish); + } + void flush_commit_position(Context *on_finish) { MockJournaler::get_instance().flush_commit_position(on_finish); } @@ -308,7 +322,36 @@ public: void expect_init_journaler(::journal::MockJournaler &mock_journaler, int r) { EXPECT_CALL(mock_journaler, init(_)) .WillOnce(CompleteContext(r, NULL)); + } + + void expect_get_journaler_cached_client(::journal::MockJournaler &mock_journaler, int r) { + + journal::ImageClientMeta image_client_meta; + image_client_meta.tag_class = 0; + + journal::ClientData client_data; + client_data.client_meta = image_client_meta; + + cls::journal::Client client; + ::encode(client_data, client.data); + + EXPECT_CALL(mock_journaler, get_cached_client("", _)) + .WillOnce(DoAll(SetArgPointee<1>(client), + Return(r))); + } + + void expect_get_journaler_tags(MockImageCtx &mock_image_ctx, + ::journal::MockJournaler &mock_journaler, + int r) { + journal::TagData tag_data; + + bufferlist tag_data_bl; + ::encode(tag_data, tag_data_bl); + ::journal::Journaler::Tags tags = {{0, 0, {}}, {1, 0, tag_data_bl}}; + EXPECT_CALL(mock_journaler, get_tags(0, _, _)) + .WillOnce(DoAll(SetArgPointee<1>(tags), + WithArg<2>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)))); } void expect_start_replay(MockJournalImageCtx &mock_image_ctx, @@ -442,6 +485,8 @@ public: InSequence seq; expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); expect_start_replay( mock_image_ctx, mock_journaler, { std::bind(&invoke_replay_complete, _1, 0) @@ -485,6 +530,8 @@ TEST_F(TestMockJournal, StateTransitions) { ::journal::MockJournaler mock_journaler; expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); expect_start_replay( mock_image_ctx, mock_journaler, { std::bind(&invoke_replay_ready, _1), @@ -533,6 +580,45 @@ TEST_F(TestMockJournal, InitError) { ASSERT_EQ(-EINVAL, when_open(mock_journal)); } +TEST_F(TestMockJournal, GetCachedClientError) { + REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockImageCtx mock_image_ctx(*ictx); + MockJournal mock_journal(mock_image_ctx); + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + + ::journal::MockJournaler mock_journaler; + expect_construct_journaler(mock_journaler); + expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, -ENOENT); + ASSERT_EQ(-ENOENT, when_open(mock_journal)); +} + +TEST_F(TestMockJournal, GetTagsError) { + REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockImageCtx mock_image_ctx(*ictx); + MockJournal mock_journal(mock_image_ctx); + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + + ::journal::MockJournaler mock_journaler; + expect_construct_journaler(mock_journaler); + expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, -EBADMSG); + ASSERT_EQ(-EBADMSG, when_open(mock_journal)); +} + TEST_F(TestMockJournal, ReplayCompleteError) { REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); @@ -548,6 +634,8 @@ TEST_F(TestMockJournal, ReplayCompleteError) { ::journal::MockJournaler mock_journaler; expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); expect_start_replay( mock_image_ctx, mock_journaler, { std::bind(&invoke_replay_complete, _1, -EINVAL) @@ -560,6 +648,8 @@ TEST_F(TestMockJournal, ReplayCompleteError) { // replay failure should result in replay-restart expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); expect_start_replay( mock_image_ctx, mock_journaler, { std::bind(&invoke_replay_complete, _1, 0) @@ -589,6 +679,8 @@ TEST_F(TestMockJournal, FlushReplayError) { ::journal::MockJournaler mock_journaler; expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); expect_start_replay( mock_image_ctx, mock_journaler, { std::bind(&invoke_replay_ready, _1), @@ -606,6 +698,8 @@ TEST_F(TestMockJournal, FlushReplayError) { // replay flush failure should result in replay-restart expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); expect_start_replay( mock_image_ctx, mock_journaler, { std::bind(&invoke_replay_complete, _1, 0) @@ -635,6 +729,8 @@ TEST_F(TestMockJournal, StopError) { ::journal::MockJournaler mock_journaler; expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); expect_start_replay( mock_image_ctx, mock_journaler, { std::bind(&invoke_replay_complete, _1, 0) @@ -664,6 +760,8 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) { ::journal::MockJournaler mock_journaler; expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); ::journal::ReplayHandler *replay_handler = nullptr; expect_start_replay( @@ -688,6 +786,8 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) { // replay write-to-disk failure should result in replay-restart expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); expect_start_replay( mock_image_ctx, mock_journaler, { std::bind(&invoke_replay_complete, _1, 0) @@ -738,6 +838,8 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) { ::journal::MockJournaler mock_journaler; expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); expect_start_replay( mock_image_ctx, mock_journaler, { std::bind(&invoke_replay_ready, _1), @@ -759,6 +861,8 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) { // replay write-to-disk failure should result in replay-restart expect_construct_journaler(mock_journaler); expect_init_journaler(mock_journaler, 0); + expect_get_journaler_cached_client(mock_journaler, 0); + expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0); expect_start_replay( mock_image_ctx, mock_journaler, { std::bind(&invoke_replay_complete, _1, 0)