Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add stop delay arg #331

Merged
merged 4 commits into from
Feb 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [12.13.0, 12.x, 14.x, 16.x, 17.x]
node-version: [12.x, 14.x, 16.x, 17.x]

runs-on: ${{matrix.os}}
steps:
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ To avoid that behavior you can either quote ("--", '--') or escape (`--`) the do
## Supported Node.js versions

Clinic.js relies heavily on Node.js core instrumentation available in later versions.
Currently the supported Node.js versions are `>= 12.13.0`.
Currently the supported Node.js versions are `>= 12.22.7`.

## Examples and Demos

Expand Down Expand Up @@ -123,6 +123,7 @@ clinic heapprofiler --help
--on-port Run a script when the server starts listening on a port.
--autocannon Run the autocannon benchmarking tool when the server starts listening on a port.
--dest Destination for the collect data (default .).
--stop-delay Add a delay to close the process when a job is done through either `autocannon` or `on-port` flag (milliseconds)
```

## Programmable Interfaces
Expand Down
25 changes: 20 additions & 5 deletions bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ const result = commist()
'visualize-only',
'sample-interval',
'on-port',
'dest'
'dest',
'stop-delay'
],
default: {
'sample-interval': '10',
Expand Down Expand Up @@ -117,7 +118,8 @@ const result = commist()
],
string: [
'visualize-only',
'dest'
'dest',
'stop-delay'
],
default: {
open: true,
Expand Down Expand Up @@ -158,7 +160,8 @@ const result = commist()
],
string: [
'visualize-only',
'dest'
'dest',
'stop-delay'
],
default: {
open: true,
Expand Down Expand Up @@ -198,7 +201,8 @@ const result = commist()
],
string: [
'visualize-only',
'dest'
'dest',
'stop-delay'
],
default: {
open: true,
Expand Down Expand Up @@ -322,6 +326,8 @@ async function runTool (toolName, Tool, version, args, uiOptions) {
kernelTracing: args['kernel-tracing']
})

const stopDelayMs = parseInt(args['stop-delay'])

const spinner = ora({
text: 'Analysing data',
color: uiOptions.color,
Expand All @@ -337,7 +343,16 @@ async function runTool (toolName, Tool, version, args, uiOptions) {
tool.on('port', function (port, proc, cb) {
process.env.PORT = port
// inline the PORT env to make it easier for cross platform usage
execspawn(envString(onPort, { PORT: port }), { stdio: 'inherit' }).on('exit', cb)
execspawn(envString(onPort, { PORT: port }), { stdio: 'inherit' })
.on('exit', () => {
if (stopDelayMs) {
tool.emit('status', 'Waiting to close the process')
if (spinner.isEnabled && !spinner.isSpinning) spinner.start()
setTimeout(() => cb(), stopDelayMs)
} else {
cb()
}
})
})

tool.on('analysing', function (message = 'Analysing data') {
Expand Down
1 change: 1 addition & 0 deletions docs/clinic-bubbleprof.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@
--autocannon Run the autocannon benchmarking tool when the server starts listening on a port.
--open Boolean to enable or disable your report opening in your web browser.
--dest Destination for the collected data (default <code>.clinic/</code>).
--stop-delay Add a delay to close the process when a job is done through either `autocannon` or `on-port` flag (milliseconds)
1 change: 1 addition & 0 deletions docs/clinic-doctor.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@
--autocannon Run the autocannon benchmarking tool when the server starts listening on a port.
--open Boolean to enable or disable your report opening in your web browser.
--dest Destination for the collected data (default <code>.clinic/</code>).
--stop-delay Add a delay to close the process when a job is done through either `autocannon` or `on-port` flag (milliseconds)
1 change: 1 addition & 0 deletions docs/clinic-flame.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@
--open Boolean to enable or disable your report opening in your web browser.
--dest Destination for the collected data (default <code>.clinic/</code>).
--kernel-tracing Profile application using linux_perf (linux only).
--stop-delay Add a delay to close the process when a job is done through either `autocannon` or `on-port` flag (milliseconds)
1 change: 1 addition & 0 deletions docs/clinic-heap-profiler.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@
--autocannon Run the autocannon benchmarking tool when the server starts listening on a port.
--open Boolean to enable or disable your report opening in your web browser.
--dest Destination for the collected data (default <code>.clinic/</code>).
--stop-delay Add a delay to close the process when a job is done through either `autocannon` or `on-port` flag (milliseconds)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"repository": "clinicjs/node-clinic",
"version": "11.0.0",
"engines": {
"node": ">= 12.13.0"
"node": ">= 12.22.7"
},
"bin": {
"clinic": "bin.js"
Expand Down
40 changes: 40 additions & 0 deletions test/cli-bubbleprof-stop-delay.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict'

const fs = require('fs')
const url = require('url')
const async = require('async')
const path = require('path')
const test = require('tap').test
const cli = require('./cli.js')

test('clinic bubbleprof --stop-delay --on-port - no issues', function (t) {
cli({}, [
'clinic', 'bubbleprof', '--no-open', '--stop-delay', '500', '--on-port', 'node -e "setTimeout(() => {}, 0)"',
'--', 'node', '-e', `
const http = require('http')

http.createServer((req, res) => res.end('ok')).listen(0)
`
], function (err, stdout, stderr, tempdir) {
t.error(err)

const dirname = stdout.match(/(\.clinic[/\\]\d+.clinic-bubbleprof)/)[1]
const fullpath = url.pathToFileURL(fs.realpathSync(path.resolve(tempdir, dirname)))
t.equal(stdout.split('\n')[0], 'Waiting to close the process')
t.equal(stdout.split('\n')[1], 'Analysing data')
t.equal(stdout.split('\n')[2], `Generated HTML file is ${fullpath}.html`)

// check that files exists
async.parallel({
sourceData (done) {
fs.access(path.resolve(tempdir, dirname), done)
},
htmlFile (done) {
fs.access(path.resolve(tempdir, dirname + '.html'), done)
}
}, function (err) {
t.error(err)
t.end()
})
})
})
59 changes: 59 additions & 0 deletions test/cli-doctor-stop-delay.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use strict'

const fs = require('fs')
const url = require('url')
const async = require('async')
const path = require('path')
const test = require('tap').test
const cli = require('./cli.js')

test('clinic doctor --stop-delay --on-port - no issues', function (t) {
cli({}, [
'clinic', 'doctor', '--no-open', '--stop-delay', '500', '--on-port', 'node -e "setTimeout(() => {}, 0)"',
'--', 'node', '-e', `
const http = require('http')

http.createServer((req, res) => res.end('ok')).listen(0)
`
], function (err, stdout, stderr, tempdir) {
t.error(err)

const dirname = stdout.match(/(\.clinic[/\\]\d+.clinic-doctor)/)[1]
const fullpath = url.pathToFileURL(fs.realpathSync(path.resolve(tempdir, dirname)))
t.equal(stdout.split('\n')[0], 'Waiting to close the process')
t.equal(stdout.split('\n')[1], 'Analysing data')
t.equal(stdout.split('\n')[2], `Generated HTML file is ${fullpath}.html`)

// check that files exists
async.parallel({
sourceData (done) {
fs.access(path.resolve(tempdir, dirname), done)
},
htmlFile (done) {
fs.access(path.resolve(tempdir, dirname + '.html'), done)
}
}, function (err) {
t.error(err)
t.end()
})
})
})

test('clinic doctor --stop-delay --on-port - exceeding timeout', function (t) {
const onPortDuration = 500
setTimeout(() => {
t.pass('timeout should be called before t.fail')
t.end()
process.exit(0)
}, onPortDuration + 500)
cli({}, [
'clinic', 'doctor', '--no-open', '--stop-delay', '2000', '--on-port', `node -e "setTimeout(() => {}, ${onPortDuration})"`,
'--', 'node', '-e', `
const http = require('http')

http.createServer((req, res) => res.end('ok')).listen(0)
`
], function () {
t.fail('it should not be called once timeout is reached')
})
})
40 changes: 40 additions & 0 deletions test/cli-flame-stop-delay.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict'

const fs = require('fs')
const url = require('url')
const async = require('async')
const path = require('path')
const test = require('tap').test
const cli = require('./cli.js')

test('clinic flame --stop-delay --on-port - no issues', function (t) {
cli({}, [
'clinic', 'flame', '--no-open', '--stop-delay', '500', '--on-port', 'node -e "setTimeout(() => {}, 0)"',
'--', 'node', '-e', `
const http = require('http')

http.createServer((req, res) => res.end('ok')).listen(0)
`
], function (err, stdout, stderr, tempdir) {
t.error(err)

const dirname = stdout.match(/(\.clinic[/\\]\d+.clinic-flame)/)[1]
const fullpath = url.pathToFileURL(fs.realpathSync(path.resolve(tempdir, dirname)))
t.equal(stdout.split('\n')[0], 'Waiting to close the process')
t.equal(stdout.split('\n')[1], 'Analysing data')
t.equal(stdout.split('\n')[2], `Generated HTML file is ${fullpath}.html`)

// check that files exists
async.parallel({
sourceData (done) {
fs.access(path.resolve(tempdir, dirname), done)
},
htmlFile (done) {
fs.access(path.resolve(tempdir, dirname + '.html'), done)
}
}, function (err) {
t.error(err)
t.end()
})
})
})
40 changes: 40 additions & 0 deletions test/cli-heapprofiler-stop-delay.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict'

const fs = require('fs')
const url = require('url')
const async = require('async')
const path = require('path')
const test = require('tap').test
const cli = require('./cli.js')

test('clinic heapprofiler --stop-delay --on-port - no issues', function (t) {
cli({}, [
'clinic', 'heapprofiler', '--no-open', '--stop-delay', '500', '--on-port', 'node -e "setTimeout(() => {}, 0)"',
'--', 'node', '-e', `
const http = require('http')

http.createServer((req, res) => res.end('ok')).listen(0)
`
], function (err, stdout, stderr, tempdir) {
t.error(err)

const dirname = stdout.match(/(\.clinic[/\\]\d+.clinic-heapprofile)/)[1]
const fullpath = url.pathToFileURL(fs.realpathSync(path.resolve(tempdir, dirname)))
t.equal(stdout.split('\n')[0], 'Waiting to close the process')
t.equal(stdout.split('\n')[1], 'Analysing data')
t.equal(stdout.split('\n')[2], `Generated HTML file is ${fullpath}.html`)

// check that files exists
async.parallel({
sourceData (done) {
fs.access(path.resolve(tempdir, dirname), done)
},
htmlFile (done) {
fs.access(path.resolve(tempdir, dirname + '.html'), done)
}
}, function (err) {
t.error(err)
t.end()
})
})
})