1 use std::env;
2 use std::time::Duration;
3 
4 use super::util::{config, make_component};
5 use futures::stream::{FuturesUnordered, TryStreamExt};
6 use wasmtime::Result;
7 use wasmtime::component::{Linker, ResourceTable};
8 use wasmtime::{Engine, Store};
9 use wasmtime_wasi::WasiCtxBuilder;
10 
11 #[tokio::test]
async_borrowing_caller() -> Result<()>12 pub async fn async_borrowing_caller() -> Result<()> {
13     test_run_bool(
14         &[
15             test_programs_artifacts::ASYNC_BORROWING_CALLER_COMPONENT,
16             test_programs_artifacts::ASYNC_BORROWING_CALLEE_COMPONENT,
17         ],
18         false,
19     )
20     .await
21 }
22 
23 #[tokio::test]
async_borrowing_caller_misbehave() -> Result<()>24 async fn async_borrowing_caller_misbehave() -> Result<()> {
25     let error = format!(
26         "{:?}",
27         test_run_bool(
28             &[
29                 test_programs_artifacts::ASYNC_BORROWING_CALLER_COMPONENT,
30                 test_programs_artifacts::ASYNC_BORROWING_CALLEE_COMPONENT
31             ],
32             true
33         )
34         .await
35         .unwrap_err()
36     );
37     assert!(error.contains("unknown handle index"), "{error}");
38     Ok(())
39 }
40 
41 #[tokio::test]
async_borrowing_callee_misbehave() -> Result<()>42 async fn async_borrowing_callee_misbehave() -> Result<()> {
43     let error = format!(
44         "{:?}",
45         test_run_bool(
46             &[test_programs_artifacts::ASYNC_BORROWING_CALLEE_COMPONENT],
47             true
48         )
49         .await
50         .unwrap_err()
51     );
52     assert!(error.contains("unknown handle index"), "{error}");
53     Ok(())
54 }
55 
56 #[tokio::test]
async_borrowing_callee() -> Result<()>57 pub async fn async_borrowing_callee() -> Result<()> {
58     test_run_bool(
59         &[test_programs_artifacts::ASYNC_BORROWING_CALLEE_COMPONENT],
60         false,
61     )
62     .await
63 }
64 
test_run_bool(components: &[&str], v: bool) -> Result<()>65 pub async fn test_run_bool(components: &[&str], v: bool) -> Result<()> {
66     let mut config = config();
67     // As of this writing, miri/pulley/epochs is a problematic combination, so
68     // we don't test it.
69     if env::var_os("MIRI_TEST_CWASM_DIR").is_none() {
70         config.epoch_interruption(true);
71     }
72 
73     let engine = Engine::new(&config)?;
74 
75     let component = make_component(&engine, components).await?;
76 
77     let mut linker = Linker::new(&engine);
78 
79     wasmtime_wasi::p2::add_to_linker_async(&mut linker)?;
80     component_async_tests::borrowing_host::bindings::local::local::borrowing_types::add_to_linker::<
81         _,
82         component_async_tests::Ctx,
83     >(&mut linker, |ctx| ctx)?;
84 
85     let mut store = Store::new(
86         &engine,
87         component_async_tests::Ctx {
88             wasi: WasiCtxBuilder::new().inherit_stdio().build(),
89             table: ResourceTable::default(),
90             continue_: false,
91         },
92     );
93 
94     if env::var_os("MIRI_TEST_CWASM_DIR").is_none() {
95         store.set_epoch_deadline(1);
96 
97         std::thread::spawn(move || {
98             std::thread::sleep(Duration::from_secs(10));
99             engine.increment_epoch();
100         });
101     }
102 
103     let borrowing_host =
104         component_async_tests::borrowing_host::bindings::BorrowingHost::instantiate_async(
105             &mut store, &component, &linker,
106         )
107         .await?;
108 
109     store
110         .run_concurrent(async move |accessor| {
111             // Start three concurrent calls and then join them all:
112             let mut futures = FuturesUnordered::new();
113             for _ in 0..3 {
114                 futures.push(borrowing_host.local_local_run_bool().call_run(accessor, v));
115             }
116 
117             while let Some(()) = futures.try_next().await? {
118                 // continue
119             }
120 
121             wasmtime::error::Ok(())
122         })
123         .await?
124 }
125