summaryrefslogtreecommitdiff
path: root/cli/ops
diff options
context:
space:
mode:
authorCasper Beyer <caspervonb@pm.me>2021-04-26 05:38:59 +0800
committerGitHub <noreply@github.com>2021-04-25 23:38:59 +0200
commitf3751e498faabd524494a4b70c49b1f53fe5ebdd (patch)
tree9f3cf5b15fc10d0ef12f78c984fbbb59554343ef /cli/ops
parent7063e449f11ab2cff492ba90314da7a0bcd994a6 (diff)
feat(cli): add test permissions to Deno.test (#10188)
This commits adds adds "permissions" option to the test definitions which allows tests to run with different permission sets than the process's permission. The change will only be in effect within the test function, once the test has completed the original process permission set is restored. Test permissions cannot exceed the process's permission. You can only narrow or drop permissions, failure to acquire a permission results in an error being thrown and the test case will fail.
Diffstat (limited to 'cli/ops')
-rw-r--r--cli/ops/mod.rs1
-rw-r--r--cli/ops/test_runner.rs66
2 files changed, 67 insertions, 0 deletions
diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs
index cce0625c6..386ad16fa 100644
--- a/cli/ops/mod.rs
+++ b/cli/ops/mod.rs
@@ -2,5 +2,6 @@
pub mod errors;
pub mod runtime_compiler;
+pub mod test_runner;
pub use deno_runtime::ops::{reg_async, reg_sync};
diff --git a/cli/ops/test_runner.rs b/cli/ops/test_runner.rs
new file mode 100644
index 000000000..380ec7fb0
--- /dev/null
+++ b/cli/ops/test_runner.rs
@@ -0,0 +1,66 @@
+// 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<ZeroCopyBuf>,
+) -> Result<Uuid, AnyError> {
+ deno_runtime::ops::check_unstable(state, "Deno.test.permissions");
+
+ let token = Uuid::new_v4();
+ let parent_permissions = state.borrow::<Permissions>().clone();
+ let worker_permissions = {
+ let permissions: PermissionsArg = serde_json::from_value(args)?;
+ create_worker_permissions(parent_permissions.clone(), permissions)?
+ };
+
+ state.put::<PermissionsHolder>(PermissionsHolder(token, parent_permissions));
+
+ // NOTE: This call overrides current permission set for the worker
+ state.put::<Permissions>(worker_permissions);
+
+ Ok(token)
+}
+
+pub fn op_restore_test_permissions(
+ state: &mut OpState,
+ token: Uuid,
+ _zero_copy: Option<ZeroCopyBuf>,
+) -> Result<(), AnyError> {
+ deno_runtime::ops::check_unstable(state, "Deno.test.permissions");
+
+ if let Some(permissions_holder) = state.try_take::<PermissionsHolder>() {
+ if token != permissions_holder.0 {
+ panic!("restore test permissions token does not match the stored token");
+ }
+
+ let permissions = permissions_holder.1;
+ state.put::<Permissions>(permissions);
+ Ok(())
+ } else {
+ Err(generic_error("no permissions to restore"))
+ }
+}