Skip to content

Commit 2e8a4b1

Browse files
test: deflake fastutf8stream destroy and reopen tests
Both tests read the destination file with no ordering guarantee against the fs.write() that Utf8Stream still has in flight, so under load the read can observe an empty file. In test-fastutf8stream-destroy the read is issued right after destroy(). In test-fastutf8stream-reopen it is ordered on 'drain', documented as emitted when the buffer has drained enough to allow continued writing, which says nothing about the bytes being observable in the file. The reopen path also emits a 'drain' of its own from a nextTick before the write has landed. Order both reads on 'write' instead, documented as emitted when a write operation has completed and emitted from #release() once the underlying write returned. In sync mode it is emitted from within write(), so the listener is attached before the write call. No data is lost by Utf8Stream here: re-reading the file after a failed assertion shows the expected content. This corrects an expectation of the tests, not the runtime. Signed-off-by: Christian Aurich <christian.aurichzm@gmail.com> PR-URL: #65554 Refs: https://github.com/nodejs/reliability/blob/main/reports/2026-08-20.md Refs: https://github.com/nodejs/reliability/blob/main/reports/2026-08-26.md Reviewed-By: Shelley Vohr <shelley.vohr@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
1 parent 37887a3 commit 2e8a4b1

2 files changed

Lines changed: 14 additions & 8 deletions

File tree

test/parallel/test-fastutf8stream-destroy.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ function getTempFile() {
3434

3535
assert.throws(() => stream.write('hello world\n'), Error);
3636

37-
readFile(dest, 'utf8', common.mustSucceed((data) => {
38-
assert.strictEqual(data, 'hello world\n');
37+
// Reading now would race the fs.write() still in flight.
38+
stream.once('write', common.mustCall(() => {
39+
readFile(dest, 'utf8', common.mustSucceed((data) => {
40+
assert.strictEqual(data, 'hello world\n');
41+
}));
3942
}));
4043

4144
stream.on('finish', common.mustNotCall());

test/parallel/test-fastutf8stream-reopen.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ function runTests(sync) {
4343
stream.reopen();
4444

4545
stream.once('ready', common.mustCall(() => {
46-
assert.ok(stream.write('after reopen\n'));
47-
48-
stream.once('drain', common.mustCall(() => {
46+
// 'drain' can come from reopen() before this write completes. 'write'
47+
// is emitted synchronously in sync mode, so attach before writing.
48+
stream.once('write', common.mustCall(() => {
4949
readFile(after, 'utf8', common.mustSucceed((data) => {
5050
assert.strictEqual(data, 'hello world\nsomething else\n');
5151
readFile(dest, 'utf8', common.mustSucceed((data) => {
@@ -54,6 +54,8 @@ function runTests(sync) {
5454
}));
5555
}));
5656
}));
57+
58+
assert.ok(stream.write('after reopen\n'));
5759
}));
5860
}));
5961
}
@@ -85,9 +87,8 @@ function runTests(sync) {
8587
assert.strictEqual(stream.file, after);
8688

8789
stream.once('ready', common.mustCall(() => {
88-
assert.ok(stream.write('after reopen\n'));
89-
90-
stream.once('drain', common.mustCall(() => {
90+
// As above: 'drain' can come from reopen() before the write completes.
91+
stream.once('write', common.mustCall(() => {
9192
readFile(dest, 'utf8', common.mustSucceed((data) => {
9293
assert.strictEqual(data, 'hello world\nsomething else\n');
9394
readFile(after, 'utf8', common.mustSucceed((data) => {
@@ -96,6 +97,8 @@ function runTests(sync) {
9697
}));
9798
}));
9899
}));
100+
101+
assert.ok(stream.write('after reopen\n'));
99102
}));
100103
}));
101104
}

0 commit comments

Comments
 (0)