test: deflake stream-readable-to-web test · nodejs/node@244d0c3

Original file line numberDiff line numberDiff line change

@@ -0,0 +1,64 @@

1+

import { mustCall } from '../common/index.mjs';

2+

import { Readable } from 'node:stream';

3+

import { memoryUsage } from 'node:process';

4+

import assert from 'node:assert';

5+

import { setImmediate } from 'node:timers/promises';

6+
7+

// Based on: https://github.com/nodejs/node/issues/46347#issuecomment-1413886707

8+

// edit: make it cross-platform as /dev/urandom is not available on Windows

9+
10+

const MAX_MEM = 256 * 1024 * 1024; // 256 MiB

11+
12+

function checkMemoryUsage() {

13+

assert(memoryUsage().arrayBuffers < MAX_MEM);

14+

}

15+
16+

const MAX_BUFFERS = 1000;

17+

let buffersCreated = 0;

18+
19+

const randomNodeStream = new Readable({

20+

read(size) {

21+

if (buffersCreated >= MAX_BUFFERS) {

22+

this.push(null);

23+

return;

24+

}

25+
26+

this.push(Buffer.alloc(size));

27+

buffersCreated++;

28+

}

29+

});

30+
31+

randomNodeStream.on('error', (err) => {

32+

assert.fail(err);

33+

});

34+
35+

// Before doing anything, make sure memory usage is okay

36+

checkMemoryUsage();

37+
38+

// Create stream and check memory usage remains okay

39+
40+

const randomWebStream = Readable.toWeb(randomNodeStream);

41+
42+

checkMemoryUsage();

43+
44+

let timeout;

45+

try {

46+

// Wait two seconds before consuming the stream to see if memory usage increases

47+

timeout = setTimeout(mustCall(async () => {

48+

// Did the stream leak memory?

49+

checkMemoryUsage();

50+

// eslint-disable-next-line no-unused-vars

51+

for await (const _ of randomWebStream) {

52+

// Yield event loop to allow garbage collection

53+

await setImmediate();

54+

// consume the stream

55+

// check memory usage remains okay

56+

checkMemoryUsage();

57+

}

58+

}), 2000);

59+

} catch (err) {

60+

if (timeout) {

61+

clearTimeout(timeout);

62+

}

63+

assert.fail(err);

64+

}