Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/multipart/test/dynamic-option.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('test/dynamic-option.test.ts', () => {
});

afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});
afterAll(() => app.close());
afterAll(() => server.close());
Comment on lines 23 to 27

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In Vitest, afterAll hooks are executed sequentially in the order they are registered. Currently, the temporary directory removal (fs.rm) is registered before app.close() and server.close(). This means the test suite attempts to delete the temporary directory while the server and application are still active and potentially holding open file handles or writing files, which is the primary cause of the flaky ENOTEMPTY / EBUSY errors.

Reordering the hooks so that server.close() and app.close() run first ensures that all network activity has ceased and all file handles are released before fs.rm is executed.

Suggested change
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});
afterAll(() => app.close());
afterAll(() => server.close());
afterAll(() => server.close());
afterAll(() => app.close());
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, but this rests on an incorrect premise about Vitest. Vitest's default sequence.hooks is 'stack', so afterAll hooks run in reverse registration order — verified empirically on v4.1.9 (3rd-registered runs first, 1st-registered last). The current order therefore already executes server.close()app.close()fs.rm(...): the tmpdir is removed last, after the server and app are closed. Applying the suggested reorder would move fs.rm to run first, reintroducing exactly the race described. The residual ENOTEMPTY is a transient FS-level race during the recursive removal (macOS APFS / async per-request file cleanup draining), which maxRetries: 3 handles. Keeping the current order + maxRetries.

Expand Down
2 changes: 1 addition & 1 deletion plugins/multipart/test/enable-pathToRegexpModule.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe.skip('test/enable-pathToRegexpModule.test.ts', () => {
host = 'http://127.0.0.1:' + server.address().port;
});
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});
afterAll(() => app.close());
afterAll(() => server.close());
Comment on lines 25 to 29

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In Vitest, afterAll hooks are executed sequentially in the order they are registered. Currently, the temporary directory removal (fs.rm) is registered before app.close() and server.close(). This means the test suite attempts to delete the temporary directory while the server and application are still active and potentially holding open file handles or writing files, which is the primary cause of the flaky ENOTEMPTY / EBUSY errors.

Reordering the hooks so that server.close() and app.close() run first ensures that all network activity has ceased and all file handles are released before fs.rm is executed.

Suggested change
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});
afterAll(() => app.close());
afterAll(() => server.close());
afterAll(() => server.close());
afterAll(() => app.close());
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, but this rests on an incorrect premise about Vitest. Vitest's default sequence.hooks is 'stack', so afterAll hooks run in reverse registration order — verified empirically on v4.1.9 (3rd-registered runs first, 1st-registered last). The current order therefore already executes server.close()app.close()fs.rm(...): the tmpdir is removed last, after the server and app are closed. Applying the suggested reorder would move fs.rm to run first, reintroducing exactly the race described. The residual ENOTEMPTY is a transient FS-level race during the recursive removal (macOS APFS / async per-request file cleanup draining), which maxRetries: 3 handles. Keeping the current order + maxRetries.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('test/file-mode-limit-filesize-per-request.test.ts', () => {
host = 'http://127.0.0.1:' + server.address().port;
});
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});
afterAll(() => app.close());
afterAll(() => server.close());
Comment on lines 24 to 28

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In Vitest, afterAll hooks are executed sequentially in the order they are registered. Currently, the temporary directory removal (fs.rm) is registered before app.close() and server.close(). This means the test suite attempts to delete the temporary directory while the server and application are still active and potentially holding open file handles or writing files, which is the primary cause of the flaky ENOTEMPTY / EBUSY errors.

Reordering the hooks so that server.close() and app.close() run first ensures that all network activity has ceased and all file handles are released before fs.rm is executed.

Suggested change
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});
afterAll(() => app.close());
afterAll(() => server.close());
afterAll(() => server.close());
afterAll(() => app.close());
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, but this rests on an incorrect premise about Vitest. Vitest's default sequence.hooks is 'stack', so afterAll hooks run in reverse registration order — verified empirically on v4.1.9 (3rd-registered runs first, 1st-registered last). The current order therefore already executes server.close()app.close()fs.rm(...): the tmpdir is removed last, after the server and app are closed. Applying the suggested reorder would move fs.rm to run first, reintroducing exactly the race described. The residual ENOTEMPTY is a transient FS-level race during the recursive removal (macOS APFS / async per-request file cleanup draining), which maxRetries: 3 handles. Keeping the current order + maxRetries.

Expand Down
2 changes: 1 addition & 1 deletion plugins/multipart/test/file-mode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('test/file-mode.test.ts', () => {
host = 'http://127.0.0.1:' + server.address().port;
});
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});
afterAll(() => app.close());
afterAll(() => server.close());
Comment on lines 30 to 34

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In Vitest, afterAll hooks are executed sequentially in the order they are registered. Currently, the temporary directory removal (fs.rm) is registered before app.close() and server.close(). This means the test suite attempts to delete the temporary directory while the server and application are still active and potentially holding open file handles or writing files, which is the primary cause of the flaky ENOTEMPTY / EBUSY errors.

Reordering the hooks so that server.close() and app.close() run first ensures that all network activity has ceased and all file handles are released before fs.rm is executed.

Suggested change
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});
afterAll(() => app.close());
afterAll(() => server.close());
afterAll(() => server.close());
afterAll(() => app.close());
afterAll(async () => {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, but this rests on an incorrect premise about Vitest. Vitest's default sequence.hooks is 'stack', so afterAll hooks run in reverse registration order — verified empirically on v4.1.9 (3rd-registered runs first, 1st-registered last). The current order therefore already executes server.close()app.close()fs.rm(...): the tmpdir is removed last, after the server and app are closed. Applying the suggested reorder would move fs.rm to run first, reintroducing exactly the race described. The residual ENOTEMPTY is a transient FS-level race during the recursive removal (macOS APFS / async per-request file cleanup draining), which maxRetries: 3 handles. Keeping the current order + maxRetries.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('test/stream-mode-with-filematch-glob.test.ts', () => {
});
afterAll(async () => {
try {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
} catch (err) {
console.error(err);
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/multipart/test/stream-mode-with-filematch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('test/stream-mode-with-filematch.test.ts', () => {
});
afterAll(async () => {
try {
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
await fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
} catch (err) {
console.error(err);
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/multipart/test/ts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('test/ts.test.ts', () => {
host = 'http://127.0.0.1:' + server.address().port;
});
afterAll(() => {
return fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
return fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});
afterAll(() => app.close());
afterAll(() => server.close());
Comment on lines 27 to 31

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In Vitest, afterAll hooks are executed sequentially in the order they are registered. Currently, the temporary directory removal (fs.rm) is registered before app.close() and server.close(). This means the test suite attempts to delete the temporary directory while the server and application are still active and potentially holding open file handles or writing files, which is the primary cause of the flaky ENOTEMPTY / EBUSY errors.

Reordering the hooks so that server.close() and app.close() run first ensures that all network activity has ceased and all file handles are released before fs.rm is executed.

Suggested change
afterAll(() => {
return fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true });
return fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});
afterAll(() => app.close());
afterAll(() => server.close());
afterAll(() => server.close());
afterAll(() => app.close());
afterAll(() => {
return fs.rm(app.config.multipart.tmpdir, { force: true, recursive: true, maxRetries: 3 });
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, but this rests on an incorrect premise about Vitest. Vitest's default sequence.hooks is 'stack', so afterAll hooks run in reverse registration order — verified empirically on v4.1.9 (3rd-registered runs first, 1st-registered last). The current order therefore already executes server.close()app.close()fs.rm(...): the tmpdir is removed last, after the server and app are closed. Applying the suggested reorder would move fs.rm to run first, reintroducing exactly the race described. The residual ENOTEMPTY is a transient FS-level race during the recursive removal (macOS APFS / async per-request file cleanup draining), which maxRetries: 3 handles. Keeping the current order + maxRetries.

Expand Down
Loading