| 'use strict'; |
| const common = require('../common.js'); |
| const { spawnSync } = require('child_process'); |
| const { existsSync } = require('fs'); |
| const path = require('path'); |
| |
| // This benchmarks the startup of various CLI tools that are already |
| // checked into the source code. We use --version because the output |
| // tends to be minimal and fewer operations are done to generate |
| // these so that the startup cost is still dominated by a more |
| // indispensible part of the CLI. |
| // NOTE: not all tools are present in tarball hence need to filter |
| const availableCli = [ |
| 'tools/eslint/node_modules/eslint/bin/eslint.js', |
| 'deps/npm/bin/npx-cli.js', |
| 'deps/npm/bin/npm-cli.js', |
| 'deps/corepack/dist/corepack.js', |
| ].filter((cli) => existsSync(path.resolve(__dirname, '../../', cli))); |
| const bench = common.createBenchmark(main, { |
| cli: availableCli, |
| n: [30], |
| }); |
| |
| function spawnProcess(cli, bench, state) { |
| const cmd = process.execPath || process.argv[0]; |
| while (state.finished < state.n) { |
| const child = spawnSync(cmd, [cli, '--version'], { |
| env: { npm_config_loglevel: 'silent', ...process.env }, |
| }); |
| // Log some information for debugging if it fails, which it shouldn't. |
| if (child.status !== 0) { |
| console.log('---- STDOUT ----'); |
| console.log(child.stdout.toString()); |
| console.log('---- STDERR ----'); |
| console.log(child.stderr.toString()); |
| throw new Error(`Child process stopped with exit code ${child.status}`); |
| } |
| state.finished++; |
| if (state.finished === 0) { |
| // Finished warmup. |
| bench.start(); |
| } |
| |
| if (state.finished === state.n) { |
| bench.end(state.n); |
| } |
| } |
| } |
| |
| function main({ n, cli }) { |
| cli = path.resolve(__dirname, '../../', cli); |
| const warmup = 3; |
| const state = { n, finished: -warmup }; |
| spawnProcess(cli, bench, state); |
| } |