From a615af233af115a607319af983afa89f05d3e954 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 21 Apr 2022 19:32:12 +0300 Subject: [PATCH] Provide more information when the native program crashed on a host (errored with a negative return code) // Resolve #3429 --- HISTORY.rst | 4 ++ platformio/unittest/runners/mixins/native.py | 17 +++++- tests/commands/test_test.py | 61 ++++++++++++++------ 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index e1cc411e..448f2db6 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -40,6 +40,10 @@ Please check `Migration guide from 5.x to 6.0 `__ - Fixed an issue when manually removed dependencies from the `"platformio.ini" `__ configuration file were not uninstalled from the storage (`issue #3076 `_) +* **Unit Testing** + + - Provide more information when the native program crashed on a host (errored with a negative return code) (`issue #3429 `_) + * **Static Code Analysis** - Added support for the custom `Clang-Tidy `__ configuration file (`issue #4186 `_) diff --git a/platformio/unittest/runners/mixins/native.py b/platformio/unittest/runners/mixins/native.py index 4787a473..9f635cb2 100644 --- a/platformio/unittest/runners/mixins/native.py +++ b/platformio/unittest/runners/mixins/native.py @@ -13,8 +13,10 @@ # limitations under the License. import os +import signal from platformio import proc +from platformio.unittest.exception import UnitTestError class TestRunnerNativeMixin: @@ -25,5 +27,16 @@ class TestRunnerNativeMixin: stdout=proc.LineBufferedAsyncPipe(self.on_run_output), stderr=proc.LineBufferedAsyncPipe(self.on_run_output), ) - assert "returncode" in result - return result["returncode"] == 0 + if result["returncode"] == 0: + return True + try: + sig = signal.Signals(abs(result["returncode"])) + try: + signal_description = signal.strsignal(sig) + except AttributeError: + signal_description = "" + raise UnitTestError( + f"Program received signal {sig.name} ({signal_description})" + ) + except ValueError: + raise UnitTestError("Program errored with %d code" % result["returncode"]) diff --git a/tests/commands/test_test.py b/tests/commands/test_test.py index 565849d5..b2f4bbf7 100644 --- a/tests/commands/test_test.py +++ b/tests/commands/test_test.py @@ -71,27 +71,54 @@ int main() { unittest_cmd, ["-d", str(project_dir), "-e", "native"], ) - - test_dir.join("unittest_transport.h").write( - """ -#ifdef __cplusplus -extern "C" { -#endif - -void unittest_uart_begin(){} -void unittest_uart_putchar(char c){} -void unittest_uart_flush(){} -void unittest_uart_end(){} - -#ifdef __cplusplus -} -#endif -""" - ) validate_cliresult(result) assert all(f in result.output for f in ("setUp called", "tearDown called")) +def test_crashed_program(clirunner, tmpdir): + project_dir = tmpdir.mkdir("project") + project_dir.join("platformio.ini").write( + """ +[env:native] +platform = native +""" + ) + test_dir = project_dir.mkdir("test") + test_dir.join("test_main.c").write( + """ +#include +#include + +void setUp(){ + printf("setUp called"); +} +void tearDown(){ + printf("tearDown called"); +} + +void dummy_test(void) { + TEST_ASSERT_EQUAL(1, 1); +} + +int main(int argc, char *argv[]) { + printf("Address boundary error is %s", argv[-1]); + UNITY_BEGIN(); + RUN_TEST(dummy_test); + UNITY_END(); + return 0; +} +""" + ) + result = clirunner.invoke( + unittest_cmd, + ["-d", str(project_dir), "-e", "native"], + ) + assert result.exit_code != 0 + assert any( + s in result.output for s in ("Program received signal", "Program errored with") + ) + + def test_legacy_unity_custom_transport(clirunner, validate_cliresult, tmpdir): project_dir = tmpdir.mkdir("project") project_dir.join("platformio.ini").write(