#![cfg(feature = "tokio")]
use std::sync::Arc;
fn corpus(name: &str) -> std::path::PathBuf {
let dir = std::env::var("MANED_CONFORMANCE_DIR")
.unwrap_or_else(|_| "/Users/fabianodicheti/Documents/maned/capi-freeze/conformance".into());
std::path::PathBuf::from(dir).join(name)
}
fn shared() -> Arc<maned::SharedScript> {
Arc::new(
maned::load(corpus("01_local_matmul.mnd"))
.unwrap()
.into_shared()
.unwrap(),
)
}
#[tokio::test]
async fn run_async_returns_the_same_bytes_as_run() {
let script = shared();
let sync_body = script
.run(&serde_json::json!({"h0": [[3,1],[2,4]]}))
.unwrap()
.body()
.to_vec();
let r = Arc::clone(&script)
.run_async(serde_json::json!({"h0": [[3,1],[2,4]]}))
.await
.unwrap();
assert_eq!(r.status(), 200);
assert_eq!(r.body(), sync_body.as_slice());
}
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn many_concurrent_run_async_calls_agree() {
let script = shared();
let expected = br#"{"outputs":{"a":[[7,9],[2,4]]},"notes":[]}"#.to_vec();
let mut futures = Vec::new();
for _ in 0..32 {
futures.push(tokio::spawn(
Arc::clone(&script).run_async(serde_json::json!({"h0": [[3,1],[2,4]]})),
));
}
for f in futures {
let r = f.await.unwrap().unwrap();
assert_eq!(r.body(), expected.as_slice());
}
}
#[tokio::test]
async fn run_async_propagates_the_status_map() {
let script = shared();
let err = script
.run_async(serde_json::json!({"h0": [[3,1],[2]]}))
.await
.unwrap_err();
assert_eq!(err.status(), Some(400));
assert!(matches!(err, maned::Error::Input { .. }), "{err:?}");
assert!(err.to_string().contains("ragged array"), "{err}");
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn a_timeout_does_not_cancel_the_call() {
use std::sync::atomic::{AtomicUsize, Ordering};
static FINISHED: AtomicUsize = AtomicUsize::new(0);
let script = shared();
let task = tokio::spawn(async move {
let r = script
.run_async(serde_json::json!({"h0": [[3,1],[2,4]]}))
.await;
FINISHED.fetch_add(1, Ordering::SeqCst);
r
});
let _ = tokio::time::timeout(std::time::Duration::from_nanos(1), async {}).await;
let r = task.await.unwrap().unwrap();
assert_eq!(r.status(), 200);
assert_eq!(
FINISHED.load(Ordering::SeqCst),
1,
"the call ran to completion"
);
}