summaryrefslogtreecommitdiff
path: root/test/parallel/test-fs-promises-file-handle-readFile.js
blob: 3c6815973cb54b13fa352bcc4a77a450ab4f6fd2 (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
'use strict';

const common = require('../common');

// The following tests validate base functionality for the fs.promises
// FileHandle.readFile method.

const fs = require('fs');
const {
  open,
  readFile,
  writeFile,
  truncate,
} = fs.promises;
const path = require('path');
const tmpdir = require('../common/tmpdir');
const tick = require('../common/tick');
const assert = require('assert');
const tmpDir = tmpdir.path;

tmpdir.refresh();

async function validateReadFile() {
  const filePath = path.resolve(tmpDir, 'tmp-read-file.txt');
  const fileHandle = await open(filePath, 'w+');
  const buffer = Buffer.from('Hello world'.repeat(100), 'utf8');

  const fd = fs.openSync(filePath, 'w+');
  fs.writeSync(fd, buffer, 0, buffer.length);
  fs.closeSync(fd);

  const readFileData = await fileHandle.readFile();
  assert.deepStrictEqual(buffer, readFileData);

  await fileHandle.close();
}

async function validateReadFileProc() {
  // Test to make sure reading a file under the /proc directory works. Adapted
  // from test-fs-read-file-sync-hostname.js.
  // Refs:
  // - https://groups.google.com/forum/#!topic/nodejs-dev/rxZ_RoH1Gn0
  // - https://github.com/nodejs/node/issues/21331

  // Test is Linux-specific.
  if (!common.isLinux)
    return;

  const fileHandle = await open('/proc/sys/kernel/hostname', 'r');
  const hostname = await fileHandle.readFile();
  assert.ok(hostname.length > 0);
}

async function doReadAndCancel() {
  // Signal aborted from the start
  {
    const filePathForHandle = path.resolve(tmpDir, 'dogs-running.txt');
    const fileHandle = await open(filePathForHandle, 'w+');
    try {
      const buffer = Buffer.from('Dogs running'.repeat(10000), 'utf8');
      fs.writeFileSync(filePathForHandle, buffer);
      const signal = AbortSignal.abort();
      await assert.rejects(readFile(fileHandle, common.mustNotMutateObjectDeep({ signal })), {
        name: 'AbortError'
      });
    } finally {
      await fileHandle.close();
    }
  }

  // Signal aborted on first tick
  {
    const filePathForHandle = path.resolve(tmpDir, 'dogs-running1.txt');
    const fileHandle = await open(filePathForHandle, 'w+');
    const buffer = Buffer.from('Dogs running'.repeat(10000), 'utf8');
    fs.writeFileSync(filePathForHandle, buffer);
    const controller = new AbortController();
    const { signal } = controller;
    process.nextTick(() => controller.abort());
    await assert.rejects(readFile(fileHandle, common.mustNotMutateObjectDeep({ signal })), {
      name: 'AbortError'
    }, 'tick-0');
    await fileHandle.close();
  }

  // Signal aborted right before buffer read
  {
    const newFile = path.resolve(tmpDir, 'dogs-running2.txt');
    const buffer = Buffer.from('Dogs running'.repeat(1000), 'utf8');
    fs.writeFileSync(newFile, buffer);

    const fileHandle = await open(newFile, 'r');

    const controller = new AbortController();
    const { signal } = controller;
    tick(1, () => controller.abort());
    await assert.rejects(fileHandle.readFile(common.mustNotMutateObjectDeep({ signal, encoding: 'utf8' })), {
      name: 'AbortError'
    }, 'tick-1');

    await fileHandle.close();
  }

  // Validate file size is within range for reading
  {
    // Variable taken from https://github.com/nodejs/node/blob/1377163f3351/lib/internal/fs/promises.js#L5
    const kIoMaxLength = 2 ** 31 - 1;

    if (!tmpdir.hasEnoughSpace(kIoMaxLength)) {
      // truncate() will fail with ENOSPC if there is not enough space.
      common.printSkipMessage(`Not enough space in ${tmpDir}`);
    } else {
      const newFile = path.resolve(tmpDir, 'dogs-running3.txt');
      await writeFile(newFile, Buffer.from('0'));
      await truncate(newFile, kIoMaxLength + 1);

      const fileHandle = await open(newFile, 'r');

      await assert.rejects(fileHandle.readFile(), {
        name: 'RangeError',
        code: 'ERR_FS_FILE_TOO_LARGE'
      });
      await fileHandle.close();
    }
  }
}

validateReadFile()
  .then(validateReadFileProc)
  .then(doReadAndCancel)
  .then(common.mustCall());