From 6e8618ae0f55bcaa4cfaaa579b4e21f9f74b117d Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Thu, 13 Apr 2023 18:43:23 +0100 Subject: refactor(cli): move runTests() and runBenchmarks() to rust (#18563) Stores the test/bench functions in rust op state during registration. The functions are wrapped in JS first so that they return a directly convertible `TestResult`/`BenchResult`. Test steps are still mostly handled in JS since they are pretty much invoked by the user. Allows removing a bunch of infrastructure for communicating between JS and rust. Allows using rust utilities for things like shuffling tests (`Vec::shuffle`). We can progressively move op and resource sanitization to rust as well. Fixes #17122. Fixes #17312. --- cli/ops/bench.rs | 54 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 20 deletions(-) (limited to 'cli/ops/bench.rs') diff --git a/cli/ops/bench.rs b/cli/ops/bench.rs index 86498cd7c..da0f3d959 100644 --- a/cli/ops/bench.rs +++ b/cli/ops/bench.rs @@ -7,6 +7,8 @@ use std::time; use deno_core::error::generic_error; use deno_core::error::AnyError; use deno_core::op; +use deno_core::serde_v8; +use deno_core::v8; use deno_core::ModuleSpecifier; use deno_core::OpState; use deno_runtime::permissions::create_child_permissions; @@ -19,24 +21,26 @@ use uuid::Uuid; use crate::tools::bench::BenchDescription; use crate::tools::bench::BenchEvent; -use crate::tools::test::TestFilter; + +#[derive(Default)] +pub(crate) struct BenchContainer( + pub Vec<(BenchDescription, v8::Global)>, +); deno_core::extension!(deno_bench, ops = [ op_pledge_test_permissions, op_restore_test_permissions, - op_get_bench_origin, op_register_bench, op_dispatch_bench_event, op_bench_now, ], options = { sender: UnboundedSender, - filter: TestFilter, }, state = |state, options| { state.put(options.sender); - state.put(options.filter); + state.put(BenchContainer::default()); }, customizer = |ext: &mut deno_core::ExtensionBuilder| { ext.force_op_registration(); @@ -90,51 +94,61 @@ pub fn op_restore_test_permissions( } } -#[op] -fn op_get_bench_origin(state: &mut OpState) -> String { - state.borrow::().to_string() -} - -#[derive(Debug, Deserialize)] +#[derive(Deserialize)] #[serde(rename_all = "camelCase")] -struct BenchInfo { +struct BenchInfo<'s> { + #[serde(rename = "fn")] + function: serde_v8::Value<'s>, name: String, - origin: String, baseline: bool, group: Option, + ignore: bool, + only: bool, } #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct BenchRegisterResult { id: usize, - filtered_out: bool, + origin: String, } static NEXT_ID: AtomicUsize = AtomicUsize::new(0); -#[op] -fn op_register_bench( +#[op(v8)] +fn op_register_bench<'a>( + scope: &mut v8::HandleScope<'a>, state: &mut OpState, - info: BenchInfo, + info: BenchInfo<'a>, ) -> Result { let id = NEXT_ID.fetch_add(1, Ordering::SeqCst); - let filter = state.borrow::().clone(); - let filtered_out = !filter.includes(&info.name); + let origin = state.borrow::().to_string(); let description = BenchDescription { id, name: info.name, - origin: info.origin, + origin: origin.clone(), baseline: info.baseline, group: info.group, + ignore: info.ignore, + only: info.only, }; + let function: v8::Local = info.function.v8_value.try_into()?; + let function = v8::Global::new(scope, function); + state + .borrow_mut::() + .0 + .push((description.clone(), function)); let sender = state.borrow::>().clone(); sender.send(BenchEvent::Register(description)).ok(); - Ok(BenchRegisterResult { id, filtered_out }) + Ok(BenchRegisterResult { id, origin }) } #[op] fn op_dispatch_bench_event(state: &mut OpState, event: BenchEvent) { + assert!( + matches!(event, BenchEvent::Output(_)), + "Only output events are expected from JS." + ); let sender = state.borrow::>().clone(); sender.send(event).ok(); } -- cgit v1.2.3