From 408e06aa7ad57db805aa3233c63a6aa1c71a4e60 Mon Sep 17 00:00:00 2001 From: Ben Blaxill Date: Fri, 7 Feb 2020 17:01:05 +0000 Subject: [PATCH] Remove hard coded Wasm paths in abitest & hello_world (#578) * Remove hard coded Wasm paths in abitest & hello_world * Review --- docs/programming-oak.md | 4 +-- examples/Cargo.lock | 1 + examples/abitest/tests/src/tests.rs | 29 ++++++++++----- examples/hello_world/module/rust/src/tests.rs | 13 +++++-- scripts/run_tests | 7 ++-- sdk/rust/Cargo.lock | 1 + sdk/rust/oak_tests/Cargo.toml | 1 + sdk/rust/oak_tests/src/lib.rs | 36 +++++++++++++++---- 8 files changed, 67 insertions(+), 25 deletions(-) diff --git a/docs/programming-oak.md b/docs/programming-oak.md index 91965c88e95..ed24eca9157 100644 --- a/docs/programming-oak.md +++ b/docs/programming-oak.md @@ -445,7 +445,7 @@ fn test_say_hello() { simple_logger::init().unwrap(); let configuration = oak_tests::test_configuration( - &[(MODULE_CONFIG_NAME, WASM_PATH)], + build_wasm().expect("failed to build wasm modules"), LOG_CONFIG_NAME, MODULE_CONFIG_NAME, ENTRYPOINT_NAME, @@ -471,8 +471,6 @@ fn test_say_hello() { This has a little bit more boilerplate than testing a method directly: -- The inbound gRPC channel that requests are delivered over has to be explicitly - set up (`oak_tests::grpc_channel_setup_default`) - After being configured, the runtime executes Nodes in separate threads (`oak_runtime::configure_and_run`). The `derive(OakExports)` macro (from the [`oak_derive`](https://project-oak.github.io/oak/sdk/oak_derive/index.html) diff --git a/examples/Cargo.lock b/examples/Cargo.lock index b55a9b0e4db..5d8046638df 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -831,6 +831,7 @@ dependencies = [ "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "protoc-rust 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/examples/abitest/tests/src/tests.rs b/examples/abitest/tests/src/tests.rs index c5aed8d0bd0..404fe165086 100644 --- a/examples/abitest/tests/src/tests.rs +++ b/examples/abitest/tests/src/tests.rs @@ -26,25 +26,38 @@ const BACKEND_CONFIG_NAME: &str = "backend-config"; const LOG_CONFIG_NAME: &str = "logging-config"; const FRONTEND_ENTRYPOINT_NAME: &str = "frontend_oak_main"; -// TODO(#541) -const FRONTEND_WASM: &str = "../../target/wasm32-unknown-unknown/debug/abitest_0_frontend.wasm"; -const BACKEND_WASM: &str = "../../target/wasm32-unknown-unknown/debug/abitest_1_backend.wasm"; +const FRONTEND_MANIFEST: &str = "../module_0/rust/Cargo.toml"; +const BACKEND_MANIFEST: &str = "../module_1/rust/Cargo.toml"; + +const FRONTEND_WASM_NAME: &str = "abitest_0_frontend.wasm"; +const BACKEND_WASM_NAME: &str = "abitest_1_backend.wasm"; + +fn build_wasm() -> std::io::Result)>> { + Ok(vec![ + ( + FRONTEND_CONFIG_NAME.to_owned(), + oak_tests::compile_rust_wasm(FRONTEND_MANIFEST, FRONTEND_WASM_NAME)?, + ), + ( + BACKEND_CONFIG_NAME.to_owned(), + oak_tests::compile_rust_wasm(BACKEND_MANIFEST, BACKEND_WASM_NAME)?, + ), + ]) +} #[test] fn test_abi() { simple_logger::init().unwrap(); let configuration = oak_tests::test_configuration( - &[ - (FRONTEND_CONFIG_NAME, FRONTEND_WASM), - (BACKEND_CONFIG_NAME, BACKEND_WASM), - ], + build_wasm().expect("failed to build wasm modules"), LOG_CONFIG_NAME, FRONTEND_CONFIG_NAME, FRONTEND_ENTRYPOINT_NAME, ); + let (runtime, entry_channel) = oak_runtime::Runtime::configure_and_run(configuration) - .expect("Unable to configure runtime with test wasm!"); + .expect("unable to configure runtime with test wasm"); let result: grpc::Result = oak_tests::grpc_request( &entry_channel, diff --git a/examples/hello_world/module/rust/src/tests.rs b/examples/hello_world/module/rust/src/tests.rs index f49b80c53b1..d861e09a9c2 100644 --- a/examples/hello_world/module/rust/src/tests.rs +++ b/examples/hello_world/module/rust/src/tests.rs @@ -22,8 +22,15 @@ const MODULE_CONFIG_NAME: &str = "hello_world"; const LOG_CONFIG_NAME: &str = "log"; const ENTRYPOINT_NAME: &str = "oak_main"; -// TODO(#541) -const WASM_PATH: &str = "../../../target/wasm32-unknown-unknown/debug/hello_world.wasm"; +const MODULE_MANIFEST: &str = "Cargo.toml"; +const MODULE_WASM_NAME: &str = "hello_world.wasm"; + +fn build_wasm() -> std::io::Result)>> { + Ok(vec![( + MODULE_CONFIG_NAME.to_owned(), + oak_tests::compile_rust_wasm(MODULE_MANIFEST, MODULE_WASM_NAME)?, + )]) +} // Test invoking the SayHello Node service method via the Oak runtime. #[test] @@ -31,7 +38,7 @@ fn test_say_hello() { simple_logger::init().unwrap(); let configuration = oak_tests::test_configuration( - &[(MODULE_CONFIG_NAME, WASM_PATH)], + build_wasm().expect("failed to build wasm modules"), LOG_CONFIG_NAME, MODULE_CONFIG_NAME, ENTRYPOINT_NAME, diff --git a/scripts/run_tests b/scripts/run_tests index 42ecd8d6fd2..1a1d566404a 100755 --- a/scripts/run_tests +++ b/scripts/run_tests @@ -4,8 +4,8 @@ readonly SCRIPTS_DIR="$(dirname "$(readlink -f "$0")")" # shellcheck source=scripts/common source "$SCRIPTS_DIR/common" -# For each Rust workspace, first build Wasm modules where appropriate, then run tests, then -# run doc tests, then run clippy (turning warnings into errors). +# For each Rust workspace, run tests, then run doc tests, then run clippy +# (turning warnings into errors). # # See: # - https://doc.rust-lang.org/cargo/commands/cargo-test.html @@ -17,8 +17,7 @@ cargo test --all-targets --manifest-path=./sdk/rust/Cargo.toml cargo test --doc --manifest-path=./sdk/rust/Cargo.toml cargo clippy --all-targets --manifest-path=./sdk/rust/Cargo.toml -- --deny=warnings -cargo build --target wasm32-unknown-unknown --manifest-path=./examples/Cargo.toml -cargo test --all-targets --manifest-path=./examples/Cargo.toml +cargo test --all-targets --manifest-path=./examples/Cargo.toml -- --nocapture cargo test --doc --manifest-path=./examples/Cargo.toml cargo clippy --all-targets --manifest-path=./examples/Cargo.toml -- --deny=warnings diff --git a/sdk/rust/Cargo.lock b/sdk/rust/Cargo.lock index 4e8ef6913f6..0213cde04b2 100644 --- a/sdk/rust/Cargo.lock +++ b/sdk/rust/Cargo.lock @@ -260,6 +260,7 @@ dependencies = [ "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "protoc-rust 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/sdk/rust/oak_tests/Cargo.toml b/sdk/rust/oak_tests/Cargo.toml index 940873d84bf..909c6b23fc6 100644 --- a/sdk/rust/oak_tests/Cargo.toml +++ b/sdk/rust/oak_tests/Cargo.toml @@ -16,6 +16,7 @@ oak_log = "=0.1.0" oak_runtime = "=0.1.0" protobuf = "*" rand = { version = "*" } +tempdir = "*" [build-dependencies] protoc-rust = "*" diff --git a/sdk/rust/oak_tests/src/lib.rs b/sdk/rust/oak_tests/src/lib.rs index e61ac3172f6..91ed290e109 100644 --- a/sdk/rust/oak_tests/src/lib.rs +++ b/sdk/rust/oak_tests/src/lib.rs @@ -21,31 +21,53 @@ use log::info; use oak_runtime::ChannelEither; use protobuf::{Message, ProtobufEnum}; +use std::process::Command; +use tempdir::TempDir; + use oak_runtime::proto::manager::{ ApplicationConfiguration, LogConfiguration, NodeConfiguration, WebAssemblyConfiguration, }; // TODO(#544) +/// Uses cargo to compile a Rust manifest to Wasm bytes. Compilation is performed in a temporary +/// directory. +pub fn compile_rust_wasm(cargo_path: &str, module_name: &str) -> std::io::Result> { + let temp_dir = TempDir::new("")?; + Command::new("cargo") + .args(&["build", "--target=wasm32-unknown-unknown"]) + .args(&[ + format!("--manifest-path={}", cargo_path), + format!("--target-dir={}", temp_dir.path().display()), + ]) + .spawn()? + .wait()?; + + let mut path = temp_dir.into_path(); + path.push("wasm32-unknown-unknown/debug"); + path.push(module_name); + + std::fs::read(path) +} + /// Create a simple configuration with collection of Wasm nodes and a logger node. /// -/// - module_name_wasm: Node name and path to associated Wasm file. +/// - module_name_wasm: Node name and Wasm bytes. /// - logger_name: Node name to use for a logger configuration. /// - initial_node: Initial node to run on launch. /// - entrypoint: Entrypoint in the initial node to run on launch. // TODO(#563) -pub fn test_configuration>( - module_name_wasm: &[(&str, P)], +pub fn test_configuration( + module_name_wasm: Vec<(String, Vec)>, logger_name: &str, initial_node: &str, entrypoint: &str, ) -> ApplicationConfiguration { let mut nodes: Vec = module_name_wasm - .iter() - .map(|(name, module)| { - let wasm = std::fs::read(module).expect("Module missing"); + .into_iter() + .map(|(name, wasm)| { let mut node = NodeConfiguration::new(); - node.set_name(name.to_string()); + node.set_name(name); node.set_wasm_config({ let mut w = WebAssemblyConfiguration::new(); w.set_module_bytes(wasm);