Switch testing harness to googletest.

PiperOrigin-RevId: 281815695
This commit is contained in:
Victor Costan 2019-11-21 13:09:53 -08:00 committed by Victor Costan
parent 2c9c80bd53
commit 1c58902bdc
37 changed files with 763 additions and 863 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "third_party/googletest"]
path = third_party/googletest
url = https://github.com/google/googletest.git

View File

@ -84,6 +84,10 @@ endif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-Wthread-safety HAVE_CLANG_THREAD_SAFETY) check_cxx_compiler_flag(-Wthread-safety HAVE_CLANG_THREAD_SAFETY)
# Used by googletest.
check_cxx_compiler_flag(-Wno-missing-field-initializers
LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS)
include(CheckCXXSourceCompiles) include(CheckCXXSourceCompiles)
# Test whether C++17 __has_include is available. # Test whether C++17 __has_include is available.
@ -288,6 +292,23 @@ target_link_libraries(leveldbutil leveldb)
if(LEVELDB_BUILD_TESTS) if(LEVELDB_BUILD_TESTS)
enable_testing() enable_testing()
# Prevent overriding the parent project's compiler/linker settings on Windows.
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
set(install_gtest OFF)
set(install_gmock OFF)
set(build_gmock ON)
# This project is tested using GoogleTest.
add_subdirectory("third_party/googletest")
# GoogleTest triggers a missing field initializers warning.
if(LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS)
set_property(TARGET gtest
APPEND PROPERTY COMPILE_OPTIONS -Wno-missing-field-initializers)
set_property(TARGET gmock
APPEND PROPERTY COMPILE_OPTIONS -Wno-missing-field-initializers)
endif(LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS)
function(leveldb_test test_file) function(leveldb_test test_file)
get_filename_component(test_target_name "${test_file}" NAME_WE) get_filename_component(test_target_name "${test_file}" NAME_WE)
@ -295,14 +316,12 @@ if(LEVELDB_BUILD_TESTS)
target_sources("${test_target_name}" target_sources("${test_target_name}"
PRIVATE PRIVATE
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h" "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
"util/testharness.cc"
"util/testharness.h"
"util/testutil.cc" "util/testutil.cc"
"util/testutil.h" "util/testutil.h"
"${test_file}" "${test_file}"
) )
target_link_libraries("${test_target_name}" leveldb) target_link_libraries("${test_target_name}" leveldb gmock gtest)
target_compile_definitions("${test_target_name}" target_compile_definitions("${test_target_name}"
PRIVATE PRIVATE
${LEVELDB_PLATFORM_NAME}=1 ${LEVELDB_PLATFORM_NAME}=1
@ -374,14 +393,12 @@ if(LEVELDB_BUILD_BENCHMARKS)
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h" "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
"util/histogram.cc" "util/histogram.cc"
"util/histogram.h" "util/histogram.h"
"util/testharness.cc"
"util/testharness.h"
"util/testutil.cc" "util/testutil.cc"
"util/testutil.h" "util/testutil.h"
"${bench_file}" "${bench_file}"
) )
target_link_libraries("${bench_target_name}" leveldb) target_link_libraries("${bench_target_name}" leveldb gmock gtest)
target_compile_definitions("${bench_target_name}" target_compile_definitions("${bench_target_name}"
PRIVATE PRIVATE
${LEVELDB_PLATFORM_NAME}=1 ${LEVELDB_PLATFORM_NAME}=1

View File

@ -27,6 +27,12 @@ Authors: Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com)
* Only a single process (possibly multi-threaded) can access a particular database at a time. * Only a single process (possibly multi-threaded) can access a particular database at a time.
* There is no client-server support builtin to the library. An application that needs such support will have to wrap their own server around the library. * There is no client-server support builtin to the library. An application that needs such support will have to wrap their own server around the library.
# Getting the Source
```bash
git clone --recurse-submodules https://github.com/google/leveldb.git
```
# Building # Building
This project supports [CMake](https://cmake.org/) out of the box. This project supports [CMake](https://cmake.org/) out of the box.

View File

@ -2,24 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be // 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. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/db_impl.h" #include "db/db_impl.h"
#include "leveldb/cache.h" #include "leveldb/cache.h"
#include "leveldb/db.h" #include "leveldb/db.h"
#include "util/testharness.h"
#include "util/testutil.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
class AutoCompactTest { class AutoCompactTest : public testing::Test {
public: public:
AutoCompactTest() { AutoCompactTest() {
dbname_ = test::TmpDir() + "/autocompact_test"; dbname_ = testing::TempDir() + "autocompact_test";
tiny_cache_ = NewLRUCache(100); tiny_cache_ = NewLRUCache(100);
options_.block_cache = tiny_cache_; options_.block_cache = tiny_cache_;
DestroyDB(dbname_, options_); DestroyDB(dbname_, options_);
options_.create_if_missing = true; options_.create_if_missing = true;
options_.compression = kNoCompression; options_.compression = kNoCompression;
ASSERT_OK(DB::Open(options_, dbname_, &db_)); EXPECT_LEVELDB_OK(DB::Open(options_, dbname_, &db_));
} }
~AutoCompactTest() { ~AutoCompactTest() {
@ -62,15 +62,15 @@ void AutoCompactTest::DoReads(int n) {
// Fill database // Fill database
for (int i = 0; i < kCount; i++) { for (int i = 0; i < kCount; i++) {
ASSERT_OK(db_->Put(WriteOptions(), Key(i), value)); ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), Key(i), value));
} }
ASSERT_OK(dbi->TEST_CompactMemTable()); ASSERT_LEVELDB_OK(dbi->TEST_CompactMemTable());
// Delete everything // Delete everything
for (int i = 0; i < kCount; i++) { for (int i = 0; i < kCount; i++) {
ASSERT_OK(db_->Delete(WriteOptions(), Key(i))); ASSERT_LEVELDB_OK(db_->Delete(WriteOptions(), Key(i)));
} }
ASSERT_OK(dbi->TEST_CompactMemTable()); ASSERT_LEVELDB_OK(dbi->TEST_CompactMemTable());
// Get initial measurement of the space we will be reading. // Get initial measurement of the space we will be reading.
const int64_t initial_size = Size(Key(0), Key(n)); const int64_t initial_size = Size(Key(0), Key(n));
@ -103,10 +103,13 @@ void AutoCompactTest::DoReads(int n) {
ASSERT_GE(final_other_size, initial_other_size / 5 - 1048576); ASSERT_GE(final_other_size, initial_other_size / 5 - 1048576);
} }
TEST(AutoCompactTest, ReadAll) { DoReads(kCount); } TEST_F(AutoCompactTest, ReadAll) { DoReads(kCount); }
TEST(AutoCompactTest, ReadHalf) { DoReads(kCount / 2); } TEST_F(AutoCompactTest, ReadHalf) { DoReads(kCount / 2); }
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -4,6 +4,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/db_impl.h" #include "db/db_impl.h"
#include "db/filename.h" #include "db/filename.h"
#include "db/log_format.h" #include "db/log_format.h"
@ -13,14 +14,13 @@
#include "leveldb/table.h" #include "leveldb/table.h"
#include "leveldb/write_batch.h" #include "leveldb/write_batch.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/testharness.h"
#include "util/testutil.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
static const int kValueSize = 1000; static const int kValueSize = 1000;
class CorruptionTest { class CorruptionTest : public testing::Test {
public: public:
CorruptionTest() CorruptionTest()
: db_(nullptr), : db_(nullptr),
@ -46,12 +46,12 @@ class CorruptionTest {
return DB::Open(options_, dbname_, &db_); return DB::Open(options_, dbname_, &db_);
} }
void Reopen() { ASSERT_OK(TryReopen()); } void Reopen() { ASSERT_LEVELDB_OK(TryReopen()); }
void RepairDB() { void RepairDB() {
delete db_; delete db_;
db_ = nullptr; db_ = nullptr;
ASSERT_OK(::leveldb::RepairDB(dbname_, options_)); ASSERT_LEVELDB_OK(::leveldb::RepairDB(dbname_, options_));
} }
void Build(int n) { void Build(int n) {
@ -68,7 +68,7 @@ class CorruptionTest {
if (i == n - 1) { if (i == n - 1) {
options.sync = true; options.sync = true;
} }
ASSERT_OK(db_->Write(options, &batch)); ASSERT_LEVELDB_OK(db_->Write(options, &batch));
} }
} }
@ -112,7 +112,7 @@ class CorruptionTest {
void Corrupt(FileType filetype, int offset, int bytes_to_corrupt) { void Corrupt(FileType filetype, int offset, int bytes_to_corrupt) {
// Pick file to corrupt // Pick file to corrupt
std::vector<std::string> filenames; std::vector<std::string> filenames;
ASSERT_OK(env_.target()->GetChildren(dbname_, &filenames)); ASSERT_LEVELDB_OK(env_.target()->GetChildren(dbname_, &filenames));
uint64_t number; uint64_t number;
FileType type; FileType type;
std::string fname; std::string fname;
@ -127,7 +127,7 @@ class CorruptionTest {
ASSERT_TRUE(!fname.empty()) << filetype; ASSERT_TRUE(!fname.empty()) << filetype;
uint64_t file_size; uint64_t file_size;
ASSERT_OK(env_.target()->GetFileSize(fname, &file_size)); ASSERT_LEVELDB_OK(env_.target()->GetFileSize(fname, &file_size));
if (offset < 0) { if (offset < 0) {
// Relative to end of file; make it absolute // Relative to end of file; make it absolute
@ -189,7 +189,7 @@ class CorruptionTest {
Cache* tiny_cache_; Cache* tiny_cache_;
}; };
TEST(CorruptionTest, Recovery) { TEST_F(CorruptionTest, Recovery) {
Build(100); Build(100);
Check(100, 100); Check(100, 100);
Corrupt(kLogFile, 19, 1); // WriteBatch tag for first record Corrupt(kLogFile, 19, 1); // WriteBatch tag for first record
@ -200,13 +200,13 @@ TEST(CorruptionTest, Recovery) {
Check(36, 36); Check(36, 36);
} }
TEST(CorruptionTest, RecoverWriteError) { TEST_F(CorruptionTest, RecoverWriteError) {
env_.writable_file_error_ = true; env_.writable_file_error_ = true;
Status s = TryReopen(); Status s = TryReopen();
ASSERT_TRUE(!s.ok()); ASSERT_TRUE(!s.ok());
} }
TEST(CorruptionTest, NewFileErrorDuringWrite) { TEST_F(CorruptionTest, NewFileErrorDuringWrite) {
// Do enough writing to force minor compaction // Do enough writing to force minor compaction
env_.writable_file_error_ = true; env_.writable_file_error_ = true;
const int num = 3 + (Options().write_buffer_size / kValueSize); const int num = 3 + (Options().write_buffer_size / kValueSize);
@ -223,7 +223,7 @@ TEST(CorruptionTest, NewFileErrorDuringWrite) {
Reopen(); Reopen();
} }
TEST(CorruptionTest, TableFile) { TEST_F(CorruptionTest, TableFile) {
Build(100); Build(100);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_CompactMemTable(); dbi->TEST_CompactMemTable();
@ -234,7 +234,7 @@ TEST(CorruptionTest, TableFile) {
Check(90, 99); Check(90, 99);
} }
TEST(CorruptionTest, TableFileRepair) { TEST_F(CorruptionTest, TableFileRepair) {
options_.block_size = 2 * kValueSize; // Limit scope of corruption options_.block_size = 2 * kValueSize; // Limit scope of corruption
options_.paranoid_checks = true; options_.paranoid_checks = true;
Reopen(); Reopen();
@ -250,7 +250,7 @@ TEST(CorruptionTest, TableFileRepair) {
Check(95, 99); Check(95, 99);
} }
TEST(CorruptionTest, TableFileIndexData) { TEST_F(CorruptionTest, TableFileIndexData) {
Build(10000); // Enough to build multiple Tables Build(10000); // Enough to build multiple Tables
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_CompactMemTable(); dbi->TEST_CompactMemTable();
@ -260,36 +260,36 @@ TEST(CorruptionTest, TableFileIndexData) {
Check(5000, 9999); Check(5000, 9999);
} }
TEST(CorruptionTest, MissingDescriptor) { TEST_F(CorruptionTest, MissingDescriptor) {
Build(1000); Build(1000);
RepairDB(); RepairDB();
Reopen(); Reopen();
Check(1000, 1000); Check(1000, 1000);
} }
TEST(CorruptionTest, SequenceNumberRecovery) { TEST_F(CorruptionTest, SequenceNumberRecovery) {
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v1")); ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v1"));
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v2")); ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v2"));
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v3")); ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v3"));
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v4")); ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v4"));
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v5")); ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v5"));
RepairDB(); RepairDB();
Reopen(); Reopen();
std::string v; std::string v;
ASSERT_OK(db_->Get(ReadOptions(), "foo", &v)); ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), "foo", &v));
ASSERT_EQ("v5", v); ASSERT_EQ("v5", v);
// Write something. If sequence number was not recovered properly, // Write something. If sequence number was not recovered properly,
// it will be hidden by an earlier write. // it will be hidden by an earlier write.
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v6")); ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v6"));
ASSERT_OK(db_->Get(ReadOptions(), "foo", &v)); ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), "foo", &v));
ASSERT_EQ("v6", v); ASSERT_EQ("v6", v);
Reopen(); Reopen();
ASSERT_OK(db_->Get(ReadOptions(), "foo", &v)); ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), "foo", &v));
ASSERT_EQ("v6", v); ASSERT_EQ("v6", v);
} }
TEST(CorruptionTest, CorruptedDescriptor) { TEST_F(CorruptionTest, CorruptedDescriptor) {
ASSERT_OK(db_->Put(WriteOptions(), "foo", "hello")); ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "hello"));
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_CompactMemTable(); dbi->TEST_CompactMemTable();
dbi->TEST_CompactRange(0, nullptr, nullptr); dbi->TEST_CompactRange(0, nullptr, nullptr);
@ -301,11 +301,11 @@ TEST(CorruptionTest, CorruptedDescriptor) {
RepairDB(); RepairDB();
Reopen(); Reopen();
std::string v; std::string v;
ASSERT_OK(db_->Get(ReadOptions(), "foo", &v)); ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), "foo", &v));
ASSERT_EQ("hello", v); ASSERT_EQ("hello", v);
} }
TEST(CorruptionTest, CompactionInputError) { TEST_F(CorruptionTest, CompactionInputError) {
Build(10); Build(10);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_CompactMemTable(); dbi->TEST_CompactMemTable();
@ -320,7 +320,7 @@ TEST(CorruptionTest, CompactionInputError) {
Check(10000, 10000); Check(10000, 10000);
} }
TEST(CorruptionTest, CompactionInputErrorParanoid) { TEST_F(CorruptionTest, CompactionInputErrorParanoid) {
options_.paranoid_checks = true; options_.paranoid_checks = true;
options_.write_buffer_size = 512 << 10; options_.write_buffer_size = 512 << 10;
Reopen(); Reopen();
@ -341,22 +341,26 @@ TEST(CorruptionTest, CompactionInputErrorParanoid) {
ASSERT_TRUE(!s.ok()) << "write did not fail in corrupted paranoid db"; ASSERT_TRUE(!s.ok()) << "write did not fail in corrupted paranoid db";
} }
TEST(CorruptionTest, UnrelatedKeys) { TEST_F(CorruptionTest, UnrelatedKeys) {
Build(10); Build(10);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_CompactMemTable(); dbi->TEST_CompactMemTable();
Corrupt(kTableFile, 100, 1); Corrupt(kTableFile, 100, 1);
std::string tmp1, tmp2; std::string tmp1, tmp2;
ASSERT_OK(db_->Put(WriteOptions(), Key(1000, &tmp1), Value(1000, &tmp2))); ASSERT_LEVELDB_OK(
db_->Put(WriteOptions(), Key(1000, &tmp1), Value(1000, &tmp2)));
std::string v; std::string v;
ASSERT_OK(db_->Get(ReadOptions(), Key(1000, &tmp1), &v)); ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), Key(1000, &tmp1), &v));
ASSERT_EQ(Value(1000, &tmp2).ToString(), v); ASSERT_EQ(Value(1000, &tmp2).ToString(), v);
dbi->TEST_CompactMemTable(); dbi->TEST_CompactMemTable();
ASSERT_OK(db_->Get(ReadOptions(), Key(1000, &tmp1), &v)); ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), Key(1000, &tmp1), &v));
ASSERT_EQ(Value(1000, &tmp2).ToString(), v); ASSERT_EQ(Value(1000, &tmp2).ToString(), v);
} }
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,9 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/dbformat.h" #include "db/dbformat.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/testharness.h"
namespace leveldb { namespace leveldb {
@ -41,8 +42,6 @@ static void TestKey(const std::string& key, uint64_t seq, ValueType vt) {
ASSERT_TRUE(!ParseInternalKey(Slice("bar"), &decoded)); ASSERT_TRUE(!ParseInternalKey(Slice("bar"), &decoded));
} }
class FormatTest {};
TEST(FormatTest, InternalKey_EncodeDecode) { TEST(FormatTest, InternalKey_EncodeDecode) {
const char* keys[] = {"", "k", "hello", "longggggggggggggggggggggg"}; const char* keys[] = {"", "k", "hello", "longggggggggggggggggggggg"};
const uint64_t seq[] = {1, const uint64_t seq[] = {1,
@ -128,4 +127,7 @@ TEST(FormatTest, InternalKeyDebugString) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -9,6 +9,7 @@
#include <map> #include <map>
#include <set> #include <set>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/db_impl.h" #include "db/db_impl.h"
#include "db/filename.h" #include "db/filename.h"
#include "db/log_format.h" #include "db/log_format.h"
@ -22,7 +23,6 @@
#include "port/thread_annotations.h" #include "port/thread_annotations.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/mutexlock.h" #include "util/mutexlock.h"
#include "util/testharness.h"
#include "util/testutil.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
@ -300,7 +300,7 @@ void FaultInjectionTestEnv::UntrackFile(const std::string& f) {
Status FaultInjectionTestEnv::DeleteFile(const std::string& f) { Status FaultInjectionTestEnv::DeleteFile(const std::string& f) {
Status s = EnvWrapper::DeleteFile(f); Status s = EnvWrapper::DeleteFile(f);
ASSERT_OK(s); EXPECT_LEVELDB_OK(s);
if (s.ok()) { if (s.ok()) {
UntrackFile(f); UntrackFile(f);
} }
@ -361,7 +361,7 @@ Status FileState::DropUnsyncedData() const {
return Truncate(filename_, sync_pos); return Truncate(filename_, sync_pos);
} }
class FaultInjectionTest { class FaultInjectionTest : public testing::Test {
public: public:
enum ExpectedVerifResult { VAL_EXPECT_NO_ERROR, VAL_EXPECT_ERROR }; enum ExpectedVerifResult { VAL_EXPECT_NO_ERROR, VAL_EXPECT_ERROR };
enum ResetMethod { RESET_DROP_UNSYNCED_DATA, RESET_DELETE_UNSYNCED_FILES }; enum ResetMethod { RESET_DROP_UNSYNCED_DATA, RESET_DELETE_UNSYNCED_FILES };
@ -376,7 +376,7 @@ class FaultInjectionTest {
: env_(new FaultInjectionTestEnv), : env_(new FaultInjectionTestEnv),
tiny_cache_(NewLRUCache(100)), tiny_cache_(NewLRUCache(100)),
db_(nullptr) { db_(nullptr) {
dbname_ = test::TmpDir() + "/fault_test"; dbname_ = testing::TempDir() + "fault_test";
DestroyDB(dbname_, Options()); // Destroy any db from earlier run DestroyDB(dbname_, Options()); // Destroy any db from earlier run
options_.reuse_logs = true; options_.reuse_logs = true;
options_.env = env_; options_.env = env_;
@ -402,7 +402,7 @@ class FaultInjectionTest {
batch.Clear(); batch.Clear();
batch.Put(key, Value(i, &value_space)); batch.Put(key, Value(i, &value_space));
WriteOptions options; WriteOptions options;
ASSERT_OK(db_->Write(options, &batch)); ASSERT_LEVELDB_OK(db_->Write(options, &batch));
} }
} }
@ -424,7 +424,7 @@ class FaultInjectionTest {
s = ReadValue(i, &val); s = ReadValue(i, &val);
if (expected == VAL_EXPECT_NO_ERROR) { if (expected == VAL_EXPECT_NO_ERROR) {
if (s.ok()) { if (s.ok()) {
ASSERT_EQ(value_space, val); EXPECT_EQ(value_space, val);
} }
} else if (s.ok()) { } else if (s.ok()) {
fprintf(stderr, "Expected an error at %d, but was OK\n", i); fprintf(stderr, "Expected an error at %d, but was OK\n", i);
@ -465,7 +465,7 @@ class FaultInjectionTest {
void DeleteAllData() { void DeleteAllData() {
Iterator* iter = db_->NewIterator(ReadOptions()); Iterator* iter = db_->NewIterator(ReadOptions());
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
ASSERT_OK(db_->Delete(WriteOptions(), iter->key())); ASSERT_LEVELDB_OK(db_->Delete(WriteOptions(), iter->key()));
} }
delete iter; delete iter;
@ -474,10 +474,10 @@ class FaultInjectionTest {
void ResetDBState(ResetMethod reset_method) { void ResetDBState(ResetMethod reset_method) {
switch (reset_method) { switch (reset_method) {
case RESET_DROP_UNSYNCED_DATA: case RESET_DROP_UNSYNCED_DATA:
ASSERT_OK(env_->DropUnsyncedFileData()); ASSERT_LEVELDB_OK(env_->DropUnsyncedFileData());
break; break;
case RESET_DELETE_UNSYNCED_FILES: case RESET_DELETE_UNSYNCED_FILES:
ASSERT_OK(env_->DeleteFilesCreatedAfterLastDirSync()); ASSERT_LEVELDB_OK(env_->DeleteFilesCreatedAfterLastDirSync());
break; break;
default: default:
assert(false); assert(false);
@ -496,9 +496,10 @@ class FaultInjectionTest {
env_->SetFilesystemActive(false); env_->SetFilesystemActive(false);
CloseDB(); CloseDB();
ResetDBState(reset_method); ResetDBState(reset_method);
ASSERT_OK(OpenDB()); ASSERT_LEVELDB_OK(OpenDB());
ASSERT_OK(Verify(0, num_pre_sync, FaultInjectionTest::VAL_EXPECT_NO_ERROR)); ASSERT_LEVELDB_OK(
ASSERT_OK(Verify(num_pre_sync, num_post_sync, Verify(0, num_pre_sync, FaultInjectionTest::VAL_EXPECT_NO_ERROR));
ASSERT_LEVELDB_OK(Verify(num_pre_sync, num_post_sync,
FaultInjectionTest::VAL_EXPECT_ERROR)); FaultInjectionTest::VAL_EXPECT_ERROR));
} }
@ -507,12 +508,12 @@ class FaultInjectionTest {
void NoWriteTestReopenWithFault(ResetMethod reset_method) { void NoWriteTestReopenWithFault(ResetMethod reset_method) {
CloseDB(); CloseDB();
ResetDBState(reset_method); ResetDBState(reset_method);
ASSERT_OK(OpenDB()); ASSERT_LEVELDB_OK(OpenDB());
} }
void DoTest() { void DoTest() {
Random rnd(0); Random rnd(0);
ASSERT_OK(OpenDB()); ASSERT_LEVELDB_OK(OpenDB());
for (size_t idx = 0; idx < kNumIterations; idx++) { for (size_t idx = 0; idx < kNumIterations; idx++) {
int num_pre_sync = rnd.Uniform(kMaxNumValues); int num_pre_sync = rnd.Uniform(kMaxNumValues);
int num_post_sync = rnd.Uniform(kMaxNumValues); int num_post_sync = rnd.Uniform(kMaxNumValues);
@ -536,16 +537,19 @@ class FaultInjectionTest {
} }
}; };
TEST(FaultInjectionTest, FaultTestNoLogReuse) { TEST_F(FaultInjectionTest, FaultTestNoLogReuse) {
ReuseLogs(false); ReuseLogs(false);
DoTest(); DoTest();
} }
TEST(FaultInjectionTest, FaultTestWithLogReuse) { TEST_F(FaultInjectionTest, FaultTestWithLogReuse) {
ReuseLogs(true); ReuseLogs(true);
DoTest(); DoTest();
} }
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -4,15 +4,13 @@
#include "db/filename.h" #include "db/filename.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/dbformat.h" #include "db/dbformat.h"
#include "port/port.h" #include "port/port.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/testharness.h"
namespace leveldb { namespace leveldb {
class FileNameTest {};
TEST(FileNameTest, Parse) { TEST(FileNameTest, Parse) {
Slice db; Slice db;
FileType type; FileType type;
@ -128,4 +126,7 @@ TEST(FileNameTest, Construction) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // 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. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/log_reader.h" #include "db/log_reader.h"
#include "db/log_writer.h" #include "db/log_writer.h"
#include "leveldb/env.h" #include "leveldb/env.h"
#include "util/coding.h" #include "util/coding.h"
#include "util/crc32c.h" #include "util/crc32c.h"
#include "util/random.h" #include "util/random.h"
#include "util/testharness.h"
namespace leveldb { namespace leveldb {
namespace log { namespace log {
@ -36,7 +36,7 @@ static std::string RandomSkewedString(int i, Random* rnd) {
return BigString(NumberString(i), rnd->Skewed(17)); return BigString(NumberString(i), rnd->Skewed(17));
} }
class LogTest { class LogTest : public testing::Test {
public: public:
LogTest() LogTest()
: reading_(false), : reading_(false),
@ -177,7 +177,7 @@ class LogTest {
StringSource() : force_error_(false), returned_partial_(false) {} StringSource() : force_error_(false), returned_partial_(false) {}
Status Read(size_t n, Slice* result, char* scratch) override { Status Read(size_t n, Slice* result, char* scratch) override {
ASSERT_TRUE(!returned_partial_) << "must not Read() after eof/error"; EXPECT_TRUE(!returned_partial_) << "must not Read() after eof/error";
if (force_error_) { if (force_error_) {
force_error_ = false; force_error_ = false;
@ -258,9 +258,9 @@ uint64_t LogTest::initial_offset_last_record_offsets_[] = {
int LogTest::num_initial_offset_records_ = int LogTest::num_initial_offset_records_ =
sizeof(LogTest::initial_offset_last_record_offsets_) / sizeof(uint64_t); sizeof(LogTest::initial_offset_last_record_offsets_) / sizeof(uint64_t);
TEST(LogTest, Empty) { ASSERT_EQ("EOF", Read()); } TEST_F(LogTest, Empty) { ASSERT_EQ("EOF", Read()); }
TEST(LogTest, ReadWrite) { TEST_F(LogTest, ReadWrite) {
Write("foo"); Write("foo");
Write("bar"); Write("bar");
Write(""); Write("");
@ -273,7 +273,7 @@ TEST(LogTest, ReadWrite) {
ASSERT_EQ("EOF", Read()); // Make sure reads at eof work ASSERT_EQ("EOF", Read()); // Make sure reads at eof work
} }
TEST(LogTest, ManyBlocks) { TEST_F(LogTest, ManyBlocks) {
for (int i = 0; i < 100000; i++) { for (int i = 0; i < 100000; i++) {
Write(NumberString(i)); Write(NumberString(i));
} }
@ -283,7 +283,7 @@ TEST(LogTest, ManyBlocks) {
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
} }
TEST(LogTest, Fragmentation) { TEST_F(LogTest, Fragmentation) {
Write("small"); Write("small");
Write(BigString("medium", 50000)); Write(BigString("medium", 50000));
Write(BigString("large", 100000)); Write(BigString("large", 100000));
@ -293,7 +293,7 @@ TEST(LogTest, Fragmentation) {
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
} }
TEST(LogTest, MarginalTrailer) { TEST_F(LogTest, MarginalTrailer) {
// Make a trailer that is exactly the same length as an empty record. // Make a trailer that is exactly the same length as an empty record.
const int n = kBlockSize - 2 * kHeaderSize; const int n = kBlockSize - 2 * kHeaderSize;
Write(BigString("foo", n)); Write(BigString("foo", n));
@ -306,7 +306,7 @@ TEST(LogTest, MarginalTrailer) {
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
} }
TEST(LogTest, MarginalTrailer2) { TEST_F(LogTest, MarginalTrailer2) {
// Make a trailer that is exactly the same length as an empty record. // Make a trailer that is exactly the same length as an empty record.
const int n = kBlockSize - 2 * kHeaderSize; const int n = kBlockSize - 2 * kHeaderSize;
Write(BigString("foo", n)); Write(BigString("foo", n));
@ -319,7 +319,7 @@ TEST(LogTest, MarginalTrailer2) {
ASSERT_EQ("", ReportMessage()); ASSERT_EQ("", ReportMessage());
} }
TEST(LogTest, ShortTrailer) { TEST_F(LogTest, ShortTrailer) {
const int n = kBlockSize - 2 * kHeaderSize + 4; const int n = kBlockSize - 2 * kHeaderSize + 4;
Write(BigString("foo", n)); Write(BigString("foo", n));
ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes()); ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
@ -331,7 +331,7 @@ TEST(LogTest, ShortTrailer) {
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
} }
TEST(LogTest, AlignedEof) { TEST_F(LogTest, AlignedEof) {
const int n = kBlockSize - 2 * kHeaderSize + 4; const int n = kBlockSize - 2 * kHeaderSize + 4;
Write(BigString("foo", n)); Write(BigString("foo", n));
ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes()); ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
@ -339,7 +339,7 @@ TEST(LogTest, AlignedEof) {
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
} }
TEST(LogTest, OpenForAppend) { TEST_F(LogTest, OpenForAppend) {
Write("hello"); Write("hello");
ReopenForAppend(); ReopenForAppend();
Write("world"); Write("world");
@ -348,7 +348,7 @@ TEST(LogTest, OpenForAppend) {
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
} }
TEST(LogTest, RandomRead) { TEST_F(LogTest, RandomRead) {
const int N = 500; const int N = 500;
Random write_rnd(301); Random write_rnd(301);
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
@ -363,7 +363,7 @@ TEST(LogTest, RandomRead) {
// Tests of all the error paths in log_reader.cc follow: // Tests of all the error paths in log_reader.cc follow:
TEST(LogTest, ReadError) { TEST_F(LogTest, ReadError) {
Write("foo"); Write("foo");
ForceError(); ForceError();
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
@ -371,7 +371,7 @@ TEST(LogTest, ReadError) {
ASSERT_EQ("OK", MatchError("read error")); ASSERT_EQ("OK", MatchError("read error"));
} }
TEST(LogTest, BadRecordType) { TEST_F(LogTest, BadRecordType) {
Write("foo"); Write("foo");
// Type is stored in header[6] // Type is stored in header[6]
IncrementByte(6, 100); IncrementByte(6, 100);
@ -381,7 +381,7 @@ TEST(LogTest, BadRecordType) {
ASSERT_EQ("OK", MatchError("unknown record type")); ASSERT_EQ("OK", MatchError("unknown record type"));
} }
TEST(LogTest, TruncatedTrailingRecordIsIgnored) { TEST_F(LogTest, TruncatedTrailingRecordIsIgnored) {
Write("foo"); Write("foo");
ShrinkSize(4); // Drop all payload as well as a header byte ShrinkSize(4); // Drop all payload as well as a header byte
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
@ -390,7 +390,7 @@ TEST(LogTest, TruncatedTrailingRecordIsIgnored) {
ASSERT_EQ("", ReportMessage()); ASSERT_EQ("", ReportMessage());
} }
TEST(LogTest, BadLength) { TEST_F(LogTest, BadLength) {
const int kPayloadSize = kBlockSize - kHeaderSize; const int kPayloadSize = kBlockSize - kHeaderSize;
Write(BigString("bar", kPayloadSize)); Write(BigString("bar", kPayloadSize));
Write("foo"); Write("foo");
@ -401,7 +401,7 @@ TEST(LogTest, BadLength) {
ASSERT_EQ("OK", MatchError("bad record length")); ASSERT_EQ("OK", MatchError("bad record length"));
} }
TEST(LogTest, BadLengthAtEndIsIgnored) { TEST_F(LogTest, BadLengthAtEndIsIgnored) {
Write("foo"); Write("foo");
ShrinkSize(1); ShrinkSize(1);
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
@ -409,7 +409,7 @@ TEST(LogTest, BadLengthAtEndIsIgnored) {
ASSERT_EQ("", ReportMessage()); ASSERT_EQ("", ReportMessage());
} }
TEST(LogTest, ChecksumMismatch) { TEST_F(LogTest, ChecksumMismatch) {
Write("foo"); Write("foo");
IncrementByte(0, 10); IncrementByte(0, 10);
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
@ -417,7 +417,7 @@ TEST(LogTest, ChecksumMismatch) {
ASSERT_EQ("OK", MatchError("checksum mismatch")); ASSERT_EQ("OK", MatchError("checksum mismatch"));
} }
TEST(LogTest, UnexpectedMiddleType) { TEST_F(LogTest, UnexpectedMiddleType) {
Write("foo"); Write("foo");
SetByte(6, kMiddleType); SetByte(6, kMiddleType);
FixChecksum(0, 3); FixChecksum(0, 3);
@ -426,7 +426,7 @@ TEST(LogTest, UnexpectedMiddleType) {
ASSERT_EQ("OK", MatchError("missing start")); ASSERT_EQ("OK", MatchError("missing start"));
} }
TEST(LogTest, UnexpectedLastType) { TEST_F(LogTest, UnexpectedLastType) {
Write("foo"); Write("foo");
SetByte(6, kLastType); SetByte(6, kLastType);
FixChecksum(0, 3); FixChecksum(0, 3);
@ -435,7 +435,7 @@ TEST(LogTest, UnexpectedLastType) {
ASSERT_EQ("OK", MatchError("missing start")); ASSERT_EQ("OK", MatchError("missing start"));
} }
TEST(LogTest, UnexpectedFullType) { TEST_F(LogTest, UnexpectedFullType) {
Write("foo"); Write("foo");
Write("bar"); Write("bar");
SetByte(6, kFirstType); SetByte(6, kFirstType);
@ -446,7 +446,7 @@ TEST(LogTest, UnexpectedFullType) {
ASSERT_EQ("OK", MatchError("partial record without end")); ASSERT_EQ("OK", MatchError("partial record without end"));
} }
TEST(LogTest, UnexpectedFirstType) { TEST_F(LogTest, UnexpectedFirstType) {
Write("foo"); Write("foo");
Write(BigString("bar", 100000)); Write(BigString("bar", 100000));
SetByte(6, kFirstType); SetByte(6, kFirstType);
@ -457,7 +457,7 @@ TEST(LogTest, UnexpectedFirstType) {
ASSERT_EQ("OK", MatchError("partial record without end")); ASSERT_EQ("OK", MatchError("partial record without end"));
} }
TEST(LogTest, MissingLastIsIgnored) { TEST_F(LogTest, MissingLastIsIgnored) {
Write(BigString("bar", kBlockSize)); Write(BigString("bar", kBlockSize));
// Remove the LAST block, including header. // Remove the LAST block, including header.
ShrinkSize(14); ShrinkSize(14);
@ -466,7 +466,7 @@ TEST(LogTest, MissingLastIsIgnored) {
ASSERT_EQ(0, DroppedBytes()); ASSERT_EQ(0, DroppedBytes());
} }
TEST(LogTest, PartialLastIsIgnored) { TEST_F(LogTest, PartialLastIsIgnored) {
Write(BigString("bar", kBlockSize)); Write(BigString("bar", kBlockSize));
// Cause a bad record length in the LAST block. // Cause a bad record length in the LAST block.
ShrinkSize(1); ShrinkSize(1);
@ -475,7 +475,7 @@ TEST(LogTest, PartialLastIsIgnored) {
ASSERT_EQ(0, DroppedBytes()); ASSERT_EQ(0, DroppedBytes());
} }
TEST(LogTest, SkipIntoMultiRecord) { TEST_F(LogTest, SkipIntoMultiRecord) {
// Consider a fragmented record: // Consider a fragmented record:
// first(R1), middle(R1), last(R1), first(R2) // first(R1), middle(R1), last(R1), first(R2)
// If initial_offset points to a record after first(R1) but before first(R2) // If initial_offset points to a record after first(R1) but before first(R2)
@ -491,7 +491,7 @@ TEST(LogTest, SkipIntoMultiRecord) {
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
} }
TEST(LogTest, ErrorJoinsRecords) { TEST_F(LogTest, ErrorJoinsRecords) {
// Consider two fragmented records: // Consider two fragmented records:
// first(R1) last(R1) first(R2) last(R2) // first(R1) last(R1) first(R2) last(R2)
// where the middle two fragments disappear. We do not want // where the middle two fragments disappear. We do not want
@ -514,47 +514,50 @@ TEST(LogTest, ErrorJoinsRecords) {
ASSERT_GE(dropped, 2 * kBlockSize); ASSERT_GE(dropped, 2 * kBlockSize);
} }
TEST(LogTest, ReadStart) { CheckInitialOffsetRecord(0, 0); } TEST_F(LogTest, ReadStart) { CheckInitialOffsetRecord(0, 0); }
TEST(LogTest, ReadSecondOneOff) { CheckInitialOffsetRecord(1, 1); } TEST_F(LogTest, ReadSecondOneOff) { CheckInitialOffsetRecord(1, 1); }
TEST(LogTest, ReadSecondTenThousand) { CheckInitialOffsetRecord(10000, 1); } TEST_F(LogTest, ReadSecondTenThousand) { CheckInitialOffsetRecord(10000, 1); }
TEST(LogTest, ReadSecondStart) { CheckInitialOffsetRecord(10007, 1); } TEST_F(LogTest, ReadSecondStart) { CheckInitialOffsetRecord(10007, 1); }
TEST(LogTest, ReadThirdOneOff) { CheckInitialOffsetRecord(10008, 2); } TEST_F(LogTest, ReadThirdOneOff) { CheckInitialOffsetRecord(10008, 2); }
TEST(LogTest, ReadThirdStart) { CheckInitialOffsetRecord(20014, 2); } TEST_F(LogTest, ReadThirdStart) { CheckInitialOffsetRecord(20014, 2); }
TEST(LogTest, ReadFourthOneOff) { CheckInitialOffsetRecord(20015, 3); } TEST_F(LogTest, ReadFourthOneOff) { CheckInitialOffsetRecord(20015, 3); }
TEST(LogTest, ReadFourthFirstBlockTrailer) { TEST_F(LogTest, ReadFourthFirstBlockTrailer) {
CheckInitialOffsetRecord(log::kBlockSize - 4, 3); CheckInitialOffsetRecord(log::kBlockSize - 4, 3);
} }
TEST(LogTest, ReadFourthMiddleBlock) { TEST_F(LogTest, ReadFourthMiddleBlock) {
CheckInitialOffsetRecord(log::kBlockSize + 1, 3); CheckInitialOffsetRecord(log::kBlockSize + 1, 3);
} }
TEST(LogTest, ReadFourthLastBlock) { TEST_F(LogTest, ReadFourthLastBlock) {
CheckInitialOffsetRecord(2 * log::kBlockSize + 1, 3); CheckInitialOffsetRecord(2 * log::kBlockSize + 1, 3);
} }
TEST(LogTest, ReadFourthStart) { TEST_F(LogTest, ReadFourthStart) {
CheckInitialOffsetRecord( CheckInitialOffsetRecord(
2 * (kHeaderSize + 1000) + (2 * log::kBlockSize - 1000) + 3 * kHeaderSize, 2 * (kHeaderSize + 1000) + (2 * log::kBlockSize - 1000) + 3 * kHeaderSize,
3); 3);
} }
TEST(LogTest, ReadInitialOffsetIntoBlockPadding) { TEST_F(LogTest, ReadInitialOffsetIntoBlockPadding) {
CheckInitialOffsetRecord(3 * log::kBlockSize - 3, 5); CheckInitialOffsetRecord(3 * log::kBlockSize - 3, 5);
} }
TEST(LogTest, ReadEnd) { CheckOffsetPastEndReturnsNoRecords(0); } TEST_F(LogTest, ReadEnd) { CheckOffsetPastEndReturnsNoRecords(0); }
TEST(LogTest, ReadPastEnd) { CheckOffsetPastEndReturnsNoRecords(5); } TEST_F(LogTest, ReadPastEnd) { CheckOffsetPastEndReturnsNoRecords(5); }
} // namespace log } // namespace log
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // 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. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/db_impl.h" #include "db/db_impl.h"
#include "db/filename.h" #include "db/filename.h"
#include "db/version_set.h" #include "db/version_set.h"
@ -10,15 +11,14 @@
#include "leveldb/env.h" #include "leveldb/env.h"
#include "leveldb/write_batch.h" #include "leveldb/write_batch.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/testharness.h"
#include "util/testutil.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
class RecoveryTest { class RecoveryTest : public testing::Test {
public: public:
RecoveryTest() : env_(Env::Default()), db_(nullptr) { RecoveryTest() : env_(Env::Default()), db_(nullptr) {
dbname_ = test::TmpDir() + "/recovery_test"; dbname_ = testing::TempDir() + "/recovery_test";
DestroyDB(dbname_, Options()); DestroyDB(dbname_, Options());
Open(); Open();
} }
@ -63,7 +63,7 @@ class RecoveryTest {
} }
void Open(Options* options = nullptr) { void Open(Options* options = nullptr) {
ASSERT_OK(OpenWithStatus(options)); ASSERT_LEVELDB_OK(OpenWithStatus(options));
ASSERT_EQ(1, NumLogs()); ASSERT_EQ(1, NumLogs());
} }
@ -84,7 +84,8 @@ class RecoveryTest {
std::string ManifestFileName() { std::string ManifestFileName() {
std::string current; std::string current;
ASSERT_OK(ReadFileToString(env_, CurrentFileName(dbname_), &current)); EXPECT_LEVELDB_OK(
ReadFileToString(env_, CurrentFileName(dbname_), &current));
size_t len = current.size(); size_t len = current.size();
if (len > 0 && current[len - 1] == '\n') { if (len > 0 && current[len - 1] == '\n') {
current.resize(len - 1); current.resize(len - 1);
@ -100,18 +101,20 @@ class RecoveryTest {
Close(); Close();
std::vector<uint64_t> logs = GetFiles(kLogFile); std::vector<uint64_t> logs = GetFiles(kLogFile);
for (size_t i = 0; i < logs.size(); i++) { for (size_t i = 0; i < logs.size(); i++) {
ASSERT_OK(env_->DeleteFile(LogName(logs[i]))) << LogName(logs[i]); EXPECT_LEVELDB_OK(env_->DeleteFile(LogName(logs[i]))) << LogName(logs[i]);
} }
return logs.size(); return logs.size();
} }
void DeleteManifestFile() { ASSERT_OK(env_->DeleteFile(ManifestFileName())); } void DeleteManifestFile() {
ASSERT_LEVELDB_OK(env_->DeleteFile(ManifestFileName()));
}
uint64_t FirstLogFile() { return GetFiles(kLogFile)[0]; } uint64_t FirstLogFile() { return GetFiles(kLogFile)[0]; }
std::vector<uint64_t> GetFiles(FileType t) { std::vector<uint64_t> GetFiles(FileType t) {
std::vector<std::string> filenames; std::vector<std::string> filenames;
ASSERT_OK(env_->GetChildren(dbname_, &filenames)); EXPECT_LEVELDB_OK(env_->GetChildren(dbname_, &filenames));
std::vector<uint64_t> result; std::vector<uint64_t> result;
for (size_t i = 0; i < filenames.size(); i++) { for (size_t i = 0; i < filenames.size(); i++) {
uint64_t number; uint64_t number;
@ -129,7 +132,7 @@ class RecoveryTest {
uint64_t FileSize(const std::string& fname) { uint64_t FileSize(const std::string& fname) {
uint64_t result; uint64_t result;
ASSERT_OK(env_->GetFileSize(fname, &result)) << fname; EXPECT_LEVELDB_OK(env_->GetFileSize(fname, &result)) << fname;
return result; return result;
} }
@ -139,13 +142,13 @@ class RecoveryTest {
void MakeLogFile(uint64_t lognum, SequenceNumber seq, Slice key, Slice val) { void MakeLogFile(uint64_t lognum, SequenceNumber seq, Slice key, Slice val) {
std::string fname = LogFileName(dbname_, lognum); std::string fname = LogFileName(dbname_, lognum);
WritableFile* file; WritableFile* file;
ASSERT_OK(env_->NewWritableFile(fname, &file)); ASSERT_LEVELDB_OK(env_->NewWritableFile(fname, &file));
log::Writer writer(file); log::Writer writer(file);
WriteBatch batch; WriteBatch batch;
batch.Put(key, val); batch.Put(key, val);
WriteBatchInternal::SetSequence(&batch, seq); WriteBatchInternal::SetSequence(&batch, seq);
ASSERT_OK(writer.AddRecord(WriteBatchInternal::Contents(&batch))); ASSERT_LEVELDB_OK(writer.AddRecord(WriteBatchInternal::Contents(&batch)));
ASSERT_OK(file->Flush()); ASSERT_LEVELDB_OK(file->Flush());
delete file; delete file;
} }
@ -155,12 +158,12 @@ class RecoveryTest {
DB* db_; DB* db_;
}; };
TEST(RecoveryTest, ManifestReused) { TEST_F(RecoveryTest, ManifestReused) {
if (!CanAppend()) { if (!CanAppend()) {
fprintf(stderr, "skipping test because env does not support appending\n"); fprintf(stderr, "skipping test because env does not support appending\n");
return; return;
} }
ASSERT_OK(Put("foo", "bar")); ASSERT_LEVELDB_OK(Put("foo", "bar"));
Close(); Close();
std::string old_manifest = ManifestFileName(); std::string old_manifest = ManifestFileName();
Open(); Open();
@ -171,12 +174,12 @@ TEST(RecoveryTest, ManifestReused) {
ASSERT_EQ("bar", Get("foo")); ASSERT_EQ("bar", Get("foo"));
} }
TEST(RecoveryTest, LargeManifestCompacted) { TEST_F(RecoveryTest, LargeManifestCompacted) {
if (!CanAppend()) { if (!CanAppend()) {
fprintf(stderr, "skipping test because env does not support appending\n"); fprintf(stderr, "skipping test because env does not support appending\n");
return; return;
} }
ASSERT_OK(Put("foo", "bar")); ASSERT_LEVELDB_OK(Put("foo", "bar"));
Close(); Close();
std::string old_manifest = ManifestFileName(); std::string old_manifest = ManifestFileName();
@ -184,10 +187,10 @@ TEST(RecoveryTest, LargeManifestCompacted) {
{ {
uint64_t len = FileSize(old_manifest); uint64_t len = FileSize(old_manifest);
WritableFile* file; WritableFile* file;
ASSERT_OK(env()->NewAppendableFile(old_manifest, &file)); ASSERT_LEVELDB_OK(env()->NewAppendableFile(old_manifest, &file));
std::string zeroes(3 * 1048576 - static_cast<size_t>(len), 0); std::string zeroes(3 * 1048576 - static_cast<size_t>(len), 0);
ASSERT_OK(file->Append(zeroes)); ASSERT_LEVELDB_OK(file->Append(zeroes));
ASSERT_OK(file->Flush()); ASSERT_LEVELDB_OK(file->Flush());
delete file; delete file;
} }
@ -202,8 +205,8 @@ TEST(RecoveryTest, LargeManifestCompacted) {
ASSERT_EQ("bar", Get("foo")); ASSERT_EQ("bar", Get("foo"));
} }
TEST(RecoveryTest, NoLogFiles) { TEST_F(RecoveryTest, NoLogFiles) {
ASSERT_OK(Put("foo", "bar")); ASSERT_LEVELDB_OK(Put("foo", "bar"));
ASSERT_EQ(1, DeleteLogFiles()); ASSERT_EQ(1, DeleteLogFiles());
Open(); Open();
ASSERT_EQ("NOT_FOUND", Get("foo")); ASSERT_EQ("NOT_FOUND", Get("foo"));
@ -211,13 +214,13 @@ TEST(RecoveryTest, NoLogFiles) {
ASSERT_EQ("NOT_FOUND", Get("foo")); ASSERT_EQ("NOT_FOUND", Get("foo"));
} }
TEST(RecoveryTest, LogFileReuse) { TEST_F(RecoveryTest, LogFileReuse) {
if (!CanAppend()) { if (!CanAppend()) {
fprintf(stderr, "skipping test because env does not support appending\n"); fprintf(stderr, "skipping test because env does not support appending\n");
return; return;
} }
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
ASSERT_OK(Put("foo", "bar")); ASSERT_LEVELDB_OK(Put("foo", "bar"));
if (i == 0) { if (i == 0) {
// Compact to ensure current log is empty // Compact to ensure current log is empty
CompactMemTable(); CompactMemTable();
@ -241,13 +244,13 @@ TEST(RecoveryTest, LogFileReuse) {
} }
} }
TEST(RecoveryTest, MultipleMemTables) { TEST_F(RecoveryTest, MultipleMemTables) {
// Make a large log. // Make a large log.
const int kNum = 1000; const int kNum = 1000;
for (int i = 0; i < kNum; i++) { for (int i = 0; i < kNum; i++) {
char buf[100]; char buf[100];
snprintf(buf, sizeof(buf), "%050d", i); snprintf(buf, sizeof(buf), "%050d", i);
ASSERT_OK(Put(buf, buf)); ASSERT_LEVELDB_OK(Put(buf, buf));
} }
ASSERT_EQ(0, NumTables()); ASSERT_EQ(0, NumTables());
Close(); Close();
@ -270,8 +273,8 @@ TEST(RecoveryTest, MultipleMemTables) {
} }
} }
TEST(RecoveryTest, MultipleLogFiles) { TEST_F(RecoveryTest, MultipleLogFiles) {
ASSERT_OK(Put("foo", "bar")); ASSERT_LEVELDB_OK(Put("foo", "bar"));
Close(); Close();
ASSERT_EQ(1, NumLogs()); ASSERT_EQ(1, NumLogs());
@ -316,8 +319,8 @@ TEST(RecoveryTest, MultipleLogFiles) {
ASSERT_EQ("there", Get("hi")); ASSERT_EQ("there", Get("hi"));
} }
TEST(RecoveryTest, ManifestMissing) { TEST_F(RecoveryTest, ManifestMissing) {
ASSERT_OK(Put("foo", "bar")); ASSERT_LEVELDB_OK(Put("foo", "bar"));
Close(); Close();
DeleteManifestFile(); DeleteManifestFile();
@ -327,4 +330,7 @@ TEST(RecoveryTest, ManifestMissing) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -7,13 +7,14 @@
#include <atomic> #include <atomic>
#include <set> #include <set>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/env.h" #include "leveldb/env.h"
#include "port/port.h" #include "port/port.h"
#include "port/thread_annotations.h" #include "port/thread_annotations.h"
#include "util/arena.h" #include "util/arena.h"
#include "util/hash.h" #include "util/hash.h"
#include "util/random.h" #include "util/random.h"
#include "util/testharness.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
@ -31,8 +32,6 @@ struct Comparator {
} }
}; };
class SkipTest {};
TEST(SkipTest, Empty) { TEST(SkipTest, Empty) {
Arena arena; Arena arena;
Comparator cmp; Comparator cmp;
@ -366,4 +365,7 @@ TEST(SkipTest, Concurrent5) { RunConcurrent(5); }
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -3,7 +3,8 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/version_edit.h" #include "db/version_edit.h"
#include "util/testharness.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
namespace leveldb { namespace leveldb {
@ -17,8 +18,6 @@ static void TestEncodeDecode(const VersionEdit& edit) {
ASSERT_EQ(encoded, encoded2); ASSERT_EQ(encoded, encoded2);
} }
class VersionEditTest {};
TEST(VersionEditTest, EncodeDecode) { TEST(VersionEditTest, EncodeDecode) {
static const uint64_t kBig = 1ull << 50; static const uint64_t kBig = 1ull << 50;
@ -41,4 +40,7 @@ TEST(VersionEditTest, EncodeDecode) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -3,13 +3,14 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/version_set.h" #include "db/version_set.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/testharness.h"
#include "util/testutil.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
class FindFileTest { class FindFileTest : public testing::Test {
public: public:
FindFileTest() : disjoint_sorted_files_(true) {} FindFileTest() : disjoint_sorted_files_(true) {}
@ -50,7 +51,7 @@ class FindFileTest {
std::vector<FileMetaData*> files_; std::vector<FileMetaData*> files_;
}; };
TEST(FindFileTest, Empty) { TEST_F(FindFileTest, Empty) {
ASSERT_EQ(0, Find("foo")); ASSERT_EQ(0, Find("foo"));
ASSERT_TRUE(!Overlaps("a", "z")); ASSERT_TRUE(!Overlaps("a", "z"));
ASSERT_TRUE(!Overlaps(nullptr, "z")); ASSERT_TRUE(!Overlaps(nullptr, "z"));
@ -58,7 +59,7 @@ TEST(FindFileTest, Empty) {
ASSERT_TRUE(!Overlaps(nullptr, nullptr)); ASSERT_TRUE(!Overlaps(nullptr, nullptr));
} }
TEST(FindFileTest, Single) { TEST_F(FindFileTest, Single) {
Add("p", "q"); Add("p", "q");
ASSERT_EQ(0, Find("a")); ASSERT_EQ(0, Find("a"));
ASSERT_EQ(0, Find("p")); ASSERT_EQ(0, Find("p"));
@ -88,7 +89,7 @@ TEST(FindFileTest, Single) {
ASSERT_TRUE(Overlaps(nullptr, nullptr)); ASSERT_TRUE(Overlaps(nullptr, nullptr));
} }
TEST(FindFileTest, Multiple) { TEST_F(FindFileTest, Multiple) {
Add("150", "200"); Add("150", "200");
Add("200", "250"); Add("200", "250");
Add("300", "350"); Add("300", "350");
@ -126,7 +127,7 @@ TEST(FindFileTest, Multiple) {
ASSERT_TRUE(Overlaps("450", "500")); ASSERT_TRUE(Overlaps("450", "500"));
} }
TEST(FindFileTest, MultipleNullBoundaries) { TEST_F(FindFileTest, MultipleNullBoundaries) {
Add("150", "200"); Add("150", "200");
Add("200", "250"); Add("200", "250");
Add("300", "350"); Add("300", "350");
@ -146,7 +147,7 @@ TEST(FindFileTest, MultipleNullBoundaries) {
ASSERT_TRUE(Overlaps("450", nullptr)); ASSERT_TRUE(Overlaps("450", nullptr));
} }
TEST(FindFileTest, OverlapSequenceChecks) { TEST_F(FindFileTest, OverlapSequenceChecks) {
Add("200", "200", 5000, 3000); Add("200", "200", 5000, 3000);
ASSERT_TRUE(!Overlaps("199", "199")); ASSERT_TRUE(!Overlaps("199", "199"));
ASSERT_TRUE(!Overlaps("201", "300")); ASSERT_TRUE(!Overlaps("201", "300"));
@ -155,7 +156,7 @@ TEST(FindFileTest, OverlapSequenceChecks) {
ASSERT_TRUE(Overlaps("200", "210")); ASSERT_TRUE(Overlaps("200", "210"));
} }
TEST(FindFileTest, OverlappingFiles) { TEST_F(FindFileTest, OverlappingFiles) {
Add("150", "600"); Add("150", "600");
Add("400", "500"); Add("400", "500");
disjoint_sorted_files_ = false; disjoint_sorted_files_ = false;
@ -177,7 +178,7 @@ void AddBoundaryInputs(const InternalKeyComparator& icmp,
const std::vector<FileMetaData*>& level_files, const std::vector<FileMetaData*>& level_files,
std::vector<FileMetaData*>* compaction_files); std::vector<FileMetaData*>* compaction_files);
class AddBoundaryInputsTest { class AddBoundaryInputsTest : public testing::Test {
public: public:
std::vector<FileMetaData*> level_files_; std::vector<FileMetaData*> level_files_;
std::vector<FileMetaData*> compaction_files_; std::vector<FileMetaData*> compaction_files_;
@ -204,13 +205,13 @@ class AddBoundaryInputsTest {
} }
}; };
TEST(AddBoundaryInputsTest, TestEmptyFileSets) { TEST_F(AddBoundaryInputsTest, TestEmptyFileSets) {
AddBoundaryInputs(icmp_, level_files_, &compaction_files_); AddBoundaryInputs(icmp_, level_files_, &compaction_files_);
ASSERT_TRUE(compaction_files_.empty()); ASSERT_TRUE(compaction_files_.empty());
ASSERT_TRUE(level_files_.empty()); ASSERT_TRUE(level_files_.empty());
} }
TEST(AddBoundaryInputsTest, TestEmptyLevelFiles) { TEST_F(AddBoundaryInputsTest, TestEmptyLevelFiles) {
FileMetaData* f1 = FileMetaData* f1 =
CreateFileMetaData(1, InternalKey("100", 2, kTypeValue), CreateFileMetaData(1, InternalKey("100", 2, kTypeValue),
InternalKey(InternalKey("100", 1, kTypeValue))); InternalKey(InternalKey("100", 1, kTypeValue)));
@ -222,7 +223,7 @@ TEST(AddBoundaryInputsTest, TestEmptyLevelFiles) {
ASSERT_TRUE(level_files_.empty()); ASSERT_TRUE(level_files_.empty());
} }
TEST(AddBoundaryInputsTest, TestEmptyCompactionFiles) { TEST_F(AddBoundaryInputsTest, TestEmptyCompactionFiles) {
FileMetaData* f1 = FileMetaData* f1 =
CreateFileMetaData(1, InternalKey("100", 2, kTypeValue), CreateFileMetaData(1, InternalKey("100", 2, kTypeValue),
InternalKey(InternalKey("100", 1, kTypeValue))); InternalKey(InternalKey("100", 1, kTypeValue)));
@ -234,7 +235,7 @@ TEST(AddBoundaryInputsTest, TestEmptyCompactionFiles) {
ASSERT_EQ(f1, level_files_[0]); ASSERT_EQ(f1, level_files_[0]);
} }
TEST(AddBoundaryInputsTest, TestNoBoundaryFiles) { TEST_F(AddBoundaryInputsTest, TestNoBoundaryFiles) {
FileMetaData* f1 = FileMetaData* f1 =
CreateFileMetaData(1, InternalKey("100", 2, kTypeValue), CreateFileMetaData(1, InternalKey("100", 2, kTypeValue),
InternalKey(InternalKey("100", 1, kTypeValue))); InternalKey(InternalKey("100", 1, kTypeValue)));
@ -255,7 +256,7 @@ TEST(AddBoundaryInputsTest, TestNoBoundaryFiles) {
ASSERT_EQ(2, compaction_files_.size()); ASSERT_EQ(2, compaction_files_.size());
} }
TEST(AddBoundaryInputsTest, TestOneBoundaryFiles) { TEST_F(AddBoundaryInputsTest, TestOneBoundaryFiles) {
FileMetaData* f1 = FileMetaData* f1 =
CreateFileMetaData(1, InternalKey("100", 3, kTypeValue), CreateFileMetaData(1, InternalKey("100", 3, kTypeValue),
InternalKey(InternalKey("100", 2, kTypeValue))); InternalKey(InternalKey("100", 2, kTypeValue)));
@ -277,7 +278,7 @@ TEST(AddBoundaryInputsTest, TestOneBoundaryFiles) {
ASSERT_EQ(f2, compaction_files_[1]); ASSERT_EQ(f2, compaction_files_[1]);
} }
TEST(AddBoundaryInputsTest, TestTwoBoundaryFiles) { TEST_F(AddBoundaryInputsTest, TestTwoBoundaryFiles) {
FileMetaData* f1 = FileMetaData* f1 =
CreateFileMetaData(1, InternalKey("100", 6, kTypeValue), CreateFileMetaData(1, InternalKey("100", 6, kTypeValue),
InternalKey(InternalKey("100", 5, kTypeValue))); InternalKey(InternalKey("100", 5, kTypeValue)));
@ -300,7 +301,7 @@ TEST(AddBoundaryInputsTest, TestTwoBoundaryFiles) {
ASSERT_EQ(f2, compaction_files_[2]); ASSERT_EQ(f2, compaction_files_[2]);
} }
TEST(AddBoundaryInputsTest, TestDisjoinFilePointers) { TEST_F(AddBoundaryInputsTest, TestDisjoinFilePointers) {
FileMetaData* f1 = FileMetaData* f1 =
CreateFileMetaData(1, InternalKey("100", 6, kTypeValue), CreateFileMetaData(1, InternalKey("100", 6, kTypeValue),
InternalKey(InternalKey("100", 5, kTypeValue))); InternalKey(InternalKey("100", 5, kTypeValue)));
@ -329,4 +330,7 @@ TEST(AddBoundaryInputsTest, TestDisjoinFilePointers) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // 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. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "leveldb/db.h" #include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/memtable.h" #include "db/memtable.h"
#include "db/write_batch_internal.h" #include "db/write_batch_internal.h"
#include "leveldb/db.h"
#include "leveldb/env.h" #include "leveldb/env.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/testharness.h"
namespace leveldb { namespace leveldb {
@ -22,7 +21,7 @@ static std::string PrintContents(WriteBatch* b) {
Iterator* iter = mem->NewIterator(); Iterator* iter = mem->NewIterator();
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
ParsedInternalKey ikey; ParsedInternalKey ikey;
ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey)); EXPECT_TRUE(ParseInternalKey(iter->key(), &ikey));
switch (ikey.type) { switch (ikey.type) {
case kTypeValue: case kTypeValue:
state.append("Put("); state.append("Put(");
@ -52,8 +51,6 @@ static std::string PrintContents(WriteBatch* b) {
return state; return state;
} }
class WriteBatchTest {};
TEST(WriteBatchTest, Empty) { TEST(WriteBatchTest, Empty) {
WriteBatch batch; WriteBatch batch;
ASSERT_EQ("", PrintContents(&batch)); ASSERT_EQ("", PrintContents(&batch));
@ -134,4 +131,7 @@ TEST(WriteBatchTest, ApproximateSize) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -7,14 +7,15 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/db_impl.h" #include "db/db_impl.h"
#include "leveldb/db.h" #include "leveldb/db.h"
#include "leveldb/env.h" #include "leveldb/env.h"
#include "util/testharness.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
class MemEnvTest { class MemEnvTest : public testing::Test {
public: public:
MemEnvTest() : env_(NewMemEnv(Env::Default())) {} MemEnvTest() : env_(NewMemEnv(Env::Default())) {}
~MemEnvTest() { delete env_; } ~MemEnvTest() { delete env_; }
@ -22,55 +23,55 @@ class MemEnvTest {
Env* env_; Env* env_;
}; };
TEST(MemEnvTest, Basics) { TEST_F(MemEnvTest, Basics) {
uint64_t file_size; uint64_t file_size;
WritableFile* writable_file; WritableFile* writable_file;
std::vector<std::string> children; std::vector<std::string> children;
ASSERT_OK(env_->CreateDir("/dir")); ASSERT_LEVELDB_OK(env_->CreateDir("/dir"));
// Check that the directory is empty. // Check that the directory is empty.
ASSERT_TRUE(!env_->FileExists("/dir/non_existent")); ASSERT_TRUE(!env_->FileExists("/dir/non_existent"));
ASSERT_TRUE(!env_->GetFileSize("/dir/non_existent", &file_size).ok()); ASSERT_TRUE(!env_->GetFileSize("/dir/non_existent", &file_size).ok());
ASSERT_OK(env_->GetChildren("/dir", &children)); ASSERT_LEVELDB_OK(env_->GetChildren("/dir", &children));
ASSERT_EQ(0, children.size()); ASSERT_EQ(0, children.size());
// Create a file. // Create a file.
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file)); ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size)); ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/f", &file_size));
ASSERT_EQ(0, file_size); ASSERT_EQ(0, file_size);
delete writable_file; delete writable_file;
// Check that the file exists. // Check that the file exists.
ASSERT_TRUE(env_->FileExists("/dir/f")); ASSERT_TRUE(env_->FileExists("/dir/f"));
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size)); ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/f", &file_size));
ASSERT_EQ(0, file_size); ASSERT_EQ(0, file_size);
ASSERT_OK(env_->GetChildren("/dir", &children)); ASSERT_LEVELDB_OK(env_->GetChildren("/dir", &children));
ASSERT_EQ(1, children.size()); ASSERT_EQ(1, children.size());
ASSERT_EQ("f", children[0]); ASSERT_EQ("f", children[0]);
// Write to the file. // Write to the file.
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file)); ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_OK(writable_file->Append("abc")); ASSERT_LEVELDB_OK(writable_file->Append("abc"));
delete writable_file; delete writable_file;
// Check that append works. // Check that append works.
ASSERT_OK(env_->NewAppendableFile("/dir/f", &writable_file)); ASSERT_LEVELDB_OK(env_->NewAppendableFile("/dir/f", &writable_file));
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size)); ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/f", &file_size));
ASSERT_EQ(3, file_size); ASSERT_EQ(3, file_size);
ASSERT_OK(writable_file->Append("hello")); ASSERT_LEVELDB_OK(writable_file->Append("hello"));
delete writable_file; delete writable_file;
// Check for expected size. // Check for expected size.
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size)); ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/f", &file_size));
ASSERT_EQ(8, file_size); ASSERT_EQ(8, file_size);
// Check that renaming works. // Check that renaming works.
ASSERT_TRUE(!env_->RenameFile("/dir/non_existent", "/dir/g").ok()); ASSERT_TRUE(!env_->RenameFile("/dir/non_existent", "/dir/g").ok());
ASSERT_OK(env_->RenameFile("/dir/f", "/dir/g")); ASSERT_LEVELDB_OK(env_->RenameFile("/dir/f", "/dir/g"));
ASSERT_TRUE(!env_->FileExists("/dir/f")); ASSERT_TRUE(!env_->FileExists("/dir/f"));
ASSERT_TRUE(env_->FileExists("/dir/g")); ASSERT_TRUE(env_->FileExists("/dir/g"));
ASSERT_OK(env_->GetFileSize("/dir/g", &file_size)); ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/g", &file_size));
ASSERT_EQ(8, file_size); ASSERT_EQ(8, file_size);
// Check that opening non-existent file fails. // Check that opening non-existent file fails.
@ -83,48 +84,49 @@ TEST(MemEnvTest, Basics) {
// Check that deleting works. // Check that deleting works.
ASSERT_TRUE(!env_->DeleteFile("/dir/non_existent").ok()); ASSERT_TRUE(!env_->DeleteFile("/dir/non_existent").ok());
ASSERT_OK(env_->DeleteFile("/dir/g")); ASSERT_LEVELDB_OK(env_->DeleteFile("/dir/g"));
ASSERT_TRUE(!env_->FileExists("/dir/g")); ASSERT_TRUE(!env_->FileExists("/dir/g"));
ASSERT_OK(env_->GetChildren("/dir", &children)); ASSERT_LEVELDB_OK(env_->GetChildren("/dir", &children));
ASSERT_EQ(0, children.size()); ASSERT_EQ(0, children.size());
ASSERT_OK(env_->DeleteDir("/dir")); ASSERT_LEVELDB_OK(env_->DeleteDir("/dir"));
} }
TEST(MemEnvTest, ReadWrite) { TEST_F(MemEnvTest, ReadWrite) {
WritableFile* writable_file; WritableFile* writable_file;
SequentialFile* seq_file; SequentialFile* seq_file;
RandomAccessFile* rand_file; RandomAccessFile* rand_file;
Slice result; Slice result;
char scratch[100]; char scratch[100];
ASSERT_OK(env_->CreateDir("/dir")); ASSERT_LEVELDB_OK(env_->CreateDir("/dir"));
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file)); ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_OK(writable_file->Append("hello ")); ASSERT_LEVELDB_OK(writable_file->Append("hello "));
ASSERT_OK(writable_file->Append("world")); ASSERT_LEVELDB_OK(writable_file->Append("world"));
delete writable_file; delete writable_file;
// Read sequentially. // Read sequentially.
ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file)); ASSERT_LEVELDB_OK(env_->NewSequentialFile("/dir/f", &seq_file));
ASSERT_OK(seq_file->Read(5, &result, scratch)); // Read "hello". ASSERT_LEVELDB_OK(seq_file->Read(5, &result, scratch)); // Read "hello".
ASSERT_EQ(0, result.compare("hello")); ASSERT_EQ(0, result.compare("hello"));
ASSERT_OK(seq_file->Skip(1)); ASSERT_LEVELDB_OK(seq_file->Skip(1));
ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Read "world". ASSERT_LEVELDB_OK(seq_file->Read(1000, &result, scratch)); // Read "world".
ASSERT_EQ(0, result.compare("world")); ASSERT_EQ(0, result.compare("world"));
ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Try reading past EOF. ASSERT_LEVELDB_OK(
seq_file->Read(1000, &result, scratch)); // Try reading past EOF.
ASSERT_EQ(0, result.size()); ASSERT_EQ(0, result.size());
ASSERT_OK(seq_file->Skip(100)); // Try to skip past end of file. ASSERT_LEVELDB_OK(seq_file->Skip(100)); // Try to skip past end of file.
ASSERT_OK(seq_file->Read(1000, &result, scratch)); ASSERT_LEVELDB_OK(seq_file->Read(1000, &result, scratch));
ASSERT_EQ(0, result.size()); ASSERT_EQ(0, result.size());
delete seq_file; delete seq_file;
// Random reads. // Random reads.
ASSERT_OK(env_->NewRandomAccessFile("/dir/f", &rand_file)); ASSERT_LEVELDB_OK(env_->NewRandomAccessFile("/dir/f", &rand_file));
ASSERT_OK(rand_file->Read(6, 5, &result, scratch)); // Read "world". ASSERT_LEVELDB_OK(rand_file->Read(6, 5, &result, scratch)); // Read "world".
ASSERT_EQ(0, result.compare("world")); ASSERT_EQ(0, result.compare("world"));
ASSERT_OK(rand_file->Read(0, 5, &result, scratch)); // Read "hello". ASSERT_LEVELDB_OK(rand_file->Read(0, 5, &result, scratch)); // Read "hello".
ASSERT_EQ(0, result.compare("hello")); ASSERT_EQ(0, result.compare("hello"));
ASSERT_OK(rand_file->Read(10, 100, &result, scratch)); // Read "d". ASSERT_LEVELDB_OK(rand_file->Read(10, 100, &result, scratch)); // Read "d".
ASSERT_EQ(0, result.compare("d")); ASSERT_EQ(0, result.compare("d"));
// Too high offset. // Too high offset.
@ -132,30 +134,30 @@ TEST(MemEnvTest, ReadWrite) {
delete rand_file; delete rand_file;
} }
TEST(MemEnvTest, Locks) { TEST_F(MemEnvTest, Locks) {
FileLock* lock; FileLock* lock;
// These are no-ops, but we test they return success. // These are no-ops, but we test they return success.
ASSERT_OK(env_->LockFile("some file", &lock)); ASSERT_LEVELDB_OK(env_->LockFile("some file", &lock));
ASSERT_OK(env_->UnlockFile(lock)); ASSERT_LEVELDB_OK(env_->UnlockFile(lock));
} }
TEST(MemEnvTest, Misc) { TEST_F(MemEnvTest, Misc) {
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
ASSERT_TRUE(!test_dir.empty()); ASSERT_TRUE(!test_dir.empty());
WritableFile* writable_file; WritableFile* writable_file;
ASSERT_OK(env_->NewWritableFile("/a/b", &writable_file)); ASSERT_LEVELDB_OK(env_->NewWritableFile("/a/b", &writable_file));
// These are no-ops, but we test they return success. // These are no-ops, but we test they return success.
ASSERT_OK(writable_file->Sync()); ASSERT_LEVELDB_OK(writable_file->Sync());
ASSERT_OK(writable_file->Flush()); ASSERT_LEVELDB_OK(writable_file->Flush());
ASSERT_OK(writable_file->Close()); ASSERT_LEVELDB_OK(writable_file->Close());
delete writable_file; delete writable_file;
} }
TEST(MemEnvTest, LargeWrite) { TEST_F(MemEnvTest, LargeWrite) {
const size_t kWriteSize = 300 * 1024; const size_t kWriteSize = 300 * 1024;
char* scratch = new char[kWriteSize * 2]; char* scratch = new char[kWriteSize * 2];
@ -165,21 +167,21 @@ TEST(MemEnvTest, LargeWrite) {
} }
WritableFile* writable_file; WritableFile* writable_file;
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file)); ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_OK(writable_file->Append("foo")); ASSERT_LEVELDB_OK(writable_file->Append("foo"));
ASSERT_OK(writable_file->Append(write_data)); ASSERT_LEVELDB_OK(writable_file->Append(write_data));
delete writable_file; delete writable_file;
SequentialFile* seq_file; SequentialFile* seq_file;
Slice result; Slice result;
ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file)); ASSERT_LEVELDB_OK(env_->NewSequentialFile("/dir/f", &seq_file));
ASSERT_OK(seq_file->Read(3, &result, scratch)); // Read "foo". ASSERT_LEVELDB_OK(seq_file->Read(3, &result, scratch)); // Read "foo".
ASSERT_EQ(0, result.compare("foo")); ASSERT_EQ(0, result.compare("foo"));
size_t read = 0; size_t read = 0;
std::string read_data; std::string read_data;
while (read < kWriteSize) { while (read < kWriteSize) {
ASSERT_OK(seq_file->Read(kWriteSize - read, &result, scratch)); ASSERT_LEVELDB_OK(seq_file->Read(kWriteSize - read, &result, scratch));
read_data.append(result.data(), result.size()); read_data.append(result.data(), result.size());
read += result.size(); read += result.size();
} }
@ -188,30 +190,30 @@ TEST(MemEnvTest, LargeWrite) {
delete[] scratch; delete[] scratch;
} }
TEST(MemEnvTest, OverwriteOpenFile) { TEST_F(MemEnvTest, OverwriteOpenFile) {
const char kWrite1Data[] = "Write #1 data"; const char kWrite1Data[] = "Write #1 data";
const size_t kFileDataLen = sizeof(kWrite1Data) - 1; const size_t kFileDataLen = sizeof(kWrite1Data) - 1;
const std::string kTestFileName = test::TmpDir() + "/leveldb-TestFile.dat"; const std::string kTestFileName = testing::TempDir() + "leveldb-TestFile.dat";
ASSERT_OK(WriteStringToFile(env_, kWrite1Data, kTestFileName)); ASSERT_LEVELDB_OK(WriteStringToFile(env_, kWrite1Data, kTestFileName));
RandomAccessFile* rand_file; RandomAccessFile* rand_file;
ASSERT_OK(env_->NewRandomAccessFile(kTestFileName, &rand_file)); ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(kTestFileName, &rand_file));
const char kWrite2Data[] = "Write #2 data"; const char kWrite2Data[] = "Write #2 data";
ASSERT_OK(WriteStringToFile(env_, kWrite2Data, kTestFileName)); ASSERT_LEVELDB_OK(WriteStringToFile(env_, kWrite2Data, kTestFileName));
// Verify that overwriting an open file will result in the new file data // Verify that overwriting an open file will result in the new file data
// being read from files opened before the write. // being read from files opened before the write.
Slice result; Slice result;
char scratch[kFileDataLen]; char scratch[kFileDataLen];
ASSERT_OK(rand_file->Read(0, kFileDataLen, &result, scratch)); ASSERT_LEVELDB_OK(rand_file->Read(0, kFileDataLen, &result, scratch));
ASSERT_EQ(0, result.compare(kWrite2Data)); ASSERT_EQ(0, result.compare(kWrite2Data));
delete rand_file; delete rand_file;
} }
TEST(MemEnvTest, DBTest) { TEST_F(MemEnvTest, DBTest) {
Options options; Options options;
options.create_if_missing = true; options.create_if_missing = true;
options.env = env_; options.env = env_;
@ -220,14 +222,14 @@ TEST(MemEnvTest, DBTest) {
const Slice keys[] = {Slice("aaa"), Slice("bbb"), Slice("ccc")}; const Slice keys[] = {Slice("aaa"), Slice("bbb"), Slice("ccc")};
const Slice vals[] = {Slice("foo"), Slice("bar"), Slice("baz")}; const Slice vals[] = {Slice("foo"), Slice("bar"), Slice("baz")};
ASSERT_OK(DB::Open(options, "/dir/db", &db)); ASSERT_LEVELDB_OK(DB::Open(options, "/dir/db", &db));
for (size_t i = 0; i < 3; ++i) { for (size_t i = 0; i < 3; ++i) {
ASSERT_OK(db->Put(WriteOptions(), keys[i], vals[i])); ASSERT_LEVELDB_OK(db->Put(WriteOptions(), keys[i], vals[i]));
} }
for (size_t i = 0; i < 3; ++i) { for (size_t i = 0; i < 3; ++i) {
std::string res; std::string res;
ASSERT_OK(db->Get(ReadOptions(), keys[i], &res)); ASSERT_LEVELDB_OK(db->Get(ReadOptions(), keys[i], &res));
ASSERT_TRUE(res == vals[i]); ASSERT_TRUE(res == vals[i]);
} }
@ -243,11 +245,11 @@ TEST(MemEnvTest, DBTest) {
delete iterator; delete iterator;
DBImpl* dbi = reinterpret_cast<DBImpl*>(db); DBImpl* dbi = reinterpret_cast<DBImpl*>(db);
ASSERT_OK(dbi->TEST_CompactMemTable()); ASSERT_LEVELDB_OK(dbi->TEST_CompactMemTable());
for (size_t i = 0; i < 3; ++i) { for (size_t i = 0; i < 3; ++i) {
std::string res; std::string res;
ASSERT_OK(db->Get(ReadOptions(), keys[i], &res)); ASSERT_LEVELDB_OK(db->Get(ReadOptions(), keys[i], &res));
ASSERT_TRUE(res == vals[i]); ASSERT_TRUE(res == vals[i]);
} }
@ -256,4 +258,7 @@ TEST(MemEnvTest, DBTest) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -7,9 +7,10 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/db.h" #include "leveldb/db.h"
#include "leveldb/write_batch.h" #include "leveldb/write_batch.h"
#include "util/testharness.h" #include "util/testutil.h"
namespace { namespace {
@ -23,11 +24,9 @@ std::string Key1(int i) {
std::string Key2(int i) { return Key1(i) + "_xxx"; } std::string Key2(int i) { return Key1(i) + "_xxx"; }
class Issue178 {};
TEST(Issue178, Test) { TEST(Issue178, Test) {
// Get rid of any state from an old run. // Get rid of any state from an old run.
std::string dbpath = leveldb::test::TmpDir() + "/leveldb_cbug_test"; std::string dbpath = testing::TempDir() + "leveldb_cbug_test";
DestroyDB(dbpath, leveldb::Options()); DestroyDB(dbpath, leveldb::Options());
// Open database. Disable compression since it affects the creation // Open database. Disable compression since it affects the creation
@ -37,28 +36,28 @@ TEST(Issue178, Test) {
leveldb::Options db_options; leveldb::Options db_options;
db_options.create_if_missing = true; db_options.create_if_missing = true;
db_options.compression = leveldb::kNoCompression; db_options.compression = leveldb::kNoCompression;
ASSERT_OK(leveldb::DB::Open(db_options, dbpath, &db)); ASSERT_LEVELDB_OK(leveldb::DB::Open(db_options, dbpath, &db));
// create first key range // create first key range
leveldb::WriteBatch batch; leveldb::WriteBatch batch;
for (size_t i = 0; i < kNumKeys; i++) { for (size_t i = 0; i < kNumKeys; i++) {
batch.Put(Key1(i), "value for range 1 key"); batch.Put(Key1(i), "value for range 1 key");
} }
ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch)); ASSERT_LEVELDB_OK(db->Write(leveldb::WriteOptions(), &batch));
// create second key range // create second key range
batch.Clear(); batch.Clear();
for (size_t i = 0; i < kNumKeys; i++) { for (size_t i = 0; i < kNumKeys; i++) {
batch.Put(Key2(i), "value for range 2 key"); batch.Put(Key2(i), "value for range 2 key");
} }
ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch)); ASSERT_LEVELDB_OK(db->Write(leveldb::WriteOptions(), &batch));
// delete second key range // delete second key range
batch.Clear(); batch.Clear();
for (size_t i = 0; i < kNumKeys; i++) { for (size_t i = 0; i < kNumKeys; i++) {
batch.Delete(Key2(i)); batch.Delete(Key2(i));
} }
ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch)); ASSERT_LEVELDB_OK(db->Write(leveldb::WriteOptions(), &batch));
// compact database // compact database
std::string start_key = Key1(0); std::string start_key = Key1(0);
@ -85,4 +84,7 @@ TEST(Issue178, Test) {
} // anonymous namespace } // anonymous namespace
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -6,35 +6,34 @@
// to forward, the current key can be yielded unexpectedly if a new // to forward, the current key can be yielded unexpectedly if a new
// mutation has been added just before the current key. // mutation has been added just before the current key.
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/db.h" #include "leveldb/db.h"
#include "util/testharness.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
class Issue200 {};
TEST(Issue200, Test) { TEST(Issue200, Test) {
// Get rid of any state from an old run. // Get rid of any state from an old run.
std::string dbpath = test::TmpDir() + "/leveldb_issue200_test"; std::string dbpath = testing::TempDir() + "leveldb_issue200_test";
DestroyDB(dbpath, Options()); DestroyDB(dbpath, Options());
DB* db; DB* db;
Options options; Options options;
options.create_if_missing = true; options.create_if_missing = true;
ASSERT_OK(DB::Open(options, dbpath, &db)); ASSERT_LEVELDB_OK(DB::Open(options, dbpath, &db));
WriteOptions write_options; WriteOptions write_options;
ASSERT_OK(db->Put(write_options, "1", "b")); ASSERT_LEVELDB_OK(db->Put(write_options, "1", "b"));
ASSERT_OK(db->Put(write_options, "2", "c")); ASSERT_LEVELDB_OK(db->Put(write_options, "2", "c"));
ASSERT_OK(db->Put(write_options, "3", "d")); ASSERT_LEVELDB_OK(db->Put(write_options, "3", "d"));
ASSERT_OK(db->Put(write_options, "4", "e")); ASSERT_LEVELDB_OK(db->Put(write_options, "4", "e"));
ASSERT_OK(db->Put(write_options, "5", "f")); ASSERT_LEVELDB_OK(db->Put(write_options, "5", "f"));
ReadOptions read_options; ReadOptions read_options;
Iterator* iter = db->NewIterator(read_options); Iterator* iter = db->NewIterator(read_options);
// Add an element that should not be reflected in the iterator. // Add an element that should not be reflected in the iterator.
ASSERT_OK(db->Put(write_options, "25", "cd")); ASSERT_LEVELDB_OK(db->Put(write_options, "25", "cd"));
iter->Seek("5"); iter->Seek("5");
ASSERT_EQ(iter->key().ToString(), "5"); ASSERT_EQ(iter->key().ToString(), "5");
@ -54,4 +53,7 @@ TEST(Issue200, Test) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -9,9 +9,10 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/db.h" #include "leveldb/db.h"
#include "leveldb/write_batch.h" #include "leveldb/write_batch.h"
#include "util/testharness.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
@ -37,8 +38,6 @@ std::string CreateRandomString(int32_t index) {
} // namespace } // namespace
class Issue320 {};
TEST(Issue320, Test) { TEST(Issue320, Test) {
std::srand(0); std::srand(0);
@ -53,8 +52,8 @@ TEST(Issue320, Test) {
Options options; Options options;
options.create_if_missing = true; options.create_if_missing = true;
std::string dbpath = test::TmpDir() + "/leveldb_issue320_test"; std::string dbpath = testing::TempDir() + "leveldb_issue320_test";
ASSERT_OK(DB::Open(options, dbpath, &db)); ASSERT_LEVELDB_OK(DB::Open(options, dbpath, &db));
uint32_t target_size = 10000; uint32_t target_size = 10000;
uint32_t num_items = 0; uint32_t num_items = 0;
@ -78,7 +77,8 @@ TEST(Issue320, Test) {
CreateRandomString(index), CreateRandomString(index))); CreateRandomString(index), CreateRandomString(index)));
batch.Put(test_map[index]->first, test_map[index]->second); batch.Put(test_map[index]->first, test_map[index]->second);
} else { } else {
ASSERT_OK(db->Get(readOptions, test_map[index]->first, &old_value)); ASSERT_LEVELDB_OK(
db->Get(readOptions, test_map[index]->first, &old_value));
if (old_value != test_map[index]->second) { if (old_value != test_map[index]->second) {
std::cout << "ERROR incorrect value returned by Get" << std::endl; std::cout << "ERROR incorrect value returned by Get" << std::endl;
std::cout << " count=" << count << std::endl; std::cout << " count=" << count << std::endl;
@ -102,7 +102,7 @@ TEST(Issue320, Test) {
} }
} }
ASSERT_OK(db->Write(writeOptions, &batch)); ASSERT_LEVELDB_OK(db->Write(writeOptions, &batch));
if (keep_snapshots && GenerateRandomNumber(10) == 0) { if (keep_snapshots && GenerateRandomNumber(10) == 0) {
int i = GenerateRandomNumber(snapshots.size()); int i = GenerateRandomNumber(snapshots.size());
@ -125,4 +125,7 @@ TEST(Issue320, Test) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -4,11 +4,11 @@
#include "table/filter_block.h" #include "table/filter_block.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/filter_policy.h" #include "leveldb/filter_policy.h"
#include "util/coding.h" #include "util/coding.h"
#include "util/hash.h" #include "util/hash.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/testharness.h"
#include "util/testutil.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
@ -36,12 +36,12 @@ class TestHashFilter : public FilterPolicy {
} }
}; };
class FilterBlockTest { class FilterBlockTest : public testing::Test {
public: public:
TestHashFilter policy_; TestHashFilter policy_;
}; };
TEST(FilterBlockTest, EmptyBuilder) { TEST_F(FilterBlockTest, EmptyBuilder) {
FilterBlockBuilder builder(&policy_); FilterBlockBuilder builder(&policy_);
Slice block = builder.Finish(); Slice block = builder.Finish();
ASSERT_EQ("\\x00\\x00\\x00\\x00\\x0b", EscapeString(block)); ASSERT_EQ("\\x00\\x00\\x00\\x00\\x0b", EscapeString(block));
@ -50,7 +50,7 @@ TEST(FilterBlockTest, EmptyBuilder) {
ASSERT_TRUE(reader.KeyMayMatch(100000, "foo")); ASSERT_TRUE(reader.KeyMayMatch(100000, "foo"));
} }
TEST(FilterBlockTest, SingleChunk) { TEST_F(FilterBlockTest, SingleChunk) {
FilterBlockBuilder builder(&policy_); FilterBlockBuilder builder(&policy_);
builder.StartBlock(100); builder.StartBlock(100);
builder.AddKey("foo"); builder.AddKey("foo");
@ -71,7 +71,7 @@ TEST(FilterBlockTest, SingleChunk) {
ASSERT_TRUE(!reader.KeyMayMatch(100, "other")); ASSERT_TRUE(!reader.KeyMayMatch(100, "other"));
} }
TEST(FilterBlockTest, MultiChunk) { TEST_F(FilterBlockTest, MultiChunk) {
FilterBlockBuilder builder(&policy_); FilterBlockBuilder builder(&policy_);
// First filter // First filter
@ -121,4 +121,7 @@ TEST(FilterBlockTest, MultiChunk) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -7,6 +7,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/dbformat.h" #include "db/dbformat.h"
#include "db/memtable.h" #include "db/memtable.h"
#include "db/write_batch_internal.h" #include "db/write_batch_internal.h"
@ -18,7 +19,6 @@
#include "table/block_builder.h" #include "table/block_builder.h"
#include "table/format.h" #include "table/format.h"
#include "util/random.h" #include "util/random.h"
#include "util/testharness.h"
#include "util/testutil.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
@ -219,12 +219,12 @@ class TableConstructor : public Constructor {
for (const auto& kvp : data) { for (const auto& kvp : data) {
builder.Add(kvp.first, kvp.second); builder.Add(kvp.first, kvp.second);
ASSERT_TRUE(builder.status().ok()); EXPECT_LEVELDB_OK(builder.status());
} }
Status s = builder.Finish(); Status s = builder.Finish();
ASSERT_TRUE(s.ok()) << s.ToString(); EXPECT_LEVELDB_OK(s);
ASSERT_EQ(sink.contents().size(), builder.FileSize()); EXPECT_EQ(sink.contents().size(), builder.FileSize());
// Open the table // Open the table
source_ = new StringSource(sink.contents()); source_ = new StringSource(sink.contents());
@ -340,7 +340,7 @@ class DBConstructor : public Constructor {
for (const auto& kvp : data) { for (const auto& kvp : data) {
WriteBatch batch; WriteBatch batch;
batch.Put(kvp.first, kvp.second); batch.Put(kvp.first, kvp.second);
ASSERT_TRUE(db_->Write(WriteOptions(), &batch).ok()); EXPECT_TRUE(db_->Write(WriteOptions(), &batch).ok());
} }
return Status::OK(); return Status::OK();
} }
@ -352,7 +352,7 @@ class DBConstructor : public Constructor {
private: private:
void NewDB() { void NewDB() {
std::string name = test::TmpDir() + "/table_testdb"; std::string name = testing::TempDir() + "table_testdb";
Options options; Options options;
options.comparator = comparator_; options.comparator = comparator_;
@ -403,7 +403,7 @@ static const TestArgs kTestArgList[] = {
}; };
static const int kNumTestArgs = sizeof(kTestArgList) / sizeof(kTestArgList[0]); static const int kNumTestArgs = sizeof(kTestArgList) / sizeof(kTestArgList[0]);
class Harness { class Harness : public testing::Test {
public: public:
Harness() : constructor_(nullptr) {} Harness() : constructor_(nullptr) {}
@ -609,7 +609,7 @@ class Harness {
}; };
// Test empty table/block. // Test empty table/block.
TEST(Harness, Empty) { TEST_F(Harness, Empty) {
for (int i = 0; i < kNumTestArgs; i++) { for (int i = 0; i < kNumTestArgs; i++) {
Init(kTestArgList[i]); Init(kTestArgList[i]);
Random rnd(test::RandomSeed() + 1); Random rnd(test::RandomSeed() + 1);
@ -620,7 +620,7 @@ TEST(Harness, Empty) {
// Special test for a block with no restart entries. The C++ leveldb // Special test for a block with no restart entries. The C++ leveldb
// code never generates such blocks, but the Java version of leveldb // code never generates such blocks, but the Java version of leveldb
// seems to. // seems to.
TEST(Harness, ZeroRestartPointsInBlock) { TEST_F(Harness, ZeroRestartPointsInBlock) {
char data[sizeof(uint32_t)]; char data[sizeof(uint32_t)];
memset(data, 0, sizeof(data)); memset(data, 0, sizeof(data));
BlockContents contents; BlockContents contents;
@ -639,7 +639,7 @@ TEST(Harness, ZeroRestartPointsInBlock) {
} }
// Test the empty key // Test the empty key
TEST(Harness, SimpleEmptyKey) { TEST_F(Harness, SimpleEmptyKey) {
for (int i = 0; i < kNumTestArgs; i++) { for (int i = 0; i < kNumTestArgs; i++) {
Init(kTestArgList[i]); Init(kTestArgList[i]);
Random rnd(test::RandomSeed() + 1); Random rnd(test::RandomSeed() + 1);
@ -648,7 +648,7 @@ TEST(Harness, SimpleEmptyKey) {
} }
} }
TEST(Harness, SimpleSingle) { TEST_F(Harness, SimpleSingle) {
for (int i = 0; i < kNumTestArgs; i++) { for (int i = 0; i < kNumTestArgs; i++) {
Init(kTestArgList[i]); Init(kTestArgList[i]);
Random rnd(test::RandomSeed() + 2); Random rnd(test::RandomSeed() + 2);
@ -657,7 +657,7 @@ TEST(Harness, SimpleSingle) {
} }
} }
TEST(Harness, SimpleMulti) { TEST_F(Harness, SimpleMulti) {
for (int i = 0; i < kNumTestArgs; i++) { for (int i = 0; i < kNumTestArgs; i++) {
Init(kTestArgList[i]); Init(kTestArgList[i]);
Random rnd(test::RandomSeed() + 3); Random rnd(test::RandomSeed() + 3);
@ -668,7 +668,7 @@ TEST(Harness, SimpleMulti) {
} }
} }
TEST(Harness, SimpleSpecialKey) { TEST_F(Harness, SimpleSpecialKey) {
for (int i = 0; i < kNumTestArgs; i++) { for (int i = 0; i < kNumTestArgs; i++) {
Init(kTestArgList[i]); Init(kTestArgList[i]);
Random rnd(test::RandomSeed() + 4); Random rnd(test::RandomSeed() + 4);
@ -677,7 +677,7 @@ TEST(Harness, SimpleSpecialKey) {
} }
} }
TEST(Harness, Randomized) { TEST_F(Harness, Randomized) {
for (int i = 0; i < kNumTestArgs; i++) { for (int i = 0; i < kNumTestArgs; i++) {
Init(kTestArgList[i]); Init(kTestArgList[i]);
Random rnd(test::RandomSeed() + 5); Random rnd(test::RandomSeed() + 5);
@ -697,7 +697,7 @@ TEST(Harness, Randomized) {
} }
} }
TEST(Harness, RandomizedLongDB) { TEST_F(Harness, RandomizedLongDB) {
Random rnd(test::RandomSeed()); Random rnd(test::RandomSeed());
TestArgs args = {DB_TEST, false, 16}; TestArgs args = {DB_TEST, false, 16};
Init(args); Init(args);
@ -721,8 +721,6 @@ TEST(Harness, RandomizedLongDB) {
ASSERT_GT(files, 0); ASSERT_GT(files, 0);
} }
class MemTableTest {};
TEST(MemTableTest, Simple) { TEST(MemTableTest, Simple) {
InternalKeyComparator cmp(BytewiseComparator()); InternalKeyComparator cmp(BytewiseComparator());
MemTable* memtable = new MemTable(cmp); MemTable* memtable = new MemTable(cmp);
@ -757,8 +755,6 @@ static bool Between(uint64_t val, uint64_t low, uint64_t high) {
return result; return result;
} }
class TableTest {};
TEST(TableTest, ApproximateOffsetOfPlain) { TEST(TableTest, ApproximateOffsetOfPlain) {
TableConstructor c(BytewiseComparator()); TableConstructor c(BytewiseComparator());
c.Add("k01", "hello"); c.Add("k01", "hello");
@ -832,4 +828,7 @@ TEST(TableTest, ApproximateOffsetOfCompressed) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -4,13 +4,11 @@
#include "util/arena.h" #include "util/arena.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "util/random.h" #include "util/random.h"
#include "util/testharness.h"
namespace leveldb { namespace leveldb {
class ArenaTest {};
TEST(ArenaTest, Empty) { Arena arena; } TEST(ArenaTest, Empty) { Arena arena; }
TEST(ArenaTest, Simple) { TEST(ArenaTest, Simple) {
@ -62,4 +60,7 @@ TEST(ArenaTest, Simple) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // 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. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/filter_policy.h" #include "leveldb/filter_policy.h"
#include "util/coding.h" #include "util/coding.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/testharness.h"
#include "util/testutil.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
@ -18,7 +17,7 @@ static Slice Key(int i, char* buffer) {
return Slice(buffer, sizeof(uint32_t)); return Slice(buffer, sizeof(uint32_t));
} }
class BloomTest { class BloomTest : public testing::Test {
public: public:
BloomTest() : policy_(NewBloomFilterPolicy(10)) {} BloomTest() : policy_(NewBloomFilterPolicy(10)) {}
@ -80,12 +79,12 @@ class BloomTest {
std::vector<std::string> keys_; std::vector<std::string> keys_;
}; };
TEST(BloomTest, EmptyFilter) { TEST_F(BloomTest, EmptyFilter) {
ASSERT_TRUE(!Matches("hello")); ASSERT_TRUE(!Matches("hello"));
ASSERT_TRUE(!Matches("world")); ASSERT_TRUE(!Matches("world"));
} }
TEST(BloomTest, Small) { TEST_F(BloomTest, Small) {
Add("hello"); Add("hello");
Add("world"); Add("world");
ASSERT_TRUE(Matches("hello")); ASSERT_TRUE(Matches("hello"));
@ -107,7 +106,7 @@ static int NextLength(int length) {
return length; return length;
} }
TEST(BloomTest, VaryingLengths) { TEST_F(BloomTest, VaryingLengths) {
char buffer[sizeof(int)]; char buffer[sizeof(int)];
// Count number of filters that significantly exceed the false positive rate // Count number of filters that significantly exceed the false positive rate
@ -153,4 +152,7 @@ TEST(BloomTest, VaryingLengths) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -5,8 +5,9 @@
#include "leveldb/cache.h" #include "leveldb/cache.h"
#include <vector> #include <vector>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "util/coding.h" #include "util/coding.h"
#include "util/testharness.h"
namespace leveldb { namespace leveldb {
@ -23,7 +24,7 @@ static int DecodeKey(const Slice& k) {
static void* EncodeValue(uintptr_t v) { return reinterpret_cast<void*>(v); } static void* EncodeValue(uintptr_t v) { return reinterpret_cast<void*>(v); }
static int DecodeValue(void* v) { return reinterpret_cast<uintptr_t>(v); } static int DecodeValue(void* v) { return reinterpret_cast<uintptr_t>(v); }
class CacheTest { class CacheTest : public testing::Test {
public: public:
static void Deleter(const Slice& key, void* v) { static void Deleter(const Slice& key, void* v) {
current_->deleted_keys_.push_back(DecodeKey(key)); current_->deleted_keys_.push_back(DecodeKey(key));
@ -59,12 +60,11 @@ class CacheTest {
} }
void Erase(int key) { cache_->Erase(EncodeKey(key)); } void Erase(int key) { cache_->Erase(EncodeKey(key)); }
static CacheTest* current_; static CacheTest* current_;
}; };
CacheTest* CacheTest::current_; CacheTest* CacheTest::current_;
TEST(CacheTest, HitAndMiss) { TEST_F(CacheTest, HitAndMiss) {
ASSERT_EQ(-1, Lookup(100)); ASSERT_EQ(-1, Lookup(100));
Insert(100, 101); Insert(100, 101);
@ -87,7 +87,7 @@ TEST(CacheTest, HitAndMiss) {
ASSERT_EQ(101, deleted_values_[0]); ASSERT_EQ(101, deleted_values_[0]);
} }
TEST(CacheTest, Erase) { TEST_F(CacheTest, Erase) {
Erase(200); Erase(200);
ASSERT_EQ(0, deleted_keys_.size()); ASSERT_EQ(0, deleted_keys_.size());
@ -106,7 +106,7 @@ TEST(CacheTest, Erase) {
ASSERT_EQ(1, deleted_keys_.size()); ASSERT_EQ(1, deleted_keys_.size());
} }
TEST(CacheTest, EntriesArePinned) { TEST_F(CacheTest, EntriesArePinned) {
Insert(100, 101); Insert(100, 101);
Cache::Handle* h1 = cache_->Lookup(EncodeKey(100)); Cache::Handle* h1 = cache_->Lookup(EncodeKey(100));
ASSERT_EQ(101, DecodeValue(cache_->Value(h1))); ASSERT_EQ(101, DecodeValue(cache_->Value(h1)));
@ -131,7 +131,7 @@ TEST(CacheTest, EntriesArePinned) {
ASSERT_EQ(102, deleted_values_[1]); ASSERT_EQ(102, deleted_values_[1]);
} }
TEST(CacheTest, EvictionPolicy) { TEST_F(CacheTest, EvictionPolicy) {
Insert(100, 101); Insert(100, 101);
Insert(200, 201); Insert(200, 201);
Insert(300, 301); Insert(300, 301);
@ -150,7 +150,7 @@ TEST(CacheTest, EvictionPolicy) {
cache_->Release(h); cache_->Release(h);
} }
TEST(CacheTest, UseExceedsCacheSize) { TEST_F(CacheTest, UseExceedsCacheSize) {
// Overfill the cache, keeping handles on all inserted entries. // Overfill the cache, keeping handles on all inserted entries.
std::vector<Cache::Handle*> h; std::vector<Cache::Handle*> h;
for (int i = 0; i < kCacheSize + 100; i++) { for (int i = 0; i < kCacheSize + 100; i++) {
@ -167,7 +167,7 @@ TEST(CacheTest, UseExceedsCacheSize) {
} }
} }
TEST(CacheTest, HeavyEntries) { TEST_F(CacheTest, HeavyEntries) {
// Add a bunch of light and heavy entries and then count the combined // Add a bunch of light and heavy entries and then count the combined
// size of items still in the cache, which must be approximately the // size of items still in the cache, which must be approximately the
// same as the total capacity. // same as the total capacity.
@ -194,13 +194,13 @@ TEST(CacheTest, HeavyEntries) {
ASSERT_LE(cached_weight, kCacheSize + kCacheSize / 10); ASSERT_LE(cached_weight, kCacheSize + kCacheSize / 10);
} }
TEST(CacheTest, NewId) { TEST_F(CacheTest, NewId) {
uint64_t a = cache_->NewId(); uint64_t a = cache_->NewId();
uint64_t b = cache_->NewId(); uint64_t b = cache_->NewId();
ASSERT_NE(a, b); ASSERT_NE(a, b);
} }
TEST(CacheTest, Prune) { TEST_F(CacheTest, Prune) {
Insert(1, 100); Insert(1, 100);
Insert(2, 200); Insert(2, 200);
@ -213,7 +213,7 @@ TEST(CacheTest, Prune) {
ASSERT_EQ(-1, Lookup(2)); ASSERT_EQ(-1, Lookup(2));
} }
TEST(CacheTest, ZeroSizeCache) { TEST_F(CacheTest, ZeroSizeCache) {
delete cache_; delete cache_;
cache_ = NewLRUCache(0); cache_ = NewLRUCache(0);
@ -223,4 +223,7 @@ TEST(CacheTest, ZeroSizeCache) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -2,15 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be // 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. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "util/coding.h"
#include <vector> #include <vector>
#include "util/coding.h" #include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "util/testharness.h"
namespace leveldb { namespace leveldb {
class Coding {};
TEST(Coding, Fixed32) { TEST(Coding, Fixed32) {
std::string s; std::string s;
for (uint32_t v = 0; v < 100000; v++) { for (uint32_t v = 0; v < 100000; v++) {
@ -193,4 +192,7 @@ TEST(Coding, Strings) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -3,13 +3,12 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "util/crc32c.h" #include "util/crc32c.h"
#include "util/testharness.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
namespace leveldb { namespace leveldb {
namespace crc32c { namespace crc32c {
class CRC {};
TEST(CRC, StandardResults) { TEST(CRC, StandardResults) {
// From rfc3720 section B.4. // From rfc3720 section B.4.
char buf[32]; char buf[32];
@ -56,4 +55,7 @@ TEST(CRC, Mask) {
} // namespace crc32c } // namespace crc32c
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -13,10 +13,11 @@
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/env.h" #include "leveldb/env.h"
#include "port/port.h" #include "port/port.h"
#include "util/env_posix_test_helper.h" #include "util/env_posix_test_helper.h"
#include "util/testharness.h" #include "util/testutil.h"
#if HAVE_O_CLOEXEC #if HAVE_O_CLOEXEC
@ -168,7 +169,7 @@ namespace leveldb {
static const int kReadOnlyFileLimit = 4; static const int kReadOnlyFileLimit = 4;
static const int kMMapLimit = 4; static const int kMMapLimit = 4;
class EnvPosixTest { class EnvPosixTest : public testing::Test {
public: public:
static void SetFileLimits(int read_only_file_limit, int mmap_limit) { static void SetFileLimits(int read_only_file_limit, int mmap_limit) {
EnvPosixTestHelper::SetReadOnlyFDLimit(read_only_file_limit); EnvPosixTestHelper::SetReadOnlyFDLimit(read_only_file_limit);
@ -180,10 +181,10 @@ class EnvPosixTest {
Env* env_; Env* env_;
}; };
TEST(EnvPosixTest, TestOpenOnRead) { TEST_F(EnvPosixTest, TestOpenOnRead) {
// Write some test data to a single file that will be opened |n| times. // Write some test data to a single file that will be opened |n| times.
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string test_file = test_dir + "/open_on_read.txt"; std::string test_file = test_dir + "/open_on_read.txt";
FILE* f = fopen(test_file.c_str(), "we"); FILE* f = fopen(test_file.c_str(), "we");
@ -197,133 +198,133 @@ TEST(EnvPosixTest, TestOpenOnRead) {
const int kNumFiles = kReadOnlyFileLimit + kMMapLimit + 5; const int kNumFiles = kReadOnlyFileLimit + kMMapLimit + 5;
leveldb::RandomAccessFile* files[kNumFiles] = {0}; leveldb::RandomAccessFile* files[kNumFiles] = {0};
for (int i = 0; i < kNumFiles; i++) { for (int i = 0; i < kNumFiles; i++) {
ASSERT_OK(env_->NewRandomAccessFile(test_file, &files[i])); ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(test_file, &files[i]));
} }
char scratch; char scratch;
Slice read_result; Slice read_result;
for (int i = 0; i < kNumFiles; i++) { for (int i = 0; i < kNumFiles; i++) {
ASSERT_OK(files[i]->Read(i, 1, &read_result, &scratch)); ASSERT_LEVELDB_OK(files[i]->Read(i, 1, &read_result, &scratch));
ASSERT_EQ(kFileData[i], read_result[0]); ASSERT_EQ(kFileData[i], read_result[0]);
} }
for (int i = 0; i < kNumFiles; i++) { for (int i = 0; i < kNumFiles; i++) {
delete files[i]; delete files[i];
} }
ASSERT_OK(env_->DeleteFile(test_file)); ASSERT_LEVELDB_OK(env_->DeleteFile(test_file));
} }
#if HAVE_O_CLOEXEC #if HAVE_O_CLOEXEC
TEST(EnvPosixTest, TestCloseOnExecSequentialFile) { TEST_F(EnvPosixTest, TestCloseOnExecSequentialFile) {
std::unordered_set<int> open_fds; std::unordered_set<int> open_fds;
GetOpenFileDescriptors(&open_fds); GetOpenFileDescriptors(&open_fds);
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string file_path = test_dir + "/close_on_exec_sequential.txt"; std::string file_path = test_dir + "/close_on_exec_sequential.txt";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path)); ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
leveldb::SequentialFile* file = nullptr; leveldb::SequentialFile* file = nullptr;
ASSERT_OK(env_->NewSequentialFile(file_path, &file)); ASSERT_LEVELDB_OK(env_->NewSequentialFile(file_path, &file));
CheckCloseOnExecDoesNotLeakFDs(open_fds); CheckCloseOnExecDoesNotLeakFDs(open_fds);
delete file; delete file;
ASSERT_OK(env_->DeleteFile(file_path)); ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
} }
TEST(EnvPosixTest, TestCloseOnExecRandomAccessFile) { TEST_F(EnvPosixTest, TestCloseOnExecRandomAccessFile) {
std::unordered_set<int> open_fds; std::unordered_set<int> open_fds;
GetOpenFileDescriptors(&open_fds); GetOpenFileDescriptors(&open_fds);
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string file_path = test_dir + "/close_on_exec_random_access.txt"; std::string file_path = test_dir + "/close_on_exec_random_access.txt";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path)); ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
// Exhaust the RandomAccessFile mmap limit. This way, the test // Exhaust the RandomAccessFile mmap limit. This way, the test
// RandomAccessFile instance below is backed by a file descriptor, not by an // RandomAccessFile instance below is backed by a file descriptor, not by an
// mmap region. // mmap region.
leveldb::RandomAccessFile* mmapped_files[kReadOnlyFileLimit] = {nullptr}; leveldb::RandomAccessFile* mmapped_files[kReadOnlyFileLimit] = {nullptr};
for (int i = 0; i < kReadOnlyFileLimit; i++) { for (int i = 0; i < kReadOnlyFileLimit; i++) {
ASSERT_OK(env_->NewRandomAccessFile(file_path, &mmapped_files[i])); ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(file_path, &mmapped_files[i]));
} }
leveldb::RandomAccessFile* file = nullptr; leveldb::RandomAccessFile* file = nullptr;
ASSERT_OK(env_->NewRandomAccessFile(file_path, &file)); ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(file_path, &file));
CheckCloseOnExecDoesNotLeakFDs(open_fds); CheckCloseOnExecDoesNotLeakFDs(open_fds);
delete file; delete file;
for (int i = 0; i < kReadOnlyFileLimit; i++) { for (int i = 0; i < kReadOnlyFileLimit; i++) {
delete mmapped_files[i]; delete mmapped_files[i];
} }
ASSERT_OK(env_->DeleteFile(file_path)); ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
} }
TEST(EnvPosixTest, TestCloseOnExecWritableFile) { TEST_F(EnvPosixTest, TestCloseOnExecWritableFile) {
std::unordered_set<int> open_fds; std::unordered_set<int> open_fds;
GetOpenFileDescriptors(&open_fds); GetOpenFileDescriptors(&open_fds);
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string file_path = test_dir + "/close_on_exec_writable.txt"; std::string file_path = test_dir + "/close_on_exec_writable.txt";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path)); ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
leveldb::WritableFile* file = nullptr; leveldb::WritableFile* file = nullptr;
ASSERT_OK(env_->NewWritableFile(file_path, &file)); ASSERT_LEVELDB_OK(env_->NewWritableFile(file_path, &file));
CheckCloseOnExecDoesNotLeakFDs(open_fds); CheckCloseOnExecDoesNotLeakFDs(open_fds);
delete file; delete file;
ASSERT_OK(env_->DeleteFile(file_path)); ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
} }
TEST(EnvPosixTest, TestCloseOnExecAppendableFile) { TEST_F(EnvPosixTest, TestCloseOnExecAppendableFile) {
std::unordered_set<int> open_fds; std::unordered_set<int> open_fds;
GetOpenFileDescriptors(&open_fds); GetOpenFileDescriptors(&open_fds);
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string file_path = test_dir + "/close_on_exec_appendable.txt"; std::string file_path = test_dir + "/close_on_exec_appendable.txt";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path)); ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
leveldb::WritableFile* file = nullptr; leveldb::WritableFile* file = nullptr;
ASSERT_OK(env_->NewAppendableFile(file_path, &file)); ASSERT_LEVELDB_OK(env_->NewAppendableFile(file_path, &file));
CheckCloseOnExecDoesNotLeakFDs(open_fds); CheckCloseOnExecDoesNotLeakFDs(open_fds);
delete file; delete file;
ASSERT_OK(env_->DeleteFile(file_path)); ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
} }
TEST(EnvPosixTest, TestCloseOnExecLockFile) { TEST_F(EnvPosixTest, TestCloseOnExecLockFile) {
std::unordered_set<int> open_fds; std::unordered_set<int> open_fds;
GetOpenFileDescriptors(&open_fds); GetOpenFileDescriptors(&open_fds);
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string file_path = test_dir + "/close_on_exec_lock.txt"; std::string file_path = test_dir + "/close_on_exec_lock.txt";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path)); ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
leveldb::FileLock* lock = nullptr; leveldb::FileLock* lock = nullptr;
ASSERT_OK(env_->LockFile(file_path, &lock)); ASSERT_LEVELDB_OK(env_->LockFile(file_path, &lock));
CheckCloseOnExecDoesNotLeakFDs(open_fds); CheckCloseOnExecDoesNotLeakFDs(open_fds);
ASSERT_OK(env_->UnlockFile(lock)); ASSERT_LEVELDB_OK(env_->UnlockFile(lock));
ASSERT_OK(env_->DeleteFile(file_path)); ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
} }
TEST(EnvPosixTest, TestCloseOnExecLogger) { TEST_F(EnvPosixTest, TestCloseOnExecLogger) {
std::unordered_set<int> open_fds; std::unordered_set<int> open_fds;
GetOpenFileDescriptors(&open_fds); GetOpenFileDescriptors(&open_fds);
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string file_path = test_dir + "/close_on_exec_logger.txt"; std::string file_path = test_dir + "/close_on_exec_logger.txt";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path)); ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
leveldb::Logger* file = nullptr; leveldb::Logger* file = nullptr;
ASSERT_OK(env_->NewLogger(file_path, &file)); ASSERT_LEVELDB_OK(env_->NewLogger(file_path, &file));
CheckCloseOnExecDoesNotLeakFDs(open_fds); CheckCloseOnExecDoesNotLeakFDs(open_fds);
delete file; delete file;
ASSERT_OK(env_->DeleteFile(file_path)); ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
} }
#endif // HAVE_O_CLOEXEC #endif // HAVE_O_CLOEXEC
@ -346,5 +347,7 @@ int main(int argc, char** argv) {
// All tests currently run with the same read-only file limits. // All tests currently run with the same read-only file limits.
leveldb::EnvPosixTest::SetFileLimits(leveldb::kReadOnlyFileLimit, leveldb::EnvPosixTest::SetFileLimits(leveldb::kReadOnlyFileLimit,
leveldb::kMMapLimit); leveldb::kMMapLimit);
return leveldb::test::RunAllTests();
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
} }

View File

@ -6,32 +6,32 @@
#include <algorithm> #include <algorithm>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "port/port.h" #include "port/port.h"
#include "port/thread_annotations.h" #include "port/thread_annotations.h"
#include "util/mutexlock.h" #include "util/mutexlock.h"
#include "util/testharness.h"
#include "util/testutil.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
static const int kDelayMicros = 100000; static const int kDelayMicros = 100000;
class EnvTest { class EnvTest : public testing::Test {
public: public:
EnvTest() : env_(Env::Default()) {} EnvTest() : env_(Env::Default()) {}
Env* env_; Env* env_;
}; };
TEST(EnvTest, ReadWrite) { TEST_F(EnvTest, ReadWrite) {
Random rnd(test::RandomSeed()); Random rnd(test::RandomSeed());
// Get file to use for testing. // Get file to use for testing.
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string test_file_name = test_dir + "/open_on_read.txt"; std::string test_file_name = test_dir + "/open_on_read.txt";
WritableFile* writable_file; WritableFile* writable_file;
ASSERT_OK(env_->NewWritableFile(test_file_name, &writable_file)); ASSERT_LEVELDB_OK(env_->NewWritableFile(test_file_name, &writable_file));
// Fill a file with data generated via a sequence of randomly sized writes. // Fill a file with data generated via a sequence of randomly sized writes.
static const size_t kDataSize = 10 * 1048576; static const size_t kDataSize = 10 * 1048576;
@ -40,26 +40,26 @@ TEST(EnvTest, ReadWrite) {
int len = rnd.Skewed(18); // Up to 2^18 - 1, but typically much smaller int len = rnd.Skewed(18); // Up to 2^18 - 1, but typically much smaller
std::string r; std::string r;
test::RandomString(&rnd, len, &r); test::RandomString(&rnd, len, &r);
ASSERT_OK(writable_file->Append(r)); ASSERT_LEVELDB_OK(writable_file->Append(r));
data += r; data += r;
if (rnd.OneIn(10)) { if (rnd.OneIn(10)) {
ASSERT_OK(writable_file->Flush()); ASSERT_LEVELDB_OK(writable_file->Flush());
} }
} }
ASSERT_OK(writable_file->Sync()); ASSERT_LEVELDB_OK(writable_file->Sync());
ASSERT_OK(writable_file->Close()); ASSERT_LEVELDB_OK(writable_file->Close());
delete writable_file; delete writable_file;
// Read all data using a sequence of randomly sized reads. // Read all data using a sequence of randomly sized reads.
SequentialFile* sequential_file; SequentialFile* sequential_file;
ASSERT_OK(env_->NewSequentialFile(test_file_name, &sequential_file)); ASSERT_LEVELDB_OK(env_->NewSequentialFile(test_file_name, &sequential_file));
std::string read_result; std::string read_result;
std::string scratch; std::string scratch;
while (read_result.size() < data.size()) { while (read_result.size() < data.size()) {
int len = std::min<int>(rnd.Skewed(18), data.size() - read_result.size()); int len = std::min<int>(rnd.Skewed(18), data.size() - read_result.size());
scratch.resize(std::max(len, 1)); // at least 1 so &scratch[0] is legal scratch.resize(std::max(len, 1)); // at least 1 so &scratch[0] is legal
Slice read; Slice read;
ASSERT_OK(sequential_file->Read(len, &read, &scratch[0])); ASSERT_LEVELDB_OK(sequential_file->Read(len, &read, &scratch[0]));
if (len > 0) { if (len > 0) {
ASSERT_GT(read.size(), 0); ASSERT_GT(read.size(), 0);
} }
@ -70,7 +70,7 @@ TEST(EnvTest, ReadWrite) {
delete sequential_file; delete sequential_file;
} }
TEST(EnvTest, RunImmediately) { TEST_F(EnvTest, RunImmediately) {
struct RunState { struct RunState {
port::Mutex mu; port::Mutex mu;
port::CondVar cvar{&mu}; port::CondVar cvar{&mu};
@ -94,7 +94,7 @@ TEST(EnvTest, RunImmediately) {
} }
} }
TEST(EnvTest, RunMany) { TEST_F(EnvTest, RunMany) {
struct RunState { struct RunState {
port::Mutex mu; port::Mutex mu;
port::CondVar cvar{&mu}; port::CondVar cvar{&mu};
@ -153,7 +153,7 @@ static void ThreadBody(void* arg) {
s->mu.Unlock(); s->mu.Unlock();
} }
TEST(EnvTest, StartThread) { TEST_F(EnvTest, StartThread) {
State state(0, 3); State state(0, 3);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
env_->StartThread(&ThreadBody, &state); env_->StartThread(&ThreadBody, &state);
@ -166,10 +166,10 @@ TEST(EnvTest, StartThread) {
ASSERT_EQ(state.val, 3); ASSERT_EQ(state.val, 3);
} }
TEST(EnvTest, TestOpenNonExistentFile) { TEST_F(EnvTest, TestOpenNonExistentFile) {
// Write some test data to a single file that will be opened |n| times. // Write some test data to a single file that will be opened |n| times.
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string non_existent_file = test_dir + "/non_existent_file"; std::string non_existent_file = test_dir + "/non_existent_file";
ASSERT_TRUE(!env_->FileExists(non_existent_file)); ASSERT_TRUE(!env_->FileExists(non_existent_file));
@ -184,54 +184,57 @@ TEST(EnvTest, TestOpenNonExistentFile) {
ASSERT_TRUE(status.IsNotFound()); ASSERT_TRUE(status.IsNotFound());
} }
TEST(EnvTest, ReopenWritableFile) { TEST_F(EnvTest, ReopenWritableFile) {
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string test_file_name = test_dir + "/reopen_writable_file.txt"; std::string test_file_name = test_dir + "/reopen_writable_file.txt";
env_->DeleteFile(test_file_name); env_->DeleteFile(test_file_name);
WritableFile* writable_file; WritableFile* writable_file;
ASSERT_OK(env_->NewWritableFile(test_file_name, &writable_file)); ASSERT_LEVELDB_OK(env_->NewWritableFile(test_file_name, &writable_file));
std::string data("hello world!"); std::string data("hello world!");
ASSERT_OK(writable_file->Append(data)); ASSERT_LEVELDB_OK(writable_file->Append(data));
ASSERT_OK(writable_file->Close()); ASSERT_LEVELDB_OK(writable_file->Close());
delete writable_file; delete writable_file;
ASSERT_OK(env_->NewWritableFile(test_file_name, &writable_file)); ASSERT_LEVELDB_OK(env_->NewWritableFile(test_file_name, &writable_file));
data = "42"; data = "42";
ASSERT_OK(writable_file->Append(data)); ASSERT_LEVELDB_OK(writable_file->Append(data));
ASSERT_OK(writable_file->Close()); ASSERT_LEVELDB_OK(writable_file->Close());
delete writable_file; delete writable_file;
ASSERT_OK(ReadFileToString(env_, test_file_name, &data)); ASSERT_LEVELDB_OK(ReadFileToString(env_, test_file_name, &data));
ASSERT_EQ(std::string("42"), data); ASSERT_EQ(std::string("42"), data);
env_->DeleteFile(test_file_name); env_->DeleteFile(test_file_name);
} }
TEST(EnvTest, ReopenAppendableFile) { TEST_F(EnvTest, ReopenAppendableFile) {
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string test_file_name = test_dir + "/reopen_appendable_file.txt"; std::string test_file_name = test_dir + "/reopen_appendable_file.txt";
env_->DeleteFile(test_file_name); env_->DeleteFile(test_file_name);
WritableFile* appendable_file; WritableFile* appendable_file;
ASSERT_OK(env_->NewAppendableFile(test_file_name, &appendable_file)); ASSERT_LEVELDB_OK(env_->NewAppendableFile(test_file_name, &appendable_file));
std::string data("hello world!"); std::string data("hello world!");
ASSERT_OK(appendable_file->Append(data)); ASSERT_LEVELDB_OK(appendable_file->Append(data));
ASSERT_OK(appendable_file->Close()); ASSERT_LEVELDB_OK(appendable_file->Close());
delete appendable_file; delete appendable_file;
ASSERT_OK(env_->NewAppendableFile(test_file_name, &appendable_file)); ASSERT_LEVELDB_OK(env_->NewAppendableFile(test_file_name, &appendable_file));
data = "42"; data = "42";
ASSERT_OK(appendable_file->Append(data)); ASSERT_LEVELDB_OK(appendable_file->Append(data));
ASSERT_OK(appendable_file->Close()); ASSERT_LEVELDB_OK(appendable_file->Close());
delete appendable_file; delete appendable_file;
ASSERT_OK(ReadFileToString(env_, test_file_name, &data)); ASSERT_LEVELDB_OK(ReadFileToString(env_, test_file_name, &data));
ASSERT_EQ(std::string("hello world!42"), data); ASSERT_EQ(std::string("hello world!42"), data);
env_->DeleteFile(test_file_name); env_->DeleteFile(test_file_name);
} }
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be // 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. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/env.h" #include "leveldb/env.h"
#include "port/port.h" #include "port/port.h"
#include "util/env_windows_test_helper.h" #include "util/env_windows_test_helper.h"
#include "util/testharness.h" #include "util/testutil.h"
namespace leveldb { namespace leveldb {
static const int kMMapLimit = 4; static const int kMMapLimit = 4;
class EnvWindowsTest { class EnvWindowsTest : public testing::Test {
public: public:
static void SetFileLimits(int mmap_limit) { static void SetFileLimits(int mmap_limit) {
EnvWindowsTestHelper::SetReadOnlyMMapLimit(mmap_limit); EnvWindowsTestHelper::SetReadOnlyMMapLimit(mmap_limit);
@ -23,10 +23,10 @@ class EnvWindowsTest {
Env* env_; Env* env_;
}; };
TEST(EnvWindowsTest, TestOpenOnRead) { TEST_F(EnvWindowsTest, TestOpenOnRead) {
// Write some test data to a single file that will be opened |n| times. // Write some test data to a single file that will be opened |n| times.
std::string test_dir; std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir)); ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
std::string test_file = test_dir + "/open_on_read.txt"; std::string test_file = test_dir + "/open_on_read.txt";
FILE* f = fopen(test_file.c_str(), "w"); FILE* f = fopen(test_file.c_str(), "w");
@ -41,18 +41,18 @@ TEST(EnvWindowsTest, TestOpenOnRead) {
const int kNumFiles = kMMapLimit + 5; const int kNumFiles = kMMapLimit + 5;
leveldb::RandomAccessFile* files[kNumFiles] = {0}; leveldb::RandomAccessFile* files[kNumFiles] = {0};
for (int i = 0; i < kNumFiles; i++) { for (int i = 0; i < kNumFiles; i++) {
ASSERT_OK(env_->NewRandomAccessFile(test_file, &files[i])); ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(test_file, &files[i]));
} }
char scratch; char scratch;
Slice read_result; Slice read_result;
for (int i = 0; i < kNumFiles; i++) { for (int i = 0; i < kNumFiles; i++) {
ASSERT_OK(files[i]->Read(i, 1, &read_result, &scratch)); ASSERT_LEVELDB_OK(files[i]->Read(i, 1, &read_result, &scratch));
ASSERT_EQ(kFileData[i], read_result[0]); ASSERT_EQ(kFileData[i], read_result[0]);
} }
for (int i = 0; i < kNumFiles; i++) { for (int i = 0; i < kNumFiles; i++) {
delete files[i]; delete files[i];
} }
ASSERT_OK(env_->DeleteFile(test_file)); ASSERT_LEVELDB_OK(env_->DeleteFile(test_file));
} }
} // namespace leveldb } // namespace leveldb
@ -60,5 +60,6 @@ TEST(EnvWindowsTest, TestOpenOnRead) {
int main(int argc, char** argv) { int main(int argc, char** argv) {
// All tests currently run with the same read-only file limits. // All tests currently run with the same read-only file limits.
leveldb::EnvWindowsTest::SetFileLimits(leveldb::kMMapLimit); leveldb::EnvWindowsTest::SetFileLimits(leveldb::kMMapLimit);
return leveldb::test::RunAllTests(); testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
} }

View File

@ -3,12 +3,11 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "util/hash.h" #include "util/hash.h"
#include "util/testharness.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
namespace leveldb { namespace leveldb {
class HASH {};
TEST(HASH, SignedUnsignedIssue) { TEST(HASH, SignedUnsignedIssue) {
const uint8_t data1[1] = {0x62}; const uint8_t data1[1] = {0x62};
const uint8_t data2[2] = {0xc3, 0x97}; const uint8_t data2[2] = {0xc3, 0x97};
@ -41,4 +40,7 @@ TEST(HASH, SignedUnsignedIssue) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -2,17 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be // 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. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "util/logging.h"
#include <limits> #include <limits>
#include <string> #include <string>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/slice.h" #include "leveldb/slice.h"
#include "util/logging.h"
#include "util/testharness.h"
namespace leveldb { namespace leveldb {
class Logging {};
TEST(Logging, NumberToString) { TEST(Logging, NumberToString) {
ASSERT_EQ("0", NumberToString(0)); ASSERT_EQ("0", NumberToString(0));
ASSERT_EQ("1", NumberToString(1)); ASSERT_EQ("1", NumberToString(1));
@ -140,4 +139,7 @@ TEST(Logging, ConsumeDecimalNumberNoDigits) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // 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. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "util/no_destructor.h"
#include <cstdint> #include <cstdint>
#include <cstdlib> #include <cstdlib>
#include <utility> #include <utility>
#include "util/no_destructor.h" #include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "util/testharness.h"
namespace leveldb { namespace leveldb {
@ -28,8 +29,6 @@ constexpr const uint64_t kGoldenB = 0xaabbccddeeffaabb;
} // namespace } // namespace
class NoDestructorTest {};
TEST(NoDestructorTest, StackInstance) { TEST(NoDestructorTest, StackInstance) {
NoDestructor<DoNotDestruct> instance(kGoldenA, kGoldenB); NoDestructor<DoNotDestruct> instance(kGoldenA, kGoldenB);
ASSERT_EQ(kGoldenA, instance.get()->a); ASSERT_EQ(kGoldenA, instance.get()->a);
@ -44,4 +43,7 @@ TEST(NoDestructorTest, StaticInstance) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // 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. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "leveldb/status.h"
#include <utility> #include <utility>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/slice.h" #include "leveldb/slice.h"
#include "leveldb/status.h"
#include "util/testharness.h"
namespace leveldb { namespace leveldb {
@ -37,4 +38,7 @@ TEST(Status, MoveConstructor) {
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -1,81 +0,0 @@
// 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 "util/testharness.h"
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string>
#include <vector>
#include "leveldb/env.h"
namespace leveldb {
namespace test {
namespace {
struct Test {
const char* base;
const char* name;
void (*func)();
};
std::vector<Test>* tests;
} // namespace
bool RegisterTest(const char* base, const char* name, void (*func)()) {
if (tests == nullptr) {
tests = new std::vector<Test>;
}
Test t;
t.base = base;
t.name = name;
t.func = func;
tests->push_back(t);
return true;
}
int RunAllTests() {
const char* matcher = getenv("LEVELDB_TESTS");
int num = 0;
if (tests != nullptr) {
for (size_t i = 0; i < tests->size(); i++) {
const Test& t = (*tests)[i];
if (matcher != nullptr) {
std::string name = t.base;
name.push_back('.');
name.append(t.name);
if (strstr(name.c_str(), matcher) == nullptr) {
continue;
}
}
fprintf(stderr, "==== Test %s.%s\n", t.base, t.name);
(*t.func)();
++num;
}
}
fprintf(stderr, "==== PASSED %d tests\n", num);
return 0;
}
std::string TmpDir() {
std::string dir;
Status s = Env::Default()->GetTestDirectory(&dir);
ASSERT_TRUE(s.ok()) << s.ToString();
return dir;
}
int RandomSeed() {
const char* env = getenv("TEST_RANDOM_SEED");
int result = (env != nullptr ? atoi(env) : 301);
if (result <= 0) {
result = 301;
}
return result;
}
} // namespace test
} // namespace leveldb

View File

@ -1,141 +0,0 @@
// 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.
#ifndef STORAGE_LEVELDB_UTIL_TESTHARNESS_H_
#define STORAGE_LEVELDB_UTIL_TESTHARNESS_H_
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include "leveldb/status.h"
namespace leveldb {
namespace test {
// Run some of the tests registered by the TEST() macro. If the
// environment variable "LEVELDB_TESTS" is not set, runs all tests.
// Otherwise, runs only the tests whose name contains the value of
// "LEVELDB_TESTS" as a substring. E.g., suppose the tests are:
// TEST(Foo, Hello) { ... }
// TEST(Foo, World) { ... }
// LEVELDB_TESTS=Hello will run the first test
// LEVELDB_TESTS=o will run both tests
// LEVELDB_TESTS=Junk will run no tests
//
// Returns 0 if all tests pass.
// Dies or returns a non-zero value if some test fails.
int RunAllTests();
// Return the directory to use for temporary storage.
std::string TmpDir();
// Return a randomization seed for this run. Typically returns the
// same number on repeated invocations of this binary, but automated
// runs may be able to vary the seed.
int RandomSeed();
// An instance of Tester is allocated to hold temporary state during
// the execution of an assertion.
class Tester {
private:
bool ok_;
const char* fname_;
int line_;
std::stringstream ss_;
public:
Tester(const char* f, int l) : ok_(true), fname_(f), line_(l) {}
~Tester() {
if (!ok_) {
fprintf(stderr, "%s:%d:%s\n", fname_, line_, ss_.str().c_str());
exit(1);
}
}
Tester& Is(bool b, const char* msg) {
if (!b) {
ss_ << " Assertion failure " << msg;
ok_ = false;
}
return *this;
}
Tester& IsOk(const Status& s) {
if (!s.ok()) {
ss_ << " " << s.ToString();
ok_ = false;
}
return *this;
}
#define BINARY_OP(name, op) \
template <class X, class Y> \
Tester& name(const X& x, const Y& y) { \
if (!(x op y)) { \
ss_ << " failed: " << x << (" " #op " ") << y; \
ok_ = false; \
} \
return *this; \
}
BINARY_OP(IsEq, ==)
BINARY_OP(IsNe, !=)
BINARY_OP(IsGe, >=)
BINARY_OP(IsGt, >)
BINARY_OP(IsLe, <=)
BINARY_OP(IsLt, <)
#undef BINARY_OP
// Attach the specified value to the error message if an error has occurred
template <class V>
Tester& operator<<(const V& value) {
if (!ok_) {
ss_ << " " << value;
}
return *this;
}
};
#define ASSERT_TRUE(c) ::leveldb::test::Tester(__FILE__, __LINE__).Is((c), #c)
#define ASSERT_OK(s) ::leveldb::test::Tester(__FILE__, __LINE__).IsOk((s))
#define ASSERT_EQ(a, b) \
::leveldb::test::Tester(__FILE__, __LINE__).IsEq((a), (b))
#define ASSERT_NE(a, b) \
::leveldb::test::Tester(__FILE__, __LINE__).IsNe((a), (b))
#define ASSERT_GE(a, b) \
::leveldb::test::Tester(__FILE__, __LINE__).IsGe((a), (b))
#define ASSERT_GT(a, b) \
::leveldb::test::Tester(__FILE__, __LINE__).IsGt((a), (b))
#define ASSERT_LE(a, b) \
::leveldb::test::Tester(__FILE__, __LINE__).IsLe((a), (b))
#define ASSERT_LT(a, b) \
::leveldb::test::Tester(__FILE__, __LINE__).IsLt((a), (b))
#define TCONCAT(a, b) TCONCAT1(a, b)
#define TCONCAT1(a, b) a##b
#define TEST(base, name) \
class TCONCAT(_Test_, name) : public base { \
public: \
void _Run(); \
static void _RunIt() { \
TCONCAT(_Test_, name) t; \
t._Run(); \
} \
}; \
bool TCONCAT(_Test_ignored_, name) = ::leveldb::test::RegisterTest( \
#base, #name, &TCONCAT(_Test_, name)::_RunIt); \
void TCONCAT(_Test_, name)::_Run()
// Register the specified test. Typically not used directly, but
// invoked via the macro expansion of TEST.
bool RegisterTest(const char* base, const char* name, void (*func)());
} // namespace test
} // namespace leveldb
#endif // STORAGE_LEVELDB_UTIL_TESTHARNESS_H_

View File

@ -4,6 +4,8 @@
#include "util/testutil.h" #include "util/testutil.h"
#include <string>
#include "util/random.h" #include "util/random.h"
namespace leveldb { namespace leveldb {

View File

@ -5,6 +5,8 @@
#ifndef STORAGE_LEVELDB_UTIL_TESTUTIL_H_ #ifndef STORAGE_LEVELDB_UTIL_TESTUTIL_H_
#define STORAGE_LEVELDB_UTIL_TESTUTIL_H_ #define STORAGE_LEVELDB_UTIL_TESTUTIL_H_
#include "third_party/googletest/googlemock/include/gmock/gmock.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "helpers/memenv/memenv.h" #include "helpers/memenv/memenv.h"
#include "leveldb/env.h" #include "leveldb/env.h"
#include "leveldb/slice.h" #include "leveldb/slice.h"
@ -13,6 +15,20 @@
namespace leveldb { namespace leveldb {
namespace test { namespace test {
MATCHER(IsOK, "") { return arg.ok(); }
// Macros for testing the results of functions that return leveldb::Status or
// util::StatusOr<T> (for any type T).
#define EXPECT_LEVELDB_OK(expression) \
EXPECT_THAT(expression, leveldb::test::IsOK())
#define ASSERT_LEVELDB_OK(expression) \
ASSERT_THAT(expression, leveldb::test::IsOK())
// Returns the random seed used at the start of the current test run.
inline int RandomSeed() {
return testing::UnitTest::GetInstance()->random_seed();
}
// Store in *dst a random string of length "len" and return a Slice that // Store in *dst a random string of length "len" and return a Slice that
// references the generated data. // references the generated data.
Slice RandomString(Random* rnd, int len, std::string* dst); Slice RandomString(Random* rnd, int len, std::string* dst);