use pagedb::{CommitId, CorruptionDetail, DbMode, Evictable, PagedbError, QuotaKind, RealmId};
#[test]
fn corruption_constructor_round_trips() {
let err = PagedbError::corruption(CorruptionDetail::FooterUnverifiable {
realm_id: RealmId::new([0u8; 16]),
segment_id: [1u8; 16],
});
assert!(matches!(err, PagedbError::Corruption(_)));
let _ = format!("{err}");
let _ = format!("{err:?}");
}
#[test]
fn quota_constructor_round_trips() {
let err = PagedbError::quota(RealmId::new([0u8; 16]), QuotaKind::SegmentBytes, 1024, 512);
if let PagedbError::Quota {
kind, used, limit, ..
} = err
{
assert_eq!(kind, QuotaKind::SegmentBytes);
assert_eq!(used, 1024);
assert_eq!(limit, 512);
} else {
panic!("wrong variant");
}
}
#[test]
fn io_error_from_conversion() {
let io = std::io::Error::other("disk wobble");
let err: PagedbError = io.into();
assert!(matches!(err, PagedbError::Io(_)));
}
#[test]
fn device_exhaustion_is_classified_out_of_generic_io() {
let full = std::io::Error::from(std::io::ErrorKind::StorageFull);
let err: PagedbError = full.into();
assert!(
matches!(err, PagedbError::NoSpace),
"a full device must not hide inside Io, got: {err:?}"
);
}
#[test]
fn every_variant_displays() {
let realm = RealmId::new([0u8; 16]);
let cases: Vec<PagedbError> = vec![
PagedbError::ChecksumFailure,
PagedbError::corruption(CorruptionDetail::HeaderUnverifiable),
PagedbError::structural_header_invalid("main.db", "magic"),
PagedbError::page_chain_cycle("btree_descent", 41),
PagedbError::leaf_sibling_mismatch(31, 31, None),
PagedbError::BulkLoadNotMonotonic,
PagedbError::vfs_contract_violated(
"read_at",
"reported more bytes than the caller requested",
),
PagedbError::footer_framing_invalid("magic"),
PagedbError::node_body_malformed("slot_directory"),
PagedbError::node_kind_mismatch(Some(7), "leaf", "internal"),
PagedbError::overflow_body_malformed("root.data_length"),
PagedbError::journal_record_malformed("record.header"),
PagedbError::snapshot_artifact_invalid("manifest.magic"),
PagedbError::corruption(CorruptionDetail::ForeignSegment {
realm_id: realm,
name: "x".into(),
segment_id: [0; 16],
footer_parent_file_id: [1; 16],
expected_parent_file_id: [2; 16],
}),
PagedbError::corruption(CorruptionDetail::SegmentMissing {
realm_id: realm,
name: "x".into(),
segment_id: [0; 16],
}),
PagedbError::corruption(CorruptionDetail::StagingMissing {
segment_id: [0; 16],
}),
PagedbError::corruption(CorruptionDetail::PageUnverifiable {
realm_id: realm,
segment_id: Some([0; 16]),
page_id: 42,
evictable: Some(Evictable::Replaceable),
}),
PagedbError::corruption(CorruptionDetail::ManifestUnverifiable {
realm_id: realm,
segment_id: [0; 16],
}),
PagedbError::quota(realm, QuotaKind::Pages, 1, 0),
PagedbError::NoSpace,
PagedbError::ReadOnly,
PagedbError::WriterPresent,
PagedbError::ReadersPresent,
PagedbError::AlreadyOpen,
PagedbError::AlreadyLocked,
PagedbError::RestoredNotPromoted,
PagedbError::wrong_mode("apply_incremental", DbMode::Follower, DbMode::Standalone),
PagedbError::CommitGone {
commit: CommitId::new(10),
oldest_available: CommitId::new(20),
},
PagedbError::NotFound,
PagedbError::AlreadyLinked,
PagedbError::NotLinked,
PagedbError::NameTooLong,
PagedbError::IllegalPageKind,
PagedbError::PayloadTooLarge,
PagedbError::ManifestTooLarge,
PagedbError::MmapViewQuotaExceeded {
segment_bytes: 100,
available_bytes: 50,
},
PagedbError::Aborted,
PagedbError::ReadersPinningTruncatedRange,
PagedbError::Unsupported,
];
for c in &cases {
let _ = format!("{c}");
let _ = format!("{c:?}");
}
}