Skip to content

Commit

Permalink
Assume that SIGTERM = timeout, surface to user
Browse files Browse the repository at this point in the history
Fixes #233, provided that we can assume that SIGTERM always indicates a
timeout from the calling process.
  • Loading branch information
isaacs committed Feb 11, 2016
1 parent 3951c45 commit bf0b2b3
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 28 deletions.
22 changes: 13 additions & 9 deletions lib/root.js
Expand Up @@ -64,20 +64,25 @@ onExit(function (code, signal) {
h !== process.stderr
})
var requests = process._getActiveRequests()
var msg = 'received SIGTERM with pending event queue activity'

// Ignore this because it's really hard to test cover in a way
// that isn't inconsistent and unpredictable.
/* istanbul ignore next */
tap.fail(msg, {
requests: requests.map(function (r) {
var extra = {
at: null,
signal: signal
}
if (requests.length) {
extra.requests = requests.map(function (r) {
var ret = { type: r.constructor.name }
if (r.context) {
ret.context = r.context
}
return ret
}),
handles: handles.map(function (h) {
})
}
if (handles.length) {
extra.handles = handles.map(function (h) {
var ret = { type: h.constructor.name }
if (h.msecs) {
ret.msecs = h.msecs
Expand All @@ -92,9 +97,8 @@ onExit(function (code, signal) {
ret.connectionKey = h._connectionKey
}
return ret
}),
at: null
})
})
}

tap.end()
tap._onTimeout(extra)
})
18 changes: 11 additions & 7 deletions lib/test.js
Expand Up @@ -150,20 +150,24 @@ Test.prototype.setTimeout = function (n) {
}, n)
}

Test.prototype._onTimeout = function () {
Test.prototype._onTimeout = function (extra) {
// anything that was pending will have to wait.
var s = this
while (s._currentChild && (s._currentChild instanceof Test)) {
s._queue = []
s.end(IMPLICIT)
s = s._currentChild
}

// anything that was pending will have to wait.
s.fail('timeout!', {
expired: this._name,
timeout: this._timeout,
at: this._calledAt
})
extra = extra || {}
if (this._parent) {
extra.expired = this._name
}
if (this._timeout) {
extra.timeout = this._timeout
}
extra.at = this._calledAt
s.fail('timeout!', extra)
s.end(IMPLICIT)

this.endAll()
Expand Down
2 changes: 1 addition & 1 deletion test/runner.js
Expand Up @@ -491,7 +491,7 @@ t.test('-t or --timeout to set timeout', function (t) {
t.equal(signal, null)
t.match(
out,
/received SIGTERM with pending event queue activity/,
/signal: SIGTERM/,
{ skip: skip }
)
t.end()
Expand Down
8 changes: 4 additions & 4 deletions test/test/pending-handles-bail.tap
@@ -1,10 +1,10 @@
TAP version 13
# Subtest: ___/.*/~~~pending-handles.js child
ok 1 - this is ok
not ok 2 - received SIGTERM with pending event queue activity
not ok 2 - timeout!
---
{"handles":[{"msecs":100000,"type":"Timer"}],"requests":[]}
{"handles":[{"msecs":100000,"type":"Timer"}],"signal":"SIGTERM"}
...
Bail out! # received SIGTERM with pending event queue activity
Bail out! # received SIGTERM with pending event queue activity
Bail out! # timeout!
Bail out! # timeout!

4 changes: 2 additions & 2 deletions test/test/pending-handles.tap
@@ -1,9 +1,9 @@
TAP version 13
# Subtest: ___/.*/~~~pending-handles.js child
ok 1 - this is ok
not ok 2 - received SIGTERM with pending event queue activity
not ok 2 - timeout!
---
{"handles":[{"msecs":100000,"type":"Timer"}],"requests":[]}
{"handles":[{"msecs":100000,"type":"Timer"}],"signal":"SIGTERM"}
...
1..2
# failed 1 of 2 tests
Expand Down
12 changes: 12 additions & 0 deletions test/test/timeout-via-runner-bail.tap
@@ -0,0 +1,12 @@
TAP version 13
# Subtest: child
# Subtest: child test
1..2
ok 1 - this is fine
not ok 2 - timeout!
---
{"handles":[{"msecs":20000,"type":"Timer"}],"signal":"SIGTERM"}
...
Bail out! # timeout!
Bail out! # timeout!

13 changes: 13 additions & 0 deletions test/test/timeout-via-runner.js
@@ -0,0 +1,13 @@
var t = require('../..')

if (process.argv[2] === 'child') {
t.test('child test', function (t) {
t.plan(2)
t.pass('this is fine')
setTimeout(function (res) {
t.pass('request complete')
}, 20000)
})
} else {
t.spawn(process.execPath, [__filename, 'child'], {}, 'child', { timeout: 1000 })
}
27 changes: 27 additions & 0 deletions test/test/timeout-via-runner.tap
@@ -0,0 +1,27 @@
TAP version 13
# Subtest: child
# Subtest: child test
1..2
ok 1 - this is fine
not ok 2 - timeout!
---
{"handles":[{"msecs":20000,"type":"Timer"}],"signal":"SIGTERM"}
...
# failed 1 of 2 tests
not ok 1 - child test ___/# time=[0-9.]+(ms)?/~~~
---
{"at":{"column":5,"file":"test/test/timeout-via-runner.js","line":4},"results":{"count":2,"fail":1,"ok":false,"pass":1,"plan":{"end":2,"start":1}},"source":"t.test('child test', function (t) {\n"}
...

1..1
# failed 1 of 1 tests
___/# time=[0-9.]+(ms)?/~~~
not ok 1 - child ___/# time=[0-9.]+(ms)?/~~~
---
{"arguments":["___/.*/~~~timeout-via-runner.js","child"],"at":{"column":5,"file":"test/test/timeout-via-runner.js","line":12},"command":"___/.*(node|iojs)(.exe)?/~~~","failure":"timeout","results":{"count":1,"fail":1,"ok":false,"pass":0,"plan":{"end":1,"start":1}},"signal":"SIGTERM","source":"t.spawn(process.execPath, [__filename, 'child'], {}, 'child', { timeout: 1000 })\n","timeout":1000}
...

1..1
# failed 1 of 1 tests
___/# time=[0-9.]+(ms)?/~~~

9 changes: 4 additions & 5 deletions test/timeout.js
Expand Up @@ -40,7 +40,7 @@ tap.test('t.setTimeout()', function (t) {
tt.setTimeout('not a number')
}, {}, { message: 'setTimeout: number > 0 required' })

var tt = new Test({ timeout: 1000 })
var tt = new Test({ timeout: 1000, bail: false })
tt.setTimeout(2000)
tt.setTimeout(Infinity)
t.notOk(tt._timeout)
Expand All @@ -51,15 +51,14 @@ tap.test('t.setTimeout()', function (t) {
' ok 1 - this is fine\n' +
' not ok 2 - timeout!\n' +
' ---\n' +
'( expired: some name\n|' +
' timeout: 1\n){2}' +
' timeout: 1\n' +
' \\.\\.\\.\n' +
' 1..2\n' +
' # failed 1 of 2 tests\n' +
'not ok 1 - child test # time=')

tt = new Test({ name: 'some name' })
tt.test('child test', function (tt) {
tt = new Test({ name: 'some name', bail: false })
tt.test('child test', { bail: false }, function (tt) {
tt.pass('this is fine')
})
tt.setTimeout(1)
Expand Down

0 comments on commit bf0b2b3

Please sign in to comment.