Skip to content

Commit

Permalink
Merge 8896486 into 41b3f04
Browse files Browse the repository at this point in the history
  • Loading branch information
vpod committed Dec 11, 2019
2 parents 41b3f04 + 8896486 commit 4ceff72
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 11 deletions.
20 changes: 12 additions & 8 deletions src/Platforms/Gcc/UtestPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,29 +76,33 @@ static int PlatformSpecificWaitPidImplementation(int, int*, int)

static void GccPlatformSpecificRunTestInASeperateProcess(UtestShell* shell, TestPlugin* plugin, TestResult* result)
{
pid_t cpid, w;
const pid_t syscallError = -1;
pid_t cpid;
pid_t w;
int status;

cpid = PlatformSpecificFork();

if (cpid == -1) {
if (cpid == syscallError) {
result->addFailure(TestFailure(shell, "Call to fork() failed"));
return;
}

if (cpid == 0) { /* Code executed by child */
shell->runOneTestInCurrentProcess(plugin, *result); // LCOV_EXCL_LINE
_exit(result->getFailureCount()); // LCOV_EXCL_LINE
const int initialFailureCount = result->getFailureCount(); // LCOV_EXCL_LINE
shell->runOneTestInCurrentProcess(plugin, *result); // LCOV_EXCL_LINE
_exit(initialFailureCount < result->getFailureCount()); // LCOV_EXCL_LINE
} else { /* Code executed by parent */
result->countRun();
do {
w = PlatformSpecificWaitPid(cpid, &status, WUNTRACED);
if (w == -1) {
if(EINTR ==errno) continue; /* OS X debugger */
if (w == syscallError) {
if(EINTR == errno) continue; /* OS X debugger */
result->addFailure(TestFailure(shell, "Call to waitpid() failed"));
return;
}

if (WIFEXITED(status) && WEXITSTATUS(status) > result->getFailureCount()) {
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
result->addFailure(TestFailure(shell, "Failed in separate process"));
} else if (WIFSIGNALED(status)) {
SimpleString signal(StringFrom(WTERMSIG(status)));
Expand All @@ -111,7 +115,7 @@ static void GccPlatformSpecificRunTestInASeperateProcess(UtestShell* shell, Test
result->addFailure(TestFailure(shell, "Stopped in separate process - continuing"));
kill(w, SIGCONT);
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
} while ((w == syscallError) || (!WIFEXITED(status) && !WIFSIGNALED(status)));
}
}

Expand Down
44 changes: 41 additions & 3 deletions tests/CppUTest/UtestPlatformTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdlib.h>

#include "CppUTest/CommandLineTestRunner.h"
#include "CppUTest/TestHarness.h"
#include "CppUTest/TestTestingFixture.h"
Expand Down Expand Up @@ -56,8 +58,17 @@ static void _failFunction()
FAIL("This test fails");
}

static void _exitNonZeroFunction() __no_return__;
static void _exitNonZeroFunction()
{
exit(1);
}

#include <errno.h>

static int waitpid_while_debugging_stub_number_called = 0;
const int waitpid_while_debugging_stub_forced_failures = 10;

extern "C" {

static int (*original_waitpid)(int, int*, int) = NULLPTR;
Expand All @@ -66,10 +77,9 @@ extern "C" {

static int waitpid_while_debugging_stub(int pid, int* status, int options)
{
static int number_called = 0;
static int saved_status;

if (number_called++ < 10) {
if (waitpid_while_debugging_stub_number_called++ < waitpid_while_debugging_stub_forced_failures) {
saved_status = *status;
errno=EINTR;
return -1;
Expand All @@ -96,12 +106,20 @@ static void _stoppedTestFunction()
kill(getpid(), SIGSTOP);
}

TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, TestInSeparateProcessWorks)
{
fixture.registry_->setRunTestsInSeperateProcess();
fixture.runAllTests();
fixture.assertPrintContains("OK (1 tests, 1 ran, 0 checks, 0 ignored, 0 filtered out");
}

TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, FailureInSeparateProcessWorks)
{
fixture.registry_->setRunTestsInSeperateProcess();
fixture.setTestFunction(_failFunction);
fixture.runAllTests();
fixture.assertPrintContains("Failed in separate process");
fixture.assertPrintContains("Errors (1 failures, 1 tests, 1 ran, 0 checks, 0 ignored, 0 filtered out");
}

TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, AccessViolationInSeparateProcessWorks)
Expand All @@ -110,6 +128,7 @@ TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, AccessViolati
fixture.setTestFunction((void(*)())_accessViolationTestFunction);
fixture.runAllTests();
fixture.assertPrintContains("Failed in separate process - killed by signal 11");
fixture.assertPrintContains("Errors (1 failures, 1 tests, 1 ran");
}

TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, StoppedInSeparateProcessWorks)
Expand All @@ -118,6 +137,7 @@ TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, StoppedInSepa
fixture.setTestFunction(_stoppedTestFunction);
fixture.runAllTests();
fixture.assertPrintContains("Stopped in separate process - continuing");
fixture.assertPrintContains("Errors (1 failures, 1 tests, 1 ran");
}

TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, CallToForkFailedInSeparateProcessWorks)
Expand All @@ -126,15 +146,19 @@ TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, CallToForkFai
fixture.registry_->setRunTestsInSeperateProcess();
fixture.runAllTests();
fixture.assertPrintContains("Call to fork() failed");
fixture.assertPrintContains("Errors (1 failures, 1 tests, 0 ran");
}

TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, CallToWaitPidWhileDebuggingInSeparateProcessWorks)
{
UT_PTR_SET(original_waitpid, PlatformSpecificWaitPid);
UT_PTR_SET(PlatformSpecificWaitPid, waitpid_while_debugging_stub);
waitpid_while_debugging_stub_number_called = 0;
fixture.registry_->setRunTestsInSeperateProcess();
fixture.runAllTests();
fixture.assertPrintContains("OK (1 tests, 0 ran, 0 checks, 0 ignored, 0 filtered out");
fixture.assertPrintContains("OK (1 tests, 1 ran, 0 checks, 0 ignored, 0 filtered out");
// extra check to confirm that waitpid() was polled until it passed (and passed call adds one)
LONGS_EQUAL(waitpid_while_debugging_stub_forced_failures + 1, waitpid_while_debugging_stub_number_called);
}

TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, CallToWaitPidFailedInSeparateProcessWorks)
Expand All @@ -143,6 +167,20 @@ TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, CallToWaitPid
fixture.registry_->setRunTestsInSeperateProcess();
fixture.runAllTests();
fixture.assertPrintContains("Call to waitpid() failed");
fixture.assertPrintContains("Errors (1 failures, 1 tests, 1 ran");
}

TEST(UTestPlatformsTest_PlatformSpecificRunTestInASeperateProcess, MultipleTestsInSeparateProcessAreCountedProperly)
{
fixture.registry_->setRunTestsInSeperateProcess();
fixture.runTestWithMethod(NULLPTR);
fixture.runTestWithMethod(_stoppedTestFunction);
fixture.runTestWithMethod(NULLPTR);
fixture.runTestWithMethod(_exitNonZeroFunction);
fixture.runTestWithMethod(NULLPTR);
fixture.assertPrintContains("Failed in separate process");
fixture.assertPrintContains("Stopped in separate process");
fixture.assertPrintContains("Errors (2 failures, 5 tests, 5 ran, 0 checks, 0 ignored, 0 filtered out");
}

#endif

0 comments on commit 4ceff72

Please sign in to comment.