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

test: add few stream utils to common #31968

Closed
Closed
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
9 changes: 2 additions & 7 deletions test/addons/openssl-client-cert-engine/test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
const common = require('../../common');
const { collectStream } = require('../../common/streams');
const fixture = require('../../common/fixtures');

if (!common.hasCrypto)
Expand Down Expand Up @@ -44,13 +45,7 @@ const server = https.createServer(serverOptions, common.mustCall((req, res) => {
};

const req = https.request(clientOptions, common.mustCall((response) => {
let body = '';
response.setEncoding('utf8');
response.on('data', (chunk) => {
body += chunk;
});

response.on('end', common.mustCall(() => {
collectStream(response).then(common.mustCall((body) => {
assert.strictEqual(body, 'hello world');
server.close();
}));
Expand Down
9 changes: 2 additions & 7 deletions test/addons/openssl-key-engine/test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
const common = require('../../common');
const { collectStream } = require('../../common/streams');
const fixture = require('../../common/fixtures');

if (!common.hasCrypto)
Expand Down Expand Up @@ -46,13 +47,7 @@ const server = https.createServer(serverOptions, common.mustCall((req, res) => {
};

const req = https.request(clientOptions, common.mustCall((response) => {
let body = '';
response.setEncoding('utf8');
response.on('data', (chunk) => {
body += chunk;
});

response.on('end', common.mustCall(() => {
collectStream(response).then(common.mustCall((body) => {
assert.strictEqual(body, 'hello world');
server.close();
}));
Expand Down
61 changes: 61 additions & 0 deletions test/common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This directory contains modules used to test the Node.js implementation.
* [Internet module](#internet-module)
* [ongc module](#ongc-module)
* [Report module](#report-module)
* [Streams module](#streams-module)
* [tick module](#tick-module)
* [tmpdir module](#tmpdir-module)
* [WPT module](#wpt-module)
Expand Down Expand Up @@ -904,6 +905,65 @@ Validates the schema of a diagnostic report file whose path is specified in
Validates the schema of a diagnostic report whose content is specified in
`report`. If the report fails validation, an exception is thrown.

## Streams Module

The `streams` module provides helper functions for stream manipulation.

### `collectChildStreams(child[, waitFor])`

* return [<Promise>][]

Uses `collectStream` to collect `child.stdout`, `child.stderr` streams if
available, optionally waits for `waitFor` argument and resolves with an
object `{ stdout, stderr, data }` where `stdout`, `stderr` are strings of
respective collected streams and `data` is the result of `waitFor` or
`undefined`.

```js
const common = require('../common');
const { spawn } = require('child_process');
const { once } = require('events');

const child = spawn(...common.pwdCommand);
common.collectChildStreams(child, once(child, 'exit'))
.then(({ stdout, stderr, data: [code, signal] }) => {
// ...
});
```

### `collectStream(readable[, callback])`

* return [<Promise>][]

Uses async iterator to collect the data from the `readable` into a string and
returns it via Promise or callback if provided. Always sets encoding to `'utf8'`.

```js
const common = require('../common');
const http = require('assert');
const assert = require('assert');

http.request({ /* path, port */ }, (res) => {
common.collectStream(res).then((body) => {
assert.strictEqual(body, 'hello');
});
});
```

Or using callbacks:
```js
const common = require('../common');
const http = require('assert');
const assert = require('assert');

http.request({ /* path, port */ }, (res) => {
common.collectStream(res, (err, body) => {
assert.ifError(err);
assert.strictEqual(body, 'hello');
});
});
```

## tick Module

The `tick` module provides a helper function that can be used to call a callback
Expand Down Expand Up @@ -958,6 +1018,7 @@ See [the WPT tests README][] for details.
[<Error>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
[<Function>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
[<Object>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
[<Promise>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
[<RegExp>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
[<bigint>]: https://github.com/tc39/proposal-bigint
[<boolean>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type
Expand Down
32 changes: 32 additions & 0 deletions test/common/streams.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* eslint-disable node-core/require-common-first, node-core/required-modules */
'use strict';

async function collectStream(readable, callback) {
let data = '';
try {
readable.setEncoding('utf8');
for await (const chunk of readable)
data += chunk;
if (typeof callback === 'function')
process.nextTick(callback, null, data);
return data;
} catch (err) {
if (typeof callback === 'function') {
process.nextTick(callback, err);
} else {
throw err;
}
}
}

function collectChildStreams(child, waitFor) {
const stdout = child.stdout && collectStream(child.stdout);
const stderr = child.stderr && collectStream(child.stderr);
return Promise.all([stdout, stderr, waitFor])
.then(([stdout, stderr, data]) => ({ stdout, stderr, data }));
}

module.exports = {
collectChildStreams,
collectStream,
};
10 changes: 1 addition & 9 deletions test/parallel/test-cli-node-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const assert = require('assert');
const exec = require('child_process').execFile;
const { Worker } = require('worker_threads');

const { collectStream } = require('../common/streams');
const tmpdir = require('../common/tmpdir');
tmpdir.refresh();

Expand Down Expand Up @@ -112,15 +113,6 @@ function expect(
workerTest(opts, command, wantsError, test('worker'));
}

async function collectStream(readable) {
readable.setEncoding('utf8');
let data = '';
for await (const chunk of readable) {
data += chunk;
}
return data;
}

function workerTest(opts, command, wantsError, test) {
let workerError = null;
const worker = new Worker(command, {
Expand Down
22 changes: 9 additions & 13 deletions test/parallel/test-tracing-no-crash.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
'use strict';
const common = require('../common');
const { collectChildStreams } = require('../common/streams');
const assert = require('assert');
const { once } = require('events');
const { spawn } = require('child_process');

function CheckNoSignalAndErrorCodeOne(code, signal) {
assert.strictEqual(signal, null);
assert.strictEqual(code, 1);
}

const child = spawn(process.execPath, [
'--trace-event-categories', 'madeup', '-e', 'throw new Error()'
], { stdio: [ 'inherit', 'inherit', 'pipe' ] });
child.on('exit', common.mustCall(CheckNoSignalAndErrorCodeOne));

let stderr;
child.stderr.setEncoding('utf8');
child.stderr.on('data', (chunk) => stderr += chunk);
child.stderr.on('end', common.mustCall(() => {
assert(stderr.includes('throw new Error()'), stderr);
assert(!stderr.includes('Could not open trace file'), stderr);
}));
collectChildStreams(child, once(child, 'exit'))
.then(common.mustCall(({ stderr, data: [code, signal] }) => {
assert(stderr.includes('throw new Error()'), stderr);
assert(!stderr.includes('Could not open trace file'), stderr);
assert.strictEqual(signal, null);
assert.strictEqual(code, 1);
}));