Migrate ErrorEnv from EnvWrapper to FileSystemWrapper (#11124)

Summary:
Migrate ErrorEnv from EnvWrapper to FileSystemWrapper so we can eventually deprecate the storage methods in Env.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/11124

Reviewed By: akankshamahajan15

Differential Revision: D42727791

Pulled By: anand1976

fbshipit-source-id: e8362ad624dc28e55c99fc35eda12866755f62c6
oxigraph-8.1.1
anand76 2 years ago committed by Facebook GitHub Bot
parent 2800aa069a
commit bcbab59c55
  1. 91
      db/corruption_test.cc

@ -43,33 +43,36 @@ namespace ROCKSDB_NAMESPACE {
static constexpr int kValueSize = 1000;
namespace {
// A wrapper that allows injection of errors.
class ErrorEnv : public EnvWrapper {
class ErrorFS : public FileSystemWrapper {
public:
bool writable_file_error_;
int num_writable_file_errors_;
explicit ErrorEnv(Env* _target)
: EnvWrapper(_target),
explicit ErrorFS(const std::shared_ptr<FileSystem>& _target)
: FileSystemWrapper(_target),
writable_file_error_(false),
num_writable_file_errors_(0) {}
const char* Name() const override { return "ErrorEnv"; }
virtual Status NewWritableFile(const std::string& fname,
std::unique_ptr<WritableFile>* result,
const EnvOptions& soptions) override {
virtual IOStatus NewWritableFile(const std::string& fname,
const FileOptions& opts,
std::unique_ptr<FSWritableFile>* result,
IODebugContext* dbg) override {
result->reset();
if (writable_file_error_) {
++num_writable_file_errors_;
return Status::IOError(fname, "fake error");
return IOStatus::IOError(fname, "fake error");
}
return target()->NewWritableFile(fname, result, soptions);
return target()->NewWritableFile(fname, opts, result, dbg);
}
};
} // anonymous namespace
class CorruptionTest : public testing::Test {
public:
std::shared_ptr<Env> env_guard_;
ErrorEnv* env_;
std::shared_ptr<ErrorFS> fs_;
std::unique_ptr<Env> env_;
Env* base_env_;
std::string dbname_;
std::shared_ptr<Cache> tiny_cache_;
Options options_;
@ -80,14 +83,15 @@ class CorruptionTest : public testing::Test {
// set it to 0), test SequenceNumberRecovery will fail, likely because of a
// bug in recovery code. Keep it 4 for now to make the test passes.
tiny_cache_ = NewLRUCache(100, 4);
Env* base_env = Env::Default();
base_env_ = Env::Default();
EXPECT_OK(
test::CreateEnvFromSystem(ConfigOptions(), &base_env, &env_guard_));
EXPECT_NE(base_env, nullptr);
env_ = new ErrorEnv(base_env);
test::CreateEnvFromSystem(ConfigOptions(), &base_env_, &env_guard_));
EXPECT_NE(base_env_, nullptr);
fs_.reset(new ErrorFS(base_env_->GetFileSystem()));
env_ = NewCompositeEnv(fs_);
options_.wal_recovery_mode = WALRecoveryMode::kTolerateCorruptedTailRecords;
options_.env = env_;
dbname_ = test::PerThreadDBPath(env_, "corruption_test");
options_.env = env_.get();
dbname_ = test::PerThreadDBPath(env_.get(), "corruption_test");
Status s = DestroyDB(dbname_, options_);
EXPECT_OK(s);
@ -110,10 +114,9 @@ class CorruptionTest : public testing::Test {
fprintf(stdout, "db is still at %s\n", dbname_.c_str());
} else {
Options opts;
opts.env = env_->target();
opts.env = base_env_;
EXPECT_OK(DestroyDB(dbname_, opts));
}
delete env_;
}
void CloseDb() {
@ -128,7 +131,7 @@ class CorruptionTest : public testing::Test {
if (opt.env == Options().env) {
// If env is not overridden, replace it with ErrorEnv.
// Otherwise, the test already uses a non-default Env.
opt.env = env_;
opt.env = env_.get();
}
opt.arena_block_size = 4096;
BlockBasedTableOptions table_options;
@ -223,7 +226,7 @@ class CorruptionTest : public testing::Test {
}
ASSERT_TRUE(!fname.empty()) << filetype;
ASSERT_OK(test::CorruptFile(env_, fname, offset, bytes_to_corrupt,
ASSERT_OK(test::CorruptFile(env_.get(), fname, offset, bytes_to_corrupt,
/*verify_checksum*/ filetype == kTableFile));
}
@ -234,7 +237,7 @@ class CorruptionTest : public testing::Test {
db_->GetLiveFilesMetaData(&metadata);
for (const auto& m : metadata) {
if (m.level == level) {
ASSERT_OK(test::CorruptFile(env_, dbname_ + "/" + m.name, offset,
ASSERT_OK(test::CorruptFile(env_.get(), dbname_ + "/" + m.name, offset,
bytes_to_corrupt));
return;
}
@ -308,7 +311,7 @@ class CorruptionTest : public testing::Test {
if (bytes_to_truncate == 0) {
new_size = 0;
}
ASSERT_OK(test::TruncateFile(env_, path, new_size));
ASSERT_OK(test::TruncateFile(env_.get(), path, new_size));
}
};
@ -402,14 +405,14 @@ TEST_F(CorruptionTest, PostPITRCorruptionWALsRetained) {
}
TEST_F(CorruptionTest, RecoverWriteError) {
env_->writable_file_error_ = true;
fs_->writable_file_error_ = true;
Status s = TryReopen();
ASSERT_TRUE(!s.ok());
}
TEST_F(CorruptionTest, NewFileErrorDuringWrite) {
// Do enough writing to force minor compaction
env_->writable_file_error_ = true;
fs_->writable_file_error_ = true;
const int num =
static_cast<int>(3 + (Options().write_buffer_size / kValueSize));
std::string value_storage;
@ -425,8 +428,8 @@ TEST_F(CorruptionTest, NewFileErrorDuringWrite) {
ASSERT_TRUE(!failed || !s.ok());
}
ASSERT_TRUE(!s.ok());
ASSERT_GE(env_->num_writable_file_errors_, 1);
env_->writable_file_error_ = false;
ASSERT_GE(fs_->num_writable_file_errors_, 1);
fs_->writable_file_error_ = false;
Reopen();
}
@ -444,7 +447,7 @@ TEST_F(CorruptionTest, TableFile) {
TEST_F(CorruptionTest, VerifyChecksumReadahead) {
Options options;
SpecialEnv senv(env_->target());
SpecialEnv senv(base_env_);
options.env = &senv;
// Disable block cache as we are going to check checksum for
// the same file twice and measure number of reads.
@ -587,8 +590,8 @@ TEST_F(CorruptionTest, TableFileWrongSize) {
// Make the file smaller with truncation.
// First leaving a partial footer, and then completely removing footer.
for (size_t bytes_lost : {8, 100}) {
ASSERT_OK(
test::TruncateFile(env_, filename, metadata[0].size - bytes_lost));
ASSERT_OK(test::TruncateFile(env_.get(), filename,
metadata[0].size - bytes_lost));
// Reported well with paranoid checks
options_.paranoid_checks = true;
@ -653,7 +656,7 @@ TEST_F(CorruptionTest, CorruptedDescriptor) {
TEST_F(CorruptionTest, CompactionInputError) {
Options options;
options.env = env_;
options.env = env_.get();
Reopen(&options);
Build(10);
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
@ -674,7 +677,7 @@ TEST_F(CorruptionTest, CompactionInputError) {
TEST_F(CorruptionTest, CompactionInputErrorParanoid) {
Options options;
options.env = env_;
options.env = env_.get();
options.paranoid_checks = true;
options.write_buffer_size = 131072;
options.max_write_buffer_number = 2;
@ -761,7 +764,7 @@ TEST_F(CorruptionTest, RangeDeletionCorrupted) {
ImmutableOptions(options_), kRangeDelBlockName, &range_del_handle));
ASSERT_OK(TryReopen());
ASSERT_OK(test::CorruptFile(env_, filename,
ASSERT_OK(test::CorruptFile(env_.get(), filename,
static_cast<int>(range_del_handle.offset()), 1));
ASSERT_TRUE(TryReopen().IsCorruption());
}
@ -769,7 +772,7 @@ TEST_F(CorruptionTest, RangeDeletionCorrupted) {
TEST_F(CorruptionTest, FileSystemStateCorrupted) {
for (int iter = 0; iter < 2; ++iter) {
Options options;
options.env = env_;
options.env = env_.get();
options.paranoid_checks = true;
options.create_if_missing = true;
Reopen(&options);
@ -808,7 +811,7 @@ static const auto& corruption_modes = {
TEST_F(CorruptionTest, ParanoidFileChecksOnFlush) {
Options options;
options.env = env_;
options.env = env_.get();
options.check_flush_compaction_key_order = false;
options.paranoid_file_checks = true;
options.create_if_missing = true;
@ -836,7 +839,7 @@ TEST_F(CorruptionTest, ParanoidFileChecksOnFlush) {
TEST_F(CorruptionTest, ParanoidFileChecksOnCompact) {
Options options;
options.env = env_;
options.env = env_.get();
options.paranoid_file_checks = true;
options.create_if_missing = true;
options.check_flush_compaction_key_order = false;
@ -869,7 +872,7 @@ TEST_F(CorruptionTest, ParanoidFileChecksOnCompact) {
TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRangeFirst) {
Options options;
options.env = env_;
options.env = env_.get();
options.check_flush_compaction_key_order = false;
options.paranoid_file_checks = true;
options.create_if_missing = true;
@ -905,7 +908,7 @@ TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRangeFirst) {
TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRange) {
Options options;
options.env = env_;
options.env = env_.get();
options.check_flush_compaction_key_order = false;
options.paranoid_file_checks = true;
options.create_if_missing = true;
@ -944,7 +947,7 @@ TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRange) {
TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRangeLast) {
Options options;
options.env = env_;
options.env = env_.get();
options.check_flush_compaction_key_order = false;
options.paranoid_file_checks = true;
options.create_if_missing = true;
@ -980,7 +983,7 @@ TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRangeLast) {
TEST_F(CorruptionTest, LogCorruptionErrorsInCompactionIterator) {
Options options;
options.env = env_;
options.env = env_.get();
options.create_if_missing = true;
options.allow_data_in_errors = true;
auto mode = mock::MockTableFactory::kCorruptKey;
@ -1009,7 +1012,7 @@ TEST_F(CorruptionTest, LogCorruptionErrorsInCompactionIterator) {
TEST_F(CorruptionTest, CompactionKeyOrderCheck) {
Options options;
options.env = env_;
options.env = env_.get();
options.paranoid_file_checks = false;
options.create_if_missing = true;
options.check_flush_compaction_key_order = false;
@ -1036,7 +1039,7 @@ TEST_F(CorruptionTest, CompactionKeyOrderCheck) {
TEST_F(CorruptionTest, FlushKeyOrderCheck) {
Options options;
options.env = env_;
options.env = env_.get();
options.paranoid_file_checks = false;
options.create_if_missing = true;
ASSERT_OK(db_->SetOptions({{"check_flush_compaction_key_order", "true"}}));
@ -1089,7 +1092,7 @@ TEST_F(CorruptionTest, DisableKeyOrderCheck) {
TEST_F(CorruptionTest, VerifyWholeTableChecksum) {
CloseDb();
Options options;
options.env = env_;
options.env = env_.get();
ASSERT_OK(DestroyDB(dbname_, options));
options.create_if_missing = true;
options.file_checksum_gen_factory =
@ -1178,7 +1181,7 @@ TEST_P(CrashDuringRecoveryWithCorruptionTest, CrashDuringRecovery) {
track_and_verify_wals_in_manifest_;
options.wal_recovery_mode = WALRecoveryMode::kPointInTimeRecovery;
options.avoid_flush_during_recovery = false;
options.env = env_;
options.env = env_.get();
ASSERT_OK(DestroyDB(dbname_, options));
options.create_if_missing = true;
options.max_write_buffer_number = 8;
@ -1350,7 +1353,7 @@ TEST_P(CrashDuringRecoveryWithCorruptionTest, TxnDbCrashDuringRecovery) {
options.track_and_verify_wals_in_manifest =
track_and_verify_wals_in_manifest_;
options.avoid_flush_during_recovery = false;
options.env = env_;
options.env = env_.get();
ASSERT_OK(DestroyDB(dbname_, options));
options.create_if_missing = true;
options.max_write_buffer_number = 3;
@ -1545,7 +1548,7 @@ TEST_P(CrashDuringRecoveryWithCorruptionTest, CrashDuringRecoveryWithFlush) {
Options options;
options.wal_recovery_mode = WALRecoveryMode::kPointInTimeRecovery;
options.avoid_flush_during_recovery = false;
options.env = env_;
options.env = env_.get();
options.create_if_missing = true;
ASSERT_OK(DestroyDB(dbname_, options));

Loading…
Cancel
Save