cargo.build, the WASI test runner, the console, and core.notify ordering

- cargo.build (native): one source copy, tests under WASI, release
  build to /state/cargo/builds/<n>/, process groups killed on cancel.
  The host writes the SDK copy to /plugins/cargo/sdk/ at start.
- sausage test-runner: one instance per test, in parallel, with its own
  mount table (empty world, package folder at its path); answers
  core.lock, core.unlock, core.notify, core.log.
- The console: rustyline, notifications while typing, ls/cat through the
  process view, methods, ps, log, activate, revert, stop, kill.
- core.notify on stdout is handled in order, before the response.
This commit is contained in:
2026-10-23 01:42:19 +01:00
parent 0516158883
commit 8d058666dc
23 changed files with 1786 additions and 296 deletions
+28
View File
@@ -243,6 +243,34 @@ async fn progress_notifications_reach_the_caller() {
h.stop().await;
}
/// PROTOCOL 3.5: every stdout notification reaches the caller before the following result.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn stdout_notifications_precede_the_result() {
let w = TestWorld::new();
let h = w.start().await;
let mut notifications = h.subscribe();
for _ in 0..10 {
assert_eq!(call(&h, "probe.burst", json!({"count":64})).await, 64);
let mut call_id = None;
for index in 0..64 {
// A delayed notification fails here, even if it arrives later.
let notification = notifications.try_recv().unwrap();
assert_eq!(notification["params"]["name"], "burst");
assert_eq!(notification["params"]["params"]["index"], index);
if let Some(id) = &call_id {
assert_eq!(&notification["params"]["call"], id);
} else {
call_id = Some(notification["params"]["call"].clone());
}
}
assert!(matches!(
notifications.try_recv(),
Err(tokio::sync::broadcast::error::TryRecvError::Empty)
));
}
h.stop().await;
}
/// PROTOCOL 3.1: non message stdout warns once without its content.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn non_message_stdout_warns_once_without_its_content() {