1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "test/librbd/test_mock_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "test/librbd/mock/MockImageCtx.h"
7 #include "test/librbd/mock/MockJournal.h"
8 #include "librbd/AsyncRequest.h"
9 #include "librbd/operation/Request.h"
14 struct MockTestImageCtx : public MockImageCtx {
15 MockTestImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
19 } // anonymous namespace
22 struct AsyncRequest<librbd::MockTestImageCtx> {
23 librbd::MockTestImageCtx &m_image_ctx;
26 AsyncRequest(librbd::MockTestImageCtx &image_ctx, Context *on_finish)
27 : m_image_ctx(image_ctx), m_on_finish(on_finish) {
29 virtual ~AsyncRequest() {
32 virtual void finish(int r) {
33 m_on_finish->complete(r);
35 virtual void finish_and_destroy(int r) {
43 #include "librbd/operation/Request.cc"
48 std::ostream& operator<<(std::ostream& os, const Event&) {
52 } // namespace journal
56 using ::testing::InSequence;
57 using ::testing::Invoke;
58 using ::testing::Return;
60 struct MockRequest : public Request<librbd::MockTestImageCtx> {
61 MockRequest(librbd::MockTestImageCtx &image_ctx, Context *on_finish,
62 uint64_t journal_op_tid)
63 : Request<librbd::MockTestImageCtx>(image_ctx, on_finish, journal_op_tid) {
66 void complete(int r) {
67 finish_and_destroy(r);
70 void send_op_impl(int r) {
71 bool appending = append_op_event<
72 MockRequest, &MockRequest::handle_send>(this);
77 MOCK_METHOD1(should_complete, bool(int));
78 MOCK_METHOD0(send_op, void());
79 MOCK_METHOD1(handle_send, Context*(int*));
80 MOCK_CONST_METHOD0(can_affect_io, bool());
81 MOCK_CONST_METHOD1(create_event, journal::Event(uint64_t));
84 struct TestMockOperationRequest : public TestMockFixture {
85 void expect_can_affect_io(MockRequest &mock_request, bool can_affect) {
86 EXPECT_CALL(mock_request, can_affect_io())
87 .WillOnce(Return(can_affect));
90 void expect_is_journal_replaying(MockJournal &mock_journal, bool replaying) {
91 EXPECT_CALL(mock_journal, is_journal_replaying())
92 .WillOnce(Return(replaying));
95 void expect_is_journal_appending(MockJournal &mock_journal, bool appending) {
96 EXPECT_CALL(mock_journal, is_journal_appending())
97 .WillOnce(Return(appending));
100 void expect_send_op(MockRequest &mock_request, int r) {
101 EXPECT_CALL(mock_request, send_op())
102 .WillOnce(Invoke([&mock_request, r]() {
103 mock_request.complete(r);
107 void expect_send_op_affects_io(MockImageCtx &mock_image_ctx,
108 MockRequest &mock_request, int r) {
109 EXPECT_CALL(mock_request, send_op())
110 .WillOnce(Invoke([&mock_image_ctx, &mock_request, r]() {
111 mock_image_ctx.image_ctx->op_work_queue->queue(
112 new FunctionContext([&mock_request, r](int _) {
113 mock_request.send_op_impl(r);
120 TEST_F(TestMockOperationRequest, SendJournalDisabled) {
121 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
123 librbd::ImageCtx *ictx;
124 ASSERT_EQ(0, open_image(m_image_name, &ictx));
126 MockTestImageCtx mock_image_ctx(*ictx);
127 MockJournal mock_journal;
128 mock_image_ctx.journal = &mock_journal;
131 MockRequest *mock_request = new MockRequest(mock_image_ctx, &ctx, 0);
134 expect_can_affect_io(*mock_request, false);
135 expect_is_journal_appending(mock_journal, false);
136 expect_send_op(*mock_request, 0);
139 RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
140 mock_request->send();
143 ASSERT_EQ(0, ctx.wait());
146 TEST_F(TestMockOperationRequest, SendAffectsIOJournalDisabled) {
147 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
149 librbd::ImageCtx *ictx;
150 ASSERT_EQ(0, open_image(m_image_name, &ictx));
152 MockTestImageCtx mock_image_ctx(*ictx);
153 MockJournal mock_journal;
154 mock_image_ctx.journal = &mock_journal;
157 MockRequest *mock_request = new MockRequest(mock_image_ctx, &ctx, 0);
160 expect_can_affect_io(*mock_request, true);
161 expect_send_op_affects_io(mock_image_ctx, *mock_request, 0);
162 expect_can_affect_io(*mock_request, true);
163 expect_is_journal_replaying(mock_journal, false);
164 expect_is_journal_appending(mock_journal, false);
167 RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
168 mock_request->send();
171 ASSERT_EQ(0, ctx.wait());
174 } // namespace operation
175 } // namespace librbd