]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/journal/test_FutureImpl.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / test / journal / test_FutureImpl.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 "journal/FutureImpl.h"
5 #include "common/Cond.h"
6 #include "common/Mutex.h"
7 #include "gtest/gtest.h"
8 #include "test/journal/RadosTestFixture.h"
9
10 class TestFutureImpl : public RadosTestFixture {
11 public:
12 struct FlushHandler : public journal::FutureImpl::FlushHandler {
13 uint64_t refs;
14 uint64_t flushes;
15 FlushHandler() : refs(0), flushes(0) {}
16 void get() override {
17 ++refs;
18 }
19 void put() override {
20 assert(refs > 0);
21 --refs;
22 }
23 void flush(const journal::FutureImplPtr &future) override {
24 ++flushes;
25 }
26 };
27
28 journal::FutureImplPtr create_future(uint64_t tag_tid, uint64_t entry_tid,
29 uint64_t commit_tid,
30 const journal::FutureImplPtr &prev =
31 journal::FutureImplPtr()) {
32 journal::FutureImplPtr future(new journal::FutureImpl(tag_tid,
33 entry_tid,
34 commit_tid));
35 future->init(prev);
36 return future;
37 }
38
39 void flush(const journal::FutureImplPtr &future) {
40 }
41
42 FlushHandler m_flush_handler;
43 };
44
45 TEST_F(TestFutureImpl, Getters) {
46 std::string oid = get_temp_oid();
47 ASSERT_EQ(0, create(oid));
48 ASSERT_EQ(0, client_register(oid));
49 journal::JournalMetadataPtr metadata = create_metadata(oid);
50 ASSERT_EQ(0, init_metadata(metadata));
51
52 journal::FutureImplPtr future = create_future(234, 123, 456);
53 ASSERT_EQ(234U, future->get_tag_tid());
54 ASSERT_EQ(123U, future->get_entry_tid());
55 ASSERT_EQ(456U, future->get_commit_tid());
56 }
57
58 TEST_F(TestFutureImpl, Attach) {
59 std::string oid = get_temp_oid();
60 ASSERT_EQ(0, create(oid));
61 ASSERT_EQ(0, client_register(oid));
62 journal::JournalMetadataPtr metadata = create_metadata(oid);
63 ASSERT_EQ(0, init_metadata(metadata));
64
65 journal::FutureImplPtr future = create_future(234, 123, 456);
66 ASSERT_FALSE(future->attach(&m_flush_handler));
67 ASSERT_EQ(1U, m_flush_handler.refs);
68 }
69
70 TEST_F(TestFutureImpl, AttachWithPendingFlush) {
71 std::string oid = get_temp_oid();
72 ASSERT_EQ(0, create(oid));
73 ASSERT_EQ(0, client_register(oid));
74 journal::JournalMetadataPtr metadata = create_metadata(oid);
75 ASSERT_EQ(0, init_metadata(metadata));
76
77 journal::FutureImplPtr future = create_future(234, 123, 456);
78 future->flush(NULL);
79
80 ASSERT_TRUE(future->attach(&m_flush_handler));
81 ASSERT_EQ(1U, m_flush_handler.refs);
82 }
83
84 TEST_F(TestFutureImpl, Detach) {
85 std::string oid = get_temp_oid();
86 ASSERT_EQ(0, create(oid));
87 ASSERT_EQ(0, client_register(oid));
88 journal::JournalMetadataPtr metadata = create_metadata(oid);
89 ASSERT_EQ(0, init_metadata(metadata));
90
91 journal::FutureImplPtr future = create_future(234, 123, 456);
92 ASSERT_FALSE(future->attach(&m_flush_handler));
93 future->detach();
94 ASSERT_EQ(0U, m_flush_handler.refs);
95 }
96
97 TEST_F(TestFutureImpl, DetachImplicit) {
98 std::string oid = get_temp_oid();
99 ASSERT_EQ(0, create(oid));
100 ASSERT_EQ(0, client_register(oid));
101 journal::JournalMetadataPtr metadata = create_metadata(oid);
102 ASSERT_EQ(0, init_metadata(metadata));
103
104 journal::FutureImplPtr future = create_future(234, 123, 456);
105 ASSERT_FALSE(future->attach(&m_flush_handler));
106 future.reset();
107 ASSERT_EQ(0U, m_flush_handler.refs);
108 }
109
110 TEST_F(TestFutureImpl, Flush) {
111 std::string oid = get_temp_oid();
112 ASSERT_EQ(0, create(oid));
113 ASSERT_EQ(0, client_register(oid));
114 journal::JournalMetadataPtr metadata = create_metadata(oid);
115 ASSERT_EQ(0, init_metadata(metadata));
116
117 journal::FutureImplPtr future = create_future(234, 123, 456);
118 ASSERT_FALSE(future->attach(&m_flush_handler));
119
120 C_SaferCond cond;
121 future->flush(&cond);
122
123 ASSERT_EQ(1U, m_flush_handler.flushes);
124 future->safe(-EIO);
125 ASSERT_EQ(-EIO, cond.wait());
126 }
127
128 TEST_F(TestFutureImpl, FlushWithoutContext) {
129 std::string oid = get_temp_oid();
130 ASSERT_EQ(0, create(oid));
131 ASSERT_EQ(0, client_register(oid));
132 journal::JournalMetadataPtr metadata = create_metadata(oid);
133 ASSERT_EQ(0, init_metadata(metadata));
134
135 journal::FutureImplPtr future = create_future(234, 123, 456);
136 ASSERT_FALSE(future->attach(&m_flush_handler));
137
138 future->flush(NULL);
139 ASSERT_EQ(1U, m_flush_handler.flushes);
140 future->safe(-EIO);
141 ASSERT_TRUE(future->is_complete());
142 ASSERT_EQ(-EIO, future->get_return_value());
143 }
144
145 TEST_F(TestFutureImpl, FlushChain) {
146 std::string oid = get_temp_oid();
147 ASSERT_EQ(0, create(oid));
148 ASSERT_EQ(0, client_register(oid));
149 journal::JournalMetadataPtr metadata = create_metadata(oid);
150 ASSERT_EQ(0, init_metadata(metadata));
151
152 journal::FutureImplPtr future1 = create_future(234, 123, 456);
153 journal::FutureImplPtr future2 = create_future(234, 124, 457,
154 future1);
155 journal::FutureImplPtr future3 = create_future(235, 1, 458,
156 future2);
157
158 FlushHandler flush_handler;
159 ASSERT_FALSE(future1->attach(&m_flush_handler));
160 ASSERT_FALSE(future2->attach(&flush_handler));
161 ASSERT_FALSE(future3->attach(&m_flush_handler));
162
163 C_SaferCond cond;
164 future3->flush(&cond);
165
166 ASSERT_EQ(1U, m_flush_handler.flushes);
167 ASSERT_EQ(1U, flush_handler.flushes);
168
169 future3->safe(0);
170 ASSERT_FALSE(future3->is_complete());
171
172 future1->safe(0);
173 ASSERT_FALSE(future3->is_complete());
174
175 future2->safe(-EIO);
176 ASSERT_TRUE(future3->is_complete());
177 ASSERT_EQ(-EIO, future3->get_return_value());
178 ASSERT_EQ(-EIO, cond.wait());
179 ASSERT_EQ(0, future1->get_return_value());
180 }
181
182 TEST_F(TestFutureImpl, FlushInProgress) {
183 std::string oid = get_temp_oid();
184 ASSERT_EQ(0, create(oid));
185 ASSERT_EQ(0, client_register(oid));
186 journal::JournalMetadataPtr metadata = create_metadata(oid);
187 ASSERT_EQ(0, init_metadata(metadata));
188
189 journal::FutureImplPtr future1 = create_future(234, 123, 456);
190 journal::FutureImplPtr future2 = create_future(234, 124, 457,
191 future1);
192 ASSERT_FALSE(future1->attach(&m_flush_handler));
193 ASSERT_FALSE(future2->attach(&m_flush_handler));
194
195 future1->set_flush_in_progress();
196 ASSERT_TRUE(future1->is_flush_in_progress());
197
198 future1->flush(NULL);
199 ASSERT_EQ(0U, m_flush_handler.flushes);
200
201 future1->safe(0);
202 }
203
204 TEST_F(TestFutureImpl, FlushAlreadyComplete) {
205 std::string oid = get_temp_oid();
206 ASSERT_EQ(0, create(oid));
207 ASSERT_EQ(0, client_register(oid));
208 journal::JournalMetadataPtr metadata = create_metadata(oid);
209 ASSERT_EQ(0, init_metadata(metadata));
210
211 journal::FutureImplPtr future = create_future(234, 123, 456);
212 future->safe(-EIO);
213
214 C_SaferCond cond;
215 future->flush(&cond);
216 ASSERT_EQ(-EIO, cond.wait());
217 }
218
219 TEST_F(TestFutureImpl, Wait) {
220 std::string oid = get_temp_oid();
221 ASSERT_EQ(0, create(oid));
222 ASSERT_EQ(0, client_register(oid));
223 journal::JournalMetadataPtr metadata = create_metadata(oid);
224 ASSERT_EQ(0, init_metadata(metadata));
225
226 journal::FutureImplPtr future = create_future(234, 1, 456);
227
228 C_SaferCond cond;
229 future->wait(&cond);
230 future->safe(-EEXIST);
231 ASSERT_EQ(-EEXIST, cond.wait());
232 }
233
234 TEST_F(TestFutureImpl, WaitAlreadyComplete) {
235 std::string oid = get_temp_oid();
236 ASSERT_EQ(0, create(oid));
237 ASSERT_EQ(0, client_register(oid));
238 journal::JournalMetadataPtr metadata = create_metadata(oid);
239 ASSERT_EQ(0, init_metadata(metadata));
240
241 journal::FutureImplPtr future = create_future(234, 1, 456);
242 future->safe(-EEXIST);
243
244 C_SaferCond cond;
245 future->wait(&cond);
246 ASSERT_EQ(-EEXIST, cond.wait());
247 }
248
249 TEST_F(TestFutureImpl, SafePreservesError) {
250 std::string oid = get_temp_oid();
251 ASSERT_EQ(0, create(oid));
252 ASSERT_EQ(0, client_register(oid));
253 journal::JournalMetadataPtr metadata = create_metadata(oid);
254 ASSERT_EQ(0, init_metadata(metadata));
255
256 journal::FutureImplPtr future1 = create_future(234, 123, 456);
257 journal::FutureImplPtr future2 = create_future(234, 124, 457,
258 future1);
259
260 future1->safe(-EIO);
261 future2->safe(-EEXIST);
262 ASSERT_TRUE(future2->is_complete());
263 ASSERT_EQ(-EIO, future2->get_return_value());
264 }
265
266 TEST_F(TestFutureImpl, ConsistentPreservesError) {
267 std::string oid = get_temp_oid();
268 ASSERT_EQ(0, create(oid));
269 ASSERT_EQ(0, client_register(oid));
270 journal::JournalMetadataPtr metadata = create_metadata(oid);
271 ASSERT_EQ(0, init_metadata(metadata));
272
273 journal::FutureImplPtr future1 = create_future(234, 123, 456);
274 journal::FutureImplPtr future2 = create_future(234, 124, 457,
275 future1);
276
277 future2->safe(-EEXIST);
278 future1->safe(-EIO);
279 ASSERT_TRUE(future2->is_complete());
280 ASSERT_EQ(-EEXIST, future2->get_return_value());
281 }