1// Flags: --expose-internals 2'use strict'; 3 4const common = require('../common'); 5 6const assert = require('assert'); 7const path = require('path'); 8const { writeFile, readFile } = require('fs').promises; 9const tmpdir = require('../common/tmpdir'); 10const { internalBinding } = require('internal/test/binding'); 11const fsBinding = internalBinding('fs'); 12tmpdir.refresh(); 13 14const fn = path.join(tmpdir.path, 'large-file'); 15 16// Creating large buffer with random content 17const largeBuffer = Buffer.from( 18 Array.from({ length: 1024 ** 2 + 19 }, (_, index) => index) 19); 20 21async function createLargeFile() { 22 // Writing buffer to a file then try to read it 23 await writeFile(fn, largeBuffer); 24} 25 26async function validateReadFile() { 27 const readBuffer = await readFile(fn); 28 assert.strictEqual(readBuffer.equals(largeBuffer), true); 29} 30 31async function validateReadFileProc() { 32 // Test to make sure reading a file under the /proc directory works. Adapted 33 // from test-fs-read-file-sync-hostname.js. 34 // Refs: 35 // - https://groups.google.com/forum/#!topic/nodejs-dev/rxZ_RoH1Gn0 36 // - https://github.com/nodejs/node/issues/21331 37 38 // Test is Linux-specific. 39 if (!common.isLinux) 40 return; 41 42 const hostname = await readFile('/proc/sys/kernel/hostname'); 43 assert.ok(hostname.length > 0); 44} 45 46function validateReadFileAbortLogicBefore() { 47 const signal = AbortSignal.abort(); 48 assert.rejects(readFile(fn, { signal }), { 49 name: 'AbortError' 50 }); 51} 52 53function validateReadFileAbortLogicDuring() { 54 const controller = new AbortController(); 55 const signal = controller.signal; 56 process.nextTick(() => controller.abort()); 57 assert.rejects(readFile(fn, { signal }), { 58 name: 'AbortError' 59 }); 60} 61 62async function validateWrongSignalParam() { 63 // Verify that if something different than Abortcontroller.signal 64 // is passed, ERR_INVALID_ARG_TYPE is thrown 65 66 await assert.rejects(async () => { 67 const callback = common.mustNotCall(); 68 await readFile(fn, { signal: 'hello' }, callback); 69 }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); 70 71} 72 73async function validateZeroByteLiar() { 74 const originalFStat = fsBinding.fstat; 75 fsBinding.fstat = common.mustCall( 76 () => (/* stat fields */ [0, 1, 2, 3, 4, 5, 6, 7, 0 /* size */]) 77 ); 78 const readBuffer = await readFile(fn); 79 assert.strictEqual(readBuffer.toString(), largeBuffer.toString()); 80 fsBinding.fstat = originalFStat; 81} 82 83(async () => { 84 await createLargeFile(); 85 await validateReadFile(); 86 await validateReadFileProc(); 87 await validateReadFileAbortLogicBefore(); 88 await validateReadFileAbortLogicDuring(); 89 await validateWrongSignalParam(); 90 await validateZeroByteLiar(); 91})().then(common.mustCall()); 92