diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module index 24665c7..f4c2cbc 100644 --- a/core/modules/simpletest/simpletest.module +++ b/core/modules/simpletest/simpletest.module @@ -184,14 +184,17 @@ function simpletest_run_tests($test_list) { * @param $unescaped_test_classnames * An array of test class names, including full namespaces, to be passed as * a regular expression to PHPUnit's --filter option. + * @param int $status + * (optional) The exit status code of the PHPUnit process will be assigned to + * this variable. * * @return array * The parsed results of PHPUnit's JUnit XML output, in the format of * {simpletest}'s schema. */ -function simpletest_run_phpunit_tests($test_id, array $unescaped_test_classnames) { +function simpletest_run_phpunit_tests($test_id, array $unescaped_test_classnames, &$status = NULL) { $phpunit_file = simpletest_phpunit_xml_filepath($test_id); - simpletest_phpunit_run_command($unescaped_test_classnames, $phpunit_file); + simpletest_phpunit_run_command($unescaped_test_classnames, $phpunit_file, $status); return simpletest_phpunit_xml_to_rows($test_id, $phpunit_file); } @@ -246,11 +249,14 @@ function simpletest_phpunit_configuration_filepath() { * a regular expression to PHPUnit's --filter option. * @param string $phpunit_file * A filepath to use for PHPUnit's --log-junit option. + * @param int $status + * (optional) The exit status code of the PHPUnit process will be assigned to + * this variable. * * @return string * The results as returned by exec(). */ -function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpunit_file) { +function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpunit_file, &$status = NULL) { $phpunit_bin = simpletest_phpunit_command(); $command = array( @@ -284,7 +290,7 @@ function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpun // exec in a subshell so that the environment is isolated when running tests // via the simpletest UI. - $ret = exec(join($command, " ")); + $ret = exec(join($command, " "), $output, $status); chdir($old_cwd); return $ret; } diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh index b91a784..f4bc4e8 100755 --- a/core/scripts/run-tests.sh +++ b/core/scripts/run-tests.sh @@ -16,7 +16,10 @@ const SIMPLETEST_SCRIPT_COLOR_PASS = 32; // Green. const SIMPLETEST_SCRIPT_COLOR_FAIL = 31; // Red. const SIMPLETEST_SCRIPT_COLOR_EXCEPTION = 33; // Brown. -const SIMPLETEST_SCRIPT_FAILS_OR_ERRORS = 2; // Status code for failed tests. + +const SIMPLETEST_SCRIPT_EXIT_SUCCESS = 0; +const SIMPLETEST_SCRIPT_EXIT_FAILURE = 1; +const SIMPLETEST_SCRIPT_EXIT_EXCEPTION = 2; // Set defaults and get overrides. list($args, $count) = simpletest_script_parse_args(); @@ -503,8 +506,7 @@ function simpletest_script_setup_database($new = FALSE) { function simpletest_script_execute_batch($test_classes) { global $args, $test_ids; - // Keeps track of failures or exceptions during the tests. - $has_fails_or_exceptions = FALSE; + $total_status = SIMPLETEST_SCRIPT_EXIT_SUCCESS; // Multi-process execution. $children = array(); @@ -522,9 +524,9 @@ function simpletest_script_execute_batch($test_classes) { // Process phpunit tests immediately since they are fast and we don't need // to fork for them. if (is_subclass_of($test_class, 'Drupal\Tests\UnitTestCase')) { - $exit_code = simpletest_script_run_phpunit($test_id, $test_class); - if ($exit_code) { - $has_fails_or_exceptions = TRUE; + $phpunit_status = simpletest_script_run_phpunit($test_id, $test_class); + if ($phpunit_status > $total_status) { + $total_status = $phpunit_status; } continue; } @@ -556,8 +558,13 @@ function simpletest_script_execute_batch($test_classes) { if (empty($status['running'])) { // The child exited, unregister it. proc_close($child['process']); - if ($status['exitcode']) { - $has_fails_or_exceptions = TRUE; + if ($status['exitcode'] == SIMPLETEST_SCRIPT_EXIT_FAILURE) { + if ($status['exitcode'] > $total_status) { + $total_status = $status['exitcode']; + } + } + elseif ($status['exitcode']) { + $total_status = $status['exitcode']; echo 'FATAL ' . $child['class'] . ': test runner returned a non-zero error code (' . $status['exitcode'] . ').' . "\n"; if ($args['die-on-fail']) { list($db_prefix, ) = simpletest_last_test_get($child['test_id']); @@ -578,16 +585,14 @@ function simpletest_script_execute_batch($test_classes) { } } } - if ($has_fails_or_exceptions) { - return SIMPLETEST_SCRIPT_FAILS_OR_ERRORS; - } + return $total_status; } /** * Run a group of phpunit tests. */ function simpletest_script_run_phpunit($test_id, $class) { - $results = simpletest_run_phpunit_tests($test_id, array($class)); + $results = simpletest_run_phpunit_tests($test_id, array($class), $status); simpletest_process_phpunit_results($results); // Map phpunit results to a data structure we can pass to @@ -619,15 +624,10 @@ function simpletest_script_run_phpunit($test_id, $class) { } } - $exit_code = 0; foreach ($summaries as $class => $summary) { simpletest_script_reporter_display_summary($class, $summary); - - if ($summary['#fail'] || $summary['#exception']) { - $exit_code = SIMPLETEST_SCRIPT_FAILS_OR_ERRORS; - } } - return($exit_code); + return $status; } /** @@ -644,19 +644,17 @@ function simpletest_script_run_one_test($test_id, $test_class) { simpletest_script_reporter_display_summary($test_class, $test->results); - // Finished, kill this runner. if ($test->results['#fail'] || $test->results['#exception']) { - exit(SIMPLETEST_SCRIPT_FAILS_OR_ERRORS); + exit(SIMPLETEST_SCRIPT_EXIT_FAILURE); } exit(0); - } // DrupalTestCase::run() catches exceptions already, so this is only reached // when an exception is thrown in the wrapping test runner environment. catch (Exception $e) { echo (string) $e; - exit(1); + exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION); } }