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());