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