53dbdf0f1d
Workspace en 4 ejes (core/modules/apps/shared):
- core/: 24 crates de arje (Init systemd-compatible: ente-card, ente-zero,
ente-kernel, ente-bus, ente-cas, ente-soma, ente-wasm, ente-snapshot,
ente-brain, ente-echo, ente-policy-provider, + 12 crates *-compat)
- modules/semantic_dht/: 5 crates de minga (minga-core con AST/CAS/MST,
minga-p2p con libp2p Kad, minga-store, minga-vfs, minga-cli)
- modules/ui_engine/: 11 crates de yahweh (libs/{core,theme,bus,providers},
widgets/{tree,splitter,tabs,tiled,container_core,text_input})
- apps/: 5 crates de yahweh (file_explorer, database_explorer, text_viewer,
image_viewer, yahweh-shell)
- shared_wit/protocol.wit: handshake/lifecycle inicial
Cargo.toml unificado: thiserror bumped a 2 (transparente para arje), tokio
"full", paths intra-workspace de yahweh redirigidos a su nueva ubicación.
cargo check --workspace: 0 errores, 17 warnings (dead code preexistente).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
105 lines
3.5 KiB
Rust
105 lines
3.5 KiB
Rust
//! Test de integración del `PersistentRepo`: los tres stores conviven
|
|
//! en una misma `sled::Db`, escritos en una sesión y recuperados
|
|
//! intactos en la siguiente.
|
|
|
|
use minga_core::{parse, Attestation, ContentHash, Keypair};
|
|
use minga_store::PersistentRepo;
|
|
use tempfile::TempDir;
|
|
|
|
#[test]
|
|
fn three_stores_persist_together_across_reopen() {
|
|
let dir = TempDir::new().unwrap();
|
|
let path = dir.path();
|
|
let alice = Keypair::from_seed(&[1; 32]);
|
|
|
|
// ── Sesión 1: poblamos el repo ──────────────────────────────────
|
|
let function_hash;
|
|
let target_root_hash;
|
|
{
|
|
let repo = PersistentRepo::open(path).unwrap();
|
|
let n = parse::rust("fn add(x: i32, y: i32) -> i32 { x + y }").unwrap();
|
|
function_hash = repo.nodes.put(&n).unwrap();
|
|
repo.mst.insert(function_hash).unwrap();
|
|
repo.attestations
|
|
.add(Attestation::create(&alice, function_hash))
|
|
.unwrap();
|
|
|
|
target_root_hash = repo.mst.to_in_memory().unwrap().root_hash();
|
|
repo.flush().unwrap();
|
|
}
|
|
|
|
// ── Sesión 2: reabrimos y verificamos integridad ────────────────
|
|
{
|
|
let repo = PersistentRepo::open(path).unwrap();
|
|
|
|
// Nodo recuperable.
|
|
let stored = repo.nodes.get(&function_hash).unwrap().unwrap();
|
|
assert_eq!(stored.kind, "source_file");
|
|
|
|
// Reconstrucción completa idéntica al original.
|
|
let reconstructed = repo.nodes.reconstruct(&function_hash).unwrap().unwrap();
|
|
let original = parse::rust("fn add(x: i32, y: i32) -> i32 { x + y }").unwrap();
|
|
assert_eq!(reconstructed, original);
|
|
|
|
// MST: misma raíz tras reconstruir.
|
|
assert_eq!(
|
|
repo.mst.to_in_memory().unwrap().root_hash(),
|
|
target_root_hash
|
|
);
|
|
|
|
// Atestación: sigue ahí, sigue verificable.
|
|
let authors = repo.attestations.authors_of(&function_hash).unwrap();
|
|
assert_eq!(authors, vec![alice.did()]);
|
|
let atts = repo.attestations.get(&function_hash).unwrap();
|
|
assert!(atts[0].verify());
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn repo_supports_multiple_functions_and_authors() {
|
|
let dir = TempDir::new().unwrap();
|
|
let repo = PersistentRepo::open(dir.path()).unwrap();
|
|
|
|
let alice = Keypair::from_seed(&[1; 32]);
|
|
let bob = Keypair::from_seed(&[2; 32]);
|
|
|
|
let mut hashes: Vec<ContentHash> = Vec::new();
|
|
for src in &[
|
|
"fn one() -> i32 { 1 }",
|
|
"fn two() -> i32 { 2 }",
|
|
"fn three(x: i32) -> i32 { x + 1 }",
|
|
] {
|
|
let n = parse::rust(src).unwrap();
|
|
let h = repo.nodes.put(&n).unwrap();
|
|
repo.mst.insert(h).unwrap();
|
|
hashes.push(h);
|
|
}
|
|
|
|
// Alice firma las tres; Bob firma solo la primera.
|
|
for h in &hashes {
|
|
repo.attestations
|
|
.add(Attestation::create(&alice, *h))
|
|
.unwrap();
|
|
}
|
|
repo.attestations
|
|
.add(Attestation::create(&bob, hashes[0]))
|
|
.unwrap();
|
|
|
|
repo.flush().unwrap();
|
|
|
|
assert_eq!(repo.mst.len(), 3);
|
|
assert_eq!(repo.attestations.len(), 4);
|
|
|
|
// La función firmada por ambos tiene dos autores.
|
|
let authors_first = repo.attestations.authors_of(&hashes[0]).unwrap();
|
|
assert_eq!(authors_first.len(), 2);
|
|
assert!(authors_first.contains(&alice.did()));
|
|
assert!(authors_first.contains(&bob.did()));
|
|
|
|
// Las otras dos solo tienen a Alice.
|
|
assert_eq!(
|
|
repo.attestations.authors_of(&hashes[1]).unwrap(),
|
|
vec![alice.did()]
|
|
);
|
|
}
|