Skip to content

Commit fac9759

Browse files
committed
opt: optee-utee: switch LoadablePlugin unit tests to optee-utee-sys mock
1 parent 35e0568 commit fac9759

File tree

1 file changed

+120
-142
lines changed

1 file changed

+120
-142
lines changed

optee-utee/src/extension.rs

Lines changed: 120 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@
1616
// under the License.
1717

1818
use crate::{Error, ErrorKind, Result, Uuid};
19-
use optee_utee_sys as raw;
20-
#[cfg(not(feature = "std"))]
21-
use alloc::vec::Vec;
2219
#[cfg(not(feature = "std"))]
23-
use alloc::borrow::ToOwned;
20+
use alloc::{borrow::ToOwned, vec::Vec};
21+
use optee_utee_sys as raw;
2422

2523
pub struct LoadablePlugin {
26-
uuid: Uuid
24+
uuid: Uuid,
2725
}
2826

2927
pub struct LoadablePluginCommand<'a> {
@@ -35,7 +33,9 @@ pub struct LoadablePluginCommand<'a> {
3533

3634
impl LoadablePlugin {
3735
pub fn new(uuid: &Uuid) -> Self {
38-
Self { uuid: uuid.to_owned() }
36+
Self {
37+
uuid: uuid.to_owned(),
38+
}
3939
}
4040
/// Invoke plugin with given request data, use when you want to post something into REE.
4141
/// ``` rust,no_run
@@ -50,7 +50,7 @@ impl LoadablePlugin {
5050
/// # Ok(())
5151
/// # }
5252
/// ```
53-
/// Caution: the size of the shared buffer is set to the len of data, you could get a
53+
/// Caution: the size of the shared buffer is set to the len of data, you could get a
5454
/// ShortBuffer error if Plugin return more data than shared buffer, in that case,
5555
/// use invoke_with_capacity and set the capacity manually.
5656
pub fn invoke(&self, command_id: u32, subcommand_id: u32, data: &[u8]) -> Result<Vec<u8>> {
@@ -79,7 +79,7 @@ impl LoadablePlugin {
7979
/// ```no_run
8080
/// # use optee_utee::{LoadablePluginCommand, Uuid, LoadablePlugin, trace_println};
8181
/// # use optee_utee::ErrorKind;
82-
/// # fn main() -> optee_utee::Result<()> {
82+
/// # fn main() -> optee_utee::Result<()> {
8383
/// # let command_id = 0;
8484
/// # let subcommand_id = 0;
8585
/// # let capacity = 0;
@@ -178,44 +178,10 @@ impl<'a> LoadablePluginCommand<'a> {
178178
pub mod test_loadable_plugin {
179179
extern crate std;
180180
use super::*;
181-
use core::ffi::c_char;
182-
use once_cell::sync::Lazy;
183-
use optee_utee_sys::{TEE_Result, TEE_UUID};
181+
use alloc::string::ToString;
182+
use optee_utee_sys::{mock_api, mock_utils::SERIAL_TEST_LOCK};
184183
use rand::distributions::Alphanumeric;
185184
use rand::Rng;
186-
use std::collections::HashMap;
187-
use std::sync::RwLock;
188-
189-
static REE_RETURN_VALUES: RwLock<Lazy<HashMap<(u32, u32), Vec<u8>>>> =
190-
RwLock::new(Lazy::new(|| HashMap::new()));
191-
static REE_EXPECTED_VALUES: RwLock<Lazy<HashMap<(u32, u32), Vec<u8>>>> =
192-
RwLock::new(Lazy::new(|| HashMap::new()));
193-
194-
fn set_ree_return_value(cmd: u32, sub_cmd: u32, value: Vec<u8>) {
195-
let mut values = REE_RETURN_VALUES.write().unwrap();
196-
let key = (cmd, sub_cmd);
197-
assert!(!values.contains_key(&key));
198-
values.insert(key, value);
199-
}
200-
201-
fn set_ree_expected_value(cmd: u32, sub_cmd: u32, value: Vec<u8>) {
202-
let mut values = REE_EXPECTED_VALUES.write().unwrap();
203-
let key = (cmd, sub_cmd);
204-
assert!(!values.contains_key(&key));
205-
values.insert(key, value);
206-
}
207-
208-
fn get_ree_return_value(cmd: u32, sub_cmd: u32) -> Vec<u8> {
209-
let values = REE_RETURN_VALUES.read().unwrap();
210-
let key = (cmd, sub_cmd);
211-
values.get(&key).unwrap().to_owned()
212-
}
213-
214-
fn get_ree_expected_value(cmd: u32, sub_cmd: u32) -> Vec<u8> {
215-
let values = REE_EXPECTED_VALUES.read().unwrap();
216-
let key = (cmd, sub_cmd);
217-
values.get(&key).unwrap().to_owned()
218-
}
219185

220186
fn generate_random_bytes(len: usize) -> Vec<u8> {
221187
rand::thread_rng()
@@ -228,119 +194,129 @@ pub mod test_loadable_plugin {
228194
request_size: usize,
229195
response_size: usize,
230196
) -> (u32, u32, Vec<u8>, Vec<u8>) {
231-
let cmd: u32 = rand::thread_rng().r#gen();
232-
let sub_cmd: u32 = rand::thread_rng().r#gen();
197+
let cmd: u32 = rand::random();
198+
let sub_cmd: u32 = rand::random();
233199
let random_request: Vec<u8> = generate_random_bytes(request_size);
234200
let random_response: Vec<u8> = generate_random_bytes(response_size);
235201
(cmd, sub_cmd, random_request, random_response)
236202
}
237203

238-
#[no_mangle]
239-
extern "C" fn tee_invoke_supp_plugin(
240-
_uuid: *const TEE_UUID,
241-
cmd: u32,
242-
sub_cmd: u32,
243-
buf: *mut c_char,
244-
len: usize,
245-
outlen: *mut usize,
246-
) -> TEE_Result {
247-
// must convert buf to u8, for in some platform c_char was treated as i8
248-
let inbuf = unsafe { core::slice::from_raw_parts_mut(buf as *mut u8, len) };
249-
std::println!(
250-
"*plugin*: receive value: {:?} length {:?}",
251-
inbuf,
252-
inbuf.len()
253-
);
254-
let expected_value = get_ree_expected_value(cmd, sub_cmd);
255-
assert_eq!(inbuf, expected_value.as_slice());
256-
257-
let return_value = get_ree_return_value(cmd, sub_cmd);
258-
assert!(return_value.len() <= len);
259-
std::println!("*plugin*: write value '{:?}' to buffer", return_value);
204+
fn random_uuid() -> Uuid {
205+
Uuid::new_raw(
206+
rand::random(),
207+
rand::random(),
208+
rand::random(),
209+
rand::random(),
210+
)
211+
}
260212

261-
inbuf[0..return_value.len()].copy_from_slice(&return_value);
262-
unsafe {
263-
*outlen = return_value.len();
264-
}
265-
return raw::TEE_SUCCESS;
213+
fn expect_success_request(
214+
ctx: &mock_api::extension::__tee_invoke_supp_plugin::Context,
215+
exp_uuid: &Uuid,
216+
exp_cmd: u32,
217+
exp_sub_cmd: u32,
218+
exp_request: &[u8],
219+
exp_response: &[u8],
220+
) {
221+
let exp_request = exp_request.to_vec();
222+
let exp_response = exp_response.to_vec();
223+
let exp_uuid = exp_uuid.to_string();
224+
ctx.expect()
225+
.return_once_st(move |uuid, cmd, sub_cmd, buf, len, outlen| {
226+
let request_uuid = Uuid::from(unsafe { *uuid }).to_string();
227+
debug_assert_eq!(exp_uuid, request_uuid);
228+
debug_assert_eq!(cmd, exp_cmd);
229+
debug_assert_eq!(sub_cmd, exp_sub_cmd);
230+
debug_assert_eq!(
231+
unsafe { core::slice::from_raw_parts(buf as *mut u8, exp_request.len()) },
232+
exp_request.as_slice()
233+
);
234+
debug_assert!(len >= exp_response.len());
235+
let buffer: &mut [u8] =
236+
unsafe { core::slice::from_raw_parts_mut(buf as *mut u8, len) };
237+
buffer[0..exp_response.len()].copy_from_slice(&exp_response);
238+
unsafe { *outlen = exp_response.len() };
239+
raw::TEE_SUCCESS
240+
});
266241
}
267242

268243
#[test]
269244
fn test_invoke() {
270-
let plugin = LoadablePlugin {
271-
uuid: Uuid::parse_str("7dd54ee6-a705-4e4d-8b6b-aa5024dfcd10").unwrap(),
272-
};
245+
let _lock = SERIAL_TEST_LOCK.lock().expect("should get the lock");
246+
247+
let uuid: Uuid = random_uuid();
248+
let plugin = LoadablePlugin::new(&uuid);
273249
const REQUEST_LEN: usize = 32;
250+
let run_test = |request_size: usize, response_size: usize| {
251+
let (cmd, sub_cmd, request, exp_response) =
252+
generate_test_pairs(request_size, response_size);
253+
let fn1 = mock_api::extension::tee_invoke_supp_plugin_context();
254+
expect_success_request(&fn1, &uuid, cmd, sub_cmd, &request, &exp_response);
255+
let response = plugin.invoke(cmd, sub_cmd, &request).expect("should be ok");
256+
std::println!("*TA*: response is {:?}", response);
257+
debug_assert_eq!(response, exp_response);
258+
};
274259

275260
// test calling with output size less than input
276-
let (cmd, sub_cmd, request, exp_response) =
277-
generate_test_pairs(REQUEST_LEN, REQUEST_LEN / 2);
278-
set_ree_expected_value(cmd, sub_cmd, request.clone());
279-
set_ree_return_value(cmd, sub_cmd, exp_response.clone());
280-
let response = plugin.invoke(cmd, sub_cmd, &request).unwrap();
281-
std::println!("*TA*: response is {:?}", response);
282-
assert_eq!(response, exp_response);
283-
261+
run_test(REQUEST_LEN, REQUEST_LEN / 2);
284262
// test calling with output size equals to input
285-
let (cmd, sub_cmd, request, exp_response) = generate_test_pairs(REQUEST_LEN, REQUEST_LEN);
286-
set_ree_expected_value(cmd, sub_cmd, request.clone());
287-
set_ree_return_value(cmd, sub_cmd, exp_response.clone());
288-
let response = plugin.invoke(cmd, sub_cmd, &request).unwrap();
289-
std::println!("*TA*: response is {:?}", response);
290-
assert_eq!(response, exp_response);
263+
run_test(REQUEST_LEN, REQUEST_LEN);
264+
// test calling with output size greater than input.
265+
// Mark: Without explicitly setting the response size, this function
266+
// must not be called with a response size larger than the request size.
267+
{
268+
let (cmd, sub_cmd, request, exp_response) =
269+
generate_test_pairs(REQUEST_LEN, 2 * REQUEST_LEN);
270+
let fn1 = mock_api::extension::tee_invoke_supp_plugin_context();
271+
fn1.expect().return_once_st(move |_, _, _, _, _, outlen| {
272+
unsafe { *outlen = exp_response.len() };
273+
raw::TEE_SUCCESS
274+
});
275+
let err = plugin
276+
.invoke(cmd, sub_cmd, &request)
277+
.expect_err("should be err");
278+
debug_assert_eq!(err.kind(), ErrorKind::ShortBuffer);
279+
}
291280
}
292281

282+
// This test is equivalent to test_invoke, with the added verification that
283+
// capacity permits the response size to be larger than the request.
293284
#[test]
294285
fn test_invoke_with_capacity() {
295-
let plugin = LoadablePlugin {
296-
uuid: Uuid::parse_str("7dd54ee6-a705-4e4d-8b6b-aa5024dfcd10").unwrap(),
297-
};
286+
let _lock = SERIAL_TEST_LOCK.lock().expect("should get the lock");
287+
let uuid: Uuid = random_uuid();
288+
let plugin = LoadablePlugin::new(&uuid);
298289
const RESPONSE_LEN: usize = 32;
299290

300-
// test calling with output size less than input
301-
let (cmd, sub_cmd, request, exp_response) =
302-
generate_test_pairs(2 * RESPONSE_LEN, RESPONSE_LEN);
303-
set_ree_expected_value(cmd, sub_cmd, request.clone());
304-
set_ree_return_value(cmd, sub_cmd, exp_response.clone());
305-
let response = plugin
306-
.invoke_with_capacity(cmd, sub_cmd, exp_response.len())
307-
.chain_write_body(&request)
308-
.call()
309-
.unwrap();
310-
std::println!("*TA*: response is {:?}", response);
311-
assert_eq!(response, exp_response);
291+
let run_test = |request_size: usize, response_size: usize| {
292+
let (cmd, sub_cmd, request, exp_response) =
293+
generate_test_pairs(request_size, response_size);
294+
let fn1 = mock_api::extension::tee_invoke_supp_plugin_context();
295+
expect_success_request(&fn1, &uuid, cmd, sub_cmd, &request, &exp_response);
312296

313-
// test calling with output size equals to input
314-
let (cmd, sub_cmd, request, exp_response) = generate_test_pairs(RESPONSE_LEN, RESPONSE_LEN);
315-
set_ree_expected_value(cmd, sub_cmd, request.clone());
316-
set_ree_return_value(cmd, sub_cmd, exp_response.clone());
317-
let response = plugin
318-
.invoke_with_capacity(cmd, sub_cmd, exp_response.len())
319-
.chain_write_body(&request)
320-
.call()
321-
.unwrap();
322-
std::println!("*TA*: response is {:?}", response);
323-
assert_eq!(response, exp_response);
297+
let response = plugin
298+
.invoke_with_capacity(cmd, sub_cmd, exp_response.len())
299+
.chain_write_body(&request)
300+
.call()
301+
.unwrap();
302+
std::println!("*TA*: response is {:?}", response);
303+
debug_assert_eq!(response, exp_response);
304+
};
324305

306+
// test calling with output size less than input
307+
run_test(2 * RESPONSE_LEN, RESPONSE_LEN);
308+
// test calling with output size equals to input
309+
run_test(RESPONSE_LEN, RESPONSE_LEN);
325310
// test calling with output size greater than input
326-
let (cmd, sub_cmd, mut request, exp_response) =
327-
generate_test_pairs(RESPONSE_LEN / 2, RESPONSE_LEN);
328-
request.resize(exp_response.len(), 0);
329-
set_ree_expected_value(cmd, sub_cmd, request.clone());
330-
set_ree_return_value(cmd, sub_cmd, exp_response.clone());
331-
let response = plugin
332-
.invoke_with_capacity(cmd, sub_cmd, exp_response.len())
333-
.chain_write_body(&request)
334-
.call()
335-
.unwrap();
336-
std::println!("*TA*: response is {:?}", response);
337-
assert_eq!(response, exp_response);
311+
run_test(RESPONSE_LEN / 2, RESPONSE_LEN);
338312
}
313+
339314
#[test]
340315
fn test_invoke_with_writer() {
341-
let plugin = LoadablePlugin {
342-
uuid: Uuid::parse_str("7dd54ee6-a705-4e4d-8b6b-aa5024dfcd10").unwrap(),
343-
};
316+
let _lock = SERIAL_TEST_LOCK.lock().expect("should get the lock");
317+
let uuid: Uuid = random_uuid();
318+
let plugin = LoadablePlugin::new(&uuid);
319+
let fn1 = mock_api::extension::tee_invoke_supp_plugin_context();
344320
// impl a writer for Command
345321
struct Wrapper<'a, 'b>(&'b mut LoadablePluginCommand<'a>);
346322
impl<'a, 'b> std::io::Write for Wrapper<'a, 'b> {
@@ -362,28 +338,30 @@ pub mod test_loadable_plugin {
362338
let (cmd, sub_cmd, _, exp_response) = generate_test_pairs(0, buffer_len);
363339
let mut plugin_cmd = plugin.invoke_with_capacity(cmd, sub_cmd, buffer_len);
364340
exp_request.resize(exp_response.len(), 0);
365-
set_ree_expected_value(cmd, sub_cmd, exp_request);
366-
set_ree_return_value(cmd, sub_cmd, exp_response.clone());
341+
342+
expect_success_request(&fn1, &uuid, cmd, sub_cmd, &exp_request, &exp_response);
367343
serde_json::to_writer(Wrapper(&mut plugin_cmd), &test_data).unwrap();
368344
let response = plugin_cmd.call().unwrap();
369345
std::println!("*TA*: response is {:?}", response);
370-
assert_eq!(response, exp_response);
346+
debug_assert_eq!(response, exp_response);
371347
}
348+
372349
#[test]
373350
fn test_invoke_with_no_data() {
374-
let plugin = LoadablePlugin {
375-
uuid: Uuid::parse_str("7dd54ee6-a705-4e4d-8b6b-aa5024dfcd10").unwrap(),
376-
};
351+
let _lock = SERIAL_TEST_LOCK.lock().expect("should get the lock");
352+
353+
let uuid: Uuid = random_uuid();
354+
let plugin = LoadablePlugin::new(&uuid);
355+
let fn1 = mock_api::extension::tee_invoke_supp_plugin_context();
377356
const OUTPUT_LEN: usize = 50;
378-
let (cmd, sub_cmd, _, exp_response) = generate_test_pairs(0, OUTPUT_LEN);
379-
let exp_request = vec![0_u8; OUTPUT_LEN];
380-
set_ree_expected_value(cmd, sub_cmd, exp_request);
381-
set_ree_return_value(cmd, sub_cmd, exp_response.clone());
357+
let (cmd, sub_cmd, request, exp_response) = generate_test_pairs(0, OUTPUT_LEN);
358+
expect_success_request(&fn1, &uuid, cmd, sub_cmd, &request, &exp_response);
359+
382360
let response = plugin
383361
.invoke_with_capacity(cmd, sub_cmd, OUTPUT_LEN)
384362
.call()
385363
.unwrap();
386364
std::println!("*TA*: response is {:?}", response);
387-
assert_eq!(response, exp_response);
365+
debug_assert_eq!(response, exp_response);
388366
}
389367
}

0 commit comments

Comments
 (0)