mirror of
https://github.com/ceph/ceph
synced 2025-03-05 07:48:55 +00:00
test: unit test cases for disabling librbd journal by policy
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
parent
2e5076eb19
commit
4a256f5044
@ -22,30 +22,32 @@ set_target_properties(rbd_test_mock PROPERTIES COMPILE_FLAGS
|
||||
# unittest_librbd
|
||||
# doesn't use add_ceph_test because it is called by run-rbd-unit-tests.sh
|
||||
set(unittest_librbd_srcs
|
||||
test_ConsistencyGroups.cc
|
||||
test_ConsistencyGroups.cc
|
||||
test_main.cc
|
||||
test_mock_fixture.cc
|
||||
test_mock_ExclusiveLock.cc
|
||||
test_mock_Journal.cc
|
||||
test_mock_ObjectWatcher.cc
|
||||
exclusive_lock/test_mock_AcquireRequest.cc
|
||||
exclusive_lock/test_mock_ReleaseRequest.cc
|
||||
test_mock_fixture.cc
|
||||
test_mock_AioImageRequest.cc
|
||||
test_mock_ExclusiveLock.cc
|
||||
test_mock_Journal.cc
|
||||
test_mock_ObjectWatcher.cc
|
||||
exclusive_lock/test_mock_AcquireRequest.cc
|
||||
exclusive_lock/test_mock_ReleaseRequest.cc
|
||||
image/test_mock_RefreshRequest.cc
|
||||
journal/test_mock_Replay.cc
|
||||
object_map/test_mock_InvalidateRequest.cc
|
||||
object_map/test_mock_LockRequest.cc
|
||||
object_map/test_mock_RefreshRequest.cc
|
||||
object_map/test_mock_ResizeRequest.cc
|
||||
object_map/test_mock_SnapshotCreateRequest.cc
|
||||
object_map/test_mock_SnapshotRemoveRequest.cc
|
||||
object_map/test_mock_SnapshotRollbackRequest.cc
|
||||
object_map/test_mock_UnlockRequest.cc
|
||||
object_map/test_mock_UpdateRequest.cc
|
||||
operation/test_mock_ResizeRequest.cc
|
||||
operation/test_mock_SnapshotCreateRequest.cc
|
||||
operation/test_mock_SnapshotProtectRequest.cc
|
||||
operation/test_mock_SnapshotRemoveRequest.cc
|
||||
operation/test_mock_SnapshotRollbackRequest.cc
|
||||
journal/test_mock_Replay.cc
|
||||
object_map/test_mock_InvalidateRequest.cc
|
||||
object_map/test_mock_LockRequest.cc
|
||||
object_map/test_mock_RefreshRequest.cc
|
||||
object_map/test_mock_ResizeRequest.cc
|
||||
object_map/test_mock_SnapshotCreateRequest.cc
|
||||
object_map/test_mock_SnapshotRemoveRequest.cc
|
||||
object_map/test_mock_SnapshotRollbackRequest.cc
|
||||
object_map/test_mock_UnlockRequest.cc
|
||||
object_map/test_mock_UpdateRequest.cc
|
||||
operation/test_mock_Request.cc
|
||||
operation/test_mock_ResizeRequest.cc
|
||||
operation/test_mock_SnapshotCreateRequest.cc
|
||||
operation/test_mock_SnapshotProtectRequest.cc
|
||||
operation/test_mock_SnapshotRemoveRequest.cc
|
||||
operation/test_mock_SnapshotRollbackRequest.cc
|
||||
operation/test_mock_SnapshotUnprotectRequest.cc
|
||||
)
|
||||
add_executable(unittest_librbd
|
||||
|
@ -54,13 +54,13 @@ struct MockImageCtx {
|
||||
lockers(image_ctx.lockers),
|
||||
exclusive_locked(image_ctx.exclusive_locked),
|
||||
lock_tag(image_ctx.lock_tag),
|
||||
owner_lock("owner_lock"),
|
||||
md_lock("md_lock"),
|
||||
cache_lock("cache_lock"),
|
||||
snap_lock("snap_lock"),
|
||||
parent_lock("parent_lock"),
|
||||
object_map_lock("object_map_lock"),
|
||||
async_ops_lock("async_ops_lock"),
|
||||
owner_lock(image_ctx.owner_lock),
|
||||
md_lock(image_ctx.md_lock),
|
||||
cache_lock(image_ctx.cache_lock),
|
||||
snap_lock(image_ctx.snap_lock),
|
||||
parent_lock(image_ctx.parent_lock),
|
||||
object_map_lock(image_ctx.object_map_lock),
|
||||
async_ops_lock(image_ctx.async_ops_lock),
|
||||
order(image_ctx.order),
|
||||
size(image_ctx.size),
|
||||
features(image_ctx.features),
|
||||
@ -202,13 +202,13 @@ struct MockImageCtx {
|
||||
librados::IoCtx md_ctx;
|
||||
librados::IoCtx data_ctx;
|
||||
|
||||
RWLock owner_lock;
|
||||
RWLock md_lock;
|
||||
Mutex cache_lock;
|
||||
RWLock snap_lock;
|
||||
RWLock parent_lock;
|
||||
RWLock object_map_lock;
|
||||
Mutex async_ops_lock;
|
||||
RWLock &owner_lock;
|
||||
RWLock &md_lock;
|
||||
Mutex &cache_lock;
|
||||
RWLock &snap_lock;
|
||||
RWLock &parent_lock;
|
||||
RWLock &object_map_lock;
|
||||
Mutex &async_ops_lock;
|
||||
|
||||
uint8_t order;
|
||||
uint64_t size;
|
||||
|
176
src/test/librbd/operation/test_mock_Request.cc
Normal file
176
src/test/librbd/operation/test_mock_Request.cc
Normal file
@ -0,0 +1,176 @@
|
||||
// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
||||
// vim: ts=8 sw=2 smarttab
|
||||
|
||||
#include "test/librbd/test_mock_fixture.h"
|
||||
#include "test/librbd/test_support.h"
|
||||
#include "test/librbd/mock/MockImageCtx.h"
|
||||
#include "test/librbd/mock/MockJournal.h"
|
||||
#include "librbd/AsyncRequest.h"
|
||||
#include "librbd/operation/Request.h"
|
||||
|
||||
namespace librbd {
|
||||
namespace {
|
||||
|
||||
struct MockTestImageCtx : public MockImageCtx {
|
||||
MockTestImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
template <>
|
||||
struct AsyncRequest<librbd::MockTestImageCtx> {
|
||||
librbd::MockTestImageCtx &m_image_ctx;
|
||||
Context *m_on_finish;
|
||||
|
||||
AsyncRequest(librbd::MockTestImageCtx &image_ctx, Context *on_finish)
|
||||
: m_image_ctx(image_ctx), m_on_finish(on_finish) {
|
||||
}
|
||||
virtual ~AsyncRequest() {
|
||||
}
|
||||
|
||||
virtual void finish(int r) {
|
||||
m_on_finish->complete(r);
|
||||
}
|
||||
virtual void finish_and_destroy(int r) {
|
||||
finish(r);
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace librbd
|
||||
|
||||
#include "librbd/operation/Request.cc"
|
||||
template class librbd::operation::Request<librbd::MockTestImageCtx>;
|
||||
|
||||
namespace librbd {
|
||||
namespace journal {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Event&) {
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace journal
|
||||
|
||||
namespace operation {
|
||||
|
||||
using ::testing::InSequence;
|
||||
using ::testing::Invoke;
|
||||
using ::testing::Return;
|
||||
|
||||
struct MockRequest : public Request<librbd::MockTestImageCtx> {
|
||||
MockRequest(librbd::MockTestImageCtx &image_ctx, Context *on_finish,
|
||||
uint64_t journal_op_tid)
|
||||
: Request<librbd::MockTestImageCtx>(image_ctx, on_finish, journal_op_tid) {
|
||||
}
|
||||
|
||||
void complete(int r) {
|
||||
finish_and_destroy(r);
|
||||
}
|
||||
|
||||
void send_op_impl(int r) {
|
||||
bool appending = append_op_event<
|
||||
MockRequest, &MockRequest::handle_send>(this);
|
||||
if (!appending) {
|
||||
complete(r);
|
||||
}
|
||||
}
|
||||
MOCK_METHOD1(should_complete, bool(int));
|
||||
MOCK_METHOD0(send_op, void());
|
||||
MOCK_METHOD1(handle_send, Context*(int*));
|
||||
MOCK_CONST_METHOD0(can_affect_io, bool());
|
||||
MOCK_CONST_METHOD1(create_event, journal::Event(uint64_t));
|
||||
};
|
||||
|
||||
struct TestMockOperationRequest : public TestMockFixture {
|
||||
void expect_can_affect_io(MockRequest &mock_request, bool can_affect) {
|
||||
EXPECT_CALL(mock_request, can_affect_io())
|
||||
.WillOnce(Return(can_affect));
|
||||
}
|
||||
|
||||
void expect_is_journal_replaying(MockJournal &mock_journal, bool replaying) {
|
||||
EXPECT_CALL(mock_journal, is_journal_replaying())
|
||||
.WillOnce(Return(replaying));
|
||||
}
|
||||
|
||||
void expect_is_journal_appending(MockJournal &mock_journal, bool appending) {
|
||||
EXPECT_CALL(mock_journal, is_journal_appending())
|
||||
.WillOnce(Return(appending));
|
||||
}
|
||||
|
||||
void expect_send_op(MockRequest &mock_request, int r) {
|
||||
EXPECT_CALL(mock_request, send_op())
|
||||
.WillOnce(Invoke([&mock_request, r]() {
|
||||
mock_request.complete(r);
|
||||
}));
|
||||
}
|
||||
|
||||
void expect_send_op_affects_io(MockImageCtx &mock_image_ctx,
|
||||
MockRequest &mock_request, int r) {
|
||||
EXPECT_CALL(mock_request, send_op())
|
||||
.WillOnce(Invoke([&mock_image_ctx, &mock_request, r]() {
|
||||
mock_image_ctx.image_ctx->op_work_queue->queue(
|
||||
new FunctionContext([&mock_request, r](int _) {
|
||||
mock_request.send_op_impl(r);
|
||||
}), 0);
|
||||
}));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TEST_F(TestMockOperationRequest, SendJournalDisabled) {
|
||||
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
|
||||
|
||||
librbd::ImageCtx *ictx;
|
||||
ASSERT_EQ(0, open_image(m_image_name, &ictx));
|
||||
|
||||
MockTestImageCtx mock_image_ctx(*ictx);
|
||||
MockJournal mock_journal;
|
||||
mock_image_ctx.journal = &mock_journal;
|
||||
|
||||
C_SaferCond ctx;
|
||||
MockRequest *mock_request = new MockRequest(mock_image_ctx, &ctx, 0);
|
||||
|
||||
InSequence seq;
|
||||
expect_can_affect_io(*mock_request, false);
|
||||
expect_is_journal_appending(mock_journal, false);
|
||||
expect_send_op(*mock_request, 0);
|
||||
|
||||
{
|
||||
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
|
||||
mock_request->send();
|
||||
}
|
||||
|
||||
ASSERT_EQ(0, ctx.wait());
|
||||
}
|
||||
|
||||
TEST_F(TestMockOperationRequest, SendAffectsIOJournalDisabled) {
|
||||
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
|
||||
|
||||
librbd::ImageCtx *ictx;
|
||||
ASSERT_EQ(0, open_image(m_image_name, &ictx));
|
||||
|
||||
MockTestImageCtx mock_image_ctx(*ictx);
|
||||
MockJournal mock_journal;
|
||||
mock_image_ctx.journal = &mock_journal;
|
||||
|
||||
C_SaferCond ctx;
|
||||
MockRequest *mock_request = new MockRequest(mock_image_ctx, &ctx, 0);
|
||||
|
||||
InSequence seq;
|
||||
expect_can_affect_io(*mock_request, true);
|
||||
expect_send_op_affects_io(mock_image_ctx, *mock_request, 0);
|
||||
expect_can_affect_io(*mock_request, true);
|
||||
expect_is_journal_replaying(mock_journal, false);
|
||||
expect_is_journal_appending(mock_journal, false);
|
||||
|
||||
{
|
||||
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
|
||||
mock_request->send();
|
||||
}
|
||||
|
||||
ASSERT_EQ(0, ctx.wait());
|
||||
}
|
||||
|
||||
} // namespace operation
|
||||
} // namespace librbd
|
257
src/test/librbd/test_mock_AioImageRequest.cc
Normal file
257
src/test/librbd/test_mock_AioImageRequest.cc
Normal file
@ -0,0 +1,257 @@
|
||||
// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
||||
// vim: ts=8 sw=2 smarttab
|
||||
|
||||
#include "test/librbd/test_mock_fixture.h"
|
||||
#include "test/librbd/test_support.h"
|
||||
#include "test/librbd/mock/MockImageCtx.h"
|
||||
#include "test/librbd/mock/MockJournal.h"
|
||||
#include "librbd/AioImageRequest.h"
|
||||
#include "librbd/AioObjectRequest.h"
|
||||
|
||||
namespace librbd {
|
||||
namespace {
|
||||
|
||||
struct MockTestImageCtx : public MockImageCtx {
|
||||
MockTestImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace util {
|
||||
|
||||
inline ImageCtx *get_image_ctx(MockTestImageCtx *image_ctx) {
|
||||
return image_ctx->image_ctx;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
template <>
|
||||
struct AioObjectRequest<librbd::MockTestImageCtx> : public AioObjectRequestHandle {
|
||||
static AioObjectRequest* s_instance;
|
||||
Context *on_finish = nullptr;
|
||||
|
||||
static AioObjectRequest* create_remove(librbd::MockTestImageCtx *ictx,
|
||||
const std::string &oid,
|
||||
uint64_t object_no,
|
||||
const ::SnapContext &snapc,
|
||||
Context *completion) {
|
||||
assert(s_instance != nullptr);
|
||||
s_instance->on_finish = completion;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
static AioObjectRequest* create_truncate(librbd::MockTestImageCtx *ictx,
|
||||
const std::string &oid,
|
||||
uint64_t object_no,
|
||||
uint64_t object_off,
|
||||
const ::SnapContext &snapc,
|
||||
Context *completion) {
|
||||
assert(s_instance != nullptr);
|
||||
s_instance->on_finish = completion;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
static AioObjectRequest* create_write(librbd::MockTestImageCtx *ictx,
|
||||
const std::string &oid,
|
||||
uint64_t object_no,
|
||||
uint64_t object_off,
|
||||
const ceph::bufferlist &data,
|
||||
const ::SnapContext &snapc,
|
||||
Context *completion, int op_flags) {
|
||||
assert(s_instance != nullptr);
|
||||
s_instance->on_finish = completion;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
static AioObjectRequest* create_zero(librbd::MockTestImageCtx *ictx,
|
||||
const std::string &oid,
|
||||
uint64_t object_no, uint64_t object_off,
|
||||
uint64_t object_len,
|
||||
const ::SnapContext &snapc,
|
||||
Context *completion) {
|
||||
assert(s_instance != nullptr);
|
||||
s_instance->on_finish = completion;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
AioObjectRequest() {
|
||||
assert(s_instance == nullptr);
|
||||
s_instance = this;
|
||||
}
|
||||
~AioObjectRequest() {
|
||||
s_instance = nullptr;
|
||||
}
|
||||
|
||||
MOCK_METHOD1(complete, void(int));
|
||||
MOCK_METHOD0(send, void());
|
||||
};
|
||||
|
||||
template <>
|
||||
struct AioObjectRead<librbd::MockTestImageCtx> : public AioObjectRequest<librbd::MockTestImageCtx> {
|
||||
typedef std::vector<std::pair<uint64_t, uint64_t> > Extents;
|
||||
typedef std::map<uint64_t, uint64_t> ExtentMap;
|
||||
|
||||
static AioObjectRead* s_instance;
|
||||
|
||||
static AioObjectRead* create(librbd::MockTestImageCtx *ictx,
|
||||
const std::string &oid,
|
||||
uint64_t objectno, uint64_t offset,
|
||||
uint64_t len, Extents &buffer_extents,
|
||||
librados::snap_t snap_id, bool sparse,
|
||||
Context *completion, int op_flags) {
|
||||
assert(s_instance != nullptr);
|
||||
s_instance->on_finish = completion;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
AioObjectRead() {
|
||||
assert(s_instance == nullptr);
|
||||
s_instance = this;
|
||||
}
|
||||
~AioObjectRead() {
|
||||
s_instance = nullptr;
|
||||
}
|
||||
|
||||
MOCK_CONST_METHOD0(get_offset, uint64_t());
|
||||
MOCK_CONST_METHOD0(get_length, uint64_t());
|
||||
MOCK_METHOD0(data, ceph::bufferlist &());
|
||||
MOCK_CONST_METHOD0(get_buffer_extents, const Extents &());
|
||||
MOCK_METHOD0(get_extent_map, ExtentMap &());
|
||||
|
||||
};
|
||||
|
||||
AioObjectRequest<librbd::MockTestImageCtx>* AioObjectRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
|
||||
AioObjectRead<librbd::MockTestImageCtx>* AioObjectRead<librbd::MockTestImageCtx>::s_instance = nullptr;
|
||||
|
||||
} // namespace librbd
|
||||
|
||||
#include "librbd/AioImageRequest.cc"
|
||||
template class librbd::AioImageRequest<librbd::MockTestImageCtx>;
|
||||
|
||||
namespace librbd {
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::InSequence;
|
||||
using ::testing::Invoke;
|
||||
using ::testing::Return;
|
||||
using ::testing::WithArg;
|
||||
|
||||
struct TestMockAioImageRequest : public TestMockFixture {
|
||||
typedef AioImageRequest<librbd::MockTestImageCtx> MockAioImageRequest;
|
||||
typedef AioImageWrite<librbd::MockTestImageCtx> MockAioImageWrite;
|
||||
typedef AioImageDiscard<librbd::MockTestImageCtx> MockAioImageDiscard;
|
||||
typedef AioImageFlush<librbd::MockTestImageCtx> MockAioImageFlush;
|
||||
typedef AioObjectRequest<librbd::MockTestImageCtx> MockAioObjectRequest;
|
||||
typedef AioObjectRead<librbd::MockTestImageCtx> MockAioObjectRead;
|
||||
|
||||
void expect_is_journal_appending(MockJournal &mock_journal, bool appending) {
|
||||
EXPECT_CALL(mock_journal, is_journal_appending())
|
||||
.WillOnce(Return(appending));
|
||||
}
|
||||
|
||||
void expect_write_to_cache(MockImageCtx &mock_image_ctx,
|
||||
const object_t &object,
|
||||
uint64_t offset, uint64_t length,
|
||||
uint64_t journal_tid, int r) {
|
||||
EXPECT_CALL(mock_image_ctx, write_to_cache(object, _, length, offset, _, _,
|
||||
journal_tid))
|
||||
.WillOnce(WithArg<4>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)));
|
||||
}
|
||||
|
||||
void expect_object_request_send(MockImageCtx &mock_image_ctx,
|
||||
MockAioObjectRequest &mock_object_request,
|
||||
int r) {
|
||||
EXPECT_CALL(mock_object_request, send())
|
||||
.WillOnce(Invoke([&mock_image_ctx, &mock_object_request, r]() {
|
||||
mock_image_ctx.image_ctx->op_work_queue->queue(
|
||||
mock_object_request.on_finish, r);
|
||||
}));
|
||||
}
|
||||
|
||||
void expect_flush(MockImageCtx &mock_image_ctx, int r) {
|
||||
EXPECT_CALL(mock_image_ctx, flush(_))
|
||||
.WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TestMockAioImageRequest, AioWriteJournalAppendDisabled) {
|
||||
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
|
||||
|
||||
librbd::ImageCtx *ictx;
|
||||
ASSERT_EQ(0, open_image(m_image_name, &ictx));
|
||||
|
||||
MockAioObjectRequest mock_aio_object_request;
|
||||
MockTestImageCtx mock_image_ctx(*ictx);
|
||||
MockJournal mock_journal;
|
||||
mock_image_ctx.journal = &mock_journal;
|
||||
|
||||
InSequence seq;
|
||||
expect_is_journal_appending(mock_journal, false);
|
||||
expect_write_to_cache(mock_image_ctx, ictx->get_object_name(0),
|
||||
0, 1, 0, 0);
|
||||
|
||||
C_SaferCond aio_comp_ctx;
|
||||
AioCompletion *aio_comp = AioCompletion::create_and_start(
|
||||
&aio_comp_ctx, ictx, AIO_TYPE_WRITE);
|
||||
MockAioImageWrite mock_aio_image_write(mock_image_ctx, aio_comp, 0, 1, "1",
|
||||
0);
|
||||
{
|
||||
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
|
||||
mock_aio_image_write.send();
|
||||
}
|
||||
ASSERT_EQ(0, aio_comp_ctx.wait());
|
||||
}
|
||||
|
||||
TEST_F(TestMockAioImageRequest, AioDiscardJournalAppendDisabled) {
|
||||
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
|
||||
|
||||
librbd::ImageCtx *ictx;
|
||||
ASSERT_EQ(0, open_image(m_image_name, &ictx));
|
||||
|
||||
MockAioObjectRequest mock_aio_object_request;
|
||||
MockTestImageCtx mock_image_ctx(*ictx);
|
||||
MockJournal mock_journal;
|
||||
mock_image_ctx.journal = &mock_journal;
|
||||
|
||||
InSequence seq;
|
||||
expect_is_journal_appending(mock_journal, false);
|
||||
expect_object_request_send(mock_image_ctx, mock_aio_object_request, 0);
|
||||
|
||||
C_SaferCond aio_comp_ctx;
|
||||
AioCompletion *aio_comp = AioCompletion::create_and_start(
|
||||
&aio_comp_ctx, ictx, AIO_TYPE_DISCARD);
|
||||
MockAioImageDiscard mock_aio_image_discard(mock_image_ctx, aio_comp, 0, 1);
|
||||
{
|
||||
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
|
||||
mock_aio_image_discard.send();
|
||||
}
|
||||
ASSERT_EQ(0, aio_comp_ctx.wait());
|
||||
}
|
||||
|
||||
TEST_F(TestMockAioImageRequest, AioFlushJournalAppendDisabled) {
|
||||
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
|
||||
|
||||
librbd::ImageCtx *ictx;
|
||||
ASSERT_EQ(0, open_image(m_image_name, &ictx));
|
||||
|
||||
MockTestImageCtx mock_image_ctx(*ictx);
|
||||
MockJournal mock_journal;
|
||||
mock_image_ctx.journal = &mock_journal;
|
||||
|
||||
InSequence seq;
|
||||
expect_is_journal_appending(mock_journal, false);
|
||||
expect_flush(mock_image_ctx, 0);
|
||||
|
||||
C_SaferCond aio_comp_ctx;
|
||||
AioCompletion *aio_comp = AioCompletion::create_and_start(
|
||||
&aio_comp_ctx, ictx, AIO_TYPE_FLUSH);
|
||||
MockAioImageFlush mock_aio_image_flush(mock_image_ctx, aio_comp);
|
||||
{
|
||||
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
|
||||
mock_aio_image_flush.send();
|
||||
}
|
||||
ASSERT_EQ(0, aio_comp_ctx.wait());
|
||||
}
|
||||
|
||||
} // namespace librbd
|
@ -5,6 +5,7 @@
|
||||
#include "test/journal/mock/MockJournaler.h"
|
||||
#include "test/librbd/test_support.h"
|
||||
#include "test/librbd/mock/MockImageCtx.h"
|
||||
#include "test/librbd/mock/MockJournalPolicy.h"
|
||||
#include "common/Cond.h"
|
||||
#include "common/Mutex.h"
|
||||
#include "cls/journal/cls_journal_types.h"
|
||||
@ -158,6 +159,7 @@ public:
|
||||
}
|
||||
|
||||
void expect_shut_down_journaler(::journal::MockJournaler &mock_journaler) {
|
||||
EXPECT_CALL(mock_journaler, remove_listener(_));
|
||||
EXPECT_CALL(mock_journaler, shut_down(_))
|
||||
.WillOnce(CompleteContext(0, NULL));
|
||||
}
|
||||
@ -196,6 +198,7 @@ public:
|
||||
EXPECT_CALL(mock_journaler, get_tags(0, _, _))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(tags),
|
||||
WithArg<2>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue))));
|
||||
EXPECT_CALL(mock_journaler, add_listener(_));
|
||||
}
|
||||
|
||||
void expect_start_replay(MockJournalImageCtx &mock_image_ctx,
|
||||
@ -714,6 +717,8 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) {
|
||||
MockJournalReplay mock_journal_replay;
|
||||
expect_try_pop_front(mock_journaler, true, mock_replay_entry);
|
||||
|
||||
EXPECT_CALL(mock_journal_replay, decode(_, _))
|
||||
.WillOnce(Return(0));
|
||||
Context *on_ready;
|
||||
EXPECT_CALL(mock_journal_replay, process(_, _, _))
|
||||
.WillOnce(DoAll(SaveArg<1>(&on_ready),
|
||||
@ -1151,5 +1156,34 @@ TEST_F(TestMockJournal, ExternalReplayCloseRequest) {
|
||||
ASSERT_EQ(0, close_ctx.wait());
|
||||
}
|
||||
|
||||
TEST_F(TestMockJournal, AppendDisabled) {
|
||||
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
|
||||
|
||||
librbd::ImageCtx *ictx;
|
||||
ASSERT_EQ(0, open_image(m_image_name, &ictx));
|
||||
|
||||
MockJournalImageCtx mock_image_ctx(*ictx);
|
||||
MockJournal mock_journal(mock_image_ctx);
|
||||
MockJournalPolicy mock_journal_policy;
|
||||
|
||||
::journal::MockJournaler mock_journaler;
|
||||
open_journal(mock_image_ctx, mock_journal, mock_journaler);
|
||||
BOOST_SCOPE_EXIT_ALL(&) {
|
||||
close_journal(mock_journal, mock_journaler);
|
||||
};
|
||||
|
||||
InSequence seq;
|
||||
RWLock::RLocker snap_locker(mock_image_ctx.snap_lock);
|
||||
EXPECT_CALL(mock_image_ctx, get_journal_policy()).WillOnce(
|
||||
Return(ictx->get_journal_policy()));
|
||||
ASSERT_TRUE(mock_journal.is_journal_appending());
|
||||
|
||||
EXPECT_CALL(mock_image_ctx, get_journal_policy()).WillOnce(
|
||||
Return(&mock_journal_policy));
|
||||
EXPECT_CALL(mock_journal_policy, append_disabled()).WillOnce(Return(true));
|
||||
ASSERT_FALSE(mock_journal.is_journal_appending());
|
||||
|
||||
expect_shut_down_journaler(mock_journaler);
|
||||
}
|
||||
|
||||
} // namespace librbd
|
||||
|
@ -109,7 +109,7 @@ public:
|
||||
void expect_get_snap_id(librbd::MockTestImageCtx &mock_image_ctx) {
|
||||
EXPECT_CALL(mock_image_ctx, get_snap_id(_))
|
||||
.WillRepeatedly(Invoke([&mock_image_ctx](std::string snap_name) {
|
||||
RWLock::RLocker snap_locker(mock_image_ctx.image_ctx->snap_lock);
|
||||
assert(mock_image_ctx.image_ctx->snap_lock.is_locked());
|
||||
return mock_image_ctx.image_ctx->get_snap_id(snap_name);
|
||||
}));
|
||||
}
|
||||
|
@ -179,8 +179,8 @@ public:
|
||||
})));
|
||||
} else {
|
||||
expect.WillOnce(WithArg<5>(Invoke([&mock_image_ctx, snap_id, state, r](Context *ctx) {
|
||||
RWLock::RLocker snap_locker(mock_image_ctx.image_ctx->snap_lock);
|
||||
RWLock::WLocker object_map_locker(mock_image_ctx.image_ctx->object_map_lock);
|
||||
assert(mock_image_ctx.image_ctx->snap_lock.is_locked());
|
||||
assert(mock_image_ctx.image_ctx->object_map_lock.is_wlocked());
|
||||
mock_image_ctx.image_ctx->object_map->aio_update(snap_id, 0, 1,
|
||||
state,
|
||||
boost::none, ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user