diff options
author | Joyee Cheung <joyeec9h3@gmail.com> | 2018-04-07 17:01:06 +0800 |
---|---|---|
committer | Joyee Cheung <joyeec9h3@gmail.com> | 2018-06-07 22:05:23 +0800 |
commit | 1e7645c39ae5213a44267cff3d599264c2211f1a (patch) | |
tree | a000944a7267c0ad8b0dfe325d93f34f564844ed /test | |
parent | af2a1045631028dfad0dd5d3eb4c4866fdf55730 (diff) | |
download | android-node-v8-1e7645c39ae5213a44267cff3d599264c2211f1a.tar.gz android-node-v8-1e7645c39ae5213a44267cff3d599264c2211f1a.tar.bz2 android-node-v8-1e7645c39ae5213a44267cff3d599264c2211f1a.zip |
fs: support BigInt in fs.*stat and fs.watchFile
Add the `bigint: true` option to all the `fs.*stat` methods and
`fs.watchFile`.
PR-URL: https://github.com/nodejs/node/pull/20220
Fixes: https://github.com/nodejs/node/issues/12115
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'test')
-rw-r--r-- | test/parallel/test-fs-stat-bigint.js | 145 | ||||
-rw-r--r-- | test/parallel/test-fs-sync-fd-leak.js | 2 | ||||
-rw-r--r-- | test/parallel/test-fs-watchfile-bigint.js | 63 |
3 files changed, 209 insertions, 1 deletions
diff --git a/test/parallel/test-fs-stat-bigint.js b/test/parallel/test-fs-stat-bigint.js new file mode 100644 index 0000000000..4030a06fae --- /dev/null +++ b/test/parallel/test-fs-stat-bigint.js @@ -0,0 +1,145 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const promiseFs = require('fs').promises; +const path = require('path'); +const tmpdir = require('../common/tmpdir'); +const { isDate } = require('util').types; + +common.crashOnUnhandledRejection(); +tmpdir.refresh(); + +const fn = path.join(tmpdir.path, 'test-file'); +fs.writeFileSync(fn, 'test'); + +let link; +if (!common.isWindows) { + link = path.join(tmpdir.path, 'symbolic-link'); + fs.symlinkSync(fn, link); +} + +function verifyStats(bigintStats, numStats) { + for (const key of Object.keys(numStats)) { + const val = numStats[key]; + if (isDate(val)) { + const time = val.getTime(); + const time2 = bigintStats[key].getTime(); + assert( + Math.abs(time - time2) < 2, + `difference of ${key}.getTime() should < 2.\n` + + `Number version ${time}, BigInt version ${time2}n`); + } else if (key === 'mode') { + // eslint-disable-next-line no-undef + assert.strictEqual(bigintStats[key], BigInt(val)); + assert.strictEqual( + bigintStats.isBlockDevice(), + numStats.isBlockDevice() + ); + assert.strictEqual( + bigintStats.isCharacterDevice(), + numStats.isCharacterDevice() + ); + assert.strictEqual( + bigintStats.isDirectory(), + numStats.isDirectory() + ); + assert.strictEqual( + bigintStats.isFIFO(), + numStats.isFIFO() + ); + assert.strictEqual( + bigintStats.isFile(), + numStats.isFile() + ); + assert.strictEqual( + bigintStats.isSocket(), + numStats.isSocket() + ); + assert.strictEqual( + bigintStats.isSymbolicLink(), + numStats.isSymbolicLink() + ); + } else if (common.isWindows && (key === 'blksize' || key === 'blocks')) { + assert.strictEqual(bigintStats[key], undefined); + assert.strictEqual(numStats[key], undefined); + } else if (Number.isSafeInteger(val)) { + // eslint-disable-next-line no-undef + assert.strictEqual(bigintStats[key], BigInt(val)); + } else { + assert( + Math.abs(Number(bigintStats[key]) - val) < 1, + `${key} is not a safe integer, difference should < 1.\n` + + `Number version ${val}, BigInt version ${bigintStats[key]}n`); + } + } +} + +{ + const bigintStats = fs.statSync(fn, { bigint: true }); + const numStats = fs.statSync(fn); + verifyStats(bigintStats, numStats); +} + +if (!common.isWindows) { + const bigintStats = fs.lstatSync(link, { bigint: true }); + const numStats = fs.lstatSync(link); + verifyStats(bigintStats, numStats); +} + +{ + const fd = fs.openSync(fn, 'r'); + const bigintStats = fs.fstatSync(fd, { bigint: true }); + const numStats = fs.fstatSync(fd); + verifyStats(bigintStats, numStats); + fs.closeSync(fd); +} + +{ + fs.stat(fn, { bigint: true }, (err, bigintStats) => { + fs.stat(fn, (err, numStats) => { + verifyStats(bigintStats, numStats); + }); + }); +} + +if (!common.isWindows) { + fs.lstat(link, { bigint: true }, (err, bigintStats) => { + fs.lstat(link, (err, numStats) => { + verifyStats(bigintStats, numStats); + }); + }); +} + +{ + const fd = fs.openSync(fn, 'r'); + fs.fstat(fd, { bigint: true }, (err, bigintStats) => { + fs.fstat(fd, (err, numStats) => { + verifyStats(bigintStats, numStats); + fs.closeSync(fd); + }); + }); +} + +(async function() { + const bigintStats = await promiseFs.stat(fn, { bigint: true }); + const numStats = await promiseFs.stat(fn); + verifyStats(bigintStats, numStats); +})(); + +if (!common.isWindows) { + (async function() { + const bigintStats = await promiseFs.lstat(link, { bigint: true }); + const numStats = await promiseFs.lstat(link); + verifyStats(bigintStats, numStats); + })(); +} + +(async function() { + const handle = await promiseFs.open(fn, 'r'); + const bigintStats = await handle.stat({ bigint: true }); + const numStats = await handle.stat(); + verifyStats(bigintStats, numStats); + await handle.close(); +})(); diff --git a/test/parallel/test-fs-sync-fd-leak.js b/test/parallel/test-fs-sync-fd-leak.js index e7107546e5..52e40eb390 100644 --- a/test/parallel/test-fs-sync-fd-leak.js +++ b/test/parallel/test-fs-sync-fd-leak.js @@ -40,7 +40,7 @@ fs.writeSync = function() { throw new Error('BAM'); }; -process.binding('fs').fstat = function(fd, _, ctx) { +process.binding('fs').fstat = function(fd, bigint, _, ctx) { ctx.errno = uv.UV_EBADF; ctx.syscall = 'fstat'; }; diff --git a/test/parallel/test-fs-watchfile-bigint.js b/test/parallel/test-fs-watchfile-bigint.js new file mode 100644 index 0000000000..89cefd12e0 --- /dev/null +++ b/test/parallel/test-fs-watchfile-bigint.js @@ -0,0 +1,63 @@ +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); + +const enoentFile = path.join(tmpdir.path, 'non-existent-file'); +const expectedStatObject = new fs.Stats( + 0n, // dev + 0n, // mode + 0n, // nlink + 0n, // uid + 0n, // gid + 0n, // rdev + common.isWindows ? undefined : 0n, // blksize + 0n, // ino + 0n, // size + common.isWindows ? undefined : 0n, // blocks + 0n, // atim_msec + 0n, // mtim_msec + 0n, // ctim_msec + 0n // birthtim_msec +); + +tmpdir.refresh(); + +// If the file initially didn't exist, and gets created at a later point of +// time, the callback should be invoked again with proper values in stat object +let fileExists = false; +const options = { interval: 0, bigint: true }; + +const watcher = + fs.watchFile(enoentFile, options, common.mustCall((curr, prev) => { + if (!fileExists) { + // If the file does not exist, all the fields should be zero and the date + // fields should be UNIX EPOCH time + assert.deepStrictEqual(curr, expectedStatObject); + assert.deepStrictEqual(prev, expectedStatObject); + // Create the file now, so that the callback will be called back once the + // event loop notices it. + fs.closeSync(fs.openSync(enoentFile, 'w')); + fileExists = true; + } else { + // If the ino (inode) value is greater than zero, it means that the file + // is present in the filesystem and it has a valid inode number. + assert(curr.ino > 0n); + // As the file just got created, previous ino value should be lesser than + // or equal to zero (non-existent file). + assert(prev.ino <= 0n); + // Stop watching the file + fs.unwatchFile(enoentFile); + watcher.stop(); // stopping a stopped watcher should be a noop + } + }, 2)); + +// 'stop' should only be emitted once - stopping a stopped watcher should +// not trigger a 'stop' event. +watcher.on('stop', common.mustCall(function onStop() {})); + +watcher.start(); // starting a started watcher should be a noop |