use std::collections::BTreeSet;
use std::sync::Arc;
use crate::RealmId;
use crate::btree::BTree;
use crate::crypto::CipherId;
use crate::crypto::kdf::derive_mk;
use crate::pager::{Pager, PagerConfig};
use crate::vfs::memory::MemVfs;
const PAGE: usize = 4096;
async fn fresh_pager() -> Arc<Pager<MemVfs>> {
let mk = derive_mk(&[1u8; 32], &[0u8; 16], 0).unwrap();
let cfg = PagerConfig {
page_size: PAGE,
buffer_pool_pages: 64,
segment_cache_pages: 64,
cipher_id: CipherId::Aes256Gcm,
mk_epoch: 0,
main_db_file_id: [0xAB; 16],
main_db_path: "/main.db".into(),
anchor_budget: 1_000_000,
dek_lru_capacity: 16,
observer_retry_count: 0,
metrics_enabled: true,
};
Arc::new(Pager::open(MemVfs::new(), mk, cfg).await.unwrap())
}
#[tokio::test(flavor = "current_thread")]
async fn single_page_overflow_root_walk_has_no_false_dangling() {
let pager = fresh_pager().await;
let mut tree = BTree::open(pager, RealmId::new([1; 16]), 0, 4, PAGE);
let value = vec![0xABu8; 2000];
tree.put(b"k:single-page-overflow", &value).await.unwrap();
tree.flush().await.unwrap();
let got = tree.get(b"k:single-page-overflow").await.unwrap();
assert_eq!(got.as_deref(), Some(value.as_slice()), "value round-trips");
let dangling = tree.find_dangling().await;
assert!(
dangling.is_none(),
"false-positive dangling on a clean single-page overflow value: {dangling:?}"
);
let mut reachable = BTreeSet::new();
tree.collect_all_page_ids(&mut reachable).await.unwrap();
assert!(
!reachable.contains(&1),
"walk spuriously reached reserved page 1: {reachable:?}"
);
}