◐ Shell
clean mode source ↗

test: add test for Linux perf · nodejs/node@a4ad989

1+

'use strict';

2+3+

// This test verifies that JavaScript functions are being correctly sampled by

4+

// Linux perf. The test runs a JavaScript script, sampling the execution with

5+

// Linux perf. It then uses `perf script` to generate a human-readable output,

6+

// and uses regular expressions to find samples of the functions defined in

7+

// `fixtures/linux-perf.js`.

8+9+

// NOTE (mmarchini): this test is meant to run only on Linux machines with Linux

10+

// perf installed. It will skip if those criteria are not met.

11+12+

const common = require('../common');

13+

if (!common.hasCrypto)

14+

common.skip('missing crypto');

15+16+

const assert = require('assert');

17+

const { spawnSync } = require('child_process');

18+

const fixtures = require('../common/fixtures');

19+

const tmpdir = require('../common/tmpdir');

20+

tmpdir.refresh();

21+22+

if (process.config.variables.node_shared)

23+

common.skip("can't test Linux perf with shared libraries yet");

24+25+

const perfArgs = [

26+

'record',

27+

'-F500',

28+

'-g',

29+

'--',

30+

process.execPath,

31+

'--perf-basic-prof',

32+

'--interpreted-frames-native-stack',

33+

'--no-turbo-inlining', // Otherwise simple functions might get inlined.

34+

fixtures.path('linux-perf.js'),

35+

];

36+37+

const perfScriptArgs = [

38+

'script',

39+

];

40+41+

const options = {

42+

cwd: tmpdir.path,

43+

encoding: 'utf-8',

44+

};

45+46+

if (!common.isLinux)

47+

common.skip('only testing Linux for now');

48+49+

const perf = spawnSync('perf', perfArgs, options);

50+51+

if (perf.error && perf.error.errno === 'ENOENT')

52+

common.skip('perf not found on system');

53+54+

if (perf.status !== 0) {

55+

common.skip(`Failed to execute perf: ${perf.stderr}`);

56+

}

57+58+

const perfScript = spawnSync('perf', perfScriptArgs, options);

59+60+

if (perf.error)

61+

common.skip(`perf script aborted: ${perf.error.errno}`);

62+63+

if (perfScript.status !== 0) {

64+

common.skip(`Failed to execute perf script: ${perfScript.stderr}`);

65+

}

66+67+

const interpretedFunctionOneRe = /InterpretedFunction:functionOne/;

68+

const compiledFunctionOneRe = /LazyCompile:\*functionOne/;

69+

const interpretedFunctionTwoRe = /InterpretedFunction:functionTwo/;

70+

const compiledFunctionTwoRe = /LazyCompile:\*functionTwo/;

71+72+

const output = perfScript.stdout;

73+74+

assert.ok(output.match(interpretedFunctionOneRe),

75+

"Couldn't find interpreted functionOne()");

76+

assert.ok(output.match(compiledFunctionOneRe),

77+

"Couldn't find compiled functionOne()");

78+

assert.ok(output.match(interpretedFunctionTwoRe),

79+

"Couldn't find interpreted functionTwo()");

80+

assert.ok(output.match(compiledFunctionTwoRe),

81+

"Couldn't find compiled functionTwo");