Skip to content

Commit 772fdb0

Browse files
committed
test: fix flaky test-fs-stream-construct
The test is marked flaky on ARM because it times out on Raspberry Pi devices in CI. Split the single test file into four separate test files to ease debugging. Add fs.close() to avoid timing out. Fixes: #33796 PR-URL: #34203 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Robert Nagy <ronagy@icloud.com>
1 parent ee3416b commit 772fdb0

6 files changed

+249
-214
lines changed

test/parallel/parallel.status

-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ test-async-hooks-http-parser-destroy: PASS,FLAKY
4040
# https://github.com/nodejs/node/pull/31178
4141
test-crypto-dh-stateless: SKIP
4242
test-crypto-keygen: SKIP
43-
# https://github.com/nodejs/node/issues/33796
44-
test-fs-stream-construct: PASS,FLAKY
4543

4644
[$system==solaris] # Also applies to SmartOS
4745

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fs = require('fs');
5+
const assert = require('assert');
6+
7+
const tmpdir = require('../common/tmpdir');
8+
tmpdir.refresh();
9+
10+
{
11+
// Compat error.
12+
13+
function ReadStream(...args) {
14+
fs.ReadStream.call(this, ...args);
15+
}
16+
Object.setPrototypeOf(ReadStream.prototype, fs.ReadStream.prototype);
17+
Object.setPrototypeOf(ReadStream, fs.ReadStream);
18+
19+
ReadStream.prototype.open = common.mustCall(function ReadStream$open() {
20+
const that = this;
21+
fs.open(that.path, that.flags, that.mode, (err, fd) => {
22+
that.emit('error', err);
23+
});
24+
});
25+
26+
const r = new ReadStream('/doesnotexist', { emitClose: true })
27+
.on('error', common.mustCall((err) => {
28+
assert.strictEqual(err.code, 'ENOENT');
29+
assert.strictEqual(r.destroyed, true);
30+
r.on('close', common.mustCall());
31+
}));
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fs = require('fs');
5+
const assert = require('assert');
6+
7+
const debuglog = (arg) => {
8+
console.log(new Date().toLocaleString(), arg);
9+
};
10+
11+
const tmpdir = require('../common/tmpdir');
12+
tmpdir.refresh();
13+
14+
{
15+
// Compat error.
16+
debuglog('start test');
17+
18+
function WriteStream(...args) {
19+
debuglog('WriteStream constructor');
20+
fs.WriteStream.call(this, ...args);
21+
}
22+
Object.setPrototypeOf(WriteStream.prototype, fs.WriteStream.prototype);
23+
Object.setPrototypeOf(WriteStream, fs.WriteStream);
24+
25+
WriteStream.prototype.open = common.mustCall(function WriteStream$open() {
26+
debuglog('WriteStream open() callback');
27+
const that = this;
28+
fs.open(that.path, that.flags, that.mode, (err, fd) => {
29+
debuglog('inner fs open() callback');
30+
that.emit('error', err);
31+
});
32+
});
33+
34+
fs.open(`${tmpdir.path}/dummy`, 'wx+', common.mustCall((err, fd) => {
35+
debuglog('fs open() callback');
36+
assert.ifError(err);
37+
fs.close(fd, () => { debuglog(`closed ${fd}`); });
38+
const w = new WriteStream(`${tmpdir.path}/dummy`,
39+
{ flags: 'wx+', emitClose: true })
40+
.on('error', common.mustCall((err) => {
41+
debuglog('error event callback');
42+
assert.strictEqual(err.code, 'EEXIST');
43+
w.destroy();
44+
w.on('close', common.mustCall(() => {
45+
debuglog('close event callback');
46+
}));
47+
}));
48+
}));
49+
debuglog('waiting for callbacks');
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fs = require('fs');
5+
const assert = require('assert');
6+
const fixtures = require('../common/fixtures');
7+
8+
const tmpdir = require('../common/tmpdir');
9+
tmpdir.refresh();
10+
11+
{
12+
// Compat with graceful-fs.
13+
14+
function ReadStream(...args) {
15+
fs.ReadStream.call(this, ...args);
16+
}
17+
Object.setPrototypeOf(ReadStream.prototype, fs.ReadStream.prototype);
18+
Object.setPrototypeOf(ReadStream, fs.ReadStream);
19+
20+
ReadStream.prototype.open = common.mustCall(function ReadStream$open() {
21+
const that = this;
22+
fs.open(that.path, that.flags, that.mode, (err, fd) => {
23+
if (err) {
24+
if (that.autoClose)
25+
that.destroy();
26+
27+
that.emit('error', err);
28+
} else {
29+
that.fd = fd;
30+
that.emit('open', fd);
31+
that.read();
32+
}
33+
});
34+
});
35+
36+
const r = new ReadStream(fixtures.path('x.txt'))
37+
.on('open', common.mustCall((fd) => {
38+
assert.strictEqual(fd, r.fd);
39+
r.destroy();
40+
}));
41+
}
42+
43+
{
44+
// Compat with graceful-fs.
45+
46+
function WriteStream(...args) {
47+
fs.WriteStream.call(this, ...args);
48+
}
49+
Object.setPrototypeOf(WriteStream.prototype, fs.WriteStream.prototype);
50+
Object.setPrototypeOf(WriteStream, fs.WriteStream);
51+
52+
WriteStream.prototype.open = common.mustCall(function WriteStream$open() {
53+
const that = this;
54+
fs.open(that.path, that.flags, that.mode, function(err, fd) {
55+
if (err) {
56+
that.destroy();
57+
that.emit('error', err);
58+
} else {
59+
that.fd = fd;
60+
that.emit('open', fd);
61+
}
62+
});
63+
});
64+
65+
const w = new WriteStream(`${tmpdir.path}/dummy`)
66+
.on('open', common.mustCall((fd) => {
67+
assert.strictEqual(fd, w.fd);
68+
w.destroy();
69+
}));
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fs = require('fs');
5+
const assert = require('assert');
6+
const fixtures = require('../common/fixtures');
7+
8+
const tmpdir = require('../common/tmpdir');
9+
tmpdir.refresh();
10+
11+
{
12+
// Compat with old node.
13+
14+
function ReadStream(...args) {
15+
fs.ReadStream.call(this, ...args);
16+
}
17+
Object.setPrototypeOf(ReadStream.prototype, fs.ReadStream.prototype);
18+
Object.setPrototypeOf(ReadStream, fs.ReadStream);
19+
20+
ReadStream.prototype.open = common.mustCall(function() {
21+
fs.open(this.path, this.flags, this.mode, (er, fd) => {
22+
if (er) {
23+
if (this.autoClose) {
24+
this.destroy();
25+
}
26+
this.emit('error', er);
27+
return;
28+
}
29+
30+
this.fd = fd;
31+
this.emit('open', fd);
32+
this.emit('ready');
33+
});
34+
});
35+
36+
let readyCalled = false;
37+
let ticked = false;
38+
const r = new ReadStream(fixtures.path('x.txt'))
39+
.on('ready', common.mustCall(() => {
40+
readyCalled = true;
41+
// Make sure 'ready' is emitted in same tick as 'open'.
42+
assert.strictEqual(ticked, false);
43+
}))
44+
.on('error', common.mustNotCall())
45+
.on('open', common.mustCall((fd) => {
46+
process.nextTick(() => {
47+
ticked = true;
48+
r.destroy();
49+
});
50+
assert.strictEqual(readyCalled, false);
51+
assert.strictEqual(fd, r.fd);
52+
}));
53+
}
54+
55+
{
56+
// Compat with old node.
57+
58+
function WriteStream(...args) {
59+
fs.WriteStream.call(this, ...args);
60+
}
61+
Object.setPrototypeOf(WriteStream.prototype, fs.WriteStream.prototype);
62+
Object.setPrototypeOf(WriteStream, fs.WriteStream);
63+
64+
WriteStream.prototype.open = common.mustCall(function() {
65+
fs.open(this.path, this.flags, this.mode, (er, fd) => {
66+
if (er) {
67+
if (this.autoClose) {
68+
this.destroy();
69+
}
70+
this.emit('error', er);
71+
return;
72+
}
73+
74+
this.fd = fd;
75+
this.emit('open', fd);
76+
this.emit('ready');
77+
});
78+
});
79+
80+
let readyCalled = false;
81+
let ticked = false;
82+
const w = new WriteStream(`${tmpdir.path}/dummy`)
83+
.on('ready', common.mustCall(() => {
84+
readyCalled = true;
85+
// Make sure 'ready' is emitted in same tick as 'open'.
86+
assert.strictEqual(ticked, false);
87+
}))
88+
.on('error', common.mustNotCall())
89+
.on('open', common.mustCall((fd) => {
90+
process.nextTick(() => {
91+
ticked = true;
92+
w.destroy();
93+
});
94+
assert.strictEqual(readyCalled, false);
95+
assert.strictEqual(fd, w.fd);
96+
}));
97+
}

0 commit comments

Comments
 (0)