|
|
@ -58,6 +58,8 @@ const TRIALS: usize = 100;
|
|
|
|
const POST_TRIALS_SIZE: usize = TRIALS - (TRIALS / 10);
|
|
|
|
const POST_TRIALS_SIZE: usize = TRIALS - (TRIALS / 10);
|
|
|
|
/// a test key for single events
|
|
|
|
/// a test key for single events
|
|
|
|
const KEY: &str = concat!("1234567890-0987654321");
|
|
|
|
const KEY: &str = concat!("1234567890-0987654321");
|
|
|
|
|
|
|
|
const SIMPLEDB_JOURNAL_HEADER_SIZE: usize =
|
|
|
|
|
|
|
|
<<SimpleDBJournal as RawJournalAdapter>::Spec as FileSpecV1>::SIZE;
|
|
|
|
|
|
|
|
|
|
|
|
/// The initializer for a corruption test case
|
|
|
|
/// The initializer for a corruption test case
|
|
|
|
struct Initializer {
|
|
|
|
struct Initializer {
|
|
|
@ -70,7 +72,7 @@ struct Initializer {
|
|
|
|
/// Information about the modified journal generated by an [`Initializer`]
|
|
|
|
/// Information about the modified journal generated by an [`Initializer`]
|
|
|
|
struct ModifiedJournalInfo {
|
|
|
|
struct ModifiedJournalInfo {
|
|
|
|
init: InitializerInfo,
|
|
|
|
init: InitializerInfo,
|
|
|
|
_storage: ModifiedJournalStorageInfo,
|
|
|
|
storage: ModifiedJournalStorageInfo,
|
|
|
|
initializer_id: usize,
|
|
|
|
initializer_id: usize,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -82,7 +84,7 @@ impl ModifiedJournalInfo {
|
|
|
|
) -> Self {
|
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
Self {
|
|
|
|
init,
|
|
|
|
init,
|
|
|
|
_storage: storage,
|
|
|
|
storage,
|
|
|
|
initializer_id,
|
|
|
|
initializer_id,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -361,10 +363,12 @@ fn emulate_midway_corruption(
|
|
|
|
);
|
|
|
|
);
|
|
|
|
f.fwrite_all(segment_before_corruption)?;
|
|
|
|
f.fwrite_all(segment_before_corruption)?;
|
|
|
|
f.fwrite_all(segment_after_corruption)?;
|
|
|
|
f.fwrite_all(segment_after_corruption)?;
|
|
|
|
|
|
|
|
let corruption_range = end_offset - trim_size..end_offset;
|
|
|
|
|
|
|
|
assert_eq!(corruption_range.len(), trim_size);
|
|
|
|
Ok(ModifiedJournalStorageInfo::new(
|
|
|
|
Ok(ModifiedJournalStorageInfo::new(
|
|
|
|
orig_journal_size,
|
|
|
|
orig_journal_size,
|
|
|
|
new_size,
|
|
|
|
new_size,
|
|
|
|
end_offset - trim_size..end_offset,
|
|
|
|
corruption_range,
|
|
|
|
))
|
|
|
|
))
|
|
|
|
},
|
|
|
|
},
|
|
|
|
post_corruption_handler,
|
|
|
|
post_corruption_handler,
|
|
|
@ -814,8 +818,7 @@ fn corruption_at_runtime() {
|
|
|
|
let mut jrnl = create_journal("corruption_at_runtime_test_log.db").unwrap();
|
|
|
|
let mut jrnl = create_journal("corruption_at_runtime_test_log.db").unwrap();
|
|
|
|
sdb.push(&mut jrnl, KEY).unwrap();
|
|
|
|
sdb.push(&mut jrnl, KEY).unwrap();
|
|
|
|
let (_, offset) = debug_get_offsets().pop_last().unwrap();
|
|
|
|
let (_, offset) = debug_get_offsets().pop_last().unwrap();
|
|
|
|
let ret =
|
|
|
|
let ret = offset as usize - SIMPLEDB_JOURNAL_HEADER_SIZE;
|
|
|
|
offset as usize - <<SimpleDBJournal as RawJournalAdapter>::Spec as FileSpecV1>::SIZE;
|
|
|
|
|
|
|
|
debug_set_offset_tracking(false);
|
|
|
|
debug_set_offset_tracking(false);
|
|
|
|
let _ = debug_get_trace();
|
|
|
|
let _ = debug_get_trace();
|
|
|
|
ret
|
|
|
|
ret
|
|
|
@ -1154,10 +1157,12 @@ fn midway_corruption_close() {
|
|
|
|
// this is a serious midway corruption with major data loss
|
|
|
|
// this is a serious midway corruption with major data loss
|
|
|
|
let full_log_size = File::open(journal_id).unwrap().f_len().unwrap();
|
|
|
|
let full_log_size = File::open(journal_id).unwrap().f_len().unwrap();
|
|
|
|
assert_eq!(
|
|
|
|
assert_eq!(
|
|
|
|
repair_result.expect(&format!("failed at trim_size {trim_size} for journal {journal_id}")),
|
|
|
|
repair_result.expect(&format!(
|
|
|
|
|
|
|
|
"failed at trim_size {trim_size} for journal {journal_id}"
|
|
|
|
|
|
|
|
)),
|
|
|
|
RepairResult::UnspecifiedLoss(
|
|
|
|
RepairResult::UnspecifiedLoss(
|
|
|
|
full_log_size
|
|
|
|
full_log_size
|
|
|
|
- <<SimpleDBJournal as RawJournalAdapter>::Spec as FileSpecV1>::SIZE // account for header
|
|
|
|
- SIMPLEDB_JOURNAL_HEADER_SIZE // account for header
|
|
|
|
as u64
|
|
|
|
as u64
|
|
|
|
- (DriverEvent::FULL_EVENT_SIZE * 2) as u64 // account for close (0), reopen(1)
|
|
|
|
- (DriverEvent::FULL_EVENT_SIZE * 2) as u64 // account for close (0), reopen(1)
|
|
|
|
- trim_size as u64 // account for trim
|
|
|
|
- trim_size as u64 // account for trim
|
|
|
@ -1291,9 +1296,18 @@ fn midway_corruption_reopen() {
|
|
|
|
let _ = open_result.expect(&format!(
|
|
|
|
let _ = open_result.expect(&format!(
|
|
|
|
"failed at trim_size {trim_size} for journal {journal_id}"
|
|
|
|
"failed at trim_size {trim_size} for journal {journal_id}"
|
|
|
|
));
|
|
|
|
));
|
|
|
|
let _ = repair_result.expect(&format!(
|
|
|
|
let repair_result = repair_result.expect(&format!(
|
|
|
|
"failed at trim_size {trim_size} for journal {journal_id}"
|
|
|
|
"failed at trim_size {trim_size} for journal {journal_id}"
|
|
|
|
));
|
|
|
|
));
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
|
|
|
|
repair_result,
|
|
|
|
|
|
|
|
RepairResult::UnspecifiedLoss(
|
|
|
|
|
|
|
|
((modified_journal_info.storage.modified_file_size
|
|
|
|
|
|
|
|
- modified_journal_info.storage.corruption_range.start)
|
|
|
|
|
|
|
|
+ (DriverEvent::FULL_EVENT_SIZE - trim_size)) as u64
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
"failed at trim_size {trim_size} for journal {journal_id}"
|
|
|
|
|
|
|
|
);
|
|
|
|
match modified_journal_info.initializer_id {
|
|
|
|
match modified_journal_info.initializer_id {
|
|
|
|
0 | 2 => {
|
|
|
|
0 | 2 => {
|
|
|
|
assert_eq!(
|
|
|
|
assert_eq!(
|
|
|
@ -1332,8 +1346,7 @@ fn midway_corruption_at_runtime() {
|
|
|
|
create_journal::<SimpleDBJournal>("midway_corruption_at_runtime_fixed_key").unwrap();
|
|
|
|
create_journal::<SimpleDBJournal>("midway_corruption_at_runtime_fixed_key").unwrap();
|
|
|
|
SimpleDB::new().push(&mut jrnl, KEY).unwrap();
|
|
|
|
SimpleDB::new().push(&mut jrnl, KEY).unwrap();
|
|
|
|
let (_, offsets) = (debug_get_trace(), debug_get_offsets());
|
|
|
|
let (_, offsets) = (debug_get_trace(), debug_get_offsets());
|
|
|
|
*offsets.get(&0).unwrap() as usize
|
|
|
|
*offsets.get(&0).unwrap() as usize - SIMPLEDB_JOURNAL_HEADER_SIZE
|
|
|
|
- <<SimpleDBJournal as RawJournalAdapter>::Spec as FileSpecV1>::SIZE
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// compute offset size
|
|
|
|
// compute offset size
|
|
|
|
let event_size_dynamic_key = {
|
|
|
|
let event_size_dynamic_key = {
|
|
|
@ -1341,8 +1354,7 @@ fn midway_corruption_at_runtime() {
|
|
|
|
create_journal::<SimpleDBJournal>("midway_corruption_at_runtime_dynamic_key").unwrap();
|
|
|
|
create_journal::<SimpleDBJournal>("midway_corruption_at_runtime_dynamic_key").unwrap();
|
|
|
|
SimpleDB::new().push(&mut jrnl, keyfmt(0)).unwrap();
|
|
|
|
SimpleDB::new().push(&mut jrnl, keyfmt(0)).unwrap();
|
|
|
|
let (_, offsets) = (debug_get_trace(), debug_get_offsets());
|
|
|
|
let (_, offsets) = (debug_get_trace(), debug_get_offsets());
|
|
|
|
*offsets.get(&0).unwrap() as usize
|
|
|
|
*offsets.get(&0).unwrap() as usize - SIMPLEDB_JOURNAL_HEADER_SIZE
|
|
|
|
- <<SimpleDBJournal as RawJournalAdapter>::Spec as FileSpecV1>::SIZE
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let initializers = [
|
|
|
|
let initializers = [
|
|
|
|
Initializer::new(
|
|
|
|
Initializer::new(
|
|
|
@ -1420,7 +1432,7 @@ fn midway_corruption_at_runtime() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|journal_id, modified_journal_info, trim_size, repair_result, db, open_result| {
|
|
|
|
|journal_id, modified_journal_info, trim_size, repair_result, db, open_result| {
|
|
|
|
let _ = repair_result.expect(&format!(
|
|
|
|
let repair_result = repair_result.expect(&format!(
|
|
|
|
"failed at trim_size {trim_size} for journal {journal_id}. file data={:?}. original_data={:?}",
|
|
|
|
"failed at trim_size {trim_size} for journal {journal_id}. file data={:?}. original_data={:?}",
|
|
|
|
FileSystem::read(&make_corrupted_file_name(journal_id, trim_size)),
|
|
|
|
FileSystem::read(&make_corrupted_file_name(journal_id, trim_size)),
|
|
|
|
FileSystem::read(journal_id),
|
|
|
|
FileSystem::read(journal_id),
|
|
|
@ -1452,6 +1464,33 @@ fn midway_corruption_at_runtime() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => panic!(),
|
|
|
|
_ => panic!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
match modified_journal_info.initializer_id {
|
|
|
|
|
|
|
|
0 => {
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
|
|
|
|
repair_result,
|
|
|
|
|
|
|
|
RepairResult::UnspecifiedLoss(
|
|
|
|
|
|
|
|
((modified_journal_info.storage.modified_file_size
|
|
|
|
|
|
|
|
- modified_journal_info.storage.corruption_range.start)
|
|
|
|
|
|
|
|
+ (event_size_fixed_size_key - trim_size))
|
|
|
|
|
|
|
|
as u64
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
"failed at trim_size {trim_size} for journal {journal_id}"
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
1 | 2 => {
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
|
|
|
|
repair_result,
|
|
|
|
|
|
|
|
RepairResult::UnspecifiedLoss(
|
|
|
|
|
|
|
|
((modified_journal_info.storage.modified_file_size
|
|
|
|
|
|
|
|
- modified_journal_info.storage.corruption_range.start)
|
|
|
|
|
|
|
|
+ (event_size_dynamic_key - trim_size))
|
|
|
|
|
|
|
|
as u64
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
"failed at trim_size {trim_size} for journal {journal_id}"
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => panic!(),
|
|
|
|
|
|
|
|
}
|
|
|
|
let (_, _) = (debug_get_trace(), debug_get_offsets());
|
|
|
|
let (_, _) = (debug_get_trace(), debug_get_offsets());
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
)
|
|
|
|