1// Call fs.promises.readFile over and over again really fast.
2// Then see how many times it got called.
3// Yes, this is a silly benchmark.  Most benchmarks are silly.
4'use strict';
5
6const path = require('path');
7const common = require('../common.js');
8const fs = require('fs');
9const assert = require('assert');
10
11const tmpdir = require('../../test/common/tmpdir');
12tmpdir.refresh();
13const filename = path.resolve(tmpdir.path,
14                              `.removeme-benchmark-garbage-${process.pid}`);
15
16const bench = common.createBenchmark(main, {
17  duration: [5],
18  encoding: ['', 'utf-8'],
19  len: [
20    1024,
21    512 * 1024,
22    4 * 1024 ** 2,
23    8 * 1024 ** 2,
24    16 * 1024 ** 2,
25    32 * 1024 ** 2,
26  ],
27  concurrent: [1, 10],
28});
29
30function main({ len, duration, concurrent, encoding }) {
31  try {
32    fs.unlinkSync(filename);
33  } catch {
34    // Continue regardless of error.
35  }
36  let data = Buffer.alloc(len, 'x');
37  fs.writeFileSync(filename, data);
38  data = null;
39
40  let writes = 0;
41  let benchEnded = false;
42  bench.start();
43  setTimeout(() => {
44    benchEnded = true;
45    bench.end(writes);
46    try {
47      fs.unlinkSync(filename);
48    } catch {
49      // Continue regardless of error.
50    }
51    process.exit(0);
52  }, duration * 1000);
53
54  function read() {
55    fs.promises.readFile(filename, encoding)
56      .then((res) => afterRead(undefined, res))
57      .catch((err) => afterRead(err));
58  }
59
60  function afterRead(er, data) {
61    if (er) {
62      if (er.code === 'ENOENT') {
63        // Only OK if unlinked by the timer from main.
64        assert.ok(benchEnded);
65        return;
66      }
67      throw er;
68    }
69
70    if (data.length !== len)
71      throw new Error('wrong number of bytes returned');
72
73    writes++;
74    if (!benchEnded)
75      read();
76  }
77
78  while (concurrent--) read();
79}
80