1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00

fix: output traces for op sanitizer in more cases (#20494)

This adds traces for the "started outside test, closed inside test"
case.
This commit is contained in:
Luca Casonato 2023-09-14 16:38:15 +02:00 committed by GitHub
parent bbb348aa33
commit 851f795001
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 15 deletions

View file

@ -206,15 +206,30 @@ function assertOps(fn) {
} else if (dispatchedDiff < completedDiff) {
const [name, hint] = OP_DETAILS[key] || [key, null];
const count = completedDiff - dispatchedDiff;
ArrayPrototypePush(
details,
`${count} async operation${count === 1 ? "" : "s"} to ${name} ${
count === 1 ? "was" : "were"
} started before this test, but ${
count === 1 ? "was" : "were"
} completed during the test. Async operations should not complete in a test if they were not started in that test.
${hint ? `This is often caused by not ${hint}.` : ""}`,
);
let message = `${count} async operation${
count === 1 ? "" : "s"
} to ${name} ${
count === 1 ? "was" : "were"
} started before this test, but ${
count === 1 ? "was" : "were"
} completed during the test. Async operations should not complete in a test if they were not started in that test.`;
if (hint) {
message += ` This is often caused by not ${hint}.`;
}
const traces = [];
for (const [id, { opName, stack }] of preTraces) {
if (opName !== key) continue;
if (MapPrototypeHas(postTraces, id)) continue;
ArrayPrototypePush(traces, stack);
}
if (traces.length === 1) {
message += " The operation was started here:\n";
message += traces[0];
} else if (traces.length > 1) {
message += " The operations were started here:\n";
message += ArrayPrototypeJoin(traces, "\n\n");
}
ArrayPrototypePush(details, message);
}
}
return { failed: { leakedOps: [details, core.isOpCallTracingEnabled()] } };

View file

@ -255,6 +255,12 @@ itest!(trace_ops_catch_error {
// output: "test/ops_sanitizer_missing_details.out",
// });
itest!(ops_sanitizer_closed_inside_started_before {
args: "test --trace-ops test/ops_sanitizer_closed_inside_started_before.ts",
exit_code: 1,
output: "test/ops_sanitizer_closed_inside_started_before.out",
});
itest!(ops_sanitizer_nexttick {
args: "test --no-check test/ops_sanitizer_nexttick.ts",
output: "test/ops_sanitizer_nexttick.out",

View file

@ -0,0 +1,19 @@
Check [WILDCARD]test/ops_sanitizer_closed_inside_started_before.ts
running 1 test from ./test/ops_sanitizer_closed_inside_started_before.ts
test 1 ... FAILED [WILDCARD]
ERRORS
test 1 => ./test/ops_sanitizer_closed_inside_started_before.ts:[WILDCARD]
error: Leaking async ops:
- 1 async operation to sleep for a duration was started before this test, but was completed during the test. Async operations should not complete in a test if they were not started in that test. This is often caused by not cancelling a `setTimeout` or `setInterval` call. The operation was started here:
at [WILDCARD]
at [WILDCARD]/cli/tests/testdata/test/ops_sanitizer_closed_inside_started_before.ts:[WILDCARD]
FAILURES
test 1 => ./test/ops_sanitizer_closed_inside_started_before.ts:[WILDCARD]
FAILED | 0 passed | 1 failed [WILDCARD]
error: Test failed

View file

@ -0,0 +1,5 @@
const timer = setTimeout(() => {}, 10000000000);
Deno.test("test 1", () => {
clearTimeout(timer);
});

View file

@ -433,6 +433,13 @@ pub async fn test_specifier(
let mut coverage_collector = worker.maybe_setup_coverage_collector().await?;
if options.trace_ops {
worker.execute_script_static(
located_script_name!(),
"Deno[Deno.internal].core.enableOpCallTracing();",
)?;
}
// We execute the main module as a side module so that import.meta.main is not set.
match worker.execute_side_module_possibly_with_npm().await {
Ok(()) => {}
@ -450,12 +457,7 @@ pub async fn test_specifier(
}
let mut worker = worker.into_main_worker();
if options.trace_ops {
worker.js_runtime.execute_script_static(
located_script_name!(),
"Deno[Deno.internal].core.enableOpCallTracing();",
)?;
}
worker.dispatch_load_event(located_script_name!())?;
let tests = {

View file

@ -12,6 +12,7 @@ use deno_core::futures::FutureExt;
use deno_core::located_script_name;
use deno_core::parking_lot::Mutex;
use deno_core::url::Url;
use deno_core::v8;
use deno_core::CompiledWasmModuleStore;
use deno_core::Extension;
use deno_core::ModuleId;
@ -279,6 +280,17 @@ impl CliMainWorker {
Ok(None)
}
}
pub fn execute_script_static(
&mut self,
name: &'static str,
source_code: &'static str,
) -> Result<v8::Global<v8::Value>, AnyError> {
self
.worker
.js_runtime
.execute_script_static(name, source_code)
}
}
pub struct CliMainWorkerFactory {