tools: support environment variables via comments

PR-URL: https://github.com/nodejs/node/pull/58186
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
This commit is contained in:
Pietro Marchini 2025-05-11 19:54:56 +02:00 committed by GitHub
parent 3ad7362012
commit 6184730799
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 115 additions and 7 deletions

View file

@ -0,0 +1,16 @@
'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');
// This test verifies that the Python test runner 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
assert.strictEqual(process.env.A_SET_ENV_VAR, 'A_SET_ENV_VAR_VALUE');
assert.strictEqual(process.env.B_SET_ENV_VAR, 'B_SET_ENV_VAR_VALUE');
// Check interop with flags
const flag = require('internal/options').getOptionValue('--test-isolation');
assert.strictEqual(flag, 'none');

View file

@ -33,6 +33,7 @@ import re
from functools import reduce
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
ENV_PATTERN = re.compile(r"//\s+Env:(.*)")
class MessageTestCase(test.TestCase):
@ -89,20 +90,33 @@ class MessageTestCase(test.TestCase):
return True
return False
def _parse_source_env(self, source):
env_match = ENV_PATTERN.search(source)
env = {}
if env_match:
for env_pair in env_match.group(1).strip().split():
var, value = env_pair.split('=')
env[var] = value
return env
def GetLabel(self):
return "%s %s" % (self.mode, self.GetName())
def GetName(self):
return self.path[-1]
def GetCommand(self):
def GetRunConfiguration(self):
result = [self.config.context.GetVm(self.arch, self.mode)]
source = open(self.file).read()
flags_match = FLAGS_PATTERN.search(source)
envs = self._parse_source_env(source)
if flags_match:
result += flags_match.group(1).strip().split()
result.append(self.file)
return result
return {
'command': result,
'envs': envs
}
def GetSource(self):
return (open(self.file).read()

View 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 the Python test runner 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('testpy 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');
});
});

View file

@ -0,0 +1,16 @@
'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');
// This test verifies that the Python test runner 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
assert.strictEqual(process.env.A_SET_ENV_VAR, 'A_SET_ENV_VAR_VALUE');
assert.strictEqual(process.env.B_SET_ENV_VAR, 'B_SET_ENV_VAR_VALUE');
// Check interop with flags
const flag = require('internal/options').getOptionValue('--test-isolation');
assert.strictEqual(flag, 'none');

View file

@ -37,6 +37,7 @@ from functools import reduce
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
PTY_HELPER = join(dirname(__file__), '../../tools/pseudo-tty.py')
ENV_PATTERN = re.compile(r"//\s+Env:(.*)")
class TTYTestCase(test.TestCase):
@ -90,20 +91,33 @@ class TTYTestCase(test.TestCase):
return True
return False
def _parse_source_env(self, source):
env_match = ENV_PATTERN.search(source)
env = {}
if env_match:
for env_pair in env_match.group(1).strip().split():
var, value = env_pair.split('=')
env[var] = value
return env
def GetLabel(self):
return "%s %s" % (self.mode, self.GetName())
def GetName(self):
return self.path[-1]
def GetCommand(self):
def GetRunConfiguration(self):
result = [self.config.context.GetVm(self.arch, self.mode)]
source = open(self.file).read()
flags_match = FLAGS_PATTERN.search(source)
envs = self._parse_source_env(source)
if flags_match:
result += flags_match.group(1).strip().split()
result.append(self.file)
return result
return {
'command': result,
'envs': envs
}
def GetSource(self):
return (open(self.file).read()

View file

@ -34,6 +34,7 @@ from io import open
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
LS_RE = re.compile(r'^test-.*\.m?js$')
ENV_PATTERN = re.compile(r"//\s+Env:(.*)")
class SimpleTestCase(test.TestCase):
@ -48,6 +49,14 @@ class SimpleTestCase(test.TestCase):
else:
self.additional_flags = []
def _parse_source_env(self, source):
env_match = ENV_PATTERN.search(source)
env = {}
if env_match:
for env_pair in env_match.group(1).strip().split():
var, value = env_pair.split('=')
env[var] = value
return env
def GetLabel(self):
return "%s %s" % (self.mode, self.GetName())
@ -55,10 +64,11 @@ class SimpleTestCase(test.TestCase):
def GetName(self):
return self.path[-1]
def GetCommand(self):
def GetRunConfiguration(self):
result = [self.config.context.GetVm(self.arch, self.mode)]
source = open(self.file, encoding='utf8').read()
flags_match = FLAGS_PATTERN.search(source)
envs = self._parse_source_env(source)
if flags_match:
flags = flags_match.group(1).strip().split()
# The following block reads config.gypi to extract the v8_enable_inspector
@ -93,7 +103,10 @@ class SimpleTestCase(test.TestCase):
result += [self.file]
return result
return {
'command': result,
'envs': envs
}
def GetSource(self):
return open(self.file).read()

View file

@ -602,12 +602,21 @@ class TestCase(object):
def Run(self):
try:
result = self.RunCommand(self.GetCommand(), {
run_configuration = self.GetRunConfiguration()
command = run_configuration['command']
envs = {}
if 'envs' in run_configuration:
envs.update(run_configuration['envs'])
envs.update({
"TEST_SERIAL_ID": "%d" % self.serial_id,
"TEST_THREAD_ID": "%d" % self.thread_id,
"TEST_PARALLEL" : "%d" % self.parallel,
"GITHUB_STEP_SUMMARY": "",
})
result = self.RunCommand(
command,
envs
)
finally:
# Tests can leave the tty in non-blocking mode. If the test runner
# tries to print to stdout/stderr after that and the tty buffer is