use super::execute::{root_with_source, run, NEW_DIM, SEEDED};
use super::*;
#[test]
fn a_validated_destination_advances_the_journal_and_carries_provenance() {
let root = root_with_source();
let executed = run(root.path()).expect("execute");
let outcome = super::super::validate_destination(
&root.path().join("store"),
&executed.destination,
&TargetContract::automatic("hash", NEW_DIM),
1024,
)
.expect("validate");
assert_eq!(outcome.facts, SEEDED, "every fact must have been compared");
assert_eq!(outcome.edges, 1, "every edge must have been compared");
assert_eq!(
outcome.explained_by_expiry, 0,
"nothing expired mid-walk in this fixture; a nonzero count here means \
the discriminator explained something it should not have"
);
let journalled = MigrationState::read(&executed.workspace)
.expect("read journal")
.expect("journal exists");
assert_eq!(
journalled.phase,
Phase::DestinationValidated,
"the validation is worthless unless the journal records it"
);
let stamped = crate::embedding_provenance::read(&executed.destination)
.expect("read provenance")
.expect("the validated destination must carry a provenance stamp");
assert_eq!(
(stamped.model.as_str(), stamped.dimension),
("hash", NEW_DIM),
"the stamp must name the TARGET embedder — the daemon reads it before \
opening, and a wrong stamp would be trusted forever"
);
super::super::validate_destination(
&root.path().join("store"),
&executed.destination,
&TargetContract::automatic("hash", NEW_DIM),
1024,
)
.expect("re-validation is idempotent");
}
#[test]
fn a_fact_the_source_does_not_hold_is_refused_by_name() {
let root = root_with_source();
let executed = run(root.path()).expect("execute");
{
let db = velesdb_core::Database::open(&executed.destination).expect("open destination");
let any = db
.get_any_collection("_semantic_memory")
.expect("collection");
any.upsert(vec![velesdb_core::Point::new(
999,
vec![0.0; NEW_DIM],
Some(serde_json::json!({ "content": "an intruder the source never held" })),
)])
.expect("plant intruder");
}
let refusal = super::super::validate_destination(
&root.path().join("store"),
&executed.destination,
&TargetContract::automatic("hash", NEW_DIM),
1024,
)
.expect_err("a destination holding a fact the source does not is not valid");
let message = refusal.to_string();
assert!(
message.contains("_semantic_memory") && message.contains("999"),
"the refusal must name the collection and the fact: {message}"
);
let journalled = MigrationState::read(&executed.workspace)
.expect("read journal")
.expect("journal exists");
assert_eq!(
journalled.phase,
Phase::Prepared,
"a failed validation must leave the journal exactly where it was"
);
}
#[test]
fn an_unfinished_rebuild_cannot_be_validated() {
let root = root_with_source();
let destination = root.path().join("rebuilt");
{
let _store =
crate::storage::NativeStore::open(&destination, NEW_DIM).expect("create destination");
}
let workspace = root.path().join("rebuilt.migration-journal");
std::fs::create_dir_all(&workspace).expect("workspace");
let lock = MigrationLock::acquire(&workspace, "unfinished-test").expect("lock");
let mut progress = std::collections::BTreeMap::new();
for name in AGENT_COLLECTIONS {
progress.insert((*name).to_owned(), CollectionProgress::Complete);
}
progress.insert(
"_episodic_memory".to_owned(),
CollectionProgress::Facts { cursor: Some(3) },
);
let state = MigrationState {
format_version: STATE_FORMAT_VERSION,
phase: Phase::Prepared,
source_path: root.path().join("store"),
source_fingerprint: super::super::fingerprint(&root.path().join("store"))
.expect("fingerprint"),
target_model: "hash".to_owned(),
target_dimension: NEW_DIM,
progress,
embedder_witness: None,
};
state.write(&workspace, &lock).expect("journal");
lock.release().expect("release");
let refusal = super::super::validate_destination(
&root.path().join("store"),
&destination,
&TargetContract::automatic("hash", NEW_DIM),
1024,
)
.expect_err("validating a rebuild that is not finished");
assert!(
refusal.to_string().contains("_episodic_memory"),
"the refusal must name the unfinished collection: {refusal}"
);
}
#[test]
fn a_source_that_changed_since_the_rebuild_is_refused() {
let root = root_with_source();
let executed = run(root.path()).expect("execute");
{
let store =
crate::storage::NativeStore::open(root.path().join("store"), DIM).expect("open");
store
.store(100, "written after the rebuild", &EMBEDDING)
.expect("late write");
}
let refusal = super::super::validate_destination(
&root.path().join("store"),
&executed.destination,
&TargetContract::automatic("hash", NEW_DIM),
1024,
)
.expect_err("a moved source invalidates the comparison, not the destination");
let message = refusal.to_string();
assert!(
message.contains("fingerprint") || message.contains("changed"),
"the refusal must say the SOURCE moved, not accuse the destination: {message}"
);
}
#[test]
fn the_expiry_discriminator_tells_vanished_from_live() {
let root = root_with_source();
let store = root.path().join("store");
super::preservation::seed_raw(&store, 50, "expired long ago", Some(1_000_000));
let db = velesdb_core::Database::open(&store).expect("open");
assert!(
super::super::divergence_explained_by_expiry(&db, "_semantic_memory", 50),
"a point whose absolute expiry passed must explain its own absence"
);
assert!(
!super::super::divergence_explained_by_expiry(&db, "_semantic_memory", 1),
"a live point explains nothing — its divergence is loss"
);
}