1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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"
10 class TestFutureImpl
: public RadosTestFixture
{
12 struct FlushHandler
: public journal::FutureImpl::FlushHandler
{
15 FlushHandler() : refs(0), flushes(0) {}
23 void flush(const journal::FutureImplPtr
&future
) override
{
28 journal::FutureImplPtr
create_future(uint64_t tag_tid
, uint64_t entry_tid
,
30 const journal::FutureImplPtr
&prev
=
31 journal::FutureImplPtr()) {
32 journal::FutureImplPtr
future(new journal::FutureImpl(tag_tid
,
39 void flush(const journal::FutureImplPtr
&future
) {
42 FlushHandler m_flush_handler
;
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
));
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());
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
));
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
);
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
));
77 journal::FutureImplPtr future
= create_future(234, 123, 456);
80 ASSERT_TRUE(future
->attach(&m_flush_handler
));
81 ASSERT_EQ(1U, m_flush_handler
.refs
);
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
));
91 journal::FutureImplPtr future
= create_future(234, 123, 456);
92 ASSERT_FALSE(future
->attach(&m_flush_handler
));
94 ASSERT_EQ(0U, m_flush_handler
.refs
);
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
));
104 journal::FutureImplPtr future
= create_future(234, 123, 456);
105 ASSERT_FALSE(future
->attach(&m_flush_handler
));
107 ASSERT_EQ(0U, m_flush_handler
.refs
);
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
));
117 journal::FutureImplPtr future
= create_future(234, 123, 456);
118 ASSERT_FALSE(future
->attach(&m_flush_handler
));
121 future
->flush(&cond
);
123 ASSERT_EQ(1U, m_flush_handler
.flushes
);
125 ASSERT_EQ(-EIO
, cond
.wait());
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
));
135 journal::FutureImplPtr future
= create_future(234, 123, 456);
136 ASSERT_FALSE(future
->attach(&m_flush_handler
));
139 ASSERT_EQ(1U, m_flush_handler
.flushes
);
141 ASSERT_TRUE(future
->is_complete());
142 ASSERT_EQ(-EIO
, future
->get_return_value());
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
));
152 journal::FutureImplPtr future1
= create_future(234, 123, 456);
153 journal::FutureImplPtr future2
= create_future(234, 124, 457,
155 journal::FutureImplPtr future3
= create_future(235, 1, 458,
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
));
164 future3
->flush(&cond
);
166 ASSERT_EQ(1U, m_flush_handler
.flushes
);
167 ASSERT_EQ(1U, flush_handler
.flushes
);
170 ASSERT_FALSE(future3
->is_complete());
173 ASSERT_FALSE(future3
->is_complete());
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());
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
));
189 journal::FutureImplPtr future1
= create_future(234, 123, 456);
190 journal::FutureImplPtr future2
= create_future(234, 124, 457,
192 ASSERT_FALSE(future1
->attach(&m_flush_handler
));
193 ASSERT_FALSE(future2
->attach(&m_flush_handler
));
195 future1
->set_flush_in_progress();
196 ASSERT_TRUE(future1
->is_flush_in_progress());
198 future1
->flush(NULL
);
199 ASSERT_EQ(0U, m_flush_handler
.flushes
);
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
));
211 journal::FutureImplPtr future
= create_future(234, 123, 456);
215 future
->flush(&cond
);
216 ASSERT_EQ(-EIO
, cond
.wait());
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
));
226 journal::FutureImplPtr future
= create_future(234, 1, 456);
230 future
->safe(-EEXIST
);
231 ASSERT_EQ(-EEXIST
, cond
.wait());
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
));
241 journal::FutureImplPtr future
= create_future(234, 1, 456);
242 future
->safe(-EEXIST
);
246 ASSERT_EQ(-EEXIST
, cond
.wait());
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
));
256 journal::FutureImplPtr future1
= create_future(234, 123, 456);
257 journal::FutureImplPtr future2
= create_future(234, 124, 457,
261 future2
->safe(-EEXIST
);
262 ASSERT_TRUE(future2
->is_complete());
263 ASSERT_EQ(-EIO
, future2
->get_return_value());
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
));
273 journal::FutureImplPtr future1
= create_future(234, 123, 456);
274 journal::FutureImplPtr future2
= create_future(234, 124, 457,
277 future2
->safe(-EEXIST
);
279 ASSERT_TRUE(future2
->is_complete());
280 ASSERT_EQ(-EEXIST
, future2
->get_return_value());