Summary: Add two unit tests for SyncWAL(). One makes sure SyncWAL() doesn't block writes in the other thread. Another one makes sure SyncWAL() doesn't wait ongoing writes to finish before being executed. Create a new test file db_wal_test and move two WAL related tests from db_test to here. Test Plan: Run the new tests Reviewers: IslamAbdelRahman, rven, kradhakrishnan, kolmike, tnovak, yhchiang Reviewed By: yhchiang Subscribers: leveldb, dhruba Differential Revision: https://reviews.facebook.net/D43605main
parent
3ae386eafe
commit
7ccd1c80a7
@ -0,0 +1,144 @@ |
||||
// Copyright (c) 2013, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||
|
||||
#include "port/stack_trace.h" |
||||
#include "util/db_test_util.h" |
||||
#if !(defined NDEBUG) || !defined(OS_WIN) |
||||
#include "util/sync_point.h" |
||||
#endif |
||||
|
||||
namespace rocksdb { |
||||
class DBWALTest : public DBTestBase { |
||||
public: |
||||
DBWALTest() : DBTestBase("/db_wal_test") {} |
||||
}; |
||||
|
||||
TEST_F(DBWALTest, WAL) { |
||||
do { |
||||
CreateAndReopenWithCF({"pikachu"}, CurrentOptions()); |
||||
WriteOptions writeOpt = WriteOptions(); |
||||
writeOpt.disableWAL = true; |
||||
ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "foo", "v1")); |
||||
ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "bar", "v1")); |
||||
|
||||
ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions()); |
||||
ASSERT_EQ("v1", Get(1, "foo")); |
||||
ASSERT_EQ("v1", Get(1, "bar")); |
||||
|
||||
writeOpt.disableWAL = false; |
||||
ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "bar", "v2")); |
||||
writeOpt.disableWAL = true; |
||||
ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "foo", "v2")); |
||||
|
||||
ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions()); |
||||
// Both value's should be present.
|
||||
ASSERT_EQ("v2", Get(1, "bar")); |
||||
ASSERT_EQ("v2", Get(1, "foo")); |
||||
|
||||
writeOpt.disableWAL = true; |
||||
ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "bar", "v3")); |
||||
writeOpt.disableWAL = false; |
||||
ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "foo", "v3")); |
||||
|
||||
ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions()); |
||||
// again both values should be present.
|
||||
ASSERT_EQ("v3", Get(1, "foo")); |
||||
ASSERT_EQ("v3", Get(1, "bar")); |
||||
} while (ChangeCompactOptions()); |
||||
} |
||||
|
||||
TEST_F(DBWALTest, RollLog) { |
||||
do { |
||||
CreateAndReopenWithCF({"pikachu"}, CurrentOptions()); |
||||
ASSERT_OK(Put(1, "foo", "v1")); |
||||
ASSERT_OK(Put(1, "baz", "v5")); |
||||
|
||||
ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions()); |
||||
for (int i = 0; i < 10; i++) { |
||||
ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions()); |
||||
} |
||||
ASSERT_OK(Put(1, "foo", "v4")); |
||||
for (int i = 0; i < 10; i++) { |
||||
ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions()); |
||||
} |
||||
} while (ChangeOptions()); |
||||
} |
||||
|
||||
#if !(defined NDEBUG) || !defined(OS_WIN) |
||||
TEST_F(DBWALTest, SyncWALNotBlockWrite) { |
||||
Options options = CurrentOptions(); |
||||
options.max_write_buffer_number = 4; |
||||
DestroyAndReopen(options); |
||||
|
||||
ASSERT_OK(Put("foo1", "bar1")); |
||||
ASSERT_OK(Put("foo5", "bar5")); |
||||
|
||||
rocksdb::SyncPoint::GetInstance()->LoadDependency({ |
||||
{"WritableFileWriter::SyncWithoutFlush:1", |
||||
"DBWALTest::SyncWALNotBlockWrite:1"}, |
||||
{"DBWALTest::SyncWALNotBlockWrite:2", |
||||
"WritableFileWriter::SyncWithoutFlush:2"}, |
||||
}); |
||||
rocksdb::SyncPoint::GetInstance()->EnableProcessing(); |
||||
|
||||
std::thread thread([&]() { ASSERT_OK(db_->SyncWAL()); }); |
||||
|
||||
TEST_SYNC_POINT("DBWALTest::SyncWALNotBlockWrite:1"); |
||||
ASSERT_OK(Put("foo2", "bar2")); |
||||
ASSERT_OK(Put("foo3", "bar3")); |
||||
FlushOptions fo; |
||||
fo.wait = false; |
||||
ASSERT_OK(db_->Flush(fo)); |
||||
ASSERT_OK(Put("foo4", "bar4")); |
||||
|
||||
TEST_SYNC_POINT("DBWALTest::SyncWALNotBlockWrite:2"); |
||||
|
||||
thread.join(); |
||||
|
||||
ASSERT_EQ(Get("foo1"), "bar1"); |
||||
ASSERT_EQ(Get("foo2"), "bar2"); |
||||
ASSERT_EQ(Get("foo3"), "bar3"); |
||||
ASSERT_EQ(Get("foo4"), "bar4"); |
||||
ASSERT_EQ(Get("foo5"), "bar5"); |
||||
rocksdb::SyncPoint::GetInstance()->DisableProcessing(); |
||||
} |
||||
|
||||
TEST_F(DBWALTest, SyncWALNotWaitWrite) { |
||||
ASSERT_OK(Put("foo1", "bar1")); |
||||
ASSERT_OK(Put("foo3", "bar3")); |
||||
|
||||
rocksdb::SyncPoint::GetInstance()->LoadDependency({ |
||||
{"SpecialEnv::WalFile::Append:1", "DBWALTest::SyncWALNotWaitWrite:1"}, |
||||
{"DBWALTest::SyncWALNotWaitWrite:2", "SpecialEnv::WalFile::Append:2"}, |
||||
}); |
||||
rocksdb::SyncPoint::GetInstance()->EnableProcessing(); |
||||
|
||||
std::thread thread([&]() { ASSERT_OK(Put("foo2", "bar2")); }); |
||||
TEST_SYNC_POINT("DBWALTest::SyncWALNotWaitWrite:1"); |
||||
ASSERT_OK(db_->SyncWAL()); |
||||
TEST_SYNC_POINT("DBWALTest::SyncWALNotWaitWrite:2"); |
||||
|
||||
thread.join(); |
||||
|
||||
ASSERT_EQ(Get("foo1"), "bar1"); |
||||
ASSERT_EQ(Get("foo2"), "bar2"); |
||||
rocksdb::SyncPoint::GetInstance()->DisableProcessing(); |
||||
} |
||||
#endif |
||||
} // namespace rocksdb
|
||||
|
||||
int main(int argc, char** argv) { |
||||
#if !(defined NDEBUG) || !defined(OS_WIN) |
||||
rocksdb::port::InstallStackTraceHandler(); |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
return RUN_ALL_TESTS(); |
||||
#else |
||||
return 0; |
||||
#endif |
||||
} |
Loading…
Reference in new issue