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) { 17 return useConf ? 18 fileHandle.read({ buffer, offset, length, position }) : 19 fileHandle.read(buffer, offset, length, position); 20} 21 22async function validateRead() { 23 const filePath = path.resolve(tmpDir, 'tmp-read-file.txt'); 24 const fileHandle = await open(filePath, 'w+'); 25 const buffer = Buffer.from('Hello world', 'utf8'); 26 27 const fd = fs.openSync(filePath, 'w+'); 28 fs.writeSync(fd, buffer, 0, buffer.length); 29 fs.closeSync(fd); 30 const readAsyncHandle = await read(fileHandle, Buffer.alloc(11), 0, 11, 0); 31 assert.deepStrictEqual(buffer.length, readAsyncHandle.bytesRead); 32 assert.deepStrictEqual(buffer, readAsyncHandle.buffer); 33 34 await fileHandle.close(); 35} 36 37async function validateEmptyRead() { 38 const filePath = path.resolve(tmpDir, 'tmp-read-empty-file.txt'); 39 const fileHandle = await open(filePath, 'w+'); 40 const buffer = Buffer.from('', 'utf8'); 41 42 const fd = fs.openSync(filePath, 'w+'); 43 fs.writeSync(fd, buffer, 0, buffer.length); 44 fs.closeSync(fd); 45 const readAsyncHandle = await read(fileHandle, Buffer.alloc(11), 0, 11, 0); 46 assert.deepStrictEqual(buffer.length, readAsyncHandle.bytesRead); 47 48 await fileHandle.close(); 49} 50 51async function validateLargeRead() { 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 = await read(fileHandle, Buffer.alloc(1), 0, 1, pos); 59 60 assert.strictEqual(readHandle.bytesRead, 0); 61} 62 63async function validateReadNoParams() { 64 const filePath = fixtures.path('x.txt'); 65 const fileHandle = await open(filePath, 'r'); 66 // Should not throw 67 await fileHandle.read(); 68} 69 70let useConf = false; 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 90(async function() { 91 for (const value of [false, true]) { 92 tmpdir.refresh(); 93 useConf = value; 94 95 await validateRead() 96 .then(validateEmptyRead) 97 .then(validateLargeRead) 98 .then(common.mustCall()); 99 } 100 await validateReadNoParams(); 101 await validateReadWithPositionZero(); 102})().then(common.mustCall()); 103