From c455c28b834683f6516422dbf1b020fbb2c1bbb6 Mon Sep 17 00:00:00 2001 From: Casper Beyer Date: Thu, 29 Apr 2021 02:17:04 +0800 Subject: feat(test): run test modules in parallel (#9815) This commit adds support for running test in parallel. Entire test runner functionality has been rewritten from JavaScript to Rust and a set of ops was added to support reporting in Rust. A new "--jobs" flag was added to "deno test" that allows to configure how many threads will be used. When given no value it defaults to 2. --- cli/ops/mod.rs | 2 +- cli/ops/test_runner.rs | 66 ------------------------------------ cli/ops/testing.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 67 deletions(-) delete mode 100644 cli/ops/test_runner.rs create mode 100644 cli/ops/testing.rs (limited to 'cli/ops') diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs index 386ad16fa..a3df77fac 100644 --- a/cli/ops/mod.rs +++ b/cli/ops/mod.rs @@ -2,6 +2,6 @@ pub mod errors; pub mod runtime_compiler; -pub mod test_runner; +pub mod testing; pub use deno_runtime::ops::{reg_async, reg_sync}; diff --git a/cli/ops/test_runner.rs b/cli/ops/test_runner.rs deleted file mode 100644 index 380ec7fb0..000000000 --- a/cli/ops/test_runner.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::generic_error; -use deno_core::error::AnyError; -use deno_core::serde_json; -use deno_core::serde_json::Value; -use deno_core::OpState; -use deno_core::ZeroCopyBuf; -use deno_runtime::ops::worker_host::create_worker_permissions; -use deno_runtime::ops::worker_host::PermissionsArg; -use deno_runtime::permissions::Permissions; -use uuid::Uuid; - -pub fn init(rt: &mut deno_core::JsRuntime) { - super::reg_sync(rt, "op_pledge_test_permissions", op_pledge_test_permissions); - super::reg_sync( - rt, - "op_restore_test_permissions", - op_restore_test_permissions, - ); -} - -#[derive(Clone)] -struct PermissionsHolder(Uuid, Permissions); - -pub fn op_pledge_test_permissions( - state: &mut OpState, - args: Value, - _zero_copy: Option, -) -> Result { - deno_runtime::ops::check_unstable(state, "Deno.test.permissions"); - - let token = Uuid::new_v4(); - let parent_permissions = state.borrow::().clone(); - let worker_permissions = { - let permissions: PermissionsArg = serde_json::from_value(args)?; - create_worker_permissions(parent_permissions.clone(), permissions)? - }; - - state.put::(PermissionsHolder(token, parent_permissions)); - - // NOTE: This call overrides current permission set for the worker - state.put::(worker_permissions); - - Ok(token) -} - -pub fn op_restore_test_permissions( - state: &mut OpState, - token: Uuid, - _zero_copy: Option, -) -> Result<(), AnyError> { - deno_runtime::ops::check_unstable(state, "Deno.test.permissions"); - - if let Some(permissions_holder) = state.try_take::() { - if token != permissions_holder.0 { - panic!("restore test permissions token does not match the stored token"); - } - - let permissions = permissions_holder.1; - state.put::(permissions); - Ok(()) - } else { - Err(generic_error("no permissions to restore")) - } -} diff --git a/cli/ops/testing.rs b/cli/ops/testing.rs new file mode 100644 index 000000000..450f55a41 --- /dev/null +++ b/cli/ops/testing.rs @@ -0,0 +1,91 @@ +use crate::tools::test_runner::TestMessage; +use deno_core::error::generic_error; +use deno_core::error::AnyError; +use deno_core::serde_json; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::JsRuntime; +use deno_core::OpState; +use deno_core::ZeroCopyBuf; +use deno_runtime::ops::worker_host::create_worker_permissions; +use deno_runtime::ops::worker_host::PermissionsArg; +use deno_runtime::permissions::Permissions; +use serde::Deserialize; +use std::sync::mpsc::Sender; +use uuid::Uuid; + +pub fn init(rt: &mut JsRuntime) { + super::reg_sync(rt, "op_pledge_test_permissions", op_pledge_test_permissions); + super::reg_sync( + rt, + "op_restore_test_permissions", + op_restore_test_permissions, + ); + super::reg_sync(rt, "op_post_test_message", op_post_test_message); +} + +#[derive(Clone)] +struct PermissionsHolder(Uuid, Permissions); + +pub fn op_pledge_test_permissions( + state: &mut OpState, + args: Value, + _zero_copy: Option, +) -> Result { + deno_runtime::ops::check_unstable(state, "Deno.test.permissions"); + + let token = Uuid::new_v4(); + let parent_permissions = state.borrow::().clone(); + let worker_permissions = { + let permissions: PermissionsArg = serde_json::from_value(args)?; + create_worker_permissions(parent_permissions.clone(), permissions)? + }; + + state.put::(PermissionsHolder(token, parent_permissions)); + + // NOTE: This call overrides current permission set for the worker + state.put::(worker_permissions); + + Ok(token) +} + +pub fn op_restore_test_permissions( + state: &mut OpState, + token: Uuid, + _zero_copy: Option, +) -> Result<(), AnyError> { + deno_runtime::ops::check_unstable(state, "Deno.test.permissions"); + + if let Some(permissions_holder) = state.try_take::() { + if token != permissions_holder.0 { + panic!("restore test permissions token does not match the stored token"); + } + + let permissions = permissions_holder.1; + state.put::(permissions); + Ok(()) + } else { + Err(generic_error("no permissions to restore")) + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct PostTestMessageArgs { + message: TestMessage, +} + +fn op_post_test_message( + state: &mut OpState, + args: Value, + _zero_copy: Option, +) -> Result { + let args: PostTestMessageArgs = serde_json::from_value(args)?; + let sender = state.borrow::>().clone(); + + if sender.send(args.message).is_err() { + Ok(json!(false)) + } else { + Ok(json!(true)) + } +} -- cgit v1.2.3