Skip to content

Commit

Permalink
[Fix] Fix unit test
Browse files Browse the repository at this point in the history
Signed-off-by: csh <[email protected]>
  • Loading branch information
L-jasmine committed Oct 31, 2023
1 parent 9c95c51 commit 7f750bb
Show file tree
Hide file tree
Showing 19 changed files with 407 additions and 4,853 deletions.
41 changes: 4 additions & 37 deletions crates/wasmedge-sys/src/ast_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,7 @@ pub(crate) struct InnerExportType(pub(crate) *const ffi::WasmEdge_ExportTypeCont
unsafe impl Send for InnerExportType {}
unsafe impl Sync for InnerExportType {}

// #[cfg(test)]
#[cfg(ignore)]
#[cfg(test)]
mod tests {
use crate::{Config, Loader};
use std::{
Expand All @@ -402,38 +401,6 @@ mod tests {
};
use wasmedge_types::{ExternalInstanceType, Mutability, RefType, ValType};

#[test]
fn test_module_clone() {
let path = std::env::current_dir()
.unwrap()
.ancestors()
.nth(2)
.unwrap()
.join("examples/wasmedge-sys/data/import.wat");

let result = Config::create();
assert!(result.is_ok());
let mut config = result.unwrap();
config.bulk_memory_operations(true);
assert!(config.bulk_memory_operations_enabled());

// load module from file
let result = Loader::create(Some(&config));
assert!(result.is_ok());
let loader = result.unwrap();
let result = loader.from_file(path);
assert!(result.is_ok());
let module = result.unwrap();
assert!(!module.inner.0.is_null());

// clone module
let module_clone = module.clone();

drop(module);
assert_eq!(std::sync::Arc::strong_count(&module_clone.inner), 1);
drop(module_clone);
}

#[test]
fn test_module_import() {
let path = std::env::current_dir()
Expand Down Expand Up @@ -617,7 +584,7 @@ mod tests {
// check exports

assert_eq!(module.count_of_exports(), 16);
let exports = module.exports();
let exports = module.export();

// check the ty and name functions
let result = exports[0].ty();
Expand Down Expand Up @@ -772,7 +739,7 @@ mod tests {
// check exports

assert_eq!(module.count_of_exports(), 16);
let exports = module.exports();
let exports = module.export();

// check the ty and name functions
let result = exports[0].ty();
Expand Down Expand Up @@ -934,7 +901,7 @@ mod tests {
// check exports

assert_eq!(module.count_of_exports(), 16);
let exports = module.exports();
let exports = module.export();

// check the ty and name functions
let result = exports[0].ty();
Expand Down
217 changes: 91 additions & 126 deletions crates/wasmedge-sys/src/async/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,140 +128,105 @@ impl AsMut<Function> for AsyncFunction {
}
}

#[cfg(ignore)]
/// Defines the signature of a host function.
pub(crate) type HostFn<T> = fn(
CallingFrame,
Vec<WasmValue>,
Option<&'static mut T>,
) -> Result<Vec<WasmValue>, HostFuncError>;

#[cfg(ignore)]
extern "C" fn wrap_sync_wasi_fn<T: 'static>(
key_ptr: *mut std::ffi::c_void,
data: *mut std::ffi::c_void,
call_frame_ctx: *const ffi::WasmEdge_CallingFrameContext,
params: *const ffi::WasmEdge_Value,
param_len: u32,
returns: *mut ffi::WasmEdge_Value,
return_len: u32,
) -> ffi::WasmEdge_Result {
let frame = CallingFrame::create(call_frame_ctx);

// recover the async host function
let real_func: HostFn<T> = unsafe { std::mem::transmute(key_ptr) };

// recover the context data
let data = if std::any::TypeId::of::<T>() == std::any::TypeId::of::<NeverType>() {
None
} else {
let data: &'static mut T = unsafe { &mut *(data as *mut T) };
Some(data)
#[cfg(test)]
mod tests {
use super::*;
use crate::{
instance::function::AsFunc, r#async::fiber::AsyncState, types::WasmValue, Executor,
};

// input arguments
let input = {
let raw_input = unsafe {
std::slice::from_raw_parts(
params,
param_len
.try_into()
.expect("len of params should not greater than usize"),
)
};
raw_input.iter().map(|r| (*r).into()).collect::<Vec<_>>()
};
use wasmedge_types::{error::CoreExecutionError, FuncType, ValType};

// returns
let return_len = return_len
.try_into()
.expect("len of returns should not greater than usize");
let raw_returns = unsafe { std::slice::from_raw_parts_mut(returns, return_len) };

match real_func(frame, input, data) {
Ok(returns) => {
assert!(returns.len() == return_len, "[wasmedge-sys] check the number of returns of host function. Expected: {}, actual: {}", return_len, returns.len());
for (idx, wasm_value) in returns.into_iter().enumerate() {
raw_returns[idx] = wasm_value.as_raw();
}
ffi::WasmEdge_Result { Code: 0 }
#[tokio::test]
async fn test_func_basic() {
#[derive(Debug)]
struct Data<T, S> {
_x: i32,
_y: String,
_v: Vec<T>,
_s: Vec<S>,
}
Err(err) => match err {
HostFuncError::User(code) => unsafe {
ffi::WasmEdge_ResultGen(ffi::WasmEdge_ErrCategory_UserLevelError, code)
},
HostFuncError::Runtime(code) => unsafe {
ffi::WasmEdge_ResultGen(ffi::WasmEdge_ErrCategory_WASM, code)
},
},
}
}
#[cfg(ignore)]
extern "C" fn wrap_async_wasi_fn<T: 'static>(
key_ptr: *mut std::ffi::c_void,
data: *mut std::ffi::c_void,
call_frame_ctx: *const ffi::WasmEdge_CallingFrameContext,
params: *const ffi::WasmEdge_Value,
param_len: u32,
returns: *mut ffi::WasmEdge_Value,
return_len: u32,
) -> ffi::WasmEdge_Result {
let frame = CallingFrame::create(call_frame_ctx);

// recover the async host function
let real_func: AsyncHostFn<T> = unsafe { std::mem::transmute(key_ptr) };

// recover the context data
let data = if std::any::TypeId::of::<T>() == std::any::TypeId::of::<NeverType>() {
None
} else {
let data: &'static mut T = unsafe { &mut *(data as *mut T) };
Some(data)
};

// arguments
let input = {
let raw_input = unsafe {
std::slice::from_raw_parts(
params,
param_len
.try_into()
.expect("len of params should not greater than usize"),
)
let mut data: Data<i32, &str> = Data {
_x: 12,
_y: "hello".to_string(),
_v: vec![1, 2, 3],
_s: vec!["macos", "linux", "windows"],
};
raw_input.iter().map(|r| (*r).into()).collect::<Vec<_>>()
};

// returns
let return_len = return_len
.try_into()
.expect("len of returns should not greater than usize");
let raw_returns = unsafe { std::slice::from_raw_parts_mut(returns, return_len) };
fn real_add<T: core::fmt::Debug>(
_host_data: &mut Data<i32, &str>,
_inst: &mut AsyncInstance,
_frame: &mut CallingFrame,
input: Vec<WasmValue>,
) -> Box<dyn Future<Output = Result<Vec<WasmValue>, CoreError>> + Send> {
Box::new(async move {
println!("Rust: Entering Rust function real_add");

if input.len() != 2 {
return Err(CoreError::Execution(CoreExecutionError::FuncTypeMismatch));
}

let a = if input[0].ty() == ValType::I32 {
input[0].to_i32()
} else {
return Err(CoreError::Execution(CoreExecutionError::FuncTypeMismatch));
};

let b = if input[1].ty() == ValType::I32 {
input[1].to_i32()
} else {
return Err(CoreError::Execution(CoreExecutionError::FuncTypeMismatch));
};

tokio::time::sleep(std::time::Duration::from_millis(300)).await;

let c = a + b;
println!("Rust: calcuating in real_add c: {c:?}");

println!("Rust: Leaving Rust function real_add");
Ok(vec![WasmValue::from_i32(c)])
})
}

let async_cx = AsyncCx::new();
let mut future = Pin::from(real_func(frame, input, data));
let result = match unsafe { async_cx.block_on(future.as_mut()) } {
Ok(Ok(ret)) => Ok(ret),
Ok(Err(err)) => Err(err),
Err(_err) => Err(HostFuncError::Runtime(0x07)),
};
// create a FuncType
let func_ty = FuncType::new(vec![ValType::I32; 2], vec![ValType::I32]);
// create a host function
let result =
AsyncFunction::create_async_func(&func_ty, real_add::<Data<i32, &str>>, &mut data, 0);
assert!(result.is_ok());
let mut host_func = result.unwrap();

// get func type
let result = host_func.ty();
assert!(result.is_some());
let ty = result.unwrap();

// check parameters
assert_eq!(ty.args_len(), 2);
assert_eq!(ty.args(), &[ValType::I32; 2]);

// check returns
assert_eq!(ty.returns_len(), 1);
assert_eq!(ty.returns(), &[ValType::I32]);

// run this function
let result = Executor::create(None, None);
assert!(result.is_ok());
let mut executor = result.unwrap();

let async_state = AsyncState::new();

let result = executor
.call_func_async(
&async_state,
host_func.as_mut(),
vec![WasmValue::from_i32(1), WasmValue::from_i32(2)],
)
.await;

// parse result
match result {
Ok(returns) => {
assert!(returns.len() == return_len, "[wasmedge-sys] check the number of returns of async host function. Expected: {}, actual: {}", return_len, returns.len());
for (idx, wasm_value) in returns.into_iter().enumerate() {
raw_returns[idx] = wasm_value.as_raw();
}
ffi::WasmEdge_Result { Code: 0 }
}
Err(err) => match err {
HostFuncError::User(code) => unsafe {
ffi::WasmEdge_ResultGen(ffi::WasmEdge_ErrCategory_UserLevelError, code)
},
HostFuncError::Runtime(code) => unsafe {
ffi::WasmEdge_ResultGen(ffi::WasmEdge_ErrCategory_WASM, code)
},
},
assert!(result.is_ok());
let returns = result.unwrap();
assert_eq!(returns[0].to_i32(), 3);
}
}
23 changes: 7 additions & 16 deletions crates/wasmedge-sys/src/async/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2442,21 +2442,13 @@ impl async_wasi::snapshots::common::memory::Memory for Memory {
}
}

// #[cfg(test)]
#[cfg(ignore)]
#[cfg(test)]
mod tests {
use super::*;
use crate::{
r#async::fiber::AsyncState, Config, Executor, Loader, Store, Validator, WasiInstance,
};
use crate::{r#async::fiber::AsyncState, Executor, Loader, Store, Validator};

#[tokio::test]
async fn test_async_wasi_module() -> Result<(), Box<dyn std::error::Error>> {
// create a Config
let mut config = Config::create()?;
config.wasi(true);
assert!(config.wasi_enabled());

// create an Executor
let result = Executor::create(None, None);
assert!(result.is_ok());
Expand All @@ -2471,11 +2463,10 @@ mod tests {
// create an AsyncWasiModule
let result = AsyncWasiModule::create(Some(vec!["abc"]), Some(vec![("ENV", "1")]), None);
assert!(result.is_ok());
let async_wasi_module = result.unwrap();
let mut async_wasi_module = result.unwrap();

// register async_wasi module into the store
let wasi_import = WasiInstance::AsyncWasi(async_wasi_module);
let result = executor.register_wasi_instance(&mut store, &wasi_import);
let result = executor.register_import_module(&mut store, async_wasi_module.as_mut());
assert!(result.is_ok());

let wasm_file = std::env::current_dir()
Expand All @@ -2486,8 +2477,8 @@ mod tests {
.join("examples/wasmedge-sys/async_hello.wasm");
let module = Loader::create(None)?.from_file(&wasm_file)?;
Validator::create(None)?.validate(&module)?;
let instance = executor.register_active_module(&mut store, &module)?;
let fn_start = instance.get_func("_start")?;
let mut instance = executor.register_active_module(&mut store, &module)?;
let mut fn_start = instance.get_func_mut("_start")?;

async fn tick() {
let mut i = 0;
Expand All @@ -2501,7 +2492,7 @@ mod tests {

let async_state = AsyncState::new();
let _ = executor
.call_func_async(&async_state, &fn_start, [])
.call_func_async(&async_state, &mut fn_start, [])
.await?;

Ok(())
Expand Down
Loading

0 comments on commit 7f750bb

Please sign in to comment.