| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent caa7ecc commit 52d5dd8
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,6 +6,7 @@ This directory contains modules used to test the Node.js implementation. | |||
| 6 | 6 | ||
| 7 | 7 | * [ArrayStream module](#arraystream-module) | |
| 8 | 8 | * [Benchmark module](#benchmark-module) | |
| 9 | + * [Child process module](#child-process-module) | ||
| 9 | 10 | * [Common module API](#common-module-api) | |
| 10 | 11 | * [Countdown module](#countdown-module) | |
| 11 | 12 | * [CPU Profiler module](#cpu-profiler-module) | |
@@ -35,6 +36,42 @@ The `benchmark` module is used by tests to run benchmarks. | |||
| 35 | 36 | * `env` [\<Object>][<Object>] Environment variables to be applied during the | |
| 36 | 37 | run. | |
| 37 | 38 | ||
| 39 | + ## Child Process Module | ||
| 40 | + | ||
| 41 | + The `child_process` module is used by tests that launch child processes. | ||
| 42 | + | ||
| 43 | + ### `expectSyncExit(child, options)` | ||
| 44 | + | ||
| 45 | + Checks if a _synchronous_ child process runs in the way expected. If it does | ||
| 46 | + not, print the stdout and stderr output from the child process and additional | ||
| 47 | + information about it to the stderr of the current process before throwing | ||
| 48 | + and error. This helps gathering more information about test failures | ||
| 49 | + coming from child processes. | ||
| 50 | + | ||
| 51 | + * `child` [\<ChildProcess>][<ChildProcess>]: a `ChildProcess` instance | ||
| 52 | + returned by `child_process.spawnSync()`. | ||
| 53 | + * `options` [\<Object>][<Object>] | ||
| 54 | + * `status` [\<number>][<number>] Expected `child.status` | ||
| 55 | + * `signal` [\<string>][<string>] | `null` Expected `child.signal` | ||
| 56 | + * `stderr` [\<string>][<string>] | [\<RegExp>][<RegExp>] | | ||
| 57 | + [\<Function>][<Function>] Optional. If it's a string, check that the output | ||
| 58 | + to the stderr of the child process is exactly the same as the string. If | ||
| 59 | + it's a regular expression, check that the stderr matches it. If it's a | ||
| 60 | + function, invoke it with the stderr output as a string and check | ||
| 61 | + that it returns true. The function can just throw errors (e.g. assertion | ||
| 62 | + errors) to provide more information if the check fails. | ||
| 63 | + * `stdout` [\<string>][<string>] | [\<RegExp>][<RegExp>] | | ||
| 64 | + [\<Function>][<Function>] Optional. Similar to `stderr` but for the stdout. | ||
| 65 | + * `trim` [\<boolean>][<boolean>] Optional. Whether this method should trim | ||
| 66 | + out the whitespace characters when checking `stderr` and `stdout` outputs. | ||
| 67 | + Defaults to `false`. | ||
| 68 | + | ||
| 69 | + ### `expectSyncExitWithoutError(child[, options])` | ||
| 70 | + | ||
| 71 | + Similar to `expectSyncExit()` with the `status` expected to be 0 and | ||
| 72 | + `signal` expected to be `null`. Any other optional options are passed | ||
| 73 | + into `expectSyncExit()`. | ||
| 74 | + | ||
| 38 | 75 | ## Common Module API | |
| 39 | 76 | ||
| 40 | 77 | The `common` module is used by tests for consistency across repeated | |
@@ -1086,6 +1123,7 @@ See [the WPT tests README][] for details. | |||
| 1086 | 1123 | [<ArrayBufferView>]: https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | |
| 1087 | 1124 | [<Buffer>]: https://nodejs.org/api/buffer.html#buffer_class_buffer | |
| 1088 | 1125 | [<BufferSource>]: https://developer.mozilla.org/en-US/docs/Web/API/BufferSource | |
| 1126 | + [<ChildProcess>]: ../../doc/api/child_process.md#class-childprocess | ||
| 1089 | 1127 | [<Error>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error | |
| 1090 | 1128 | [<Function>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function | |
| 1091 | 1129 | [<Object>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | 3 | const assert = require('assert'); | |
| 4 | 4 | const common = require('./'); | |
| 5 | + const util = require('util'); | ||
| 5 | 6 | ||
| 6 | 7 | // Workaround for Windows Server 2008R2 | |
| 7 | 8 | // When CMD is used to launch a process and CMD is killed too quickly, the | |
@@ -41,9 +42,88 @@ function logAfterTime(time) { | |||
| 41 | 42 | }, time); | |
| 42 | 43 | } | |
| 43 | 44 | ||
| 45 | + function checkOutput(str, check) { | ||
| 46 | + if ((check instanceof RegExp && !check.test(str)) || | ||
| 47 | + (typeof check === 'string' && check !== str)) { | ||
| 48 | + return { passed: false, reason: `did not match ${util.inspect(check)}` }; | ||
| 49 | + } | ||
| 50 | + if (typeof check === 'function') { | ||
| 51 | + try { | ||
| 52 | + check(str); | ||
| 53 | + } catch (error) { | ||
| 54 | + return { | ||
| 55 | + passed: false, | ||
| 56 | + reason: `did not match expectation, checker throws:\n${util.inspect(error)}`, | ||
| 57 | + }; | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | + return { passed: true }; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + function expectSyncExit(child, { | ||
| 64 | + status, | ||
| 65 | + signal, | ||
| 66 | + stderr: stderrCheck, | ||
| 67 | + stdout: stdoutCheck, | ||
| 68 | + trim = false, | ||
| 69 | + }) { | ||
| 70 | + const failures = []; | ||
| 71 | + let stderrStr, stdoutStr; | ||
| 72 | + if (status !== undefined && child.status !== status) { | ||
| 73 | + failures.push(`- process terminated with status ${child.status}, expected ${status}`); | ||
| 74 | + } | ||
| 75 | + if (signal !== undefined && child.signal !== signal) { | ||
| 76 | + failures.push(`- process terminated with signal ${child.signal}, expected ${signal}`); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + function logAndThrow() { | ||
| 80 | + const tag = `[process ${child.pid}]:`; | ||
| 81 | + console.error(`${tag} --- stderr ---`); | ||
| 82 | + console.error(stderrStr === undefined ? child.stderr.toString() : stderrStr); | ||
| 83 | + console.error(`${tag} --- stdout ---`); | ||
| 84 | + console.error(stdoutStr === undefined ? child.stdout.toString() : stdoutStr); | ||
| 85 | + console.error(`${tag} status = ${child.status}, signal = ${child.signal}`); | ||
| 86 | + throw new Error(`${failures.join('\n')}`); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + // If status and signal are not matching expectations, fail early. | ||
| 90 | + if (failures.length !== 0) { | ||
| 91 | + logAndThrow(); | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + if (stderrCheck !== undefined) { | ||
| 95 | + stderrStr = child.stderr.toString(); | ||
| 96 | + const { passed, reason } = checkOutput(trim ? stderrStr.trim() : stderrStr, stderrCheck); | ||
| 97 | + if (!passed) { | ||
| 98 | + failures.push(`- stderr ${reason}`); | ||
| 99 | + } | ||
| 100 | + } | ||
| 101 | + if (stdoutCheck !== undefined) { | ||
| 102 | + stdoutStr = child.stdout.toString(); | ||
| 103 | + const { passed, reason } = checkOutput(trim ? stdoutStr.trim() : stdoutStr, stdoutCheck); | ||
| 104 | + if (!passed) { | ||
| 105 | + failures.push(`- stdout ${reason}`); | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | + if (failures.length !== 0) { | ||
| 109 | + logAndThrow(); | ||
| 110 | + } | ||
| 111 | + return { child, stderr: stderrStr, stdout: stdoutStr }; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + function expectSyncExitWithoutError(child, options) { | ||
| 115 | + return expectSyncExit(child, { | ||
| 116 | + status: 0, | ||
| 117 | + signal: null, | ||
| 118 | + ...options, | ||
| 119 | + }); | ||
| 120 | + } | ||
| 121 | + | ||
| 44 | 122 | module.exports = { | |
| 45 | 123 | cleanupStaleProcess, | |
| 46 | 124 | logAfterTime, | |
| 47 | 125 | kExpiringChildRunTime, | |
| 48 | 126 | kExpiringParentTimer, | |
| 127 | + expectSyncExit, | ||
| 128 | + expectSyncExitWithoutError, | ||
| 49 | 129 | }; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments