diff --git a/utilities/blob_db/blob_db_test.cc b/utilities/blob_db/blob_db_test.cc index b5472ae8d..4be5ee8d5 100644 --- a/utilities/blob_db/blob_db_test.cc +++ b/utilities/blob_db/blob_db_test.cc @@ -1469,12 +1469,14 @@ TEST_F(BlobDBTest, UserCompactionFilter_BlobIOError) { auto s = blob_db_->CompactRange(CompactRangeOptions(), nullptr, nullptr); ASSERT_TRUE(s.IsIOError()); + // Reactivate file system to allow test to verify and close DB. + fault_injection_env_->SetFilesystemActive(true); + SyncPoint::GetInstance()->DisableProcessing(); + SyncPoint::GetInstance()->ClearAllCallBacks(); + // Verify full data set after compaction failure VerifyDB(data); - // Reactivate file system to allow test to close DB. - fault_injection_env_->SetFilesystemActive(true); - SyncPoint::GetInstance()->ClearAllCallBacks(); delete options.compaction_filter; Destroy(); } diff --git a/utilities/fault_injection_env.cc b/utilities/fault_injection_env.cc index 06ce6b352..668daa04a 100644 --- a/utilities/fault_injection_env.cc +++ b/utilities/fault_injection_env.cc @@ -107,6 +107,51 @@ Status TestDirectory::Fsync() { return dir_->Fsync(); } +TestRandomAccessFile::TestRandomAccessFile( + std::unique_ptr&& target, FaultInjectionTestEnv* env) + : target_(std::move(target)), env_(env) { + assert(target_); + assert(env_); +} + +Status TestRandomAccessFile::Read(uint64_t offset, size_t n, Slice* result, + char* scratch) const { + assert(env_); + if (!env_->IsFilesystemActive()) { + return env_->GetError(); + } + + assert(target_); + return target_->Read(offset, n, result, scratch); +} + +Status TestRandomAccessFile::Prefetch(uint64_t offset, size_t n) { + assert(env_); + if (!env_->IsFilesystemActive()) { + return env_->GetError(); + } + + assert(target_); + return target_->Prefetch(offset, n); +} + +Status TestRandomAccessFile::MultiRead(ReadRequest* reqs, size_t num_reqs) { + assert(env_); + if (!env_->IsFilesystemActive()) { + const Status s = env_->GetError(); + + assert(reqs); + for (size_t i = 0; i < num_reqs; ++i) { + reqs[i].status = s; + } + + return s; + } + + assert(target_); + return target_->MultiRead(reqs, num_reqs); +} + TestWritableFile::TestWritableFile(const std::string& fname, std::unique_ptr&& f, FaultInjectionTestEnv* env) @@ -299,7 +344,17 @@ Status FaultInjectionTestEnv::NewRandomAccessFile( if (!IsFilesystemActive()) { return GetError(); } - return target()->NewRandomAccessFile(fname, result, soptions); + + assert(target()); + const Status s = target()->NewRandomAccessFile(fname, result, soptions); + if (!s.ok()) { + return s; + } + + assert(result); + result->reset(new TestRandomAccessFile(std::move(*result), this)); + + return Status::OK(); } Status FaultInjectionTestEnv::DeleteFile(const std::string& f) { diff --git a/utilities/fault_injection_env.h b/utilities/fault_injection_env.h index ded02083f..b1e8faa41 100644 --- a/utilities/fault_injection_env.h +++ b/utilities/fault_injection_env.h @@ -47,6 +47,23 @@ struct FileState { Status DropRandomUnsyncedData(Env* env, Random* rand) const; }; +class TestRandomAccessFile : public RandomAccessFile { + public: + TestRandomAccessFile(std::unique_ptr&& target, + FaultInjectionTestEnv* env); + + Status Read(uint64_t offset, size_t n, Slice* result, + char* scratch) const override; + + Status Prefetch(uint64_t offset, size_t n) override; + + Status MultiRead(ReadRequest* reqs, size_t num_reqs) override; + + private: + std::unique_ptr target_; + FaultInjectionTestEnv* env_; +}; + // A wrapper around WritableFileWriter* file // is written to or sync'ed. class TestWritableFile : public WritableFile {