diff --git a/Makefile b/Makefile index 6a334d96901b85..67a568cfa54efe 100644 --- a/Makefile +++ b/Makefile @@ -333,7 +333,7 @@ test-all-valgrind: test-build $(PYTHON) tools/test.py --mode=debug,release --valgrind CI_NATIVE_SUITES := addons addons-napi -CI_JS_SUITES := async-hooks doctool inspector known_issues message parallel pseudo-tty sequential +CI_JS_SUITES := abort async-hooks doctool inspector known_issues message parallel pseudo-tty sequential # Build and test addons without building anything else test-ci-native: LOGLEVEL := info diff --git a/test/abort/test-abort-backtrace.js b/test/abort/test-abort-backtrace.js index dd108171684018..6d3121e538eb02 100644 --- a/test/abort/test-abort-backtrace.js +++ b/test/abort/test-abort-backtrace.js @@ -10,13 +10,19 @@ if (process.argv[2] === 'child') { process.abort(); } else { const child = cp.spawnSync(`${process.execPath}`, [`${__filename}`, 'child']); - const frames = - child.stderr.toString().trimRight().split('\n').map((s) => s.trim()); + const stderr = child.stderr.toString(); assert.strictEqual(child.stdout.toString(), ''); - assert.ok(frames.length > 0); - // All frames should start with a frame number. - assert.ok(frames.every((frame, index) => frame.startsWith(`${index + 1}:`))); - // At least some of the frames should include the binary name. - assert.ok(frames.some((frame) => frame.includes(`[${process.execPath}]`))); + // stderr will be empty for systems that don't support backtraces. + if (stderr !== '') { + const frames = stderr.trimRight().split('\n').map((s) => s.trim()); + + if (!frames.every((frame, index) => frame.startsWith(`${index + 1}:`))) { + assert.fail(`Each frame should start with a frame number:\n${stderr}`); + } + + if (!frames.some((frame) => frame.includes(`[${process.execPath}]`))) { + assert.fail(`Some frames should include the binary name:\n${stderr}`); + } + } } diff --git a/test/abort/test-abort-uncaught-exception.js b/test/abort/test-abort-uncaught-exception.js index fb30cfba3cd34a..e88a56a48954c6 100644 --- a/test/abort/test-abort-uncaught-exception.js +++ b/test/abort/test-abort-uncaught-exception.js @@ -9,7 +9,7 @@ if (process.argv[2] === 'child') { throw new Error('child error'); } else { run('', null); - run('--abort-on-uncaught-exception', ['SIGABRT', 'SIGILL']); + run('--abort-on-uncaught-exception', ['SIGABRT', 'SIGTRAP', 'SIGILL']); } function run(flags, signals) { @@ -26,7 +26,7 @@ function run(flags, signals) { assert.strictEqual(code, 1); } else { if (signals) - assert.strictEqual(signals.includes(sig), true); + assert(signals.includes(sig), `Unexpected signal ${sig}`); else assert.strictEqual(sig, null); } diff --git a/test/abort/testcfg.py b/test/abort/testcfg.py index 5e441845681c52..e509d0453c40fb 100644 --- a/test/abort/testcfg.py +++ b/test/abort/testcfg.py @@ -3,4 +3,4 @@ import testpy def GetConfiguration(context, root): - return testpy.SimpleTestConfiguration(context, root, 'abort') + return testpy.AbortTestConfiguration(context, root, 'abort') diff --git a/test/testpy/__init__.py b/test/testpy/__init__.py index 0efabae02c005c..37e5ac710bcdf8 100644 --- a/test/testpy/__init__.py +++ b/test/testpy/__init__.py @@ -180,3 +180,15 @@ def ListTests(self, current_path, path, arch, mode): for test in result: test.parallel = True return result + +class AbortTestConfiguration(SimpleTestConfiguration): + def __init__(self, context, root, section, additional=None): + super(AbortTestConfiguration, self).__init__(context, root, section, + additional) + + def ListTests(self, current_path, path, arch, mode): + result = super(AbortTestConfiguration, self).ListTests( + current_path, path, arch, mode) + for test in result: + test.disable_core_files = True + return result diff --git a/tools/test.py b/tools/test.py index 92ccb3df20611e..5a50c7f2e6ccc6 100755 --- a/tools/test.py +++ b/tools/test.py @@ -492,6 +492,7 @@ def __init__(self, context, path, arch, mode): self.arch = arch self.mode = mode self.parallel = False + self.disable_core_files = False self.thread_id = 0 def IsNegative(self): @@ -516,7 +517,8 @@ def RunCommand(self, command, env): output = Execute(full_command, self.context, self.context.GetTimeout(self.mode), - env) + env, + disable_core_files = self.disable_core_files) self.Cleanup() return TestOutput(self, full_command, @@ -718,7 +720,7 @@ def CheckedUnlink(name): PrintError("os.unlink() " + str(e)) break -def Execute(args, context, timeout=None, env={}, faketty=False): +def Execute(args, context, timeout=None, env={}, faketty=False, disable_core_files=False): if faketty: import pty (out_master, fd_out) = pty.openpty() @@ -740,6 +742,14 @@ def Execute(args, context, timeout=None, env={}, faketty=False): for key, value in env.iteritems(): env_copy[key] = value + preexec_fn = None + + if disable_core_files and not utils.IsWindows(): + def disableCoreFiles(): + import resource + resource.setrlimit(resource.RLIMIT_CORE, (0,0)) + preexec_fn = disableCoreFiles + (process, exit_code, timed_out, output) = RunProcess( context, timeout, @@ -749,7 +759,8 @@ def Execute(args, context, timeout=None, env={}, faketty=False): stderr = fd_err, env = env_copy, faketty = faketty, - pty_out = pty_out + pty_out = pty_out, + preexec_fn = preexec_fn ) if faketty: os.close(out_master) @@ -1237,6 +1248,7 @@ def __init__(self, case, outcomes): self.case = case self.outcomes = outcomes self.parallel = self.case.parallel + self.disable_core_files = self.case.disable_core_files class Configuration(object):