Skip to content

Commit 8469c89

Browse files
authored
fix(test): harden download tests for Windows EPERM flakiness (#426)
- Clean up temp directories in afterEach to avoid stale file locks - Add retry(2) on Windows to handle Defender file scanning EPERM
1 parent 2bfd3ee commit 8469c89

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

src/download/index.test.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@ import { afterEach, describe, expect, it } from 'vitest';
66
import { formatCookieHeader, httpDownload, resolveRedirectUrl } from './index.js';
77

88
const servers: http.Server[] = [];
9+
const tempDirs: string[] = [];
910

1011
afterEach(async () => {
1112
await Promise.all(servers.map((server) => new Promise<void>((resolve, reject) => {
1213
server.close((err) => (err ? reject(err) : resolve()));
1314
})));
1415
servers.length = 0;
16+
for (const dir of tempDirs) {
17+
try { fs.rmSync(dir, { recursive: true, force: true }); } catch { /* ignore */ }
18+
}
19+
tempDirs.length = 0;
1520
});
1621

1722
async function startServer(handler: http.RequestListener, hostname = '127.0.0.1'): Promise<string> {
@@ -25,7 +30,9 @@ async function startServer(handler: http.RequestListener, hostname = '127.0.0.1'
2530
return `http://${hostname}:${address.port}`;
2631
}
2732

28-
describe('download helpers', () => {
33+
// Windows Defender can briefly lock newly-written .tmp files, causing EPERM.
34+
// Retry once to handle this flakiness.
35+
describe('download helpers', { retry: process.platform === 'win32' ? 2 : 0 }, () => {
2936
it('resolves relative redirects against the original URL', () => {
3037
expect(resolveRedirectUrl('https://example.com/a/file', '/cdn/file.bin')).toBe('https://example.com/cdn/file.bin');
3138
expect(resolveRedirectUrl('https://example.com/a/file', '../next')).toBe('https://example.com/next');
@@ -45,7 +52,8 @@ describe('download helpers', () => {
4552
res.end();
4653
});
4754

48-
const tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'opencli-download-'));
55+
const tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'opencli-dl-'));
56+
tempDirs.push(tempDir);
4957
const destPath = path.join(tempDir, 'file.txt');
5058
const result = await httpDownload(`${baseUrl}/loop`, destPath, { maxRedirects: 2 });
5159

@@ -71,7 +79,8 @@ describe('download helpers', () => {
7179
res.end();
7280
});
7381

74-
const tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'opencli-download-'));
82+
const tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'opencli-dl-'));
83+
tempDirs.push(tempDir);
7584
const destPath = path.join(tempDir, 'redirect.txt');
7685
const result = await httpDownload(`${redirectUrl}/start`, destPath, { cookies: 'sid=abc' });
7786

@@ -94,7 +103,8 @@ describe('download helpers', () => {
94103
res.end();
95104
});
96105

97-
const tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'opencli-download-'));
106+
const tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'opencli-dl-'));
107+
tempDirs.push(tempDir);
98108
const destPath = path.join(tempDir, 'redirect-header.txt');
99109
const result = await httpDownload(`${redirectUrl}/start`, destPath, {
100110
headers: { Cookie: 'sid=header-cookie' },

0 commit comments

Comments
 (0)