Skip to content

Commit 2353c63

Browse files
joyeecheungBridgeAR
authored andcommitted
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: #28170 Refs: #27611 Reviewed-By: Gireesh Punathil <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Yongsheng Zhang <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Sam Roberts <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
1 parent 9382b3b commit 2353c63

13 files changed

+572
-367
lines changed

test/common/cpu-prof.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* eslint-disable node-core/require-common-first, node-core/required-modules */
2+
3+
'use strict';
4+
5+
const common = require('./');
6+
const fs = require('fs');
7+
const path = require('path');
8+
const assert = require('assert');
9+
10+
function getCpuProfiles(dir) {
11+
const list = fs.readdirSync(dir);
12+
return list
13+
.filter((file) => file.endsWith('.cpuprofile'))
14+
.map((file) => path.join(dir, file));
15+
}
16+
17+
function getFrames(output, file, suffix) {
18+
const data = fs.readFileSync(file, 'utf8');
19+
const profile = JSON.parse(data);
20+
const frames = profile.nodes.filter((i) => {
21+
const frame = i.callFrame;
22+
return frame.url.endsWith(suffix);
23+
});
24+
return { frames, nodes: profile.nodes };
25+
}
26+
27+
function verifyFrames(output, file, suffix) {
28+
const { frames, nodes } = getFrames(output, file, suffix);
29+
if (frames.length === 0) {
30+
// Show native debug output and the profile for debugging.
31+
console.log(output.stderr.toString());
32+
console.log(nodes);
33+
}
34+
assert.notDeepStrictEqual(frames, []);
35+
}
36+
37+
let FIB = 30;
38+
// This is based on emperial values - in the CI, on Windows the program
39+
// tend to finish too fast then we won't be able to see the profiled script
40+
// in the samples, so we need to bump the values a bit. On slower platforms
41+
// like the Pis it could take more time to complete, we need to use a
42+
// smaller value so the test would not time out.
43+
if (common.isWindows) {
44+
FIB = 40;
45+
}
46+
47+
// We need to set --cpu-interval to a smaller value to make sure we can
48+
// find our workload in the samples. 50us should be a small enough sampling
49+
// interval for this.
50+
const kCpuProfInterval = 50;
51+
const env = {
52+
...process.env,
53+
FIB,
54+
NODE_DEBUG_NATIVE: 'INSPECTOR_PROFILER'
55+
};
56+
57+
module.exports = {
58+
getCpuProfiles,
59+
kCpuProfInterval,
60+
env,
61+
getFrames,
62+
verifyFrames
63+
};
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use strict';
2+
3+
// Test --cpu-prof without --cpu-prof-interval. Here we just verify that
4+
// we manage to generate a profile since it's hard to tell whether we
5+
// can sample our target function with the default sampling rate across
6+
// different platforms and machine configurations.
7+
8+
const common = require('../common');
9+
const fixtures = require('../common/fixtures');
10+
common.skipIfInspectorDisabled();
11+
12+
const assert = require('assert');
13+
const { spawnSync } = require('child_process');
14+
15+
const tmpdir = require('../common/tmpdir');
16+
const {
17+
getCpuProfiles,
18+
env
19+
} = require('../common/cpu-prof');
20+
21+
{
22+
tmpdir.refresh();
23+
const output = spawnSync(process.execPath, [
24+
'--cpu-prof',
25+
fixtures.path('workload', 'fibonacci.js'),
26+
], {
27+
cwd: tmpdir.path,
28+
env
29+
});
30+
if (output.status !== 0) {
31+
console.log(output.stderr.toString());
32+
}
33+
assert.strictEqual(output.status, 0);
34+
const profiles = getCpuProfiles(tmpdir.path);
35+
assert.strictEqual(profiles.length, 1);
36+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
'use strict';
2+
3+
// This tests that relative --cpu-prof-dir works.
4+
5+
const common = require('../common');
6+
const fixtures = require('../common/fixtures');
7+
common.skipIfInspectorDisabled();
8+
9+
const assert = require('assert');
10+
const fs = require('fs');
11+
const path = require('path');
12+
const { spawnSync } = require('child_process');
13+
14+
const tmpdir = require('../common/tmpdir');
15+
const {
16+
getCpuProfiles,
17+
kCpuProfInterval,
18+
env,
19+
verifyFrames
20+
} = require('../common/cpu-prof');
21+
22+
// relative --cpu-prof-dir
23+
{
24+
tmpdir.refresh();
25+
const dir = path.join(tmpdir.path, 'prof');
26+
const output = spawnSync(process.execPath, [
27+
'--cpu-prof',
28+
'--cpu-prof-interval',
29+
kCpuProfInterval,
30+
'--cpu-prof-dir',
31+
dir,
32+
fixtures.path('workload', 'fibonacci.js'),
33+
], {
34+
cwd: tmpdir.path,
35+
env
36+
});
37+
if (output.status !== 0) {
38+
console.log(output.stderr.toString());
39+
}
40+
assert.strictEqual(output.status, 0);
41+
assert(fs.existsSync(dir));
42+
const profiles = getCpuProfiles(dir);
43+
assert.strictEqual(profiles.length, 1);
44+
verifyFrames(output, profiles[0], 'fibonacci.js');
45+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use strict';
2+
3+
// This tests that --cpu-prof-dir and --cpu-prof-name works together.
4+
5+
const common = require('../common');
6+
const fixtures = require('../common/fixtures');
7+
common.skipIfInspectorDisabled();
8+
9+
const assert = require('assert');
10+
const fs = require('fs');
11+
const path = require('path');
12+
const { spawnSync } = require('child_process');
13+
14+
const tmpdir = require('../common/tmpdir');
15+
const {
16+
getCpuProfiles,
17+
kCpuProfInterval,
18+
env,
19+
verifyFrames
20+
} = require('../common/cpu-prof');
21+
22+
{
23+
tmpdir.refresh();
24+
const dir = path.join(tmpdir.path, 'prof');
25+
const file = path.join(dir, 'test.cpuprofile');
26+
const output = spawnSync(process.execPath, [
27+
'--cpu-prof',
28+
'--cpu-prof-interval',
29+
kCpuProfInterval,
30+
'--cpu-prof-name',
31+
'test.cpuprofile',
32+
'--cpu-prof-dir',
33+
dir,
34+
fixtures.path('workload', 'fibonacci.js'),
35+
], {
36+
cwd: tmpdir.path,
37+
env
38+
});
39+
if (output.status !== 0) {
40+
console.log(output.stderr.toString());
41+
}
42+
assert.strictEqual(output.status, 0);
43+
assert(fs.existsSync(dir));
44+
const profiles = getCpuProfiles(dir);
45+
assert.deepStrictEqual(profiles, [file]);
46+
verifyFrames(output, file, 'fibonacci.js');
47+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
'use strict';
2+
3+
// This tests that relative --cpu-prof-dir works.
4+
5+
const common = require('../common');
6+
const fixtures = require('../common/fixtures');
7+
common.skipIfInspectorDisabled();
8+
9+
const assert = require('assert');
10+
const fs = require('fs');
11+
const path = require('path');
12+
const { spawnSync } = require('child_process');
13+
14+
const tmpdir = require('../common/tmpdir');
15+
const {
16+
getCpuProfiles,
17+
kCpuProfInterval,
18+
env,
19+
verifyFrames
20+
} = require('../common/cpu-prof');
21+
22+
// relative --cpu-prof-dir
23+
{
24+
tmpdir.refresh();
25+
const output = spawnSync(process.execPath, [
26+
'--cpu-prof',
27+
'--cpu-prof-interval',
28+
kCpuProfInterval,
29+
'--cpu-prof-dir',
30+
'prof',
31+
fixtures.path('workload', 'fibonacci.js'),
32+
], {
33+
cwd: tmpdir.path,
34+
env
35+
});
36+
if (output.status !== 0) {
37+
console.log(output.stderr.toString());
38+
}
39+
assert.strictEqual(output.status, 0);
40+
const dir = path.join(tmpdir.path, 'prof');
41+
assert(fs.existsSync(dir));
42+
const profiles = getCpuProfiles(dir);
43+
assert.strictEqual(profiles.length, 1);
44+
verifyFrames(output, profiles[0], 'fibonacci.js');
45+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
'use strict';
2+
3+
// This tests that --cpu-prof-dir works for workers.
4+
5+
const common = require('../common');
6+
const fixtures = require('../common/fixtures');
7+
common.skipIfInspectorDisabled();
8+
9+
const assert = require('assert');
10+
const fs = require('fs');
11+
const path = require('path');
12+
const { spawnSync } = require('child_process');
13+
14+
const tmpdir = require('../common/tmpdir');
15+
const {
16+
getCpuProfiles,
17+
kCpuProfInterval,
18+
env,
19+
getFrames
20+
} = require('../common/cpu-prof');
21+
22+
// --cpu-prof-dir with worker
23+
{
24+
tmpdir.refresh();
25+
const output = spawnSync(process.execPath, [
26+
'--cpu-prof-interval',
27+
kCpuProfInterval,
28+
'--cpu-prof-dir',
29+
'prof',
30+
'--cpu-prof',
31+
fixtures.path('workload', 'fibonacci-worker.js'),
32+
], {
33+
cwd: tmpdir.path,
34+
env
35+
});
36+
if (output.status !== 0) {
37+
console.log(output.stderr.toString());
38+
}
39+
assert.strictEqual(output.status, 0);
40+
const dir = path.join(tmpdir.path, 'prof');
41+
assert(fs.existsSync(dir));
42+
const profiles = getCpuProfiles(dir);
43+
assert.strictEqual(profiles.length, 2);
44+
const profile1 = getFrames(output, profiles[0], 'fibonacci.js');
45+
const profile2 = getFrames(output, profiles[1], 'fibonacci.js');
46+
if (profile1.frames.length === 0 && profile2.frames.length === 0) {
47+
// Show native debug output and the profile for debugging.
48+
console.log(output.stderr.toString());
49+
console.log('CPU path: ', profiles[0]);
50+
console.log(profile1.nodes);
51+
console.log('CPU path: ', profiles[1]);
52+
console.log(profile2.nodes);
53+
}
54+
assert(profile1.frames.length > 0 || profile2.frames.length > 0);
55+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
3+
// This tests that --cpu-prof generates CPU profile when event
4+
// loop is drained.
5+
// TODO(joyeecheung): share the fixtures with v8 coverage tests
6+
7+
const common = require('../common');
8+
const fixtures = require('../common/fixtures');
9+
common.skipIfInspectorDisabled();
10+
11+
const assert = require('assert');
12+
const { spawnSync } = require('child_process');
13+
14+
const tmpdir = require('../common/tmpdir');
15+
const {
16+
getCpuProfiles,
17+
kCpuProfInterval,
18+
env,
19+
verifyFrames
20+
} = require('../common/cpu-prof');
21+
22+
{
23+
tmpdir.refresh();
24+
const output = spawnSync(process.execPath, [
25+
'--cpu-prof',
26+
'--cpu-prof-interval',
27+
kCpuProfInterval,
28+
fixtures.path('workload', 'fibonacci.js'),
29+
], {
30+
cwd: tmpdir.path,
31+
env
32+
});
33+
if (output.status !== 0) {
34+
console.log(output.stderr.toString());
35+
}
36+
assert.strictEqual(output.status, 0);
37+
const profiles = getCpuProfiles(tmpdir.path);
38+
assert.strictEqual(profiles.length, 1);
39+
verifyFrames(output, profiles[0], 'fibonacci.js');
40+
}

test/parallel/test-cpu-prof-exit.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict';
2+
3+
// This tests that --cpu-prof generates CPU profile when
4+
// process.exit(55) exits the process.
5+
6+
const common = require('../common');
7+
const fixtures = require('../common/fixtures');
8+
common.skipIfInspectorDisabled();
9+
10+
const assert = require('assert');
11+
const { spawnSync } = require('child_process');
12+
13+
const tmpdir = require('../common/tmpdir');
14+
const {
15+
getCpuProfiles,
16+
kCpuProfInterval,
17+
env,
18+
verifyFrames
19+
} = require('../common/cpu-prof');
20+
21+
{
22+
tmpdir.refresh();
23+
const output = spawnSync(process.execPath, [
24+
'--cpu-prof',
25+
'--cpu-prof-interval',
26+
kCpuProfInterval,
27+
fixtures.path('workload', 'fibonacci-exit.js'),
28+
], {
29+
cwd: tmpdir.path,
30+
env
31+
});
32+
if (output.status !== 55) {
33+
console.log(output.stderr.toString());
34+
}
35+
assert.strictEqual(output.status, 55);
36+
const profiles = getCpuProfiles(tmpdir.path);
37+
assert.strictEqual(profiles.length, 1);
38+
verifyFrames(output, profiles[0], 'fibonacci-exit.js');
39+
}

0 commit comments

Comments
 (0)