Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deno resource leak test false positive when using filter #25235

Open
loynoir opened this issue Aug 27, 2024 · 4 comments
Open

deno resource leak test false positive when using filter #25235

loynoir opened this issue Aug 27, 2024 · 4 comments
Labels
bug Something isn't working correctly testing related to deno test and coverage

Comments

@loynoir
Copy link

loynoir commented Aug 27, 2024

Version: Deno 1.46.0

bug

deno resource leak test false positive when using filter

reproduce

$ deno test -A ./x.ts 
running 2 tests from ./x.ts
a ... ok (11ms)
b ... FAILED (6ms)

 ERRORS 

b => ./x.ts:12:6
error: Leaks detected:
  - A child process was started during the test, but not closed during the test. Close the child process by calling `proc.kill()` or `proc.close()`.
  - An async operation to wait for a subprocess to exit was started in this test, but never completed. This is often caused by not awaiting the result of a `Deno.Process#status` call.
To get more details where leaks occurred, run again with the --trace-leaks flag.

 FAILURES 

b => ./x.ts:12:6

FAILED | 1 passed | 1 failed (19ms)

error: Test failed

actual

deno resource leak test false positive when using filter

$ deno test -A --filter b ./x.ts 
running 1 test from ./x.ts
b ... ok (14ms)

ok | 1 passed | 0 failed | 1 filtered out (15ms)

expected

$ deno test -A --filter b ./x.ts 
(complain resource leak when using test filter)

additional

Found this bug when evanw/esbuild#3896

@marvinhagemeister marvinhagemeister added the bug Something isn't working correctly label Aug 27, 2024
@marvinhagemeister
Copy link
Contributor

Smaller reproduction:

File foo_test.ts:

import * as child_process from "node:child_process";

const worker = "foo.ts";

Deno.test("a", async () => {
  const cp = child_process.spawn(Deno.execPath(), [worker], {});
  await new Promise((r) => setTimeout(r, 200));
  cp.kill();
});

Deno.test("b", async () => {
  const cp = child_process.spawn(Deno.execPath(), [worker], {});
  await new Promise((r) => setTimeout(r, 200));
  cp.kill();
});

File foo.ts:

await new Promise((r) => setTimeout(r, 9999));

@marvinhagemeister marvinhagemeister added the testing related to deno test and coverage label Aug 27, 2024
@lucacasonato
Copy link
Member

lucacasonato commented Aug 27, 2024

The reproduction you provided is not correct @marvinhagemeister. The reported leak is genuine. You are just not waiting for the process to actually exit after calling cp.kill. You have to wait for the "exit" event to fire on the sub process.

This is because subprocesses do not die synchronously on Unix. Calling cp.exit just sends the subprocess a signal (like SIGTERM) that the sub process can do with whatever it wants. For SIGTERM for example, most processes would shut down pretty quickly. However, that is not guaranteed. A process can just ignore the signal you send it.

Because of that you always have to wait for the process to actually exit. And with node:child_process you do that by waiting for the exit event.

@marvinhagemeister
Copy link
Contributor

Related evanw/esbuild#3701

@kt3k
Copy link
Member

kt3k commented Sep 5, 2024

I think the cases leak ops flakily and that is more likely happen when the 2 cases run together. I don't think this is an issue of filtering.

I was able to reproduce the issue with the filter enabled:

/tmp/reproduce $ deno test -A --filter=a x.ts
running 1 test from ./x.ts
a ... FAILED (27ms)

 ERRORS 

a => ./x.ts:5:6
error: Leaks detected:
  - A child process was started during the test, but not closed during the test. Close the child process by calling `proc.kill()` or `proc.close()`.
  - An async operation to wait for a subprocess to exit was started in this test, but never completed. This is often caused by not awaiting the result of a `Deno.Process#status` call.
To get more details where leaks occurred, run again with the --trace-leaks flag.

 FAILURES 

a => ./x.ts:5:6

FAILED | 0 passed | 1 failed (28ms)

error: Test failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctly testing related to deno test and coverage
Projects
None yet
Development

No branches or pull requests

4 participants