use std::error::Error;
use std::fmt::Write as _;
use chia_protocol::Bytes32;
use dig_blockstore::BlockStoreError;
use rocksdb::{Options, DB};
fn err_discriminant(e: &BlockStoreError) -> u8 {
match e {
BlockStoreError::RocksDb(_) => 0,
BlockStoreError::Serialization(_) => 1,
BlockStoreError::Compression(_) => 2,
BlockStoreError::BlockNotFound(_) => 3,
BlockStoreError::CheckpointNotFound(_) => 4,
BlockStoreError::BlockNotInStore(_) => 5,
BlockStoreError::RollbackBelowMin { .. } => 6,
BlockStoreError::RollbackAboveTip { .. } => 7,
BlockStoreError::NoTip => 8,
BlockStoreError::SchemaMismatch { .. } => 9,
BlockStoreError::NotInitialized => 10,
BlockStoreError::EmptyReorgChain => 11,
BlockStoreError::PipelineClosed => 12,
}
}
fn assert_send_sync<T: Send + Sync>() {}
#[test]
fn test_construct_all_variants_and_debug_non_empty() {
let rocks = sample_rocksdb_error();
let cases: Vec<BlockStoreError> = vec![
BlockStoreError::RocksDb(rocks),
BlockStoreError::Serialization("bincode".into()),
BlockStoreError::Compression("zstd".into()),
BlockStoreError::BlockNotFound(Bytes32::new([1u8; 32])),
BlockStoreError::CheckpointNotFound(7),
BlockStoreError::BlockNotInStore(Bytes32::new([2u8; 32])),
BlockStoreError::RollbackBelowMin { target: 1, min: 2 },
BlockStoreError::RollbackAboveTip { target: 9, tip: 3 },
BlockStoreError::NoTip,
BlockStoreError::SchemaMismatch {
expected: 1,
found: 2,
},
BlockStoreError::NotInitialized,
BlockStoreError::EmptyReorgChain,
BlockStoreError::PipelineClosed,
];
assert_eq!(cases.len(), 13, "ERR-001 defines exactly thirteen variants");
let mut buf = String::new();
for (i, e) in cases.iter().enumerate() {
assert_eq!(usize::from(err_discriminant(e)), i);
buf.clear();
write!(&mut buf, "{e:?}").expect("Debug fmt");
assert!(
buf.len() > 3,
"variant {i} should produce meaningful Debug: {buf}"
);
}
}
#[test]
fn test_rocksdb_source_chains_inner_other_variants_are_leaves() {
let inner = sample_rocksdb_error();
let wrapped = BlockStoreError::RocksDb(inner);
assert!(
wrapped.source().is_some(),
"RocksDb should forward source() per ERR-001 test plan"
);
let leaf = BlockStoreError::Serialization("x".into());
assert!(leaf.source().is_none());
}
#[test]
fn test_from_rocksdb_error() {
let inner = sample_rocksdb_error();
let e: BlockStoreError = inner.into();
assert!(matches!(e, BlockStoreError::RocksDb(_)));
}
#[test]
fn test_send_sync_bounds() {
assert_send_sync::<BlockStoreError>();
}
fn sample_rocksdb_error() -> rocksdb::Error {
let tmp = tempfile::tempdir().expect("tempdir");
let not_a_dir = tmp.path().join("not_a_directory");
std::fs::write(¬_a_dir, b"x").expect("write file");
DB::open(&Options::default(), ¬_a_dir).expect_err("expected RocksDB open failure")
}