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
;
22 using ::testing::WithArgs
;
24 struct TestMockWatcherRewatchRequest
: public TestMockFixture
{
25 typedef RewatchRequest MockRewatchRequest
;
27 TestMockWatcherRewatchRequest()
28 : m_watch_lock("watch_lock") {
31 void expect_aio_watch(MockImageCtx
&mock_image_ctx
, int r
) {
32 librados::MockTestMemIoCtxImpl
&mock_io_ctx(get_mock_io_ctx(
33 mock_image_ctx
.md_ctx
));
35 EXPECT_CALL(mock_io_ctx
, aio_watch(mock_image_ctx
.header_oid
, _
, _
, _
))
36 .WillOnce(DoAll(WithArgs
<1, 2>(Invoke([&mock_image_ctx
, &mock_io_ctx
, r
](librados::AioCompletionImpl
*c
, uint64_t *cookie
) {
39 mock_image_ctx
.image_ctx
->op_work_queue
->queue(new FunctionContext([&mock_io_ctx
, c
](int r
) {
40 mock_io_ctx
.get_mock_rados_client()->finish_aio_completion(c
, r
);
46 void expect_aio_unwatch(MockImageCtx
&mock_image_ctx
, int r
) {
47 librados::MockTestMemIoCtxImpl
&mock_io_ctx(get_mock_io_ctx(
48 mock_image_ctx
.md_ctx
));
50 EXPECT_CALL(mock_io_ctx
, aio_unwatch(m_watch_handle
, _
))
51 .WillOnce(DoAll(Invoke([&mock_image_ctx
, &mock_io_ctx
, r
](uint64_t handle
,
52 librados::AioCompletionImpl
*c
) {
54 mock_image_ctx
.image_ctx
->op_work_queue
->queue(new FunctionContext([&mock_io_ctx
, c
](int r
) {
55 mock_io_ctx
.get_mock_rados_client()->finish_aio_completion(c
, r
);
61 struct WatchCtx
: public librados::WatchCtx2
{
62 void handle_notify(uint64_t, uint64_t, uint64_t,
63 ceph::bufferlist
&) override
{
66 void handle_error(uint64_t, int) override
{
73 uint64_t m_watch_handle
= 123;
76 TEST_F(TestMockWatcherRewatchRequest
, Success
) {
77 librbd::ImageCtx
*ictx
;
78 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
80 MockImageCtx
mock_image_ctx(*ictx
);
83 expect_aio_unwatch(mock_image_ctx
, 0);
84 expect_aio_watch(mock_image_ctx
, 0);
87 MockRewatchRequest
*req
= MockRewatchRequest::create(mock_image_ctx
.md_ctx
,
88 mock_image_ctx
.header_oid
,
94 RWLock::WLocker
watch_locker(m_watch_lock
);
97 ASSERT_EQ(0, ctx
.wait());
98 ASSERT_EQ(234U, m_watch_handle
);
101 TEST_F(TestMockWatcherRewatchRequest
, UnwatchError
) {
102 librbd::ImageCtx
*ictx
;
103 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
105 MockImageCtx
mock_image_ctx(*ictx
);
108 expect_aio_unwatch(mock_image_ctx
, -EINVAL
);
109 expect_aio_watch(mock_image_ctx
, 0);
112 MockRewatchRequest
*req
= MockRewatchRequest::create(mock_image_ctx
.md_ctx
,
113 mock_image_ctx
.header_oid
,
119 RWLock::WLocker
watch_locker(m_watch_lock
);
122 ASSERT_EQ(0, ctx
.wait());
123 ASSERT_EQ(234U, m_watch_handle
);
126 TEST_F(TestMockWatcherRewatchRequest
, WatchBlacklist
) {
127 librbd::ImageCtx
*ictx
;
128 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
130 MockImageCtx
mock_image_ctx(*ictx
);
133 expect_aio_unwatch(mock_image_ctx
, 0);
134 expect_aio_watch(mock_image_ctx
, -EBLACKLISTED
);
137 MockRewatchRequest
*req
= MockRewatchRequest::create(mock_image_ctx
.md_ctx
,
138 mock_image_ctx
.header_oid
,
144 RWLock::WLocker
watch_locker(m_watch_lock
);
147 ASSERT_EQ(-EBLACKLISTED
, ctx
.wait());
148 ASSERT_EQ(0U, m_watch_handle
);
151 TEST_F(TestMockWatcherRewatchRequest
, WatchDNE
) {
152 librbd::ImageCtx
*ictx
;
153 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
155 MockImageCtx
mock_image_ctx(*ictx
);
158 expect_aio_unwatch(mock_image_ctx
, 0);
159 expect_aio_watch(mock_image_ctx
, -ENOENT
);
162 MockRewatchRequest
*req
= MockRewatchRequest::create(mock_image_ctx
.md_ctx
,
163 mock_image_ctx
.header_oid
,
169 RWLock::WLocker
watch_locker(m_watch_lock
);
172 ASSERT_EQ(-ENOENT
, ctx
.wait());
173 ASSERT_EQ(0U, m_watch_handle
);
176 TEST_F(TestMockWatcherRewatchRequest
, WatchError
) {
177 librbd::ImageCtx
*ictx
;
178 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
180 MockImageCtx
mock_image_ctx(*ictx
);
183 expect_aio_unwatch(mock_image_ctx
, 0);
184 expect_aio_watch(mock_image_ctx
, -EINVAL
);
187 MockRewatchRequest
*req
= MockRewatchRequest::create(mock_image_ctx
.md_ctx
,
188 mock_image_ctx
.header_oid
,
194 RWLock::WLocker
watch_locker(m_watch_lock
);
197 ASSERT_EQ(-EINVAL
, ctx
.wait());
198 ASSERT_EQ(0U, m_watch_handle
);
201 TEST_F(TestMockWatcherRewatchRequest
, InvalidWatchHandler
) {
202 librbd::ImageCtx
*ictx
;
203 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
205 MockImageCtx
mock_image_ctx(*ictx
);
208 expect_aio_watch(mock_image_ctx
, 0);
213 MockRewatchRequest
*req
= MockRewatchRequest::create(mock_image_ctx
.md_ctx
,
214 mock_image_ctx
.header_oid
,
220 RWLock::WLocker
watch_locker(m_watch_lock
);
224 ASSERT_EQ(0, ctx
.wait());
225 ASSERT_EQ(234U, m_watch_handle
);
228 } // namespace watcher
229 } // namespace librbd