From 1683044ed97953cb1dbfc0080440d5c4cc47bd2e Mon Sep 17 00:00:00 2001 From: Casper Beyer Date: Mon, 11 Oct 2021 23:00:33 +0800 Subject: [PATCH] feat: provide ops details for ops sanitizer failures (#12188) --- cli/tests/integration/test_tests.rs | 6 +++ .../testdata/test/ops_sanitizer_unstable.out | 35 ++++++++++++++++++ .../testdata/test/ops_sanitizer_unstable.ts | 4 ++ runtime/js/40_testing.js | 37 +++++++++++++++++-- 4 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 cli/tests/testdata/test/ops_sanitizer_unstable.out create mode 100644 cli/tests/testdata/test/ops_sanitizer_unstable.ts diff --git a/cli/tests/integration/test_tests.rs b/cli/tests/integration/test_tests.rs index 3ea8186b87..d4412191e6 100644 --- a/cli/tests/integration/test_tests.rs +++ b/cli/tests/integration/test_tests.rs @@ -133,6 +133,12 @@ itest!(allow_none { output: "test/allow_none.out", }); +itest!(ops_sanitizer_unstable { + args: "test --unstable test/ops_sanitizer_unstable.ts", + exit_code: 1, + output: "test/ops_sanitizer_unstable.out", +}); + itest!(exit_sanitizer { args: "test test/exit_sanitizer.ts", output: "test/exit_sanitizer.out", diff --git a/cli/tests/testdata/test/ops_sanitizer_unstable.out b/cli/tests/testdata/test/ops_sanitizer_unstable.out new file mode 100644 index 0000000000..3faea472b0 --- /dev/null +++ b/cli/tests/testdata/test/ops_sanitizer_unstable.out @@ -0,0 +1,35 @@ +Check [WILDCARD]/testdata/test/ops_sanitizer_unstable.ts +running 2 tests from [WILDCARD]/testdata/test/ops_sanitizer_unstable.ts +test no-op ... ok ([WILDCARD]) +test leak interval ... FAILED ([WILDCARD]) + +failures: + +leak interval +AssertionError: Test case is leaking async ops. +Before: + - dispatched: 1 + - completed: 1 +After: + - dispatched: 3 + - completed: 2 +Ops: + op_global_timer: + Before: + - dispatched: 1 + - completed: 1 + After: + - dispatched: 3 + - completed: 2 + +Make sure to await all promises returned from Deno APIs before +finishing test case. + at [WILDCARD] + +failures: + + leak interval + +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD]) + +error: Test failed diff --git a/cli/tests/testdata/test/ops_sanitizer_unstable.ts b/cli/tests/testdata/test/ops_sanitizer_unstable.ts new file mode 100644 index 0000000000..92f7bb888c --- /dev/null +++ b/cli/tests/testdata/test/ops_sanitizer_unstable.ts @@ -0,0 +1,4 @@ +Deno.test("no-op", function () {}); +Deno.test("leak interval", function () { + setInterval(function () {}); +}); diff --git a/runtime/js/40_testing.js b/runtime/js/40_testing.js index 2adb487fbe..1fec581963 100644 --- a/runtime/js/40_testing.js +++ b/runtime/js/40_testing.js @@ -23,6 +23,7 @@ StringPrototypeIncludes, StringPrototypeSlice, RegExp, + Number, RegExpPrototypeTest, SymbolToStringTag, } = window.__bootstrap.primordials; @@ -46,22 +47,50 @@ } const post = metrics(); + // We're checking diff because one might spawn HTTP server in the background // that will be a pending async op before test starts. const dispatchedDiff = post.opsDispatchedAsync - pre.opsDispatchedAsync; const completedDiff = post.opsCompletedAsync - pre.opsCompletedAsync; - assert( - dispatchedDiff === completedDiff, - `Test case is leaking async ops. + + const details = []; + for (const key in post.ops) { + const dispatchedDiff = Number( + post.ops[key]?.opsDispatchedAsync - + (pre.ops[key]?.opsDispatchedAsync ?? 0), + ); + const completedDiff = Number( + post.ops[key]?.opsCompletedAsync - + (pre.ops[key]?.opsCompletedAsync ?? 0), + ); + + if (dispatchedDiff !== completedDiff) { + details.push(` + ${key}: + Before: + - dispatched: ${pre.ops[key]?.opsDispatchedAsync ?? 0} + - completed: ${pre.ops[key]?.opsCompletedAsync ?? 0} + After: + - dispatched: ${post.ops[key].opsDispatchedAsync} + - completed: ${post.ops[key].opsCompletedAsync}`); + } + } + + const message = `Test case is leaking async ops. Before: - dispatched: ${pre.opsDispatchedAsync} - completed: ${pre.opsCompletedAsync} After: - dispatched: ${post.opsDispatchedAsync} - completed: ${post.opsCompletedAsync} +${details.length > 0 ? "Ops:" + details.join("") : ""} Make sure to await all promises returned from Deno APIs before -finishing test case.`, +finishing test case.`; + + assert( + dispatchedDiff === completedDiff, + message, ); }; }