Browse Source

Switch testing harness to googletest.

PiperOrigin-RevId: 281815695
baseline
Victor Costan 5 years ago
committed by Victor Costan
parent
commit
1c58902bdc
37 changed files with 763 additions and 863 deletions
  1. +3
    -0
      .gitmodules
  2. +23
    -6
      CMakeLists.txt
  3. +6
    -0
      README.md
  4. +14
    -11
      db/autocompact_test.cc
  5. +38
    -34
      db/corruption_test.cc
  6. +212
    -206
      db/db_test.cc
  7. +6
    -4
      db/dbformat_test.cc
  8. +22
    -18
      db/fault_injection_test.cc
  9. +5
    -4
      db/filename_test.cc
  10. +45
    -42
      db/log_test.cc
  11. +36
    -30
      db/recovery_test.cc
  12. +6
    -4
      db/skiplist_test.cc
  13. +6
    -4
      db/version_edit_test.cc
  14. +21
    -17
      db/version_set_test.cc
  15. +7
    -7
      db/write_batch_test.cc
  16. +70
    -65
      helpers/memenv/memenv_test.cc
  17. +11
    -9
      issues/issue178_test.cc
  18. +14
    -12
      issues/issue200_test.cc
  19. +11
    -8
      issues/issue320_test.cc
  20. +9
    -6
      table/filter_block_test.cc
  21. +19
    -20
      table/table_test.cc
  22. +5
    -4
      util/arena_test.cc
  23. +9
    -7
      util/bloom_test.cc
  24. +16
    -13
      util/cache_test.cc
  25. +7
    -5
      util/coding_test.cc
  26. +6
    -4
      util/crc32c_test.cc
  27. +43
    -40
      util/env_posix_test.cc
  28. +38
    -35
      util/env_test.cc
  29. +10
    -9
      util/env_windows_test.cc
  30. +6
    -4
      util/hash_test.cc
  31. +7
    -5
      util/logging_test.cc
  32. +7
    -5
      util/no_destructor_test.cc
  33. +7
    -3
      util/status_test.cc
  34. +0
    -81
      util/testharness.cc
  35. +0
    -141
      util/testharness.h
  36. +2
    -0
      util/testutil.cc
  37. +16
    -0
      util/testutil.h

+ 3
- 0
.gitmodules View File

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

+ 23
- 6
CMakeLists.txt View File

@ -84,6 +84,10 @@ endif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
include(CheckCXXCompilerFlag)
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)
# Test whether C++17 __has_include is available.
@ -288,6 +292,23 @@ target_link_libraries(leveldbutil leveldb)
if(LEVELDB_BUILD_TESTS)
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)
get_filename_component(test_target_name "${test_file}" NAME_WE)
@ -295,14 +316,12 @@ if(LEVELDB_BUILD_TESTS)
target_sources("${test_target_name}"
PRIVATE
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
"util/testharness.cc"
"util/testharness.h"
"util/testutil.cc"
"util/testutil.h"
"${test_file}"
)
target_link_libraries("${test_target_name}" leveldb)
target_link_libraries("${test_target_name}" leveldb gmock gtest)
target_compile_definitions("${test_target_name}"
PRIVATE
${LEVELDB_PLATFORM_NAME}=1
@ -374,14 +393,12 @@ if(LEVELDB_BUILD_BENCHMARKS)
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
"util/histogram.cc"
"util/histogram.h"
"util/testharness.cc"
"util/testharness.h"
"util/testutil.cc"
"util/testutil.h"
"${bench_file}"
)
target_link_libraries("${bench_target_name}" leveldb)
target_link_libraries("${bench_target_name}" leveldb gmock gtest)
target_compile_definitions("${bench_target_name}"
PRIVATE
${LEVELDB_PLATFORM_NAME}=1

+ 6
- 0
README.md 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.
* 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
This project supports [CMake](https://cmake.org/) out of the box.

+ 14
- 11
db/autocompact_test.cc View File

@ -2,24 +2,24 @@
// 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 "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/db_impl.h"
#include "leveldb/cache.h"
#include "leveldb/db.h"
#include "util/testharness.h"
#include "util/testutil.h"
namespace leveldb {
class AutoCompactTest {
class AutoCompactTest : public testing::Test {
public:
AutoCompactTest() {
dbname_ = test::TmpDir() + "/autocompact_test";
dbname_ = testing::TempDir() + "autocompact_test";
tiny_cache_ = NewLRUCache(100);
options_.block_cache = tiny_cache_;
DestroyDB(dbname_, options_);
options_.create_if_missing = true;
options_.compression = kNoCompression;
ASSERT_OK(DB::Open(options_, dbname_, &db_));
EXPECT_LEVELDB_OK(DB::Open(options_, dbname_, &db_));
}
~AutoCompactTest() {
@ -62,15 +62,15 @@ void AutoCompactTest::DoReads(int n) {
// Fill database
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
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.
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);
}
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
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

+ 38
- 34
db/corruption_test.cc View File

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

+ 212
- 206
db/db_test.cc
File diff suppressed because it is too large
View File


+ 6
- 4
db/dbformat_test.cc View File

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

+ 22
- 18
db/fault_injection_test.cc View File

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

+ 5
- 4
db/filename_test.cc View File

@ -4,15 +4,13 @@
#include "db/filename.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/dbformat.h"
#include "port/port.h"
#include "util/logging.h"
#include "util/testharness.h"
namespace leveldb {
class FileNameTest {};
TEST(FileNameTest, Parse) {
Slice db;
FileType type;
@ -128,4 +126,7 @@ TEST(FileNameTest, Construction) {
} // 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();
}

+ 45
- 42
db/log_test.cc View File

@ -2,13 +2,13 @@
// 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 "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/log_reader.h"
#include "db/log_writer.h"
#include "leveldb/env.h"
#include "util/coding.h"
#include "util/crc32c.h"
#include "util/random.h"
#include "util/testharness.h"
namespace leveldb {
namespace log {
@ -36,7 +36,7 @@ static std::string RandomSkewedString(int i, Random* rnd) {
return BigString(NumberString(i), rnd->Skewed(17));
}
class LogTest {
class LogTest : public testing::Test {
public:
LogTest()
: reading_(false),
@ -177,7 +177,7 @@ class LogTest {
StringSource() : force_error_(false), returned_partial_(false) {}
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_) {
force_error_ = false;
@ -258,9 +258,9 @@ uint64_t LogTest::initial_offset_last_record_offsets_[] = {
int LogTest::num_initial_offset_records_ =
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("bar");
Write("");
@ -273,7 +273,7 @@ TEST(LogTest, ReadWrite) {
ASSERT_EQ("EOF", Read()); // Make sure reads at eof work
}
TEST(LogTest, ManyBlocks) {
TEST_F(LogTest, ManyBlocks) {
for (int i = 0; i < 100000; i++) {
Write(NumberString(i));
}
@ -283,7 +283,7 @@ TEST(LogTest, ManyBlocks) {
ASSERT_EQ("EOF", Read());
}
TEST(LogTest, Fragmentation) {
TEST_F(LogTest, Fragmentation) {
Write("small");
Write(BigString("medium", 50000));
Write(BigString("large", 100000));
@ -293,7 +293,7 @@ TEST(LogTest, Fragmentation) {
ASSERT_EQ("EOF", Read());
}
TEST(LogTest, MarginalTrailer) {
TEST_F(LogTest, MarginalTrailer) {
// Make a trailer that is exactly the same length as an empty record.
const int n = kBlockSize - 2 * kHeaderSize;
Write(BigString("foo", n));
@ -306,7 +306,7 @@ TEST(LogTest, MarginalTrailer) {
ASSERT_EQ("EOF", Read());
}
TEST(LogTest, MarginalTrailer2) {
TEST_F(LogTest, MarginalTrailer2) {
// Make a trailer that is exactly the same length as an empty record.
const int n = kBlockSize - 2 * kHeaderSize;
Write(BigString("foo", n));
@ -319,7 +319,7 @@ TEST(LogTest, MarginalTrailer2) {
ASSERT_EQ("", ReportMessage());
}
TEST(LogTest, ShortTrailer) {
TEST_F(LogTest, ShortTrailer) {
const int n = kBlockSize - 2 * kHeaderSize + 4;
Write(BigString("foo", n));
ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
@ -331,7 +331,7 @@ TEST(LogTest, ShortTrailer) {
ASSERT_EQ("EOF", Read());
}
TEST(LogTest, AlignedEof) {
TEST_F(LogTest, AlignedEof) {
const int n = kBlockSize - 2 * kHeaderSize + 4;
Write(BigString("foo", n));
ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
@ -339,7 +339,7 @@ TEST(LogTest, AlignedEof) {
ASSERT_EQ("EOF", Read());
}
TEST(LogTest, OpenForAppend) {
TEST_F(LogTest, OpenForAppend) {
Write("hello");
ReopenForAppend();
Write("world");
@ -348,7 +348,7 @@ TEST(LogTest, OpenForAppend) {
ASSERT_EQ("EOF", Read());
}
TEST(LogTest, RandomRead) {
TEST_F(LogTest, RandomRead) {
const int N = 500;
Random write_rnd(301);
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:
TEST(LogTest, ReadError) {
TEST_F(LogTest, ReadError) {
Write("foo");
ForceError();
ASSERT_EQ("EOF", Read());
@ -371,7 +371,7 @@ TEST(LogTest, ReadError) {
ASSERT_EQ("OK", MatchError("read error"));
}
TEST(LogTest, BadRecordType) {
TEST_F(LogTest, BadRecordType) {
Write("foo");
// Type is stored in header[6]
IncrementByte(6, 100);
@ -381,7 +381,7 @@ TEST(LogTest, BadRecordType) {
ASSERT_EQ("OK", MatchError("unknown record type"));
}
TEST(LogTest, TruncatedTrailingRecordIsIgnored) {
TEST_F(LogTest, TruncatedTrailingRecordIsIgnored) {
Write("foo");
ShrinkSize(4); // Drop all payload as well as a header byte
ASSERT_EQ("EOF", Read());
@ -390,7 +390,7 @@ TEST(LogTest, TruncatedTrailingRecordIsIgnored) {
ASSERT_EQ("", ReportMessage());
}
TEST(LogTest, BadLength) {
TEST_F(LogTest, BadLength) {
const int kPayloadSize = kBlockSize - kHeaderSize;
Write(BigString("bar", kPayloadSize));
Write("foo");
@ -401,7 +401,7 @@ TEST(LogTest, BadLength) {
ASSERT_EQ("OK", MatchError("bad record length"));
}
TEST(LogTest, BadLengthAtEndIsIgnored) {
TEST_F(LogTest, BadLengthAtEndIsIgnored) {
Write("foo");
ShrinkSize(1);
ASSERT_EQ("EOF", Read());
@ -409,7 +409,7 @@ TEST(LogTest, BadLengthAtEndIsIgnored) {
ASSERT_EQ("", ReportMessage());
}
TEST(LogTest, ChecksumMismatch) {
TEST_F(LogTest, ChecksumMismatch) {
Write("foo");
IncrementByte(0, 10);
ASSERT_EQ("EOF", Read());
@ -417,7 +417,7 @@ TEST(LogTest, ChecksumMismatch) {
ASSERT_EQ("OK", MatchError("checksum mismatch"));
}
TEST(LogTest, UnexpectedMiddleType) {
TEST_F(LogTest, UnexpectedMiddleType) {
Write("foo");
SetByte(6, kMiddleType);
FixChecksum(0, 3);
@ -426,7 +426,7 @@ TEST(LogTest, UnexpectedMiddleType) {
ASSERT_EQ("OK", MatchError("missing start"));
}
TEST(LogTest, UnexpectedLastType) {
TEST_F(LogTest, UnexpectedLastType) {
Write("foo");
SetByte(6, kLastType);
FixChecksum(0, 3);
@ -435,7 +435,7 @@ TEST(LogTest, UnexpectedLastType) {
ASSERT_EQ("OK", MatchError("missing start"));
}
TEST(LogTest, UnexpectedFullType) {
TEST_F(LogTest, UnexpectedFullType) {
Write("foo");
Write("bar");
SetByte(6, kFirstType);
@ -446,7 +446,7 @@ TEST(LogTest, UnexpectedFullType) {
ASSERT_EQ("OK", MatchError("partial record without end"));
}
TEST(LogTest, UnexpectedFirstType) {
TEST_F(LogTest, UnexpectedFirstType) {
Write("foo");
Write(BigString("bar", 100000));
SetByte(6, kFirstType);
@ -457,7 +457,7 @@ TEST(LogTest, UnexpectedFirstType) {
ASSERT_EQ("OK", MatchError("partial record without end"));
}
TEST(LogTest, MissingLastIsIgnored) {
TEST_F(LogTest, MissingLastIsIgnored) {
Write(BigString("bar", kBlockSize));
// Remove the LAST block, including header.
ShrinkSize(14);
@ -466,7 +466,7 @@ TEST(LogTest, MissingLastIsIgnored) {
ASSERT_EQ(0, DroppedBytes());
}
TEST(LogTest, PartialLastIsIgnored) {
TEST_F(LogTest, PartialLastIsIgnored) {
Write(BigString("bar", kBlockSize));
// Cause a bad record length in the LAST block.
ShrinkSize(1);
@ -475,7 +475,7 @@ TEST(LogTest, PartialLastIsIgnored) {
ASSERT_EQ(0, DroppedBytes());
}
TEST(LogTest, SkipIntoMultiRecord) {
TEST_F(LogTest, SkipIntoMultiRecord) {
// Consider a fragmented record:
// first(R1), middle(R1), last(R1), 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());
}
TEST(LogTest, ErrorJoinsRecords) {
TEST_F(LogTest, ErrorJoinsRecords) {
// Consider two fragmented records:
// first(R1) last(R1) first(R2) last(R2)
// where the middle two fragments disappear. We do not want
@ -514,47 +514,50 @@ TEST(LogTest, ErrorJoinsRecords) {
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);
}
TEST(LogTest, ReadFourthMiddleBlock) {
TEST_F(LogTest, ReadFourthMiddleBlock) {
CheckInitialOffsetRecord(log::kBlockSize + 1, 3);
}
TEST(LogTest, ReadFourthLastBlock) {
TEST_F(LogTest, ReadFourthLastBlock) {
CheckInitialOffsetRecord(2 * log::kBlockSize + 1, 3);
}
TEST(LogTest, ReadFourthStart) {
TEST_F(LogTest, ReadFourthStart) {
CheckInitialOffsetRecord(
2 * (kHeaderSize + 1000) + (2 * log::kBlockSize - 1000) + 3 * kHeaderSize,
3);
}
TEST(LogTest, ReadInitialOffsetIntoBlockPadding) {
TEST_F(LogTest, ReadInitialOffsetIntoBlockPadding) {
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 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();
}

+ 36
- 30
db/recovery_test.cc View File

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

+ 6
- 4
db/skiplist_test.cc View File

@ -7,13 +7,14 @@
#include <atomic>
#include <set>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/env.h"
#include "port/port.h"
#include "port/thread_annotations.h"
#include "util/arena.h"
#include "util/hash.h"
#include "util/random.h"
#include "util/testharness.h"
#include "util/testutil.h"
namespace leveldb {
@ -31,8 +32,6 @@ struct Comparator {
}
};
class SkipTest {};
TEST(SkipTest, Empty) {
Arena arena;
Comparator cmp;
@ -366,4 +365,7 @@ TEST(SkipTest, Concurrent5) { RunConcurrent(5); }
} // 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();
}

+ 6
- 4
db/version_edit_test.cc View File

@ -3,7 +3,8 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/version_edit.h"
#include "util/testharness.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
namespace leveldb {
@ -17,8 +18,6 @@ static void TestEncodeDecode(const VersionEdit& edit) {
ASSERT_EQ(encoded, encoded2);
}
class VersionEditTest {};
TEST(VersionEditTest, EncodeDecode) {
static const uint64_t kBig = 1ull << 50;
@ -41,4 +40,7 @@ TEST(VersionEditTest, EncodeDecode) {
} // 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();
}

+ 21
- 17
db/version_set_test.cc View File

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

+ 7
- 7
db/write_batch_test.cc View File

@ -2,13 +2,12 @@
// 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 "leveldb/db.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/memtable.h"
#include "db/write_batch_internal.h"
#include "leveldb/db.h"
#include "leveldb/env.h"
#include "util/logging.h"
#include "util/testharness.h"
namespace leveldb {
@ -22,7 +21,7 @@ static std::string PrintContents(WriteBatch* b) {
Iterator* iter = mem->NewIterator();
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
ParsedInternalKey ikey;
ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey));
EXPECT_TRUE(ParseInternalKey(iter->key(), &ikey));
switch (ikey.type) {
case kTypeValue:
state.append("Put(");
@ -52,8 +51,6 @@ static std::string PrintContents(WriteBatch* b) {
return state;
}
class WriteBatchTest {};
TEST(WriteBatchTest, Empty) {
WriteBatch batch;
ASSERT_EQ("", PrintContents(&batch));
@ -134,4 +131,7 @@ TEST(WriteBatchTest, ApproximateSize) {
} // 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();
}

+ 70
- 65
helpers/memenv/memenv_test.cc View File

@ -7,14 +7,15 @@
#include <string>
#include <vector>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "db/db_impl.h"
#include "leveldb/db.h"
#include "leveldb/env.h"
#include "util/testharness.h"
#include "util/testutil.h"
namespace leveldb {
class MemEnvTest {
class MemEnvTest : public testing::Test {
public:
MemEnvTest() : env_(NewMemEnv(Env::Default())) {}
~MemEnvTest() { delete env_; }
@ -22,55 +23,55 @@ class MemEnvTest {
Env* env_;
};
TEST(MemEnvTest, Basics) {
TEST_F(MemEnvTest, Basics) {
uint64_t file_size;
WritableFile* writable_file;
std::vector<std::string> children;
ASSERT_OK(env_->CreateDir("/dir"));
ASSERT_LEVELDB_OK(env_->CreateDir("/dir"));
// Check that the directory is empty.
ASSERT_TRUE(!env_->FileExists("/dir/non_existent"));
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());
// Create a file.
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/f", &file_size));
ASSERT_EQ(0, file_size);
delete writable_file;
// Check that the file exists.
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_OK(env_->GetChildren("/dir", &children));
ASSERT_LEVELDB_OK(env_->GetChildren("/dir", &children));
ASSERT_EQ(1, children.size());
ASSERT_EQ("f", children[0]);
// Write to the file.
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_OK(writable_file->Append("abc"));
ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_LEVELDB_OK(writable_file->Append("abc"));
delete writable_file;
// Check that append works.
ASSERT_OK(env_->NewAppendableFile("/dir/f", &writable_file));
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
ASSERT_LEVELDB_OK(env_->NewAppendableFile("/dir/f", &writable_file));
ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/f", &file_size));
ASSERT_EQ(3, file_size);
ASSERT_OK(writable_file->Append("hello"));
ASSERT_LEVELDB_OK(writable_file->Append("hello"));
delete writable_file;
// 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);
// Check that renaming works.
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/g"));
ASSERT_OK(env_->GetFileSize("/dir/g", &file_size));
ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/g", &file_size));
ASSERT_EQ(8, file_size);
// Check that opening non-existent file fails.
@ -83,48 +84,49 @@ TEST(MemEnvTest, Basics) {
// Check that deleting works.
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_OK(env_->GetChildren("/dir", &children));
ASSERT_LEVELDB_OK(env_->GetChildren("/dir", &children));
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;
SequentialFile* seq_file;
RandomAccessFile* rand_file;
Slice result;
char scratch[100];
ASSERT_OK(env_->CreateDir("/dir"));
ASSERT_LEVELDB_OK(env_->CreateDir("/dir"));
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_OK(writable_file->Append("hello "));
ASSERT_OK(writable_file->Append("world"));
ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_LEVELDB_OK(writable_file->Append("hello "));
ASSERT_LEVELDB_OK(writable_file->Append("world"));
delete writable_file;
// Read sequentially.
ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file));
ASSERT_OK(seq_file->Read(5, &result, scratch)); // Read "hello".
ASSERT_LEVELDB_OK(env_->NewSequentialFile("/dir/f", &seq_file));
ASSERT_LEVELDB_OK(seq_file->Read(5, &result, scratch)); // Read "hello".
ASSERT_EQ(0, result.compare("hello"));
ASSERT_OK(seq_file->Skip(1));
ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Read "world".
ASSERT_LEVELDB_OK(seq_file->Skip(1));
ASSERT_LEVELDB_OK(seq_file->Read(1000, &result, scratch)); // Read "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_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->Skip(100)); // Try to skip past end of file.
ASSERT_LEVELDB_OK(seq_file->Read(1000, &result, scratch));
ASSERT_EQ(0, result.size());
delete seq_file;
// Random reads.
ASSERT_OK(env_->NewRandomAccessFile("/dir/f", &rand_file));
ASSERT_OK(rand_file->Read(6, 5, &result, scratch)); // Read "world".
ASSERT_LEVELDB_OK(env_->NewRandomAccessFile("/dir/f", &rand_file));
ASSERT_LEVELDB_OK(rand_file->Read(6, 5, &result, scratch)); // Read "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_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"));
// Too high offset.
@ -132,30 +134,30 @@ TEST(MemEnvTest, ReadWrite) {
delete rand_file;
}
TEST(MemEnvTest, Locks) {
TEST_F(MemEnvTest, Locks) {
FileLock* lock;
// These are no-ops, but we test they return success.
ASSERT_OK(env_->LockFile("some file", &lock));
ASSERT_OK(env_->UnlockFile(lock));
ASSERT_LEVELDB_OK(env_->LockFile("some file", &lock));
ASSERT_LEVELDB_OK(env_->UnlockFile(lock));
}
TEST(MemEnvTest, Misc) {
TEST_F(MemEnvTest, Misc) {
std::string test_dir;
ASSERT_OK(env_->GetTestDirectory(&test_dir));
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
ASSERT_TRUE(!test_dir.empty());
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.
ASSERT_OK(writable_file->Sync());
ASSERT_OK(writable_file->Flush());
ASSERT_OK(writable_file->Close());
ASSERT_LEVELDB_OK(writable_file->Sync());
ASSERT_LEVELDB_OK(writable_file->Flush());
ASSERT_LEVELDB_OK(writable_file->Close());
delete writable_file;
}
TEST(MemEnvTest, LargeWrite) {
TEST_F(MemEnvTest, LargeWrite) {
const size_t kWriteSize = 300 * 1024;
char* scratch = new char[kWriteSize * 2];
@ -165,21 +167,21 @@ TEST(MemEnvTest, LargeWrite) {
}
WritableFile* writable_file;
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_OK(writable_file->Append("foo"));
ASSERT_OK(writable_file->Append(write_data));
ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
ASSERT_LEVELDB_OK(writable_file->Append("foo"));
ASSERT_LEVELDB_OK(writable_file->Append(write_data));
delete writable_file;
SequentialFile* seq_file;
Slice result;
ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file));
ASSERT_OK(seq_file->Read(3, &result, scratch)); // Read "foo".
ASSERT_LEVELDB_OK(env_->NewSequentialFile("/dir/f", &seq_file));
ASSERT_LEVELDB_OK(seq_file->Read(3, &result, scratch)); // Read "foo".
ASSERT_EQ(0, result.compare("foo"));
size_t read = 0;
std::string read_data;
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 += result.size();
}
@ -188,30 +190,30 @@ TEST(MemEnvTest, LargeWrite) {
delete[] scratch;
}
TEST(MemEnvTest, OverwriteOpenFile) {
TEST_F(MemEnvTest, OverwriteOpenFile) {
const char kWrite1Data[] = "Write #1 data";
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;
ASSERT_OK(env_->NewRandomAccessFile(kTestFileName, &rand_file));
ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(kTestFileName, &rand_file));
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
// being read from files opened before the write.
Slice result;
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));
delete rand_file;
}
TEST(MemEnvTest, DBTest) {
TEST_F(MemEnvTest, DBTest) {
Options options;
options.create_if_missing = true;
options.env = env_;
@ -220,14 +222,14 @@ TEST(MemEnvTest, DBTest) {
const Slice keys[] = {Slice("aaa"), Slice("bbb"), Slice("ccc")};
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) {
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) {
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]);
}
@ -243,11 +245,11 @@ TEST(MemEnvTest, DBTest) {
delete iterator;
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) {
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]);
}
@ -256,4 +258,7 @@ TEST(MemEnvTest, DBTest) {
} // 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();
}

+ 11
- 9
issues/issue178_test.cc View File

@ -7,9 +7,10 @@
#include <iostream>
#include <sstream>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/db.h"
#include "leveldb/write_batch.h"
#include "util/testharness.h"
#include "util/testutil.h"
namespace {
@ -23,11 +24,9 @@ std::string Key1(int i) {
std::string Key2(int i) { return Key1(i) + "_xxx"; }
class Issue178 {};
TEST(Issue178, Test) {
// 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());
// Open database. Disable compression since it affects the creation
@ -37,28 +36,28 @@ TEST(Issue178, Test) {
leveldb::Options db_options;
db_options.create_if_missing = true;
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
leveldb::WriteBatch batch;
for (size_t i = 0; i < kNumKeys; i++) {
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
batch.Clear();
for (size_t i = 0; i < kNumKeys; i++) {
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
batch.Clear();
for (size_t i = 0; i < kNumKeys; i++) {
batch.Delete(Key2(i));
}
ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));
ASSERT_LEVELDB_OK(db->Write(leveldb::WriteOptions(), &batch));
// compact database
std::string start_key = Key1(0);
@ -85,4 +84,7 @@ TEST(Issue178, Test) {
} // 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();
}

+ 14
- 12
issues/issue200_test.cc View File

@ -6,35 +6,34 @@
// to forward, the current key can be yielded unexpectedly if a new
// mutation has been added just before the current key.
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/db.h"
#include "util/testharness.h"
#include "util/testutil.h"
namespace leveldb {
class Issue200 {};
TEST(Issue200, Test) {
// 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());
DB* db;
Options options;
options.create_if_missing = true;
ASSERT_OK(DB::Open(options, dbpath, &db));
ASSERT_LEVELDB_OK(DB::Open(options, dbpath, &db));
WriteOptions write_options;
ASSERT_OK(db->Put(write_options, "1", "b"));
ASSERT_OK(db->Put(write_options, "2", "c"));
ASSERT_OK(db->Put(write_options, "3", "d"));
ASSERT_OK(db->Put(write_options, "4", "e"));
ASSERT_OK(db->Put(write_options, "5", "f"));
ASSERT_LEVELDB_OK(db->Put(write_options, "1", "b"));
ASSERT_LEVELDB_OK(db->Put(write_options, "2", "c"));
ASSERT_LEVELDB_OK(db->Put(write_options, "3", "d"));
ASSERT_LEVELDB_OK(db->Put(write_options, "4", "e"));
ASSERT_LEVELDB_OK(db->Put(write_options, "5", "f"));
ReadOptions read_options;
Iterator* iter = db->NewIterator(read_options);
// 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");
ASSERT_EQ(iter->key().ToString(), "5");
@ -54,4 +53,7 @@ TEST(Issue200, Test) {
} // 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();
}

+ 11
- 8
issues/issue320_test.cc View File

@ -9,9 +9,10 @@
#include <string>
#include <vector>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/db.h"
#include "leveldb/write_batch.h"
#include "util/testharness.h"
#include "util/testutil.h"
namespace leveldb {
@ -37,8 +38,6 @@ std::string CreateRandomString(int32_t index) {
} // namespace
class Issue320 {};
TEST(Issue320, Test) {
std::srand(0);
@ -53,8 +52,8 @@ TEST(Issue320, Test) {
Options options;
options.create_if_missing = true;
std::string dbpath = test::TmpDir() + "/leveldb_issue320_test";
ASSERT_OK(DB::Open(options, dbpath, &db));
std::string dbpath = testing::TempDir() + "leveldb_issue320_test";
ASSERT_LEVELDB_OK(DB::Open(options, dbpath, &db));
uint32_t target_size = 10000;
uint32_t num_items = 0;
@ -78,7 +77,8 @@ TEST(Issue320, Test) {
CreateRandomString(index), CreateRandomString(index)));
batch.Put(test_map[index]->first, test_map[index]->second);
} 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) {
std::cout << "ERROR incorrect value returned by Get" << 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) {
int i = GenerateRandomNumber(snapshots.size());
@ -125,4 +125,7 @@ TEST(Issue320, Test) {
} // 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();
}

+ 9
- 6
table/filter_block_test.cc View File

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

+ 19
- 20
table/table_test.cc View File

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

+ 5
- 4
util/arena_test.cc View File

@ -4,13 +4,11 @@
#include "util/arena.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "util/random.h"
#include "util/testharness.h"
namespace leveldb {
class ArenaTest {};
TEST(ArenaTest, Empty) { Arena arena; }
TEST(ArenaTest, Simple) {
@ -62,4 +60,7 @@ TEST(ArenaTest, Simple) {
} // 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();
}

+ 9
- 7
util/bloom_test.cc View File

@ -2,11 +2,10 @@
// 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 "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/filter_policy.h"
#include "util/coding.h"
#include "util/logging.h"
#include "util/testharness.h"
#include "util/testutil.h"
namespace leveldb {
@ -18,7 +17,7 @@ static Slice Key(int i, char* buffer) {
return Slice(buffer, sizeof(uint32_t));
}
class BloomTest {
class BloomTest : public testing::Test {
public:
BloomTest() : policy_(NewBloomFilterPolicy(10)) {}
@ -80,12 +79,12 @@ class BloomTest {
std::vector<std::string> keys_;
};
TEST(BloomTest, EmptyFilter) {
TEST_F(BloomTest, EmptyFilter) {
ASSERT_TRUE(!Matches("hello"));
ASSERT_TRUE(!Matches("world"));
}
TEST(BloomTest, Small) {
TEST_F(BloomTest, Small) {
Add("hello");
Add("world");
ASSERT_TRUE(Matches("hello"));
@ -107,7 +106,7 @@ static int NextLength(int length) {
return length;
}
TEST(BloomTest, VaryingLengths) {
TEST_F(BloomTest, VaryingLengths) {
char buffer[sizeof(int)];
// Count number of filters that significantly exceed the false positive rate
@ -153,4 +152,7 @@ TEST(BloomTest, VaryingLengths) {
} // 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();
}

+ 16
- 13
util/cache_test.cc View File

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

+ 7
- 5
util/coding_test.cc View File

@ -2,15 +2,14 @@
// 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/coding.h"
#include <vector>
#include "util/coding.h"
#include "util/testharness.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
namespace leveldb {
class Coding {};
TEST(Coding, Fixed32) {
std::string s;
for (uint32_t v = 0; v < 100000; v++) {
@ -193,4 +192,7 @@ TEST(Coding, Strings) {
} // 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();
}

+ 6
- 4
util/crc32c_test.cc View File

@ -3,13 +3,12 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "util/crc32c.h"
#include "util/testharness.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
namespace leveldb {
namespace crc32c {
class CRC {};
TEST(CRC, StandardResults) {
// From rfc3720 section B.4.
char buf[32];
@ -56,4 +55,7 @@ TEST(CRC, Mask) {
} // namespace crc32c
} // 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();
}

+ 43
- 40
util/env_posix_test.cc View File

@ -13,10 +13,11 @@
#include <unordered_set>
#include <vector>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/env.h"
#include "port/port.h"
#include "util/env_posix_test_helper.h"
#include "util/testharness.h"
#include "util/testutil.h"
#if HAVE_O_CLOEXEC
@ -168,7 +169,7 @@ namespace leveldb {
static const int kReadOnlyFileLimit = 4;
static const int kMMapLimit = 4;
class EnvPosixTest {
class EnvPosixTest : public testing::Test {
public:
static void SetFileLimits(int read_only_file_limit, int mmap_limit) {
EnvPosixTestHelper::SetReadOnlyFDLimit(read_only_file_limit);
@ -180,10 +181,10 @@ class EnvPosixTest {
Env* env_;
};
TEST(EnvPosixTest, TestOpenOnRead) {
TEST_F(EnvPosixTest, TestOpenOnRead) {
// Write some test data to a single file that will be opened |n| times.
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";
FILE* f = fopen(test_file.c_str(), "we");
@ -197,133 +198,133 @@ TEST(EnvPosixTest, TestOpenOnRead) {
const int kNumFiles = kReadOnlyFileLimit + kMMapLimit + 5;
leveldb::RandomAccessFile* files[kNumFiles] = {0};
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;
Slice read_result;
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]);
}
for (int i = 0; i < kNumFiles; i++) {
delete files[i];
}
ASSERT_OK(env_->DeleteFile(test_file));
ASSERT_LEVELDB_OK(env_->DeleteFile(test_file));
}
#if HAVE_O_CLOEXEC
TEST(EnvPosixTest, TestCloseOnExecSequentialFile) {
TEST_F(EnvPosixTest, TestCloseOnExecSequentialFile) {
std::unordered_set<int> open_fds;
GetOpenFileDescriptors(&open_fds);
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";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
leveldb::SequentialFile* file = nullptr;
ASSERT_OK(env_->NewSequentialFile(file_path, &file));
ASSERT_LEVELDB_OK(env_->NewSequentialFile(file_path, &file));
CheckCloseOnExecDoesNotLeakFDs(open_fds);
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;
GetOpenFileDescriptors(&open_fds);
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";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
// Exhaust the RandomAccessFile mmap limit. This way, the test
// RandomAccessFile instance below is backed by a file descriptor, not by an
// mmap region.
leveldb::RandomAccessFile* mmapped_files[kReadOnlyFileLimit] = {nullptr};
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;
ASSERT_OK(env_->NewRandomAccessFile(file_path, &file));
ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(file_path, &file));
CheckCloseOnExecDoesNotLeakFDs(open_fds);
delete file;
for (int i = 0; i < kReadOnlyFileLimit; 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;
GetOpenFileDescriptors(&open_fds);
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";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
leveldb::WritableFile* file = nullptr;
ASSERT_OK(env_->NewWritableFile(file_path, &file));
ASSERT_LEVELDB_OK(env_->NewWritableFile(file_path, &file));
CheckCloseOnExecDoesNotLeakFDs(open_fds);
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;
GetOpenFileDescriptors(&open_fds);
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";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
leveldb::WritableFile* file = nullptr;
ASSERT_OK(env_->NewAppendableFile(file_path, &file));
ASSERT_LEVELDB_OK(env_->NewAppendableFile(file_path, &file));
CheckCloseOnExecDoesNotLeakFDs(open_fds);
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;
GetOpenFileDescriptors(&open_fds);
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";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
leveldb::FileLock* lock = nullptr;
ASSERT_OK(env_->LockFile(file_path, &lock));
ASSERT_LEVELDB_OK(env_->LockFile(file_path, &lock));
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;
GetOpenFileDescriptors(&open_fds);
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";
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
leveldb::Logger* file = nullptr;
ASSERT_OK(env_->NewLogger(file_path, &file));
ASSERT_LEVELDB_OK(env_->NewLogger(file_path, &file));
CheckCloseOnExecDoesNotLeakFDs(open_fds);
delete file;
ASSERT_OK(env_->DeleteFile(file_path));
ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
}
#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.
leveldb::EnvPosixTest::SetFileLimits(leveldb::kReadOnlyFileLimit,
leveldb::kMMapLimit);
return leveldb::test::RunAllTests();
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

+ 38
- 35
util/env_test.cc View File

@ -6,32 +6,32 @@
#include <algorithm>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "port/port.h"
#include "port/thread_annotations.h"
#include "util/mutexlock.h"
#include "util/testharness.h"
#include "util/testutil.h"
namespace leveldb {
static const int kDelayMicros = 100000;
class EnvTest {
class EnvTest : public testing::Test {
public:
EnvTest() : env_(Env::Default()) {}
Env* env_;
};
TEST(EnvTest, ReadWrite) {
TEST_F(EnvTest, ReadWrite) {
Random rnd(test::RandomSeed());
// Get file to use for testing.
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";
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.
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
std::string r;
test::RandomString(&rnd, len, &r);
ASSERT_OK(writable_file->Append(r));
ASSERT_LEVELDB_OK(writable_file->Append(r));
data += r;
if (rnd.OneIn(10)) {
ASSERT_OK(writable_file->Flush());
ASSERT_LEVELDB_OK(writable_file->Flush());
}
}
ASSERT_OK(writable_file->Sync());
ASSERT_OK(writable_file->Close());
ASSERT_LEVELDB_OK(writable_file->Sync());
ASSERT_LEVELDB_OK(writable_file->Close());
delete writable_file;
// Read all data using a sequence of randomly sized reads.
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 scratch;
while (read_result.size() < data.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
Slice read;
ASSERT_OK(sequential_file->Read(len, &read, &scratch[0]));
ASSERT_LEVELDB_OK(sequential_file->Read(len, &read, &scratch[0]));
if (len > 0) {
ASSERT_GT(read.size(), 0);
}
@ -70,7 +70,7 @@ TEST(EnvTest, ReadWrite) {
delete sequential_file;
}
TEST(EnvTest, RunImmediately) {
TEST_F(EnvTest, RunImmediately) {
struct RunState {
port::Mutex mu;
port::CondVar cvar{&mu};
@ -94,7 +94,7 @@ TEST(EnvTest, RunImmediately) {
}
}
TEST(EnvTest, RunMany) {
TEST_F(EnvTest, RunMany) {
struct RunState {
port::Mutex mu;
port::CondVar cvar{&mu};
@ -153,7 +153,7 @@ static void ThreadBody(void* arg) {
s->mu.Unlock();
}
TEST(EnvTest, StartThread) {
TEST_F(EnvTest, StartThread) {
State state(0, 3);
for (int i = 0; i < 3; i++) {
env_->StartThread(&ThreadBody, &state);
@ -166,10 +166,10 @@ TEST(EnvTest, StartThread) {
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.
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";
ASSERT_TRUE(!env_->FileExists(non_existent_file));
@ -184,54 +184,57 @@ TEST(EnvTest, TestOpenNonExistentFile) {
ASSERT_TRUE(status.IsNotFound());
}
TEST(EnvTest, ReopenWritableFile) {
TEST_F(EnvTest, ReopenWritableFile) {
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";
env_->DeleteFile(test_file_name);
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!");
ASSERT_OK(writable_file->Append(data));
ASSERT_OK(writable_file->Close());
ASSERT_LEVELDB_OK(writable_file->Append(data));
ASSERT_LEVELDB_OK(writable_file->Close());
delete writable_file;
ASSERT_OK(env_->NewWritableFile(test_file_name, &writable_file));
ASSERT_LEVELDB_OK(env_->NewWritableFile(test_file_name, &writable_file));
data = "42";
ASSERT_OK(writable_file->Append(data));
ASSERT_OK(writable_file->Close());
ASSERT_LEVELDB_OK(writable_file->Append(data));
ASSERT_LEVELDB_OK(writable_file->Close());
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);
env_->DeleteFile(test_file_name);
}
TEST(EnvTest, ReopenAppendableFile) {
TEST_F(EnvTest, ReopenAppendableFile) {
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";
env_->DeleteFile(test_file_name);
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!");
ASSERT_OK(appendable_file->Append(data));
ASSERT_OK(appendable_file->Close());
ASSERT_LEVELDB_OK(appendable_file->Append(data));
ASSERT_LEVELDB_OK(appendable_file->Close());
delete appendable_file;
ASSERT_OK(env_->NewAppendableFile(test_file_name, &appendable_file));
ASSERT_LEVELDB_OK(env_->NewAppendableFile(test_file_name, &appendable_file));
data = "42";
ASSERT_OK(appendable_file->Append(data));
ASSERT_OK(appendable_file->Close());
ASSERT_LEVELDB_OK(appendable_file->Append(data));
ASSERT_LEVELDB_OK(appendable_file->Close());
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);
env_->DeleteFile(test_file_name);
}
} // 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();
}

+ 10
- 9
util/env_windows_test.cc View File

@ -2,17 +2,17 @@
// 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 "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/env.h"
#include "port/port.h"
#include "util/env_windows_test_helper.h"
#include "util/testharness.h"
#include "util/testutil.h"
namespace leveldb {
static const int kMMapLimit = 4;
class EnvWindowsTest {
class EnvWindowsTest : public testing::Test {
public:
static void SetFileLimits(int mmap_limit) {
EnvWindowsTestHelper::SetReadOnlyMMapLimit(mmap_limit);
@ -23,10 +23,10 @@ class EnvWindowsTest {
Env* env_;
};
TEST(EnvWindowsTest, TestOpenOnRead) {
TEST_F(EnvWindowsTest, TestOpenOnRead) {
// Write some test data to a single file that will be opened |n| times.
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";
FILE* f = fopen(test_file.c_str(), "w");
@ -41,18 +41,18 @@ TEST(EnvWindowsTest, TestOpenOnRead) {
const int kNumFiles = kMMapLimit + 5;
leveldb::RandomAccessFile* files[kNumFiles] = {0};
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;
Slice read_result;
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]);
}
for (int i = 0; i < kNumFiles; i++) {
delete files[i];
}
ASSERT_OK(env_->DeleteFile(test_file));
ASSERT_LEVELDB_OK(env_->DeleteFile(test_file));
}
} // namespace leveldb
@ -60,5 +60,6 @@ TEST(EnvWindowsTest, TestOpenOnRead) {
int main(int argc, char** argv) {
// All tests currently run with the same read-only file limits.
leveldb::EnvWindowsTest::SetFileLimits(leveldb::kMMapLimit);
return leveldb::test::RunAllTests();
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

+ 6
- 4
util/hash_test.cc View File

@ -3,11 +3,10 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "util/hash.h"
#include "util/testharness.h"
namespace leveldb {
#include "third_party/googletest/googletest/include/gtest/gtest.h"
class HASH {};
namespace leveldb {
TEST(HASH, SignedUnsignedIssue) {
const uint8_t data1[1] = {0x62};
@ -41,4 +40,7 @@ TEST(HASH, SignedUnsignedIssue) {
} // 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();
}

+ 7
- 5
util/logging_test.cc View File

@ -2,17 +2,16 @@
// 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/logging.h"
#include <limits>
#include <string>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/slice.h"
#include "util/logging.h"
#include "util/testharness.h"
namespace leveldb {
class Logging {};
TEST(Logging, NumberToString) {
ASSERT_EQ("0", NumberToString(0));
ASSERT_EQ("1", NumberToString(1));
@ -140,4 +139,7 @@ TEST(Logging, ConsumeDecimalNumberNoDigits) {
} // 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();
}

+ 7
- 5
util/no_destructor_test.cc View File

@ -2,12 +2,13 @@
// 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/no_destructor.h"
#include <cstdint>
#include <cstdlib>
#include <utility>
#include "util/no_destructor.h"
#include "util/testharness.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
namespace leveldb {
@ -28,8 +29,6 @@ constexpr const uint64_t kGoldenB = 0xaabbccddeeffaabb;
} // namespace
class NoDestructorTest {};
TEST(NoDestructorTest, StackInstance) {
NoDestructor<DoNotDestruct> instance(kGoldenA, kGoldenB);
ASSERT_EQ(kGoldenA, instance.get()->a);
@ -44,4 +43,7 @@ TEST(NoDestructorTest, StaticInstance) {
} // 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();
}

+ 7
- 3
util/status_test.cc View File

@ -2,11 +2,12 @@
// 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 "leveldb/status.h"
#include <utility>
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "leveldb/slice.h"
#include "leveldb/status.h"
#include "util/testharness.h"
namespace leveldb {
@ -37,4 +38,7 @@ TEST(Status, MoveConstructor) {
} // 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();
}

+ 0
- 81
util/testharness.cc 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

+ 0
- 141
util/testharness.h 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_

+ 2
- 0
util/testutil.cc View File

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

+ 16
- 0
util/testutil.h View File

@ -5,6 +5,8 @@
#ifndef 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 "leveldb/env.h"
#include "leveldb/slice.h"
@ -13,6 +15,20 @@
namespace leveldb {
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
// references the generated data.
Slice RandomString(Random* rnd, int len, std::string* dst);

Loading…
Cancel
Save