11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciconst assert = require('assert'); 51cb0ef41Sopenharmony_ciconst fs = require('fs'); 61cb0ef41Sopenharmony_ciconst promiseFs = require('fs').promises; 71cb0ef41Sopenharmony_ciconst path = require('path'); 81cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 91cb0ef41Sopenharmony_ciconst { isDate } = require('util').types; 101cb0ef41Sopenharmony_ciconst { inspect } = require('util'); 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_citmpdir.refresh(); 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_cilet testIndex = 0; 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_cifunction getFilename() { 171cb0ef41Sopenharmony_ci const filename = path.join(tmpdir.path, `test-file-${++testIndex}`); 181cb0ef41Sopenharmony_ci fs.writeFileSync(filename, 'test'); 191cb0ef41Sopenharmony_ci return filename; 201cb0ef41Sopenharmony_ci} 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_cifunction verifyStats(bigintStats, numStats, allowableDelta) { 231cb0ef41Sopenharmony_ci // allowableDelta: It's possible that the file stats are updated between the 241cb0ef41Sopenharmony_ci // two stat() calls so allow for a small difference. 251cb0ef41Sopenharmony_ci for (const key of Object.keys(numStats)) { 261cb0ef41Sopenharmony_ci const val = numStats[key]; 271cb0ef41Sopenharmony_ci if (isDate(val)) { 281cb0ef41Sopenharmony_ci const time = val.getTime(); 291cb0ef41Sopenharmony_ci const time2 = bigintStats[key].getTime(); 301cb0ef41Sopenharmony_ci assert( 311cb0ef41Sopenharmony_ci time - time2 <= allowableDelta, 321cb0ef41Sopenharmony_ci `difference of ${key}.getTime() should <= ${allowableDelta}.\n` + 331cb0ef41Sopenharmony_ci `Number version ${time}, BigInt version ${time2}n`); 341cb0ef41Sopenharmony_ci } else if (key === 'mode') { 351cb0ef41Sopenharmony_ci assert.strictEqual(bigintStats[key], BigInt(val)); 361cb0ef41Sopenharmony_ci assert.strictEqual( 371cb0ef41Sopenharmony_ci bigintStats.isBlockDevice(), 381cb0ef41Sopenharmony_ci numStats.isBlockDevice() 391cb0ef41Sopenharmony_ci ); 401cb0ef41Sopenharmony_ci assert.strictEqual( 411cb0ef41Sopenharmony_ci bigintStats.isCharacterDevice(), 421cb0ef41Sopenharmony_ci numStats.isCharacterDevice() 431cb0ef41Sopenharmony_ci ); 441cb0ef41Sopenharmony_ci assert.strictEqual( 451cb0ef41Sopenharmony_ci bigintStats.isDirectory(), 461cb0ef41Sopenharmony_ci numStats.isDirectory() 471cb0ef41Sopenharmony_ci ); 481cb0ef41Sopenharmony_ci assert.strictEqual( 491cb0ef41Sopenharmony_ci bigintStats.isFIFO(), 501cb0ef41Sopenharmony_ci numStats.isFIFO() 511cb0ef41Sopenharmony_ci ); 521cb0ef41Sopenharmony_ci assert.strictEqual( 531cb0ef41Sopenharmony_ci bigintStats.isFile(), 541cb0ef41Sopenharmony_ci numStats.isFile() 551cb0ef41Sopenharmony_ci ); 561cb0ef41Sopenharmony_ci assert.strictEqual( 571cb0ef41Sopenharmony_ci bigintStats.isSocket(), 581cb0ef41Sopenharmony_ci numStats.isSocket() 591cb0ef41Sopenharmony_ci ); 601cb0ef41Sopenharmony_ci assert.strictEqual( 611cb0ef41Sopenharmony_ci bigintStats.isSymbolicLink(), 621cb0ef41Sopenharmony_ci numStats.isSymbolicLink() 631cb0ef41Sopenharmony_ci ); 641cb0ef41Sopenharmony_ci } else if (key.endsWith('Ms')) { 651cb0ef41Sopenharmony_ci const nsKey = key.replace('Ms', 'Ns'); 661cb0ef41Sopenharmony_ci const msFromBigInt = bigintStats[key]; 671cb0ef41Sopenharmony_ci const nsFromBigInt = bigintStats[nsKey]; 681cb0ef41Sopenharmony_ci const msFromBigIntNs = Number(nsFromBigInt / (10n ** 6n)); 691cb0ef41Sopenharmony_ci const msFromNum = numStats[key]; 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci assert( 721cb0ef41Sopenharmony_ci msFromNum - Number(msFromBigInt) <= allowableDelta, 731cb0ef41Sopenharmony_ci `Number version ${key} = ${msFromNum}, ` + 741cb0ef41Sopenharmony_ci `BigInt version ${key} = ${msFromBigInt}n, ` + 751cb0ef41Sopenharmony_ci `Allowable delta = ${allowableDelta}`); 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci assert( 781cb0ef41Sopenharmony_ci msFromNum - Number(msFromBigIntNs) <= allowableDelta, 791cb0ef41Sopenharmony_ci `Number version ${key} = ${msFromNum}, ` + 801cb0ef41Sopenharmony_ci `BigInt version ${nsKey} = ${nsFromBigInt}n` + 811cb0ef41Sopenharmony_ci ` = ${msFromBigIntNs}ms, Allowable delta = ${allowableDelta}`); 821cb0ef41Sopenharmony_ci } else if (Number.isSafeInteger(val)) { 831cb0ef41Sopenharmony_ci assert.strictEqual( 841cb0ef41Sopenharmony_ci bigintStats[key], BigInt(val), 851cb0ef41Sopenharmony_ci `${inspect(bigintStats[key])} !== ${inspect(BigInt(val))}\n` + 861cb0ef41Sopenharmony_ci `key=${key}, val=${val}` 871cb0ef41Sopenharmony_ci ); 881cb0ef41Sopenharmony_ci } else { 891cb0ef41Sopenharmony_ci assert( 901cb0ef41Sopenharmony_ci Number(bigintStats[key]) - val < 1, 911cb0ef41Sopenharmony_ci `${key} is not a safe integer, difference should < 1.\n` + 921cb0ef41Sopenharmony_ci `Number version ${val}, BigInt version ${bigintStats[key]}n`); 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci} 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ciconst runSyncTest = (func, arg) => { 981cb0ef41Sopenharmony_ci const startTime = process.hrtime.bigint(); 991cb0ef41Sopenharmony_ci const bigintStats = func(arg, common.mustNotMutateObjectDeep({ bigint: true })); 1001cb0ef41Sopenharmony_ci const numStats = func(arg); 1011cb0ef41Sopenharmony_ci const endTime = process.hrtime.bigint(); 1021cb0ef41Sopenharmony_ci const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6); 1031cb0ef41Sopenharmony_ci verifyStats(bigintStats, numStats, allowableDelta); 1041cb0ef41Sopenharmony_ci}; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci{ 1071cb0ef41Sopenharmony_ci const filename = getFilename(); 1081cb0ef41Sopenharmony_ci runSyncTest(fs.statSync, filename); 1091cb0ef41Sopenharmony_ci} 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ciif (!common.isWindows) { 1121cb0ef41Sopenharmony_ci const filename = getFilename(); 1131cb0ef41Sopenharmony_ci const link = `${filename}-link`; 1141cb0ef41Sopenharmony_ci fs.symlinkSync(filename, link); 1151cb0ef41Sopenharmony_ci runSyncTest(fs.lstatSync, link); 1161cb0ef41Sopenharmony_ci} 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci{ 1191cb0ef41Sopenharmony_ci const filename = getFilename(); 1201cb0ef41Sopenharmony_ci const fd = fs.openSync(filename, 'r'); 1211cb0ef41Sopenharmony_ci runSyncTest(fs.fstatSync, fd); 1221cb0ef41Sopenharmony_ci fs.closeSync(fd); 1231cb0ef41Sopenharmony_ci} 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci{ 1261cb0ef41Sopenharmony_ci assert.throws( 1271cb0ef41Sopenharmony_ci () => fs.statSync('does_not_exist'), 1281cb0ef41Sopenharmony_ci { code: 'ENOENT' }); 1291cb0ef41Sopenharmony_ci assert.strictEqual( 1301cb0ef41Sopenharmony_ci fs.statSync('does_not_exist', common.mustNotMutateObjectDeep({ throwIfNoEntry: false })), 1311cb0ef41Sopenharmony_ci undefined); 1321cb0ef41Sopenharmony_ci} 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci{ 1351cb0ef41Sopenharmony_ci assert.throws( 1361cb0ef41Sopenharmony_ci () => fs.lstatSync('does_not_exist'), 1371cb0ef41Sopenharmony_ci { code: 'ENOENT' }); 1381cb0ef41Sopenharmony_ci assert.strictEqual( 1391cb0ef41Sopenharmony_ci fs.lstatSync('does_not_exist', common.mustNotMutateObjectDeep({ throwIfNoEntry: false })), 1401cb0ef41Sopenharmony_ci undefined); 1411cb0ef41Sopenharmony_ci} 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci{ 1441cb0ef41Sopenharmony_ci assert.throws( 1451cb0ef41Sopenharmony_ci () => fs.fstatSync(9999), 1461cb0ef41Sopenharmony_ci { code: 'EBADF' }); 1471cb0ef41Sopenharmony_ci assert.throws( 1481cb0ef41Sopenharmony_ci () => fs.fstatSync(9999, common.mustNotMutateObjectDeep({ throwIfNoEntry: false })), 1491cb0ef41Sopenharmony_ci { code: 'EBADF' }); 1501cb0ef41Sopenharmony_ci} 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ciconst runCallbackTest = (func, arg, done) => { 1531cb0ef41Sopenharmony_ci const startTime = process.hrtime.bigint(); 1541cb0ef41Sopenharmony_ci func(arg, common.mustNotMutateObjectDeep({ bigint: true }), common.mustCall((err, bigintStats) => { 1551cb0ef41Sopenharmony_ci func(arg, common.mustCall((err, numStats) => { 1561cb0ef41Sopenharmony_ci const endTime = process.hrtime.bigint(); 1571cb0ef41Sopenharmony_ci const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6); 1581cb0ef41Sopenharmony_ci verifyStats(bigintStats, numStats, allowableDelta); 1591cb0ef41Sopenharmony_ci if (done) { 1601cb0ef41Sopenharmony_ci done(); 1611cb0ef41Sopenharmony_ci } 1621cb0ef41Sopenharmony_ci })); 1631cb0ef41Sopenharmony_ci })); 1641cb0ef41Sopenharmony_ci}; 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci{ 1671cb0ef41Sopenharmony_ci const filename = getFilename(); 1681cb0ef41Sopenharmony_ci runCallbackTest(fs.stat, filename); 1691cb0ef41Sopenharmony_ci} 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ciif (!common.isWindows) { 1721cb0ef41Sopenharmony_ci const filename = getFilename(); 1731cb0ef41Sopenharmony_ci const link = `${filename}-link`; 1741cb0ef41Sopenharmony_ci fs.symlinkSync(filename, link); 1751cb0ef41Sopenharmony_ci runCallbackTest(fs.lstat, link); 1761cb0ef41Sopenharmony_ci} 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci{ 1791cb0ef41Sopenharmony_ci const filename = getFilename(); 1801cb0ef41Sopenharmony_ci const fd = fs.openSync(filename, 'r'); 1811cb0ef41Sopenharmony_ci runCallbackTest(fs.fstat, fd, () => { fs.closeSync(fd); }); 1821cb0ef41Sopenharmony_ci} 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ciconst runPromiseTest = async (func, arg) => { 1851cb0ef41Sopenharmony_ci const startTime = process.hrtime.bigint(); 1861cb0ef41Sopenharmony_ci const bigintStats = await func(arg, common.mustNotMutateObjectDeep({ bigint: true })); 1871cb0ef41Sopenharmony_ci const numStats = await func(arg); 1881cb0ef41Sopenharmony_ci const endTime = process.hrtime.bigint(); 1891cb0ef41Sopenharmony_ci const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6); 1901cb0ef41Sopenharmony_ci verifyStats(bigintStats, numStats, allowableDelta); 1911cb0ef41Sopenharmony_ci}; 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ci{ 1941cb0ef41Sopenharmony_ci const filename = getFilename(); 1951cb0ef41Sopenharmony_ci runPromiseTest(promiseFs.stat, filename); 1961cb0ef41Sopenharmony_ci} 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ciif (!common.isWindows) { 1991cb0ef41Sopenharmony_ci const filename = getFilename(); 2001cb0ef41Sopenharmony_ci const link = `${filename}-link`; 2011cb0ef41Sopenharmony_ci fs.symlinkSync(filename, link); 2021cb0ef41Sopenharmony_ci runPromiseTest(promiseFs.lstat, link); 2031cb0ef41Sopenharmony_ci} 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci(async function() { 2061cb0ef41Sopenharmony_ci const filename = getFilename(); 2071cb0ef41Sopenharmony_ci const handle = await promiseFs.open(filename, 'r'); 2081cb0ef41Sopenharmony_ci const startTime = process.hrtime.bigint(); 2091cb0ef41Sopenharmony_ci const bigintStats = await handle.stat(common.mustNotMutateObjectDeep({ bigint: true })); 2101cb0ef41Sopenharmony_ci const numStats = await handle.stat(); 2111cb0ef41Sopenharmony_ci const endTime = process.hrtime.bigint(); 2121cb0ef41Sopenharmony_ci const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6); 2131cb0ef41Sopenharmony_ci verifyStats(bigintStats, numStats, allowableDelta); 2141cb0ef41Sopenharmony_ci await handle.close(); 2151cb0ef41Sopenharmony_ci})().then(common.mustCall()); 216