mirror of
https://github.com/nodejs/node.git
synced 2024-11-29 23:16:30 +01:00
546d6cdd9e
Co-authored-by: Matheus Marchini <mat@mmarchini.me> PR-URL: https://github.com/nodejs/node/pull/27364 Refs: https://github.com/nodejs/build/issues/1774 Reviewed-By: Matheus Marchini <mat@mmarchini.me> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
113 lines
3.0 KiB
JavaScript
113 lines
3.0 KiB
JavaScript
'use strict';
|
|
|
|
// This test verifies that JavaScript functions are being correctly sampled by
|
|
// Linux perf. The test runs a JavaScript script, sampling the execution with
|
|
// Linux perf. It then uses `perf script` to generate a human-readable output,
|
|
// and uses regular expressions to find samples of the functions defined in
|
|
// `fixtures/linux-perf.js`.
|
|
|
|
// NOTE (mmarchini): this test is meant to run only on Linux machines with Linux
|
|
// perf installed. It will skip if those criteria are not met.
|
|
|
|
const common = require('../common');
|
|
if (!common.hasCrypto)
|
|
common.skip('missing crypto');
|
|
|
|
const assert = require('assert');
|
|
const { spawnSync } = require('child_process');
|
|
const fixtures = require('../common/fixtures');
|
|
const tmpdir = require('../common/tmpdir');
|
|
tmpdir.refresh();
|
|
|
|
if (process.config.variables.node_shared)
|
|
common.skip("can't test Linux perf with shared libraries yet");
|
|
|
|
if (!common.isLinux)
|
|
common.skip('only testing Linux for now');
|
|
|
|
const frequency = 99;
|
|
|
|
const repeat = 5;
|
|
|
|
// Expected number of samples we'll capture per repeat
|
|
const sampleCount = 10;
|
|
const sleepTime = sampleCount * (1.0 / frequency);
|
|
|
|
const perfFlags = [
|
|
'record',
|
|
`-F${frequency}`,
|
|
'-g',
|
|
];
|
|
|
|
const nodeCommonFlags = [
|
|
'--perf-basic-prof',
|
|
'--interpreted-frames-native-stack',
|
|
'--no-turbo-inlining', // Otherwise simple functions might get inlined.
|
|
];
|
|
|
|
const perfInterpretedFramesArgs = [
|
|
...perfFlags,
|
|
'--',
|
|
process.execPath,
|
|
...nodeCommonFlags,
|
|
'--no-opt',
|
|
fixtures.path('linux-perf.js'),
|
|
`${sleepTime}`,
|
|
`${repeat}`,
|
|
];
|
|
|
|
const perfCompiledFramesArgs = [
|
|
...perfFlags,
|
|
'--',
|
|
process.execPath,
|
|
...nodeCommonFlags,
|
|
'--always-opt',
|
|
fixtures.path('linux-perf.js'),
|
|
`${sleepTime}`,
|
|
`${repeat}`,
|
|
];
|
|
|
|
const perfArgsList = [
|
|
perfInterpretedFramesArgs, perfCompiledFramesArgs
|
|
];
|
|
|
|
const perfScriptArgs = [
|
|
'script',
|
|
];
|
|
|
|
const options = {
|
|
cwd: tmpdir.path,
|
|
encoding: 'utf-8',
|
|
};
|
|
|
|
let output = '';
|
|
|
|
for (const perfArgs of perfArgsList) {
|
|
const perf = spawnSync('perf', perfArgs, options);
|
|
assert.ifError(perf.error);
|
|
if (perf.status !== 0)
|
|
throw new Error(`Failed to execute 'perf': ${perf.stderr}`);
|
|
|
|
const perfScript = spawnSync('perf', perfScriptArgs, options);
|
|
assert.ifError(perfScript.error);
|
|
if (perfScript.status !== 0)
|
|
throw new Error(`Failed to execute perf script: ${perfScript.stderr}`);
|
|
|
|
output += perfScript.stdout;
|
|
}
|
|
|
|
const interpretedFunctionOneRe = /InterpretedFunction:functionOne/;
|
|
const compiledFunctionOneRe = /LazyCompile:\*functionOne/;
|
|
const interpretedFunctionTwoRe = /InterpretedFunction:functionTwo/;
|
|
const compiledFunctionTwoRe = /LazyCompile:\*functionTwo/;
|
|
|
|
|
|
assert.ok(output.match(interpretedFunctionOneRe),
|
|
"Couldn't find interpreted functionOne()");
|
|
assert.ok(output.match(compiledFunctionOneRe),
|
|
"Couldn't find compiled functionOne()");
|
|
assert.ok(output.match(interpretedFunctionTwoRe),
|
|
"Couldn't find interpreted functionTwo()");
|
|
assert.ok(output.match(compiledFunctionTwoRe),
|
|
"Couldn't find compiled functionTwo");
|