• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4
5// The following tests validate base functionality for the fs.promises
6// FileHandle.read method.
7
8const fs = require('fs');
9const { open } = fs.promises;
10const path = require('path');
11const fixtures = require('../common/fixtures');
12const tmpdir = require('../common/tmpdir');
13const assert = require('assert');
14const tmpDir = tmpdir.path;
15
16async function read(fileHandle, buffer, offset, length, position, options) {
17  return options.useConf ?
18    fileHandle.read({ buffer, offset, length, position }) :
19    fileHandle.read(buffer, offset, length, position);
20}
21
22async function validateRead(data, file, options) {
23  const filePath = path.resolve(tmpDir, file);
24  const buffer = Buffer.from(data, 'utf8');
25
26  const fd = fs.openSync(filePath, 'w+');
27  const fileHandle = await open(filePath, 'w+');
28  const streamFileHandle = await open(filePath, 'w+');
29
30  fs.writeSync(fd, buffer, 0, buffer.length);
31  fs.closeSync(fd);
32
33  fileHandle.on('close', common.mustCall());
34  const readAsyncHandle =
35    await read(fileHandle, Buffer.alloc(11), 0, 11, 0, options);
36  assert.deepStrictEqual(data.length, readAsyncHandle.bytesRead);
37  if (data.length)
38    assert.deepStrictEqual(buffer, readAsyncHandle.buffer);
39  await fileHandle.close();
40
41  const stream = fs.createReadStream(null, { fd: streamFileHandle });
42  let streamData = Buffer.alloc(0);
43  for await (const chunk of stream)
44    streamData = Buffer.from(chunk);
45  assert.deepStrictEqual(buffer, streamData);
46  if (data.length)
47    assert.deepStrictEqual(streamData, readAsyncHandle.buffer);
48  await streamFileHandle.close();
49}
50
51async function validateLargeRead(options) {
52  // Reading beyond file length (3 in this case) should return no data.
53  // This is a test for a bug where reads > uint32 would return data
54  // from the current position in the file.
55  const filePath = fixtures.path('x.txt');
56  const fileHandle = await open(filePath, 'r');
57  const pos = 0xffffffff + 1; // max-uint32 + 1
58  const readHandle =
59    await read(fileHandle, Buffer.alloc(1), 0, 1, pos, options);
60
61  assert.strictEqual(readHandle.bytesRead, 0);
62}
63
64async function validateReadNoParams() {
65  const filePath = fixtures.path('x.txt');
66  const fileHandle = await open(filePath, 'r');
67  // Should not throw
68  await fileHandle.read();
69}
70
71// Validates that the zero position is respected after the position has been
72// moved. The test iterates over the xyz chars twice making sure that the values
73// are read from the correct position.
74async function validateReadWithPositionZero() {
75  const opts = { useConf: true };
76  const filePath = fixtures.path('x.txt');
77  const fileHandle = await open(filePath, 'r');
78  const expectedSequence = ['x', 'y', 'z'];
79
80  for (let i = 0; i < expectedSequence.length * 2; i++) {
81    const len = 1;
82    const pos = i % 3;
83    const buf = Buffer.alloc(len);
84    const { bytesRead } = await read(fileHandle, buf, 0, len, pos, opts);
85    assert.strictEqual(bytesRead, len);
86    assert.strictEqual(buf.toString(), expectedSequence[pos]);
87  }
88}
89
90async function validateReadLength(len) {
91  const buf = Buffer.alloc(4);
92  const opts = { useConf: true };
93  const filePath = fixtures.path('x.txt');
94  const fileHandle = await open(filePath, 'r');
95  const { bytesRead } = await read(fileHandle, buf, 0, len, 0, opts);
96  assert.strictEqual(bytesRead, len);
97}
98
99
100(async function() {
101  tmpdir.refresh();
102  await validateRead('Hello world', 'read-file', { useConf: false });
103  await validateRead('', 'read-empty-file', { useConf: false });
104  await validateRead('Hello world', 'read-file-conf', { useConf: true });
105  await validateRead('', 'read-empty-file-conf', { useConf: true });
106  await validateLargeRead({ useConf: false });
107  await validateLargeRead({ useConf: true });
108  await validateReadNoParams();
109  await validateReadWithPositionZero();
110  await validateReadLength(0);
111  await validateReadLength(1);
112})().then(common.mustCall());
113