Commit 1edfae73 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2189345 by sanduhrs, jbekker, joshtaylor, benjy, sun: run-tests.sh...

Issue #2189345 by sanduhrs, jbekker, joshtaylor, benjy, sun: run-tests.sh should exit with a failure code if any tests failed
parent 2d4be0ef
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -170,14 +170,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);
}

@@ -232,11 +235,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(
@@ -270,7 +276,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;
}
+43 −23
Original line number Diff line number Diff line
@@ -20,12 +20,16 @@
// Restricting the chunk of queries prevents memory exhaustion.
const SIMPLETEST_SCRIPT_SQLITE_VARIABLE_LIMIT = 350;

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();

if ($args['help'] || $count == 0) {
  simpletest_script_help();
  exit;
  exit(($count == 0) ? SIMPLETEST_SCRIPT_EXIT_FAILURE : SIMPLETEST_SCRIPT_EXIT_SUCCESS);
}

simpletest_script_init();
@@ -38,7 +42,7 @@
  simpletest_script_setup_database();
  simpletest_script_run_one_test($args['test-id'], $args['execute-test']);
  // Sub-process exited already; this is just for clarity.
  exit;
  exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
}

simpletest_script_setup_database(TRUE);
@@ -53,7 +57,7 @@
  foreach ($messages['status'] as $text) {
    echo " - " . $text . "\n";
  }
  exit;
  exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
}

if ($args['list']) {
@@ -67,7 +71,7 @@
      echo " - $class\n";
    }
  }
  exit;
  exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
}

$test_list = simpletest_script_get_test_list();
@@ -82,7 +86,7 @@
}

// Execute tests.
simpletest_script_execute_batch($tests_to_run);
$status = simpletest_script_execute_batch($tests_to_run);

// Stop the timer.
simpletest_script_reporter_timer_stop();
@@ -100,7 +104,7 @@
}

// Test complete, exit.
exit;
exit($status);

/**
 * Print help text.
@@ -273,7 +277,7 @@ function simpletest_script_parse_args() {
      else {
        // Argument not found in list.
        simpletest_script_print_error("Unknown argument '$arg'.");
        exit;
        exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
      }
    }
    else {
@@ -286,7 +290,7 @@ function simpletest_script_parse_args() {
  // Validate the concurrency argument
  if (!is_numeric($args['concurrency']) || $args['concurrency'] <= 0) {
    simpletest_script_print_error("--concurrency must be a strictly positive integer.");
    exit;
    exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
  }

  return array($args, $count);
@@ -318,7 +322,7 @@ function simpletest_script_init() {
  else {
    simpletest_script_print_error('Unable to automatically determine the path to the PHP interpreter. Supply the --php command line argument.');
    simpletest_script_help();
    exit();
    exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
  }

  // Get URL from arguments.
@@ -404,7 +408,7 @@ function simpletest_script_setup_database($new = FALSE) {
    $info = parse_url($args['dburl']);
    if (!isset($info['scheme'], $info['host'], $info['path'])) {
      simpletest_script_print_error('Invalid --dburl. Minimum requirement: driver://host/database');
      exit(1);
      exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
    }
    $info += array(
      'user' => '',
@@ -439,7 +443,7 @@ function simpletest_script_setup_database($new = FALSE) {
  // If there is no default database connection for tests, we cannot continue.
  if (!isset($databases['default']['default'])) {
    simpletest_script_print_error('Missing default database connection for tests. Use --dburl to specify one.');
    exit(1);
    exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
  }
  Database::addConnectionInfo('default', 'default', $databases['default']['default']);

@@ -483,7 +487,7 @@ function simpletest_script_setup_database($new = FALSE) {
  }
  catch (\PDOException $e) {
    simpletest_script_print_error($databases['test-runner']['default']['driver'] . ': ' . $e->getMessage());
    exit(1);
    exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
  }
  if ($new && $sqlite) {
    require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'simpletest') . '/simpletest.install';
@@ -497,7 +501,7 @@ function simpletest_script_setup_database($new = FALSE) {
  // Verify that the Simpletest database schema exists by checking one table.
  if (!$schema->tableExists('simpletest')) {
    simpletest_script_print_error('Missing Simpletest database schema. Either install Simpletest module or use the --sqlite parameter.');
    exit(1);
    exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
  }
}

@@ -507,6 +511,8 @@ function simpletest_script_setup_database($new = FALSE) {
function simpletest_script_execute_batch($test_classes) {
  global $args, $test_ids;

  $total_status = SIMPLETEST_SCRIPT_EXIT_SUCCESS;

  // Multi-process execution.
  $children = array();
  while (!empty($test_classes) || !empty($children)) {
@@ -523,7 +529,10 @@ 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')) {
        simpletest_script_run_phpunit($test_id, $test_class);
        $phpunit_status = simpletest_script_run_phpunit($test_id, $test_class);
        if ($phpunit_status > $total_status) {
          $total_status = $phpunit_status;
        }
        continue;
      }

@@ -533,7 +542,7 @@ function simpletest_script_execute_batch($test_classes) {

      if (!is_resource($process)) {
        echo "Unable to fork test process. Aborting.\n";
        exit;
        exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
      }

      // Register our new child.
@@ -554,7 +563,13 @@ function simpletest_script_execute_batch($test_classes) {
      if (empty($status['running'])) {
        // The child exited, unregister it.
        proc_close($child['process']);
        if ($status['exitcode']) {
        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']);
@@ -575,13 +590,14 @@ function simpletest_script_execute_batch($test_classes) {
      }
    }
  }
  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
@@ -616,6 +632,7 @@ function simpletest_script_run_phpunit($test_id, $class) {
  foreach ($summaries as $class => $summary) {
    simpletest_script_reporter_display_summary($class, $summary);
  }
  return $status;
}

/**
@@ -633,13 +650,16 @@ function simpletest_script_run_one_test($test_id, $test_class) {
    simpletest_script_reporter_display_summary($test_class, $test->results);

    // Finished, kill this runner.
    exit(0);
    if ($test->results['#fail'] || $test->results['#exception']) {
      exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
    }
    exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
  }
  // 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);
  }
}

@@ -785,7 +805,7 @@ function simpletest_script_get_test_list() {
          }
          simpletest_script_print_error('Test class not found: ' . $test_class);
          simpletest_script_print_alternatives($test_class, $all_classes, 6);
          exit(1);
          exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
        }
      }
    }
@@ -794,7 +814,7 @@ function simpletest_script_get_test_list() {
      foreach ($args['test_names'] as $file) {
        if (!file_exists($file)) {
          simpletest_script_print_error('File not found: ' . $file);
          exit;
          exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
        }
        $content = file_get_contents($file);
        // Extract a potential namespace.
@@ -827,7 +847,7 @@ function simpletest_script_get_test_list() {
        else {
          simpletest_script_print_error('Test group not found: ' . $group_name);
          simpletest_script_print_alternatives($group_name, array_keys($groups));
          exit(1);
          exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
        }
      }
    }
@@ -835,7 +855,7 @@ function simpletest_script_get_test_list() {

  if (empty($test_list)) {
    simpletest_script_print_error('No valid tests were specified.');
    exit;
    exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
  }
  return $test_list;
}