From 49e48fba37e3b8bef69b241662ebb31370825c86 Mon Sep 17 00:00:00 2001 From: Szabo Bogdan Date: Thu, 21 Sep 2017 22:07:37 +0300 Subject: [PATCH 1/3] fix failing runs with empty arguments --- .gitignore | 3 ++- runner/app.d | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 36d52c4..4d02ba9 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,5 @@ libtrial.a xunit/ trial_*.d trial-lifecycle -trial-runner \ No newline at end of file +trial-runner +trial-root \ No newline at end of file diff --git a/runner/app.d b/runner/app.d index 90e4419..a440393 100644 --- a/runner/app.d +++ b/runner/app.d @@ -89,6 +89,8 @@ void showVersion() { version(unitttest) {} else { int main(string[] arguments) { + arguments = arguments.map!(a => a.strip).filter!(a => a != "").array; + version(Windows) { environment["TEMP"] = environment["TEMP"].replace("/", "\\"); } From b4f37aba95f46c8346689f9e980892673d66ad45 Mon Sep 17 00:00:00 2001 From: Szabo Bogdan Date: Tue, 26 Sep 2017 10:19:29 +0300 Subject: [PATCH 2/3] add seg handler --- lifecycle/trial/runner.d | 86 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/lifecycle/trial/runner.d b/lifecycle/trial/runner.d index 6175b50..21dcb05 100644 --- a/lifecycle/trial/runner.d +++ b/lifecycle/trial/runner.d @@ -130,6 +130,7 @@ const(TestCase)[][string] describeTests(const(TestCase)[] tests) { return groupedTests; } +/// string toJSONHierarchy(T)(const(T)[][string] items) { struct Node { Node[string] nodes; @@ -222,6 +223,8 @@ unittest { /// Runs the tests and returns the results auto runTests(const(TestCase)[] tests, string testName = "") { + setupSegmentationHandler(); + const(TestCase)[] filteredTests = tests; if(testName != "") { @@ -295,8 +298,19 @@ class LifeCycleListeners { ITestDiscovery[] testDiscoveryListeners; IAttachmentListener[] attachmentListeners; ITestExecutor executor; + + string currentTest; + } + + @property { + /// Return an unique name for the current running test. If there is no test running it + /// will return an empty string + string runningTest() const nothrow { + return currentTest; + } } + /// TestCase[] getTestCases() { return testDiscoveryListeners.map!(a => a.getTestCases).join; } @@ -370,21 +384,25 @@ class LifeCycleListeners { /// Send the begin test event to all listeners void begin(string suite, ref TestResult test) { + currentTest = suite ~ "." ~ test.name; testListeners.each!(a => a.begin(suite, test)); } /// Send the end test event to all listeners void end(string suite, ref TestResult test) { + currentTest = ""; testListeners.each!(a => a.end(suite, test)); } /// Send the begin step event to all listeners void begin(string suite, string test, ref StepResult step) { + currentTest = suite ~ "." ~ test ~ "." ~ step.name; stepListeners.each!(a => a.begin(suite, test, step)); } /// Send the end step event to all listeners void end(string suite, string test, ref StepResult step) { + currentTest = ""; stepListeners.each!(a => a.end(suite, test, step)); } @@ -402,4 +420,72 @@ class LifeCycleListeners { SuiteResult[] endExecution() { return executor.endExecution(); } +} + +/// It should return the name of this test +unittest { + LifeCycleListeners.instance.runningTest.should.equal("trial.runner.It should return the name of this test"); +} + +void setupSegmentationHandler() +{ + import core.runtime; + writeln("SETUP Seg handler"); + + // backtrace + version( CRuntime_Glibc ) + import core.sys.linux.execinfo; + else version( OSX ) + import core.sys.darwin.execinfo; + else version( FreeBSD ) + import core.sys.freebsd.execinfo; + else version( NetBSD ) + import core.sys.netbsd.execinfo; + else version( Windows ) + import core.sys.windows.stacktrace; + else version( Solaris ) + import core.sys.solaris.execinfo; + + static if( __traits( compiles, backtrace ) ) + { + import core.sys.posix.signal; // segv handler + + static extern (C) void unittestSegvHandler(int signum, siginfo_t* info, void* ptr ) nothrow + { + import core.stdc.stdio; + + core.stdc.stdio.printf("\n\n"); + + if(signum == SIGSEGV) { + core.stdc.stdio.printf("Got a Segmentation Fault running "); + } + + if(signum == SIGBUS) { + core.stdc.stdio.printf("Got a bus error running "); + } + + + if(LifeCycleListeners.instance.runningTest != "") { + core.stdc.stdio.printf("%s\n\n", LifeCycleListeners.instance.runningTest.ptr); + } else { + core.stdc.stdio.printf("some setup step. This is probably a Trial bug. Please create an issue on github.\n\n"); + } + + + static enum MAXFRAMES = 128; + void*[MAXFRAMES] callstack; + int numframes; + + numframes = backtrace( callstack.ptr, MAXFRAMES ); + backtrace_symbols_fd( callstack.ptr, numframes, 2); + } + + sigaction_t action = void; + (cast(byte*) &action)[0 .. action.sizeof] = 0; + sigfillset( &action.sa_mask ); // block other signals + action.sa_flags = SA_SIGINFO | SA_RESETHAND; + action.sa_sigaction = &unittestSegvHandler; + sigaction( SIGSEGV, &action, null ); + sigaction( SIGBUS, &action, null ); + } } \ No newline at end of file From 6cb7171a6f26bf440ba5c220f2fcc200c83a4bd2 Mon Sep 17 00:00:00 2001 From: Bogdan Szabo Date: Tue, 26 Sep 2017 11:48:58 +0300 Subject: [PATCH 3/3] add se handler to the main runner --- lifecycle/trial/runner.d | 36 +++++++++++++++++++++++------------- runner/app.d | 3 +++ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/lifecycle/trial/runner.d b/lifecycle/trial/runner.d index 21dcb05..fad1116 100644 --- a/lifecycle/trial/runner.d +++ b/lifecycle/trial/runner.d @@ -223,7 +223,7 @@ unittest { /// Runs the tests and returns the results auto runTests(const(TestCase)[] tests, string testName = "") { - setupSegmentationHandler(); + setupSegmentationHandler!true(); const(TestCase)[] filteredTests = tests; @@ -427,10 +427,9 @@ unittest { LifeCycleListeners.instance.runningTest.should.equal("trial.runner.It should return the name of this test"); } -void setupSegmentationHandler() +void setupSegmentationHandler(bool testRunner)() { import core.runtime; - writeln("SETUP Seg handler"); // backtrace version( CRuntime_Glibc ) @@ -456,21 +455,32 @@ void setupSegmentationHandler() core.stdc.stdio.printf("\n\n"); - if(signum == SIGSEGV) { - core.stdc.stdio.printf("Got a Segmentation Fault running "); - } + static if(testRunner) { + if(signum == SIGSEGV) { + core.stdc.stdio.printf("Got a Segmentation Fault running "); + } - if(signum == SIGBUS) { - core.stdc.stdio.printf("Got a bus error running "); - } + if(signum == SIGBUS) { + core.stdc.stdio.printf("Got a bus error running "); + } - if(LifeCycleListeners.instance.runningTest != "") { - core.stdc.stdio.printf("%s\n\n", LifeCycleListeners.instance.runningTest.ptr); + if(LifeCycleListeners.instance.runningTest != "") { + core.stdc.stdio.printf("%s\n\n", LifeCycleListeners.instance.runningTest.ptr); + } else { + core.stdc.stdio.printf("some setup step. This is probably a Trial bug. Please create an issue on github.\n\n"); + } } else { - core.stdc.stdio.printf("some setup step. This is probably a Trial bug. Please create an issue on github.\n\n"); - } + if(signum == SIGSEGV) { + core.stdc.stdio.printf("Got a Segmentation Fault! "); + } + if(signum == SIGBUS) { + core.stdc.stdio.printf("Got a bus error! "); + } + + core.stdc.stdio.printf(" This is probably a Trial bug. Please create an issue on github.\n\n"); + } static enum MAXFRAMES = 128; void*[MAXFRAMES] callstack; diff --git a/runner/app.d b/runner/app.d index a440393..721f959 100644 --- a/runner/app.d +++ b/runner/app.d @@ -89,6 +89,9 @@ void showVersion() { version(unitttest) {} else { int main(string[] arguments) { + import trial.runner; + setupSegmentationHandler!false; + arguments = arguments.map!(a => a.strip).filter!(a => a != "").array; version(Windows) {