diff --git a/README.md b/README.md index 09f2897..face38c 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,10 @@ const heapProfiler = new ClinicHeapProfiler() **Default**: false - debug [``][] If set to true, the generated html will not be minified. **Default**: false - - dest [``][] The file where the collected data is stored. - **Default**: `./.clinic/.clinic-heapprofile` + - dest [``][] Destination for the collected data + **Default**: `.clinic` + - name [``][] File name for the collected data + **Default**: `.clinic-heapprofiler` #### `heapProfiler.collect(args, callback)` diff --git a/src/index.js b/src/index.js index 5661d2c..1d3a3ec 100644 --- a/src/index.js +++ b/src/index.js @@ -16,7 +16,7 @@ const { analyse } = require('./analysis/index.js') const noop = function () {} function execute (instance, args, env, nodeOptions, cb) { - ensureDir(path.dirname(instance.dest), err => { + ensureDir(instance.path, err => { /* istanbul ignore if */ if (err) { cb(err) @@ -44,7 +44,7 @@ function execute (instance, args, env, nodeOptions, cb) { return } - cb(null, instance.dest) + cb(null, `${instance.path}/${instance.name || instance.process.pid}.clinic-heapprofiler`) }) }) } @@ -105,14 +105,15 @@ class ClinicHeapProfiler extends events.EventEmitter { detectPort = false, collectOnFailure = false, debug = false, - name, - dest = `.clinic/${name || process.pid}.clinic-heapprofiler` + dest = '.clinic', + name } = settings this.detectPort = !!detectPort this.collectOnFailure = !!collectOnFailure this.debug = debug - this.dest = dest + this.path = dest + this.name = name } collect (args, cb) { @@ -125,7 +126,8 @@ class ClinicHeapProfiler extends events.EventEmitter { const env = { ...process.env, - HEAP_PROFILER_DESTINATION: this.dest, + HEAP_PROFILER_NAME: this.name, + HEAP_PROFILER_PATH: this.path, HEAP_PROFILER_PRELOADER_DISABLED: 'true', HEAP_PROFILER_USE_IPC: this.detectPort } diff --git a/src/injects/ipc.js b/src/injects/ipc.js index 42608ae..3c851dc 100644 --- a/src/injects/ipc.js +++ b/src/injects/ipc.js @@ -7,7 +7,10 @@ const onNetListen = require('on-net-listen') const controller = new AbortController() const clinicPort = parseInt(process.env.CLINIC_HEAP_PROFILER_PORT, 10) -const profilerOptions = { destination: process.env.HEAP_PROFILER_DESTINATION, signal: controller.signal } +const profilerOptions = { + destination: `${process.env.HEAP_PROFILER_PATH}/${process.env.HEAP_PROFILER_NAME || process.pid}.clinic-heapprofiler`, + signal: controller.signal +} let toSend = 2 // We need to send two ports: the IPC one and the application one let server diff --git a/test/cmd-dest.test.js b/test/cmd-dest.test.js index 32a9896..252c157 100644 --- a/test/cmd-dest.test.js +++ b/test/cmd-dest.test.js @@ -5,45 +5,152 @@ const path = require('path') const { test } = require('tap') const ClinicHeapProfiler = require('../src/index.js') +test('cmd - test collect - default name (child_process.pid) and output destination (.clinic)', t => { + const tool = new ClinicHeapProfiler({ debug: true }) + + function cleanup (err, filepath) { + function callback (err) { + t.error(err) + t.end() + } + + t.error(err) + + t.match(filepath, /^\.clinic(\/|\\)[0-9]+\.clinic-heapprofiler$/) + + fs.rm(path.dirname(filepath), { recursive: true }, callback) + } + + tool.collect([process.execPath, path.join('test', 'fixtures', 'randomHashes.js')], (err, filepath) => { + if (err) { + cleanup(err, filepath) + return + } + + t.match(filepath, tool.process.pid.toString()) + + t.ok(fs.statSync(filepath).isFile()) + + tool.visualize(filepath, `${filepath}.html`, err => { + if (err) { + cleanup(err, filepath) + return + } + + t.ok(fs.statSync(`${filepath}.html`).isFile()) + + cleanup(null, filepath) + }) + }) +}) + test('cmd - test collect - custom output destination', t => { const tool = new ClinicHeapProfiler({ debug: true, dest: 'test-output-destination' }) - function cleanup (err, filename) { - let count = 0 + function cleanup (err, filepath) { + function callback (err) { + t.error(err) + t.end() + } + + t.error(err) + + t.match(filepath, /^test-output-destination/) + + fs.rm(path.dirname(filepath), { recursive: true }, callback) + } + + tool.collect([process.execPath, path.join('test', 'fixtures', 'randomHashes.js')], (err, filepath) => { + if (err) { + cleanup(err, filepath) + return + } + + t.ok(fs.statSync(filepath).isFile()) + + tool.visualize(filepath, `${filepath}.html`, err => { + if (err) { + cleanup(err, filepath) + return + } + + t.ok(fs.statSync(`${filepath}.html`).isFile()) + + cleanup(null, filepath) + }) + }) +}) +test('cmd - test collect - custom output name', t => { + const tool = new ClinicHeapProfiler({ debug: true, name: 'test-custom-name' }) + + function cleanup (err, filepath) { function callback (err) { t.error(err) + t.end() + } - if (++count === 2) { - t.end() + t.error(err) + + t.equal(filepath, '.clinic/test-custom-name.clinic-heapprofiler') + + fs.rm(path.dirname(filepath), { recursive: true }, callback) + } + + tool.collect([process.execPath, path.join('test', 'fixtures', 'randomHashes.js')], (err, filepath) => { + if (err) { + cleanup(err, filepath) + return + } + + t.ok(fs.statSync(filepath).isFile()) + + tool.visualize(filepath, `${filepath}.html`, err => { + if (err) { + cleanup(err, filepath) + return } + + t.ok(fs.statSync(`${filepath}.html`).isFile()) + + cleanup(null, filepath) + }) + }) +}) + +test('cmd - test collect - custom name and output destination', t => { + const tool = new ClinicHeapProfiler({ debug: true, name: 'test-custom-name', dest: 'test-output-destination' }) + + function cleanup (err, filepath) { + function callback (err) { + t.error(err) + t.end() } t.error(err) - t.match(filename, /^test-output-destination$/) + t.equal(filepath, 'test-output-destination/test-custom-name.clinic-heapprofiler') - fs.unlink(filename, callback) - fs.unlink(filename + '.html', callback) + fs.rm(path.dirname(filepath), { recursive: true }, callback) } - tool.collect([process.execPath, path.join('test', 'fixtures', 'randomHashes.js')], (err, filename) => { + tool.collect([process.execPath, path.join('test', 'fixtures', 'randomHashes.js')], (err, filepath) => { if (err) { - cleanup(err, filename) + cleanup(err, filepath) return } - t.ok(fs.statSync(filename).isFile()) + t.ok(fs.statSync(filepath).isFile()) - tool.visualize(filename, `${filename}.html`, err => { + tool.visualize(filepath, `${filepath}.html`, err => { if (err) { - cleanup(err, filename) + cleanup(err, filepath) return } - t.ok(fs.statSync(`${filename}.html`).isFile()) + t.ok(fs.statSync(`${filepath}.html`).isFile()) - cleanup(null, filename) + cleanup(null, filepath) }) }) })