From a59c84284cc9db347399bd81ce823e2438d5be02 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Thu, 24 Aug 2017 22:18:47 -0700 Subject: [PATCH 1/3] test: improve test-abort-uncaught-exception Add `SIGTRAP` to allowed signals (seen on PPC machines in CI). Improve message when assertion fails in test-abort-uncaught-exception by providing the signal name that was not expected. --- test/abort/test-abort-uncaught-exception.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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); } From b68451843e29b9219095f455a471a6a7c8f41eee Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Thu, 24 Aug 2017 23:18:58 -0700 Subject: [PATCH 2/3] test: improve test-abort-backtrace Improve error message by showing output when frames output does not meet expectations. Since we can't tell at runtime if we have the correct libc for backtraces, allow an empty backtrace and run the test on all platforms. --- test/abort/test-abort-backtrace.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) 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}`); + } + } } From 66b9ab68b358902f19285f0b26e89c55d055a45f Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 30 Jun 2017 13:14:04 -0700 Subject: [PATCH 3/3] test: run abort tests Currently, tests in test/abort do not run in CI. This change configures the test runner to not write core files for abort tests and to run them. Fixes: https://github.com/nodejs/node/issues/14012 --- Makefile | 2 +- test/abort/testcfg.py | 2 +- test/testpy/__init__.py | 12 ++++++++++++ tools/test.py | 18 +++++++++++++++--- 4 files changed, 29 insertions(+), 5 deletions(-) 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/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):