Skip to content

test_runner: --test-force-exit does not end a run held open by a leaked child with inherited stdio (Linux) #66336

Description

@thejebo

Version

v22.23.3, v24.21.0

Platform

Linux x64: official node:22-bookworm and node:24-bookworm Docker images. Not reproducible on Windows.

Subsystem

test_runner

What steps will reproduce the bug?

// leak.test.mjs
import { test } from 'node:test';
import { spawn } from 'node:child_process';

test('leaks a child with inherited stdio', () => {
  spawn(process.execPath, ['-e', 'setTimeout(() => {}, 20000)'], { stdio: 'inherit' });
});
time node --test --test-force-exit leak.test.mjs

How often does it reproduce?

Every run we measured.

What is the expected behavior?

The run ends shortly after the test passes, as it does on Windows (about 1 s). --test-force-exit is documented to exit the process once all known tests have finished, even if the event loop would otherwise stay active.

What do you see instead?

The test passes immediately, but the run does not end until the leaked child exits: 20 s for a child that lives 20 s. That happened on both versions above, with --test-force-exit and with or without a preload that makes stdout blocking.

Our reading: the per-file test process does exit, but the child still holds a copy of that process's stdout pipe (inherited), and the parent runner waits for the pipe to close. Nothing inside the test process can close another process's copy of the pipe, so the test file itself cannot work around it.

Additional information

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions