vitest
vitest copied to clipboard
CTRL+C does not exit tests in watch mode
Describe the bug
When I am running tests in watch mode and make some minor changes in the test files, after a while, vitest can not exit watch mode. Hitting CTRL+C multiple times does not work either. I tried to isolate the problem, but strangely this only happens when some tests are run together.
Running vitest with pnpm run test:server or pnpm run test:native does not make vitest hang. But running pnpm run test:only which is a combination of both previous tests makes vitest hang after a while. In the only-native.spec.ts file I am using Fastify native, in the only-server.spec.ts file Fastify is completely mocked out.
Reproduction
System Info
System:
OS: Linux 5.15 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish)
CPU: (16) x64 AMD Ryzen 7 5700G with Radeon Graphics
Memory: 15.87 GB / 30.73 GB
Container: Yes
Shell: 5.1.16 - /bin/bash
Binaries:
Node: 20.8.0 - ~/.nvm/versions/node/v20.8.0/bin/node
npm: 10.1.0 - ~/.nvm/versions/node/v20.8.0/bin/npm
pnpm: 8.14.0 - ~/.local/share/pnpm/pnpm
Browsers:
Chrome: 120.0.6099.216
npmPackages:
vite: ^5.0.11 => 5.0.11
vitest: ^1.2.0 => 1.2.0
Used Package Manager
npm
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- [X] The provided reproduction is a minimal reproducible example of the bug.
I tried the reproduction case on Github Codespaces but wasn't able to reproduce the issue.
make some minor changes in the test files
Could you write down more specific steps describing what exactly has to be changed in test files?
I mean any changes which trigger a reload of the test watcher, like changing one letter in a test description or making a change for a test to fail. I also could not reproduce the failure on github codespaces, but realized that this happens on my machine only when node is version 20 or 21. With node 16 or 18 I can not reproduce this behavior. I also wiped the whole pnpm file cache and reinstalled everything but it did not make any difference.
I am also seeing this (and have been for a number of weeks) but I am struggling to narrow down what exactly causes the issue.
For me, I start vitest with the vitest command and all is well for a short while. However, after a few minutes of making changes to my code, the test watcher becomes unresponsive and I can't quit using q or crtl-c. I have to close the terminal instance and then issue a SIGSTOP to kill the underlying process. The offending process is also running at 100% CPU when the problem occurs.
I am on node 20, using Kitty terminal emulator on OSX. Vitest v1.
this happens on my machine only when node is version 20 or 21.
I'm unable to reproduce this locally using Node v21 with MacOS.
I created a Dockerfile in which I can reproduce the same error. I added it to my repository. If I build and run the Dockerfile and connect to it from two terminals, then I can run pnpm run test:only in one terminal and edit the statusCode to be 20 with vim src/only-native.spec.ts, than after saving the file, the test runner hangs in the other terminal.
I can reproduce this issue using the provided Dockerfile. Is fastify or some of your dependencies using Node's native fetch? It seems that as soon as I switch Vitest to use --pool=forks the issue goes away.
This looks very much like a duplicate of https://github.com/vitest-dev/vitest/issues/3077 (and https://github.com/vitest-dev/vitest/issues/2008).
It's not really CTRL + c that stops working - it's the whole Node process being stuck. See https://github.com/nodejs/undici/issues/2026.
I am not using in any way fetch from node. What cached my eyes is that the @types/node for version 20 imports the undici-types package. The version for node 18 does not import this package. But this package contains only types. When I use node prior to version 20 or set the flag --pool=forks this issue does not happen.
What cached my eyes is that the
@types/nodefor version 20 imports theundici-typespackage. The version for node 18 does not import this package.
The types for node 18 do as of more recent versions; this is definitely unrelated to the issue.
I am not using in any way
fetchfromnode.
It's possible that the root cause of https://github.com/nodejs/undici/issues/2026 that makes node:worker_threads stuck is not directly fetch - it could be other module like ReadableStream or similar. Maybe one of your dependencies is using those.
I mocked all dependencies out, except the package effection and Fastify, which imports nothing from any other package. It is still the same issue:
fastify-vitest-shutdown
I tried to make a minimal reproduction. When I remove one of the following things than it seems not to fail (with this minimal example it can take many repeated changes before it hangs):
kyselywhich is not used in the functionyield* createPool(...);- Remove any of the
fastify.register(routesBenchmark)orfastify.register(routesScope) fastify.addSchema(schemas)
Using just fastify seems to be enough to make node:worker_threads stuck. Having contents below in two different test files and running them parallel in the docker reproduces the issue. Next step would be to look what fastify is doing under-the-hood and trying to replicate this hang without depending on fastify.
repro.test.ts
import { beforeEach, describe, expect, it, afterEach } from "vitest";
import Fastify, { FastifyInstance } from "fastify";
describe("Test native server", () => {
async function buildFastify() {
const fastify = await Fastify();
fastify.get("/", function (_, reply) {
reply.send({ hello: "world" });
});
return fastify;
}
let fastify: FastifyInstance;
beforeEach(async () => {
fastify = await buildFastify();
});
it("should work", async () => {
fastify.inject(
{
method: "GET",
url: "/",
},
(_, response) => {
expect(response.statusCode).toBe(200);
}
);
await new Promise((resolve) => setTimeout(() => resolve(undefined), 1));
});
afterEach(async () => {
await fastify.close();
});
});
not in watch mode, but when using javascript debug terminal, i guess its more or less same issue https://github.com/vitest-dev/vitest/issues/5039