summaryrefslogtreecommitdiffstats
path: root/src/test/journal/test_FutureImpl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/journal/test_FutureImpl.cc')
-rw-r--r--src/test/journal/test_FutureImpl.cc281
1 files changed, 281 insertions, 0 deletions
diff --git a/src/test/journal/test_FutureImpl.cc b/src/test/journal/test_FutureImpl.cc
new file mode 100644
index 00000000..14e9d530
--- /dev/null
+++ b/src/test/journal/test_FutureImpl.cc
@@ -0,0 +1,281 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "journal/FutureImpl.h"
+#include "common/Cond.h"
+#include "common/Mutex.h"
+#include "gtest/gtest.h"
+#include "test/journal/RadosTestFixture.h"
+
+class TestFutureImpl : public RadosTestFixture {
+public:
+ struct FlushHandler : public journal::FutureImpl::FlushHandler {
+ uint64_t refs;
+ uint64_t flushes;
+ FlushHandler() : refs(0), flushes(0) {}
+ void get() override {
+ ++refs;
+ }
+ void put() override {
+ ceph_assert(refs > 0);
+ --refs;
+ }
+ void flush(const journal::FutureImplPtr &future) override {
+ ++flushes;
+ }
+ };
+
+ journal::FutureImplPtr create_future(uint64_t tag_tid, uint64_t entry_tid,
+ uint64_t commit_tid,
+ const journal::FutureImplPtr &prev =
+ journal::FutureImplPtr()) {
+ journal::FutureImplPtr future(new journal::FutureImpl(tag_tid,
+ entry_tid,
+ commit_tid));
+ future->init(prev);
+ return future;
+ }
+
+ void flush(const journal::FutureImplPtr &future) {
+ }
+
+ FlushHandler m_flush_handler;
+};
+
+TEST_F(TestFutureImpl, Getters) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future = create_future(234, 123, 456);
+ ASSERT_EQ(234U, future->get_tag_tid());
+ ASSERT_EQ(123U, future->get_entry_tid());
+ ASSERT_EQ(456U, future->get_commit_tid());
+}
+
+TEST_F(TestFutureImpl, Attach) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future = create_future(234, 123, 456);
+ ASSERT_FALSE(future->attach(&m_flush_handler));
+ ASSERT_EQ(1U, m_flush_handler.refs);
+}
+
+TEST_F(TestFutureImpl, AttachWithPendingFlush) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future = create_future(234, 123, 456);
+ future->flush(NULL);
+
+ ASSERT_TRUE(future->attach(&m_flush_handler));
+ ASSERT_EQ(1U, m_flush_handler.refs);
+}
+
+TEST_F(TestFutureImpl, Detach) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future = create_future(234, 123, 456);
+ ASSERT_FALSE(future->attach(&m_flush_handler));
+ future->detach();
+ ASSERT_EQ(0U, m_flush_handler.refs);
+}
+
+TEST_F(TestFutureImpl, DetachImplicit) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future = create_future(234, 123, 456);
+ ASSERT_FALSE(future->attach(&m_flush_handler));
+ future.reset();
+ ASSERT_EQ(0U, m_flush_handler.refs);
+}
+
+TEST_F(TestFutureImpl, Flush) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future = create_future(234, 123, 456);
+ ASSERT_FALSE(future->attach(&m_flush_handler));
+
+ C_SaferCond cond;
+ future->flush(&cond);
+
+ ASSERT_EQ(1U, m_flush_handler.flushes);
+ future->safe(-EIO);
+ ASSERT_EQ(-EIO, cond.wait());
+}
+
+TEST_F(TestFutureImpl, FlushWithoutContext) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future = create_future(234, 123, 456);
+ ASSERT_FALSE(future->attach(&m_flush_handler));
+
+ future->flush(NULL);
+ ASSERT_EQ(1U, m_flush_handler.flushes);
+ future->safe(-EIO);
+ ASSERT_TRUE(future->is_complete());
+ ASSERT_EQ(-EIO, future->get_return_value());
+}
+
+TEST_F(TestFutureImpl, FlushChain) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future1 = create_future(234, 123, 456);
+ journal::FutureImplPtr future2 = create_future(234, 124, 457,
+ future1);
+ journal::FutureImplPtr future3 = create_future(235, 1, 458,
+ future2);
+
+ FlushHandler flush_handler;
+ ASSERT_FALSE(future1->attach(&m_flush_handler));
+ ASSERT_FALSE(future2->attach(&flush_handler));
+ ASSERT_FALSE(future3->attach(&m_flush_handler));
+
+ C_SaferCond cond;
+ future3->flush(&cond);
+
+ ASSERT_EQ(1U, m_flush_handler.flushes);
+ ASSERT_EQ(1U, flush_handler.flushes);
+
+ future3->safe(0);
+ ASSERT_FALSE(future3->is_complete());
+
+ future1->safe(0);
+ ASSERT_FALSE(future3->is_complete());
+
+ future2->safe(-EIO);
+ ASSERT_TRUE(future3->is_complete());
+ ASSERT_EQ(-EIO, future3->get_return_value());
+ ASSERT_EQ(-EIO, cond.wait());
+ ASSERT_EQ(0, future1->get_return_value());
+}
+
+TEST_F(TestFutureImpl, FlushInProgress) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future1 = create_future(234, 123, 456);
+ journal::FutureImplPtr future2 = create_future(234, 124, 457,
+ future1);
+ ASSERT_FALSE(future1->attach(&m_flush_handler));
+ ASSERT_FALSE(future2->attach(&m_flush_handler));
+
+ future1->set_flush_in_progress();
+ ASSERT_TRUE(future1->is_flush_in_progress());
+
+ future1->flush(NULL);
+ ASSERT_EQ(0U, m_flush_handler.flushes);
+
+ future1->safe(0);
+}
+
+TEST_F(TestFutureImpl, FlushAlreadyComplete) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future = create_future(234, 123, 456);
+ future->safe(-EIO);
+
+ C_SaferCond cond;
+ future->flush(&cond);
+ ASSERT_EQ(-EIO, cond.wait());
+}
+
+TEST_F(TestFutureImpl, Wait) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future = create_future(234, 1, 456);
+
+ C_SaferCond cond;
+ future->wait(&cond);
+ future->safe(-EEXIST);
+ ASSERT_EQ(-EEXIST, cond.wait());
+}
+
+TEST_F(TestFutureImpl, WaitAlreadyComplete) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future = create_future(234, 1, 456);
+ future->safe(-EEXIST);
+
+ C_SaferCond cond;
+ future->wait(&cond);
+ ASSERT_EQ(-EEXIST, cond.wait());
+}
+
+TEST_F(TestFutureImpl, SafePreservesError) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future1 = create_future(234, 123, 456);
+ journal::FutureImplPtr future2 = create_future(234, 124, 457,
+ future1);
+
+ future1->safe(-EIO);
+ future2->safe(-EEXIST);
+ ASSERT_TRUE(future2->is_complete());
+ ASSERT_EQ(-EIO, future2->get_return_value());
+}
+
+TEST_F(TestFutureImpl, ConsistentPreservesError) {
+ std::string oid = get_temp_oid();
+ ASSERT_EQ(0, create(oid));
+ ASSERT_EQ(0, client_register(oid));
+ journal::JournalMetadataPtr metadata = create_metadata(oid);
+ ASSERT_EQ(0, init_metadata(metadata));
+
+ journal::FutureImplPtr future1 = create_future(234, 123, 456);
+ journal::FutureImplPtr future2 = create_future(234, 124, 457,
+ future1);
+
+ future2->safe(-EEXIST);
+ future1->safe(-EIO);
+ ASSERT_TRUE(future2->is_complete());
+ ASSERT_EQ(-EEXIST, future2->get_return_value());
+}