| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent a139f5d commit b5901a0
13 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,67 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const assert = require('assert'); | ||
| 4 | + const fs = require('fs'); | ||
| 5 | + const path = require('path'); | ||
| 6 | + | ||
| 7 | + function getHeapProfiles(dir) { | ||
| 8 | + const list = fs.readdirSync(dir); | ||
| 9 | + return list | ||
| 10 | + .filter((file) => file.endsWith('.heapprofile')) | ||
| 11 | + .map((file) => path.join(dir, file)); | ||
| 12 | + } | ||
| 13 | + | ||
| 14 | + function findFirstFrameInNode(root, func) { | ||
| 15 | + const first = root.children.find( | ||
| 16 | + (child) => child.callFrame.functionName === func | ||
| 17 | + ); | ||
| 18 | + if (first) { | ||
| 19 | + return first; | ||
| 20 | + } | ||
| 21 | + for (const child of root.children) { | ||
| 22 | + const first = findFirstFrameInNode(child, func); | ||
| 23 | + if (first) { | ||
| 24 | + return first; | ||
| 25 | + } | ||
| 26 | + } | ||
| 27 | + return undefined; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + function findFirstFrame(file, func) { | ||
| 31 | + const data = fs.readFileSync(file, 'utf8'); | ||
| 32 | + const profile = JSON.parse(data); | ||
| 33 | + const first = findFirstFrameInNode(profile.head, func); | ||
| 34 | + return { frame: first, roots: profile.head.children }; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + function verifyFrames(output, file, func) { | ||
| 38 | + const { frame, roots } = findFirstFrame(file, func); | ||
| 39 | + if (!frame) { | ||
| 40 | + // Show native debug output and the profile for debugging. | ||
| 41 | + console.log(output.stderr.toString()); | ||
| 42 | + console.log(roots); | ||
| 43 | + } | ||
| 44 | + assert.notStrictEqual(frame, undefined); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + // We need to set --heap-prof-interval to a small enough value to make | ||
| 48 | + // sure we can find our workload in the samples, so we need to set | ||
| 49 | + // TEST_ALLOCATION > kHeapProfInterval. | ||
| 50 | + const kHeapProfInterval = 128; | ||
| 51 | + const TEST_ALLOCATION = kHeapProfInterval * 2; | ||
| 52 | + | ||
| 53 | + const env = { | ||
| 54 | + ...process.env, | ||
| 55 | + TEST_ALLOCATION, | ||
| 56 | + NODE_DEBUG_NATIVE: 'INSPECTOR_PROFILER' | ||
| 57 | + }; | ||
| 58 | + | ||
| 59 | + // TODO(joyeecheung): share the fixutres with v8 coverage tests | ||
| 60 | + module.exports = { | ||
| 61 | + getHeapProfiles, | ||
| 62 | + verifyFrames, | ||
| 63 | + findFirstFrame, | ||
| 64 | + kHeapProfInterval, | ||
| 65 | + TEST_ALLOCATION, | ||
| 66 | + env | ||
| 67 | + }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,37 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // Tests --heap-prof without --heap-prof-interval. Here we just verify that | ||
| 4 | + // we manage to generate a profile. | ||
| 5 | + | ||
| 6 | + const common = require('../common'); | ||
| 7 | + | ||
| 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 | + | ||
| 16 | + const { | ||
| 17 | + getHeapProfiles, | ||
| 18 | + env | ||
| 19 | + } = require('../common/prof'); | ||
| 20 | + | ||
| 21 | + { | ||
| 22 | + tmpdir.refresh(); | ||
| 23 | + const output = spawnSync(process.execPath, [ | ||
| 24 | + '--heap-prof', | ||
| 25 | + fixtures.path('workload', 'allocation.js'), | ||
| 26 | + ], { | ||
| 27 | + cwd: tmpdir.path, | ||
| 28 | + env | ||
| 29 | + }); | ||
| 30 | + if (output.status !== 0) { | ||
| 31 | + console.log(output.stderr.toString()); | ||
| 32 | + console.log(output); | ||
| 33 | + } | ||
| 34 | + assert.strictEqual(output.status, 0); | ||
| 35 | + const profiles = getHeapProfiles(tmpdir.path); | ||
| 36 | + assert.strictEqual(profiles.length, 1); | ||
| 37 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,47 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // This tests that --heap-prof, --heap-prof-dir and --heap-prof-name works. | ||
| 4 | + | ||
| 5 | + const common = require('../common'); | ||
| 6 | + | ||
| 7 | + const fixtures = require('../common/fixtures'); | ||
| 8 | + common.skipIfInspectorDisabled(); | ||
| 9 | + | ||
| 10 | + const assert = require('assert'); | ||
| 11 | + const fs = require('fs'); | ||
| 12 | + const path = require('path'); | ||
| 13 | + const { spawnSync } = require('child_process'); | ||
| 14 | + | ||
| 15 | + const tmpdir = require('../common/tmpdir'); | ||
| 16 | + | ||
| 17 | + const { | ||
| 18 | + getHeapProfiles, | ||
| 19 | + verifyFrames, | ||
| 20 | + kHeapProfInterval, | ||
| 21 | + env | ||
| 22 | + } = require('../common/prof'); | ||
| 23 | + | ||
| 24 | + // Tests absolute --heap-prof-dir | ||
| 25 | + { | ||
| 26 | + tmpdir.refresh(); | ||
| 27 | + const dir = path.join(tmpdir.path, 'prof'); | ||
| 28 | + const output = spawnSync(process.execPath, [ | ||
| 29 | + '--heap-prof', | ||
| 30 | + '--heap-prof-dir', | ||
| 31 | + dir, | ||
| 32 | + '--heap-prof-interval', | ||
| 33 | + kHeapProfInterval, | ||
| 34 | + fixtures.path('workload', 'allocation.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 = getHeapProfiles(dir); | ||
| 45 | + assert.strictEqual(profiles.length, 1); | ||
| 46 | + verifyFrames(output, profiles[0], 'runAllocation'); | ||
| 47 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,49 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // Tests --heap-prof-dir and --heap-prof-name work together. | ||
| 4 | + | ||
| 5 | + const common = require('../common'); | ||
| 6 | + | ||
| 7 | + const fixtures = require('../common/fixtures'); | ||
| 8 | + common.skipIfInspectorDisabled(); | ||
| 9 | + | ||
| 10 | + const assert = require('assert'); | ||
| 11 | + const fs = require('fs'); | ||
| 12 | + const path = require('path'); | ||
| 13 | + const { spawnSync } = require('child_process'); | ||
| 14 | + | ||
| 15 | + const tmpdir = require('../common/tmpdir'); | ||
| 16 | + | ||
| 17 | + const { | ||
| 18 | + getHeapProfiles, | ||
| 19 | + verifyFrames, | ||
| 20 | + kHeapProfInterval, | ||
| 21 | + env | ||
| 22 | + } = require('../common/prof'); | ||
| 23 | + | ||
| 24 | + { | ||
| 25 | + tmpdir.refresh(); | ||
| 26 | + const dir = path.join(tmpdir.path, 'prof'); | ||
| 27 | + const file = path.join(dir, 'test.heapprofile'); | ||
| 28 | + const output = spawnSync(process.execPath, [ | ||
| 29 | + '--heap-prof', | ||
| 30 | + '--heap-prof-name', | ||
| 31 | + 'test.heapprofile', | ||
| 32 | + '--heap-prof-dir', | ||
| 33 | + dir, | ||
| 34 | + '--heap-prof-interval', | ||
| 35 | + kHeapProfInterval, | ||
| 36 | + fixtures.path('workload', 'allocation.js'), | ||
| 37 | + ], { | ||
| 38 | + cwd: tmpdir.path, | ||
| 39 | + env | ||
| 40 | + }); | ||
| 41 | + if (output.status !== 0) { | ||
| 42 | + console.log(output.stderr.toString()); | ||
| 43 | + } | ||
| 44 | + assert.strictEqual(output.status, 0); | ||
| 45 | + assert(fs.existsSync(dir)); | ||
| 46 | + const profiles = getHeapProfiles(dir); | ||
| 47 | + assert.deepStrictEqual(profiles, [file]); | ||
| 48 | + verifyFrames(output, file, 'runAllocation'); | ||
| 49 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,46 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // Tests relative --heap-prof-dir works. | ||
| 4 | + | ||
| 5 | + const common = require('../common'); | ||
| 6 | + | ||
| 7 | + const fixtures = require('../common/fixtures'); | ||
| 8 | + common.skipIfInspectorDisabled(); | ||
| 9 | + | ||
| 10 | + const assert = require('assert'); | ||
| 11 | + const fs = require('fs'); | ||
| 12 | + const path = require('path'); | ||
| 13 | + const { spawnSync } = require('child_process'); | ||
| 14 | + | ||
| 15 | + const tmpdir = require('../common/tmpdir'); | ||
| 16 | + | ||
| 17 | + const { | ||
| 18 | + getHeapProfiles, | ||
| 19 | + verifyFrames, | ||
| 20 | + kHeapProfInterval, | ||
| 21 | + env | ||
| 22 | + } = require('../common/prof'); | ||
| 23 | + | ||
| 24 | + { | ||
| 25 | + tmpdir.refresh(); | ||
| 26 | + const output = spawnSync(process.execPath, [ | ||
| 27 | + '--heap-prof', | ||
| 28 | + '--heap-prof-dir', | ||
| 29 | + 'prof', | ||
| 30 | + '--heap-prof-interval', | ||
| 31 | + kHeapProfInterval, | ||
| 32 | + fixtures.path('workload', 'allocation.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 | + const dir = path.join(tmpdir.path, 'prof'); | ||
| 42 | + assert(fs.existsSync(dir)); | ||
| 43 | + const profiles = getHeapProfiles(dir); | ||
| 44 | + assert.strictEqual(profiles.length, 1); | ||
| 45 | + verifyFrames(output, profiles[0], 'runAllocation'); | ||
| 46 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,39 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // Tests --heap-prof generates a heap profile from worker | ||
| 4 | + // when execArgv is set. | ||
| 5 | + | ||
| 6 | + const common = require('../common'); | ||
| 7 | + | ||
| 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 | + | ||
| 16 | + const { | ||
| 17 | + getHeapProfiles, | ||
| 18 | + verifyFrames, | ||
| 19 | + } = require('../common/prof'); | ||
| 20 | + | ||
| 21 | + { | ||
| 22 | + tmpdir.refresh(); | ||
| 23 | + const output = spawnSync(process.execPath, [ | ||
| 24 | + fixtures.path('workload', 'allocation-worker-argv.js'), | ||
| 25 | + ], { | ||
| 26 | + cwd: tmpdir.path, | ||
| 27 | + env: { | ||
| 28 | + ...process.env, | ||
| 29 | + HEAP_PROF_INTERVAL: '128' | ||
| 30 | + } | ||
| 31 | + }); | ||
| 32 | + if (output.status !== 0) { | ||
| 33 | + console.log(output.stderr.toString()); | ||
| 34 | + } | ||
| 35 | + assert.strictEqual(output.status, 0); | ||
| 36 | + const profiles = getHeapProfiles(tmpdir.path); | ||
| 37 | + assert.strictEqual(profiles.length, 1); | ||
| 38 | + verifyFrames(output, profiles[0], 'runAllocation'); | ||
| 39 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,41 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // Tests --heap-prof generates a heap profile when process.exit(55) exits | ||
| 4 | + // process. | ||
| 5 | + | ||
| 6 | + const common = require('../common'); | ||
| 7 | + | ||
| 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 | + | ||
| 16 | + const { | ||
| 17 | + getHeapProfiles, | ||
| 18 | + verifyFrames, | ||
| 19 | + kHeapProfInterval, | ||
| 20 | + env | ||
| 21 | + } = require('../common/prof'); | ||
| 22 | + | ||
| 23 | + { | ||
| 24 | + tmpdir.refresh(); | ||
| 25 | + const output = spawnSync(process.execPath, [ | ||
| 26 | + '--heap-prof', | ||
| 27 | + '--heap-prof-interval', | ||
| 28 | + kHeapProfInterval, | ||
| 29 | + fixtures.path('workload', 'allocation-exit.js'), | ||
| 30 | + ], { | ||
| 31 | + cwd: tmpdir.path, | ||
| 32 | + env | ||
| 33 | + }); | ||
| 34 | + if (output.status !== 55) { | ||
| 35 | + console.log(output.stderr.toString()); | ||
| 36 | + } | ||
| 37 | + assert.strictEqual(output.status, 55); | ||
| 38 | + const profiles = getHeapProfiles(tmpdir.path); | ||
| 39 | + assert.strictEqual(profiles.length, 1); | ||
| 40 | + verifyFrames(output, profiles[0], 'runAllocation'); | ||
| 41 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,56 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // Tests multiple profiles generated by --heap-prof-interval are valid. | ||
| 4 | + | ||
| 5 | + const common = require('../common'); | ||
| 6 | + | ||
| 7 | + const fixtures = require('../common/fixtures'); | ||
| 8 | + common.skipIfInspectorDisabled(); | ||
| 9 | + | ||
| 10 | + const assert = require('assert'); | ||
| 11 | + const fs = require('fs'); | ||
| 12 | + const path = require('path'); | ||
| 13 | + const { spawnSync } = require('child_process'); | ||
| 14 | + | ||
| 15 | + const tmpdir = require('../common/tmpdir'); | ||
| 16 | + | ||
| 17 | + const { | ||
| 18 | + getHeapProfiles, | ||
| 19 | + findFirstFrame, | ||
| 20 | + kHeapProfInterval, | ||
| 21 | + env | ||
| 22 | + } = require('../common/prof'); | ||
| 23 | + | ||
| 24 | + { | ||
| 25 | + tmpdir.refresh(); | ||
| 26 | + const output = spawnSync(process.execPath, [ | ||
| 27 | + '--heap-prof-interval', | ||
| 28 | + kHeapProfInterval, | ||
| 29 | + '--heap-prof-dir', | ||
| 30 | + 'prof', | ||
| 31 | + '--heap-prof', | ||
| 32 | + fixtures.path('workload', 'allocation-worker.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 | + const dir = path.join(tmpdir.path, 'prof'); | ||
| 42 | + assert(fs.existsSync(dir)); | ||
| 43 | + const profiles = getHeapProfiles(dir); | ||
| 44 | + assert.strictEqual(profiles.length, 2); | ||
| 45 | + const profile1 = findFirstFrame(profiles[0], 'runAllocation'); | ||
| 46 | + const profile2 = findFirstFrame(profiles[1], 'runAllocation'); | ||
| 47 | + if (!profile1.frame && !profile2.frame) { | ||
| 48 | + // Show native debug output and the profile for debugging. | ||
| 49 | + console.log(output.stderr.toString()); | ||
| 50 | + console.log('heap path: ', profiles[0]); | ||
| 51 | + console.log(profile1.roots); | ||
| 52 | + console.log('heap path: ', profiles[1]); | ||
| 53 | + console.log(profile2.roots); | ||
| 54 | + } | ||
| 55 | + assert(profile1.frame || profile2.frame); | ||
| 56 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments