From d6544ac4b862b5d105d51032b2665f9e807f98f8 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Wed, 10 Mar 2021 19:17:44 -0800 Subject: [PATCH] test: fix test-fs-utimes on non-Y2K38 file systems Move Y2K38-specific parts of test-fs-utimes to test-fs-utimes-y2K38.js. On non-Windows, check for Y2K38 support and skip if it is unsupported. Fixes: https://github.com/nodejs/node/issues/36591 --- test/parallel/test-fs-utimes-y2K38.js | 55 +++++++++++++++++++++++++++ test/parallel/test-fs-utimes.js | 31 --------------- 2 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 test/parallel/test-fs-utimes-y2K38.js diff --git a/test/parallel/test-fs-utimes-y2K38.js b/test/parallel/test-fs-utimes-y2K38.js new file mode 100644 index 00000000000000..dfd37ffa31aaa9 --- /dev/null +++ b/test/parallel/test-fs-utimes-y2K38.js @@ -0,0 +1,55 @@ +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); + +const assert = require('assert'); +const fs = require('fs'); + +tmpdir.refresh(); + +// Check for Y2K38 support on POSIX. For Windows, assume it's there. +if (!common.isWindows) { + const testFilePath = `${tmpdir.path}/y2k38-test`; + const testFileDate = '203801020304'; + const { spawnSync } = require('child_process'); + const touchResult = spawnSync('touch', + ['-t', testFileDate, testFilePath], + { encoding: 'utf8' }); + assert.strictEqual(touchResult.status, 0); + + const dateResult = spawnSync('date', + ['-r', testFilePath, '+%Y%m%d%H%M'], + { encoding: 'utf8' }); + assert.strictEqual(dateResult.status, 0); + + if (dateResult.stdout.trim() !== testFileDate) { + common.skip('File system appears to lack Y2k38 support'); + } +} + +// Ref: https://github.com/nodejs/node/issues/13255 +const path = `${tmpdir.path}/test-utimes-precision`; +fs.writeFileSync(path, ''); + +const Y2K38_mtime = 2 ** 31; +fs.utimesSync(path, Y2K38_mtime, Y2K38_mtime); +const Y2K38_stats = fs.statSync(path); +assert.strictEqual(Y2K38_stats.mtime.getTime() / 1000, Y2K38_mtime); + +if (common.isWindows) { + // This value would get converted to (double)1713037251359.9998 + const truncate_mtime = 1713037251360; + fs.utimesSync(path, truncate_mtime / 1000, truncate_mtime / 1000); + const truncate_stats = fs.statSync(path); + assert.strictEqual(truncate_stats.mtime.getTime(), truncate_mtime); + + // test Y2K38 for windows + // This value if treaded as a `signed long` gets converted to -2135622133469. + // POSIX systems stores timestamps in {long t_sec, long t_usec}. + // NTFS stores times in nanoseconds in a single `uint64_t`, so when libuv + // calculates (long)`uv_timespec_t.tv_sec` we get 2's complement. + const overflow_mtime = 2159345162531; + fs.utimesSync(path, overflow_mtime / 1000, overflow_mtime / 1000); + const overflow_stats = fs.statSync(path); + assert.strictEqual(overflow_stats.mtime.getTime(), overflow_mtime); +} diff --git a/test/parallel/test-fs-utimes.js b/test/parallel/test-fs-utimes.js index b81c5b6bf62940..8f8286f8a3343f 100644 --- a/test/parallel/test-fs-utimes.js +++ b/test/parallel/test-fs-utimes.js @@ -156,37 +156,6 @@ function runTests(iter) { } } -// Ref: https://github.com/nodejs/node/issues/13255 -const path = `${tmpdir.path}/test-utimes-precision`; -fs.writeFileSync(path, ''); - -// Test Y2K38 for all platforms [except 'arm', 'OpenBSD', 'SunOS' and 'IBMi'] -if (!process.arch.includes('arm') && - !common.isOpenBSD && !common.isSunOS && !common.isIBMi) { - const Y2K38_mtime = 2 ** 31; - fs.utimesSync(path, Y2K38_mtime, Y2K38_mtime); - const Y2K38_stats = fs.statSync(path); - assert.strictEqual(Y2K38_stats.mtime.getTime() / 1000, Y2K38_mtime); -} - -if (common.isWindows) { - // This value would get converted to (double)1713037251359.9998 - const truncate_mtime = 1713037251360; - fs.utimesSync(path, truncate_mtime / 1000, truncate_mtime / 1000); - const truncate_stats = fs.statSync(path); - assert.strictEqual(truncate_stats.mtime.getTime(), truncate_mtime); - - // test Y2K38 for windows - // This value if treaded as a `signed long` gets converted to -2135622133469. - // POSIX systems stores timestamps in {long t_sec, long t_usec}. - // NTFS stores times in nanoseconds in a single `uint64_t`, so when libuv - // calculates (long)`uv_timespec_t.tv_sec` we get 2's complement. - const overflow_mtime = 2159345162531; - fs.utimesSync(path, overflow_mtime / 1000, overflow_mtime / 1000); - const overflow_stats = fs.statSync(path); - assert.strictEqual(overflow_stats.mtime.getTime(), overflow_mtime); -} - const expectTypeError = { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError'