Skip to content

Commit 9eb8bf1

Browse files
LiviaMedeirosBethGriggs
authored andcommitted
test: reduce flakiness of test-fs-read-position-validation.mjs
PR-URL: #42999 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 531a0a9 commit 9eb8bf1

File tree

2 files changed

+107
-66
lines changed

2 files changed

+107
-66
lines changed

test/parallel/test-fs-read-position-validation.mjs

+27-66
Original file line numberDiff line numberDiff line change
@@ -14,73 +14,27 @@ const length = buffer.byteLength;
1414
// allowedErrors is an array of acceptable internal errors
1515
// For example, on some platforms read syscall might return -EFBIG
1616
async function testValid(position, allowedErrors = []) {
17-
let fdSync;
18-
try {
19-
fdSync = fs.openSync(filepath, 'r');
20-
fs.readSync(fdSync, buffer, offset, length, position);
21-
fs.readSync(fdSync, buffer, { offset, length, position });
22-
} catch (err) {
23-
if (!allowedErrors.includes(err.code)) {
24-
assert.fail(err);
25-
}
26-
} finally {
27-
if (fdSync) fs.closeSync(fdSync);
28-
}
29-
30-
fs.open(filepath, 'r', common.mustSucceed((fd) => {
31-
try {
32-
if (allowedErrors.length) {
33-
fs.read(fd, buffer, offset, length, position, common.mustCall((err, ...results) => {
34-
if (err && !allowedErrors.includes(err.code)) {
35-
assert.fail(err);
36-
}
37-
}));
38-
fs.read(fd, { buffer, offset, length, position }, common.mustCall((err, ...results) => {
39-
if (err && !allowedErrors.includes(err.code)) {
40-
assert.fail(err);
41-
}
42-
}));
43-
} else {
44-
fs.read(fd, buffer, offset, length, position, common.mustSucceed());
45-
fs.read(fd, { buffer, offset, length, position }, common.mustSucceed());
46-
}
47-
} finally {
48-
fs.close(fd, common.mustSucceed());
49-
}
50-
}));
51-
}
52-
53-
async function testInvalid(code, position, internalCatch = false) {
54-
let fdSync;
55-
try {
56-
fdSync = fs.openSync(filepath, 'r');
57-
assert.throws(
58-
() => fs.readSync(fdSync, buffer, offset, length, position),
59-
{ code }
60-
);
61-
assert.throws(
62-
() => fs.readSync(fdSync, buffer, { offset, length, position }),
63-
{ code }
64-
);
65-
} finally {
66-
if (fdSync) fs.closeSync(fdSync);
67-
}
68-
69-
// Set this flag for catching errors via first argument of callback function
70-
if (internalCatch) {
17+
return new Promise((resolve, reject) => {
7118
fs.open(filepath, 'r', common.mustSucceed((fd) => {
72-
try {
73-
fs.read(fd, buffer, offset, length, position, (err, ...results) => {
74-
assert.strictEqual(err.code, code);
75-
});
76-
fs.read(fd, { buffer, offset, length, position }, (err, ...results) => {
77-
assert.strictEqual(err.code, code);
78-
});
79-
} finally {
80-
fs.close(fd, common.mustSucceed());
81-
}
19+
let callCount = 3;
20+
const handler = common.mustCall((err) => {
21+
callCount--;
22+
if (err && !allowedErrors.includes(err.code)) {
23+
fs.close(fd, common.mustSucceed());
24+
reject(err);
25+
} else if (callCount === 0) {
26+
fs.close(fd, common.mustSucceed(resolve));
27+
}
28+
}, callCount);
29+
fs.read(fd, buffer, offset, length, position, handler);
30+
fs.read(fd, { buffer, offset, length, position }, handler);
31+
fs.read(fd, buffer, { offset, length, position }, handler);
8232
}));
83-
} else {
33+
});
34+
}
35+
36+
async function testInvalid(code, position) {
37+
return new Promise((resolve, reject) => {
8438
fs.open(filepath, 'r', common.mustSucceed((fd) => {
8539
try {
8640
assert.throws(
@@ -91,11 +45,18 @@ async function testInvalid(code, position, internalCatch = false) {
9145
() => fs.read(fd, { buffer, offset, length, position }, common.mustNotCall()),
9246
{ code }
9347
);
48+
assert.throws(
49+
() => fs.read(fd, buffer, { offset, length, position }, common.mustNotCall()),
50+
{ code }
51+
);
52+
resolve();
53+
} catch (err) {
54+
reject(err);
9455
} finally {
9556
fs.close(fd, common.mustSucceed());
9657
}
9758
}));
98-
}
59+
});
9960
}
10061

10162
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import '../common/index.mjs';
2+
import * as fixtures from '../common/fixtures.mjs';
3+
import fs from 'fs';
4+
import assert from 'assert';
5+
6+
// This test ensures that "position" argument is correctly validated
7+
8+
const filepath = fixtures.path('x.txt');
9+
10+
const buffer = Buffer.from('xyz\n');
11+
const offset = 0;
12+
const length = buffer.byteLength;
13+
14+
// allowedErrors is an array of acceptable internal errors
15+
// For example, on some platforms read syscall might return -EFBIG
16+
function testValid(position, allowedErrors = []) {
17+
let fdSync;
18+
try {
19+
fdSync = fs.openSync(filepath, 'r');
20+
fs.readSync(fdSync, buffer, offset, length, position);
21+
fs.readSync(fdSync, buffer, { offset, length, position });
22+
} catch (err) {
23+
if (!allowedErrors.includes(err.code)) {
24+
assert.fail(err);
25+
}
26+
} finally {
27+
if (fdSync) fs.closeSync(fdSync);
28+
}
29+
}
30+
31+
function testInvalid(code, position, internalCatch = false) {
32+
let fdSync;
33+
try {
34+
fdSync = fs.openSync(filepath, 'r');
35+
assert.throws(
36+
() => fs.readSync(fdSync, buffer, offset, length, position),
37+
{ code }
38+
);
39+
assert.throws(
40+
() => fs.readSync(fdSync, buffer, { offset, length, position }),
41+
{ code }
42+
);
43+
} finally {
44+
if (fdSync) fs.closeSync(fdSync);
45+
}
46+
}
47+
48+
{
49+
testValid(undefined);
50+
testValid(null);
51+
testValid(-1);
52+
testValid(-1n);
53+
54+
testValid(0);
55+
testValid(0n);
56+
testValid(1);
57+
testValid(1n);
58+
testValid(9);
59+
testValid(9n);
60+
testValid(Number.MAX_SAFE_INTEGER, [ 'EFBIG' ]);
61+
62+
testValid(2n ** 63n - 1n - BigInt(length), [ 'EFBIG' ]);
63+
testInvalid('ERR_OUT_OF_RANGE', 2n ** 63n);
64+
65+
// TODO(LiviaMedeiros): test `2n ** 63n - BigInt(length)`
66+
67+
testInvalid('ERR_OUT_OF_RANGE', NaN);
68+
testInvalid('ERR_OUT_OF_RANGE', -Infinity);
69+
testInvalid('ERR_OUT_OF_RANGE', Infinity);
70+
testInvalid('ERR_OUT_OF_RANGE', -0.999);
71+
testInvalid('ERR_OUT_OF_RANGE', -(2n ** 64n));
72+
testInvalid('ERR_OUT_OF_RANGE', Number.MAX_SAFE_INTEGER + 1);
73+
testInvalid('ERR_OUT_OF_RANGE', Number.MAX_VALUE);
74+
75+
for (const badTypeValue of [
76+
false, true, '1', Symbol(1), {}, [], () => {}, Promise.resolve(1),
77+
]) {
78+
testInvalid('ERR_INVALID_ARG_TYPE', badTypeValue);
79+
}
80+
}

0 commit comments

Comments
 (0)