Switch testing harness to googletest.
PiperOrigin-RevId: 281815695
This commit is contained in:
parent
2c9c80bd53
commit
1c58902bdc
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "third_party/googletest"]
|
||||||
|
path = third_party/googletest
|
||||||
|
url = https://github.com/google/googletest.git
|
@ -84,6 +84,10 @@ endif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
check_cxx_compiler_flag(-Wthread-safety HAVE_CLANG_THREAD_SAFETY)
|
check_cxx_compiler_flag(-Wthread-safety HAVE_CLANG_THREAD_SAFETY)
|
||||||
|
|
||||||
|
# Used by googletest.
|
||||||
|
check_cxx_compiler_flag(-Wno-missing-field-initializers
|
||||||
|
LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS)
|
||||||
|
|
||||||
include(CheckCXXSourceCompiles)
|
include(CheckCXXSourceCompiles)
|
||||||
|
|
||||||
# Test whether C++17 __has_include is available.
|
# Test whether C++17 __has_include is available.
|
||||||
@ -288,6 +292,23 @@ target_link_libraries(leveldbutil leveldb)
|
|||||||
if(LEVELDB_BUILD_TESTS)
|
if(LEVELDB_BUILD_TESTS)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
|
# Prevent overriding the parent project's compiler/linker settings on Windows.
|
||||||
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||||
|
set(install_gtest OFF)
|
||||||
|
set(install_gmock OFF)
|
||||||
|
set(build_gmock ON)
|
||||||
|
|
||||||
|
# This project is tested using GoogleTest.
|
||||||
|
add_subdirectory("third_party/googletest")
|
||||||
|
|
||||||
|
# GoogleTest triggers a missing field initializers warning.
|
||||||
|
if(LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS)
|
||||||
|
set_property(TARGET gtest
|
||||||
|
APPEND PROPERTY COMPILE_OPTIONS -Wno-missing-field-initializers)
|
||||||
|
set_property(TARGET gmock
|
||||||
|
APPEND PROPERTY COMPILE_OPTIONS -Wno-missing-field-initializers)
|
||||||
|
endif(LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS)
|
||||||
|
|
||||||
function(leveldb_test test_file)
|
function(leveldb_test test_file)
|
||||||
get_filename_component(test_target_name "${test_file}" NAME_WE)
|
get_filename_component(test_target_name "${test_file}" NAME_WE)
|
||||||
|
|
||||||
@ -295,14 +316,12 @@ if(LEVELDB_BUILD_TESTS)
|
|||||||
target_sources("${test_target_name}"
|
target_sources("${test_target_name}"
|
||||||
PRIVATE
|
PRIVATE
|
||||||
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
|
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
|
||||||
"util/testharness.cc"
|
|
||||||
"util/testharness.h"
|
|
||||||
"util/testutil.cc"
|
"util/testutil.cc"
|
||||||
"util/testutil.h"
|
"util/testutil.h"
|
||||||
|
|
||||||
"${test_file}"
|
"${test_file}"
|
||||||
)
|
)
|
||||||
target_link_libraries("${test_target_name}" leveldb)
|
target_link_libraries("${test_target_name}" leveldb gmock gtest)
|
||||||
target_compile_definitions("${test_target_name}"
|
target_compile_definitions("${test_target_name}"
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${LEVELDB_PLATFORM_NAME}=1
|
${LEVELDB_PLATFORM_NAME}=1
|
||||||
@ -374,14 +393,12 @@ if(LEVELDB_BUILD_BENCHMARKS)
|
|||||||
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
|
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
|
||||||
"util/histogram.cc"
|
"util/histogram.cc"
|
||||||
"util/histogram.h"
|
"util/histogram.h"
|
||||||
"util/testharness.cc"
|
|
||||||
"util/testharness.h"
|
|
||||||
"util/testutil.cc"
|
"util/testutil.cc"
|
||||||
"util/testutil.h"
|
"util/testutil.h"
|
||||||
|
|
||||||
"${bench_file}"
|
"${bench_file}"
|
||||||
)
|
)
|
||||||
target_link_libraries("${bench_target_name}" leveldb)
|
target_link_libraries("${bench_target_name}" leveldb gmock gtest)
|
||||||
target_compile_definitions("${bench_target_name}"
|
target_compile_definitions("${bench_target_name}"
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${LEVELDB_PLATFORM_NAME}=1
|
${LEVELDB_PLATFORM_NAME}=1
|
||||||
|
@ -27,6 +27,12 @@ Authors: Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com)
|
|||||||
* Only a single process (possibly multi-threaded) can access a particular database at a time.
|
* Only a single process (possibly multi-threaded) can access a particular database at a time.
|
||||||
* There is no client-server support builtin to the library. An application that needs such support will have to wrap their own server around the library.
|
* There is no client-server support builtin to the library. An application that needs such support will have to wrap their own server around the library.
|
||||||
|
|
||||||
|
# Getting the Source
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone --recurse-submodules https://github.com/google/leveldb.git
|
||||||
|
```
|
||||||
|
|
||||||
# Building
|
# Building
|
||||||
|
|
||||||
This project supports [CMake](https://cmake.org/) out of the box.
|
This project supports [CMake](https://cmake.org/) out of the box.
|
||||||
|
@ -2,24 +2,24 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "db/db_impl.h"
|
#include "db/db_impl.h"
|
||||||
#include "leveldb/cache.h"
|
#include "leveldb/cache.h"
|
||||||
#include "leveldb/db.h"
|
#include "leveldb/db.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
#include "util/testutil.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
class AutoCompactTest {
|
class AutoCompactTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
AutoCompactTest() {
|
AutoCompactTest() {
|
||||||
dbname_ = test::TmpDir() + "/autocompact_test";
|
dbname_ = testing::TempDir() + "autocompact_test";
|
||||||
tiny_cache_ = NewLRUCache(100);
|
tiny_cache_ = NewLRUCache(100);
|
||||||
options_.block_cache = tiny_cache_;
|
options_.block_cache = tiny_cache_;
|
||||||
DestroyDB(dbname_, options_);
|
DestroyDB(dbname_, options_);
|
||||||
options_.create_if_missing = true;
|
options_.create_if_missing = true;
|
||||||
options_.compression = kNoCompression;
|
options_.compression = kNoCompression;
|
||||||
ASSERT_OK(DB::Open(options_, dbname_, &db_));
|
EXPECT_LEVELDB_OK(DB::Open(options_, dbname_, &db_));
|
||||||
}
|
}
|
||||||
|
|
||||||
~AutoCompactTest() {
|
~AutoCompactTest() {
|
||||||
@ -62,15 +62,15 @@ void AutoCompactTest::DoReads(int n) {
|
|||||||
|
|
||||||
// Fill database
|
// Fill database
|
||||||
for (int i = 0; i < kCount; i++) {
|
for (int i = 0; i < kCount; i++) {
|
||||||
ASSERT_OK(db_->Put(WriteOptions(), Key(i), value));
|
ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), Key(i), value));
|
||||||
}
|
}
|
||||||
ASSERT_OK(dbi->TEST_CompactMemTable());
|
ASSERT_LEVELDB_OK(dbi->TEST_CompactMemTable());
|
||||||
|
|
||||||
// Delete everything
|
// Delete everything
|
||||||
for (int i = 0; i < kCount; i++) {
|
for (int i = 0; i < kCount; i++) {
|
||||||
ASSERT_OK(db_->Delete(WriteOptions(), Key(i)));
|
ASSERT_LEVELDB_OK(db_->Delete(WriteOptions(), Key(i)));
|
||||||
}
|
}
|
||||||
ASSERT_OK(dbi->TEST_CompactMemTable());
|
ASSERT_LEVELDB_OK(dbi->TEST_CompactMemTable());
|
||||||
|
|
||||||
// Get initial measurement of the space we will be reading.
|
// Get initial measurement of the space we will be reading.
|
||||||
const int64_t initial_size = Size(Key(0), Key(n));
|
const int64_t initial_size = Size(Key(0), Key(n));
|
||||||
@ -103,10 +103,13 @@ void AutoCompactTest::DoReads(int n) {
|
|||||||
ASSERT_GE(final_other_size, initial_other_size / 5 - 1048576);
|
ASSERT_GE(final_other_size, initial_other_size / 5 - 1048576);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AutoCompactTest, ReadAll) { DoReads(kCount); }
|
TEST_F(AutoCompactTest, ReadAll) { DoReads(kCount); }
|
||||||
|
|
||||||
TEST(AutoCompactTest, ReadHalf) { DoReads(kCount / 2); }
|
TEST_F(AutoCompactTest, ReadHalf) { DoReads(kCount / 2); }
|
||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "db/db_impl.h"
|
#include "db/db_impl.h"
|
||||||
#include "db/filename.h"
|
#include "db/filename.h"
|
||||||
#include "db/log_format.h"
|
#include "db/log_format.h"
|
||||||
@ -13,14 +14,13 @@
|
|||||||
#include "leveldb/table.h"
|
#include "leveldb/table.h"
|
||||||
#include "leveldb/write_batch.h"
|
#include "leveldb/write_batch.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
#include "util/testutil.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
static const int kValueSize = 1000;
|
static const int kValueSize = 1000;
|
||||||
|
|
||||||
class CorruptionTest {
|
class CorruptionTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
CorruptionTest()
|
CorruptionTest()
|
||||||
: db_(nullptr),
|
: db_(nullptr),
|
||||||
@ -46,12 +46,12 @@ class CorruptionTest {
|
|||||||
return DB::Open(options_, dbname_, &db_);
|
return DB::Open(options_, dbname_, &db_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reopen() { ASSERT_OK(TryReopen()); }
|
void Reopen() { ASSERT_LEVELDB_OK(TryReopen()); }
|
||||||
|
|
||||||
void RepairDB() {
|
void RepairDB() {
|
||||||
delete db_;
|
delete db_;
|
||||||
db_ = nullptr;
|
db_ = nullptr;
|
||||||
ASSERT_OK(::leveldb::RepairDB(dbname_, options_));
|
ASSERT_LEVELDB_OK(::leveldb::RepairDB(dbname_, options_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Build(int n) {
|
void Build(int n) {
|
||||||
@ -68,7 +68,7 @@ class CorruptionTest {
|
|||||||
if (i == n - 1) {
|
if (i == n - 1) {
|
||||||
options.sync = true;
|
options.sync = true;
|
||||||
}
|
}
|
||||||
ASSERT_OK(db_->Write(options, &batch));
|
ASSERT_LEVELDB_OK(db_->Write(options, &batch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ class CorruptionTest {
|
|||||||
void Corrupt(FileType filetype, int offset, int bytes_to_corrupt) {
|
void Corrupt(FileType filetype, int offset, int bytes_to_corrupt) {
|
||||||
// Pick file to corrupt
|
// Pick file to corrupt
|
||||||
std::vector<std::string> filenames;
|
std::vector<std::string> filenames;
|
||||||
ASSERT_OK(env_.target()->GetChildren(dbname_, &filenames));
|
ASSERT_LEVELDB_OK(env_.target()->GetChildren(dbname_, &filenames));
|
||||||
uint64_t number;
|
uint64_t number;
|
||||||
FileType type;
|
FileType type;
|
||||||
std::string fname;
|
std::string fname;
|
||||||
@ -127,7 +127,7 @@ class CorruptionTest {
|
|||||||
ASSERT_TRUE(!fname.empty()) << filetype;
|
ASSERT_TRUE(!fname.empty()) << filetype;
|
||||||
|
|
||||||
uint64_t file_size;
|
uint64_t file_size;
|
||||||
ASSERT_OK(env_.target()->GetFileSize(fname, &file_size));
|
ASSERT_LEVELDB_OK(env_.target()->GetFileSize(fname, &file_size));
|
||||||
|
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
// Relative to end of file; make it absolute
|
// Relative to end of file; make it absolute
|
||||||
@ -189,7 +189,7 @@ class CorruptionTest {
|
|||||||
Cache* tiny_cache_;
|
Cache* tiny_cache_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(CorruptionTest, Recovery) {
|
TEST_F(CorruptionTest, Recovery) {
|
||||||
Build(100);
|
Build(100);
|
||||||
Check(100, 100);
|
Check(100, 100);
|
||||||
Corrupt(kLogFile, 19, 1); // WriteBatch tag for first record
|
Corrupt(kLogFile, 19, 1); // WriteBatch tag for first record
|
||||||
@ -200,13 +200,13 @@ TEST(CorruptionTest, Recovery) {
|
|||||||
Check(36, 36);
|
Check(36, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, RecoverWriteError) {
|
TEST_F(CorruptionTest, RecoverWriteError) {
|
||||||
env_.writable_file_error_ = true;
|
env_.writable_file_error_ = true;
|
||||||
Status s = TryReopen();
|
Status s = TryReopen();
|
||||||
ASSERT_TRUE(!s.ok());
|
ASSERT_TRUE(!s.ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, NewFileErrorDuringWrite) {
|
TEST_F(CorruptionTest, NewFileErrorDuringWrite) {
|
||||||
// Do enough writing to force minor compaction
|
// Do enough writing to force minor compaction
|
||||||
env_.writable_file_error_ = true;
|
env_.writable_file_error_ = true;
|
||||||
const int num = 3 + (Options().write_buffer_size / kValueSize);
|
const int num = 3 + (Options().write_buffer_size / kValueSize);
|
||||||
@ -223,7 +223,7 @@ TEST(CorruptionTest, NewFileErrorDuringWrite) {
|
|||||||
Reopen();
|
Reopen();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, TableFile) {
|
TEST_F(CorruptionTest, TableFile) {
|
||||||
Build(100);
|
Build(100);
|
||||||
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
|
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
|
||||||
dbi->TEST_CompactMemTable();
|
dbi->TEST_CompactMemTable();
|
||||||
@ -234,7 +234,7 @@ TEST(CorruptionTest, TableFile) {
|
|||||||
Check(90, 99);
|
Check(90, 99);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, TableFileRepair) {
|
TEST_F(CorruptionTest, TableFileRepair) {
|
||||||
options_.block_size = 2 * kValueSize; // Limit scope of corruption
|
options_.block_size = 2 * kValueSize; // Limit scope of corruption
|
||||||
options_.paranoid_checks = true;
|
options_.paranoid_checks = true;
|
||||||
Reopen();
|
Reopen();
|
||||||
@ -250,7 +250,7 @@ TEST(CorruptionTest, TableFileRepair) {
|
|||||||
Check(95, 99);
|
Check(95, 99);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, TableFileIndexData) {
|
TEST_F(CorruptionTest, TableFileIndexData) {
|
||||||
Build(10000); // Enough to build multiple Tables
|
Build(10000); // Enough to build multiple Tables
|
||||||
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
|
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
|
||||||
dbi->TEST_CompactMemTable();
|
dbi->TEST_CompactMemTable();
|
||||||
@ -260,36 +260,36 @@ TEST(CorruptionTest, TableFileIndexData) {
|
|||||||
Check(5000, 9999);
|
Check(5000, 9999);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, MissingDescriptor) {
|
TEST_F(CorruptionTest, MissingDescriptor) {
|
||||||
Build(1000);
|
Build(1000);
|
||||||
RepairDB();
|
RepairDB();
|
||||||
Reopen();
|
Reopen();
|
||||||
Check(1000, 1000);
|
Check(1000, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, SequenceNumberRecovery) {
|
TEST_F(CorruptionTest, SequenceNumberRecovery) {
|
||||||
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v1"));
|
ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v1"));
|
||||||
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v2"));
|
ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v2"));
|
||||||
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v3"));
|
ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v3"));
|
||||||
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v4"));
|
ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v4"));
|
||||||
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v5"));
|
ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v5"));
|
||||||
RepairDB();
|
RepairDB();
|
||||||
Reopen();
|
Reopen();
|
||||||
std::string v;
|
std::string v;
|
||||||
ASSERT_OK(db_->Get(ReadOptions(), "foo", &v));
|
ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), "foo", &v));
|
||||||
ASSERT_EQ("v5", v);
|
ASSERT_EQ("v5", v);
|
||||||
// Write something. If sequence number was not recovered properly,
|
// Write something. If sequence number was not recovered properly,
|
||||||
// it will be hidden by an earlier write.
|
// it will be hidden by an earlier write.
|
||||||
ASSERT_OK(db_->Put(WriteOptions(), "foo", "v6"));
|
ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "v6"));
|
||||||
ASSERT_OK(db_->Get(ReadOptions(), "foo", &v));
|
ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), "foo", &v));
|
||||||
ASSERT_EQ("v6", v);
|
ASSERT_EQ("v6", v);
|
||||||
Reopen();
|
Reopen();
|
||||||
ASSERT_OK(db_->Get(ReadOptions(), "foo", &v));
|
ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), "foo", &v));
|
||||||
ASSERT_EQ("v6", v);
|
ASSERT_EQ("v6", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, CorruptedDescriptor) {
|
TEST_F(CorruptionTest, CorruptedDescriptor) {
|
||||||
ASSERT_OK(db_->Put(WriteOptions(), "foo", "hello"));
|
ASSERT_LEVELDB_OK(db_->Put(WriteOptions(), "foo", "hello"));
|
||||||
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
|
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
|
||||||
dbi->TEST_CompactMemTable();
|
dbi->TEST_CompactMemTable();
|
||||||
dbi->TEST_CompactRange(0, nullptr, nullptr);
|
dbi->TEST_CompactRange(0, nullptr, nullptr);
|
||||||
@ -301,11 +301,11 @@ TEST(CorruptionTest, CorruptedDescriptor) {
|
|||||||
RepairDB();
|
RepairDB();
|
||||||
Reopen();
|
Reopen();
|
||||||
std::string v;
|
std::string v;
|
||||||
ASSERT_OK(db_->Get(ReadOptions(), "foo", &v));
|
ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), "foo", &v));
|
||||||
ASSERT_EQ("hello", v);
|
ASSERT_EQ("hello", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, CompactionInputError) {
|
TEST_F(CorruptionTest, CompactionInputError) {
|
||||||
Build(10);
|
Build(10);
|
||||||
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
|
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
|
||||||
dbi->TEST_CompactMemTable();
|
dbi->TEST_CompactMemTable();
|
||||||
@ -320,7 +320,7 @@ TEST(CorruptionTest, CompactionInputError) {
|
|||||||
Check(10000, 10000);
|
Check(10000, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, CompactionInputErrorParanoid) {
|
TEST_F(CorruptionTest, CompactionInputErrorParanoid) {
|
||||||
options_.paranoid_checks = true;
|
options_.paranoid_checks = true;
|
||||||
options_.write_buffer_size = 512 << 10;
|
options_.write_buffer_size = 512 << 10;
|
||||||
Reopen();
|
Reopen();
|
||||||
@ -341,22 +341,26 @@ TEST(CorruptionTest, CompactionInputErrorParanoid) {
|
|||||||
ASSERT_TRUE(!s.ok()) << "write did not fail in corrupted paranoid db";
|
ASSERT_TRUE(!s.ok()) << "write did not fail in corrupted paranoid db";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionTest, UnrelatedKeys) {
|
TEST_F(CorruptionTest, UnrelatedKeys) {
|
||||||
Build(10);
|
Build(10);
|
||||||
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
|
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
|
||||||
dbi->TEST_CompactMemTable();
|
dbi->TEST_CompactMemTable();
|
||||||
Corrupt(kTableFile, 100, 1);
|
Corrupt(kTableFile, 100, 1);
|
||||||
|
|
||||||
std::string tmp1, tmp2;
|
std::string tmp1, tmp2;
|
||||||
ASSERT_OK(db_->Put(WriteOptions(), Key(1000, &tmp1), Value(1000, &tmp2)));
|
ASSERT_LEVELDB_OK(
|
||||||
|
db_->Put(WriteOptions(), Key(1000, &tmp1), Value(1000, &tmp2)));
|
||||||
std::string v;
|
std::string v;
|
||||||
ASSERT_OK(db_->Get(ReadOptions(), Key(1000, &tmp1), &v));
|
ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), Key(1000, &tmp1), &v));
|
||||||
ASSERT_EQ(Value(1000, &tmp2).ToString(), v);
|
ASSERT_EQ(Value(1000, &tmp2).ToString(), v);
|
||||||
dbi->TEST_CompactMemTable();
|
dbi->TEST_CompactMemTable();
|
||||||
ASSERT_OK(db_->Get(ReadOptions(), Key(1000, &tmp1), &v));
|
ASSERT_LEVELDB_OK(db_->Get(ReadOptions(), Key(1000, &tmp1), &v));
|
||||||
ASSERT_EQ(Value(1000, &tmp2).ToString(), v);
|
ASSERT_EQ(Value(1000, &tmp2).ToString(), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
418
db/db_test.cc
418
db/db_test.cc
File diff suppressed because it is too large
Load Diff
@ -3,8 +3,9 @@
|
|||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
#include "db/dbformat.h"
|
#include "db/dbformat.h"
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
@ -41,8 +42,6 @@ static void TestKey(const std::string& key, uint64_t seq, ValueType vt) {
|
|||||||
ASSERT_TRUE(!ParseInternalKey(Slice("bar"), &decoded));
|
ASSERT_TRUE(!ParseInternalKey(Slice("bar"), &decoded));
|
||||||
}
|
}
|
||||||
|
|
||||||
class FormatTest {};
|
|
||||||
|
|
||||||
TEST(FormatTest, InternalKey_EncodeDecode) {
|
TEST(FormatTest, InternalKey_EncodeDecode) {
|
||||||
const char* keys[] = {"", "k", "hello", "longggggggggggggggggggggg"};
|
const char* keys[] = {"", "k", "hello", "longggggggggggggggggggggg"};
|
||||||
const uint64_t seq[] = {1,
|
const uint64_t seq[] = {1,
|
||||||
@ -128,4 +127,7 @@ TEST(FormatTest, InternalKeyDebugString) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "db/db_impl.h"
|
#include "db/db_impl.h"
|
||||||
#include "db/filename.h"
|
#include "db/filename.h"
|
||||||
#include "db/log_format.h"
|
#include "db/log_format.h"
|
||||||
@ -22,7 +23,6 @@
|
|||||||
#include "port/thread_annotations.h"
|
#include "port/thread_annotations.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/mutexlock.h"
|
#include "util/mutexlock.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
#include "util/testutil.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
@ -300,7 +300,7 @@ void FaultInjectionTestEnv::UntrackFile(const std::string& f) {
|
|||||||
|
|
||||||
Status FaultInjectionTestEnv::DeleteFile(const std::string& f) {
|
Status FaultInjectionTestEnv::DeleteFile(const std::string& f) {
|
||||||
Status s = EnvWrapper::DeleteFile(f);
|
Status s = EnvWrapper::DeleteFile(f);
|
||||||
ASSERT_OK(s);
|
EXPECT_LEVELDB_OK(s);
|
||||||
if (s.ok()) {
|
if (s.ok()) {
|
||||||
UntrackFile(f);
|
UntrackFile(f);
|
||||||
}
|
}
|
||||||
@ -361,7 +361,7 @@ Status FileState::DropUnsyncedData() const {
|
|||||||
return Truncate(filename_, sync_pos);
|
return Truncate(filename_, sync_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FaultInjectionTest {
|
class FaultInjectionTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
enum ExpectedVerifResult { VAL_EXPECT_NO_ERROR, VAL_EXPECT_ERROR };
|
enum ExpectedVerifResult { VAL_EXPECT_NO_ERROR, VAL_EXPECT_ERROR };
|
||||||
enum ResetMethod { RESET_DROP_UNSYNCED_DATA, RESET_DELETE_UNSYNCED_FILES };
|
enum ResetMethod { RESET_DROP_UNSYNCED_DATA, RESET_DELETE_UNSYNCED_FILES };
|
||||||
@ -376,7 +376,7 @@ class FaultInjectionTest {
|
|||||||
: env_(new FaultInjectionTestEnv),
|
: env_(new FaultInjectionTestEnv),
|
||||||
tiny_cache_(NewLRUCache(100)),
|
tiny_cache_(NewLRUCache(100)),
|
||||||
db_(nullptr) {
|
db_(nullptr) {
|
||||||
dbname_ = test::TmpDir() + "/fault_test";
|
dbname_ = testing::TempDir() + "fault_test";
|
||||||
DestroyDB(dbname_, Options()); // Destroy any db from earlier run
|
DestroyDB(dbname_, Options()); // Destroy any db from earlier run
|
||||||
options_.reuse_logs = true;
|
options_.reuse_logs = true;
|
||||||
options_.env = env_;
|
options_.env = env_;
|
||||||
@ -402,7 +402,7 @@ class FaultInjectionTest {
|
|||||||
batch.Clear();
|
batch.Clear();
|
||||||
batch.Put(key, Value(i, &value_space));
|
batch.Put(key, Value(i, &value_space));
|
||||||
WriteOptions options;
|
WriteOptions options;
|
||||||
ASSERT_OK(db_->Write(options, &batch));
|
ASSERT_LEVELDB_OK(db_->Write(options, &batch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,7 +424,7 @@ class FaultInjectionTest {
|
|||||||
s = ReadValue(i, &val);
|
s = ReadValue(i, &val);
|
||||||
if (expected == VAL_EXPECT_NO_ERROR) {
|
if (expected == VAL_EXPECT_NO_ERROR) {
|
||||||
if (s.ok()) {
|
if (s.ok()) {
|
||||||
ASSERT_EQ(value_space, val);
|
EXPECT_EQ(value_space, val);
|
||||||
}
|
}
|
||||||
} else if (s.ok()) {
|
} else if (s.ok()) {
|
||||||
fprintf(stderr, "Expected an error at %d, but was OK\n", i);
|
fprintf(stderr, "Expected an error at %d, but was OK\n", i);
|
||||||
@ -465,7 +465,7 @@ class FaultInjectionTest {
|
|||||||
void DeleteAllData() {
|
void DeleteAllData() {
|
||||||
Iterator* iter = db_->NewIterator(ReadOptions());
|
Iterator* iter = db_->NewIterator(ReadOptions());
|
||||||
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
||||||
ASSERT_OK(db_->Delete(WriteOptions(), iter->key()));
|
ASSERT_LEVELDB_OK(db_->Delete(WriteOptions(), iter->key()));
|
||||||
}
|
}
|
||||||
|
|
||||||
delete iter;
|
delete iter;
|
||||||
@ -474,10 +474,10 @@ class FaultInjectionTest {
|
|||||||
void ResetDBState(ResetMethod reset_method) {
|
void ResetDBState(ResetMethod reset_method) {
|
||||||
switch (reset_method) {
|
switch (reset_method) {
|
||||||
case RESET_DROP_UNSYNCED_DATA:
|
case RESET_DROP_UNSYNCED_DATA:
|
||||||
ASSERT_OK(env_->DropUnsyncedFileData());
|
ASSERT_LEVELDB_OK(env_->DropUnsyncedFileData());
|
||||||
break;
|
break;
|
||||||
case RESET_DELETE_UNSYNCED_FILES:
|
case RESET_DELETE_UNSYNCED_FILES:
|
||||||
ASSERT_OK(env_->DeleteFilesCreatedAfterLastDirSync());
|
ASSERT_LEVELDB_OK(env_->DeleteFilesCreatedAfterLastDirSync());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
@ -496,9 +496,10 @@ class FaultInjectionTest {
|
|||||||
env_->SetFilesystemActive(false);
|
env_->SetFilesystemActive(false);
|
||||||
CloseDB();
|
CloseDB();
|
||||||
ResetDBState(reset_method);
|
ResetDBState(reset_method);
|
||||||
ASSERT_OK(OpenDB());
|
ASSERT_LEVELDB_OK(OpenDB());
|
||||||
ASSERT_OK(Verify(0, num_pre_sync, FaultInjectionTest::VAL_EXPECT_NO_ERROR));
|
ASSERT_LEVELDB_OK(
|
||||||
ASSERT_OK(Verify(num_pre_sync, num_post_sync,
|
Verify(0, num_pre_sync, FaultInjectionTest::VAL_EXPECT_NO_ERROR));
|
||||||
|
ASSERT_LEVELDB_OK(Verify(num_pre_sync, num_post_sync,
|
||||||
FaultInjectionTest::VAL_EXPECT_ERROR));
|
FaultInjectionTest::VAL_EXPECT_ERROR));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,12 +508,12 @@ class FaultInjectionTest {
|
|||||||
void NoWriteTestReopenWithFault(ResetMethod reset_method) {
|
void NoWriteTestReopenWithFault(ResetMethod reset_method) {
|
||||||
CloseDB();
|
CloseDB();
|
||||||
ResetDBState(reset_method);
|
ResetDBState(reset_method);
|
||||||
ASSERT_OK(OpenDB());
|
ASSERT_LEVELDB_OK(OpenDB());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoTest() {
|
void DoTest() {
|
||||||
Random rnd(0);
|
Random rnd(0);
|
||||||
ASSERT_OK(OpenDB());
|
ASSERT_LEVELDB_OK(OpenDB());
|
||||||
for (size_t idx = 0; idx < kNumIterations; idx++) {
|
for (size_t idx = 0; idx < kNumIterations; idx++) {
|
||||||
int num_pre_sync = rnd.Uniform(kMaxNumValues);
|
int num_pre_sync = rnd.Uniform(kMaxNumValues);
|
||||||
int num_post_sync = rnd.Uniform(kMaxNumValues);
|
int num_post_sync = rnd.Uniform(kMaxNumValues);
|
||||||
@ -536,16 +537,19 @@ class FaultInjectionTest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(FaultInjectionTest, FaultTestNoLogReuse) {
|
TEST_F(FaultInjectionTest, FaultTestNoLogReuse) {
|
||||||
ReuseLogs(false);
|
ReuseLogs(false);
|
||||||
DoTest();
|
DoTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FaultInjectionTest, FaultTestWithLogReuse) {
|
TEST_F(FaultInjectionTest, FaultTestWithLogReuse) {
|
||||||
ReuseLogs(true);
|
ReuseLogs(true);
|
||||||
DoTest();
|
DoTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -4,15 +4,13 @@
|
|||||||
|
|
||||||
#include "db/filename.h"
|
#include "db/filename.h"
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "db/dbformat.h"
|
#include "db/dbformat.h"
|
||||||
#include "port/port.h"
|
#include "port/port.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
class FileNameTest {};
|
|
||||||
|
|
||||||
TEST(FileNameTest, Parse) {
|
TEST(FileNameTest, Parse) {
|
||||||
Slice db;
|
Slice db;
|
||||||
FileType type;
|
FileType type;
|
||||||
@ -128,4 +126,7 @@ TEST(FileNameTest, Construction) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "db/log_reader.h"
|
#include "db/log_reader.h"
|
||||||
#include "db/log_writer.h"
|
#include "db/log_writer.h"
|
||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
#include "util/coding.h"
|
#include "util/coding.h"
|
||||||
#include "util/crc32c.h"
|
#include "util/crc32c.h"
|
||||||
#include "util/random.h"
|
#include "util/random.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
namespace log {
|
namespace log {
|
||||||
@ -36,7 +36,7 @@ static std::string RandomSkewedString(int i, Random* rnd) {
|
|||||||
return BigString(NumberString(i), rnd->Skewed(17));
|
return BigString(NumberString(i), rnd->Skewed(17));
|
||||||
}
|
}
|
||||||
|
|
||||||
class LogTest {
|
class LogTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
LogTest()
|
LogTest()
|
||||||
: reading_(false),
|
: reading_(false),
|
||||||
@ -177,7 +177,7 @@ class LogTest {
|
|||||||
StringSource() : force_error_(false), returned_partial_(false) {}
|
StringSource() : force_error_(false), returned_partial_(false) {}
|
||||||
|
|
||||||
Status Read(size_t n, Slice* result, char* scratch) override {
|
Status Read(size_t n, Slice* result, char* scratch) override {
|
||||||
ASSERT_TRUE(!returned_partial_) << "must not Read() after eof/error";
|
EXPECT_TRUE(!returned_partial_) << "must not Read() after eof/error";
|
||||||
|
|
||||||
if (force_error_) {
|
if (force_error_) {
|
||||||
force_error_ = false;
|
force_error_ = false;
|
||||||
@ -258,9 +258,9 @@ uint64_t LogTest::initial_offset_last_record_offsets_[] = {
|
|||||||
int LogTest::num_initial_offset_records_ =
|
int LogTest::num_initial_offset_records_ =
|
||||||
sizeof(LogTest::initial_offset_last_record_offsets_) / sizeof(uint64_t);
|
sizeof(LogTest::initial_offset_last_record_offsets_) / sizeof(uint64_t);
|
||||||
|
|
||||||
TEST(LogTest, Empty) { ASSERT_EQ("EOF", Read()); }
|
TEST_F(LogTest, Empty) { ASSERT_EQ("EOF", Read()); }
|
||||||
|
|
||||||
TEST(LogTest, ReadWrite) {
|
TEST_F(LogTest, ReadWrite) {
|
||||||
Write("foo");
|
Write("foo");
|
||||||
Write("bar");
|
Write("bar");
|
||||||
Write("");
|
Write("");
|
||||||
@ -273,7 +273,7 @@ TEST(LogTest, ReadWrite) {
|
|||||||
ASSERT_EQ("EOF", Read()); // Make sure reads at eof work
|
ASSERT_EQ("EOF", Read()); // Make sure reads at eof work
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, ManyBlocks) {
|
TEST_F(LogTest, ManyBlocks) {
|
||||||
for (int i = 0; i < 100000; i++) {
|
for (int i = 0; i < 100000; i++) {
|
||||||
Write(NumberString(i));
|
Write(NumberString(i));
|
||||||
}
|
}
|
||||||
@ -283,7 +283,7 @@ TEST(LogTest, ManyBlocks) {
|
|||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, Fragmentation) {
|
TEST_F(LogTest, Fragmentation) {
|
||||||
Write("small");
|
Write("small");
|
||||||
Write(BigString("medium", 50000));
|
Write(BigString("medium", 50000));
|
||||||
Write(BigString("large", 100000));
|
Write(BigString("large", 100000));
|
||||||
@ -293,7 +293,7 @@ TEST(LogTest, Fragmentation) {
|
|||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, MarginalTrailer) {
|
TEST_F(LogTest, MarginalTrailer) {
|
||||||
// Make a trailer that is exactly the same length as an empty record.
|
// Make a trailer that is exactly the same length as an empty record.
|
||||||
const int n = kBlockSize - 2 * kHeaderSize;
|
const int n = kBlockSize - 2 * kHeaderSize;
|
||||||
Write(BigString("foo", n));
|
Write(BigString("foo", n));
|
||||||
@ -306,7 +306,7 @@ TEST(LogTest, MarginalTrailer) {
|
|||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, MarginalTrailer2) {
|
TEST_F(LogTest, MarginalTrailer2) {
|
||||||
// Make a trailer that is exactly the same length as an empty record.
|
// Make a trailer that is exactly the same length as an empty record.
|
||||||
const int n = kBlockSize - 2 * kHeaderSize;
|
const int n = kBlockSize - 2 * kHeaderSize;
|
||||||
Write(BigString("foo", n));
|
Write(BigString("foo", n));
|
||||||
@ -319,7 +319,7 @@ TEST(LogTest, MarginalTrailer2) {
|
|||||||
ASSERT_EQ("", ReportMessage());
|
ASSERT_EQ("", ReportMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, ShortTrailer) {
|
TEST_F(LogTest, ShortTrailer) {
|
||||||
const int n = kBlockSize - 2 * kHeaderSize + 4;
|
const int n = kBlockSize - 2 * kHeaderSize + 4;
|
||||||
Write(BigString("foo", n));
|
Write(BigString("foo", n));
|
||||||
ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
|
ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
|
||||||
@ -331,7 +331,7 @@ TEST(LogTest, ShortTrailer) {
|
|||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, AlignedEof) {
|
TEST_F(LogTest, AlignedEof) {
|
||||||
const int n = kBlockSize - 2 * kHeaderSize + 4;
|
const int n = kBlockSize - 2 * kHeaderSize + 4;
|
||||||
Write(BigString("foo", n));
|
Write(BigString("foo", n));
|
||||||
ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
|
ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
|
||||||
@ -339,7 +339,7 @@ TEST(LogTest, AlignedEof) {
|
|||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, OpenForAppend) {
|
TEST_F(LogTest, OpenForAppend) {
|
||||||
Write("hello");
|
Write("hello");
|
||||||
ReopenForAppend();
|
ReopenForAppend();
|
||||||
Write("world");
|
Write("world");
|
||||||
@ -348,7 +348,7 @@ TEST(LogTest, OpenForAppend) {
|
|||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, RandomRead) {
|
TEST_F(LogTest, RandomRead) {
|
||||||
const int N = 500;
|
const int N = 500;
|
||||||
Random write_rnd(301);
|
Random write_rnd(301);
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
@ -363,7 +363,7 @@ TEST(LogTest, RandomRead) {
|
|||||||
|
|
||||||
// Tests of all the error paths in log_reader.cc follow:
|
// Tests of all the error paths in log_reader.cc follow:
|
||||||
|
|
||||||
TEST(LogTest, ReadError) {
|
TEST_F(LogTest, ReadError) {
|
||||||
Write("foo");
|
Write("foo");
|
||||||
ForceError();
|
ForceError();
|
||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
@ -371,7 +371,7 @@ TEST(LogTest, ReadError) {
|
|||||||
ASSERT_EQ("OK", MatchError("read error"));
|
ASSERT_EQ("OK", MatchError("read error"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, BadRecordType) {
|
TEST_F(LogTest, BadRecordType) {
|
||||||
Write("foo");
|
Write("foo");
|
||||||
// Type is stored in header[6]
|
// Type is stored in header[6]
|
||||||
IncrementByte(6, 100);
|
IncrementByte(6, 100);
|
||||||
@ -381,7 +381,7 @@ TEST(LogTest, BadRecordType) {
|
|||||||
ASSERT_EQ("OK", MatchError("unknown record type"));
|
ASSERT_EQ("OK", MatchError("unknown record type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, TruncatedTrailingRecordIsIgnored) {
|
TEST_F(LogTest, TruncatedTrailingRecordIsIgnored) {
|
||||||
Write("foo");
|
Write("foo");
|
||||||
ShrinkSize(4); // Drop all payload as well as a header byte
|
ShrinkSize(4); // Drop all payload as well as a header byte
|
||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
@ -390,7 +390,7 @@ TEST(LogTest, TruncatedTrailingRecordIsIgnored) {
|
|||||||
ASSERT_EQ("", ReportMessage());
|
ASSERT_EQ("", ReportMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, BadLength) {
|
TEST_F(LogTest, BadLength) {
|
||||||
const int kPayloadSize = kBlockSize - kHeaderSize;
|
const int kPayloadSize = kBlockSize - kHeaderSize;
|
||||||
Write(BigString("bar", kPayloadSize));
|
Write(BigString("bar", kPayloadSize));
|
||||||
Write("foo");
|
Write("foo");
|
||||||
@ -401,7 +401,7 @@ TEST(LogTest, BadLength) {
|
|||||||
ASSERT_EQ("OK", MatchError("bad record length"));
|
ASSERT_EQ("OK", MatchError("bad record length"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, BadLengthAtEndIsIgnored) {
|
TEST_F(LogTest, BadLengthAtEndIsIgnored) {
|
||||||
Write("foo");
|
Write("foo");
|
||||||
ShrinkSize(1);
|
ShrinkSize(1);
|
||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
@ -409,7 +409,7 @@ TEST(LogTest, BadLengthAtEndIsIgnored) {
|
|||||||
ASSERT_EQ("", ReportMessage());
|
ASSERT_EQ("", ReportMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, ChecksumMismatch) {
|
TEST_F(LogTest, ChecksumMismatch) {
|
||||||
Write("foo");
|
Write("foo");
|
||||||
IncrementByte(0, 10);
|
IncrementByte(0, 10);
|
||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
@ -417,7 +417,7 @@ TEST(LogTest, ChecksumMismatch) {
|
|||||||
ASSERT_EQ("OK", MatchError("checksum mismatch"));
|
ASSERT_EQ("OK", MatchError("checksum mismatch"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, UnexpectedMiddleType) {
|
TEST_F(LogTest, UnexpectedMiddleType) {
|
||||||
Write("foo");
|
Write("foo");
|
||||||
SetByte(6, kMiddleType);
|
SetByte(6, kMiddleType);
|
||||||
FixChecksum(0, 3);
|
FixChecksum(0, 3);
|
||||||
@ -426,7 +426,7 @@ TEST(LogTest, UnexpectedMiddleType) {
|
|||||||
ASSERT_EQ("OK", MatchError("missing start"));
|
ASSERT_EQ("OK", MatchError("missing start"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, UnexpectedLastType) {
|
TEST_F(LogTest, UnexpectedLastType) {
|
||||||
Write("foo");
|
Write("foo");
|
||||||
SetByte(6, kLastType);
|
SetByte(6, kLastType);
|
||||||
FixChecksum(0, 3);
|
FixChecksum(0, 3);
|
||||||
@ -435,7 +435,7 @@ TEST(LogTest, UnexpectedLastType) {
|
|||||||
ASSERT_EQ("OK", MatchError("missing start"));
|
ASSERT_EQ("OK", MatchError("missing start"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, UnexpectedFullType) {
|
TEST_F(LogTest, UnexpectedFullType) {
|
||||||
Write("foo");
|
Write("foo");
|
||||||
Write("bar");
|
Write("bar");
|
||||||
SetByte(6, kFirstType);
|
SetByte(6, kFirstType);
|
||||||
@ -446,7 +446,7 @@ TEST(LogTest, UnexpectedFullType) {
|
|||||||
ASSERT_EQ("OK", MatchError("partial record without end"));
|
ASSERT_EQ("OK", MatchError("partial record without end"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, UnexpectedFirstType) {
|
TEST_F(LogTest, UnexpectedFirstType) {
|
||||||
Write("foo");
|
Write("foo");
|
||||||
Write(BigString("bar", 100000));
|
Write(BigString("bar", 100000));
|
||||||
SetByte(6, kFirstType);
|
SetByte(6, kFirstType);
|
||||||
@ -457,7 +457,7 @@ TEST(LogTest, UnexpectedFirstType) {
|
|||||||
ASSERT_EQ("OK", MatchError("partial record without end"));
|
ASSERT_EQ("OK", MatchError("partial record without end"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, MissingLastIsIgnored) {
|
TEST_F(LogTest, MissingLastIsIgnored) {
|
||||||
Write(BigString("bar", kBlockSize));
|
Write(BigString("bar", kBlockSize));
|
||||||
// Remove the LAST block, including header.
|
// Remove the LAST block, including header.
|
||||||
ShrinkSize(14);
|
ShrinkSize(14);
|
||||||
@ -466,7 +466,7 @@ TEST(LogTest, MissingLastIsIgnored) {
|
|||||||
ASSERT_EQ(0, DroppedBytes());
|
ASSERT_EQ(0, DroppedBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, PartialLastIsIgnored) {
|
TEST_F(LogTest, PartialLastIsIgnored) {
|
||||||
Write(BigString("bar", kBlockSize));
|
Write(BigString("bar", kBlockSize));
|
||||||
// Cause a bad record length in the LAST block.
|
// Cause a bad record length in the LAST block.
|
||||||
ShrinkSize(1);
|
ShrinkSize(1);
|
||||||
@ -475,7 +475,7 @@ TEST(LogTest, PartialLastIsIgnored) {
|
|||||||
ASSERT_EQ(0, DroppedBytes());
|
ASSERT_EQ(0, DroppedBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, SkipIntoMultiRecord) {
|
TEST_F(LogTest, SkipIntoMultiRecord) {
|
||||||
// Consider a fragmented record:
|
// Consider a fragmented record:
|
||||||
// first(R1), middle(R1), last(R1), first(R2)
|
// first(R1), middle(R1), last(R1), first(R2)
|
||||||
// If initial_offset points to a record after first(R1) but before first(R2)
|
// If initial_offset points to a record after first(R1) but before first(R2)
|
||||||
@ -491,7 +491,7 @@ TEST(LogTest, SkipIntoMultiRecord) {
|
|||||||
ASSERT_EQ("EOF", Read());
|
ASSERT_EQ("EOF", Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, ErrorJoinsRecords) {
|
TEST_F(LogTest, ErrorJoinsRecords) {
|
||||||
// Consider two fragmented records:
|
// Consider two fragmented records:
|
||||||
// first(R1) last(R1) first(R2) last(R2)
|
// first(R1) last(R1) first(R2) last(R2)
|
||||||
// where the middle two fragments disappear. We do not want
|
// where the middle two fragments disappear. We do not want
|
||||||
@ -514,47 +514,50 @@ TEST(LogTest, ErrorJoinsRecords) {
|
|||||||
ASSERT_GE(dropped, 2 * kBlockSize);
|
ASSERT_GE(dropped, 2 * kBlockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, ReadStart) { CheckInitialOffsetRecord(0, 0); }
|
TEST_F(LogTest, ReadStart) { CheckInitialOffsetRecord(0, 0); }
|
||||||
|
|
||||||
TEST(LogTest, ReadSecondOneOff) { CheckInitialOffsetRecord(1, 1); }
|
TEST_F(LogTest, ReadSecondOneOff) { CheckInitialOffsetRecord(1, 1); }
|
||||||
|
|
||||||
TEST(LogTest, ReadSecondTenThousand) { CheckInitialOffsetRecord(10000, 1); }
|
TEST_F(LogTest, ReadSecondTenThousand) { CheckInitialOffsetRecord(10000, 1); }
|
||||||
|
|
||||||
TEST(LogTest, ReadSecondStart) { CheckInitialOffsetRecord(10007, 1); }
|
TEST_F(LogTest, ReadSecondStart) { CheckInitialOffsetRecord(10007, 1); }
|
||||||
|
|
||||||
TEST(LogTest, ReadThirdOneOff) { CheckInitialOffsetRecord(10008, 2); }
|
TEST_F(LogTest, ReadThirdOneOff) { CheckInitialOffsetRecord(10008, 2); }
|
||||||
|
|
||||||
TEST(LogTest, ReadThirdStart) { CheckInitialOffsetRecord(20014, 2); }
|
TEST_F(LogTest, ReadThirdStart) { CheckInitialOffsetRecord(20014, 2); }
|
||||||
|
|
||||||
TEST(LogTest, ReadFourthOneOff) { CheckInitialOffsetRecord(20015, 3); }
|
TEST_F(LogTest, ReadFourthOneOff) { CheckInitialOffsetRecord(20015, 3); }
|
||||||
|
|
||||||
TEST(LogTest, ReadFourthFirstBlockTrailer) {
|
TEST_F(LogTest, ReadFourthFirstBlockTrailer) {
|
||||||
CheckInitialOffsetRecord(log::kBlockSize - 4, 3);
|
CheckInitialOffsetRecord(log::kBlockSize - 4, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, ReadFourthMiddleBlock) {
|
TEST_F(LogTest, ReadFourthMiddleBlock) {
|
||||||
CheckInitialOffsetRecord(log::kBlockSize + 1, 3);
|
CheckInitialOffsetRecord(log::kBlockSize + 1, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, ReadFourthLastBlock) {
|
TEST_F(LogTest, ReadFourthLastBlock) {
|
||||||
CheckInitialOffsetRecord(2 * log::kBlockSize + 1, 3);
|
CheckInitialOffsetRecord(2 * log::kBlockSize + 1, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, ReadFourthStart) {
|
TEST_F(LogTest, ReadFourthStart) {
|
||||||
CheckInitialOffsetRecord(
|
CheckInitialOffsetRecord(
|
||||||
2 * (kHeaderSize + 1000) + (2 * log::kBlockSize - 1000) + 3 * kHeaderSize,
|
2 * (kHeaderSize + 1000) + (2 * log::kBlockSize - 1000) + 3 * kHeaderSize,
|
||||||
3);
|
3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, ReadInitialOffsetIntoBlockPadding) {
|
TEST_F(LogTest, ReadInitialOffsetIntoBlockPadding) {
|
||||||
CheckInitialOffsetRecord(3 * log::kBlockSize - 3, 5);
|
CheckInitialOffsetRecord(3 * log::kBlockSize - 3, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LogTest, ReadEnd) { CheckOffsetPastEndReturnsNoRecords(0); }
|
TEST_F(LogTest, ReadEnd) { CheckOffsetPastEndReturnsNoRecords(0); }
|
||||||
|
|
||||||
TEST(LogTest, ReadPastEnd) { CheckOffsetPastEndReturnsNoRecords(5); }
|
TEST_F(LogTest, ReadPastEnd) { CheckOffsetPastEndReturnsNoRecords(5); }
|
||||||
|
|
||||||
} // namespace log
|
} // namespace log
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "db/db_impl.h"
|
#include "db/db_impl.h"
|
||||||
#include "db/filename.h"
|
#include "db/filename.h"
|
||||||
#include "db/version_set.h"
|
#include "db/version_set.h"
|
||||||
@ -10,15 +11,14 @@
|
|||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
#include "leveldb/write_batch.h"
|
#include "leveldb/write_batch.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
#include "util/testutil.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
class RecoveryTest {
|
class RecoveryTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
RecoveryTest() : env_(Env::Default()), db_(nullptr) {
|
RecoveryTest() : env_(Env::Default()), db_(nullptr) {
|
||||||
dbname_ = test::TmpDir() + "/recovery_test";
|
dbname_ = testing::TempDir() + "/recovery_test";
|
||||||
DestroyDB(dbname_, Options());
|
DestroyDB(dbname_, Options());
|
||||||
Open();
|
Open();
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ class RecoveryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Open(Options* options = nullptr) {
|
void Open(Options* options = nullptr) {
|
||||||
ASSERT_OK(OpenWithStatus(options));
|
ASSERT_LEVELDB_OK(OpenWithStatus(options));
|
||||||
ASSERT_EQ(1, NumLogs());
|
ASSERT_EQ(1, NumLogs());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +84,8 @@ class RecoveryTest {
|
|||||||
|
|
||||||
std::string ManifestFileName() {
|
std::string ManifestFileName() {
|
||||||
std::string current;
|
std::string current;
|
||||||
ASSERT_OK(ReadFileToString(env_, CurrentFileName(dbname_), ¤t));
|
EXPECT_LEVELDB_OK(
|
||||||
|
ReadFileToString(env_, CurrentFileName(dbname_), ¤t));
|
||||||
size_t len = current.size();
|
size_t len = current.size();
|
||||||
if (len > 0 && current[len - 1] == '\n') {
|
if (len > 0 && current[len - 1] == '\n') {
|
||||||
current.resize(len - 1);
|
current.resize(len - 1);
|
||||||
@ -100,18 +101,20 @@ class RecoveryTest {
|
|||||||
Close();
|
Close();
|
||||||
std::vector<uint64_t> logs = GetFiles(kLogFile);
|
std::vector<uint64_t> logs = GetFiles(kLogFile);
|
||||||
for (size_t i = 0; i < logs.size(); i++) {
|
for (size_t i = 0; i < logs.size(); i++) {
|
||||||
ASSERT_OK(env_->DeleteFile(LogName(logs[i]))) << LogName(logs[i]);
|
EXPECT_LEVELDB_OK(env_->DeleteFile(LogName(logs[i]))) << LogName(logs[i]);
|
||||||
}
|
}
|
||||||
return logs.size();
|
return logs.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteManifestFile() { ASSERT_OK(env_->DeleteFile(ManifestFileName())); }
|
void DeleteManifestFile() {
|
||||||
|
ASSERT_LEVELDB_OK(env_->DeleteFile(ManifestFileName()));
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t FirstLogFile() { return GetFiles(kLogFile)[0]; }
|
uint64_t FirstLogFile() { return GetFiles(kLogFile)[0]; }
|
||||||
|
|
||||||
std::vector<uint64_t> GetFiles(FileType t) {
|
std::vector<uint64_t> GetFiles(FileType t) {
|
||||||
std::vector<std::string> filenames;
|
std::vector<std::string> filenames;
|
||||||
ASSERT_OK(env_->GetChildren(dbname_, &filenames));
|
EXPECT_LEVELDB_OK(env_->GetChildren(dbname_, &filenames));
|
||||||
std::vector<uint64_t> result;
|
std::vector<uint64_t> result;
|
||||||
for (size_t i = 0; i < filenames.size(); i++) {
|
for (size_t i = 0; i < filenames.size(); i++) {
|
||||||
uint64_t number;
|
uint64_t number;
|
||||||
@ -129,7 +132,7 @@ class RecoveryTest {
|
|||||||
|
|
||||||
uint64_t FileSize(const std::string& fname) {
|
uint64_t FileSize(const std::string& fname) {
|
||||||
uint64_t result;
|
uint64_t result;
|
||||||
ASSERT_OK(env_->GetFileSize(fname, &result)) << fname;
|
EXPECT_LEVELDB_OK(env_->GetFileSize(fname, &result)) << fname;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,13 +142,13 @@ class RecoveryTest {
|
|||||||
void MakeLogFile(uint64_t lognum, SequenceNumber seq, Slice key, Slice val) {
|
void MakeLogFile(uint64_t lognum, SequenceNumber seq, Slice key, Slice val) {
|
||||||
std::string fname = LogFileName(dbname_, lognum);
|
std::string fname = LogFileName(dbname_, lognum);
|
||||||
WritableFile* file;
|
WritableFile* file;
|
||||||
ASSERT_OK(env_->NewWritableFile(fname, &file));
|
ASSERT_LEVELDB_OK(env_->NewWritableFile(fname, &file));
|
||||||
log::Writer writer(file);
|
log::Writer writer(file);
|
||||||
WriteBatch batch;
|
WriteBatch batch;
|
||||||
batch.Put(key, val);
|
batch.Put(key, val);
|
||||||
WriteBatchInternal::SetSequence(&batch, seq);
|
WriteBatchInternal::SetSequence(&batch, seq);
|
||||||
ASSERT_OK(writer.AddRecord(WriteBatchInternal::Contents(&batch)));
|
ASSERT_LEVELDB_OK(writer.AddRecord(WriteBatchInternal::Contents(&batch)));
|
||||||
ASSERT_OK(file->Flush());
|
ASSERT_LEVELDB_OK(file->Flush());
|
||||||
delete file;
|
delete file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,12 +158,12 @@ class RecoveryTest {
|
|||||||
DB* db_;
|
DB* db_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(RecoveryTest, ManifestReused) {
|
TEST_F(RecoveryTest, ManifestReused) {
|
||||||
if (!CanAppend()) {
|
if (!CanAppend()) {
|
||||||
fprintf(stderr, "skipping test because env does not support appending\n");
|
fprintf(stderr, "skipping test because env does not support appending\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ASSERT_OK(Put("foo", "bar"));
|
ASSERT_LEVELDB_OK(Put("foo", "bar"));
|
||||||
Close();
|
Close();
|
||||||
std::string old_manifest = ManifestFileName();
|
std::string old_manifest = ManifestFileName();
|
||||||
Open();
|
Open();
|
||||||
@ -171,12 +174,12 @@ TEST(RecoveryTest, ManifestReused) {
|
|||||||
ASSERT_EQ("bar", Get("foo"));
|
ASSERT_EQ("bar", Get("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RecoveryTest, LargeManifestCompacted) {
|
TEST_F(RecoveryTest, LargeManifestCompacted) {
|
||||||
if (!CanAppend()) {
|
if (!CanAppend()) {
|
||||||
fprintf(stderr, "skipping test because env does not support appending\n");
|
fprintf(stderr, "skipping test because env does not support appending\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ASSERT_OK(Put("foo", "bar"));
|
ASSERT_LEVELDB_OK(Put("foo", "bar"));
|
||||||
Close();
|
Close();
|
||||||
std::string old_manifest = ManifestFileName();
|
std::string old_manifest = ManifestFileName();
|
||||||
|
|
||||||
@ -184,10 +187,10 @@ TEST(RecoveryTest, LargeManifestCompacted) {
|
|||||||
{
|
{
|
||||||
uint64_t len = FileSize(old_manifest);
|
uint64_t len = FileSize(old_manifest);
|
||||||
WritableFile* file;
|
WritableFile* file;
|
||||||
ASSERT_OK(env()->NewAppendableFile(old_manifest, &file));
|
ASSERT_LEVELDB_OK(env()->NewAppendableFile(old_manifest, &file));
|
||||||
std::string zeroes(3 * 1048576 - static_cast<size_t>(len), 0);
|
std::string zeroes(3 * 1048576 - static_cast<size_t>(len), 0);
|
||||||
ASSERT_OK(file->Append(zeroes));
|
ASSERT_LEVELDB_OK(file->Append(zeroes));
|
||||||
ASSERT_OK(file->Flush());
|
ASSERT_LEVELDB_OK(file->Flush());
|
||||||
delete file;
|
delete file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,8 +205,8 @@ TEST(RecoveryTest, LargeManifestCompacted) {
|
|||||||
ASSERT_EQ("bar", Get("foo"));
|
ASSERT_EQ("bar", Get("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RecoveryTest, NoLogFiles) {
|
TEST_F(RecoveryTest, NoLogFiles) {
|
||||||
ASSERT_OK(Put("foo", "bar"));
|
ASSERT_LEVELDB_OK(Put("foo", "bar"));
|
||||||
ASSERT_EQ(1, DeleteLogFiles());
|
ASSERT_EQ(1, DeleteLogFiles());
|
||||||
Open();
|
Open();
|
||||||
ASSERT_EQ("NOT_FOUND", Get("foo"));
|
ASSERT_EQ("NOT_FOUND", Get("foo"));
|
||||||
@ -211,13 +214,13 @@ TEST(RecoveryTest, NoLogFiles) {
|
|||||||
ASSERT_EQ("NOT_FOUND", Get("foo"));
|
ASSERT_EQ("NOT_FOUND", Get("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RecoveryTest, LogFileReuse) {
|
TEST_F(RecoveryTest, LogFileReuse) {
|
||||||
if (!CanAppend()) {
|
if (!CanAppend()) {
|
||||||
fprintf(stderr, "skipping test because env does not support appending\n");
|
fprintf(stderr, "skipping test because env does not support appending\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
ASSERT_OK(Put("foo", "bar"));
|
ASSERT_LEVELDB_OK(Put("foo", "bar"));
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
// Compact to ensure current log is empty
|
// Compact to ensure current log is empty
|
||||||
CompactMemTable();
|
CompactMemTable();
|
||||||
@ -241,13 +244,13 @@ TEST(RecoveryTest, LogFileReuse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RecoveryTest, MultipleMemTables) {
|
TEST_F(RecoveryTest, MultipleMemTables) {
|
||||||
// Make a large log.
|
// Make a large log.
|
||||||
const int kNum = 1000;
|
const int kNum = 1000;
|
||||||
for (int i = 0; i < kNum; i++) {
|
for (int i = 0; i < kNum; i++) {
|
||||||
char buf[100];
|
char buf[100];
|
||||||
snprintf(buf, sizeof(buf), "%050d", i);
|
snprintf(buf, sizeof(buf), "%050d", i);
|
||||||
ASSERT_OK(Put(buf, buf));
|
ASSERT_LEVELDB_OK(Put(buf, buf));
|
||||||
}
|
}
|
||||||
ASSERT_EQ(0, NumTables());
|
ASSERT_EQ(0, NumTables());
|
||||||
Close();
|
Close();
|
||||||
@ -270,8 +273,8 @@ TEST(RecoveryTest, MultipleMemTables) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RecoveryTest, MultipleLogFiles) {
|
TEST_F(RecoveryTest, MultipleLogFiles) {
|
||||||
ASSERT_OK(Put("foo", "bar"));
|
ASSERT_LEVELDB_OK(Put("foo", "bar"));
|
||||||
Close();
|
Close();
|
||||||
ASSERT_EQ(1, NumLogs());
|
ASSERT_EQ(1, NumLogs());
|
||||||
|
|
||||||
@ -316,8 +319,8 @@ TEST(RecoveryTest, MultipleLogFiles) {
|
|||||||
ASSERT_EQ("there", Get("hi"));
|
ASSERT_EQ("there", Get("hi"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RecoveryTest, ManifestMissing) {
|
TEST_F(RecoveryTest, ManifestMissing) {
|
||||||
ASSERT_OK(Put("foo", "bar"));
|
ASSERT_LEVELDB_OK(Put("foo", "bar"));
|
||||||
Close();
|
Close();
|
||||||
DeleteManifestFile();
|
DeleteManifestFile();
|
||||||
|
|
||||||
@ -327,4 +330,7 @@ TEST(RecoveryTest, ManifestMissing) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -7,13 +7,14 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
#include "port/port.h"
|
#include "port/port.h"
|
||||||
#include "port/thread_annotations.h"
|
#include "port/thread_annotations.h"
|
||||||
#include "util/arena.h"
|
#include "util/arena.h"
|
||||||
#include "util/hash.h"
|
#include "util/hash.h"
|
||||||
#include "util/random.h"
|
#include "util/random.h"
|
||||||
#include "util/testharness.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
@ -31,8 +32,6 @@ struct Comparator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SkipTest {};
|
|
||||||
|
|
||||||
TEST(SkipTest, Empty) {
|
TEST(SkipTest, Empty) {
|
||||||
Arena arena;
|
Arena arena;
|
||||||
Comparator cmp;
|
Comparator cmp;
|
||||||
@ -366,4 +365,7 @@ TEST(SkipTest, Concurrent5) { RunConcurrent(5); }
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
#include "db/version_edit.h"
|
#include "db/version_edit.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
@ -17,8 +18,6 @@ static void TestEncodeDecode(const VersionEdit& edit) {
|
|||||||
ASSERT_EQ(encoded, encoded2);
|
ASSERT_EQ(encoded, encoded2);
|
||||||
}
|
}
|
||||||
|
|
||||||
class VersionEditTest {};
|
|
||||||
|
|
||||||
TEST(VersionEditTest, EncodeDecode) {
|
TEST(VersionEditTest, EncodeDecode) {
|
||||||
static const uint64_t kBig = 1ull << 50;
|
static const uint64_t kBig = 1ull << 50;
|
||||||
|
|
||||||
@ -41,4 +40,7 @@ TEST(VersionEditTest, EncodeDecode) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -3,13 +3,14 @@
|
|||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
#include "db/version_set.h"
|
#include "db/version_set.h"
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
#include "util/testutil.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
class FindFileTest {
|
class FindFileTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
FindFileTest() : disjoint_sorted_files_(true) {}
|
FindFileTest() : disjoint_sorted_files_(true) {}
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ class FindFileTest {
|
|||||||
std::vector<FileMetaData*> files_;
|
std::vector<FileMetaData*> files_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(FindFileTest, Empty) {
|
TEST_F(FindFileTest, Empty) {
|
||||||
ASSERT_EQ(0, Find("foo"));
|
ASSERT_EQ(0, Find("foo"));
|
||||||
ASSERT_TRUE(!Overlaps("a", "z"));
|
ASSERT_TRUE(!Overlaps("a", "z"));
|
||||||
ASSERT_TRUE(!Overlaps(nullptr, "z"));
|
ASSERT_TRUE(!Overlaps(nullptr, "z"));
|
||||||
@ -58,7 +59,7 @@ TEST(FindFileTest, Empty) {
|
|||||||
ASSERT_TRUE(!Overlaps(nullptr, nullptr));
|
ASSERT_TRUE(!Overlaps(nullptr, nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FindFileTest, Single) {
|
TEST_F(FindFileTest, Single) {
|
||||||
Add("p", "q");
|
Add("p", "q");
|
||||||
ASSERT_EQ(0, Find("a"));
|
ASSERT_EQ(0, Find("a"));
|
||||||
ASSERT_EQ(0, Find("p"));
|
ASSERT_EQ(0, Find("p"));
|
||||||
@ -88,7 +89,7 @@ TEST(FindFileTest, Single) {
|
|||||||
ASSERT_TRUE(Overlaps(nullptr, nullptr));
|
ASSERT_TRUE(Overlaps(nullptr, nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FindFileTest, Multiple) {
|
TEST_F(FindFileTest, Multiple) {
|
||||||
Add("150", "200");
|
Add("150", "200");
|
||||||
Add("200", "250");
|
Add("200", "250");
|
||||||
Add("300", "350");
|
Add("300", "350");
|
||||||
@ -126,7 +127,7 @@ TEST(FindFileTest, Multiple) {
|
|||||||
ASSERT_TRUE(Overlaps("450", "500"));
|
ASSERT_TRUE(Overlaps("450", "500"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FindFileTest, MultipleNullBoundaries) {
|
TEST_F(FindFileTest, MultipleNullBoundaries) {
|
||||||
Add("150", "200");
|
Add("150", "200");
|
||||||
Add("200", "250");
|
Add("200", "250");
|
||||||
Add("300", "350");
|
Add("300", "350");
|
||||||
@ -146,7 +147,7 @@ TEST(FindFileTest, MultipleNullBoundaries) {
|
|||||||
ASSERT_TRUE(Overlaps("450", nullptr));
|
ASSERT_TRUE(Overlaps("450", nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FindFileTest, OverlapSequenceChecks) {
|
TEST_F(FindFileTest, OverlapSequenceChecks) {
|
||||||
Add("200", "200", 5000, 3000);
|
Add("200", "200", 5000, 3000);
|
||||||
ASSERT_TRUE(!Overlaps("199", "199"));
|
ASSERT_TRUE(!Overlaps("199", "199"));
|
||||||
ASSERT_TRUE(!Overlaps("201", "300"));
|
ASSERT_TRUE(!Overlaps("201", "300"));
|
||||||
@ -155,7 +156,7 @@ TEST(FindFileTest, OverlapSequenceChecks) {
|
|||||||
ASSERT_TRUE(Overlaps("200", "210"));
|
ASSERT_TRUE(Overlaps("200", "210"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FindFileTest, OverlappingFiles) {
|
TEST_F(FindFileTest, OverlappingFiles) {
|
||||||
Add("150", "600");
|
Add("150", "600");
|
||||||
Add("400", "500");
|
Add("400", "500");
|
||||||
disjoint_sorted_files_ = false;
|
disjoint_sorted_files_ = false;
|
||||||
@ -177,7 +178,7 @@ void AddBoundaryInputs(const InternalKeyComparator& icmp,
|
|||||||
const std::vector<FileMetaData*>& level_files,
|
const std::vector<FileMetaData*>& level_files,
|
||||||
std::vector<FileMetaData*>* compaction_files);
|
std::vector<FileMetaData*>* compaction_files);
|
||||||
|
|
||||||
class AddBoundaryInputsTest {
|
class AddBoundaryInputsTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
std::vector<FileMetaData*> level_files_;
|
std::vector<FileMetaData*> level_files_;
|
||||||
std::vector<FileMetaData*> compaction_files_;
|
std::vector<FileMetaData*> compaction_files_;
|
||||||
@ -204,13 +205,13 @@ class AddBoundaryInputsTest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(AddBoundaryInputsTest, TestEmptyFileSets) {
|
TEST_F(AddBoundaryInputsTest, TestEmptyFileSets) {
|
||||||
AddBoundaryInputs(icmp_, level_files_, &compaction_files_);
|
AddBoundaryInputs(icmp_, level_files_, &compaction_files_);
|
||||||
ASSERT_TRUE(compaction_files_.empty());
|
ASSERT_TRUE(compaction_files_.empty());
|
||||||
ASSERT_TRUE(level_files_.empty());
|
ASSERT_TRUE(level_files_.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AddBoundaryInputsTest, TestEmptyLevelFiles) {
|
TEST_F(AddBoundaryInputsTest, TestEmptyLevelFiles) {
|
||||||
FileMetaData* f1 =
|
FileMetaData* f1 =
|
||||||
CreateFileMetaData(1, InternalKey("100", 2, kTypeValue),
|
CreateFileMetaData(1, InternalKey("100", 2, kTypeValue),
|
||||||
InternalKey(InternalKey("100", 1, kTypeValue)));
|
InternalKey(InternalKey("100", 1, kTypeValue)));
|
||||||
@ -222,7 +223,7 @@ TEST(AddBoundaryInputsTest, TestEmptyLevelFiles) {
|
|||||||
ASSERT_TRUE(level_files_.empty());
|
ASSERT_TRUE(level_files_.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AddBoundaryInputsTest, TestEmptyCompactionFiles) {
|
TEST_F(AddBoundaryInputsTest, TestEmptyCompactionFiles) {
|
||||||
FileMetaData* f1 =
|
FileMetaData* f1 =
|
||||||
CreateFileMetaData(1, InternalKey("100", 2, kTypeValue),
|
CreateFileMetaData(1, InternalKey("100", 2, kTypeValue),
|
||||||
InternalKey(InternalKey("100", 1, kTypeValue)));
|
InternalKey(InternalKey("100", 1, kTypeValue)));
|
||||||
@ -234,7 +235,7 @@ TEST(AddBoundaryInputsTest, TestEmptyCompactionFiles) {
|
|||||||
ASSERT_EQ(f1, level_files_[0]);
|
ASSERT_EQ(f1, level_files_[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AddBoundaryInputsTest, TestNoBoundaryFiles) {
|
TEST_F(AddBoundaryInputsTest, TestNoBoundaryFiles) {
|
||||||
FileMetaData* f1 =
|
FileMetaData* f1 =
|
||||||
CreateFileMetaData(1, InternalKey("100", 2, kTypeValue),
|
CreateFileMetaData(1, InternalKey("100", 2, kTypeValue),
|
||||||
InternalKey(InternalKey("100", 1, kTypeValue)));
|
InternalKey(InternalKey("100", 1, kTypeValue)));
|
||||||
@ -255,7 +256,7 @@ TEST(AddBoundaryInputsTest, TestNoBoundaryFiles) {
|
|||||||
ASSERT_EQ(2, compaction_files_.size());
|
ASSERT_EQ(2, compaction_files_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AddBoundaryInputsTest, TestOneBoundaryFiles) {
|
TEST_F(AddBoundaryInputsTest, TestOneBoundaryFiles) {
|
||||||
FileMetaData* f1 =
|
FileMetaData* f1 =
|
||||||
CreateFileMetaData(1, InternalKey("100", 3, kTypeValue),
|
CreateFileMetaData(1, InternalKey("100", 3, kTypeValue),
|
||||||
InternalKey(InternalKey("100", 2, kTypeValue)));
|
InternalKey(InternalKey("100", 2, kTypeValue)));
|
||||||
@ -277,7 +278,7 @@ TEST(AddBoundaryInputsTest, TestOneBoundaryFiles) {
|
|||||||
ASSERT_EQ(f2, compaction_files_[1]);
|
ASSERT_EQ(f2, compaction_files_[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AddBoundaryInputsTest, TestTwoBoundaryFiles) {
|
TEST_F(AddBoundaryInputsTest, TestTwoBoundaryFiles) {
|
||||||
FileMetaData* f1 =
|
FileMetaData* f1 =
|
||||||
CreateFileMetaData(1, InternalKey("100", 6, kTypeValue),
|
CreateFileMetaData(1, InternalKey("100", 6, kTypeValue),
|
||||||
InternalKey(InternalKey("100", 5, kTypeValue)));
|
InternalKey(InternalKey("100", 5, kTypeValue)));
|
||||||
@ -300,7 +301,7 @@ TEST(AddBoundaryInputsTest, TestTwoBoundaryFiles) {
|
|||||||
ASSERT_EQ(f2, compaction_files_[2]);
|
ASSERT_EQ(f2, compaction_files_[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AddBoundaryInputsTest, TestDisjoinFilePointers) {
|
TEST_F(AddBoundaryInputsTest, TestDisjoinFilePointers) {
|
||||||
FileMetaData* f1 =
|
FileMetaData* f1 =
|
||||||
CreateFileMetaData(1, InternalKey("100", 6, kTypeValue),
|
CreateFileMetaData(1, InternalKey("100", 6, kTypeValue),
|
||||||
InternalKey(InternalKey("100", 5, kTypeValue)));
|
InternalKey(InternalKey("100", 5, kTypeValue)));
|
||||||
@ -329,4 +330,7 @@ TEST(AddBoundaryInputsTest, TestDisjoinFilePointers) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
#include "leveldb/db.h"
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "db/memtable.h"
|
#include "db/memtable.h"
|
||||||
#include "db/write_batch_internal.h"
|
#include "db/write_batch_internal.h"
|
||||||
|
#include "leveldb/db.h"
|
||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
@ -22,7 +21,7 @@ static std::string PrintContents(WriteBatch* b) {
|
|||||||
Iterator* iter = mem->NewIterator();
|
Iterator* iter = mem->NewIterator();
|
||||||
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
||||||
ParsedInternalKey ikey;
|
ParsedInternalKey ikey;
|
||||||
ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey));
|
EXPECT_TRUE(ParseInternalKey(iter->key(), &ikey));
|
||||||
switch (ikey.type) {
|
switch (ikey.type) {
|
||||||
case kTypeValue:
|
case kTypeValue:
|
||||||
state.append("Put(");
|
state.append("Put(");
|
||||||
@ -52,8 +51,6 @@ static std::string PrintContents(WriteBatch* b) {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
class WriteBatchTest {};
|
|
||||||
|
|
||||||
TEST(WriteBatchTest, Empty) {
|
TEST(WriteBatchTest, Empty) {
|
||||||
WriteBatch batch;
|
WriteBatch batch;
|
||||||
ASSERT_EQ("", PrintContents(&batch));
|
ASSERT_EQ("", PrintContents(&batch));
|
||||||
@ -134,4 +131,7 @@ TEST(WriteBatchTest, ApproximateSize) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -7,14 +7,15 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "db/db_impl.h"
|
#include "db/db_impl.h"
|
||||||
#include "leveldb/db.h"
|
#include "leveldb/db.h"
|
||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
#include "util/testharness.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
class MemEnvTest {
|
class MemEnvTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
MemEnvTest() : env_(NewMemEnv(Env::Default())) {}
|
MemEnvTest() : env_(NewMemEnv(Env::Default())) {}
|
||||||
~MemEnvTest() { delete env_; }
|
~MemEnvTest() { delete env_; }
|
||||||
@ -22,55 +23,55 @@ class MemEnvTest {
|
|||||||
Env* env_;
|
Env* env_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(MemEnvTest, Basics) {
|
TEST_F(MemEnvTest, Basics) {
|
||||||
uint64_t file_size;
|
uint64_t file_size;
|
||||||
WritableFile* writable_file;
|
WritableFile* writable_file;
|
||||||
std::vector<std::string> children;
|
std::vector<std::string> children;
|
||||||
|
|
||||||
ASSERT_OK(env_->CreateDir("/dir"));
|
ASSERT_LEVELDB_OK(env_->CreateDir("/dir"));
|
||||||
|
|
||||||
// Check that the directory is empty.
|
// Check that the directory is empty.
|
||||||
ASSERT_TRUE(!env_->FileExists("/dir/non_existent"));
|
ASSERT_TRUE(!env_->FileExists("/dir/non_existent"));
|
||||||
ASSERT_TRUE(!env_->GetFileSize("/dir/non_existent", &file_size).ok());
|
ASSERT_TRUE(!env_->GetFileSize("/dir/non_existent", &file_size).ok());
|
||||||
ASSERT_OK(env_->GetChildren("/dir", &children));
|
ASSERT_LEVELDB_OK(env_->GetChildren("/dir", &children));
|
||||||
ASSERT_EQ(0, children.size());
|
ASSERT_EQ(0, children.size());
|
||||||
|
|
||||||
// Create a file.
|
// Create a file.
|
||||||
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
|
ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
|
||||||
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
|
ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/f", &file_size));
|
||||||
ASSERT_EQ(0, file_size);
|
ASSERT_EQ(0, file_size);
|
||||||
delete writable_file;
|
delete writable_file;
|
||||||
|
|
||||||
// Check that the file exists.
|
// Check that the file exists.
|
||||||
ASSERT_TRUE(env_->FileExists("/dir/f"));
|
ASSERT_TRUE(env_->FileExists("/dir/f"));
|
||||||
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
|
ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/f", &file_size));
|
||||||
ASSERT_EQ(0, file_size);
|
ASSERT_EQ(0, file_size);
|
||||||
ASSERT_OK(env_->GetChildren("/dir", &children));
|
ASSERT_LEVELDB_OK(env_->GetChildren("/dir", &children));
|
||||||
ASSERT_EQ(1, children.size());
|
ASSERT_EQ(1, children.size());
|
||||||
ASSERT_EQ("f", children[0]);
|
ASSERT_EQ("f", children[0]);
|
||||||
|
|
||||||
// Write to the file.
|
// Write to the file.
|
||||||
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
|
ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
|
||||||
ASSERT_OK(writable_file->Append("abc"));
|
ASSERT_LEVELDB_OK(writable_file->Append("abc"));
|
||||||
delete writable_file;
|
delete writable_file;
|
||||||
|
|
||||||
// Check that append works.
|
// Check that append works.
|
||||||
ASSERT_OK(env_->NewAppendableFile("/dir/f", &writable_file));
|
ASSERT_LEVELDB_OK(env_->NewAppendableFile("/dir/f", &writable_file));
|
||||||
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
|
ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/f", &file_size));
|
||||||
ASSERT_EQ(3, file_size);
|
ASSERT_EQ(3, file_size);
|
||||||
ASSERT_OK(writable_file->Append("hello"));
|
ASSERT_LEVELDB_OK(writable_file->Append("hello"));
|
||||||
delete writable_file;
|
delete writable_file;
|
||||||
|
|
||||||
// Check for expected size.
|
// Check for expected size.
|
||||||
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
|
ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/f", &file_size));
|
||||||
ASSERT_EQ(8, file_size);
|
ASSERT_EQ(8, file_size);
|
||||||
|
|
||||||
// Check that renaming works.
|
// Check that renaming works.
|
||||||
ASSERT_TRUE(!env_->RenameFile("/dir/non_existent", "/dir/g").ok());
|
ASSERT_TRUE(!env_->RenameFile("/dir/non_existent", "/dir/g").ok());
|
||||||
ASSERT_OK(env_->RenameFile("/dir/f", "/dir/g"));
|
ASSERT_LEVELDB_OK(env_->RenameFile("/dir/f", "/dir/g"));
|
||||||
ASSERT_TRUE(!env_->FileExists("/dir/f"));
|
ASSERT_TRUE(!env_->FileExists("/dir/f"));
|
||||||
ASSERT_TRUE(env_->FileExists("/dir/g"));
|
ASSERT_TRUE(env_->FileExists("/dir/g"));
|
||||||
ASSERT_OK(env_->GetFileSize("/dir/g", &file_size));
|
ASSERT_LEVELDB_OK(env_->GetFileSize("/dir/g", &file_size));
|
||||||
ASSERT_EQ(8, file_size);
|
ASSERT_EQ(8, file_size);
|
||||||
|
|
||||||
// Check that opening non-existent file fails.
|
// Check that opening non-existent file fails.
|
||||||
@ -83,48 +84,49 @@ TEST(MemEnvTest, Basics) {
|
|||||||
|
|
||||||
// Check that deleting works.
|
// Check that deleting works.
|
||||||
ASSERT_TRUE(!env_->DeleteFile("/dir/non_existent").ok());
|
ASSERT_TRUE(!env_->DeleteFile("/dir/non_existent").ok());
|
||||||
ASSERT_OK(env_->DeleteFile("/dir/g"));
|
ASSERT_LEVELDB_OK(env_->DeleteFile("/dir/g"));
|
||||||
ASSERT_TRUE(!env_->FileExists("/dir/g"));
|
ASSERT_TRUE(!env_->FileExists("/dir/g"));
|
||||||
ASSERT_OK(env_->GetChildren("/dir", &children));
|
ASSERT_LEVELDB_OK(env_->GetChildren("/dir", &children));
|
||||||
ASSERT_EQ(0, children.size());
|
ASSERT_EQ(0, children.size());
|
||||||
ASSERT_OK(env_->DeleteDir("/dir"));
|
ASSERT_LEVELDB_OK(env_->DeleteDir("/dir"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemEnvTest, ReadWrite) {
|
TEST_F(MemEnvTest, ReadWrite) {
|
||||||
WritableFile* writable_file;
|
WritableFile* writable_file;
|
||||||
SequentialFile* seq_file;
|
SequentialFile* seq_file;
|
||||||
RandomAccessFile* rand_file;
|
RandomAccessFile* rand_file;
|
||||||
Slice result;
|
Slice result;
|
||||||
char scratch[100];
|
char scratch[100];
|
||||||
|
|
||||||
ASSERT_OK(env_->CreateDir("/dir"));
|
ASSERT_LEVELDB_OK(env_->CreateDir("/dir"));
|
||||||
|
|
||||||
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
|
ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
|
||||||
ASSERT_OK(writable_file->Append("hello "));
|
ASSERT_LEVELDB_OK(writable_file->Append("hello "));
|
||||||
ASSERT_OK(writable_file->Append("world"));
|
ASSERT_LEVELDB_OK(writable_file->Append("world"));
|
||||||
delete writable_file;
|
delete writable_file;
|
||||||
|
|
||||||
// Read sequentially.
|
// Read sequentially.
|
||||||
ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file));
|
ASSERT_LEVELDB_OK(env_->NewSequentialFile("/dir/f", &seq_file));
|
||||||
ASSERT_OK(seq_file->Read(5, &result, scratch)); // Read "hello".
|
ASSERT_LEVELDB_OK(seq_file->Read(5, &result, scratch)); // Read "hello".
|
||||||
ASSERT_EQ(0, result.compare("hello"));
|
ASSERT_EQ(0, result.compare("hello"));
|
||||||
ASSERT_OK(seq_file->Skip(1));
|
ASSERT_LEVELDB_OK(seq_file->Skip(1));
|
||||||
ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Read "world".
|
ASSERT_LEVELDB_OK(seq_file->Read(1000, &result, scratch)); // Read "world".
|
||||||
ASSERT_EQ(0, result.compare("world"));
|
ASSERT_EQ(0, result.compare("world"));
|
||||||
ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Try reading past EOF.
|
ASSERT_LEVELDB_OK(
|
||||||
|
seq_file->Read(1000, &result, scratch)); // Try reading past EOF.
|
||||||
ASSERT_EQ(0, result.size());
|
ASSERT_EQ(0, result.size());
|
||||||
ASSERT_OK(seq_file->Skip(100)); // Try to skip past end of file.
|
ASSERT_LEVELDB_OK(seq_file->Skip(100)); // Try to skip past end of file.
|
||||||
ASSERT_OK(seq_file->Read(1000, &result, scratch));
|
ASSERT_LEVELDB_OK(seq_file->Read(1000, &result, scratch));
|
||||||
ASSERT_EQ(0, result.size());
|
ASSERT_EQ(0, result.size());
|
||||||
delete seq_file;
|
delete seq_file;
|
||||||
|
|
||||||
// Random reads.
|
// Random reads.
|
||||||
ASSERT_OK(env_->NewRandomAccessFile("/dir/f", &rand_file));
|
ASSERT_LEVELDB_OK(env_->NewRandomAccessFile("/dir/f", &rand_file));
|
||||||
ASSERT_OK(rand_file->Read(6, 5, &result, scratch)); // Read "world".
|
ASSERT_LEVELDB_OK(rand_file->Read(6, 5, &result, scratch)); // Read "world".
|
||||||
ASSERT_EQ(0, result.compare("world"));
|
ASSERT_EQ(0, result.compare("world"));
|
||||||
ASSERT_OK(rand_file->Read(0, 5, &result, scratch)); // Read "hello".
|
ASSERT_LEVELDB_OK(rand_file->Read(0, 5, &result, scratch)); // Read "hello".
|
||||||
ASSERT_EQ(0, result.compare("hello"));
|
ASSERT_EQ(0, result.compare("hello"));
|
||||||
ASSERT_OK(rand_file->Read(10, 100, &result, scratch)); // Read "d".
|
ASSERT_LEVELDB_OK(rand_file->Read(10, 100, &result, scratch)); // Read "d".
|
||||||
ASSERT_EQ(0, result.compare("d"));
|
ASSERT_EQ(0, result.compare("d"));
|
||||||
|
|
||||||
// Too high offset.
|
// Too high offset.
|
||||||
@ -132,30 +134,30 @@ TEST(MemEnvTest, ReadWrite) {
|
|||||||
delete rand_file;
|
delete rand_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemEnvTest, Locks) {
|
TEST_F(MemEnvTest, Locks) {
|
||||||
FileLock* lock;
|
FileLock* lock;
|
||||||
|
|
||||||
// These are no-ops, but we test they return success.
|
// These are no-ops, but we test they return success.
|
||||||
ASSERT_OK(env_->LockFile("some file", &lock));
|
ASSERT_LEVELDB_OK(env_->LockFile("some file", &lock));
|
||||||
ASSERT_OK(env_->UnlockFile(lock));
|
ASSERT_LEVELDB_OK(env_->UnlockFile(lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemEnvTest, Misc) {
|
TEST_F(MemEnvTest, Misc) {
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
ASSERT_TRUE(!test_dir.empty());
|
ASSERT_TRUE(!test_dir.empty());
|
||||||
|
|
||||||
WritableFile* writable_file;
|
WritableFile* writable_file;
|
||||||
ASSERT_OK(env_->NewWritableFile("/a/b", &writable_file));
|
ASSERT_LEVELDB_OK(env_->NewWritableFile("/a/b", &writable_file));
|
||||||
|
|
||||||
// These are no-ops, but we test they return success.
|
// These are no-ops, but we test they return success.
|
||||||
ASSERT_OK(writable_file->Sync());
|
ASSERT_LEVELDB_OK(writable_file->Sync());
|
||||||
ASSERT_OK(writable_file->Flush());
|
ASSERT_LEVELDB_OK(writable_file->Flush());
|
||||||
ASSERT_OK(writable_file->Close());
|
ASSERT_LEVELDB_OK(writable_file->Close());
|
||||||
delete writable_file;
|
delete writable_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemEnvTest, LargeWrite) {
|
TEST_F(MemEnvTest, LargeWrite) {
|
||||||
const size_t kWriteSize = 300 * 1024;
|
const size_t kWriteSize = 300 * 1024;
|
||||||
char* scratch = new char[kWriteSize * 2];
|
char* scratch = new char[kWriteSize * 2];
|
||||||
|
|
||||||
@ -165,21 +167,21 @@ TEST(MemEnvTest, LargeWrite) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WritableFile* writable_file;
|
WritableFile* writable_file;
|
||||||
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
|
ASSERT_LEVELDB_OK(env_->NewWritableFile("/dir/f", &writable_file));
|
||||||
ASSERT_OK(writable_file->Append("foo"));
|
ASSERT_LEVELDB_OK(writable_file->Append("foo"));
|
||||||
ASSERT_OK(writable_file->Append(write_data));
|
ASSERT_LEVELDB_OK(writable_file->Append(write_data));
|
||||||
delete writable_file;
|
delete writable_file;
|
||||||
|
|
||||||
SequentialFile* seq_file;
|
SequentialFile* seq_file;
|
||||||
Slice result;
|
Slice result;
|
||||||
ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file));
|
ASSERT_LEVELDB_OK(env_->NewSequentialFile("/dir/f", &seq_file));
|
||||||
ASSERT_OK(seq_file->Read(3, &result, scratch)); // Read "foo".
|
ASSERT_LEVELDB_OK(seq_file->Read(3, &result, scratch)); // Read "foo".
|
||||||
ASSERT_EQ(0, result.compare("foo"));
|
ASSERT_EQ(0, result.compare("foo"));
|
||||||
|
|
||||||
size_t read = 0;
|
size_t read = 0;
|
||||||
std::string read_data;
|
std::string read_data;
|
||||||
while (read < kWriteSize) {
|
while (read < kWriteSize) {
|
||||||
ASSERT_OK(seq_file->Read(kWriteSize - read, &result, scratch));
|
ASSERT_LEVELDB_OK(seq_file->Read(kWriteSize - read, &result, scratch));
|
||||||
read_data.append(result.data(), result.size());
|
read_data.append(result.data(), result.size());
|
||||||
read += result.size();
|
read += result.size();
|
||||||
}
|
}
|
||||||
@ -188,30 +190,30 @@ TEST(MemEnvTest, LargeWrite) {
|
|||||||
delete[] scratch;
|
delete[] scratch;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemEnvTest, OverwriteOpenFile) {
|
TEST_F(MemEnvTest, OverwriteOpenFile) {
|
||||||
const char kWrite1Data[] = "Write #1 data";
|
const char kWrite1Data[] = "Write #1 data";
|
||||||
const size_t kFileDataLen = sizeof(kWrite1Data) - 1;
|
const size_t kFileDataLen = sizeof(kWrite1Data) - 1;
|
||||||
const std::string kTestFileName = test::TmpDir() + "/leveldb-TestFile.dat";
|
const std::string kTestFileName = testing::TempDir() + "leveldb-TestFile.dat";
|
||||||
|
|
||||||
ASSERT_OK(WriteStringToFile(env_, kWrite1Data, kTestFileName));
|
ASSERT_LEVELDB_OK(WriteStringToFile(env_, kWrite1Data, kTestFileName));
|
||||||
|
|
||||||
RandomAccessFile* rand_file;
|
RandomAccessFile* rand_file;
|
||||||
ASSERT_OK(env_->NewRandomAccessFile(kTestFileName, &rand_file));
|
ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(kTestFileName, &rand_file));
|
||||||
|
|
||||||
const char kWrite2Data[] = "Write #2 data";
|
const char kWrite2Data[] = "Write #2 data";
|
||||||
ASSERT_OK(WriteStringToFile(env_, kWrite2Data, kTestFileName));
|
ASSERT_LEVELDB_OK(WriteStringToFile(env_, kWrite2Data, kTestFileName));
|
||||||
|
|
||||||
// Verify that overwriting an open file will result in the new file data
|
// Verify that overwriting an open file will result in the new file data
|
||||||
// being read from files opened before the write.
|
// being read from files opened before the write.
|
||||||
Slice result;
|
Slice result;
|
||||||
char scratch[kFileDataLen];
|
char scratch[kFileDataLen];
|
||||||
ASSERT_OK(rand_file->Read(0, kFileDataLen, &result, scratch));
|
ASSERT_LEVELDB_OK(rand_file->Read(0, kFileDataLen, &result, scratch));
|
||||||
ASSERT_EQ(0, result.compare(kWrite2Data));
|
ASSERT_EQ(0, result.compare(kWrite2Data));
|
||||||
|
|
||||||
delete rand_file;
|
delete rand_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemEnvTest, DBTest) {
|
TEST_F(MemEnvTest, DBTest) {
|
||||||
Options options;
|
Options options;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
options.env = env_;
|
options.env = env_;
|
||||||
@ -220,14 +222,14 @@ TEST(MemEnvTest, DBTest) {
|
|||||||
const Slice keys[] = {Slice("aaa"), Slice("bbb"), Slice("ccc")};
|
const Slice keys[] = {Slice("aaa"), Slice("bbb"), Slice("ccc")};
|
||||||
const Slice vals[] = {Slice("foo"), Slice("bar"), Slice("baz")};
|
const Slice vals[] = {Slice("foo"), Slice("bar"), Slice("baz")};
|
||||||
|
|
||||||
ASSERT_OK(DB::Open(options, "/dir/db", &db));
|
ASSERT_LEVELDB_OK(DB::Open(options, "/dir/db", &db));
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
ASSERT_OK(db->Put(WriteOptions(), keys[i], vals[i]));
|
ASSERT_LEVELDB_OK(db->Put(WriteOptions(), keys[i], vals[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
std::string res;
|
std::string res;
|
||||||
ASSERT_OK(db->Get(ReadOptions(), keys[i], &res));
|
ASSERT_LEVELDB_OK(db->Get(ReadOptions(), keys[i], &res));
|
||||||
ASSERT_TRUE(res == vals[i]);
|
ASSERT_TRUE(res == vals[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,11 +245,11 @@ TEST(MemEnvTest, DBTest) {
|
|||||||
delete iterator;
|
delete iterator;
|
||||||
|
|
||||||
DBImpl* dbi = reinterpret_cast<DBImpl*>(db);
|
DBImpl* dbi = reinterpret_cast<DBImpl*>(db);
|
||||||
ASSERT_OK(dbi->TEST_CompactMemTable());
|
ASSERT_LEVELDB_OK(dbi->TEST_CompactMemTable());
|
||||||
|
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
std::string res;
|
std::string res;
|
||||||
ASSERT_OK(db->Get(ReadOptions(), keys[i], &res));
|
ASSERT_LEVELDB_OK(db->Get(ReadOptions(), keys[i], &res));
|
||||||
ASSERT_TRUE(res == vals[i]);
|
ASSERT_TRUE(res == vals[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,4 +258,7 @@ TEST(MemEnvTest, DBTest) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -7,9 +7,10 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "leveldb/db.h"
|
#include "leveldb/db.h"
|
||||||
#include "leveldb/write_batch.h"
|
#include "leveldb/write_batch.h"
|
||||||
#include "util/testharness.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -23,11 +24,9 @@ std::string Key1(int i) {
|
|||||||
|
|
||||||
std::string Key2(int i) { return Key1(i) + "_xxx"; }
|
std::string Key2(int i) { return Key1(i) + "_xxx"; }
|
||||||
|
|
||||||
class Issue178 {};
|
|
||||||
|
|
||||||
TEST(Issue178, Test) {
|
TEST(Issue178, Test) {
|
||||||
// Get rid of any state from an old run.
|
// Get rid of any state from an old run.
|
||||||
std::string dbpath = leveldb::test::TmpDir() + "/leveldb_cbug_test";
|
std::string dbpath = testing::TempDir() + "leveldb_cbug_test";
|
||||||
DestroyDB(dbpath, leveldb::Options());
|
DestroyDB(dbpath, leveldb::Options());
|
||||||
|
|
||||||
// Open database. Disable compression since it affects the creation
|
// Open database. Disable compression since it affects the creation
|
||||||
@ -37,28 +36,28 @@ TEST(Issue178, Test) {
|
|||||||
leveldb::Options db_options;
|
leveldb::Options db_options;
|
||||||
db_options.create_if_missing = true;
|
db_options.create_if_missing = true;
|
||||||
db_options.compression = leveldb::kNoCompression;
|
db_options.compression = leveldb::kNoCompression;
|
||||||
ASSERT_OK(leveldb::DB::Open(db_options, dbpath, &db));
|
ASSERT_LEVELDB_OK(leveldb::DB::Open(db_options, dbpath, &db));
|
||||||
|
|
||||||
// create first key range
|
// create first key range
|
||||||
leveldb::WriteBatch batch;
|
leveldb::WriteBatch batch;
|
||||||
for (size_t i = 0; i < kNumKeys; i++) {
|
for (size_t i = 0; i < kNumKeys; i++) {
|
||||||
batch.Put(Key1(i), "value for range 1 key");
|
batch.Put(Key1(i), "value for range 1 key");
|
||||||
}
|
}
|
||||||
ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));
|
ASSERT_LEVELDB_OK(db->Write(leveldb::WriteOptions(), &batch));
|
||||||
|
|
||||||
// create second key range
|
// create second key range
|
||||||
batch.Clear();
|
batch.Clear();
|
||||||
for (size_t i = 0; i < kNumKeys; i++) {
|
for (size_t i = 0; i < kNumKeys; i++) {
|
||||||
batch.Put(Key2(i), "value for range 2 key");
|
batch.Put(Key2(i), "value for range 2 key");
|
||||||
}
|
}
|
||||||
ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));
|
ASSERT_LEVELDB_OK(db->Write(leveldb::WriteOptions(), &batch));
|
||||||
|
|
||||||
// delete second key range
|
// delete second key range
|
||||||
batch.Clear();
|
batch.Clear();
|
||||||
for (size_t i = 0; i < kNumKeys; i++) {
|
for (size_t i = 0; i < kNumKeys; i++) {
|
||||||
batch.Delete(Key2(i));
|
batch.Delete(Key2(i));
|
||||||
}
|
}
|
||||||
ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));
|
ASSERT_LEVELDB_OK(db->Write(leveldb::WriteOptions(), &batch));
|
||||||
|
|
||||||
// compact database
|
// compact database
|
||||||
std::string start_key = Key1(0);
|
std::string start_key = Key1(0);
|
||||||
@ -85,4 +84,7 @@ TEST(Issue178, Test) {
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -6,35 +6,34 @@
|
|||||||
// to forward, the current key can be yielded unexpectedly if a new
|
// to forward, the current key can be yielded unexpectedly if a new
|
||||||
// mutation has been added just before the current key.
|
// mutation has been added just before the current key.
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "leveldb/db.h"
|
#include "leveldb/db.h"
|
||||||
#include "util/testharness.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
class Issue200 {};
|
|
||||||
|
|
||||||
TEST(Issue200, Test) {
|
TEST(Issue200, Test) {
|
||||||
// Get rid of any state from an old run.
|
// Get rid of any state from an old run.
|
||||||
std::string dbpath = test::TmpDir() + "/leveldb_issue200_test";
|
std::string dbpath = testing::TempDir() + "leveldb_issue200_test";
|
||||||
DestroyDB(dbpath, Options());
|
DestroyDB(dbpath, Options());
|
||||||
|
|
||||||
DB* db;
|
DB* db;
|
||||||
Options options;
|
Options options;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
ASSERT_OK(DB::Open(options, dbpath, &db));
|
ASSERT_LEVELDB_OK(DB::Open(options, dbpath, &db));
|
||||||
|
|
||||||
WriteOptions write_options;
|
WriteOptions write_options;
|
||||||
ASSERT_OK(db->Put(write_options, "1", "b"));
|
ASSERT_LEVELDB_OK(db->Put(write_options, "1", "b"));
|
||||||
ASSERT_OK(db->Put(write_options, "2", "c"));
|
ASSERT_LEVELDB_OK(db->Put(write_options, "2", "c"));
|
||||||
ASSERT_OK(db->Put(write_options, "3", "d"));
|
ASSERT_LEVELDB_OK(db->Put(write_options, "3", "d"));
|
||||||
ASSERT_OK(db->Put(write_options, "4", "e"));
|
ASSERT_LEVELDB_OK(db->Put(write_options, "4", "e"));
|
||||||
ASSERT_OK(db->Put(write_options, "5", "f"));
|
ASSERT_LEVELDB_OK(db->Put(write_options, "5", "f"));
|
||||||
|
|
||||||
ReadOptions read_options;
|
ReadOptions read_options;
|
||||||
Iterator* iter = db->NewIterator(read_options);
|
Iterator* iter = db->NewIterator(read_options);
|
||||||
|
|
||||||
// Add an element that should not be reflected in the iterator.
|
// Add an element that should not be reflected in the iterator.
|
||||||
ASSERT_OK(db->Put(write_options, "25", "cd"));
|
ASSERT_LEVELDB_OK(db->Put(write_options, "25", "cd"));
|
||||||
|
|
||||||
iter->Seek("5");
|
iter->Seek("5");
|
||||||
ASSERT_EQ(iter->key().ToString(), "5");
|
ASSERT_EQ(iter->key().ToString(), "5");
|
||||||
@ -54,4 +53,7 @@ TEST(Issue200, Test) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -9,9 +9,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "leveldb/db.h"
|
#include "leveldb/db.h"
|
||||||
#include "leveldb/write_batch.h"
|
#include "leveldb/write_batch.h"
|
||||||
#include "util/testharness.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
@ -37,8 +38,6 @@ std::string CreateRandomString(int32_t index) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class Issue320 {};
|
|
||||||
|
|
||||||
TEST(Issue320, Test) {
|
TEST(Issue320, Test) {
|
||||||
std::srand(0);
|
std::srand(0);
|
||||||
|
|
||||||
@ -53,8 +52,8 @@ TEST(Issue320, Test) {
|
|||||||
Options options;
|
Options options;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
|
|
||||||
std::string dbpath = test::TmpDir() + "/leveldb_issue320_test";
|
std::string dbpath = testing::TempDir() + "leveldb_issue320_test";
|
||||||
ASSERT_OK(DB::Open(options, dbpath, &db));
|
ASSERT_LEVELDB_OK(DB::Open(options, dbpath, &db));
|
||||||
|
|
||||||
uint32_t target_size = 10000;
|
uint32_t target_size = 10000;
|
||||||
uint32_t num_items = 0;
|
uint32_t num_items = 0;
|
||||||
@ -78,7 +77,8 @@ TEST(Issue320, Test) {
|
|||||||
CreateRandomString(index), CreateRandomString(index)));
|
CreateRandomString(index), CreateRandomString(index)));
|
||||||
batch.Put(test_map[index]->first, test_map[index]->second);
|
batch.Put(test_map[index]->first, test_map[index]->second);
|
||||||
} else {
|
} else {
|
||||||
ASSERT_OK(db->Get(readOptions, test_map[index]->first, &old_value));
|
ASSERT_LEVELDB_OK(
|
||||||
|
db->Get(readOptions, test_map[index]->first, &old_value));
|
||||||
if (old_value != test_map[index]->second) {
|
if (old_value != test_map[index]->second) {
|
||||||
std::cout << "ERROR incorrect value returned by Get" << std::endl;
|
std::cout << "ERROR incorrect value returned by Get" << std::endl;
|
||||||
std::cout << " count=" << count << std::endl;
|
std::cout << " count=" << count << std::endl;
|
||||||
@ -102,7 +102,7 @@ TEST(Issue320, Test) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_OK(db->Write(writeOptions, &batch));
|
ASSERT_LEVELDB_OK(db->Write(writeOptions, &batch));
|
||||||
|
|
||||||
if (keep_snapshots && GenerateRandomNumber(10) == 0) {
|
if (keep_snapshots && GenerateRandomNumber(10) == 0) {
|
||||||
int i = GenerateRandomNumber(snapshots.size());
|
int i = GenerateRandomNumber(snapshots.size());
|
||||||
@ -125,4 +125,7 @@ TEST(Issue320, Test) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
#include "table/filter_block.h"
|
#include "table/filter_block.h"
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "leveldb/filter_policy.h"
|
#include "leveldb/filter_policy.h"
|
||||||
#include "util/coding.h"
|
#include "util/coding.h"
|
||||||
#include "util/hash.h"
|
#include "util/hash.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
#include "util/testutil.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
@ -36,12 +36,12 @@ class TestHashFilter : public FilterPolicy {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FilterBlockTest {
|
class FilterBlockTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
TestHashFilter policy_;
|
TestHashFilter policy_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(FilterBlockTest, EmptyBuilder) {
|
TEST_F(FilterBlockTest, EmptyBuilder) {
|
||||||
FilterBlockBuilder builder(&policy_);
|
FilterBlockBuilder builder(&policy_);
|
||||||
Slice block = builder.Finish();
|
Slice block = builder.Finish();
|
||||||
ASSERT_EQ("\\x00\\x00\\x00\\x00\\x0b", EscapeString(block));
|
ASSERT_EQ("\\x00\\x00\\x00\\x00\\x0b", EscapeString(block));
|
||||||
@ -50,7 +50,7 @@ TEST(FilterBlockTest, EmptyBuilder) {
|
|||||||
ASSERT_TRUE(reader.KeyMayMatch(100000, "foo"));
|
ASSERT_TRUE(reader.KeyMayMatch(100000, "foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FilterBlockTest, SingleChunk) {
|
TEST_F(FilterBlockTest, SingleChunk) {
|
||||||
FilterBlockBuilder builder(&policy_);
|
FilterBlockBuilder builder(&policy_);
|
||||||
builder.StartBlock(100);
|
builder.StartBlock(100);
|
||||||
builder.AddKey("foo");
|
builder.AddKey("foo");
|
||||||
@ -71,7 +71,7 @@ TEST(FilterBlockTest, SingleChunk) {
|
|||||||
ASSERT_TRUE(!reader.KeyMayMatch(100, "other"));
|
ASSERT_TRUE(!reader.KeyMayMatch(100, "other"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FilterBlockTest, MultiChunk) {
|
TEST_F(FilterBlockTest, MultiChunk) {
|
||||||
FilterBlockBuilder builder(&policy_);
|
FilterBlockBuilder builder(&policy_);
|
||||||
|
|
||||||
// First filter
|
// First filter
|
||||||
@ -121,4 +121,7 @@ TEST(FilterBlockTest, MultiChunk) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "db/dbformat.h"
|
#include "db/dbformat.h"
|
||||||
#include "db/memtable.h"
|
#include "db/memtable.h"
|
||||||
#include "db/write_batch_internal.h"
|
#include "db/write_batch_internal.h"
|
||||||
@ -18,7 +19,6 @@
|
|||||||
#include "table/block_builder.h"
|
#include "table/block_builder.h"
|
||||||
#include "table/format.h"
|
#include "table/format.h"
|
||||||
#include "util/random.h"
|
#include "util/random.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
#include "util/testutil.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
@ -219,12 +219,12 @@ class TableConstructor : public Constructor {
|
|||||||
|
|
||||||
for (const auto& kvp : data) {
|
for (const auto& kvp : data) {
|
||||||
builder.Add(kvp.first, kvp.second);
|
builder.Add(kvp.first, kvp.second);
|
||||||
ASSERT_TRUE(builder.status().ok());
|
EXPECT_LEVELDB_OK(builder.status());
|
||||||
}
|
}
|
||||||
Status s = builder.Finish();
|
Status s = builder.Finish();
|
||||||
ASSERT_TRUE(s.ok()) << s.ToString();
|
EXPECT_LEVELDB_OK(s);
|
||||||
|
|
||||||
ASSERT_EQ(sink.contents().size(), builder.FileSize());
|
EXPECT_EQ(sink.contents().size(), builder.FileSize());
|
||||||
|
|
||||||
// Open the table
|
// Open the table
|
||||||
source_ = new StringSource(sink.contents());
|
source_ = new StringSource(sink.contents());
|
||||||
@ -340,7 +340,7 @@ class DBConstructor : public Constructor {
|
|||||||
for (const auto& kvp : data) {
|
for (const auto& kvp : data) {
|
||||||
WriteBatch batch;
|
WriteBatch batch;
|
||||||
batch.Put(kvp.first, kvp.second);
|
batch.Put(kvp.first, kvp.second);
|
||||||
ASSERT_TRUE(db_->Write(WriteOptions(), &batch).ok());
|
EXPECT_TRUE(db_->Write(WriteOptions(), &batch).ok());
|
||||||
}
|
}
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
@ -352,7 +352,7 @@ class DBConstructor : public Constructor {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void NewDB() {
|
void NewDB() {
|
||||||
std::string name = test::TmpDir() + "/table_testdb";
|
std::string name = testing::TempDir() + "table_testdb";
|
||||||
|
|
||||||
Options options;
|
Options options;
|
||||||
options.comparator = comparator_;
|
options.comparator = comparator_;
|
||||||
@ -403,7 +403,7 @@ static const TestArgs kTestArgList[] = {
|
|||||||
};
|
};
|
||||||
static const int kNumTestArgs = sizeof(kTestArgList) / sizeof(kTestArgList[0]);
|
static const int kNumTestArgs = sizeof(kTestArgList) / sizeof(kTestArgList[0]);
|
||||||
|
|
||||||
class Harness {
|
class Harness : public testing::Test {
|
||||||
public:
|
public:
|
||||||
Harness() : constructor_(nullptr) {}
|
Harness() : constructor_(nullptr) {}
|
||||||
|
|
||||||
@ -609,7 +609,7 @@ class Harness {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Test empty table/block.
|
// Test empty table/block.
|
||||||
TEST(Harness, Empty) {
|
TEST_F(Harness, Empty) {
|
||||||
for (int i = 0; i < kNumTestArgs; i++) {
|
for (int i = 0; i < kNumTestArgs; i++) {
|
||||||
Init(kTestArgList[i]);
|
Init(kTestArgList[i]);
|
||||||
Random rnd(test::RandomSeed() + 1);
|
Random rnd(test::RandomSeed() + 1);
|
||||||
@ -620,7 +620,7 @@ TEST(Harness, Empty) {
|
|||||||
// Special test for a block with no restart entries. The C++ leveldb
|
// Special test for a block with no restart entries. The C++ leveldb
|
||||||
// code never generates such blocks, but the Java version of leveldb
|
// code never generates such blocks, but the Java version of leveldb
|
||||||
// seems to.
|
// seems to.
|
||||||
TEST(Harness, ZeroRestartPointsInBlock) {
|
TEST_F(Harness, ZeroRestartPointsInBlock) {
|
||||||
char data[sizeof(uint32_t)];
|
char data[sizeof(uint32_t)];
|
||||||
memset(data, 0, sizeof(data));
|
memset(data, 0, sizeof(data));
|
||||||
BlockContents contents;
|
BlockContents contents;
|
||||||
@ -639,7 +639,7 @@ TEST(Harness, ZeroRestartPointsInBlock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Test the empty key
|
// Test the empty key
|
||||||
TEST(Harness, SimpleEmptyKey) {
|
TEST_F(Harness, SimpleEmptyKey) {
|
||||||
for (int i = 0; i < kNumTestArgs; i++) {
|
for (int i = 0; i < kNumTestArgs; i++) {
|
||||||
Init(kTestArgList[i]);
|
Init(kTestArgList[i]);
|
||||||
Random rnd(test::RandomSeed() + 1);
|
Random rnd(test::RandomSeed() + 1);
|
||||||
@ -648,7 +648,7 @@ TEST(Harness, SimpleEmptyKey) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Harness, SimpleSingle) {
|
TEST_F(Harness, SimpleSingle) {
|
||||||
for (int i = 0; i < kNumTestArgs; i++) {
|
for (int i = 0; i < kNumTestArgs; i++) {
|
||||||
Init(kTestArgList[i]);
|
Init(kTestArgList[i]);
|
||||||
Random rnd(test::RandomSeed() + 2);
|
Random rnd(test::RandomSeed() + 2);
|
||||||
@ -657,7 +657,7 @@ TEST(Harness, SimpleSingle) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Harness, SimpleMulti) {
|
TEST_F(Harness, SimpleMulti) {
|
||||||
for (int i = 0; i < kNumTestArgs; i++) {
|
for (int i = 0; i < kNumTestArgs; i++) {
|
||||||
Init(kTestArgList[i]);
|
Init(kTestArgList[i]);
|
||||||
Random rnd(test::RandomSeed() + 3);
|
Random rnd(test::RandomSeed() + 3);
|
||||||
@ -668,7 +668,7 @@ TEST(Harness, SimpleMulti) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Harness, SimpleSpecialKey) {
|
TEST_F(Harness, SimpleSpecialKey) {
|
||||||
for (int i = 0; i < kNumTestArgs; i++) {
|
for (int i = 0; i < kNumTestArgs; i++) {
|
||||||
Init(kTestArgList[i]);
|
Init(kTestArgList[i]);
|
||||||
Random rnd(test::RandomSeed() + 4);
|
Random rnd(test::RandomSeed() + 4);
|
||||||
@ -677,7 +677,7 @@ TEST(Harness, SimpleSpecialKey) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Harness, Randomized) {
|
TEST_F(Harness, Randomized) {
|
||||||
for (int i = 0; i < kNumTestArgs; i++) {
|
for (int i = 0; i < kNumTestArgs; i++) {
|
||||||
Init(kTestArgList[i]);
|
Init(kTestArgList[i]);
|
||||||
Random rnd(test::RandomSeed() + 5);
|
Random rnd(test::RandomSeed() + 5);
|
||||||
@ -697,7 +697,7 @@ TEST(Harness, Randomized) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Harness, RandomizedLongDB) {
|
TEST_F(Harness, RandomizedLongDB) {
|
||||||
Random rnd(test::RandomSeed());
|
Random rnd(test::RandomSeed());
|
||||||
TestArgs args = {DB_TEST, false, 16};
|
TestArgs args = {DB_TEST, false, 16};
|
||||||
Init(args);
|
Init(args);
|
||||||
@ -721,8 +721,6 @@ TEST(Harness, RandomizedLongDB) {
|
|||||||
ASSERT_GT(files, 0);
|
ASSERT_GT(files, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemTableTest {};
|
|
||||||
|
|
||||||
TEST(MemTableTest, Simple) {
|
TEST(MemTableTest, Simple) {
|
||||||
InternalKeyComparator cmp(BytewiseComparator());
|
InternalKeyComparator cmp(BytewiseComparator());
|
||||||
MemTable* memtable = new MemTable(cmp);
|
MemTable* memtable = new MemTable(cmp);
|
||||||
@ -757,8 +755,6 @@ static bool Between(uint64_t val, uint64_t low, uint64_t high) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TableTest {};
|
|
||||||
|
|
||||||
TEST(TableTest, ApproximateOffsetOfPlain) {
|
TEST(TableTest, ApproximateOffsetOfPlain) {
|
||||||
TableConstructor c(BytewiseComparator());
|
TableConstructor c(BytewiseComparator());
|
||||||
c.Add("k01", "hello");
|
c.Add("k01", "hello");
|
||||||
@ -832,4 +828,7 @@ TEST(TableTest, ApproximateOffsetOfCompressed) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -4,13 +4,11 @@
|
|||||||
|
|
||||||
#include "util/arena.h"
|
#include "util/arena.h"
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "util/random.h"
|
#include "util/random.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
class ArenaTest {};
|
|
||||||
|
|
||||||
TEST(ArenaTest, Empty) { Arena arena; }
|
TEST(ArenaTest, Empty) { Arena arena; }
|
||||||
|
|
||||||
TEST(ArenaTest, Simple) {
|
TEST(ArenaTest, Simple) {
|
||||||
@ -62,4 +60,7 @@ TEST(ArenaTest, Simple) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -2,11 +2,10 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "leveldb/filter_policy.h"
|
#include "leveldb/filter_policy.h"
|
||||||
|
|
||||||
#include "util/coding.h"
|
#include "util/coding.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
#include "util/testutil.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
@ -18,7 +17,7 @@ static Slice Key(int i, char* buffer) {
|
|||||||
return Slice(buffer, sizeof(uint32_t));
|
return Slice(buffer, sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
class BloomTest {
|
class BloomTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
BloomTest() : policy_(NewBloomFilterPolicy(10)) {}
|
BloomTest() : policy_(NewBloomFilterPolicy(10)) {}
|
||||||
|
|
||||||
@ -80,12 +79,12 @@ class BloomTest {
|
|||||||
std::vector<std::string> keys_;
|
std::vector<std::string> keys_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(BloomTest, EmptyFilter) {
|
TEST_F(BloomTest, EmptyFilter) {
|
||||||
ASSERT_TRUE(!Matches("hello"));
|
ASSERT_TRUE(!Matches("hello"));
|
||||||
ASSERT_TRUE(!Matches("world"));
|
ASSERT_TRUE(!Matches("world"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BloomTest, Small) {
|
TEST_F(BloomTest, Small) {
|
||||||
Add("hello");
|
Add("hello");
|
||||||
Add("world");
|
Add("world");
|
||||||
ASSERT_TRUE(Matches("hello"));
|
ASSERT_TRUE(Matches("hello"));
|
||||||
@ -107,7 +106,7 @@ static int NextLength(int length) {
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BloomTest, VaryingLengths) {
|
TEST_F(BloomTest, VaryingLengths) {
|
||||||
char buffer[sizeof(int)];
|
char buffer[sizeof(int)];
|
||||||
|
|
||||||
// Count number of filters that significantly exceed the false positive rate
|
// Count number of filters that significantly exceed the false positive rate
|
||||||
@ -153,4 +152,7 @@ TEST(BloomTest, VaryingLengths) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -5,8 +5,9 @@
|
|||||||
#include "leveldb/cache.h"
|
#include "leveldb/cache.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "util/coding.h"
|
#include "util/coding.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ static int DecodeKey(const Slice& k) {
|
|||||||
static void* EncodeValue(uintptr_t v) { return reinterpret_cast<void*>(v); }
|
static void* EncodeValue(uintptr_t v) { return reinterpret_cast<void*>(v); }
|
||||||
static int DecodeValue(void* v) { return reinterpret_cast<uintptr_t>(v); }
|
static int DecodeValue(void* v) { return reinterpret_cast<uintptr_t>(v); }
|
||||||
|
|
||||||
class CacheTest {
|
class CacheTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
static void Deleter(const Slice& key, void* v) {
|
static void Deleter(const Slice& key, void* v) {
|
||||||
current_->deleted_keys_.push_back(DecodeKey(key));
|
current_->deleted_keys_.push_back(DecodeKey(key));
|
||||||
@ -59,12 +60,11 @@ class CacheTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Erase(int key) { cache_->Erase(EncodeKey(key)); }
|
void Erase(int key) { cache_->Erase(EncodeKey(key)); }
|
||||||
|
|
||||||
static CacheTest* current_;
|
static CacheTest* current_;
|
||||||
};
|
};
|
||||||
CacheTest* CacheTest::current_;
|
CacheTest* CacheTest::current_;
|
||||||
|
|
||||||
TEST(CacheTest, HitAndMiss) {
|
TEST_F(CacheTest, HitAndMiss) {
|
||||||
ASSERT_EQ(-1, Lookup(100));
|
ASSERT_EQ(-1, Lookup(100));
|
||||||
|
|
||||||
Insert(100, 101);
|
Insert(100, 101);
|
||||||
@ -87,7 +87,7 @@ TEST(CacheTest, HitAndMiss) {
|
|||||||
ASSERT_EQ(101, deleted_values_[0]);
|
ASSERT_EQ(101, deleted_values_[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CacheTest, Erase) {
|
TEST_F(CacheTest, Erase) {
|
||||||
Erase(200);
|
Erase(200);
|
||||||
ASSERT_EQ(0, deleted_keys_.size());
|
ASSERT_EQ(0, deleted_keys_.size());
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ TEST(CacheTest, Erase) {
|
|||||||
ASSERT_EQ(1, deleted_keys_.size());
|
ASSERT_EQ(1, deleted_keys_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CacheTest, EntriesArePinned) {
|
TEST_F(CacheTest, EntriesArePinned) {
|
||||||
Insert(100, 101);
|
Insert(100, 101);
|
||||||
Cache::Handle* h1 = cache_->Lookup(EncodeKey(100));
|
Cache::Handle* h1 = cache_->Lookup(EncodeKey(100));
|
||||||
ASSERT_EQ(101, DecodeValue(cache_->Value(h1)));
|
ASSERT_EQ(101, DecodeValue(cache_->Value(h1)));
|
||||||
@ -131,7 +131,7 @@ TEST(CacheTest, EntriesArePinned) {
|
|||||||
ASSERT_EQ(102, deleted_values_[1]);
|
ASSERT_EQ(102, deleted_values_[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CacheTest, EvictionPolicy) {
|
TEST_F(CacheTest, EvictionPolicy) {
|
||||||
Insert(100, 101);
|
Insert(100, 101);
|
||||||
Insert(200, 201);
|
Insert(200, 201);
|
||||||
Insert(300, 301);
|
Insert(300, 301);
|
||||||
@ -150,7 +150,7 @@ TEST(CacheTest, EvictionPolicy) {
|
|||||||
cache_->Release(h);
|
cache_->Release(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CacheTest, UseExceedsCacheSize) {
|
TEST_F(CacheTest, UseExceedsCacheSize) {
|
||||||
// Overfill the cache, keeping handles on all inserted entries.
|
// Overfill the cache, keeping handles on all inserted entries.
|
||||||
std::vector<Cache::Handle*> h;
|
std::vector<Cache::Handle*> h;
|
||||||
for (int i = 0; i < kCacheSize + 100; i++) {
|
for (int i = 0; i < kCacheSize + 100; i++) {
|
||||||
@ -167,7 +167,7 @@ TEST(CacheTest, UseExceedsCacheSize) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CacheTest, HeavyEntries) {
|
TEST_F(CacheTest, HeavyEntries) {
|
||||||
// Add a bunch of light and heavy entries and then count the combined
|
// Add a bunch of light and heavy entries and then count the combined
|
||||||
// size of items still in the cache, which must be approximately the
|
// size of items still in the cache, which must be approximately the
|
||||||
// same as the total capacity.
|
// same as the total capacity.
|
||||||
@ -194,13 +194,13 @@ TEST(CacheTest, HeavyEntries) {
|
|||||||
ASSERT_LE(cached_weight, kCacheSize + kCacheSize / 10);
|
ASSERT_LE(cached_weight, kCacheSize + kCacheSize / 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CacheTest, NewId) {
|
TEST_F(CacheTest, NewId) {
|
||||||
uint64_t a = cache_->NewId();
|
uint64_t a = cache_->NewId();
|
||||||
uint64_t b = cache_->NewId();
|
uint64_t b = cache_->NewId();
|
||||||
ASSERT_NE(a, b);
|
ASSERT_NE(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CacheTest, Prune) {
|
TEST_F(CacheTest, Prune) {
|
||||||
Insert(1, 100);
|
Insert(1, 100);
|
||||||
Insert(2, 200);
|
Insert(2, 200);
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ TEST(CacheTest, Prune) {
|
|||||||
ASSERT_EQ(-1, Lookup(2));
|
ASSERT_EQ(-1, Lookup(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CacheTest, ZeroSizeCache) {
|
TEST_F(CacheTest, ZeroSizeCache) {
|
||||||
delete cache_;
|
delete cache_;
|
||||||
cache_ = NewLRUCache(0);
|
cache_ = NewLRUCache(0);
|
||||||
|
|
||||||
@ -223,4 +223,7 @@ TEST(CacheTest, ZeroSizeCache) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -2,15 +2,14 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#include "util/coding.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "util/coding.h"
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
class Coding {};
|
|
||||||
|
|
||||||
TEST(Coding, Fixed32) {
|
TEST(Coding, Fixed32) {
|
||||||
std::string s;
|
std::string s;
|
||||||
for (uint32_t v = 0; v < 100000; v++) {
|
for (uint32_t v = 0; v < 100000; v++) {
|
||||||
@ -193,4 +192,7 @@ TEST(Coding, Strings) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -3,13 +3,12 @@
|
|||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
#include "util/crc32c.h"
|
#include "util/crc32c.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
namespace crc32c {
|
namespace crc32c {
|
||||||
|
|
||||||
class CRC {};
|
|
||||||
|
|
||||||
TEST(CRC, StandardResults) {
|
TEST(CRC, StandardResults) {
|
||||||
// From rfc3720 section B.4.
|
// From rfc3720 section B.4.
|
||||||
char buf[32];
|
char buf[32];
|
||||||
@ -56,4 +55,7 @@ TEST(CRC, Mask) {
|
|||||||
} // namespace crc32c
|
} // namespace crc32c
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -13,10 +13,11 @@
|
|||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
#include "port/port.h"
|
#include "port/port.h"
|
||||||
#include "util/env_posix_test_helper.h"
|
#include "util/env_posix_test_helper.h"
|
||||||
#include "util/testharness.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
#if HAVE_O_CLOEXEC
|
#if HAVE_O_CLOEXEC
|
||||||
|
|
||||||
@ -168,7 +169,7 @@ namespace leveldb {
|
|||||||
static const int kReadOnlyFileLimit = 4;
|
static const int kReadOnlyFileLimit = 4;
|
||||||
static const int kMMapLimit = 4;
|
static const int kMMapLimit = 4;
|
||||||
|
|
||||||
class EnvPosixTest {
|
class EnvPosixTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
static void SetFileLimits(int read_only_file_limit, int mmap_limit) {
|
static void SetFileLimits(int read_only_file_limit, int mmap_limit) {
|
||||||
EnvPosixTestHelper::SetReadOnlyFDLimit(read_only_file_limit);
|
EnvPosixTestHelper::SetReadOnlyFDLimit(read_only_file_limit);
|
||||||
@ -180,10 +181,10 @@ class EnvPosixTest {
|
|||||||
Env* env_;
|
Env* env_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(EnvPosixTest, TestOpenOnRead) {
|
TEST_F(EnvPosixTest, TestOpenOnRead) {
|
||||||
// Write some test data to a single file that will be opened |n| times.
|
// Write some test data to a single file that will be opened |n| times.
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string test_file = test_dir + "/open_on_read.txt";
|
std::string test_file = test_dir + "/open_on_read.txt";
|
||||||
|
|
||||||
FILE* f = fopen(test_file.c_str(), "we");
|
FILE* f = fopen(test_file.c_str(), "we");
|
||||||
@ -197,133 +198,133 @@ TEST(EnvPosixTest, TestOpenOnRead) {
|
|||||||
const int kNumFiles = kReadOnlyFileLimit + kMMapLimit + 5;
|
const int kNumFiles = kReadOnlyFileLimit + kMMapLimit + 5;
|
||||||
leveldb::RandomAccessFile* files[kNumFiles] = {0};
|
leveldb::RandomAccessFile* files[kNumFiles] = {0};
|
||||||
for (int i = 0; i < kNumFiles; i++) {
|
for (int i = 0; i < kNumFiles; i++) {
|
||||||
ASSERT_OK(env_->NewRandomAccessFile(test_file, &files[i]));
|
ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(test_file, &files[i]));
|
||||||
}
|
}
|
||||||
char scratch;
|
char scratch;
|
||||||
Slice read_result;
|
Slice read_result;
|
||||||
for (int i = 0; i < kNumFiles; i++) {
|
for (int i = 0; i < kNumFiles; i++) {
|
||||||
ASSERT_OK(files[i]->Read(i, 1, &read_result, &scratch));
|
ASSERT_LEVELDB_OK(files[i]->Read(i, 1, &read_result, &scratch));
|
||||||
ASSERT_EQ(kFileData[i], read_result[0]);
|
ASSERT_EQ(kFileData[i], read_result[0]);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < kNumFiles; i++) {
|
for (int i = 0; i < kNumFiles; i++) {
|
||||||
delete files[i];
|
delete files[i];
|
||||||
}
|
}
|
||||||
ASSERT_OK(env_->DeleteFile(test_file));
|
ASSERT_LEVELDB_OK(env_->DeleteFile(test_file));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_O_CLOEXEC
|
#if HAVE_O_CLOEXEC
|
||||||
|
|
||||||
TEST(EnvPosixTest, TestCloseOnExecSequentialFile) {
|
TEST_F(EnvPosixTest, TestCloseOnExecSequentialFile) {
|
||||||
std::unordered_set<int> open_fds;
|
std::unordered_set<int> open_fds;
|
||||||
GetOpenFileDescriptors(&open_fds);
|
GetOpenFileDescriptors(&open_fds);
|
||||||
|
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string file_path = test_dir + "/close_on_exec_sequential.txt";
|
std::string file_path = test_dir + "/close_on_exec_sequential.txt";
|
||||||
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
|
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
|
||||||
|
|
||||||
leveldb::SequentialFile* file = nullptr;
|
leveldb::SequentialFile* file = nullptr;
|
||||||
ASSERT_OK(env_->NewSequentialFile(file_path, &file));
|
ASSERT_LEVELDB_OK(env_->NewSequentialFile(file_path, &file));
|
||||||
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
||||||
delete file;
|
delete file;
|
||||||
|
|
||||||
ASSERT_OK(env_->DeleteFile(file_path));
|
ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvPosixTest, TestCloseOnExecRandomAccessFile) {
|
TEST_F(EnvPosixTest, TestCloseOnExecRandomAccessFile) {
|
||||||
std::unordered_set<int> open_fds;
|
std::unordered_set<int> open_fds;
|
||||||
GetOpenFileDescriptors(&open_fds);
|
GetOpenFileDescriptors(&open_fds);
|
||||||
|
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string file_path = test_dir + "/close_on_exec_random_access.txt";
|
std::string file_path = test_dir + "/close_on_exec_random_access.txt";
|
||||||
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
|
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
|
||||||
|
|
||||||
// Exhaust the RandomAccessFile mmap limit. This way, the test
|
// Exhaust the RandomAccessFile mmap limit. This way, the test
|
||||||
// RandomAccessFile instance below is backed by a file descriptor, not by an
|
// RandomAccessFile instance below is backed by a file descriptor, not by an
|
||||||
// mmap region.
|
// mmap region.
|
||||||
leveldb::RandomAccessFile* mmapped_files[kReadOnlyFileLimit] = {nullptr};
|
leveldb::RandomAccessFile* mmapped_files[kReadOnlyFileLimit] = {nullptr};
|
||||||
for (int i = 0; i < kReadOnlyFileLimit; i++) {
|
for (int i = 0; i < kReadOnlyFileLimit; i++) {
|
||||||
ASSERT_OK(env_->NewRandomAccessFile(file_path, &mmapped_files[i]));
|
ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(file_path, &mmapped_files[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
leveldb::RandomAccessFile* file = nullptr;
|
leveldb::RandomAccessFile* file = nullptr;
|
||||||
ASSERT_OK(env_->NewRandomAccessFile(file_path, &file));
|
ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(file_path, &file));
|
||||||
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
||||||
delete file;
|
delete file;
|
||||||
|
|
||||||
for (int i = 0; i < kReadOnlyFileLimit; i++) {
|
for (int i = 0; i < kReadOnlyFileLimit; i++) {
|
||||||
delete mmapped_files[i];
|
delete mmapped_files[i];
|
||||||
}
|
}
|
||||||
ASSERT_OK(env_->DeleteFile(file_path));
|
ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvPosixTest, TestCloseOnExecWritableFile) {
|
TEST_F(EnvPosixTest, TestCloseOnExecWritableFile) {
|
||||||
std::unordered_set<int> open_fds;
|
std::unordered_set<int> open_fds;
|
||||||
GetOpenFileDescriptors(&open_fds);
|
GetOpenFileDescriptors(&open_fds);
|
||||||
|
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string file_path = test_dir + "/close_on_exec_writable.txt";
|
std::string file_path = test_dir + "/close_on_exec_writable.txt";
|
||||||
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
|
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
|
||||||
|
|
||||||
leveldb::WritableFile* file = nullptr;
|
leveldb::WritableFile* file = nullptr;
|
||||||
ASSERT_OK(env_->NewWritableFile(file_path, &file));
|
ASSERT_LEVELDB_OK(env_->NewWritableFile(file_path, &file));
|
||||||
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
||||||
delete file;
|
delete file;
|
||||||
|
|
||||||
ASSERT_OK(env_->DeleteFile(file_path));
|
ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvPosixTest, TestCloseOnExecAppendableFile) {
|
TEST_F(EnvPosixTest, TestCloseOnExecAppendableFile) {
|
||||||
std::unordered_set<int> open_fds;
|
std::unordered_set<int> open_fds;
|
||||||
GetOpenFileDescriptors(&open_fds);
|
GetOpenFileDescriptors(&open_fds);
|
||||||
|
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string file_path = test_dir + "/close_on_exec_appendable.txt";
|
std::string file_path = test_dir + "/close_on_exec_appendable.txt";
|
||||||
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
|
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
|
||||||
|
|
||||||
leveldb::WritableFile* file = nullptr;
|
leveldb::WritableFile* file = nullptr;
|
||||||
ASSERT_OK(env_->NewAppendableFile(file_path, &file));
|
ASSERT_LEVELDB_OK(env_->NewAppendableFile(file_path, &file));
|
||||||
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
||||||
delete file;
|
delete file;
|
||||||
|
|
||||||
ASSERT_OK(env_->DeleteFile(file_path));
|
ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvPosixTest, TestCloseOnExecLockFile) {
|
TEST_F(EnvPosixTest, TestCloseOnExecLockFile) {
|
||||||
std::unordered_set<int> open_fds;
|
std::unordered_set<int> open_fds;
|
||||||
GetOpenFileDescriptors(&open_fds);
|
GetOpenFileDescriptors(&open_fds);
|
||||||
|
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string file_path = test_dir + "/close_on_exec_lock.txt";
|
std::string file_path = test_dir + "/close_on_exec_lock.txt";
|
||||||
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
|
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
|
||||||
|
|
||||||
leveldb::FileLock* lock = nullptr;
|
leveldb::FileLock* lock = nullptr;
|
||||||
ASSERT_OK(env_->LockFile(file_path, &lock));
|
ASSERT_LEVELDB_OK(env_->LockFile(file_path, &lock));
|
||||||
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
||||||
ASSERT_OK(env_->UnlockFile(lock));
|
ASSERT_LEVELDB_OK(env_->UnlockFile(lock));
|
||||||
|
|
||||||
ASSERT_OK(env_->DeleteFile(file_path));
|
ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvPosixTest, TestCloseOnExecLogger) {
|
TEST_F(EnvPosixTest, TestCloseOnExecLogger) {
|
||||||
std::unordered_set<int> open_fds;
|
std::unordered_set<int> open_fds;
|
||||||
GetOpenFileDescriptors(&open_fds);
|
GetOpenFileDescriptors(&open_fds);
|
||||||
|
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string file_path = test_dir + "/close_on_exec_logger.txt";
|
std::string file_path = test_dir + "/close_on_exec_logger.txt";
|
||||||
ASSERT_OK(WriteStringToFile(env_, "0123456789", file_path));
|
ASSERT_LEVELDB_OK(WriteStringToFile(env_, "0123456789", file_path));
|
||||||
|
|
||||||
leveldb::Logger* file = nullptr;
|
leveldb::Logger* file = nullptr;
|
||||||
ASSERT_OK(env_->NewLogger(file_path, &file));
|
ASSERT_LEVELDB_OK(env_->NewLogger(file_path, &file));
|
||||||
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
CheckCloseOnExecDoesNotLeakFDs(open_fds);
|
||||||
delete file;
|
delete file;
|
||||||
|
|
||||||
ASSERT_OK(env_->DeleteFile(file_path));
|
ASSERT_LEVELDB_OK(env_->DeleteFile(file_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAVE_O_CLOEXEC
|
#endif // HAVE_O_CLOEXEC
|
||||||
@ -346,5 +347,7 @@ int main(int argc, char** argv) {
|
|||||||
// All tests currently run with the same read-only file limits.
|
// All tests currently run with the same read-only file limits.
|
||||||
leveldb::EnvPosixTest::SetFileLimits(leveldb::kReadOnlyFileLimit,
|
leveldb::EnvPosixTest::SetFileLimits(leveldb::kReadOnlyFileLimit,
|
||||||
leveldb::kMMapLimit);
|
leveldb::kMMapLimit);
|
||||||
return leveldb::test::RunAllTests();
|
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
|
@ -6,32 +6,32 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "port/port.h"
|
#include "port/port.h"
|
||||||
#include "port/thread_annotations.h"
|
#include "port/thread_annotations.h"
|
||||||
#include "util/mutexlock.h"
|
#include "util/mutexlock.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
#include "util/testutil.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
static const int kDelayMicros = 100000;
|
static const int kDelayMicros = 100000;
|
||||||
|
|
||||||
class EnvTest {
|
class EnvTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
EnvTest() : env_(Env::Default()) {}
|
EnvTest() : env_(Env::Default()) {}
|
||||||
|
|
||||||
Env* env_;
|
Env* env_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(EnvTest, ReadWrite) {
|
TEST_F(EnvTest, ReadWrite) {
|
||||||
Random rnd(test::RandomSeed());
|
Random rnd(test::RandomSeed());
|
||||||
|
|
||||||
// Get file to use for testing.
|
// Get file to use for testing.
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string test_file_name = test_dir + "/open_on_read.txt";
|
std::string test_file_name = test_dir + "/open_on_read.txt";
|
||||||
WritableFile* writable_file;
|
WritableFile* writable_file;
|
||||||
ASSERT_OK(env_->NewWritableFile(test_file_name, &writable_file));
|
ASSERT_LEVELDB_OK(env_->NewWritableFile(test_file_name, &writable_file));
|
||||||
|
|
||||||
// Fill a file with data generated via a sequence of randomly sized writes.
|
// Fill a file with data generated via a sequence of randomly sized writes.
|
||||||
static const size_t kDataSize = 10 * 1048576;
|
static const size_t kDataSize = 10 * 1048576;
|
||||||
@ -40,26 +40,26 @@ TEST(EnvTest, ReadWrite) {
|
|||||||
int len = rnd.Skewed(18); // Up to 2^18 - 1, but typically much smaller
|
int len = rnd.Skewed(18); // Up to 2^18 - 1, but typically much smaller
|
||||||
std::string r;
|
std::string r;
|
||||||
test::RandomString(&rnd, len, &r);
|
test::RandomString(&rnd, len, &r);
|
||||||
ASSERT_OK(writable_file->Append(r));
|
ASSERT_LEVELDB_OK(writable_file->Append(r));
|
||||||
data += r;
|
data += r;
|
||||||
if (rnd.OneIn(10)) {
|
if (rnd.OneIn(10)) {
|
||||||
ASSERT_OK(writable_file->Flush());
|
ASSERT_LEVELDB_OK(writable_file->Flush());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT_OK(writable_file->Sync());
|
ASSERT_LEVELDB_OK(writable_file->Sync());
|
||||||
ASSERT_OK(writable_file->Close());
|
ASSERT_LEVELDB_OK(writable_file->Close());
|
||||||
delete writable_file;
|
delete writable_file;
|
||||||
|
|
||||||
// Read all data using a sequence of randomly sized reads.
|
// Read all data using a sequence of randomly sized reads.
|
||||||
SequentialFile* sequential_file;
|
SequentialFile* sequential_file;
|
||||||
ASSERT_OK(env_->NewSequentialFile(test_file_name, &sequential_file));
|
ASSERT_LEVELDB_OK(env_->NewSequentialFile(test_file_name, &sequential_file));
|
||||||
std::string read_result;
|
std::string read_result;
|
||||||
std::string scratch;
|
std::string scratch;
|
||||||
while (read_result.size() < data.size()) {
|
while (read_result.size() < data.size()) {
|
||||||
int len = std::min<int>(rnd.Skewed(18), data.size() - read_result.size());
|
int len = std::min<int>(rnd.Skewed(18), data.size() - read_result.size());
|
||||||
scratch.resize(std::max(len, 1)); // at least 1 so &scratch[0] is legal
|
scratch.resize(std::max(len, 1)); // at least 1 so &scratch[0] is legal
|
||||||
Slice read;
|
Slice read;
|
||||||
ASSERT_OK(sequential_file->Read(len, &read, &scratch[0]));
|
ASSERT_LEVELDB_OK(sequential_file->Read(len, &read, &scratch[0]));
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
ASSERT_GT(read.size(), 0);
|
ASSERT_GT(read.size(), 0);
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ TEST(EnvTest, ReadWrite) {
|
|||||||
delete sequential_file;
|
delete sequential_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvTest, RunImmediately) {
|
TEST_F(EnvTest, RunImmediately) {
|
||||||
struct RunState {
|
struct RunState {
|
||||||
port::Mutex mu;
|
port::Mutex mu;
|
||||||
port::CondVar cvar{&mu};
|
port::CondVar cvar{&mu};
|
||||||
@ -94,7 +94,7 @@ TEST(EnvTest, RunImmediately) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvTest, RunMany) {
|
TEST_F(EnvTest, RunMany) {
|
||||||
struct RunState {
|
struct RunState {
|
||||||
port::Mutex mu;
|
port::Mutex mu;
|
||||||
port::CondVar cvar{&mu};
|
port::CondVar cvar{&mu};
|
||||||
@ -153,7 +153,7 @@ static void ThreadBody(void* arg) {
|
|||||||
s->mu.Unlock();
|
s->mu.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvTest, StartThread) {
|
TEST_F(EnvTest, StartThread) {
|
||||||
State state(0, 3);
|
State state(0, 3);
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
env_->StartThread(&ThreadBody, &state);
|
env_->StartThread(&ThreadBody, &state);
|
||||||
@ -166,10 +166,10 @@ TEST(EnvTest, StartThread) {
|
|||||||
ASSERT_EQ(state.val, 3);
|
ASSERT_EQ(state.val, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvTest, TestOpenNonExistentFile) {
|
TEST_F(EnvTest, TestOpenNonExistentFile) {
|
||||||
// Write some test data to a single file that will be opened |n| times.
|
// Write some test data to a single file that will be opened |n| times.
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
|
|
||||||
std::string non_existent_file = test_dir + "/non_existent_file";
|
std::string non_existent_file = test_dir + "/non_existent_file";
|
||||||
ASSERT_TRUE(!env_->FileExists(non_existent_file));
|
ASSERT_TRUE(!env_->FileExists(non_existent_file));
|
||||||
@ -184,54 +184,57 @@ TEST(EnvTest, TestOpenNonExistentFile) {
|
|||||||
ASSERT_TRUE(status.IsNotFound());
|
ASSERT_TRUE(status.IsNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvTest, ReopenWritableFile) {
|
TEST_F(EnvTest, ReopenWritableFile) {
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string test_file_name = test_dir + "/reopen_writable_file.txt";
|
std::string test_file_name = test_dir + "/reopen_writable_file.txt";
|
||||||
env_->DeleteFile(test_file_name);
|
env_->DeleteFile(test_file_name);
|
||||||
|
|
||||||
WritableFile* writable_file;
|
WritableFile* writable_file;
|
||||||
ASSERT_OK(env_->NewWritableFile(test_file_name, &writable_file));
|
ASSERT_LEVELDB_OK(env_->NewWritableFile(test_file_name, &writable_file));
|
||||||
std::string data("hello world!");
|
std::string data("hello world!");
|
||||||
ASSERT_OK(writable_file->Append(data));
|
ASSERT_LEVELDB_OK(writable_file->Append(data));
|
||||||
ASSERT_OK(writable_file->Close());
|
ASSERT_LEVELDB_OK(writable_file->Close());
|
||||||
delete writable_file;
|
delete writable_file;
|
||||||
|
|
||||||
ASSERT_OK(env_->NewWritableFile(test_file_name, &writable_file));
|
ASSERT_LEVELDB_OK(env_->NewWritableFile(test_file_name, &writable_file));
|
||||||
data = "42";
|
data = "42";
|
||||||
ASSERT_OK(writable_file->Append(data));
|
ASSERT_LEVELDB_OK(writable_file->Append(data));
|
||||||
ASSERT_OK(writable_file->Close());
|
ASSERT_LEVELDB_OK(writable_file->Close());
|
||||||
delete writable_file;
|
delete writable_file;
|
||||||
|
|
||||||
ASSERT_OK(ReadFileToString(env_, test_file_name, &data));
|
ASSERT_LEVELDB_OK(ReadFileToString(env_, test_file_name, &data));
|
||||||
ASSERT_EQ(std::string("42"), data);
|
ASSERT_EQ(std::string("42"), data);
|
||||||
env_->DeleteFile(test_file_name);
|
env_->DeleteFile(test_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnvTest, ReopenAppendableFile) {
|
TEST_F(EnvTest, ReopenAppendableFile) {
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string test_file_name = test_dir + "/reopen_appendable_file.txt";
|
std::string test_file_name = test_dir + "/reopen_appendable_file.txt";
|
||||||
env_->DeleteFile(test_file_name);
|
env_->DeleteFile(test_file_name);
|
||||||
|
|
||||||
WritableFile* appendable_file;
|
WritableFile* appendable_file;
|
||||||
ASSERT_OK(env_->NewAppendableFile(test_file_name, &appendable_file));
|
ASSERT_LEVELDB_OK(env_->NewAppendableFile(test_file_name, &appendable_file));
|
||||||
std::string data("hello world!");
|
std::string data("hello world!");
|
||||||
ASSERT_OK(appendable_file->Append(data));
|
ASSERT_LEVELDB_OK(appendable_file->Append(data));
|
||||||
ASSERT_OK(appendable_file->Close());
|
ASSERT_LEVELDB_OK(appendable_file->Close());
|
||||||
delete appendable_file;
|
delete appendable_file;
|
||||||
|
|
||||||
ASSERT_OK(env_->NewAppendableFile(test_file_name, &appendable_file));
|
ASSERT_LEVELDB_OK(env_->NewAppendableFile(test_file_name, &appendable_file));
|
||||||
data = "42";
|
data = "42";
|
||||||
ASSERT_OK(appendable_file->Append(data));
|
ASSERT_LEVELDB_OK(appendable_file->Append(data));
|
||||||
ASSERT_OK(appendable_file->Close());
|
ASSERT_LEVELDB_OK(appendable_file->Close());
|
||||||
delete appendable_file;
|
delete appendable_file;
|
||||||
|
|
||||||
ASSERT_OK(ReadFileToString(env_, test_file_name, &data));
|
ASSERT_LEVELDB_OK(ReadFileToString(env_, test_file_name, &data));
|
||||||
ASSERT_EQ(std::string("hello world!42"), data);
|
ASSERT_EQ(std::string("hello world!42"), data);
|
||||||
env_->DeleteFile(test_file_name);
|
env_->DeleteFile(test_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -2,17 +2,17 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
|
|
||||||
#include "port/port.h"
|
#include "port/port.h"
|
||||||
#include "util/env_windows_test_helper.h"
|
#include "util/env_windows_test_helper.h"
|
||||||
#include "util/testharness.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
static const int kMMapLimit = 4;
|
static const int kMMapLimit = 4;
|
||||||
|
|
||||||
class EnvWindowsTest {
|
class EnvWindowsTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
static void SetFileLimits(int mmap_limit) {
|
static void SetFileLimits(int mmap_limit) {
|
||||||
EnvWindowsTestHelper::SetReadOnlyMMapLimit(mmap_limit);
|
EnvWindowsTestHelper::SetReadOnlyMMapLimit(mmap_limit);
|
||||||
@ -23,10 +23,10 @@ class EnvWindowsTest {
|
|||||||
Env* env_;
|
Env* env_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(EnvWindowsTest, TestOpenOnRead) {
|
TEST_F(EnvWindowsTest, TestOpenOnRead) {
|
||||||
// Write some test data to a single file that will be opened |n| times.
|
// Write some test data to a single file that will be opened |n| times.
|
||||||
std::string test_dir;
|
std::string test_dir;
|
||||||
ASSERT_OK(env_->GetTestDirectory(&test_dir));
|
ASSERT_LEVELDB_OK(env_->GetTestDirectory(&test_dir));
|
||||||
std::string test_file = test_dir + "/open_on_read.txt";
|
std::string test_file = test_dir + "/open_on_read.txt";
|
||||||
|
|
||||||
FILE* f = fopen(test_file.c_str(), "w");
|
FILE* f = fopen(test_file.c_str(), "w");
|
||||||
@ -41,18 +41,18 @@ TEST(EnvWindowsTest, TestOpenOnRead) {
|
|||||||
const int kNumFiles = kMMapLimit + 5;
|
const int kNumFiles = kMMapLimit + 5;
|
||||||
leveldb::RandomAccessFile* files[kNumFiles] = {0};
|
leveldb::RandomAccessFile* files[kNumFiles] = {0};
|
||||||
for (int i = 0; i < kNumFiles; i++) {
|
for (int i = 0; i < kNumFiles; i++) {
|
||||||
ASSERT_OK(env_->NewRandomAccessFile(test_file, &files[i]));
|
ASSERT_LEVELDB_OK(env_->NewRandomAccessFile(test_file, &files[i]));
|
||||||
}
|
}
|
||||||
char scratch;
|
char scratch;
|
||||||
Slice read_result;
|
Slice read_result;
|
||||||
for (int i = 0; i < kNumFiles; i++) {
|
for (int i = 0; i < kNumFiles; i++) {
|
||||||
ASSERT_OK(files[i]->Read(i, 1, &read_result, &scratch));
|
ASSERT_LEVELDB_OK(files[i]->Read(i, 1, &read_result, &scratch));
|
||||||
ASSERT_EQ(kFileData[i], read_result[0]);
|
ASSERT_EQ(kFileData[i], read_result[0]);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < kNumFiles; i++) {
|
for (int i = 0; i < kNumFiles; i++) {
|
||||||
delete files[i];
|
delete files[i];
|
||||||
}
|
}
|
||||||
ASSERT_OK(env_->DeleteFile(test_file));
|
ASSERT_LEVELDB_OK(env_->DeleteFile(test_file));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
@ -60,5 +60,6 @@ TEST(EnvWindowsTest, TestOpenOnRead) {
|
|||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
// All tests currently run with the same read-only file limits.
|
// All tests currently run with the same read-only file limits.
|
||||||
leveldb::EnvWindowsTest::SetFileLimits(leveldb::kMMapLimit);
|
leveldb::EnvWindowsTest::SetFileLimits(leveldb::kMMapLimit);
|
||||||
return leveldb::test::RunAllTests();
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,11 @@
|
|||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
#include "util/hash.h"
|
#include "util/hash.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
class HASH {};
|
|
||||||
|
|
||||||
TEST(HASH, SignedUnsignedIssue) {
|
TEST(HASH, SignedUnsignedIssue) {
|
||||||
const uint8_t data1[1] = {0x62};
|
const uint8_t data1[1] = {0x62};
|
||||||
const uint8_t data2[2] = {0xc3, 0x97};
|
const uint8_t data2[2] = {0xc3, 0x97};
|
||||||
@ -41,4 +40,7 @@ TEST(HASH, SignedUnsignedIssue) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -2,17 +2,16 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#include "util/logging.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "leveldb/slice.h"
|
#include "leveldb/slice.h"
|
||||||
#include "util/logging.h"
|
|
||||||
#include "util/testharness.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
class Logging {};
|
|
||||||
|
|
||||||
TEST(Logging, NumberToString) {
|
TEST(Logging, NumberToString) {
|
||||||
ASSERT_EQ("0", NumberToString(0));
|
ASSERT_EQ("0", NumberToString(0));
|
||||||
ASSERT_EQ("1", NumberToString(1));
|
ASSERT_EQ("1", NumberToString(1));
|
||||||
@ -140,4 +139,7 @@ TEST(Logging, ConsumeDecimalNumberNoDigits) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#include "util/no_destructor.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "util/no_destructor.h"
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "util/testharness.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
@ -28,8 +29,6 @@ constexpr const uint64_t kGoldenB = 0xaabbccddeeffaabb;
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class NoDestructorTest {};
|
|
||||||
|
|
||||||
TEST(NoDestructorTest, StackInstance) {
|
TEST(NoDestructorTest, StackInstance) {
|
||||||
NoDestructor<DoNotDestruct> instance(kGoldenA, kGoldenB);
|
NoDestructor<DoNotDestruct> instance(kGoldenA, kGoldenB);
|
||||||
ASSERT_EQ(kGoldenA, instance.get()->a);
|
ASSERT_EQ(kGoldenA, instance.get()->a);
|
||||||
@ -44,4 +43,7 @@ TEST(NoDestructorTest, StaticInstance) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -2,11 +2,12 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#include "leveldb/status.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "leveldb/slice.h"
|
#include "leveldb/slice.h"
|
||||||
#include "leveldb/status.h"
|
|
||||||
#include "util/testharness.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
@ -37,4 +38,7 @@ TEST(Status, MoveConstructor) {
|
|||||||
|
|
||||||
} // namespace leveldb
|
} // namespace leveldb
|
||||||
|
|
||||||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
|
@ -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
|
|
@ -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_
|
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "util/testutil.h"
|
#include "util/testutil.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "util/random.h"
|
#include "util/random.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#ifndef STORAGE_LEVELDB_UTIL_TESTUTIL_H_
|
#ifndef STORAGE_LEVELDB_UTIL_TESTUTIL_H_
|
||||||
#define STORAGE_LEVELDB_UTIL_TESTUTIL_H_
|
#define STORAGE_LEVELDB_UTIL_TESTUTIL_H_
|
||||||
|
|
||||||
|
#include "third_party/googletest/googlemock/include/gmock/gmock.h"
|
||||||
|
#include "third_party/googletest/googletest/include/gtest/gtest.h"
|
||||||
#include "helpers/memenv/memenv.h"
|
#include "helpers/memenv/memenv.h"
|
||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
#include "leveldb/slice.h"
|
#include "leveldb/slice.h"
|
||||||
@ -13,6 +15,20 @@
|
|||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
|
MATCHER(IsOK, "") { return arg.ok(); }
|
||||||
|
|
||||||
|
// Macros for testing the results of functions that return leveldb::Status or
|
||||||
|
// util::StatusOr<T> (for any type T).
|
||||||
|
#define EXPECT_LEVELDB_OK(expression) \
|
||||||
|
EXPECT_THAT(expression, leveldb::test::IsOK())
|
||||||
|
#define ASSERT_LEVELDB_OK(expression) \
|
||||||
|
ASSERT_THAT(expression, leveldb::test::IsOK())
|
||||||
|
|
||||||
|
// Returns the random seed used at the start of the current test run.
|
||||||
|
inline int RandomSeed() {
|
||||||
|
return testing::UnitTest::GetInstance()->random_seed();
|
||||||
|
}
|
||||||
|
|
||||||
// Store in *dst a random string of length "len" and return a Slice that
|
// Store in *dst a random string of length "len" and return a Slice that
|
||||||
// references the generated data.
|
// references the generated data.
|
||||||
Slice RandomString(Random* rnd, int len, std::string* dst);
|
Slice RandomString(Random* rnd, int len, std::string* dst);
|
||||||
|
Loading…
Reference in New Issue
Block a user