From 2748595fd2338864e64089a052e76863462b0851 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Tue, 21 Apr 2026 18:10:46 -0700 Subject: [PATCH] test: fix race in FetchDownloader write-stream failure test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test emitted the write-stream error via setTimeout(..., 0). With the fetch-based downloader the ~2 KB response body is typically already buffered when fetch() resolves, so pipeline() can drain it entirely via microtasks and resolve before the setTimeout macrotask fires — the promise resolves instead of rejecting. Inject the error deterministically by overriding _write/_writev on the returned WriteStream so it fails the moment pipeline() flushes data, matching how a real ENOSPC surfaces. Both overrides are needed because chunks that arrive during the async file-open (_construct) are drained via _writev rather than _write. --- test/FetchDownloader.network.spec.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/FetchDownloader.network.spec.ts b/test/FetchDownloader.network.spec.ts index 44381b27..8a66af3e 100644 --- a/test/FetchDownloader.network.spec.ts +++ b/test/FetchDownloader.network.spec.ts @@ -50,10 +50,12 @@ describe('FetchDownloader', () => { it('should throw an error if the file write stream fails', async () => { const downloader = new FetchDownloader(); const createWriteStream = fs.createWriteStream; + const writeError = new Error('ENOSPC: no space left on device, write'); const spy = vi.spyOn(fs, 'createWriteStream'); spy.mockImplementationOnce((path: PathLike) => { const stream = createWriteStream(path); - setTimeout(() => stream.emit('error', 'bad write error thing'), 0); + stream._write = (_chunk, _encoding, callback): void => callback(writeError); + stream._writev = (_chunks, callback): void => callback(writeError); return stream; }); await withTempDirectory(async (dir) => { @@ -63,8 +65,9 @@ describe('FetchDownloader', () => { 'https://github.com/electron/electron/releases/download/v2.0.18/SHASUMS256.txt', testFile, ), - ).rejects.toMatchInlineSnapshot(`"bad write error thing"`); + ).rejects.toThrowError(writeError); }, TempDirCleanUpMode.CLEAN); + spy.mockRestore(); }); it('should download to a deep uncreated path', async () => {