• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5const fs = require('fs');
6const promiseFs = require('fs').promises;
7const path = require('path');
8const tmpdir = require('../common/tmpdir');
9const { isDate } = require('util').types;
10const { inspect } = require('util');
11
12tmpdir.refresh();
13
14let testIndex = 0;
15
16function getFilename() {
17  const filename = path.join(tmpdir.path, `test-file-${++testIndex}`);
18  fs.writeFileSync(filename, 'test');
19  return filename;
20}
21
22function verifyStats(bigintStats, numStats, allowableDelta) {
23  // allowableDelta: It's possible that the file stats are updated between the
24  // two stat() calls so allow for a small difference.
25  for (const key of Object.keys(numStats)) {
26    const val = numStats[key];
27    if (isDate(val)) {
28      const time = val.getTime();
29      const time2 = bigintStats[key].getTime();
30      assert(
31        time - time2 <= allowableDelta,
32        `difference of ${key}.getTime() should <= ${allowableDelta}.\n` +
33        `Number version ${time}, BigInt version ${time2}n`);
34    } else if (key === 'mode') {
35      assert.strictEqual(bigintStats[key], BigInt(val));
36      assert.strictEqual(
37        bigintStats.isBlockDevice(),
38        numStats.isBlockDevice()
39      );
40      assert.strictEqual(
41        bigintStats.isCharacterDevice(),
42        numStats.isCharacterDevice()
43      );
44      assert.strictEqual(
45        bigintStats.isDirectory(),
46        numStats.isDirectory()
47      );
48      assert.strictEqual(
49        bigintStats.isFIFO(),
50        numStats.isFIFO()
51      );
52      assert.strictEqual(
53        bigintStats.isFile(),
54        numStats.isFile()
55      );
56      assert.strictEqual(
57        bigintStats.isSocket(),
58        numStats.isSocket()
59      );
60      assert.strictEqual(
61        bigintStats.isSymbolicLink(),
62        numStats.isSymbolicLink()
63      );
64    } else if (key.endsWith('Ms')) {
65      const nsKey = key.replace('Ms', 'Ns');
66      const msFromBigInt = bigintStats[key];
67      const nsFromBigInt = bigintStats[nsKey];
68      const msFromBigIntNs = Number(nsFromBigInt / (10n ** 6n));
69      const msFromNum = numStats[key];
70
71      assert(
72        msFromNum - Number(msFromBigInt) <= allowableDelta,
73        `Number version ${key} = ${msFromNum}, ` +
74        `BigInt version ${key} = ${msFromBigInt}n, ` +
75        `Allowable delta = ${allowableDelta}`);
76
77      assert(
78        msFromNum - Number(msFromBigIntNs) <= allowableDelta,
79        `Number version ${key} = ${msFromNum}, ` +
80        `BigInt version ${nsKey} = ${nsFromBigInt}n` +
81        ` = ${msFromBigIntNs}ms, Allowable delta = ${allowableDelta}`);
82    } else if (Number.isSafeInteger(val)) {
83      assert.strictEqual(
84        bigintStats[key], BigInt(val),
85        `${inspect(bigintStats[key])} !== ${inspect(BigInt(val))}\n` +
86        `key=${key}, val=${val}`
87      );
88    } else {
89      assert(
90        Number(bigintStats[key]) - val < 1,
91        `${key} is not a safe integer, difference should < 1.\n` +
92        `Number version ${val}, BigInt version ${bigintStats[key]}n`);
93    }
94  }
95}
96
97const runSyncTest = (func, arg) => {
98  const startTime = process.hrtime.bigint();
99  const bigintStats = func(arg, { bigint: true });
100  const numStats = func(arg);
101  const endTime = process.hrtime.bigint();
102  const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6);
103  verifyStats(bigintStats, numStats, allowableDelta);
104};
105
106{
107  const filename = getFilename();
108  runSyncTest(fs.statSync, filename);
109}
110
111if (!common.isWindows) {
112  const filename = getFilename();
113  const link = `${filename}-link`;
114  fs.symlinkSync(filename, link);
115  runSyncTest(fs.lstatSync, link);
116}
117
118{
119  const filename = getFilename();
120  const fd = fs.openSync(filename, 'r');
121  runSyncTest(fs.fstatSync, fd);
122  fs.closeSync(fd);
123}
124
125const runCallbackTest = (func, arg, done) => {
126  const startTime = process.hrtime.bigint();
127  func(arg, { bigint: true }, common.mustCall((err, bigintStats) => {
128    func(arg, common.mustCall((err, numStats) => {
129      const endTime = process.hrtime.bigint();
130      const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6);
131      verifyStats(bigintStats, numStats, allowableDelta);
132      if (done) {
133        done();
134      }
135    }));
136  }));
137};
138
139{
140  const filename = getFilename();
141  runCallbackTest(fs.stat, filename);
142}
143
144if (!common.isWindows) {
145  const filename = getFilename();
146  const link = `${filename}-link`;
147  fs.symlinkSync(filename, link);
148  runCallbackTest(fs.lstat, link);
149}
150
151{
152  const filename = getFilename();
153  const fd = fs.openSync(filename, 'r');
154  runCallbackTest(fs.fstat, fd, () => { fs.closeSync(fd); });
155}
156
157const runPromiseTest = async (func, arg) => {
158  const startTime = process.hrtime.bigint();
159  const bigintStats = await func(arg, { bigint: true });
160  const numStats = await func(arg);
161  const endTime = process.hrtime.bigint();
162  const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6);
163  verifyStats(bigintStats, numStats, allowableDelta);
164};
165
166{
167  const filename = getFilename();
168  runPromiseTest(promiseFs.stat, filename);
169}
170
171if (!common.isWindows) {
172  const filename = getFilename();
173  const link = `${filename}-link`;
174  fs.symlinkSync(filename, link);
175  runPromiseTest(promiseFs.lstat, link);
176}
177
178(async function() {
179  const filename = getFilename();
180  const handle = await promiseFs.open(filename, 'r');
181  const startTime = process.hrtime.bigint();
182  const bigintStats = await handle.stat({ bigint: true });
183  const numStats = await handle.stat();
184  const endTime = process.hrtime.bigint();
185  const allowableDelta = Math.ceil(Number(endTime - startTime) / 1e6);
186  verifyStats(bigintStats, numStats, allowableDelta);
187  await handle.close();
188})();
189