mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 12:20:27 +01:00
test: add parseTestMetadata support
PR-URL: https://github.com/nodejs/node/pull/59503 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
This commit is contained in:
parent
3e5885b3cb
commit
518d80d48a
|
|
@ -84,7 +84,7 @@ async function spawnAndAssert(filename, transform = (x) => x, { tty = false, ...
|
||||||
test({ skip: 'Skipping pseudo-tty tests, as pseudo terminals are not available on Windows.' });
|
test({ skip: 'Skipping pseudo-tty tests, as pseudo terminals are not available on Windows.' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let flags = common.parseTestFlags(filename);
|
let { flags } = common.parseTestMetadata(filename);
|
||||||
if (options.flags) {
|
if (options.flags) {
|
||||||
flags = [...options.flags, ...flags];
|
flags = [...options.flags, ...flags];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,16 @@ const hasSQLite = Boolean(process.versions.sqlite);
|
||||||
|
|
||||||
const hasQuic = hasCrypto && !!process.config.variables.node_quic;
|
const hasQuic = hasCrypto && !!process.config.variables.node_quic;
|
||||||
|
|
||||||
function parseTestFlags(filename = process.argv[1]) {
|
/**
|
||||||
// The copyright notice is relatively big and the flags could come afterwards.
|
* Parse test metadata from the specified file.
|
||||||
|
* @param {string} filename - The name of the file to parse.
|
||||||
|
* @returns {{
|
||||||
|
* flags: string[],
|
||||||
|
* envs: Record<string, string>
|
||||||
|
* }} An object containing the parsed flags and environment variables.
|
||||||
|
*/
|
||||||
|
function parseTestMetadata(filename = process.argv[1]) {
|
||||||
|
// The copyright notice is relatively big and the metadata could come afterwards.
|
||||||
const bytesToRead = 1500;
|
const bytesToRead = 1500;
|
||||||
const buffer = Buffer.allocUnsafe(bytesToRead);
|
const buffer = Buffer.allocUnsafe(bytesToRead);
|
||||||
const fd = fs.openSync(filename, 'r');
|
const fd = fs.openSync(filename, 'r');
|
||||||
|
|
@ -68,19 +76,33 @@ function parseTestFlags(filename = process.argv[1]) {
|
||||||
const source = buffer.toString('utf8', 0, bytesRead);
|
const source = buffer.toString('utf8', 0, bytesRead);
|
||||||
|
|
||||||
const flagStart = source.search(/\/\/ Flags:\s+--/) + 10;
|
const flagStart = source.search(/\/\/ Flags:\s+--/) + 10;
|
||||||
|
let flags = [];
|
||||||
|
if (flagStart !== 9) {
|
||||||
|
let flagEnd = source.indexOf('\n', flagStart);
|
||||||
|
if (source[flagEnd - 1] === '\r') {
|
||||||
|
flagEnd--;
|
||||||
|
}
|
||||||
|
flags = source
|
||||||
|
.substring(flagStart, flagEnd)
|
||||||
|
.split(/\s+/)
|
||||||
|
.filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
if (flagStart === 9) {
|
const envStart = source.search(/\/\/ Env:\s+/) + 8;
|
||||||
return [];
|
let envs = {};
|
||||||
|
if (envStart !== 7) {
|
||||||
|
let envEnd = source.indexOf('\n', envStart);
|
||||||
|
if (source[envEnd - 1] === '\r') {
|
||||||
|
envEnd--;
|
||||||
|
}
|
||||||
|
const envArray = source
|
||||||
|
.substring(envStart, envEnd)
|
||||||
|
.split(/\s+/)
|
||||||
|
.filter(Boolean);
|
||||||
|
envs = Object.fromEntries(envArray.map((env) => env.split('=')));
|
||||||
}
|
}
|
||||||
let flagEnd = source.indexOf('\n', flagStart);
|
|
||||||
// Normalize different EOL.
|
return { flags, envs };
|
||||||
if (source[flagEnd - 1] === '\r') {
|
|
||||||
flagEnd--;
|
|
||||||
}
|
|
||||||
return source
|
|
||||||
.substring(flagStart, flagEnd)
|
|
||||||
.split(/\s+/)
|
|
||||||
.filter(Boolean);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for flags. Skip this for workers (both, the `cluster` module and
|
// Check for flags. Skip this for workers (both, the `cluster` module and
|
||||||
|
|
@ -93,7 +115,7 @@ if (process.argv.length === 2 &&
|
||||||
hasCrypto &&
|
hasCrypto &&
|
||||||
require('cluster').isPrimary &&
|
require('cluster').isPrimary &&
|
||||||
fs.existsSync(process.argv[1])) {
|
fs.existsSync(process.argv[1])) {
|
||||||
const flags = parseTestFlags();
|
const { flags, envs } = parseTestMetadata();
|
||||||
for (const flag of flags) {
|
for (const flag of flags) {
|
||||||
if (!process.execArgv.includes(flag) &&
|
if (!process.execArgv.includes(flag) &&
|
||||||
// If the binary is build without `intl` the inspect option is
|
// If the binary is build without `intl` the inspect option is
|
||||||
|
|
@ -102,11 +124,20 @@ if (process.argv.length === 2 &&
|
||||||
console.log(
|
console.log(
|
||||||
'NOTE: The test started as a child_process using these flags:',
|
'NOTE: The test started as a child_process using these flags:',
|
||||||
inspect(flags),
|
inspect(flags),
|
||||||
|
'And these environment variables:',
|
||||||
|
inspect(envs),
|
||||||
'Use NODE_SKIP_FLAG_CHECK to run the test with the original flags.',
|
'Use NODE_SKIP_FLAG_CHECK to run the test with the original flags.',
|
||||||
);
|
);
|
||||||
const { spawnSync } = require('child_process');
|
const { spawnSync } = require('child_process');
|
||||||
const args = [...flags, ...process.execArgv, ...process.argv.slice(1)];
|
const args = [...flags, ...process.execArgv, ...process.argv.slice(1)];
|
||||||
const options = { encoding: 'utf8', stdio: 'inherit' };
|
const options = {
|
||||||
|
encoding: 'utf8',
|
||||||
|
stdio: 'inherit',
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
...envs,
|
||||||
|
},
|
||||||
|
};
|
||||||
const result = spawnSync(process.execPath, args, options);
|
const result = spawnSync(process.execPath, args, options);
|
||||||
if (result.signal) {
|
if (result.signal) {
|
||||||
process.kill(0, result.signal);
|
process.kill(0, result.signal);
|
||||||
|
|
@ -912,7 +943,7 @@ const common = {
|
||||||
mustSucceed,
|
mustSucceed,
|
||||||
nodeProcessAborted,
|
nodeProcessAborted,
|
||||||
PIPE,
|
PIPE,
|
||||||
parseTestFlags,
|
parseTestMetadata,
|
||||||
platformTimeout,
|
platformTimeout,
|
||||||
printSkipMessage,
|
printSkipMessage,
|
||||||
pwdCommand,
|
pwdCommand,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ const {
|
||||||
mustNotMutateObjectDeep,
|
mustNotMutateObjectDeep,
|
||||||
mustSucceed,
|
mustSucceed,
|
||||||
nodeProcessAborted,
|
nodeProcessAborted,
|
||||||
parseTestFlags,
|
parseTestMetadata,
|
||||||
PIPE,
|
PIPE,
|
||||||
platformTimeout,
|
platformTimeout,
|
||||||
printSkipMessage,
|
printSkipMessage,
|
||||||
|
|
@ -86,7 +86,7 @@ export {
|
||||||
mustNotMutateObjectDeep,
|
mustNotMutateObjectDeep,
|
||||||
mustSucceed,
|
mustSucceed,
|
||||||
nodeProcessAborted,
|
nodeProcessAborted,
|
||||||
parseTestFlags,
|
parseTestMetadata,
|
||||||
PIPE,
|
PIPE,
|
||||||
platformTimeout,
|
platformTimeout,
|
||||||
printSkipMessage,
|
printSkipMessage,
|
||||||
|
|
|
||||||
26
test/parallel/test-parse-test-envs.js
Normal file
26
test/parallel/test-parse-test-envs.js
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Env: A_SET_ENV_VAR=A_SET_ENV_VAR_VALUE B_SET_ENV_VAR=B_SET_ENV_VAR_VALUE
|
||||||
|
// Flags: --test-isolation=none --expose-internals
|
||||||
|
|
||||||
|
require('../common');
|
||||||
|
const assert = require('node:assert');
|
||||||
|
const { describe, it } = require('node:test');
|
||||||
|
|
||||||
|
|
||||||
|
// This test verifies that a test file that requires 'common' can set environment variables
|
||||||
|
// via comments in the test file, similar to how we set flags via comments.
|
||||||
|
// Ref: https://github.com/nodejs/node/issues/58179
|
||||||
|
describe('env var via comment', () => {
|
||||||
|
it('should set env var A_SET_ENV_VAR', () => {
|
||||||
|
assert.strictEqual(process.env.A_SET_ENV_VAR, 'A_SET_ENV_VAR_VALUE');
|
||||||
|
});
|
||||||
|
it('should set env var B_SET_ENV_VAR', () => {
|
||||||
|
assert.strictEqual(process.env.B_SET_ENV_VAR, 'B_SET_ENV_VAR_VALUE');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should interop with flags', () => {
|
||||||
|
const flag = require('internal/options').getOptionValue('--test-isolation');
|
||||||
|
assert.strictEqual(flag, 'none');
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user