Skip to content

Commit 4487483

Browse files
Trottruyadorno
authored andcommitted
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: #36591 PR-URL: #37707 Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Richard Lau <[email protected]>
1 parent 836cb67 commit 4487483

File tree

2 files changed

+63
-31
lines changed

2 files changed

+63
-31
lines changed

test/parallel/test-fs-utimes-y2K38.js

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
'use strict';
2+
const common = require('../common');
3+
4+
if (common.isIBMi) {
5+
common.skip('fs.utimesSync() currently fails on IBM i with Y2K38 values');
6+
}
7+
8+
const tmpdir = require('../common/tmpdir');
9+
tmpdir.refresh();
10+
11+
const assert = require('assert');
12+
const fs = require('fs');
13+
14+
// Check for Y2K38 support. For Windows and AIX, assume it's there. Windows
15+
// doesn't have `touch` and `date -r` which are used in the check for support.
16+
// AIX lacks `date -r`.
17+
if (!common.isWindows && !common.isAIX) {
18+
const testFilePath = `${tmpdir.path}/y2k38-test`;
19+
const testFileDate = '204001020304';
20+
const { spawnSync } = require('child_process');
21+
const touchResult = spawnSync('touch',
22+
['-t', testFileDate, testFilePath],
23+
{ encoding: 'utf8' });
24+
if (touchResult.status !== 0) {
25+
common.skip('File system appears to lack Y2K38 support (touch failed)');
26+
}
27+
28+
const dateResult = spawnSync('date',
29+
['-r', testFilePath, '+%Y%m%d%H%M'],
30+
{ encoding: 'utf8' });
31+
32+
assert.strictEqual(dateResult.status, 0);
33+
if (dateResult.stdout.trim() !== testFileDate) {
34+
common.skip('File system appears to lack Y2k38 support (date failed)');
35+
}
36+
}
37+
38+
// Ref: https://github.com/nodejs/node/issues/13255
39+
const path = `${tmpdir.path}/test-utimes-precision`;
40+
fs.writeFileSync(path, '');
41+
42+
const Y2K38_mtime = 2 ** 31;
43+
fs.utimesSync(path, Y2K38_mtime, Y2K38_mtime);
44+
const Y2K38_stats = fs.statSync(path);
45+
assert.strictEqual(Y2K38_stats.mtime.getTime() / 1000, Y2K38_mtime);
46+
47+
if (common.isWindows) {
48+
// This value would get converted to (double)1713037251359.9998
49+
const truncate_mtime = 1713037251360;
50+
fs.utimesSync(path, truncate_mtime / 1000, truncate_mtime / 1000);
51+
const truncate_stats = fs.statSync(path);
52+
assert.strictEqual(truncate_stats.mtime.getTime(), truncate_mtime);
53+
54+
// test Y2K38 for windows
55+
// This value if treaded as a `signed long` gets converted to -2135622133469.
56+
// POSIX systems stores timestamps in {long t_sec, long t_usec}.
57+
// NTFS stores times in nanoseconds in a single `uint64_t`, so when libuv
58+
// calculates (long)`uv_timespec_t.tv_sec` we get 2's complement.
59+
const overflow_mtime = 2159345162531;
60+
fs.utimesSync(path, overflow_mtime / 1000, overflow_mtime / 1000);
61+
const overflow_stats = fs.statSync(path);
62+
assert.strictEqual(overflow_stats.mtime.getTime(), overflow_mtime);
63+
}

test/parallel/test-fs-utimes.js

-31
Original file line numberDiff line numberDiff line change
@@ -156,37 +156,6 @@ function runTests(iter) {
156156
}
157157
}
158158

159-
// Ref: https://github.com/nodejs/node/issues/13255
160-
const path = `${tmpdir.path}/test-utimes-precision`;
161-
fs.writeFileSync(path, '');
162-
163-
// Test Y2K38 for all platforms [except 'arm', 'OpenBSD', 'SunOS' and 'IBMi']
164-
if (!process.arch.includes('arm') &&
165-
!common.isOpenBSD && !common.isSunOS && !common.isIBMi) {
166-
const Y2K38_mtime = 2 ** 31;
167-
fs.utimesSync(path, Y2K38_mtime, Y2K38_mtime);
168-
const Y2K38_stats = fs.statSync(path);
169-
assert.strictEqual(Y2K38_stats.mtime.getTime() / 1000, Y2K38_mtime);
170-
}
171-
172-
if (common.isWindows) {
173-
// This value would get converted to (double)1713037251359.9998
174-
const truncate_mtime = 1713037251360;
175-
fs.utimesSync(path, truncate_mtime / 1000, truncate_mtime / 1000);
176-
const truncate_stats = fs.statSync(path);
177-
assert.strictEqual(truncate_stats.mtime.getTime(), truncate_mtime);
178-
179-
// test Y2K38 for windows
180-
// This value if treaded as a `signed long` gets converted to -2135622133469.
181-
// POSIX systems stores timestamps in {long t_sec, long t_usec}.
182-
// NTFS stores times in nanoseconds in a single `uint64_t`, so when libuv
183-
// calculates (long)`uv_timespec_t.tv_sec` we get 2's complement.
184-
const overflow_mtime = 2159345162531;
185-
fs.utimesSync(path, overflow_mtime / 1000, overflow_mtime / 1000);
186-
const overflow_stats = fs.statSync(path);
187-
assert.strictEqual(overflow_stats.mtime.getTime(), overflow_mtime);
188-
}
189-
190159
const expectTypeError = {
191160
code: 'ERR_INVALID_ARG_TYPE',
192161
name: 'TypeError'

0 commit comments

Comments
 (0)