mirror of https://github.com/nodejs/node.git
test: split test-cpu-prof.js
Split test-cpu-prof.js into multiple files for different test cases so it's easier to find the problematic one if it flakes. Also move the split tests into parallel. PR-URL: https://github.com/nodejs/node/pull/28170 Refs: https://github.com/nodejs/node/issues/27611 Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This commit is contained in:
parent
d2634be562
commit
8f98cf5e15
|
@ -0,0 +1,63 @@
|
|||
/* eslint-disable node-core/require-common-first, node-core/required-modules */
|
||||
|
||||
'use strict';
|
||||
|
||||
const common = require('./');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const assert = require('assert');
|
||||
|
||||
function getCpuProfiles(dir) {
|
||||
const list = fs.readdirSync(dir);
|
||||
return list
|
||||
.filter((file) => file.endsWith('.cpuprofile'))
|
||||
.map((file) => path.join(dir, file));
|
||||
}
|
||||
|
||||
function getFrames(output, file, suffix) {
|
||||
const data = fs.readFileSync(file, 'utf8');
|
||||
const profile = JSON.parse(data);
|
||||
const frames = profile.nodes.filter((i) => {
|
||||
const frame = i.callFrame;
|
||||
return frame.url.endsWith(suffix);
|
||||
});
|
||||
return { frames, nodes: profile.nodes };
|
||||
}
|
||||
|
||||
function verifyFrames(output, file, suffix) {
|
||||
const { frames, nodes } = getFrames(output, file, suffix);
|
||||
if (frames.length === 0) {
|
||||
// Show native debug output and the profile for debugging.
|
||||
console.log(output.stderr.toString());
|
||||
console.log(nodes);
|
||||
}
|
||||
assert.notDeepStrictEqual(frames, []);
|
||||
}
|
||||
|
||||
let FIB = 30;
|
||||
// This is based on emperial values - in the CI, on Windows the program
|
||||
// tend to finish too fast then we won't be able to see the profiled script
|
||||
// in the samples, so we need to bump the values a bit. On slower platforms
|
||||
// like the Pis it could take more time to complete, we need to use a
|
||||
// smaller value so the test would not time out.
|
||||
if (common.isWindows) {
|
||||
FIB = 40;
|
||||
}
|
||||
|
||||
// We need to set --cpu-interval to a smaller value to make sure we can
|
||||
// find our workload in the samples. 50us should be a small enough sampling
|
||||
// interval for this.
|
||||
const kCpuProfInterval = 50;
|
||||
const env = {
|
||||
...process.env,
|
||||
FIB,
|
||||
NODE_DEBUG_NATIVE: 'INSPECTOR_PROFILER'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getCpuProfiles,
|
||||
kCpuProfInterval,
|
||||
env,
|
||||
getFrames,
|
||||
verifyFrames
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
'use strict';
|
||||
|
||||
// Test --cpu-prof without --cpu-prof-interval. Here we just verify that
|
||||
// we manage to generate a profile since it's hard to tell whether we
|
||||
// can sample our target function with the default sampling rate across
|
||||
// different platforms and machine configurations.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
getCpuProfiles,
|
||||
env
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that relative --cpu-prof-dir works.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
getCpuProfiles,
|
||||
kCpuProfInterval,
|
||||
env,
|
||||
verifyFrames
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
// relative --cpu-prof-dir
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const dir = path.join(tmpdir.path, 'prof');
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
'--cpu-prof-dir',
|
||||
dir,
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
assert(fs.existsSync(dir));
|
||||
const profiles = getCpuProfiles(dir);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci.js');
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that --cpu-prof-dir and --cpu-prof-name works together.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
getCpuProfiles,
|
||||
kCpuProfInterval,
|
||||
env,
|
||||
verifyFrames
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const dir = path.join(tmpdir.path, 'prof');
|
||||
const file = path.join(dir, 'test.cpuprofile');
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
'--cpu-prof-name',
|
||||
'test.cpuprofile',
|
||||
'--cpu-prof-dir',
|
||||
dir,
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
assert(fs.existsSync(dir));
|
||||
const profiles = getCpuProfiles(dir);
|
||||
assert.deepStrictEqual(profiles, [file]);
|
||||
verifyFrames(output, file, 'fibonacci.js');
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that relative --cpu-prof-dir works.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
getCpuProfiles,
|
||||
kCpuProfInterval,
|
||||
env,
|
||||
verifyFrames
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
// relative --cpu-prof-dir
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
'--cpu-prof-dir',
|
||||
'prof',
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const dir = path.join(tmpdir.path, 'prof');
|
||||
assert(fs.existsSync(dir));
|
||||
const profiles = getCpuProfiles(dir);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci.js');
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that --cpu-prof-dir works for workers.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
getCpuProfiles,
|
||||
kCpuProfInterval,
|
||||
env,
|
||||
getFrames
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
// --cpu-prof-dir with worker
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
'--cpu-prof-dir',
|
||||
'prof',
|
||||
'--cpu-prof',
|
||||
fixtures.path('workload', 'fibonacci-worker.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const dir = path.join(tmpdir.path, 'prof');
|
||||
assert(fs.existsSync(dir));
|
||||
const profiles = getCpuProfiles(dir);
|
||||
assert.strictEqual(profiles.length, 2);
|
||||
const profile1 = getFrames(output, profiles[0], 'fibonacci.js');
|
||||
const profile2 = getFrames(output, profiles[1], 'fibonacci.js');
|
||||
if (profile1.frames.length === 0 && profile2.frames.length === 0) {
|
||||
// Show native debug output and the profile for debugging.
|
||||
console.log(output.stderr.toString());
|
||||
console.log('CPU path: ', profiles[0]);
|
||||
console.log(profile1.nodes);
|
||||
console.log('CPU path: ', profiles[1]);
|
||||
console.log(profile2.nodes);
|
||||
}
|
||||
assert(profile1.frames.length > 0 || profile2.frames.length > 0);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that --cpu-prof generates CPU profile when event
|
||||
// loop is drained.
|
||||
// TODO(joyeecheung): share the fixtures with v8 coverage tests
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
getCpuProfiles,
|
||||
kCpuProfInterval,
|
||||
env,
|
||||
verifyFrames
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci.js');
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that --cpu-prof generates CPU profile when
|
||||
// process.exit(55) exits the process.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
getCpuProfiles,
|
||||
kCpuProfInterval,
|
||||
env,
|
||||
verifyFrames
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
fixtures.path('workload', 'fibonacci-exit.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 55) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 55);
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci-exit.js');
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that invalid --cpu-prof options are rejected.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
kCpuProfInterval,
|
||||
env
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
// --cpu-prof-name without --cpu-prof
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof-name',
|
||||
'test.cpuprofile',
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
const stderr = output.stderr.toString().trim();
|
||||
if (output.status !== 9) {
|
||||
console.log(stderr);
|
||||
}
|
||||
assert.strictEqual(output.status, 9);
|
||||
assert.strictEqual(
|
||||
stderr,
|
||||
`${process.execPath}: --cpu-prof-name must be used with --cpu-prof`);
|
||||
}
|
||||
|
||||
// --cpu-prof-dir without --cpu-prof
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof-dir',
|
||||
'prof',
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
const stderr = output.stderr.toString().trim();
|
||||
if (output.status !== 9) {
|
||||
console.log(stderr);
|
||||
}
|
||||
assert.strictEqual(output.status, 9);
|
||||
assert.strictEqual(
|
||||
stderr,
|
||||
`${process.execPath}: --cpu-prof-dir must be used with --cpu-prof`);
|
||||
}
|
||||
|
||||
// --cpu-prof-interval without --cpu-prof
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
const stderr = output.stderr.toString().trim();
|
||||
if (output.status !== 9) {
|
||||
console.log(stderr);
|
||||
}
|
||||
assert.strictEqual(output.status, 9);
|
||||
assert.strictEqual(
|
||||
stderr,
|
||||
`${process.execPath}: --cpu-prof-interval must be used with --cpu-prof`);
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that --cpu-prof generates CPU profile when
|
||||
// process.kill(process.pid, "SIGINT"); exits the process.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
getCpuProfiles,
|
||||
kCpuProfInterval,
|
||||
env,
|
||||
verifyFrames
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
fixtures.path('workload', 'fibonacci-sigint.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (!common.isWindows) {
|
||||
if (output.signal !== 'SIGINT') {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.signal, 'SIGINT');
|
||||
}
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci-sigint.js');
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that --cpu-prof-name can be used to specify the
|
||||
// name of the generated CPU profile.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
getCpuProfiles,
|
||||
kCpuProfInterval,
|
||||
env,
|
||||
verifyFrames
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
// --cpu-prof-name
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const file = path.join(tmpdir.path, 'test.cpuprofile');
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
'--cpu-prof-name',
|
||||
'test.cpuprofile',
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.deepStrictEqual(profiles, [file]);
|
||||
verifyFrames(output, file, 'fibonacci.js');
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that --cpu-prof generates CPU profile from worker
|
||||
// when execArgv is set.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const {
|
||||
getCpuProfiles,
|
||||
kCpuProfInterval,
|
||||
verifyFrames
|
||||
} = require('../common/cpu-prof');
|
||||
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
fixtures.path('workload', 'fibonacci-worker-argv.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env: {
|
||||
...process.env,
|
||||
CPU_PROF_INTERVAL: kCpuProfInterval
|
||||
}
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci.js');
|
||||
}
|
|
@ -1,367 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
// This tests that --cpu-prof, --cpu-prof-dir and --cpu-prof-name works.
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
common.skipIfInspectorDisabled();
|
||||
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
|
||||
function getCpuProfiles(dir) {
|
||||
const list = fs.readdirSync(dir);
|
||||
return list
|
||||
.filter((file) => file.endsWith('.cpuprofile'))
|
||||
.map((file) => path.join(dir, file));
|
||||
}
|
||||
|
||||
function getFrames(output, file, suffix) {
|
||||
const data = fs.readFileSync(file, 'utf8');
|
||||
const profile = JSON.parse(data);
|
||||
const frames = profile.nodes.filter((i) => {
|
||||
const frame = i.callFrame;
|
||||
return frame.url.endsWith(suffix);
|
||||
});
|
||||
return { frames, nodes: profile.nodes };
|
||||
}
|
||||
|
||||
function verifyFrames(output, file, suffix) {
|
||||
const { frames, nodes } = getFrames(output, file, suffix);
|
||||
if (frames.length === 0) {
|
||||
// Show native debug output and the profile for debugging.
|
||||
console.log(output.stderr.toString());
|
||||
console.log(nodes);
|
||||
}
|
||||
assert.notDeepStrictEqual(frames, []);
|
||||
}
|
||||
|
||||
let FIB = 30;
|
||||
// This is based on emperial values - in the CI, on Windows the program
|
||||
// tend to finish too fast then we won't be able to see the profiled script
|
||||
// in the samples, so we need to bump the values a bit. On slower platforms
|
||||
// like the Pis it could take more time to complete, we need to use a
|
||||
// smaller value so the test would not time out.
|
||||
if (common.isWindows) {
|
||||
FIB = 40;
|
||||
}
|
||||
|
||||
// We need to set --cpu-interval to a smaller value to make sure we can
|
||||
// find our workload in the samples. 50us should be a small enough sampling
|
||||
// interval for this.
|
||||
const kCpuProfInterval = 50;
|
||||
const env = {
|
||||
...process.env,
|
||||
FIB,
|
||||
NODE_DEBUG_NATIVE: 'INSPECTOR_PROFILER'
|
||||
};
|
||||
|
||||
// Test --cpu-prof without --cpu-prof-interval. Here we just verify that
|
||||
// we manage to generate a profile.
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
}
|
||||
|
||||
// Outputs CPU profile when event loop is drained.
|
||||
// TODO(joyeecheung): share the fixutres with v8 coverage tests
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci.js');
|
||||
}
|
||||
|
||||
// Outputs CPU profile when process.exit(55) exits process.
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
fixtures.path('workload', 'fibonacci-exit.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 55) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 55);
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci-exit.js');
|
||||
}
|
||||
|
||||
// Outputs CPU profile when process.kill(process.pid, "SIGINT"); exits process.
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
fixtures.path('workload', 'fibonacci-sigint.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (!common.isWindows) {
|
||||
if (output.signal !== 'SIGINT') {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.signal, 'SIGINT');
|
||||
}
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci-sigint.js');
|
||||
}
|
||||
|
||||
// Outputs CPU profile from worker when execArgv is set.
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
fixtures.path('workload', 'fibonacci-worker-argv.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env: {
|
||||
...process.env,
|
||||
CPU_PROF_INTERVAL: kCpuProfInterval
|
||||
}
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci.js');
|
||||
}
|
||||
|
||||
// --cpu-prof-name without --cpu-prof
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof-name',
|
||||
'test.cpuprofile',
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
const stderr = output.stderr.toString().trim();
|
||||
if (output.status !== 9) {
|
||||
console.log(stderr);
|
||||
}
|
||||
assert.strictEqual(output.status, 9);
|
||||
assert.strictEqual(
|
||||
stderr,
|
||||
`${process.execPath}: --cpu-prof-name must be used with --cpu-prof`);
|
||||
}
|
||||
|
||||
// --cpu-prof-dir without --cpu-prof
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof-dir',
|
||||
'prof',
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
const stderr = output.stderr.toString().trim();
|
||||
if (output.status !== 9) {
|
||||
console.log(stderr);
|
||||
}
|
||||
assert.strictEqual(output.status, 9);
|
||||
assert.strictEqual(
|
||||
stderr,
|
||||
`${process.execPath}: --cpu-prof-dir must be used with --cpu-prof`);
|
||||
}
|
||||
|
||||
// --cpu-prof-interval without --cpu-prof
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
const stderr = output.stderr.toString().trim();
|
||||
if (output.status !== 9) {
|
||||
console.log(stderr);
|
||||
}
|
||||
assert.strictEqual(output.status, 9);
|
||||
assert.strictEqual(
|
||||
stderr,
|
||||
`${process.execPath}: --cpu-prof-interval must be used with --cpu-prof`);
|
||||
}
|
||||
|
||||
// --cpu-prof-name
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const file = path.join(tmpdir.path, 'test.cpuprofile');
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
'--cpu-prof-name',
|
||||
'test.cpuprofile',
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const profiles = getCpuProfiles(tmpdir.path);
|
||||
assert.deepStrictEqual(profiles, [file]);
|
||||
verifyFrames(output, file, 'fibonacci.js');
|
||||
}
|
||||
|
||||
// relative --cpu-prof-dir
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
'--cpu-prof-dir',
|
||||
'prof',
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const dir = path.join(tmpdir.path, 'prof');
|
||||
assert(fs.existsSync(dir));
|
||||
const profiles = getCpuProfiles(dir);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci.js');
|
||||
}
|
||||
|
||||
// absolute --cpu-prof-dir
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const dir = path.join(tmpdir.path, 'prof');
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
'--cpu-prof-dir',
|
||||
dir,
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
assert(fs.existsSync(dir));
|
||||
const profiles = getCpuProfiles(dir);
|
||||
assert.strictEqual(profiles.length, 1);
|
||||
verifyFrames(output, profiles[0], 'fibonacci.js');
|
||||
}
|
||||
|
||||
// --cpu-prof-dir and --cpu-prof-name
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const dir = path.join(tmpdir.path, 'prof');
|
||||
const file = path.join(dir, 'test.cpuprofile');
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof',
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
'--cpu-prof-name',
|
||||
'test.cpuprofile',
|
||||
'--cpu-prof-dir',
|
||||
dir,
|
||||
fixtures.path('workload', 'fibonacci.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
assert(fs.existsSync(dir));
|
||||
const profiles = getCpuProfiles(dir);
|
||||
assert.deepStrictEqual(profiles, [file]);
|
||||
verifyFrames(output, file, 'fibonacci.js');
|
||||
}
|
||||
|
||||
// --cpu-prof-dir with worker
|
||||
{
|
||||
tmpdir.refresh();
|
||||
const output = spawnSync(process.execPath, [
|
||||
'--cpu-prof-interval',
|
||||
kCpuProfInterval,
|
||||
'--cpu-prof-dir',
|
||||
'prof',
|
||||
'--cpu-prof',
|
||||
fixtures.path('workload', 'fibonacci-worker.js'),
|
||||
], {
|
||||
cwd: tmpdir.path,
|
||||
env
|
||||
});
|
||||
if (output.status !== 0) {
|
||||
console.log(output.stderr.toString());
|
||||
}
|
||||
assert.strictEqual(output.status, 0);
|
||||
const dir = path.join(tmpdir.path, 'prof');
|
||||
assert(fs.existsSync(dir));
|
||||
const profiles = getCpuProfiles(dir);
|
||||
assert.strictEqual(profiles.length, 2);
|
||||
const profile1 = getFrames(output, profiles[0], 'fibonacci.js');
|
||||
const profile2 = getFrames(output, profiles[1], 'fibonacci.js');
|
||||
if (profile1.frames.length === 0 && profile2.frames.length === 0) {
|
||||
// Show native debug output and the profile for debugging.
|
||||
console.log(output.stderr.toString());
|
||||
console.log('CPU path: ', profiles[0]);
|
||||
console.log(profile1.nodes);
|
||||
console.log('CPU path: ', profiles[1]);
|
||||
console.log(profile2.nodes);
|
||||
}
|
||||
assert(profile1.frames.length > 0 || profile2.frames.length > 0);
|
||||
}
|
Loading…
Reference in New Issue