nodejs / nodejs/node

Test runner with isolation=none does not work in child process

未关闭
#60,020 6 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

child_process test_runner
主要语言
JavaScript
星标
122k
派生
37.4k
平均合并
4 天 3 小时
30 天内合并 PR
272

描述

Version

v24.9.0

Platform
Linux home 5.15.0-153-generic #163-Ubuntu SMP Thu Aug 7 16:37:18 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Subsystem

No response

What steps will reproduce the bug?

runner.js

import cluster from 'node:cluster';
import { run } from "node:test";

if (cluster.isPrimary) {
  cluster.fork();
} else {
  const stream = run({
    isolation: "none",
  });

  stream.on("data", (data) => {
    console.log("on data", data.type);
  });

  stream.on("end", () => {
    console.log("on end")
    process.exit(0);
  });

  stream.on("error", (err) => {
    console.log("on error", err);
  });
}

dummy.test.js

import { describe, it } from "node:test";
import * as assert from "node:assert";

describe("suite", () => {
  it("works", ()  => {
    assert.ok(true);
  });
});

How often does it reproduce? Is there a required condition?

Always. No.

What is the expected behavior? Why is that the expected behavior?

With isolation: "process" (the default), here's the output:

on data test:enqueue
on data test:dequeue
on data test:enqueue
on data test:dequeue
on data test:enqueue
on data test:dequeue
on data test:complete
on data test:start
on data test:start
on data test:pass
on data test:complete
on data test:plan
on data test:pass
on data test:summary
on data test:complete
on data test:plan
on data test:diagnostic
on data test:diagnostic
on data test:diagnostic
on data test:diagnostic
on data test:diagnostic
on data test:diagnostic
on data test:diagnostic
on data test:diagnostic
on data test:summary
on end

Process finished with exit code 0

The process cleanly exits at the end of the tests.

What do you see instead?

With isolation: "none", here's the output:

on data test:enqueue
on data test:dequeue
on data test:enqueue
on data test:dequeue
on data test:complete
on data test:start
on data test:start
on data test:pass
on data test:complete
on data test:plan
on data test:pass

And the process hangs.

Additional information

The goal was to use the "cluster" module to run the tests in parallel with the shard option:

import { run } from "node:test";
import { spec } from "node:test/reporters";
import { PassThrough } from "node:stream";
import { availableParallelism } from "node:os";
import cluster from 'node:cluster';

const concurrency = availableParallelism();
let completed = 0;

if (cluster.isPrimary) {
  const mergedStream = new PassThrough({
    objectMode: true
  });

  cluster.on("message", (_worker, message) => {
    mergedStream.emit("data", message);
  });

  mergedStream
    .compose(spec)
    .pipe(process.stdout);

  for (let i = 1; i <= concurrency; i++) {
    cluster.fork({
      SHARD_INDEX: i,
      SHARD_TOTAL: concurrency,
    });
  }

  cluster.on("exit", (worker, code, signal) => {
    if (++completed === concurrency) {
      mergedStream.end();
    }
  });
} else {
  const stream = run({
    isolation: "none",
    shard: {
      index: parseInt(process.env.SHARD_INDEX, 10),
      total: parseInt(process.env.SHARD_TOTAL, 10),
    },
  });

  stream.on("data", (chunk) => {
    process.send(chunk);
  });
}

Related: https://github.com/nodejs/node/issues/55939

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

先在 runner.js 和 dummy.test.js 中进行复现,然后跟踪从 cluster 子进程调用时 isolation 设置为 "none" 的 node:test run() 入口点。将其流生命周期与默认的 "process" isolation 以及相关 issue 55939 进行比较。当子进程流发出剩余事件、结束并干净地退出,同时保留 shard 支持时,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript, node.js
领域
testing-qa
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
活跃
描述清晰度
基本清楚
新手友好度
55/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。