Commit cc754301 authored by alexpott's avatar alexpott

Issue #2605290 by sanduhrs, Mile23: Improve docs, coding standards for run-tests.sh

parent fcbf91be
...@@ -17,9 +17,13 @@ ...@@ -17,9 +17,13 @@
$autoloader = require_once __DIR__ . '/../../autoload.php'; $autoloader = require_once __DIR__ . '/../../autoload.php';
const SIMPLETEST_SCRIPT_COLOR_PASS = 32; // Green. // Define some colors for display.
const SIMPLETEST_SCRIPT_COLOR_FAIL = 31; // Red. // A nice calming green.
const SIMPLETEST_SCRIPT_COLOR_EXCEPTION = 33; // Brown. const SIMPLETEST_SCRIPT_COLOR_PASS = 32;
// An alerting Red.
const SIMPLETEST_SCRIPT_COLOR_FAIL = 31;
// An annoying brown.
const SIMPLETEST_SCRIPT_COLOR_EXCEPTION = 33;
// Restricting the chunk of queries prevents memory exhaustion. // Restricting the chunk of queries prevents memory exhaustion.
const SIMPLETEST_SCRIPT_SQLITE_VARIABLE_LIMIT = 350; const SIMPLETEST_SCRIPT_SQLITE_VARIABLE_LIMIT = 350;
...@@ -58,7 +62,7 @@ ...@@ -58,7 +62,7 @@
if ($args['list']) { if ($args['list']) {
// Display all available tests. // Display all available tests.
echo "\nAvailable test groups & classes\n"; echo "\nAvailable test groups & classes\n";
echo "-------------------------------\n\n"; echo "-------------------------------\n\n";
try { try {
$groups = simpletest_test_get_all($args['module']); $groups = simpletest_test_get_all($args['module']);
} }
...@@ -268,7 +272,8 @@ function simpletest_script_help() { ...@@ -268,7 +272,8 @@ function simpletest_script_help() {
/** /**
* Parse execution argument and ensure that all are valid. * Parse execution argument and ensure that all are valid.
* *
* @return The list of arguments. * @return array
* The list of arguments.
*/ */
function simpletest_script_parse_args() { function simpletest_script_parse_args() {
// Set default values. // Set default values.
...@@ -334,7 +339,7 @@ function simpletest_script_parse_args() { ...@@ -334,7 +339,7 @@ function simpletest_script_parse_args() {
} }
} }
// Validate the concurrency argument // Validate the concurrency argument.
if (!is_numeric($args['concurrency']) || $args['concurrency'] <= 0) { if (!is_numeric($args['concurrency']) || $args['concurrency'] <= 0) {
simpletest_script_print_error("--concurrency must be a strictly positive integer."); simpletest_script_print_error("--concurrency must be a strictly positive integer.");
exit(SIMPLETEST_SCRIPT_EXIT_FAILURE); exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
...@@ -356,18 +361,20 @@ function simpletest_script_init() { ...@@ -356,18 +361,20 @@ function simpletest_script_init() {
$path = ''; $path = '';
$port = '80'; $port = '80';
// Determine location of php command automatically, unless a command line argument is supplied. // Determine location of php command automatically, unless a command line
// argument is supplied.
if (!empty($args['php'])) { if (!empty($args['php'])) {
$php = $args['php']; $php = $args['php'];
} }
elseif ($php_env = getenv('_')) { elseif ($php_env = getenv('_')) {
// '_' is an environment variable set by the shell. It contains the command that was executed. // '_' is an environment variable set by the shell. It contains the command
// that was executed.
$php = $php_env; $php = $php_env;
} }
elseif ($sudo = getenv('SUDO_COMMAND')) { elseif ($sudo = getenv('SUDO_COMMAND')) {
// 'SUDO_COMMAND' is an environment variable set by the sudo program. // 'SUDO_COMMAND' is an environment variable set by the sudo program.
// Extract only the PHP interpreter, not the rest of the command. // Extract only the PHP interpreter, not the rest of the command.
list($php, ) = explode(' ', $sudo, 2); list($php) = explode(' ', $sudo, 2);
} }
else { else {
simpletest_script_print_error('Unable to automatically determine the path to the PHP interpreter. Supply the --php command line argument.'); simpletest_script_print_error('Unable to automatically determine the path to the PHP interpreter. Supply the --php command line argument.');
...@@ -408,11 +415,11 @@ function simpletest_script_init() { ...@@ -408,11 +415,11 @@ function simpletest_script_init() {
$_SERVER['SERVER_PORT'] = $port; $_SERVER['SERVER_PORT'] = $port;
$_SERVER['SERVER_SOFTWARE'] = NULL; $_SERVER['SERVER_SOFTWARE'] = NULL;
$_SERVER['SERVER_NAME'] = 'localhost'; $_SERVER['SERVER_NAME'] = 'localhost';
$_SERVER['REQUEST_URI'] = $path .'/'; $_SERVER['REQUEST_URI'] = $path . '/';
$_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['SCRIPT_NAME'] = $path .'/index.php'; $_SERVER['SCRIPT_NAME'] = $path . '/index.php';
$_SERVER['SCRIPT_FILENAME'] = $path .'/index.php'; $_SERVER['SCRIPT_FILENAME'] = $path . '/index.php';
$_SERVER['PHP_SELF'] = $path .'/index.php'; $_SERVER['PHP_SELF'] = $path . '/index.php';
$_SERVER['HTTP_USER_AGENT'] = 'Drupal command line'; $_SERVER['HTTP_USER_AGENT'] = 'Drupal command line';
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') { if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
...@@ -459,7 +466,6 @@ function simpletest_script_setup_database($new = FALSE) { ...@@ -459,7 +466,6 @@ function simpletest_script_setup_database($new = FALSE) {
// hold the default database connection already. This connection is assumed to // hold the default database connection already. This connection is assumed to
// be valid, and this connection will be used in tests, so that they run // be valid, and this connection will be used in tests, so that they run
// against e.g. MySQL instead of SQLite. // against e.g. MySQL instead of SQLite.
// However, in case no Drupal installation exists, this default database // However, in case no Drupal installation exists, this default database
// connection can be set and/or overridden with the --dburl parameter. // connection can be set and/or overridden with the --dburl parameter.
if (!empty($args['dburl'])) { if (!empty($args['dburl'])) {
...@@ -619,12 +625,15 @@ function simpletest_script_execute_batch($test_classes) { ...@@ -619,12 +625,15 @@ function simpletest_script_execute_batch($test_classes) {
echo $message . "\n"; echo $message . "\n";
// Insert a fail for xml results. // Insert a fail for xml results.
TestBase::insertAssert($child['test_id'], $child['class'], FALSE, $message, 'run-tests.sh check'); TestBase::insertAssert($child['test_id'], $child['class'], FALSE, $message, 'run-tests.sh check');
/// Ensure that an error line is displayed for the class. // Ensure that an error line is displayed for the class.
simpletest_script_reporter_display_summary($child['class'], ['#pass' => 0, '#fail' => 1, '#exception' => 0, '#debug' => 0]); simpletest_script_reporter_display_summary(
$child['class'],
['#pass' => 0, '#fail' => 1, '#exception' => 0, '#debug' => 0]
);
if ($args['die-on-fail']) { if ($args['die-on-fail']) {
list($db_prefix, ) = simpletest_last_test_get($child['test_id']); list($db_prefix) = simpletest_last_test_get($child['test_id']);
$test_directory = 'sites/simpletest/' . substr($db_prefix, 10); $test_directory = 'sites/simpletest/' . substr($db_prefix, 10);
echo 'Simpletest database and files kept and test exited immediately on fail so should be reproducible if you change settings.php to use the database prefix '. $db_prefix . ' and config directories in '. $test_directory . "\n"; echo 'Simpletest database and files kept and test exited immediately on fail so should be reproducible if you change settings.php to use the database prefix ' . $db_prefix . ' and config directories in ' . $test_directory . "\n";
$args['keep-results'] = TRUE; $args['keep-results'] = TRUE;
// Exit repeat loop immediately. // Exit repeat loop immediately.
$args['repeat'] = -1; $args['repeat'] = -1;
...@@ -644,7 +653,7 @@ function simpletest_script_execute_batch($test_classes) { ...@@ -644,7 +653,7 @@ function simpletest_script_execute_batch($test_classes) {
} }
/** /**
* Run a group of phpunit tests. * Run a PHPUnit-based test.
*/ */
function simpletest_script_run_phpunit($test_id, $class) { function simpletest_script_run_phpunit($test_id, $class) {
$reflection = new \ReflectionClass($class); $reflection = new \ReflectionClass($class);
...@@ -672,12 +681,15 @@ function simpletest_script_run_phpunit($test_id, $class) { ...@@ -672,12 +681,15 @@ function simpletest_script_run_phpunit($test_id, $class) {
case 'pass': case 'pass':
$summaries[$result['test_class']]['#pass']++; $summaries[$result['test_class']]['#pass']++;
break; break;
case 'fail': case 'fail':
$summaries[$result['test_class']]['#fail']++; $summaries[$result['test_class']]['#fail']++;
break; break;
case 'exception': case 'exception':
$summaries[$result['test_class']]['#exception']++; $summaries[$result['test_class']]['#exception']++;
break; break;
case 'debug': case 'debug':
$summaries[$result['test_class']]['#debug']++; $summaries[$result['test_class']]['#debug']++;
break; break;
...@@ -691,7 +703,7 @@ function simpletest_script_run_phpunit($test_id, $class) { ...@@ -691,7 +703,7 @@ function simpletest_script_run_phpunit($test_id, $class) {
} }
/** /**
* Bootstrap Drupal and run a single test. * Run a single test, bootstrapping Drupal if needed.
*/ */
function simpletest_script_run_one_test($test_id, $test_class) { function simpletest_script_run_one_test($test_id, $test_class) {
global $args; global $args;
...@@ -736,10 +748,13 @@ function simpletest_script_run_one_test($test_id, $test_class) { ...@@ -736,10 +748,13 @@ function simpletest_script_run_one_test($test_id, $test_class) {
/** /**
* Return a command used to run a test in a separate process. * Return a command used to run a test in a separate process.
* *
* @param $test_id * @param int $test_id
* The current test ID. * The current test ID.
* @param $test_class * @param string $test_class
* The name of the test class to run. * The name of the test class to run.
*
* @return string
* The assembled command string.
*/ */
function simpletest_script_command($test_id, $test_class) { function simpletest_script_command($test_id, $test_class) {
global $args, $php; global $args, $php;
...@@ -792,7 +807,7 @@ function simpletest_script_cleanup($test_id, $test_class, $exitcode) { ...@@ -792,7 +807,7 @@ function simpletest_script_cleanup($test_id, $test_class, $exitcode) {
} }
// Retrieve the last database prefix used for testing. // Retrieve the last database prefix used for testing.
try { try {
list($db_prefix,) = simpletest_last_test_get($test_id); list($db_prefix) = simpletest_last_test_get($test_id);
} }
catch (Exception $e) { catch (Exception $e) {
echo (string) $e; echo (string) $e;
...@@ -864,12 +879,13 @@ function simpletest_script_cleanup($test_id, $test_class, $exitcode) { ...@@ -864,12 +879,13 @@ function simpletest_script_cleanup($test_id, $test_class, $exitcode) {
} }
/** /**
* Get list of tests based on arguments. If --all specified then * Get list of tests based on arguments.
* returns all available tests, otherwise reads list of tests.
* *
* Will print error and exit if no valid tests were found. * If --all specified then return all available tests, otherwise reads list of
* tests.
* *
* @return List of tests. * @return array
* List of tests.
*/ */
function simpletest_script_get_test_list() { function simpletest_script_get_test_list() {
global $args; global $args;
...@@ -893,7 +909,7 @@ function simpletest_script_get_test_list() { ...@@ -893,7 +909,7 @@ function simpletest_script_get_test_list() {
if ($args['class']) { if ($args['class']) {
$test_list = array(); $test_list = array();
foreach ($args['test_names'] as $test_class) { foreach ($args['test_names'] as $test_class) {
list($class_name, ) = explode('::', $test_class, 2); list($class_name) = explode('::', $test_class, 2);
if (class_exists($class_name)) { if (class_exists($class_name)) {
$test_list[] = $test_class; $test_list[] = $test_class;
} }
...@@ -964,13 +980,13 @@ function simpletest_script_get_test_list() { ...@@ -964,13 +980,13 @@ function simpletest_script_get_test_list() {
// '/Tests/' can be contained anywhere in the file's path (there can be // '/Tests/' can be contained anywhere in the file's path (there can be
// sub-directories below /Tests), but must be contained literally. // sub-directories below /Tests), but must be contained literally.
// Case-insensitive to match all Simpletest and PHPUnit tests: // Case-insensitive to match all Simpletest and PHPUnit tests:
// ./lib/Drupal/foo/Tests/Bar/Baz.php // ./lib/Drupal/foo/Tests/Bar/Baz.php
// ./foo/src/Tests/Bar/Baz.php // ./foo/src/Tests/Bar/Baz.php
// ./foo/tests/Drupal/foo/Tests/FooTest.php // ./foo/tests/Drupal/foo/Tests/FooTest.php
// ./foo/tests/src/FooTest.php // ./foo/tests/src/FooTest.php
// $file->filename doesn't give us a directory, so we use $file->uri // $file->filename doesn't give us a directory, so we use $file->uri
// Strip the drupal root directory and trailing slash off the URI // Strip the drupal root directory and trailing slash off the URI.
$filename = substr($file->uri, strlen(DRUPAL_ROOT)+1); $filename = substr($file->uri, strlen(DRUPAL_ROOT) + 1);
if (stripos($filename, '/Tests/')) { if (stripos($filename, '/Tests/')) {
$files[$filename] = $filename; $files[$filename] = $filename;
} }
...@@ -1035,7 +1051,7 @@ function simpletest_script_reporter_init() { ...@@ -1035,7 +1051,7 @@ function simpletest_script_reporter_init() {
$results_map = array( $results_map = array(
'pass' => 'Pass', 'pass' => 'Pass',
'fail' => 'Fail', 'fail' => 'Fail',
'exception' => 'Exception' 'exception' => 'Exception',
); );
echo "\n"; echo "\n";
...@@ -1079,10 +1095,10 @@ function simpletest_script_reporter_display_summary($class, $results) { ...@@ -1079,10 +1095,10 @@ function simpletest_script_reporter_display_summary($class, $results) {
// by default (more than 999 assertions are rare). // by default (more than 999 assertions are rare).
$output = vsprintf('%-60.60s %10s %9s %14s %12s', array( $output = vsprintf('%-60.60s %10s %9s %14s %12s', array(
$class, $class,
$results['#pass'] . ' passes', $results['#pass'] . ' passes',
!$results['#fail'] ? '' : $results['#fail'] . ' fails', !$results['#fail'] ? '' : $results['#fail'] . ' fails',
!$results['#exception'] ? '' : $results['#exception'] . ' exceptions', !$results['#exception'] ? '' : $results['#exception'] . ' exceptions',
!$results['#debug'] ? '' : $results['#debug'] . ' messages', !$results['#debug'] ? '' : $results['#debug'] . ' messages',
)); ));
$status = ($results['#fail'] || $results['#exception'] ? 'fail' : 'pass'); $status = ($results['#fail'] || $results['#exception'] ? 'fail' : 'pass');
...@@ -1109,7 +1125,8 @@ function simpletest_script_reporter_write_xml_results() { ...@@ -1109,7 +1125,8 @@ function simpletest_script_reporter_write_xml_results() {
foreach ($results as $result) { foreach ($results as $result) {
if (isset($results_map[$result->status])) { if (isset($results_map[$result->status])) {
if ($result->test_class != $test_class) { if ($result->test_class != $test_class) {
// We've moved onto a new class, so write the last classes results to a file: // We've moved onto a new class, so write the last classes results to a
// file:
if (isset($xml_files[$test_class])) { if (isset($xml_files[$test_class])) {
file_put_contents($args['xml'] . '/' . str_replace('\\', '_', $test_class) . '.xml', $xml_files[$test_class]['doc']->saveXML()); file_put_contents($args['xml'] . '/' . str_replace('\\', '_', $test_class) . '.xml', $xml_files[$test_class]['doc']->saveXML());
unset($xml_files[$test_class]); unset($xml_files[$test_class]);
...@@ -1137,7 +1154,8 @@ function simpletest_script_reporter_write_xml_results() { ...@@ -1137,7 +1154,8 @@ function simpletest_script_reporter_write_xml_results() {
} }
$case->setAttribute('name', $name); $case->setAttribute('name', $name);
// Passes get no further attention, but failures and exceptions get to add more detail: // Passes get no further attention, but failures and exceptions get to add
// more detail:
if ($result->status == 'fail') { if ($result->status == 'fail') {
$fail = $dom_document->createElement('failure'); $fail = $dom_document->createElement('failure');
$fail->setAttribute('type', 'failure'); $fail->setAttribute('type', 'failure');
...@@ -1218,10 +1236,10 @@ function simpletest_script_reporter_display_results() { ...@@ -1218,10 +1236,10 @@ function simpletest_script_reporter_display_results() {
} }
/** /**
* Format the result so that it fits within the default 80 character * Format the result so that it fits within 80 characters.
* terminal size.
* *
* @param $result The result object to format. * @param object $result
* The result object to format.
*/ */
function simpletest_script_format_result($result) { function simpletest_script_format_result($result) {
global $args, $results_map, $color; global $args, $results_map, $color;
...@@ -1242,21 +1260,25 @@ function simpletest_script_format_result($result) { ...@@ -1242,21 +1260,25 @@ function simpletest_script_format_result($result) {
} }
/** /**
* Print error message prefixed with " ERROR: " and displayed in fail color * Print error messages so the user will notice them.
* if color output is enabled.
* *
* @param $message The message to print. * Print error message prefixed with " ERROR: " and displayed in fail color if
* color output is enabled.
*
* @param string $message
* The message to print.
*/ */
function simpletest_script_print_error($message) { function simpletest_script_print_error($message) {
simpletest_script_print(" ERROR: $message\n", SIMPLETEST_SCRIPT_COLOR_FAIL); simpletest_script_print(" ERROR: $message\n", SIMPLETEST_SCRIPT_COLOR_FAIL);
} }
/** /**
* Print a message to the console, if color is enabled then the specified * Print a message to the console, using a color.
* color code will be used.
* *
* @param $message The message to print. * @param string $message
* @param $color_code The color code to use for coloring. * The message to print.
* @param int $color_code
* The color code to use for coloring.
*/ */
function simpletest_script_print($message, $color_code) { function simpletest_script_print($message, $color_code) {
global $args; global $args;
...@@ -1271,19 +1293,26 @@ function simpletest_script_print($message, $color_code) { ...@@ -1271,19 +1293,26 @@ function simpletest_script_print($message, $color_code) {
/** /**
* Get the color code associated with the specified status. * Get the color code associated with the specified status.
* *
* @param $status The status string to get code for. * @param string $status
* @return Color code. * The status string to get code for. Special cases are: 'pass', 'fail', or
* 'exception'.
*
* @return int
* Color code. Returns 0 for default case.
*/ */
function simpletest_script_color_code($status) { function simpletest_script_color_code($status) {
switch ($status) { switch ($status) {
case 'pass': case 'pass':
return SIMPLETEST_SCRIPT_COLOR_PASS; return SIMPLETEST_SCRIPT_COLOR_PASS;
case 'fail': case 'fail':
return SIMPLETEST_SCRIPT_COLOR_FAIL; return SIMPLETEST_SCRIPT_COLOR_FAIL;
case 'exception': case 'exception':
return SIMPLETEST_SCRIPT_COLOR_EXCEPTION; return SIMPLETEST_SCRIPT_COLOR_EXCEPTION;
} }
return 0; // Default formatting. // Default formatting.
return 0;
} }
/** /**
...@@ -1292,8 +1321,6 @@ function simpletest_script_color_code($status) { ...@@ -1292,8 +1321,6 @@ function simpletest_script_color_code($status) {
* Searches the provided array of string values for close matches based on the * Searches the provided array of string values for close matches based on the
* Levenshtein algorithm. * Levenshtein algorithm.
* *
* @see http://php.net/manual/en/function.levenshtein.php
*
* @param string $string * @param string $string
* A string to test. * A string to test.
* @param array $array * @param array $array
...@@ -1303,6 +1330,8 @@ function simpletest_script_color_code($status) { ...@@ -1303,6 +1330,8 @@ function simpletest_script_color_code($status) {
* 4 means that the function will return strings from $array if the candidate * 4 means that the function will return strings from $array if the candidate
* string in $array would be identical to $string by changing 1/4 or fewer of * string in $array would be identical to $string by changing 1/4 or fewer of
* its characters. * its characters.
*
* @see http://php.net/manual/en/function.levenshtein.php
*/ */
function simpletest_script_print_alternatives($string, $array, $degree = 4) { function simpletest_script_print_alternatives($string, $array, $degree = 4) {
$alternatives = array(); $alternatives = array();
...@@ -1391,7 +1420,11 @@ function simpletest_script_open_browser() { ...@@ -1391,7 +1420,11 @@ function simpletest_script_open_browser() {
// Get the assets to make the details element collapsible and theme the result // Get the assets to make the details element collapsible and theme the result
// form. // form.
$assets = new \Drupal\Core\Asset\AttachedAssets(); $assets = new \Drupal\Core\Asset\AttachedAssets();
$assets->setLibraries(['core/drupal.collapse', 'system/admin', 'simpletest/drupal.simpletest']); $assets->setLibraries([
'core/drupal.collapse',
'system/admin',
'simpletest/drupal.simpletest',
]);
$resolver = \Drupal::service('asset.resolver'); $resolver = \Drupal::service('asset.resolver');
list($js_assets_header, $js_assets_footer) = $resolver->getJsAssets($assets, FALSE); list($js_assets_header, $js_assets_footer) = $resolver->getJsAssets($assets, FALSE);
$js_collection_renderer = \Drupal::service('asset.js.collection_renderer'); $js_collection_renderer = \Drupal::service('asset.js.collection_renderer');
...@@ -1401,14 +1434,14 @@ function simpletest_script_open_browser() { ...@@ -1401,14 +1434,14 @@ function simpletest_script_open_browser() {
// Make the html page to write to disk. // Make the html page to write to disk.
$render_service = \Drupal::service('renderer'); $render_service = \Drupal::service('renderer');
$html = '<head>' . $render_service->renderPlain($js_assets_header) . $render_service->renderPlain($css_assets) . '</head><body>' . $render_service->renderPlain($form) . $render_service->renderPlain($js_assets_footer) .'</body>'; $html = '<head>' . $render_service->renderPlain($js_assets_header) . $render_service->renderPlain($css_assets) . '</head><body>' . $render_service->renderPlain($form) . $render_service->renderPlain($js_assets_footer) . '</body>';
// Ensure we have assets verbose directory - tests with no verbose output will not // Ensure we have assets verbose directory - tests with no verbose output will
// have created one. // not have created one.
$directory = PublicStream::basePath() . '/simpletest/verbose'; $directory = PublicStream::basePath() . '/simpletest/verbose';
file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
$uuid = new Php(); $uuid = new Php();
$filename = $directory .'/results-'. $uuid->generate() .'.html'; $filename = $directory . '/results-' . $uuid->generate() . '.html';
file_put_contents($filename, $html); file_put_contents($filename, $html);
// See if we can find an OS helper to open URLs in default browser. // See if we can find an OS helper to open URLs in default browser.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment