enclave_runner/
builder.rs1use std::convert::TryInto;
8
9use crate::Command;
10use crate::platform::*;
11use crate::stream_router::{StreamRouter, OsStreamRouter};
12
13pub struct EnclaveBuilder<P: EnclavePlatform<T>, T: EnclaveType> {
14 platform: P,
15 stream_router: Option<Box<dyn StreamRouter + Send + Sync>>,
16 forward_panics: bool,
17 type_builder: T::ConfigurationBuilder,
18}
19
20impl<P: EnclavePlatform<T>, T: EnclaveType> EnclaveBuilder<P, T> {
21 pub fn new(platform: P) -> Self {
22 EnclaveBuilder {
23 platform,
24 stream_router: None,
25 forward_panics: false,
26 type_builder: Default::default(),
27 }
28 }
29
30 pub fn stream_router<R: Into<Box<dyn StreamRouter + Send + Sync>>>(&mut self, router: R) -> &mut Self {
33 self.stream_router = Some(router.into());
34 self
35 }
36
37 pub fn forward_panics(&mut self, fp: bool) -> &mut Self {
43 self.forward_panics = fp;
44 self
45 }
46
47 pub fn build(self, loader: P::Loader) -> Result<T, anyhow::Error> {
48 let configuration = EnclaveConfiguration {
49 stream_router: self.stream_router.unwrap_or_else(|| OsStreamRouter::new()),
50 forward_panics: self.forward_panics,
51 };
52 self.platform.build(loader, configuration, self.type_builder.try_into()?)
53 }
54}
55
56impl<P: EnclavePlatform<Command>> EnclaveBuilder<P, Command> where {
57 pub fn args<I, S>(&mut self, args: I) -> &mut Self
61 where
62 I: IntoIterator<Item = S>,
63 S: AsRef<[u8]>,
64 {
65 let args = args.into_iter().map(|a| a.as_ref().to_owned());
66 self.type_builder.cmd_args.extend(args);
67 self
68 }
69
70 pub fn arg<S: AsRef<[u8]>>(&mut self, arg: S) -> &mut Self {
74 let arg = arg.as_ref().to_owned();
75 self.type_builder.cmd_args.push(arg);
76 self
77 }
78
79 pub fn num_worker_threads(&mut self, num_worker_threads: usize) -> &mut Self {
81 self.type_builder.num_worker_threads = Some(num_worker_threads);
82 self
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use test_case::test_case;
90
91 struct TestEnclaveBuilder(Vec<String>);
92
93 impl EnclavePlatform<Command> for TestEnclaveBuilder {
94 type Loader = ();
95
96 fn build(
97 self,
98 _loader: Self::Loader,
99 _configuration: EnclaveConfiguration,
100 cmd_configuration: CommandConfiguration,
101 ) -> Result<Command, anyhow::Error> {
102 let f = Box::new(move || {
103 let enclave_args = cmd_configuration
104 .cmd_args
105 .into_iter()
106 .map(|arr| String::from_utf8(arr))
107 .collect::<Result<Vec<_>, _>>()?;
108 assert_eq!(
109 self.0, enclave_args,
110 "{:?} differs from expected: {:?}",
111 enclave_args, self.0
112 );
113 Ok(())
114 }) as Box<dyn FnOnce() -> _>;
115 Ok(f.into())
116 }
117 }
118
119 #[test_case(vec![]; "empty")]
120 #[test_case(vec!["--arg1".to_owned(), "--arg2".to_owned()]; "with args")]
121 fn test_enclave_args(args: Vec<String>) {
122 let mut expected = vec!["enclave".to_owned()];
123 expected.extend_from_slice(&args[..]);
124 let enclave_builder = TestEnclaveBuilder(expected);
125 let mut enclave_builder = EnclaveBuilder::new(enclave_builder);
126 enclave_builder.args(args);
127 enclave_builder.build(()).unwrap().run().unwrap();
128 }
129}