Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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 }