Skip to content

Commit 815cb5b

Browse files
committed
tmp
Signed-off-by: danbugs <[email protected]>
1 parent 04e8e96 commit 815cb5b

20 files changed

+2326
-3412
lines changed

Justfile

+16
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@ clean-rust:
6060
### TESTING ####
6161
################
6262

63+
# run full CI test matrix
64+
test-ci config=default-target hypervisor="kvm":
65+
@# with default features
66+
just test {{config}} {{ if hypervisor == "mshv3" {"mshv3"} else {""} }}
67+
68+
@# with only one driver enabled + seccomp + inprocess
69+
just test {{config}} inprocess,seccomp,{{ if hypervisor == "mshv" {"mshv2"} else if hypervisor == "mshv3" {"mshv3"} else {"kvm"} }}
70+
71+
@# make sure certain cargo features compile
72+
cargo check -p hyperlight-host --features crashdump
73+
cargo check -p hyperlight-host --features print_debug
74+
cargo check -p hyperlight-host --features gdb
75+
76+
@# without any driver (should fail to compile)
77+
just test-compilation-fail {{config}}
78+
6379
# Note: most testing recipes take an optional "features" comma separated list argument. If provided, these will be passed to cargo as **THE ONLY FEATURES**, i.e. default features will be disabled.
6480

6581
# runs all tests

src/hyperlight_host/src/func/call_ctx.rs

+160-160
Original file line numberDiff line numberDiff line change
@@ -104,163 +104,163 @@ impl MultiUseGuestCallContext {
104104
}
105105
}
106106

107-
// TODO(danbugs:297): bring back
108-
// #[cfg(test)]
109-
// mod tests {
110-
// use std::sync::mpsc::sync_channel;
111-
// use std::thread::{self, JoinHandle};
112-
//
113-
// use hyperlight_common::flatbuffer_wrappers::function_types::{
114-
// ParameterValue, ReturnType, ReturnValue,
115-
// };
116-
// use hyperlight_testing::simple_guest_as_string;
117-
//
118-
// use crate::sandbox_state::sandbox::EvolvableSandbox;
119-
// use crate::sandbox_state::transition::Noop;
120-
// use crate::{GuestBinary, HyperlightError, MultiUseSandbox, Result, UninitializedSandbox};
121-
//
122-
// fn new_uninit() -> Result<UninitializedSandbox> {
123-
// let path = simple_guest_as_string().map_err(|e| {
124-
// HyperlightError::Error(format!("failed to get simple guest path ({e:?})"))
125-
// })?;
126-
// UninitializedSandbox::new(GuestBinary::FilePath(path), None, None, None)
127-
// }
128-
//
129-
// /// Test to create a `MultiUseSandbox`, then call several guest functions
130-
// /// on it across different threads.
131-
// ///
132-
// /// This test works by passing messages between threads using Rust's
133-
// /// [mpsc crate](https://doc.rust-lang.org/std/sync/mpsc). Details of this
134-
// /// interaction are as follows.
135-
// ///
136-
// /// One thread acts as the receiver (AKA: consumer) and owns the
137-
// /// `MultiUseSandbox`. This receiver fields requests from N senders
138-
// /// (AKA: producers) to make batches of calls.
139-
// ///
140-
// /// Upon receipt of a message to execute a batch, a new
141-
// /// `MultiUseGuestCallContext` is created in the receiver thread from the
142-
// /// existing `MultiUseSandbox`, and the batch is executed.
143-
// ///
144-
// /// After the batch is complete, the `MultiUseGuestCallContext` is done
145-
// /// and it is converted back to the underlying `MultiUseSandbox`
146-
// #[test]
147-
// fn test_multi_call_multi_thread() {
148-
// let (snd, recv) = sync_channel::<Vec<TestFuncCall>>(0);
149-
//
150-
// // create new receiver thread and on it, begin listening for
151-
// // requests to execute batches of calls
152-
// let recv_hdl = thread::spawn(move || {
153-
// let mut sbox: MultiUseSandbox = new_uninit().unwrap().evolve(Noop::default()).unwrap();
154-
// while let Ok(calls) = recv.recv() {
155-
// let mut ctx = sbox.new_call_context();
156-
// for call in calls {
157-
// let res = ctx
158-
// .call(call.func_name.as_str(), call.ret_type, call.params)
159-
// .unwrap();
160-
// assert_eq!(call.expected_ret, res);
161-
// }
162-
// sbox = ctx.finish().unwrap();
163-
// }
164-
// });
165-
//
166-
// // create new sender threads
167-
// let send_handles: Vec<JoinHandle<()>> = (0..10)
168-
// .map(|i| {
169-
// let sender = snd.clone();
170-
// thread::spawn(move || {
171-
// let calls: Vec<TestFuncCall> = vec![
172-
// TestFuncCall {
173-
// func_name: "Echo".to_string(),
174-
// ret_type: ReturnType::String,
175-
// params: Some(vec![ParameterValue::String(
176-
// format!("Hello {}", i).to_string(),
177-
// )]),
178-
// expected_ret: ReturnValue::String(format!("Hello {}", i).to_string()),
179-
// },
180-
// TestFuncCall {
181-
// func_name: "CallMalloc".to_string(),
182-
// ret_type: ReturnType::Int,
183-
// params: Some(vec![ParameterValue::Int(i + 2)]),
184-
// expected_ret: ReturnValue::Int(i + 2),
185-
// },
186-
// ];
187-
// sender.send(calls).unwrap();
188-
// })
189-
// })
190-
// .collect();
191-
//
192-
// for hdl in send_handles {
193-
// hdl.join().unwrap();
194-
// }
195-
// // after all sender threads are done, drop the sender itself
196-
// // so the receiver thread can exit. then, ensure the receiver
197-
// // thread has exited.
198-
// drop(snd);
199-
// recv_hdl.join().unwrap();
200-
// }
201-
//
202-
// pub struct TestSandbox {
203-
// sandbox: MultiUseSandbox,
204-
// }
205-
//
206-
// impl TestSandbox {
207-
// pub fn new() -> Self {
208-
// let sbox: MultiUseSandbox = new_uninit().unwrap().evolve(Noop::default()).unwrap();
209-
// Self { sandbox: sbox }
210-
// }
211-
// pub fn call_add_to_static_multiple_times(mut self, i: i32) -> Result<TestSandbox> {
212-
// let mut ctx = self.sandbox.new_call_context();
213-
// let mut sum: i32 = 0;
214-
// for n in 0..i {
215-
// let result = ctx.call(
216-
// "AddToStatic",
217-
// ReturnType::Int,
218-
// Some(vec![ParameterValue::Int(n)]),
219-
// );
220-
// sum += n;
221-
// println!("{:?}", result);
222-
// let result = result.unwrap();
223-
// assert_eq!(result, ReturnValue::Int(sum));
224-
// }
225-
// let result = ctx.finish();
226-
// assert!(result.is_ok());
227-
// self.sandbox = result.unwrap();
228-
// Ok(self)
229-
// }
230-
//
231-
// pub fn call_add_to_static(mut self, i: i32) -> Result<()> {
232-
// for n in 0..i {
233-
// let result = self.sandbox.call_guest_function_by_name(
234-
// "AddToStatic",
235-
// ReturnType::Int,
236-
// Some(vec![ParameterValue::Int(n)]),
237-
// );
238-
// println!("{:?}", result);
239-
// let result = result.unwrap();
240-
// assert_eq!(result, ReturnValue::Int(n));
241-
// }
242-
// Ok(())
243-
// }
244-
// }
245-
//
246-
// #[test]
247-
// fn ensure_multiusesandbox_multi_calls_dont_reset_state() {
248-
// let sandbox = TestSandbox::new();
249-
// let result = sandbox.call_add_to_static_multiple_times(5);
250-
// assert!(result.is_ok());
251-
// }
252-
//
253-
// #[test]
254-
// fn ensure_multiusesandbox_single_calls_do_reset_state() {
255-
// let sandbox = TestSandbox::new();
256-
// let result = sandbox.call_add_to_static(5);
257-
// assert!(result.is_ok());
258-
// }
259-
//
260-
// struct TestFuncCall {
261-
// func_name: String,
262-
// ret_type: ReturnType,
263-
// params: Option<Vec<ParameterValue>>,
264-
// expected_ret: ReturnValue,
265-
// }
266-
// }
107+
#[cfg(test)]
108+
mod tests {
109+
use std::sync::mpsc::sync_channel;
110+
use std::thread::{self, JoinHandle};
111+
112+
use hyperlight_common::flatbuffer_wrappers::function_types::{
113+
ParameterValue, ReturnType, ReturnValue,
114+
};
115+
use hyperlight_testing::simple_guest_as_string;
116+
117+
use crate::sandbox::sandbox_builder::SandboxBuilder;
118+
use crate::sandbox_state::sandbox::EvolvableSandbox;
119+
use crate::sandbox_state::transition::Noop;
120+
use crate::{GuestBinary, MultiUseSandbox, Result, UninitializedSandbox};
121+
122+
fn new_uninit() -> Result<UninitializedSandbox> {
123+
let sandbox_builder =
124+
SandboxBuilder::new(GuestBinary::FilePath(simple_guest_as_string()?))?;
125+
126+
sandbox_builder.build()
127+
}
128+
129+
/// Test to create a `MultiUseSandbox`, then call several guest functions
130+
/// on it across different threads.
131+
///
132+
/// This test works by passing messages between threads using Rust's
133+
/// [mpsc crate](https://doc.rust-lang.org/std/sync/mpsc). Details of this
134+
/// interaction are as follows.
135+
///
136+
/// One thread acts as the receiver (AKA: consumer) and owns the
137+
/// `MultiUseSandbox`. This receiver fields requests from N senders
138+
/// (AKA: producers) to make batches of calls.
139+
///
140+
/// Upon receipt of a message to execute a batch, a new
141+
/// `MultiUseGuestCallContext` is created in the receiver thread from the
142+
/// existing `MultiUseSandbox`, and the batch is executed.
143+
///
144+
/// After the batch is complete, the `MultiUseGuestCallContext` is done
145+
/// and it is converted back to the underlying `MultiUseSandbox`
146+
#[test]
147+
fn test_multi_call_multi_thread() {
148+
let (snd, recv) = sync_channel::<Vec<TestFuncCall>>(0);
149+
150+
// create new receiver thread and on it, begin listening for
151+
// requests to execute batches of calls
152+
let recv_hdl = thread::spawn(move || {
153+
let mut sbox: MultiUseSandbox = new_uninit().unwrap().evolve(Noop::default()).unwrap();
154+
while let Ok(calls) = recv.recv() {
155+
let mut ctx = sbox.new_call_context();
156+
for call in calls {
157+
let res = ctx
158+
.call(call.func_name.as_str(), call.ret_type, call.params)
159+
.unwrap();
160+
assert_eq!(call.expected_ret, res);
161+
}
162+
sbox = ctx.finish().unwrap();
163+
}
164+
});
165+
166+
// create new sender threads
167+
let send_handles: Vec<JoinHandle<()>> = (0..10)
168+
.map(|i| {
169+
let sender = snd.clone();
170+
thread::spawn(move || {
171+
let calls: Vec<TestFuncCall> = vec![
172+
TestFuncCall {
173+
func_name: "Echo".to_string(),
174+
ret_type: ReturnType::String,
175+
params: Some(vec![ParameterValue::String(
176+
format!("Hello {}", i).to_string(),
177+
)]),
178+
expected_ret: ReturnValue::String(format!("Hello {}", i).to_string()),
179+
},
180+
TestFuncCall {
181+
func_name: "CallMalloc".to_string(),
182+
ret_type: ReturnType::Int,
183+
params: Some(vec![ParameterValue::Int(i + 2)]),
184+
expected_ret: ReturnValue::Int(i + 2),
185+
},
186+
];
187+
sender.send(calls).unwrap();
188+
})
189+
})
190+
.collect();
191+
192+
for hdl in send_handles {
193+
hdl.join().unwrap();
194+
}
195+
// after all sender threads are done, drop the sender itself
196+
// so the receiver thread can exit. then, ensure the receiver
197+
// thread has exited.
198+
drop(snd);
199+
recv_hdl.join().unwrap();
200+
}
201+
202+
pub struct TestSandbox {
203+
sandbox: MultiUseSandbox,
204+
}
205+
206+
impl TestSandbox {
207+
pub fn new() -> Self {
208+
let sbox: MultiUseSandbox = new_uninit().unwrap().evolve(Noop::default()).unwrap();
209+
Self { sandbox: sbox }
210+
}
211+
pub fn call_add_to_static_multiple_times(mut self, i: i32) -> Result<TestSandbox> {
212+
let mut ctx = self.sandbox.new_call_context();
213+
let mut sum: i32 = 0;
214+
for n in 0..i {
215+
let result = ctx.call(
216+
"AddToStatic",
217+
ReturnType::Int,
218+
Some(vec![ParameterValue::Int(n)]),
219+
);
220+
sum += n;
221+
println!("{:?}", result);
222+
let result = result.unwrap();
223+
assert_eq!(result, ReturnValue::Int(sum));
224+
}
225+
let result = ctx.finish();
226+
assert!(result.is_ok());
227+
self.sandbox = result.unwrap();
228+
Ok(self)
229+
}
230+
231+
pub fn call_add_to_static(mut self, i: i32) -> Result<()> {
232+
for n in 0..i {
233+
let result = self.sandbox.call_guest_function_by_name(
234+
"AddToStatic",
235+
ReturnType::Int,
236+
Some(vec![ParameterValue::Int(n)]),
237+
);
238+
println!("{:?}", result);
239+
let result = result.unwrap();
240+
assert_eq!(result, ReturnValue::Int(n));
241+
}
242+
Ok(())
243+
}
244+
}
245+
246+
#[test]
247+
fn ensure_multiusesandbox_multi_calls_dont_reset_state() {
248+
let sandbox = TestSandbox::new();
249+
let result = sandbox.call_add_to_static_multiple_times(5);
250+
assert!(result.is_ok());
251+
}
252+
253+
#[test]
254+
fn ensure_multiusesandbox_single_calls_do_reset_state() {
255+
let sandbox = TestSandbox::new();
256+
let result = sandbox.call_add_to_static(5);
257+
assert!(result.is_ok());
258+
}
259+
260+
struct TestFuncCall {
261+
func_name: String,
262+
ret_type: ReturnType,
263+
params: Option<Vec<ParameterValue>>,
264+
expected_ret: ReturnValue,
265+
}
266+
}

0 commit comments

Comments
 (0)