tawasuyu

tawasuyu/brahman

Rust 326TOML 123JSON 17Markdown 144606 Definiciones

⎇ d3649bfd1a80153652c2a028315369bb4b184024 crates/modules/semantic_dht/minga-p2p/tests/async_driver_invariants.rs Rust · 161 líneas · 5.6 KB Historia Quién tocó qué crudo

chore: monorepo inicial con arje + minga + yahweh absorbidos 53dbdf0f1 · Sergio ·

1//! Tests del `run_sync_async` sobre canales async in-memory.
2//!
3//! Equivalentes a los del harness síncrono pero ejecutados sobre
4//! `tokio::io::duplex` — la misma lógica protocolar viajando sobre
5//! bytes serializados con postcard, encuadrados con length-prefix, y
6//! transportados por una pipa async. Si esto pasa, lo único que falta
7//! para el sync sobre TCP/QUIC/libp2p es enchufar el transporte real.
8
9use minga_core::{parse, ContentHash, Keypair, MemStore, Mst, NodeStore};
10use minga_p2p::{run_sync_async, SyncSession};
11
12fn kp(seed: u8) -> Keypair {
13    Keypair::from_seed(&[seed; 32])
14}
15
16fn build_repo(sources: &[&str]) -> (Mst, MemStore, Vec<ContentHash>) {
17    let mut mst = Mst::new();
18    let mut store = MemStore::new();
19    let mut roots = Vec::new();
20    for src in sources {
21        let n = parse::rust(src).unwrap();
22        let h = store.put(&n);
23        mst.insert(h);
24        roots.push(h);
25    }
26    (mst, store, roots)
27}
28
29#[tokio::test]
30async fn async_sync_identical_repos() {
31    let sources = &["fn add(x: i32, y: i32) -> i32 { x + y }"];
32    let (mst_a, store_a, _) = build_repo(sources);
33    let (mst_b, store_b, _) = build_repo(sources);
34
35    let session_a = SyncSession::without_attestations(mst_a, store_a, kp(1));
36    let session_b = SyncSession::without_attestations(mst_b, store_b, kp(2));
37
38    let (a_stream, b_stream) = tokio::io::duplex(64 * 1024);
39
40    let task_a = tokio::spawn(run_sync_async(session_a, a_stream));
41    let task_b = tokio::spawn(run_sync_async(session_b, b_stream));
42
43    let a = task_a.await.unwrap().unwrap();
44    let b = task_b.await.unwrap().unwrap();
45
46    assert_eq!(a.mst().root_hash(), b.mst().root_hash());
47}
48
49#[tokio::test]
50async fn async_sync_one_empty_pulls_everything() {
51    let sources = &["fn complex(x: i32) -> i32 { let y = x * 2; y + 1 }"];
52    let (mst_a, store_a, _) = build_repo(sources);
53    let (mst_b, store_b, _) = build_repo(&[]);
54    let store_a_size = store_a.len();
55
56    let session_a = SyncSession::without_attestations(mst_a, store_a, kp(1));
57    let session_b = SyncSession::without_attestations(mst_b, store_b, kp(2));
58
59    let (a_stream, b_stream) = tokio::io::duplex(64 * 1024);
60
61    let task_a = tokio::spawn(run_sync_async(session_a, a_stream));
62    let task_b = tokio::spawn(run_sync_async(session_b, b_stream));
63
64    let a = task_a.await.unwrap().unwrap();
65    let b = task_b.await.unwrap().unwrap();
66
67    assert_eq!(a.mst().root_hash(), b.mst().root_hash());
68    assert_eq!(a.store().len(), b.store().len());
69    assert_eq!(b.store().len(), store_a_size);
70}
71
72#[tokio::test]
73async fn async_sync_disjoint_sets_merge() {
74    let only_a = &[
75        "fn alpha() -> i32 { 1 }",
76        "fn beta(x: i32) -> i32 { x + 1 }",
77    ];
78    let only_b = &[
79        "fn gamma(y: i32) -> bool { y > 0 }",
80        "fn delta() -> &'static str { \"hello\" }",
81    ];
82
83    let (mst_a, store_a, _) = build_repo(only_a);
84    let (mst_b, store_b, _) = build_repo(only_b);
85
86    let session_a = SyncSession::without_attestations(mst_a, store_a, kp(1));
87    let session_b = SyncSession::without_attestations(mst_b, store_b, kp(2));
88
89    let (a_stream, b_stream) = tokio::io::duplex(64 * 1024);
90
91    let task_a = tokio::spawn(run_sync_async(session_a, a_stream));
92    let task_b = tokio::spawn(run_sync_async(session_b, b_stream));
93
94    let a = task_a.await.unwrap().unwrap();
95    let b = task_b.await.unwrap().unwrap();
96
97    assert_eq!(a.mst().root_hash(), b.mst().root_hash());
98    assert_eq!(a.mst().len(), 4);
99}
100
101#[tokio::test]
102async fn async_sync_propagates_authenticated_identity() {
103    // Cada peer debe acabar conociendo el DID verificado del otro,
104    // exactamente como en el harness síncrono.
105    let kp_a = kp(10);
106    let kp_b = kp(20);
107    let did_a = kp_a.did();
108    let did_b = kp_b.did();
109
110    let session_a = SyncSession::without_attestations(Mst::new(), MemStore::new(), kp_a);
111    let session_b = SyncSession::without_attestations(Mst::new(), MemStore::new(), kp_b);
112
113    let (a_stream, b_stream) = tokio::io::duplex(64 * 1024);
114
115    let task_a = tokio::spawn(run_sync_async(session_a, a_stream));
116    let task_b = tokio::spawn(run_sync_async(session_b, b_stream));
117
118    let a = task_a.await.unwrap().unwrap();
119    let b = task_b.await.unwrap().unwrap();
120
121    assert_eq!(a.peer_did(), Some(did_b));
122    assert_eq!(b.peer_did(), Some(did_a));
123}
124
125#[tokio::test]
126async fn async_sync_propagates_attestations() {
127    use minga_core::{Attestation, AttestationStore};
128
129    let kp_a = kp(30);
130    let kp_b = kp(40);
131
132    let (mst_a, store_a, roots_a) = build_repo(&["fn from_a() -> i32 { 1 }"]);
133    let (mst_b, store_b, roots_b) = build_repo(&["fn from_b() -> i32 { 2 }"]);
134
135    let mut atts_a = AttestationStore::new();
136    atts_a
137        .add(Attestation::create(&kp_a, roots_a[0]))
138        .unwrap();
139
140    let mut atts_b = AttestationStore::new();
141    atts_b
142        .add(Attestation::create(&kp_b, roots_b[0]))
143        .unwrap();
144
145    let session_a = SyncSession::new(mst_a, store_a, atts_a, kp_a.clone());
146    let session_b = SyncSession::new(mst_b, store_b, atts_b, kp_b.clone());
147
148    let (a_stream, b_stream) = tokio::io::duplex(128 * 1024);
149
150    let task_a = tokio::spawn(run_sync_async(session_a, a_stream));
151    let task_b = tokio::spawn(run_sync_async(session_b, b_stream));
152
153    let a = task_a.await.unwrap().unwrap();
154    let b = task_b.await.unwrap().unwrap();
155
156    // Los DIDs y atestaciones cruzaron correctamente sobre el wire.
157    assert_eq!(a.attestations().authors_of(&roots_a[0]), vec![kp_a.did()]);
158    assert_eq!(a.attestations().authors_of(&roots_b[0]), vec![kp_b.did()]);
159    assert_eq!(b.attestations().authors_of(&roots_a[0]), vec![kp_a.did()]);
160    assert_eq!(b.attestations().authors_of(&roots_b[0]), vec![kp_b.did()]);
161}