You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by ms...@apache.org on 2020/03/23 21:25:09 UTC
[incubator-teaclave] branch develop updated: [tests] Add functional
test for execution service
This is an automated email from the ASF dual-hosted git repository.
mssun pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git
The following commit(s) were added to refs/heads/develop by this push:
new 9536e52 [tests] Add functional test for execution service
9536e52 is described below
commit 9536e527d0d0ee7d02bcb8629b262326bf4b7768
Author: Mingshen Sun <bo...@mssun.me>
AuthorDate: Mon Mar 23 11:57:55 2020 -0700
[tests] Add functional test for execution service
---
binder/src/proto.rs | 12 +++-
cmake/scripts/test.sh | 22 +++++-
services/execution/enclave/src/service.rs | 8 +++
tests/functional/app/Cargo.toml | 1 +
tests/functional/app/src/main.rs | 22 +++---
tests/functional/enclave/src/execution_service.rs | 82 +++++++++++++++++++++++
tests/functional/enclave/src/lib.rs | 49 +++++++++++---
tests/integration/app/src/main.rs | 3 +-
tests/unit/app/src/main.rs | 3 +-
types/src/worker.rs | 2 +-
10 files changed, 177 insertions(+), 27 deletions(-)
diff --git a/binder/src/proto.rs b/binder/src/proto.rs
index e08b19c..95e103a 100644
--- a/binder/src/proto.rs
+++ b/binder/src/proto.rs
@@ -79,8 +79,16 @@ pub struct FinalizeEnclaveInput;
#[derive(Serialize, Deserialize, Debug)]
pub struct FinalizeEnclaveOutput;
-#[derive(Serialize, Deserialize, Debug)]
-pub struct RunTestInput;
+#[derive(Default, Serialize, Deserialize, Debug)]
+pub struct RunTestInput {
+ pub test_names: Vec<String>,
+}
+
+impl RunTestInput {
+ pub fn new(test_names: Vec<String>) -> Self {
+ Self { test_names }
+ }
+}
#[derive(Serialize, Deserialize, Debug)]
pub struct RunTestOutput;
diff --git a/cmake/scripts/test.sh b/cmake/scripts/test.sh
index c903ea9..c9ef7e8 100755
--- a/cmake/scripts/test.sh
+++ b/cmake/scripts/test.sh
@@ -59,7 +59,7 @@ run_integration_tests() {
popd
- cleanup
+ cleanup
}
run_functional_tests() {
@@ -77,11 +77,27 @@ run_functional_tests() {
sleep 3 # wait for management service and scheduler_service
./teaclave_access_control_service &
./teaclave_frontend_service &
- # ./teaclave_execution_service &
popd
sleep 3 # wait for other services
- ./teaclave_functional_tests
+ # Run function tests for all except execution service
+ ./teaclave_functional_tests -t \
+ access_control_service \
+ authentication_service \
+ frontend_service \
+ management_service \
+ scheduler_service \
+ storage_service
+
+ # Run tests of execution service separately
+ pushd ${TEACLAVE_SERVICE_INSTALL_DIR}
+ ./teaclave_execution_service &
+ popd
+ sleep 3 # wait for execution services
+
+ ./teaclave_functional_tests -t execution_service
+
+ # Run script tests
./scripts/functional_tests.py -v
popd
diff --git a/services/execution/enclave/src/service.rs b/services/execution/enclave/src/service.rs
index d3a3c00..5cae334 100644
--- a/services/execution/enclave/src/service.rs
+++ b/services/execution/enclave/src/service.rs
@@ -27,6 +27,7 @@ use teaclave_types::{ExecutionResult, StagedFunction, StagedTask, TaskStatus};
use teaclave_worker::Worker;
use anyhow::Result;
+use log::debug;
use uuid::Uuid;
#[derive(Clone)]
@@ -77,9 +78,12 @@ impl TeaclaveExecutionService {
continue;
}
};
+ drop(client); // drop mutex guard
+
log::debug!("response: {:?}", response);
let staged_task = response.staged_task;
let result = self.invoke_task(&staged_task).unwrap();
+ debug!("result: {:?}", result);
match self.update_task_status(&staged_task.task_id, TaskStatus::Finished) {
Ok(_) => (),
Err(e) => {
@@ -98,10 +102,12 @@ impl TeaclaveExecutionService {
}
fn invoke_task(&mut self, task: &StagedTask) -> Result<ExecutionResult> {
+ debug!("invoke_task");
self.update_task_status(&task.task_id, TaskStatus::Running)?;
let invocation = prepare_task(&task);
let worker = Worker::default();
let summary = worker.invoke_function(invocation)?;
+ debug!("summary: {:?}", summary);
finalize_task(&task)?;
let mut result = ExecutionResult::default();
result.return_value = summary.as_bytes().to_vec();
@@ -110,6 +116,7 @@ impl TeaclaveExecutionService {
}
fn update_task_result(&mut self, task_id: &Uuid, result: ExecutionResult) -> Result<()> {
+ debug!("update_task_result");
let request = UpdateTaskResultRequest::new(
task_id.to_owned(),
&result.return_value,
@@ -126,6 +133,7 @@ impl TeaclaveExecutionService {
}
fn update_task_status(&mut self, task_id: &Uuid, task_status: TaskStatus) -> Result<()> {
+ debug!("update_task_status");
let request = UpdateTaskStatusRequest::new(task_id.to_owned(), task_status);
let _response = self
.scheduler_client
diff --git a/tests/functional/app/Cargo.toml b/tests/functional/app/Cargo.toml
index 727a438..e059327 100644
--- a/tests/functional/app/Cargo.toml
+++ b/tests/functional/app/Cargo.toml
@@ -11,6 +11,7 @@ edition = "2018"
log = { version = "0.4.6" }
env_logger = { version = "0.7.1" }
anyhow = { version = "1.0.26" }
+structopt = { version = "0.3" }
teaclave_binder = { path = "../../../binder", features = ["app"] }
teaclave_types = { path = "../../../types" }
diff --git a/tests/functional/app/src/main.rs b/tests/functional/app/src/main.rs
index 95b545f..f3c50ab 100644
--- a/tests/functional/app/src/main.rs
+++ b/tests/functional/app/src/main.rs
@@ -17,22 +17,32 @@
use anyhow;
use log::error;
+use structopt::StructOpt;
use teaclave_binder::proto::{ECallCommand, RunTestInput, RunTestOutput};
use teaclave_binder::TeeBinder;
use teaclave_types::TeeServiceResult;
+#[derive(Debug, StructOpt)]
+struct Cli {
+ /// Names of tests to execute.
+ #[structopt(short = "t", required = false)]
+ test_names: Vec<String>,
+}
+
fn main() -> anyhow::Result<()> {
+ let args = Cli::from_args();
env_logger::init();
let tee = TeeBinder::new(env!("CARGO_PKG_NAME"))?;
- run(&tee)?;
+ start_enclave_unit_test_driver(&tee, args.test_names)?;
tee.finalize();
Ok(())
}
-fn start_enclave_unit_test_driver(tee: &TeeBinder) -> anyhow::Result<()> {
+fn start_enclave_unit_test_driver(tee: &TeeBinder, test_names: Vec<String>) -> anyhow::Result<()> {
let cmd = ECallCommand::RunTest;
- match tee.invoke::<RunTestInput, TeeServiceResult<RunTestOutput>>(cmd, RunTestInput) {
+ let input = RunTestInput::new(test_names);
+ match tee.invoke::<RunTestInput, TeeServiceResult<RunTestOutput>>(cmd, input) {
Err(e) => error!("{:?}", e),
Ok(Err(e)) => error!("{:?}", e),
_ => (),
@@ -40,9 +50,3 @@ fn start_enclave_unit_test_driver(tee: &TeeBinder) -> anyhow::Result<()> {
Ok(())
}
-
-fn run(tee: &TeeBinder) -> anyhow::Result<()> {
- start_enclave_unit_test_driver(tee)?;
-
- Ok(())
-}
diff --git a/tests/functional/enclave/src/execution_service.rs b/tests/functional/enclave/src/execution_service.rs
new file mode 100644
index 0000000..f9c0d44
--- /dev/null
+++ b/tests/functional/enclave/src/execution_service.rs
@@ -0,0 +1,82 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::utils::*;
+use std::collections::HashMap;
+use std::collections::HashSet;
+use std::prelude::v1::*;
+use teaclave_proto::teaclave_storage_service::*;
+use teaclave_types::*;
+
+use uuid::Uuid;
+
+pub fn run_tests() -> bool {
+ use teaclave_test_utils::*;
+
+ run_tests!(test_execute_function)
+}
+
+fn test_execute_function() {
+ let task_id = Uuid::new_v4();
+ let task = Task {
+ task_id,
+ creator: "".to_string(),
+ function_id: "".to_string(),
+ function_owner: "".to_string(),
+ function_arguments: FunctionArguments::default(),
+ input_data_owner_list: HashMap::new(),
+ output_data_owner_list: HashMap::new(),
+ participants: HashSet::new(),
+ approved_user_list: HashSet::new(),
+ input_map: HashMap::new(),
+ output_map: HashMap::new(),
+ return_value: None,
+ output_file_hash: HashMap::new(),
+ status: TaskStatus::Running,
+ };
+
+ let function_id = Uuid::new_v4();
+ let function_name = "echo";
+ let function_arguments = FunctionArguments::new(hashmap!(
+ "message" => "Hello, Teaclave Tests!"
+ ));
+
+ let staged_task = StagedTask::new()
+ .task_id(task_id)
+ .function_id(function_id.clone())
+ .function_name(function_name)
+ .function_arguments(function_arguments);
+
+ let mut storage_client = get_storage_client();
+ let enqueue_request = EnqueueRequest::new(
+ StagedTask::get_queue_key().as_bytes(),
+ staged_task.to_vec().unwrap(),
+ );
+ let _enqueue_response = storage_client.enqueue(enqueue_request).unwrap();
+ let put_request = PutRequest::new(task.key().as_slice(), task.to_vec().unwrap().as_slice());
+ let _put_response = storage_client.put(put_request).unwrap();
+
+ std::thread::sleep(std::time::Duration::from_secs(5));
+
+ let get_request = GetRequest::new(task.key().as_slice());
+ let get_response = storage_client.get(get_request).unwrap();
+ let updated_task = Task::from_slice(get_response.value.as_slice()).unwrap();
+ assert_eq!(
+ updated_task.return_value.unwrap(),
+ b"Hello, Teaclave Tests!"
+ );
+}
diff --git a/tests/functional/enclave/src/lib.rs b/tests/functional/enclave/src/lib.rs
index 6c42584..5476e03 100644
--- a/tests/functional/enclave/src/lib.rs
+++ b/tests/functional/enclave/src/lib.rs
@@ -23,6 +23,7 @@ extern crate sgx_tstd as std;
#[macro_use]
extern crate log;
+use std::collections::HashMap;
use std::prelude::v1::*;
use teaclave_binder::proto::{
@@ -31,28 +32,56 @@ use teaclave_binder::proto::{
};
use teaclave_binder::{handle_ecall, register_ecall_handler};
use teaclave_service_enclave_utils::ServiceEnclave;
-use teaclave_test_utils::check_all_passed;
use teaclave_types;
use teaclave_types::TeeServiceResult;
mod access_control_service;
mod authentication_service;
+mod execution_service;
mod frontend_service;
mod management_service;
mod scheduler_service;
mod storage_service;
mod utils;
+type BoxedFnTest = Box<dyn Fn() -> bool>;
+
#[handle_ecall]
-fn handle_run_test(_: &RunTestInput) -> TeeServiceResult<RunTestOutput> {
- let ret = check_all_passed!(
- access_control_service::run_tests(),
- authentication_service::run_tests(),
- storage_service::run_tests(),
- frontend_service::run_tests(),
- management_service::run_tests(),
- scheduler_service::run_tests(),
- );
+fn handle_run_test(input: &RunTestInput) -> TeeServiceResult<RunTestOutput> {
+ let test_names = &input.test_names;
+ let v: Vec<(_, BoxedFnTest)> = vec![
+ (
+ "access_control_service",
+ Box::new(access_control_service::run_tests),
+ ),
+ (
+ "authentication_service",
+ Box::new(authentication_service::run_tests),
+ ),
+ ("storage_service", Box::new(storage_service::run_tests)),
+ ("frontend_service", Box::new(frontend_service::run_tests)),
+ (
+ "management_service",
+ Box::new(management_service::run_tests),
+ ),
+ ("scheduler_service", Box::new(scheduler_service::run_tests)),
+ ("execution_service", Box::new(execution_service::run_tests)),
+ ];
+ let test_map: HashMap<_, BoxedFnTest> =
+ v.into_iter().map(|(k, v)| (k.to_string(), v)).collect();
+
+ let mut ret = true;
+
+ if test_names.is_empty() {
+ for fn_test in test_map.values() {
+ ret &= fn_test();
+ }
+ }
+
+ for name in test_names.iter() {
+ let fn_test = test_map.get(name).unwrap();
+ ret &= fn_test();
+ }
assert_eq!(ret, true);
Ok(RunTestOutput)
diff --git a/tests/integration/app/src/main.rs b/tests/integration/app/src/main.rs
index 95b545f..1d2133f 100644
--- a/tests/integration/app/src/main.rs
+++ b/tests/integration/app/src/main.rs
@@ -32,7 +32,8 @@ fn main() -> anyhow::Result<()> {
fn start_enclave_unit_test_driver(tee: &TeeBinder) -> anyhow::Result<()> {
let cmd = ECallCommand::RunTest;
- match tee.invoke::<RunTestInput, TeeServiceResult<RunTestOutput>>(cmd, RunTestInput) {
+ let input = RunTestInput::default();
+ match tee.invoke::<RunTestInput, TeeServiceResult<RunTestOutput>>(cmd, input) {
Err(e) => error!("{:?}", e),
Ok(Err(e)) => error!("{:?}", e),
_ => (),
diff --git a/tests/unit/app/src/main.rs b/tests/unit/app/src/main.rs
index 16fd76c..ea19a46 100644
--- a/tests/unit/app/src/main.rs
+++ b/tests/unit/app/src/main.rs
@@ -34,7 +34,8 @@ fn main() -> anyhow::Result<()> {
fn start_enclave_unit_test_driver(tee: &TeeBinder) -> anyhow::Result<()> {
let cmd = ECallCommand::RunTest;
- match tee.invoke::<RunTestInput, TeeServiceResult<RunTestOutput>>(cmd, RunTestInput) {
+ let input = RunTestInput::default();
+ match tee.invoke::<RunTestInput, TeeServiceResult<RunTestOutput>>(cmd, input) {
Err(e) => error!("{:?}", e),
Ok(Err(e)) => error!("{:?}", e),
_ => (),
diff --git a/types/src/worker.rs b/types/src/worker.rs
index b498bfd..ce1a8af 100644
--- a/types/src/worker.rs
+++ b/types/src/worker.rs
@@ -61,7 +61,7 @@ pub struct WorkerCapability {
pub functions: HashSet<String>,
}
-#[derive(Default)]
+#[derive(Debug, Default)]
pub struct ExecutionResult {
pub return_value: Vec<u8>,
pub output_file_hash: HashMap<String, String>,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org