11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci// The following tests validate base functionality for the fs.promises 61cb0ef41Sopenharmony_ci// FileHandle.readFile method. 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ciconst fs = require('fs'); 91cb0ef41Sopenharmony_ciconst { 101cb0ef41Sopenharmony_ci open, 111cb0ef41Sopenharmony_ci readFile, 121cb0ef41Sopenharmony_ci writeFile, 131cb0ef41Sopenharmony_ci truncate, 141cb0ef41Sopenharmony_ci} = fs.promises; 151cb0ef41Sopenharmony_ciconst path = require('path'); 161cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 171cb0ef41Sopenharmony_ciconst tick = require('../common/tick'); 181cb0ef41Sopenharmony_ciconst assert = require('assert'); 191cb0ef41Sopenharmony_ciconst tmpDir = tmpdir.path; 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_citmpdir.refresh(); 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ciasync function validateReadFile() { 241cb0ef41Sopenharmony_ci const filePath = path.resolve(tmpDir, 'tmp-read-file.txt'); 251cb0ef41Sopenharmony_ci const fileHandle = await open(filePath, 'w+'); 261cb0ef41Sopenharmony_ci const buffer = Buffer.from('Hello world'.repeat(100), 'utf8'); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci const fd = fs.openSync(filePath, 'w+'); 291cb0ef41Sopenharmony_ci fs.writeSync(fd, buffer, 0, buffer.length); 301cb0ef41Sopenharmony_ci fs.closeSync(fd); 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci const readFileData = await fileHandle.readFile(); 331cb0ef41Sopenharmony_ci assert.deepStrictEqual(buffer, readFileData); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci await fileHandle.close(); 361cb0ef41Sopenharmony_ci} 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ciasync function validateReadFileProc() { 391cb0ef41Sopenharmony_ci // Test to make sure reading a file under the /proc directory works. Adapted 401cb0ef41Sopenharmony_ci // from test-fs-read-file-sync-hostname.js. 411cb0ef41Sopenharmony_ci // Refs: 421cb0ef41Sopenharmony_ci // - https://groups.google.com/forum/#!topic/nodejs-dev/rxZ_RoH1Gn0 431cb0ef41Sopenharmony_ci // - https://github.com/nodejs/node/issues/21331 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci // Test is Linux-specific. 461cb0ef41Sopenharmony_ci if (!common.isLinux) 471cb0ef41Sopenharmony_ci return; 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci const fileHandle = await open('/proc/sys/kernel/hostname', 'r'); 501cb0ef41Sopenharmony_ci const hostname = await fileHandle.readFile(); 511cb0ef41Sopenharmony_ci assert.ok(hostname.length > 0); 521cb0ef41Sopenharmony_ci} 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ciasync function doReadAndCancel() { 551cb0ef41Sopenharmony_ci // Signal aborted from the start 561cb0ef41Sopenharmony_ci { 571cb0ef41Sopenharmony_ci const filePathForHandle = path.resolve(tmpDir, 'dogs-running.txt'); 581cb0ef41Sopenharmony_ci const fileHandle = await open(filePathForHandle, 'w+'); 591cb0ef41Sopenharmony_ci try { 601cb0ef41Sopenharmony_ci const buffer = Buffer.from('Dogs running'.repeat(10000), 'utf8'); 611cb0ef41Sopenharmony_ci fs.writeFileSync(filePathForHandle, buffer); 621cb0ef41Sopenharmony_ci const signal = AbortSignal.abort(); 631cb0ef41Sopenharmony_ci await assert.rejects(readFile(fileHandle, common.mustNotMutateObjectDeep({ signal })), { 641cb0ef41Sopenharmony_ci name: 'AbortError' 651cb0ef41Sopenharmony_ci }); 661cb0ef41Sopenharmony_ci } finally { 671cb0ef41Sopenharmony_ci await fileHandle.close(); 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci } 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci // Signal aborted on first tick 721cb0ef41Sopenharmony_ci { 731cb0ef41Sopenharmony_ci const filePathForHandle = path.resolve(tmpDir, 'dogs-running1.txt'); 741cb0ef41Sopenharmony_ci const fileHandle = await open(filePathForHandle, 'w+'); 751cb0ef41Sopenharmony_ci const buffer = Buffer.from('Dogs running'.repeat(10000), 'utf8'); 761cb0ef41Sopenharmony_ci fs.writeFileSync(filePathForHandle, buffer); 771cb0ef41Sopenharmony_ci const controller = new AbortController(); 781cb0ef41Sopenharmony_ci const { signal } = controller; 791cb0ef41Sopenharmony_ci process.nextTick(() => controller.abort()); 801cb0ef41Sopenharmony_ci await assert.rejects(readFile(fileHandle, common.mustNotMutateObjectDeep({ signal })), { 811cb0ef41Sopenharmony_ci name: 'AbortError' 821cb0ef41Sopenharmony_ci }, 'tick-0'); 831cb0ef41Sopenharmony_ci await fileHandle.close(); 841cb0ef41Sopenharmony_ci } 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci // Signal aborted right before buffer read 871cb0ef41Sopenharmony_ci { 881cb0ef41Sopenharmony_ci const newFile = path.resolve(tmpDir, 'dogs-running2.txt'); 891cb0ef41Sopenharmony_ci const buffer = Buffer.from('Dogs running'.repeat(1000), 'utf8'); 901cb0ef41Sopenharmony_ci fs.writeFileSync(newFile, buffer); 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci const fileHandle = await open(newFile, 'r'); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci const controller = new AbortController(); 951cb0ef41Sopenharmony_ci const { signal } = controller; 961cb0ef41Sopenharmony_ci tick(1, () => controller.abort()); 971cb0ef41Sopenharmony_ci await assert.rejects(fileHandle.readFile(common.mustNotMutateObjectDeep({ signal, encoding: 'utf8' })), { 981cb0ef41Sopenharmony_ci name: 'AbortError' 991cb0ef41Sopenharmony_ci }, 'tick-1'); 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci await fileHandle.close(); 1021cb0ef41Sopenharmony_ci } 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci // Validate file size is within range for reading 1051cb0ef41Sopenharmony_ci { 1061cb0ef41Sopenharmony_ci // Variable taken from https://github.com/nodejs/node/blob/1377163f3351/lib/internal/fs/promises.js#L5 1071cb0ef41Sopenharmony_ci const kIoMaxLength = 2 ** 31 - 1; 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci if (!tmpdir.hasEnoughSpace(kIoMaxLength)) { 1101cb0ef41Sopenharmony_ci // truncate() will fail with ENOSPC if there is not enough space. 1111cb0ef41Sopenharmony_ci common.printSkipMessage(`Not enough space in ${tmpDir}`); 1121cb0ef41Sopenharmony_ci } else { 1131cb0ef41Sopenharmony_ci const newFile = path.resolve(tmpDir, 'dogs-running3.txt'); 1141cb0ef41Sopenharmony_ci await writeFile(newFile, Buffer.from('0')); 1151cb0ef41Sopenharmony_ci await truncate(newFile, kIoMaxLength + 1); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci const fileHandle = await open(newFile, 'r'); 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci await assert.rejects(fileHandle.readFile(), { 1201cb0ef41Sopenharmony_ci name: 'RangeError', 1211cb0ef41Sopenharmony_ci code: 'ERR_FS_FILE_TOO_LARGE' 1221cb0ef41Sopenharmony_ci }); 1231cb0ef41Sopenharmony_ci await fileHandle.close(); 1241cb0ef41Sopenharmony_ci } 1251cb0ef41Sopenharmony_ci } 1261cb0ef41Sopenharmony_ci} 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_civalidateReadFile() 1291cb0ef41Sopenharmony_ci .then(validateReadFileProc) 1301cb0ef41Sopenharmony_ci .then(doReadAndCancel) 1311cb0ef41Sopenharmony_ci .then(common.mustCall()); 132