From 77274d07d287c656cdca67bfb3bda1f69bf52a93 Mon Sep 17 00:00:00 2001 From: Jeremiah Senkpiel Date: Tue, 22 Jan 2019 19:10:04 -0800 Subject: [PATCH] test: rewrite fs {f}utimes test file Previously this test silently swallowed some errors. Refactored to use `common.mustCall()` & `assert()`s. Also, this adds a couple of extra error-checking cases. PR-URL: https://github.com/nodejs/node/pull/25656 Reviewed-By: Ruben Bridgewater Reviewed-By: Anna Henningsen --- test/parallel/test-fs-utimes.js | 207 ++++++++++++++++---------------- 1 file changed, 101 insertions(+), 106 deletions(-) diff --git a/test/parallel/test-fs-utimes.js b/test/parallel/test-fs-utimes.js index bed403dc2db82c..93932e27d7e777 100644 --- a/test/parallel/test-fs-utimes.js +++ b/test/parallel/test-fs-utimes.js @@ -28,9 +28,6 @@ const fs = require('fs'); const tmpdir = require('../common/tmpdir'); tmpdir.refresh(); -let tests_ok = 0; -let tests_run = 0; - function stat_resource(resource) { if (typeof resource === 'string') { return fs.statSync(resource); @@ -49,71 +46,46 @@ function check_mtime(resource, mtime) { mtime = fs._toUnixTimestamp(mtime); const stats = stat_resource(resource); const real_mtime = fs._toUnixTimestamp(stats.mtime); - // check up to single-second precision - // sub-second precision is OS and fs dependant - return mtime - real_mtime < 2; + return mtime - real_mtime; } function expect_errno(syscall, resource, err, errno) { - if (err && (err.code === errno || err.code === 'ENOSYS')) { - tests_ok++; - } else { - console.log('FAILED:', 'expect_errno', util.inspect(arguments)); - } + assert( + err && (err.code === errno || err.code === 'ENOSYS'), + `FAILED: expect_errno ${util.inspect(arguments)}` + ); } function expect_ok(syscall, resource, err, atime, mtime) { - if (!err && check_mtime(resource, mtime) || - err && err.code === 'ENOSYS') { - tests_ok++; - } else { - console.log('FAILED:', 'expect_ok', util.inspect(arguments)); - } + const mtime_diff = check_mtime(resource, mtime); + assert( + // check up to single-second precision + // sub-second precision is OS and fs dependant + !err && (mtime_diff < 2) || err && err.code === 'ENOSYS', + `FAILED: expect_ok ${util.inspect(arguments)} + check_mtime: ${mtime_diff}` + ); } -function testIt(atime, mtime, callback) { - - let fd; - // - // test synchronized code paths, these functions throw on failure - // - function syncTests() { - fs.utimesSync(tmpdir.path, atime, mtime); - expect_ok('utimesSync', tmpdir.path, undefined, atime, mtime); - tests_run++; - - // some systems don't have futimes - // if there's an error, it should be ENOSYS - try { - tests_run++; - fs.futimesSync(fd, atime, mtime); - expect_ok('futimesSync', fd, undefined, atime, mtime); - } catch (ex) { - expect_errno('futimesSync', fd, ex, 'ENOSYS'); - } - - let err; - try { - fs.utimesSync('foobarbaz', atime, mtime); - } catch (ex) { - err = ex; - } - expect_errno('utimesSync', 'foobarbaz', err, 'ENOENT'); - tests_run++; +const stats = fs.statSync(tmpdir.path); - err = undefined; - common.expectsError( - () => fs.futimesSync(-1, atime, mtime), - { - code: 'ERR_OUT_OF_RANGE', - type: RangeError, - message: 'The value of "fd" is out of range. ' + - 'It must be >= 0 && < 4294967296. Received -1' - } - ); - tests_run++; - } +const cases = [ + new Date('1982-09-10 13:37'), + new Date(), + 123456.789, + stats.mtime, + ['123456', -1], + new Date('2017-04-08T17:59:38.008Z') +]; +runTests(cases.values()); + +function runTests(iter) { + const { value, done } = iter.next(); + if (done) return; + // Support easy setting same or different atime / mtime values + const [atime, mtime] = Array.isArray(value) ? value : [value, value]; + let fd; // // test async code paths // @@ -133,54 +105,40 @@ function testIt(atime, mtime, callback) { fs.futimes(fd, atime, mtime, common.mustCall((err) => { expect_ok('futimes', fd, err, atime, mtime); - common.expectsError( - () => fs.futimes(-1, atime, mtime, common.mustNotCall()), - { - code: 'ERR_OUT_OF_RANGE', - type: RangeError, - message: 'The value of "fd" is out of range. ' + - 'It must be >= 0 && < 4294967296. Received -1' - } - ); - syncTests(); - tests_run++; + setImmediate(common.mustCall(runTests), iter); })); - tests_run++; })); - tests_run++; })); - tests_run++; -} -const stats = fs.statSync(tmpdir.path); + // + // test synchronized code paths, these functions throw on failure + // + function syncTests() { + fs.utimesSync(tmpdir.path, atime, mtime); + expect_ok('utimesSync', tmpdir.path, undefined, atime, mtime); -// Run tests -const runTest = common.mustCall(testIt, 1); - -runTest(new Date('1982-09-10 13:37'), new Date('1982-09-10 13:37'), () => { - runTest(new Date(), new Date(), () => { - runTest(123456.789, 123456.789, () => { - runTest(stats.mtime, stats.mtime, () => { - runTest('123456', -1, () => { - runTest( - new Date('2017-04-08T17:59:38.008Z'), - new Date('2017-04-08T17:59:38.008Z'), - common.mustCall(() => { - // Done - }) - ); - }); - }); - }); - }); -}); + // some systems don't have futimes + // if there's an error, it should be ENOSYS + try { + fs.futimesSync(fd, atime, mtime); + expect_ok('futimesSync', fd, undefined, atime, mtime); + } catch (ex) { + expect_errno('futimesSync', fd, ex, 'ENOSYS'); + } -process.on('exit', () => { - assert.strictEqual(tests_ok, tests_run - 2); -}); + let err; + try { + fs.utimesSync('foobarbaz', atime, mtime); + } catch (ex) { + err = ex; + } + expect_errno('utimesSync', 'foobarbaz', err, 'ENOENT'); + err = undefined; + } +} // Ref: https://github.com/nodejs/node/issues/13255 const path = `${tmpdir.path}/test-utimes-precision`; @@ -212,19 +170,56 @@ if (common.isWindows) { assert.strictEqual(overflow_mtime, overflow_stats.mtime.getTime()); } -[false, 0, {}, [], null, undefined].forEach((i) => { +const expectTypeError = { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError +}; +// utimes-only error cases +{ + common.expectsError( + () => fs.utimes(0, new Date(), new Date(), common.mustNotCall()), + expectTypeError + ); + common.expectsError( + () => fs.utimesSync(0, new Date(), new Date()), + expectTypeError + ); +} + +// shared error cases +[false, {}, [], null, undefined].forEach((i) => { common.expectsError( () => fs.utimes(i, new Date(), new Date(), common.mustNotCall()), - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError - } + expectTypeError ); common.expectsError( () => fs.utimesSync(i, new Date(), new Date()), - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError - } + expectTypeError + ); + common.expectsError( + () => fs.futimes(i, new Date(), new Date(), common.mustNotCall()), + expectTypeError + ); + common.expectsError( + () => fs.futimesSync(i, new Date(), new Date()), + expectTypeError ); }); + +const expectRangeError = { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: 'The value of "fd" is out of range. ' + + 'It must be >= 0 && < 4294967296. Received -1' +}; +// futimes-only error cases +{ + common.expectsError( + () => fs.futimes(-1, new Date(), new Date(), common.mustNotCall()), + expectRangeError + ); + common.expectsError( + () => fs.futimesSync(-1, new Date(), new Date()), + expectRangeError + ); +}