summaryrefslogtreecommitdiff
path: root/runtime/js/40_testing.js
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 /runtime/js/40_testing.js
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 'runtime/js/40_testing.js')
-rw-r--r--runtime/js/40_testing.js29
1 files changed, 29 insertions, 0 deletions
diff --git a/runtime/js/40_testing.js b/runtime/js/40_testing.js
index 7666fa050..4a97f6437 100644
--- a/runtime/js/40_testing.js
+++ b/runtime/js/40_testing.js
@@ -4,6 +4,7 @@
((window) => {
const core = window.Deno.core;
const colors = window.__bootstrap.colors;
+ const { parsePermissions } = window.__bootstrap.worker;
const { setExitHandler, exit } = window.__bootstrap.os;
const { Console, inspectArgs } = window.__bootstrap.console;
const { stdout } = window.__bootstrap.files;
@@ -121,6 +122,7 @@ finishing test case.`;
sanitizeOps: true,
sanitizeResources: true,
sanitizeExit: true,
+ permissions: null,
};
if (typeof t === "string") {
@@ -226,6 +228,17 @@ finishing test case.`;
}
}
+ function pledgeTestPermissions(permissions) {
+ return core.opSync(
+ "op_pledge_test_permissions",
+ parsePermissions(permissions),
+ );
+ }
+
+ function restoreTestPermissions(token) {
+ core.opSync("op_restore_test_permissions", token);
+ }
+
// TODO(bartlomieju): already implements AsyncGenerator<RunTestsMessage>, but add as "implements to class"
// TODO(bartlomieju): implements PromiseLike<RunTestsEndResult>
class TestRunner {
@@ -257,6 +270,7 @@ finishing test case.`;
const results = [];
const suiteStart = +new Date();
+
for (const test of this.testsToRun) {
const endMessage = {
name: test.name,
@@ -268,15 +282,30 @@ finishing test case.`;
this.stats.ignored++;
} else {
const start = +new Date();
+
+ let token;
try {
+ if (test.permissions) {
+ token = pledgeTestPermissions(test.permissions);
+ }
+
await test.fn();
+
endMessage.status = "passed";
this.stats.passed++;
} catch (err) {
endMessage.status = "failed";
endMessage.error = err;
this.stats.failed++;
+ } finally {
+ // Permissions must always be restored for a clean environment,
+ // otherwise the process can end up dropping permissions
+ // until there are none left.
+ if (token) {
+ restoreTestPermissions(token);
+ }
}
+
endMessage.duration = +new Date() - start;
}
results.push(endMessage);