From 9a1066869457037d6ab24965da82e80e1e5c77a9 Mon Sep 17 00:00:00 2001 From: Andreu Botella Date: Tue, 30 Nov 2021 01:27:30 +0100 Subject: fix(test): Improve reliability of `deno test`'s op sanitizer with timers (#12934) Although not easy to replicate in the wild, the `deno test` op sanitizer can fail when there are intervals that started before a test runs, since the op sanitizer can end up running in the time between the timer op for an interval's run resolves and the op for the next run starts. This change fixes that by adding a new macrotask callback that will run after the timer macrotask queue has drained. This ensures that there is a timer op if there are any timers which are unresolved by the time the op sanitizer runs. --- cli/tests/integration/test_tests.rs | 10 ++++++++++ cli/tests/testdata/test/ops_sanitizer_nexttick.out | 7 +++++++ cli/tests/testdata/test/ops_sanitizer_nexttick.ts | 11 +++++++++++ .../test/ops_sanitizer_timeout_failure.out | 6 ++++++ .../testdata/test/ops_sanitizer_timeout_failure.ts | 22 ++++++++++++++++++++++ 5 files changed, 56 insertions(+) create mode 100644 cli/tests/testdata/test/ops_sanitizer_nexttick.out create mode 100644 cli/tests/testdata/test/ops_sanitizer_nexttick.ts create mode 100644 cli/tests/testdata/test/ops_sanitizer_timeout_failure.out create mode 100644 cli/tests/testdata/test/ops_sanitizer_timeout_failure.ts (limited to 'cli/tests') diff --git a/cli/tests/integration/test_tests.rs b/cli/tests/integration/test_tests.rs index 3f23efca2..bddb0cc6e 100644 --- a/cli/tests/integration/test_tests.rs +++ b/cli/tests/integration/test_tests.rs @@ -151,6 +151,16 @@ itest!(ops_sanitizer_unstable { output: "test/ops_sanitizer_unstable.out", }); +itest!(ops_sanitizer_timeout_failure { + args: "test test/ops_sanitizer_timeout_failure.ts", + output: "test/ops_sanitizer_timeout_failure.out", +}); + +itest!(ops_sanitizer_nexttick { + args: "test test/ops_sanitizer_nexttick.ts", + output: "test/ops_sanitizer_nexttick.out", +}); + itest!(exit_sanitizer { args: "test test/exit_sanitizer.ts", output: "test/exit_sanitizer.out", diff --git a/cli/tests/testdata/test/ops_sanitizer_nexttick.out b/cli/tests/testdata/test/ops_sanitizer_nexttick.out new file mode 100644 index 000000000..43a4915d0 --- /dev/null +++ b/cli/tests/testdata/test/ops_sanitizer_nexttick.out @@ -0,0 +1,7 @@ +Check [WILDCARD]/testdata/test/ops_sanitizer_nexttick.ts +running 2 tests from [WILDCARD]/testdata/test/ops_sanitizer_nexttick.ts +test test 1 ... ok ([WILDCARD]) +test test 2 ... ok ([WILDCARD]) + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD]) + diff --git a/cli/tests/testdata/test/ops_sanitizer_nexttick.ts b/cli/tests/testdata/test/ops_sanitizer_nexttick.ts new file mode 100644 index 000000000..fcc9cb92a --- /dev/null +++ b/cli/tests/testdata/test/ops_sanitizer_nexttick.ts @@ -0,0 +1,11 @@ +import { nextTick } from "../../../../test_util/std/node/_next_tick.ts"; + +// https://github.com/denoland/deno_std/issues/1651 + +Deno.test("test 1", async () => { + await new Promise((resolve) => nextTick(resolve)); +}); + +Deno.test("test 2", async () => { + await new Promise((resolve) => nextTick(resolve)); +}); diff --git a/cli/tests/testdata/test/ops_sanitizer_timeout_failure.out b/cli/tests/testdata/test/ops_sanitizer_timeout_failure.out new file mode 100644 index 000000000..81a1af63b --- /dev/null +++ b/cli/tests/testdata/test/ops_sanitizer_timeout_failure.out @@ -0,0 +1,6 @@ +Check [WILDCARD]/testdata/test/ops_sanitizer_timeout_failure.ts +running 1 test from [WILDCARD]/testdata/test/ops_sanitizer_timeout_failure.ts +test wait ... ok ([WILDCARD]) + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD]) + diff --git a/cli/tests/testdata/test/ops_sanitizer_timeout_failure.ts b/cli/tests/testdata/test/ops_sanitizer_timeout_failure.ts new file mode 100644 index 000000000..d40a5a258 --- /dev/null +++ b/cli/tests/testdata/test/ops_sanitizer_timeout_failure.ts @@ -0,0 +1,22 @@ +let intervalHandle: number; +let firstIntervalPromise: Promise; + +addEventListener("load", () => { + firstIntervalPromise = new Promise((resolve) => { + let firstIntervalCalled = false; + intervalHandle = setInterval(() => { + if (!firstIntervalCalled) { + resolve(); + firstIntervalCalled = true; + } + }, 5); + }); +}); + +addEventListener("unload", () => { + clearInterval(intervalHandle); +}); + +Deno.test("wait", async function () { + await firstIntervalPromise; +}); -- cgit v1.2.3