]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/watcher/test_mock_RewatchRequest.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / test / librbd / watcher / test_mock_RewatchRequest.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
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"
12
13 namespace librbd {
14 namespace watcher {
15
16 using ::testing::_;
17 using ::testing::DoAll;
18 using ::testing::InSequence;
19 using ::testing::Invoke;
20 using ::testing::Return;
21 using ::testing::WithArg;
22 using ::testing::WithArgs;
23
24 struct TestMockWatcherRewatchRequest : public TestMockFixture {
25 typedef RewatchRequest MockRewatchRequest;
26
27 TestMockWatcherRewatchRequest()
28 : m_watch_lock("watch_lock") {
29 }
30
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));
34
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) {
37 *cookie = 234;
38 c->get();
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);
41 }), r);
42 })),
43 Return(0)));
44 }
45
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));
49
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) {
53 c->get();
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);
56 }), r);
57 }),
58 Return(0)));
59 }
60
61 struct WatchCtx : public librados::WatchCtx2 {
62 void handle_notify(uint64_t, uint64_t, uint64_t,
63 ceph::bufferlist&) override {
64 ceph_abort();
65 }
66 void handle_error(uint64_t, int) override {
67 ceph_abort();
68 }
69 };
70
71 RWLock m_watch_lock;
72 WatchCtx m_watch_ctx;
73 uint64_t m_watch_handle = 123;
74 };
75
76 TEST_F(TestMockWatcherRewatchRequest, Success) {
77 librbd::ImageCtx *ictx;
78 ASSERT_EQ(0, open_image(m_image_name, &ictx));
79
80 MockImageCtx mock_image_ctx(*ictx);
81
82 InSequence seq;
83 expect_aio_unwatch(mock_image_ctx, 0);
84 expect_aio_watch(mock_image_ctx, 0);
85
86 C_SaferCond ctx;
87 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
88 mock_image_ctx.header_oid,
89 m_watch_lock,
90 &m_watch_ctx,
91 &m_watch_handle,
92 &ctx);
93 {
94 RWLock::WLocker watch_locker(m_watch_lock);
95 req->send();
96 }
97 ASSERT_EQ(0, ctx.wait());
98 ASSERT_EQ(234U, m_watch_handle);
99 }
100
101 TEST_F(TestMockWatcherRewatchRequest, UnwatchError) {
102 librbd::ImageCtx *ictx;
103 ASSERT_EQ(0, open_image(m_image_name, &ictx));
104
105 MockImageCtx mock_image_ctx(*ictx);
106
107 InSequence seq;
108 expect_aio_unwatch(mock_image_ctx, -EINVAL);
109 expect_aio_watch(mock_image_ctx, 0);
110
111 C_SaferCond ctx;
112 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
113 mock_image_ctx.header_oid,
114 m_watch_lock,
115 &m_watch_ctx,
116 &m_watch_handle,
117 &ctx);
118 {
119 RWLock::WLocker watch_locker(m_watch_lock);
120 req->send();
121 }
122 ASSERT_EQ(0, ctx.wait());
123 ASSERT_EQ(234U, m_watch_handle);
124 }
125
126 TEST_F(TestMockWatcherRewatchRequest, WatchBlacklist) {
127 librbd::ImageCtx *ictx;
128 ASSERT_EQ(0, open_image(m_image_name, &ictx));
129
130 MockImageCtx mock_image_ctx(*ictx);
131
132 InSequence seq;
133 expect_aio_unwatch(mock_image_ctx, 0);
134 expect_aio_watch(mock_image_ctx, -EBLACKLISTED);
135
136 C_SaferCond ctx;
137 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
138 mock_image_ctx.header_oid,
139 m_watch_lock,
140 &m_watch_ctx,
141 &m_watch_handle,
142 &ctx);
143 {
144 RWLock::WLocker watch_locker(m_watch_lock);
145 req->send();
146 }
147 ASSERT_EQ(-EBLACKLISTED, ctx.wait());
148 ASSERT_EQ(0U, m_watch_handle);
149 }
150
151 TEST_F(TestMockWatcherRewatchRequest, WatchDNE) {
152 librbd::ImageCtx *ictx;
153 ASSERT_EQ(0, open_image(m_image_name, &ictx));
154
155 MockImageCtx mock_image_ctx(*ictx);
156
157 InSequence seq;
158 expect_aio_unwatch(mock_image_ctx, 0);
159 expect_aio_watch(mock_image_ctx, -ENOENT);
160
161 C_SaferCond ctx;
162 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
163 mock_image_ctx.header_oid,
164 m_watch_lock,
165 &m_watch_ctx,
166 &m_watch_handle,
167 &ctx);
168 {
169 RWLock::WLocker watch_locker(m_watch_lock);
170 req->send();
171 }
172 ASSERT_EQ(-ENOENT, ctx.wait());
173 ASSERT_EQ(0U, m_watch_handle);
174 }
175
176 TEST_F(TestMockWatcherRewatchRequest, WatchError) {
177 librbd::ImageCtx *ictx;
178 ASSERT_EQ(0, open_image(m_image_name, &ictx));
179
180 MockImageCtx mock_image_ctx(*ictx);
181
182 InSequence seq;
183 expect_aio_unwatch(mock_image_ctx, 0);
184 expect_aio_watch(mock_image_ctx, -EINVAL);
185
186 C_SaferCond ctx;
187 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
188 mock_image_ctx.header_oid,
189 m_watch_lock,
190 &m_watch_ctx,
191 &m_watch_handle,
192 &ctx);
193 {
194 RWLock::WLocker watch_locker(m_watch_lock);
195 req->send();
196 }
197 ASSERT_EQ(-EINVAL, ctx.wait());
198 ASSERT_EQ(0U, m_watch_handle);
199 }
200
201 TEST_F(TestMockWatcherRewatchRequest, InvalidWatchHandler) {
202 librbd::ImageCtx *ictx;
203 ASSERT_EQ(0, open_image(m_image_name, &ictx));
204
205 MockImageCtx mock_image_ctx(*ictx);
206
207 InSequence seq;
208 expect_aio_watch(mock_image_ctx, 0);
209
210 m_watch_handle = 0;
211
212 C_SaferCond ctx;
213 MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
214 mock_image_ctx.header_oid,
215 m_watch_lock,
216 &m_watch_ctx,
217 &m_watch_handle,
218 &ctx);
219 {
220 RWLock::WLocker watch_locker(m_watch_lock);
221 req->send();
222 }
223
224 ASSERT_EQ(0, ctx.wait());
225 ASSERT_EQ(234U, m_watch_handle);
226 }
227
228 } // namespace watcher
229 } // namespace librbd