mirror of https://github.com/lukechilds/node.git
Browse Source
Split up test-domain into multiple, more focused test files and use more modern JS inside of them. PR-URL: https://github.com/nodejs/node/pull/13614 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>v9.x-staging
Anna Henningsen
8 years ago
12 changed files with 263 additions and 275 deletions
@ -0,0 +1,17 @@ |
|||
'use strict'; |
|||
|
|||
const common = require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
|
|||
const d = new domain.Domain(); |
|||
|
|||
d.on('error', common.mustCall((err) => { |
|||
assert.strictEqual(err.message, 'foobar'); |
|||
assert.strictEqual(err.domain, d); |
|||
assert.strictEqual(err.domainEmitter, undefined); |
|||
assert.strictEqual(err.domainBound, undefined); |
|||
assert.strictEqual(err.domainThrown, true); |
|||
})); |
|||
|
|||
setTimeout(d.bind(() => { throw new Error('foobar'); }), 1); |
@ -0,0 +1,28 @@ |
|||
'use strict'; |
|||
|
|||
const common = require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
const EventEmitter = require('events'); |
|||
|
|||
const d = new domain.Domain(); |
|||
let implicit; |
|||
|
|||
d.on('error', common.mustCall((err) => { |
|||
assert.strictEqual(err.message, 'foobar'); |
|||
assert.strictEqual(err.domain, d); |
|||
assert.strictEqual(err.domainEmitter, implicit); |
|||
assert.strictEqual(err.domainBound, undefined); |
|||
assert.strictEqual(err.domainThrown, false); |
|||
})); |
|||
|
|||
// Implicit addition of the EventEmitter by being created within a domain-bound
|
|||
// context.
|
|||
d.run(common.mustCall(() => { |
|||
implicit = new EventEmitter(); |
|||
})); |
|||
|
|||
setTimeout(common.mustCall(() => { |
|||
// escape from the domain, but implicit is still bound to it.
|
|||
implicit.emit('error', new Error('foobar')); |
|||
}), 1); |
@ -0,0 +1,20 @@ |
|||
'use strict'; |
|||
|
|||
const common = require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
const EventEmitter = require('events'); |
|||
|
|||
const d = new domain.Domain(); |
|||
const e = new EventEmitter(); |
|||
|
|||
d.on('error', common.mustCall((err) => { |
|||
assert.strictEqual(err.message, 'foobar'); |
|||
assert.strictEqual(err.domain, d); |
|||
assert.strictEqual(err.domainEmitter, e); |
|||
assert.strictEqual(err.domainBound, undefined); |
|||
assert.strictEqual(err.domainThrown, false); |
|||
})); |
|||
|
|||
d.add(e); |
|||
e.emit('error', new Error('foobar')); |
@ -0,0 +1,23 @@ |
|||
'use strict'; |
|||
|
|||
const common = require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
|
|||
// This test is similar to test-domain-multiple-errors, but uses a new domain
|
|||
// for each errors.
|
|||
|
|||
for (const something of [ |
|||
42, null, undefined, false, () => {}, 'string', Symbol('foo') |
|||
]) { |
|||
const d = new domain.Domain(); |
|||
d.run(common.mustCall(() => { |
|||
process.nextTick(common.mustCall(() => { |
|||
throw something; |
|||
})); |
|||
})); |
|||
|
|||
d.on('error', common.mustCall((err) => { |
|||
assert.strictEqual(something, err); |
|||
})); |
|||
} |
@ -0,0 +1,20 @@ |
|||
'use strict'; |
|||
|
|||
const common = require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
const fs = require('fs'); |
|||
|
|||
const d = new domain.Domain(); |
|||
|
|||
const fst = fs.createReadStream('stream for nonexistent file'); |
|||
|
|||
d.on('error', common.mustCall((err) => { |
|||
assert.ok(err.message.match(/^ENOENT: no such file or directory, open '/)); |
|||
assert.strictEqual(err.domain, d); |
|||
assert.strictEqual(err.domainEmitter, fst); |
|||
assert.strictEqual(err.domainBound, undefined); |
|||
assert.strictEqual(err.domainThrown, false); |
|||
})); |
|||
|
|||
d.add(fst); |
@ -0,0 +1,31 @@ |
|||
'use strict'; |
|||
|
|||
const common = require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
const fs = require('fs'); |
|||
|
|||
{ |
|||
const d = new domain.Domain(); |
|||
|
|||
d.on('error', common.mustCall((err) => { |
|||
assert.strictEqual(err.message, 'foobar'); |
|||
assert.strictEqual(err.domain, d); |
|||
assert.strictEqual(err.domainEmitter, undefined); |
|||
assert.strictEqual(err.domainBound, undefined); |
|||
assert.strictEqual(err.domainThrown, true); |
|||
})); |
|||
|
|||
d.run(common.mustCall(() => { |
|||
process.nextTick(common.mustCall(() => { |
|||
const i = setInterval(common.mustCall(() => { |
|||
clearInterval(i); |
|||
setTimeout(common.mustCall(() => { |
|||
fs.stat('this file does not exist', common.mustCall((er, stat) => { |
|||
throw new Error('foobar'); |
|||
})); |
|||
}), 1); |
|||
}), 1); |
|||
})); |
|||
})); |
|||
} |
@ -0,0 +1,43 @@ |
|||
'use strict'; |
|||
|
|||
const common = require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
|
|||
{ |
|||
const d = new domain.Domain(); |
|||
|
|||
const mustNotCall = common.mustNotCall(); |
|||
|
|||
d.on('error', common.mustCall((err) => { |
|||
assert.strictEqual(err.message, 'foobar'); |
|||
assert.strictEqual(err.domain, d); |
|||
assert.strictEqual(err.domainEmitter, undefined); |
|||
assert.strictEqual(err.domainBound, mustNotCall); |
|||
assert.strictEqual(err.domainThrown, false); |
|||
})); |
|||
|
|||
const bound = d.intercept(mustNotCall); |
|||
bound(new Error('foobar')); |
|||
} |
|||
|
|||
{ |
|||
const d = new domain.Domain(); |
|||
|
|||
const bound = d.intercept(common.mustCall((data) => { |
|||
assert.strictEqual(data, 'data'); |
|||
})); |
|||
|
|||
bound(null, 'data'); |
|||
} |
|||
|
|||
{ |
|||
const d = new domain.Domain(); |
|||
|
|||
const bound = d.intercept(common.mustCall((data, data2) => { |
|||
assert.strictEqual(data, 'data'); |
|||
assert.strictEqual(data2, 'data2'); |
|||
})); |
|||
|
|||
bound(null, 'data', 'data2'); |
|||
} |
@ -0,0 +1,26 @@ |
|||
'use strict'; |
|||
|
|||
const common = require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
|
|||
// This test is similar to test-domain-error-types, but uses a single domain
|
|||
// to emit all errors.
|
|||
|
|||
const d = new domain.Domain(); |
|||
|
|||
const values = [ |
|||
42, null, undefined, false, () => {}, 'string', Symbol('foo') |
|||
]; |
|||
|
|||
d.on('error', common.mustCall((err) => { |
|||
assert(values.includes(err)); |
|||
}, values.length)); |
|||
|
|||
for (const something of values) { |
|||
d.run(common.mustCall(() => { |
|||
process.nextTick(common.mustCall(() => { |
|||
throw something; |
|||
})); |
|||
})); |
|||
} |
@ -0,0 +1,21 @@ |
|||
'use strict'; |
|||
|
|||
const common = require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
|
|||
const d = new domain.Domain(); |
|||
|
|||
d.on('error', common.mustCall((err) => { |
|||
assert.strictEqual(err.message, 'foobar'); |
|||
assert.strictEqual(err.domain, d); |
|||
assert.strictEqual(err.domainEmitter, undefined); |
|||
assert.strictEqual(err.domainBound, undefined); |
|||
assert.strictEqual(err.domainThrown, true); |
|||
})); |
|||
|
|||
d.run(common.mustCall(() => { |
|||
process.nextTick(common.mustCall(() => { |
|||
throw new Error('foobar'); |
|||
})); |
|||
})); |
@ -0,0 +1,13 @@ |
|||
'use strict'; |
|||
|
|||
require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
|
|||
const d = new domain.Domain(); |
|||
|
|||
assert.strictEqual(d.run(() => 'return value'), |
|||
'return value'); |
|||
|
|||
assert.strictEqual(d.run((a, b) => `${a} ${b}`, 'return', 'value'), |
|||
'return value'); |
@ -0,0 +1,21 @@ |
|||
'use strict'; |
|||
|
|||
const common = require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
|
|||
const d = new domain.Domain(); |
|||
|
|||
d.on('error', common.mustCall((err) => { |
|||
assert.strictEqual(err.message, 'foobar'); |
|||
assert.strictEqual(err.domain, d); |
|||
assert.strictEqual(err.domainEmitter, undefined); |
|||
assert.strictEqual(err.domainBound, undefined); |
|||
assert.strictEqual(err.domainThrown, true); |
|||
})); |
|||
|
|||
d.run(common.mustCall(() => { |
|||
setTimeout(common.mustCall(() => { |
|||
throw new Error('foobar'); |
|||
}), 1); |
|||
})); |
@ -1,275 +0,0 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
'use strict'; |
|||
// Simple tests of most basic domain functionality.
|
|||
|
|||
require('../common'); |
|||
const assert = require('assert'); |
|||
const domain = require('domain'); |
|||
const events = require('events'); |
|||
const fs = require('fs'); |
|||
let caught = 0; |
|||
let expectCaught = 0; |
|||
|
|||
const d = new domain.Domain(); |
|||
const e = new events.EventEmitter(); |
|||
|
|||
d.on('error', function(er) { |
|||
console.error('caught', er && (er.message || er)); |
|||
|
|||
let er_message = er.message; |
|||
let er_path = er.path; |
|||
|
|||
// On windows, error messages can contain full path names. If this is the
|
|||
// case, remove the directory part.
|
|||
if (typeof er_path === 'string') { |
|||
const slash = er_path.lastIndexOf('\\'); |
|||
if (slash !== -1) { |
|||
const dir = er_path.slice(0, slash + 1); |
|||
er_path = er_path.replace(dir, ''); |
|||
er_message = er_message.replace(dir, ''); |
|||
} |
|||
} |
|||
|
|||
switch (er_message) { |
|||
case 'emitted': |
|||
assert.strictEqual(er.domain, d); |
|||
assert.strictEqual(er.domainEmitter, e); |
|||
assert.strictEqual(er.domainThrown, false); |
|||
break; |
|||
|
|||
case 'bound': |
|||
assert.ok(!er.domainEmitter); |
|||
assert.strictEqual(er.domain, d); |
|||
assert.strictEqual(er.domainBound, fn); |
|||
assert.strictEqual(er.domainThrown, false); |
|||
break; |
|||
|
|||
case 'thrown': |
|||
assert.ok(!er.domainEmitter); |
|||
assert.strictEqual(er.domain, d); |
|||
assert.strictEqual(er.domainThrown, true); |
|||
break; |
|||
|
|||
case "ENOENT: no such file or directory, open 'this file does not exist'": |
|||
assert.strictEqual(er.domain, d); |
|||
assert.strictEqual(er.domainThrown, false); |
|||
assert.strictEqual(typeof er.domainBound, 'function'); |
|||
assert.ok(!er.domainEmitter); |
|||
assert.strictEqual(er.code, 'ENOENT'); |
|||
assert.strictEqual(er_path, 'this file does not exist'); |
|||
assert.strictEqual(typeof er.errno, 'number'); |
|||
break; |
|||
|
|||
case |
|||
"ENOENT: no such file or directory, open 'stream for nonexistent file'": |
|||
assert.strictEqual(typeof er.errno, 'number'); |
|||
assert.strictEqual(er.code, 'ENOENT'); |
|||
assert.strictEqual(er_path, 'stream for nonexistent file'); |
|||
assert.strictEqual(er.domain, d); |
|||
assert.strictEqual(er.domainEmitter, fst); |
|||
assert.ok(!er.domainBound); |
|||
assert.strictEqual(er.domainThrown, false); |
|||
break; |
|||
|
|||
case 'implicit': |
|||
assert.strictEqual(er.domainEmitter, implicit); |
|||
assert.strictEqual(er.domain, d); |
|||
assert.strictEqual(er.domainThrown, false); |
|||
assert.ok(!er.domainBound); |
|||
break; |
|||
|
|||
case 'implicit timer': |
|||
assert.strictEqual(er.domain, d); |
|||
assert.strictEqual(er.domainThrown, true); |
|||
assert.ok(!er.domainEmitter); |
|||
assert.ok(!er.domainBound); |
|||
break; |
|||
|
|||
case 'Cannot read property \'isDirectory\' of undefined': |
|||
assert.strictEqual(er.domain, d); |
|||
assert.ok(!er.domainEmitter); |
|||
assert.ok(!er.domainBound); |
|||
break; |
|||
|
|||
case 'nextTick execution loop': |
|||
assert.strictEqual(er.domain, d); |
|||
assert.ok(!er.domainEmitter); |
|||
assert.ok(!er.domainBound); |
|||
break; |
|||
|
|||
default: |
|||
console.error('unexpected error, throwing %j', er.message, er); |
|||
throw er; |
|||
} |
|||
|
|||
caught++; |
|||
}); |
|||
|
|||
|
|||
process.on('exit', function() { |
|||
console.error('exit', caught, expectCaught); |
|||
assert.strictEqual(caught, expectCaught, |
|||
'caught the expected number of errors'); |
|||
console.log('ok'); |
|||
}); |
|||
|
|||
|
|||
// revert to using the domain when a callback is passed to nextTick in
|
|||
// the middle of a tickCallback loop
|
|||
d.run(function() { |
|||
process.nextTick(function() { |
|||
throw new Error('nextTick execution loop'); |
|||
}); |
|||
}); |
|||
expectCaught++; |
|||
|
|||
|
|||
// catch thrown errors no matter how many times we enter the event loop
|
|||
// this only uses implicit binding, except for the first function
|
|||
// passed to d.run(). The rest are implicitly bound by virtue of being
|
|||
// set up while in the scope of the d domain.
|
|||
d.run(function() { |
|||
process.nextTick(function() { |
|||
const i = setInterval(function() { |
|||
clearInterval(i); |
|||
setTimeout(function() { |
|||
fs.stat('this file does not exist', function(er, stat) { |
|||
// uh oh! stat isn't set!
|
|||
// pretty common error.
|
|||
console.log(stat.isDirectory()); |
|||
}); |
|||
}, 1); |
|||
}, 1); |
|||
}); |
|||
}); |
|||
expectCaught++; |
|||
|
|||
|
|||
// implicit addition of a timer created within a domain-bound context.
|
|||
d.run(function() { |
|||
setTimeout(function() { |
|||
throw new Error('implicit timer'); |
|||
}, 1); |
|||
}); |
|||
expectCaught++; |
|||
|
|||
|
|||
// Event emitters added to the domain have their errors routed.
|
|||
d.add(e); |
|||
e.emit('error', new Error('emitted')); |
|||
expectCaught++; |
|||
|
|||
|
|||
// get rid of the `if (er) return cb(er)` malarky, by intercepting
|
|||
// the cb functions to the domain, and using the intercepted function
|
|||
// as a callback instead.
|
|||
function fn() { |
|||
throw new Error('This function should never be called!'); |
|||
} |
|||
|
|||
let bound = d.intercept(fn); |
|||
bound(new Error('bound')); |
|||
expectCaught++; |
|||
|
|||
|
|||
// intercepted should never pass first argument to callback
|
|||
function fn2(data) { |
|||
assert.strictEqual(data, 'data', 'should not be null err argument'); |
|||
} |
|||
|
|||
bound = d.intercept(fn2); |
|||
bound(null, 'data'); |
|||
|
|||
// intercepted should never pass first argument to callback
|
|||
// even if arguments length is more than 2.
|
|||
function fn3(data, data2) { |
|||
assert.strictEqual(data, 'data', 'should not be null err argument'); |
|||
assert.strictEqual(data2, 'data2', 'should not be data argument'); |
|||
} |
|||
|
|||
bound = d.intercept(fn3); |
|||
bound(null, 'data', 'data2'); |
|||
|
|||
// throwing in a bound fn is also caught,
|
|||
// even if it's asynchronous, by hitting the
|
|||
// global uncaughtException handler. This doesn't
|
|||
// require interception, since throws are always
|
|||
// caught by the domain.
|
|||
function thrower() { |
|||
throw new Error('thrown'); |
|||
} |
|||
setTimeout(d.bind(thrower), 100); |
|||
expectCaught++; |
|||
|
|||
|
|||
// Pass an intercepted function to an fs operation that fails.
|
|||
fs.open('this file does not exist', 'r', d.intercept(function(er) { |
|||
console.error('should not get here!', er); |
|||
throw new Error('should not get here!'); |
|||
}, true)); |
|||
expectCaught++; |
|||
|
|||
|
|||
// implicit addition by being created within a domain-bound context.
|
|||
let implicit; |
|||
|
|||
d.run(function() { |
|||
implicit = new events.EventEmitter(); |
|||
}); |
|||
|
|||
setTimeout(function() { |
|||
// escape from the domain, but implicit is still bound to it.
|
|||
implicit.emit('error', new Error('implicit')); |
|||
}, 10); |
|||
expectCaught++; |
|||
|
|||
|
|||
let result = d.run(function() { |
|||
return 'return value'; |
|||
}); |
|||
assert.strictEqual(result, 'return value'); |
|||
|
|||
|
|||
// check if the executed function take in count the applied parameters
|
|||
result = d.run((a, b) => `${a} ${b}`, 'return', 'value'); |
|||
assert.strictEqual(result, 'return value'); |
|||
|
|||
|
|||
const fst = fs.createReadStream('stream for nonexistent file'); |
|||
d.add(fst); |
|||
expectCaught++; |
|||
|
|||
[42, null, undefined, false, () => {}, 'string'].forEach(function(something) { |
|||
const d = new domain.Domain(); |
|||
d.run(function() { |
|||
process.nextTick(function() { |
|||
throw something; |
|||
}); |
|||
expectCaught++; |
|||
}); |
|||
|
|||
d.on('error', function(er) { |
|||
assert.strictEqual(something, er); |
|||
caught++; |
|||
}); |
|||
}); |
Loading…
Reference in new issue