diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php index 8f03bd5fceb8906249a67354d4069426cabee78f..302a2e86f7e487ff20e24136ac571c89e3b5eddf 100644 --- a/modules/simpletest/drupal_web_test_case.php +++ b/modules/simpletest/drupal_web_test_case.php @@ -137,6 +137,39 @@ protected function assert($status, $message = '', $group = 'Other', array $calle } } + /** + * Make assertions from outside the test case. + * + * @see DrupalTestCase::assert() + */ + public static function assertStatic($test_id, $test_class, $status, $message = '', $group = 'Other', array $caller = NULL) { + // Convert boolean status to string status. + if (is_bool($status)) { + $status = $status ? 'pass' : 'fail'; + } + + $caller += array( + 'function' => t('N/A'), + 'line' => -1, + 'file' => t('N/A'), + ); + + $assertion = array( + 'test_id' => $test_id, + 'test_class' => $test_class, + 'status' => $status, + 'message' => $message, + 'message_group' => $group, + 'function' => $caller['function'], + 'line' => $caller['line'], + 'file' => $caller['file'], + ); + + db_insert('simpletest') + ->fields($assertion) + ->execute(); + } + /** * Cycles through backtrace until the first non-assertion method is found. * @@ -981,7 +1014,12 @@ protected function setUp() { $clean_url_original = variable_get('clean_url', 0); // Generate temporary prefixed database to ensure that tests have a clean starting point. - $db_prefix = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}'); + $db_prefix_new = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}'); + db_update('simpletest_test_id') + ->fields(array('last_prefix' => $db_prefix_new)) + ->condition('test_id', $this->testId) + ->execute(); + $db_prefix = $db_prefix_new; include_once DRUPAL_ROOT . '/includes/install.inc'; drupal_install_system(); @@ -1043,6 +1081,10 @@ protected function setUp() { // Create the files directory. file_check_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); + // Log fatal errors. + ini_set('log_errors', 1); + ini_set('error_log', $directory . '/error.log'); + set_time_limit($this->timeLimit); } diff --git a/modules/simpletest/simpletest.install b/modules/simpletest/simpletest.install index 9adcc3a710e3ff1b69479e4ab2c9b05a6061853e..1a79a7979f79330879f50a28248c2bf7a343a01c 100644 --- a/modules/simpletest/simpletest.install +++ b/modules/simpletest/simpletest.install @@ -229,6 +229,13 @@ function simpletest_schema() { 'description' => 'Primary Key: Unique simpletest ID used to group test results together. Each time a set of tests are run a new test ID is used.', ), + 'last_prefix' => array( + 'type' => 'varchar', + 'length' => 60, + 'not null' => FALSE, + 'default' => '', + 'description' => 'The last database prefix used during testing.', + ), ), 'primary key' => array('test_id'), ); diff --git a/modules/simpletest/simpletest.module b/modules/simpletest/simpletest.module index 4a131db9b3529e7e1d1bdb80e6e87754ee574eb2..496434fe1785411e03d9e0657277d4e16257e8a5 100644 --- a/modules/simpletest/simpletest.module +++ b/modules/simpletest/simpletest.module @@ -191,11 +191,45 @@ function _simpletest_batch_finished($success, $results, $operations, $elapsed) { drupal_set_message(t('The test run finished in @elapsed.', array('@elapsed' => $elapsed))); } else { + // Use the test_id passed as a parameter to _simpletest_batch_operation(). + simpletest_log_read($operations[0][1][1]); + drupal_set_message(t('The test run did not successfully finish.'), 'error'); } module_invoke_all('test_group_finished'); } +/** + * Read the error log and report any errors as assertion failures. + * + * The errors in the log should only be fatal errors since any other errors + * will have been recorded by the error handler. + * + * @param $test_id + * The test ID to read log file for. + */ +function simpletest_log_read($test_id) { + $last_prefix = db_result(db_query('SELECT last_prefix FROM {simpletest_test_id} WHERE test_id = :test_id', array(':test_id' => $test_id))); + $last_prefix = substr($last_prefix, 10); + + $test_class = db_result(db_query('SELECT test_class FROM {simpletest} WHERE test_id = :test_id ORDER BY message_id', array(':test_id' => $test_id))); + $log = file_directory_path() . "/simpletest/$last_prefix/error.log"; + if (file_exists($log)) { + foreach (file($log) as $line) { + if (preg_match('/PHP Fatal error: (.*?) in (.*) on line (\d+)/', $line, $match)) { + $caller = array( + 'line' => $match[3], + 'file' => $match[2], + ); + DrupalTestCase::assertStatic($test_id, $test_class, FALSE, $match[1], 'Fatal error', $caller); + } + else { + DrupalTestCase::assertStatic($test_id, $test_class, FALSE, $line, 'Fatal error'); + } + } + } +} + /** * Get a list of all of the tests provided by the system. * diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index f370d65a79a4e46b4fe8522d10f6388350b0a26a..6de37ae5b94316135599feaae2852d7d1240e692 100755 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -466,6 +466,8 @@ function simpletest_script_reporter_init() { function simpletest_script_reporter_display_results() { global $args, $test_id, $results_map; + simpletest_log_read($test_id); + echo "\n"; $end = timer_stop('run-tests'); echo "Test run duration: " . format_interval($end['time'] / 1000);