• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --experimental-abortcontroller
2'use strict';
3const common = require('../common');
4
5// This test ensures that fs.readFile correctly returns the
6// contents of varying-sized files.
7
8const tmpdir = require('../../test/common/tmpdir');
9const assert = require('assert');
10const fs = require('fs');
11const path = require('path');
12
13const prefix = `.removeme-fs-readfile-${process.pid}`;
14
15tmpdir.refresh();
16
17const fileInfo = [
18  { name: path.join(tmpdir.path, `${prefix}-1K.txt`),
19    len: 1024 },
20  { name: path.join(tmpdir.path, `${prefix}-64K.txt`),
21    len: 64 * 1024 },
22  { name: path.join(tmpdir.path, `${prefix}-64KLessOne.txt`),
23    len: (64 * 1024) - 1 },
24  { name: path.join(tmpdir.path, `${prefix}-1M.txt`),
25    len: 1 * 1024 * 1024 },
26  { name: path.join(tmpdir.path, `${prefix}-1MPlusOne.txt`),
27    len: (1 * 1024 * 1024) + 1 },
28];
29
30// Populate each fileInfo (and file) with unique fill.
31const sectorSize = 512;
32for (const e of fileInfo) {
33  e.contents = Buffer.allocUnsafe(e.len);
34
35  // This accounts for anything unusual in Node's implementation of readFile.
36  // Using e.g. 'aa...aa' would miss bugs like Node re-reading
37  // the same section twice instead of two separate sections.
38  for (let offset = 0; offset < e.len; offset += sectorSize) {
39    const fillByte = 256 * Math.random();
40    const nBytesToFill = Math.min(sectorSize, e.len - offset);
41    e.contents.fill(fillByte, offset, offset + nBytesToFill);
42  }
43
44  fs.writeFileSync(e.name, e.contents);
45}
46// All files are now populated.
47
48// Test readFile on each size.
49for (const e of fileInfo) {
50  fs.readFile(e.name, common.mustCall((err, buf) => {
51    console.log(`Validating readFile on file ${e.name} of length ${e.len}`);
52    assert.ifError(err);
53    assert.deepStrictEqual(buf, e.contents);
54  }));
55}
56{
57  // Test cancellation, before
58  const controller = new AbortController();
59  const signal = controller.signal;
60  controller.abort();
61  fs.readFile(fileInfo[0].name, { signal }, common.mustCall((err, buf) => {
62    assert.strictEqual(err.name, 'AbortError');
63  }));
64}
65{
66  // Test cancellation, during read
67  const controller = new AbortController();
68  const signal = controller.signal;
69  fs.readFile(fileInfo[0].name, { signal }, common.mustCall((err, buf) => {
70    assert.strictEqual(err.name, 'AbortError');
71  }));
72  process.nextTick(() => controller.abort());
73}
74{
75  // Verify that if something different than Abortcontroller.signal
76  // is passed, ERR_INVALID_ARG_TYPE is thrown
77  assert.throws(() => {
78    const callback = common.mustNotCall(() => {});
79    fs.readFile(fileInfo[0].name, { signal: 'hello' }, callback);
80  }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' });
81}
82