Newer
Older
<?php

Angie Byron
committed
/**
* @file
* This script runs Drupal tests from command line.
*/
use Drupal\Component\FileSystem\FileSystem;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Timer;
use Drupal\Component\Uuid\Php;

Lee Rowlands
committed
use Drupal\Core\Asset\AttachedAssets;

Angie Byron
committed
use Drupal\Core\Database\Database;
use Drupal\Core\File\Exception\FileException;

Alex Pott
committed
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\StreamWrapper\PublicStream;

catch
committed
use Drupal\Core\Test\TestDatabase;
use Drupal\Core\Test\TestRunnerKernel;
use Drupal\simpletest\Form\SimpletestResultsForm;
use Drupal\simpletest\TestBase;
use Drupal\simpletest\TestDiscovery;

Alex Pott
committed
use PHPUnit\Framework\TestCase;
use PHPUnit\Runner\Version;

Angie Byron
committed
use Symfony\Component\HttpFoundation\Request;

Alex Pott
committed
// Define some colors for display.
// A nice calming green.
const SIMPLETEST_SCRIPT_COLOR_PASS = 32;
// An alerting Red.
const SIMPLETEST_SCRIPT_COLOR_FAIL = 31;
// An annoying brown.
const SIMPLETEST_SCRIPT_COLOR_EXCEPTION = 33;

Angie Byron
committed
// Restricting the chunk of queries prevents memory exhaustion.
const SIMPLETEST_SCRIPT_SQLITE_VARIABLE_LIMIT = 350;

Dries Buytaert
committed
const SIMPLETEST_SCRIPT_EXIT_SUCCESS = 0;
const SIMPLETEST_SCRIPT_EXIT_FAILURE = 1;
const SIMPLETEST_SCRIPT_EXIT_EXCEPTION = 2;

Dries Buytaert
committed
// Set defaults and get overrides.
list($args, $count) = simpletest_script_parse_args();
if ($args['help'] || $count == 0) {
simpletest_script_help();
exit(($count == 0) ? SIMPLETEST_SCRIPT_EXIT_FAILURE : SIMPLETEST_SCRIPT_EXIT_SUCCESS);

Dries Buytaert
committed
}

Angie Byron
committed
simpletest_script_init();
if (!class_exists(TestCase::class)) {

Alex Pott
committed
echo "\nrun-tests.sh requires the PHPUnit testing framework. Please use 'composer install' to ensure that it is present.\n\n";
exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
}

Angie Byron
committed

Angie Byron
committed
if ($args['execute-test']) {

Angie Byron
committed
simpletest_script_setup_database();

Angie Byron
committed
simpletest_script_run_one_test($args['test-id'], $args['execute-test']);

Angie Byron
committed
// Sub-process exited already; this is just for clarity.
exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);

Dries Buytaert
committed
}

Angie Byron
committed
if ($args['list']) {

Alex Pott
committed
// Display all available tests organized by one @group annotation.
echo "\nAvailable test groups & classes\n";

Alex Pott
committed
echo "-------------------------------\n\n";
try {
$groups = \Drupal::service('test_discovery')->getTestClasses($args['module']);
}
catch (Exception $e) {

Alex Pott
committed
error_log((string) $e);
echo (string) $e;
exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
}

Alex Pott
committed
// A given class can appear in multiple groups. For historical reasons, we
// need to present each test only once. The test is shown in the group that is
// printed first.
$printed_tests = [];
foreach ($groups as $group => $tests) {
echo $group . "\n";

Alex Pott
committed
$tests = array_diff(array_keys($tests), $printed_tests);
foreach ($tests as $test) {
echo " - $test\n";
}

Alex Pott
committed
$printed_tests = array_merge($printed_tests, $tests);
}
exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
}

Alex Pott
committed
// List-files and list-files-json provide a way for external tools such as the
// testbot to prioritize running changed tests.
// @see https://www.drupal.org/node/2569585
if ($args['list-files'] || $args['list-files-json']) {
// List all files which could be run as tests.
$test_discovery = NULL;
try {
$test_discovery = \Drupal::service('test_discovery');

Lee Rowlands
committed
}
catch (Exception $e) {

Alex Pott
committed
error_log((string) $e);

Lee Rowlands
committed
echo (string) $e;

Alex Pott
committed
exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
}
// TestDiscovery::findAllClassFiles() gives us a classmap similar to a
// Composer 'classmap' array.
$test_classes = $test_discovery->findAllClassFiles();
// JSON output is the easiest.
if ($args['list-files-json']) {
echo json_encode($test_classes);
exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
}
// Output the list of files.
else {

Lee Rowlands
committed
foreach (array_values($test_classes) as $test_class) {

Alex Pott
committed
echo $test_class . "\n";
}
}
exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
}

Angie Byron
committed
simpletest_script_setup_database(TRUE);

Dries Buytaert
committed
if ($args['clean']) {

Angie Byron
committed
// Clean up left-over tables and directories.
try {
simpletest_clean_environment();
}
catch (Exception $e) {
echo (string) $e;
exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
}

Dries Buytaert
committed
echo "\nEnvironment cleaned.\n";
// Get the status messages and print them.
$messages = \Drupal::messenger()->messagesByType('status');
foreach ($messages as $text) {

Dries Buytaert
committed
echo " - " . $text . "\n";
}
exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);

Dries Buytaert
committed
}
// Ensure we have the correct PHPUnit version for the version of PHP.
if (class_exists('\PHPUnit_Runner_Version')) {
$phpunit_version = \PHPUnit_Runner_Version::id();
}
else {
$phpunit_version = Version::id();
}

Dries Buytaert
committed
$test_list = simpletest_script_get_test_list();
// Try to allocate unlimited time to run the tests.
drupal_set_time_limit(0);

Dries Buytaert
committed
simpletest_script_reporter_init();

Lee Rowlands
committed
$tests_to_run = [];
for ($i = 0; $i < $args['repeat']; $i++) {

Dries Buytaert
committed
$tests_to_run = array_merge($tests_to_run, $test_list);

Angie Byron
committed
}

Dries Buytaert
committed

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

Dries Buytaert
committed

Dries Buytaert
committed
// Stop the timer.
simpletest_script_reporter_timer_stop();

catch
committed
// Ensure all test locks are released once finished. If tests are run with a
// concurrency of 1 the each test will clean up its own lock. Test locks are

catch
committed
// not released if using a higher concurrency to ensure each test method has
// unique fixtures.
TestDatabase::releaseAllTestLocks();

Dries Buytaert
committed
// Display results before database is cleared.
if ($args['browser']) {
simpletest_script_open_browser();
}
else {
simpletest_script_reporter_display_results();
}

Dries Buytaert
committed

Dries Buytaert
committed
if ($args['xml']) {
simpletest_script_reporter_write_xml_results();
}

Dries Buytaert
committed
// Clean up all test results.
if (!$args['keep-results']) {
try {
simpletest_clean_results_table();
}
catch (Exception $e) {
echo (string) $e;
exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
}
}

Dries Buytaert
committed

Angie Byron
committed
// Test complete, exit.
exit($status);

Angie Byron
committed
Loading
Loading full blame...