forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtest-fs-readfile.js
101 lines (88 loc) · 3.19 KB
/
test-fs-readfile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
'use strict';
const common = require('../common');
// This test ensures that fs.readFile correctly returns the
// contents of varying-sized files.
const tmpdir = require('../../test/common/tmpdir');
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const prefix = `.removeme-fs-readfile-${process.pid}`;
tmpdir.refresh();
const fileInfo = [
{ name: path.join(tmpdir.path, `${prefix}-1K.txt`),
len: 1024 },
{ name: path.join(tmpdir.path, `${prefix}-64K.txt`),
len: 64 * 1024 },
{ name: path.join(tmpdir.path, `${prefix}-64KLessOne.txt`),
len: (64 * 1024) - 1 },
{ name: path.join(tmpdir.path, `${prefix}-1M.txt`),
len: 1 * 1024 * 1024 },
{ name: path.join(tmpdir.path, `${prefix}-1MPlusOne.txt`),
len: (1 * 1024 * 1024) + 1 },
];
// Populate each fileInfo (and file) with unique fill.
const sectorSize = 512;
for (const e of fileInfo) {
e.contents = Buffer.allocUnsafe(e.len);
// This accounts for anything unusual in Node's implementation of readFile.
// Using e.g. 'aa...aa' would miss bugs like Node re-reading
// the same section twice instead of two separate sections.
for (let offset = 0; offset < e.len; offset += sectorSize) {
const fillByte = 256 * Math.random();
const nBytesToFill = Math.min(sectorSize, e.len - offset);
e.contents.fill(fillByte, offset, offset + nBytesToFill);
}
fs.writeFileSync(e.name, e.contents);
}
// All files are now populated.
// Test readFile on each size.
for (const e of fileInfo) {
fs.readFile(e.name, common.mustCall((err, buf) => {
console.log(`Validating readFile on file ${e.name} of length ${e.len}`);
assert.ifError(err);
assert.deepStrictEqual(buf, e.contents);
}));
}
// readFile() and readFileSync() should fail if the file is too big.
{
const kIoMaxLength = 2 ** 31 - 1;
if (!tmpdir.hasEnoughSpace(kIoMaxLength)) {
// truncateSync() will fail with ENOSPC if there is not enough space.
common.printSkipMessage(`Not enough space in ${tmpdir.path}`);
} else {
const file = path.join(tmpdir.path, `${prefix}-too-large.txt`);
fs.writeFileSync(file, Buffer.from('0'));
fs.truncateSync(file, kIoMaxLength + 1);
fs.readFile(file, common.expectsError({
code: 'ERR_FS_FILE_TOO_LARGE',
name: 'RangeError',
}));
assert.throws(() => {
fs.readFileSync(file);
}, { code: 'ERR_FS_FILE_TOO_LARGE', name: 'RangeError' });
}
}
{
// Test cancellation, before
const signal = AbortSignal.abort();
fs.readFile(fileInfo[0].name, { signal }, common.mustCall((err, buf) => {
assert.strictEqual(err.name, 'AbortError');
}));
}
{
// Test cancellation, during read
const controller = new AbortController();
const signal = controller.signal;
fs.readFile(fileInfo[0].name, { signal }, common.mustCall((err, buf) => {
assert.strictEqual(err.name, 'AbortError');
}));
process.nextTick(() => controller.abort());
}
{
// Verify that if something different than Abortcontroller.signal
// is passed, ERR_INVALID_ARG_TYPE is thrown
assert.throws(() => {
const callback = common.mustNotCall(() => {});
fs.readFile(fileInfo[0].name, { signal: 'hello' }, callback);
}, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' });
}