Skip to content

Commit

Permalink
feat: validate concurrency option
Browse files Browse the repository at this point in the history
PR-URL: nodejs/node#43976
Reviewed-By: Darshan Sen <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
(cherry picked from commit 60da0a1b364efdd84870269d23b39faa12fb46d8)
  • Loading branch information
aduh95 committed Jul 27, 2022
1 parent 8c95f07 commit f875da2
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 14 deletions.
30 changes: 19 additions & 11 deletions lib/internal/test_runner/test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// https://github.com/nodejs/node/blob/dab492f0444b0a6ae8a41dd1d9605e036c363655/lib/internal/test_runner/test.js
// https://github.com/nodejs/node/blob/60da0a1b364efdd84870269d23b39faa12fb46d8/lib/internal/test_runner/test.js

'use strict'

Expand Down Expand Up @@ -36,9 +36,9 @@ const {
} = require('#internal/util')
const { isPromise } = require('#internal/util/types')
const {
isUint32,
validateAbortSignal,
validateNumber
validateNumber,
validateUint32
} = require('#internal/validators')
const { setTimeout } = require('#timers/promises')
const { TIMEOUT_MAX } = require('#internal/timers')
Expand Down Expand Up @@ -152,14 +152,22 @@ class Test extends AsyncResource {
this.timeout = parent.timeout
}

if (isUint32(concurrency) && concurrency !== 0) {
this.concurrency = concurrency
} else if (typeof concurrency === 'boolean') {
if (concurrency) {
this.concurrency = isTestRunner ? MathMax(cpus().length - 1, 1) : Infinity
} else {
this.concurrency = 1
}
switch (typeof concurrency) {
case 'number':
validateUint32(concurrency, 'options.concurrency', 1)
this.concurrency = concurrency
break

case 'boolean':
if (concurrency) {
this.concurrency = isTestRunner ? MathMax(cpus().length - 1, 1) : Infinity
} else {
this.concurrency = 1
}
break

default:
if (concurrency != null) throw new TypeError(`Expected options.concurrency to be a number or boolean, got ${concurrency}`)
}

if (timeout != null && timeout !== Infinity) {
Expand Down
20 changes: 18 additions & 2 deletions lib/internal/validators.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// https://github.com/nodejs/node/blob/d83446b4c4694322e12d2b7d22592f2be674e580/lib/internal/validators.js
// https://github.com/nodejs/node/blob/60da0a1b364efdd84870269d23b39faa12fb46d8/lib/internal/validators.js
function isUint32 (value) {
return value === (value >>> 0)
}
Expand All @@ -23,8 +23,24 @@ const validateAbortSignal = (signal, name) => {
}
}

const validateUint32 = (value, name, positive) => {
if (typeof value !== 'number') {
throw new TypeError(`Expected ${name} to be a number, got ${value}`)
}
if (!Number.isInteger(value)) {
throw new RangeError(`Expected ${name} to be an integer, got ${value}`)
}
const min = positive ? 1 : 0
// 2 ** 32 === 4294967296
const max = 4_294_967_295
if (value < min || value > max) {
throw new RangeError(`Expected ${name} to be ${`>= ${min} && <= ${max}`}, got ${value}`)
}
}

module.exports = {
isUint32,
validateAbortSignal,
validateNumber
validateNumber,
validateUint32
}
14 changes: 13 additions & 1 deletion test/parallel/test-runner-option-validation.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// https://github.com/nodejs/node/blob/d83446b4c4694322e12d2b7d22592f2be674e580/test/parallel/test-runner-option-validation.js
// https://github.com/nodejs/node/blob/60da0a1b364efdd84870269d23b39faa12fb46d8/test/parallel/test-runner-option-validation.js

'use strict'
require('../common')
Expand All @@ -15,4 +15,16 @@ const test = require('node:test');
[null, undefined, Infinity, 0, 1, 1.1].forEach((timeout) => {
// Valid values should not throw.
test({ timeout })
});

// eslint-disable-next-line symbol-description
[Symbol(), {}, [], () => {}, 1n, '1'].forEach((concurrency) => {
assert.throws(() => test({ concurrency }), { code: 'ERR_INVALID_ARG_TYPE' })
});
[-1, 0, 1.1, -Infinity, NaN, 2 ** 33, Number.MAX_SAFE_INTEGER].forEach((concurrency) => {
assert.throws(() => test({ concurrency }), { code: 'ERR_OUT_OF_RANGE' })
});
[null, undefined, 1, 2 ** 31, true, false].forEach((concurrency) => {
// Valid values should not throw.
test({ concurrency })
})

0 comments on commit f875da2

Please sign in to comment.