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 "include/rados/librados.hpp"
6 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
7 #include "test/librados_test_stub/MockTestMemRadosClient.h"
8 #include "test/librbd/test_support.h"
9 #include "test/librbd/mock/MockImageCtx.h"
10 #include "librados/AioCompletionImpl.h"
11 #include "librbd/watcher/RewatchRequest.h"
17 using ::testing::DoAll;
18 using ::testing::InSequence;
19 using ::testing::Invoke;
20 using ::testing::Return;
21 using ::testing::WithArg;
23 struct TestMockWatcherRewatchRequest : public TestMockFixture {
24 typedef RewatchRequest MockRewatchRequest;
26 TestMockWatcherRewatchRequest()
27 : m_watch_lock("watch_lock") {
30 void expect_aio_watch(MockImageCtx &mock_image_ctx, int r) {
31 librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(
32 mock_image_ctx.md_ctx));
34 EXPECT_CALL(mock_io_ctx, aio_watch(mock_image_ctx.header_oid, _, _, _))
35 .WillOnce(DoAll(WithArg<1>(Invoke([&mock_image_ctx, &mock_io_ctx, r](librados::AioCompletionImpl *c) {
37 mock_image_ctx.image_ctx->op_work_queue->queue(new FunctionContext([&mock_io_ctx, c](int r) {
38 mock_io_ctx.get_mock_rados_client()->finish_aio_completion(c, r);
44 void expect_aio_unwatch(MockImageCtx &mock_image_ctx, int r) {
45 librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(
46 mock_image_ctx.md_ctx));
48 EXPECT_CALL(mock_io_ctx, aio_unwatch(m_watch_handle, _))
49 .WillOnce(DoAll(Invoke([&mock_image_ctx, &mock_io_ctx, r](uint64_t handle,
50 librados::AioCompletionImpl *c) {
52 mock_image_ctx.image_ctx->op_work_queue->queue(new FunctionContext([&mock_io_ctx, c](int r) {
53 mock_io_ctx.get_mock_rados_client()->finish_aio_completion(c, r);
59 struct WatchCtx : public librados::WatchCtx2 {
60 void handle_notify(uint64_t, uint64_t, uint64_t,
61 ceph::bufferlist&) override {
64 void handle_error(uint64_t, int) override {
71 uint64_t m_watch_handle = 123;
74 TEST_F(TestMockWatcherRewatchRequest, Success) {
75 librbd::ImageCtx *ictx;
76 ASSERT_EQ(0, open_image(m_image_name, &ictx));
78 MockImageCtx mock_image_ctx(*ictx);
81 expect_aio_unwatch(mock_image_ctx, 0);
82 expect_aio_watch(mock_image_ctx, 0);
85 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
86 mock_image_ctx.header_oid,
92 RWLock::WLocker watch_locker(m_watch_lock);
95 ASSERT_EQ(0, ctx.wait());
98 TEST_F(TestMockWatcherRewatchRequest, UnwatchError) {
99 librbd::ImageCtx *ictx;
100 ASSERT_EQ(0, open_image(m_image_name, &ictx));
102 MockImageCtx mock_image_ctx(*ictx);
105 expect_aio_unwatch(mock_image_ctx, -EINVAL);
106 expect_aio_watch(mock_image_ctx, 0);
109 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
110 mock_image_ctx.header_oid,
116 RWLock::WLocker watch_locker(m_watch_lock);
119 ASSERT_EQ(0, ctx.wait());
122 TEST_F(TestMockWatcherRewatchRequest, WatchBlacklist) {
123 librbd::ImageCtx *ictx;
124 ASSERT_EQ(0, open_image(m_image_name, &ictx));
126 MockImageCtx mock_image_ctx(*ictx);
129 expect_aio_unwatch(mock_image_ctx, 0);
130 expect_aio_watch(mock_image_ctx, -EBLACKLISTED);
133 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
134 mock_image_ctx.header_oid,
140 RWLock::WLocker watch_locker(m_watch_lock);
143 ASSERT_EQ(-EBLACKLISTED, ctx.wait());
146 TEST_F(TestMockWatcherRewatchRequest, WatchDNE) {
147 librbd::ImageCtx *ictx;
148 ASSERT_EQ(0, open_image(m_image_name, &ictx));
150 MockImageCtx mock_image_ctx(*ictx);
153 expect_aio_unwatch(mock_image_ctx, 0);
154 expect_aio_watch(mock_image_ctx, -ENOENT);
157 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
158 mock_image_ctx.header_oid,
164 RWLock::WLocker watch_locker(m_watch_lock);
167 ASSERT_EQ(-ENOENT, ctx.wait());
170 TEST_F(TestMockWatcherRewatchRequest, WatchError) {
171 librbd::ImageCtx *ictx;
172 ASSERT_EQ(0, open_image(m_image_name, &ictx));
174 MockImageCtx mock_image_ctx(*ictx);
177 expect_aio_unwatch(mock_image_ctx, 0);
178 expect_aio_watch(mock_image_ctx, -EINVAL);
179 expect_aio_watch(mock_image_ctx, 0);
182 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
183 mock_image_ctx.header_oid,
189 RWLock::WLocker watch_locker(m_watch_lock);
192 ASSERT_EQ(0, ctx.wait());
195 } // namespace watcher
196 } // namespace librbd