fault_injection_test: add a test case to drop random number of unsynced data
Summary: Currently fault_injection_test has a test case to drop all the unsynced data. Add one more case to take a randomized bytes from it. Test Plan: Run the test Reviewers: rven, yhchiang, igor Reviewed By: igor Subscribers: leveldb, dhruba Differential Revision: https://reviews.facebook.net/D32229
This commit is contained in:
parent
d888c95748
commit
c1de6c42a0
@ -114,6 +114,8 @@ struct FileState {
|
|||||||
bool IsFullySynced() const { return pos_ <= 0 || pos_ == pos_at_last_sync_; }
|
bool IsFullySynced() const { return pos_ <= 0 || pos_ == pos_at_last_sync_; }
|
||||||
|
|
||||||
Status DropUnsyncedData() const;
|
Status DropUnsyncedData() const;
|
||||||
|
|
||||||
|
Status DropRandomUnsyncedData(Random* rand) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
@ -226,7 +228,9 @@ class FaultInjectionTestEnv : public EnvWrapper {
|
|||||||
db_file_state_[state.filename_] = state;
|
db_file_state_[state.filename_] = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status DropUnsyncedFileData() {
|
// For every file that is not fully synced, make a call to `func` with
|
||||||
|
// FileState of the file as the parameter.
|
||||||
|
Status DropFileData(std::function<Status(FileState)> func) {
|
||||||
Status s;
|
Status s;
|
||||||
MutexLock l(&mutex_);
|
MutexLock l(&mutex_);
|
||||||
for (std::map<std::string, FileState>::const_iterator it =
|
for (std::map<std::string, FileState>::const_iterator it =
|
||||||
@ -234,12 +238,23 @@ class FaultInjectionTestEnv : public EnvWrapper {
|
|||||||
s.ok() && it != db_file_state_.end(); ++it) {
|
s.ok() && it != db_file_state_.end(); ++it) {
|
||||||
const FileState& state = it->second;
|
const FileState& state = it->second;
|
||||||
if (!state.IsFullySynced()) {
|
if (!state.IsFullySynced()) {
|
||||||
s = state.DropUnsyncedData();
|
s = func(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status DropUnsyncedFileData() {
|
||||||
|
return DropFileData(
|
||||||
|
[&](const FileState& state) { return state.DropUnsyncedData(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
Status DropRandomUnsyncedFileData(Random* rnd) {
|
||||||
|
return DropFileData([&](const FileState& state) {
|
||||||
|
return state.DropRandomUnsyncedData(rnd);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Status DeleteFilesCreatedAfterLastDirSync() {
|
Status DeleteFilesCreatedAfterLastDirSync() {
|
||||||
// Because DeleteFile access this container make a copy to avoid deadlock
|
// Because DeleteFile access this container make a copy to avoid deadlock
|
||||||
std::map<std::string, std::set<std::string>> map_copy;
|
std::map<std::string, std::set<std::string>> map_copy;
|
||||||
@ -296,6 +311,15 @@ Status FileState::DropUnsyncedData() const {
|
|||||||
return Truncate(filename_, sync_pos);
|
return Truncate(filename_, sync_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status FileState::DropRandomUnsyncedData(Random* rand) const {
|
||||||
|
ssize_t sync_pos = pos_at_last_sync_ == -1 ? 0 : pos_at_last_sync_;
|
||||||
|
assert(pos_ >= sync_pos);
|
||||||
|
int range = static_cast<int>(pos_ - sync_pos);
|
||||||
|
uint64_t truncated_size =
|
||||||
|
static_cast<uint64_t>(sync_pos) + rand->Uniform(range);
|
||||||
|
return Truncate(filename_, truncated_size);
|
||||||
|
}
|
||||||
|
|
||||||
Status TestDirectory::Fsync() {
|
Status TestDirectory::Fsync() {
|
||||||
env_->SyncDir(dirname_);
|
env_->SyncDir(dirname_);
|
||||||
return dir_->Fsync();
|
return dir_->Fsync();
|
||||||
@ -373,6 +397,7 @@ class FaultInjectionTest {
|
|||||||
enum ExpectedVerifResult { kValExpectFound, kValExpectNoError };
|
enum ExpectedVerifResult { kValExpectFound, kValExpectNoError };
|
||||||
enum ResetMethod {
|
enum ResetMethod {
|
||||||
kResetDropUnsyncedData,
|
kResetDropUnsyncedData,
|
||||||
|
kResetDropRandomUnsyncedData,
|
||||||
kResetDeleteUnsyncedFiles,
|
kResetDeleteUnsyncedFiles,
|
||||||
kResetDropAndDeleteUnsynced
|
kResetDropAndDeleteUnsynced
|
||||||
};
|
};
|
||||||
@ -563,11 +588,15 @@ class FaultInjectionTest {
|
|||||||
db_->Flush(flush_options);
|
db_->Flush(flush_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetDBState(ResetMethod reset_method) {
|
// rnd cannot be null for kResetDropRandomUnsyncedData
|
||||||
|
void ResetDBState(ResetMethod reset_method, Random* rnd = nullptr) {
|
||||||
switch (reset_method) {
|
switch (reset_method) {
|
||||||
case kResetDropUnsyncedData:
|
case kResetDropUnsyncedData:
|
||||||
ASSERT_OK(env_->DropUnsyncedFileData());
|
ASSERT_OK(env_->DropUnsyncedFileData());
|
||||||
break;
|
break;
|
||||||
|
case kResetDropRandomUnsyncedData:
|
||||||
|
ASSERT_OK(env_->DropRandomUnsyncedFileData(rnd));
|
||||||
|
break;
|
||||||
case kResetDeleteUnsyncedFiles:
|
case kResetDeleteUnsyncedFiles:
|
||||||
ASSERT_OK(env_->DeleteFilesCreatedAfterLastDirSync());
|
ASSERT_OK(env_->DeleteFilesCreatedAfterLastDirSync());
|
||||||
break;
|
break;
|
||||||
@ -595,11 +624,11 @@ class FaultInjectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PartialCompactTestReopenWithFault(ResetMethod reset_method,
|
void PartialCompactTestReopenWithFault(ResetMethod reset_method,
|
||||||
int num_pre_sync,
|
int num_pre_sync, int num_post_sync,
|
||||||
int num_post_sync) {
|
Random* rnd = nullptr) {
|
||||||
env_->SetFilesystemActive(false);
|
env_->SetFilesystemActive(false);
|
||||||
CloseDB();
|
CloseDB();
|
||||||
ResetDBState(reset_method);
|
ResetDBState(reset_method, rnd);
|
||||||
ASSERT_OK(OpenDB());
|
ASSERT_OK(OpenDB());
|
||||||
ASSERT_OK(Verify(0, num_pre_sync, FaultInjectionTest::kValExpectFound));
|
ASSERT_OK(Verify(0, num_pre_sync, FaultInjectionTest::kValExpectFound));
|
||||||
ASSERT_OK(Verify(num_pre_sync, num_post_sync,
|
ASSERT_OK(Verify(num_pre_sync, num_post_sync,
|
||||||
@ -631,6 +660,12 @@ TEST(FaultInjectionTest, FaultTest) {
|
|||||||
NoWriteTestPreFault();
|
NoWriteTestPreFault();
|
||||||
NoWriteTestReopenWithFault(kResetDropUnsyncedData);
|
NoWriteTestReopenWithFault(kResetDropUnsyncedData);
|
||||||
|
|
||||||
|
PartialCompactTestPreFault(num_pre_sync, num_post_sync);
|
||||||
|
PartialCompactTestReopenWithFault(kResetDropRandomUnsyncedData,
|
||||||
|
num_pre_sync, num_post_sync, &rnd);
|
||||||
|
NoWriteTestPreFault();
|
||||||
|
NoWriteTestReopenWithFault(kResetDropUnsyncedData);
|
||||||
|
|
||||||
// Setting a separate data path won't pass the test as we don't sync
|
// Setting a separate data path won't pass the test as we don't sync
|
||||||
// it after creating new files,
|
// it after creating new files,
|
||||||
PartialCompactTestPreFault(num_pre_sync, num_post_sync);
|
PartialCompactTestPreFault(num_pre_sync, num_post_sync);
|
||||||
|
Loading…
Reference in New Issue
Block a user