the freenet layer: adapter, persona and profile services, the contracts bundled as commitments
This commit is contained in:
1 parent
63a0357651
commit
6dce4e2ac7
16 files changed
+3337
-10
No files matched your search
@@ -0,0 +1,95 @@
|
||||
//! Live integration against a REAL local Freenet node — the house pattern
|
||||
//! (`#[ignore]`d corpus tests inside the crate, run on demand):
|
||||
//!
|
||||
//! 1. start a node: freenet local local --config-dir <dir> --data-dir <dir>
|
||||
//! 2. set SOULSTREAM_F0_WASM to a contract wasm (the F0 spike's
|
||||
//! research/freenet-f0/f0-contract build works verbatim)
|
||||
//! 3. cargo test -p freenet-adapter --release -- --ignored
|
||||
//!
|
||||
//! Exercises the full adapter loop: detect → enable → put → get →
|
||||
//! subscribe → update (with the first-write priming path) → notification
|
||||
//! event → kill switch mid-life.
|
||||
|
||||
use freenet_adapter::{AdapterEvent, AdapterStatus, FreenetAdapter};
|
||||
use std::time::Duration;
|
||||
|
||||
fn wasm() -> Option<Vec<u8>> {
|
||||
let path = std::env::var("SOULSTREAM_F0_WASM").ok()?;
|
||||
std::fs::read(path).ok()
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore = "needs a local freenet node on 7509 and SOULSTREAM_F0_WASM"]
|
||||
async fn full_loop_against_live_node() {
|
||||
let Some(code) = wasm() else {
|
||||
panic!("set SOULSTREAM_F0_WASM to a contract wasm path");
|
||||
};
|
||||
let a = FreenetAdapter::default();
|
||||
|
||||
// Detection first — a wrong environment should fail here, loudly.
|
||||
let detected = a.detect().await;
|
||||
assert_eq!(detected, AdapterStatus::Connected, "node not reachable: {detected:?}");
|
||||
|
||||
a.enable();
|
||||
// Wait for the supervisor to connect.
|
||||
let mut tries = 0;
|
||||
while a.status() != AdapterStatus::Connected {
|
||||
tokio::time::sleep(Duration::from_millis(200)).await;
|
||||
tries += 1;
|
||||
assert!(tries < 50, "supervisor never connected: {:?}", a.status());
|
||||
}
|
||||
|
||||
// A fresh instance per run: params carry a nonce.
|
||||
let params = format!("adapter-live-{}", std::process::id()).into_bytes();
|
||||
let ids = FreenetAdapter::contract_ids(code.clone(), ¶ms);
|
||||
|
||||
// PUT initial state.
|
||||
let put_ids = a
|
||||
.contract_put(code.clone(), ¶ms, br#"["alpha"]"#.to_vec(), false)
|
||||
.await
|
||||
.expect("put");
|
||||
assert_eq!(put_ids.instance, ids.instance);
|
||||
|
||||
// GET it back.
|
||||
let state = a.contract_get(&ids.instance, false).await.expect("get");
|
||||
assert_eq!(state, br#"["alpha"]"#);
|
||||
|
||||
// SUBSCRIBE, then watch for the update notification through the
|
||||
// adapter's bounded event bus.
|
||||
let mut events = a.subscribe();
|
||||
assert!(a.contract_subscribe(&ids.instance).await.expect("subscribe"));
|
||||
|
||||
// UPDATE via the primed path (exercises get_then_update's shape even
|
||||
// though this node already holds the contract).
|
||||
let summary = a
|
||||
.get_then_update(code.clone(), ¶ms, br#"["beta"]"#.to_vec())
|
||||
.await
|
||||
.expect("update");
|
||||
assert!(!summary.is_empty(), "update summary should carry bytes");
|
||||
|
||||
// The merged state must be the union.
|
||||
let state = a.contract_get(&ids.instance, false).await.expect("get2");
|
||||
assert_eq!(state, br#"["alpha","beta"]"#);
|
||||
|
||||
// The notification should have crossed the event bus (ids only).
|
||||
let deadline = tokio::time::Instant::now() + Duration::from_secs(10);
|
||||
let mut saw_update = false;
|
||||
while tokio::time::Instant::now() < deadline {
|
||||
match tokio::time::timeout(Duration::from_secs(1), events.recv()).await {
|
||||
Ok(Ok(AdapterEvent::ContractUpdate { instance, .. })) if instance == ids.instance => {
|
||||
saw_update = true;
|
||||
break;
|
||||
}
|
||||
Ok(Ok(_)) => continue,
|
||||
Ok(Err(_)) => break,
|
||||
Err(_) => continue,
|
||||
}
|
||||
}
|
||||
assert!(saw_update, "no ContractUpdate event reached the bus");
|
||||
|
||||
// Kill switch mid-life: immediate, and ops refuse afterwards.
|
||||
a.disable();
|
||||
assert_eq!(a.status(), AdapterStatus::Disabled);
|
||||
let err = a.contract_get(&ids.instance, false).await;
|
||||
assert!(matches!(err, Err(freenet_adapter::AdapterError::Disabled)));
|
||||
}
|
||||
Reference in new issue
Block a user