Index: index.php
===================================================================
RCS file: /cvs/drupal/drupal/index.php,v
retrieving revision 1.98
diff -u -r1.98 index.php
--- index.php	8 Feb 2009 20:27:51 -0000	1.98
+++ index.php	11 Jul 2009 02:21:20 -0000
@@ -19,6 +19,13 @@
 
 require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
+
+if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^simpletest\d+$/", $_SERVER['HTTP_USER_AGENT'])) {
+  // Log fatal errors.
+  ini_set('log_errors', 1);
+  ini_set('error_log', file_directory_path() . '/error.log');
+}
+
 $return = menu_execute_active_handler();
 
 // Menu status constants are integers; page content is a string or array.
Index: scripts/run-tests.sh
===================================================================
RCS file: /cvs/drupal/drupal/scripts/run-tests.sh,v
retrieving revision 1.29
diff -u -r1.29 run-tests.sh
--- scripts/run-tests.sh	7 Jul 2009 07:50:53 -0000	1.29
+++ scripts/run-tests.sh	11 Jul 2009 02:21:21 -0000
@@ -83,6 +83,11 @@
 // Execute tests.
 simpletest_script_command($args['concurrency'], $test_id, implode(",", $test_list));
 
+if (simpletest_log_read($test_id)) {
+  // TODO
+  // simpletest_script_print($info['name'] . ' ' . _simpletest_format_summary_line($test->results) . "\n", simpletest_script_color_code($status));
+}
+
 // Display results before database is cleared.
 simpletest_script_reporter_display_results();
 
@@ -466,8 +471,6 @@
 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);
Index: modules/simpletest/simpletest.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v
retrieving revision 1.60
diff -u -r1.60 simpletest.module
--- modules/simpletest/simpletest.module	7 Jul 2009 08:07:24 -0000	1.60
+++ modules/simpletest/simpletest.module	11 Jul 2009 02:21:21 -0000
@@ -219,6 +219,8 @@
  *
  * @param $test_id
  *   The test ID to read log file for.
+ * @return
+ *   Found any entries in log.
  */
 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)));
@@ -226,6 +228,7 @@
 
   $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";
+  $found = FALSE;
   if (file_exists($log)) {
     foreach (file($log) as $line) {
       if (preg_match('/PHP Fatal error: (.*?) in (.*) on line (\d+)/', $line, $match)) {
@@ -233,13 +236,15 @@
           'line' => $match[3],
           'file' => $match[2],
         );
-        DrupalTestCase::assertStatic($test_id, $test_class, FALSE, $match[1], 'Fatal error', $caller);
+        DrupalTestCase::insertAssert($test_id, $test_class, FALSE, $match[1], 'Fatal error', $caller);
       }
       else {
-        DrupalTestCase::assertStatic($test_id, $test_class, FALSE, $line, 'Fatal error');
+        DrupalTestCase::insertAssert($test_id, $test_class, FALSE, $line, 'Fatal error');
       }
+      $found = TRUE;
     }
   }
+  return $found;
 }
 
 /**
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.123
diff -u -r1.123 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	8 Jul 2009 07:23:23 -0000	1.123
+++ modules/simpletest/drupal_web_test_case.php	11 Jul 2009 02:21:21 -0000
@@ -138,20 +138,27 @@
   }
 
   /**
-   * Make assertions from outside the test case.
+   * Store an assertion from outside the testing context.
+   *
+   * This is useful for inserting assertions that can only be recorded after
+   * the test case has been destroyed, such as PHP fatal errors. The caller
+   * information is not automatically gathered since the caller is most likely
+   * inserting the assertion on behalf of other code. In all other respects
+   * the method behaves just like DrupalTestCase::assert() in terms of storing
+   * the assertion.
    *
    * @see DrupalTestCase::assert()
    */
-  public static function assertStatic($test_id, $test_class, $status, $message = '', $group = 'Other', array $caller = NULL) {
+  public static function insertAssert($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'),
+      'function' => t('Unknown'),
       'line' => -1,
-      'file' => t('N/A'),
+      'file' => t('Unknown'),
     );
 
     $assertion = array(
@@ -1130,6 +1137,16 @@
   protected function tearDown() {
     global $db_prefix, $user, $language;
 
+    $file_directory_temp = file_directory_path();
+    variable_set('file_directory_path', $this->originalFileDirectory);
+
+    $db_prefix_temp = $db_prefix;
+    $db_prefix = $this->originalPrefix;
+    simpletest_log_read($this->testId);
+    $db_prefix = $db_prefix_temp;
+
+    variable_set('file_directory_path', $file_directory_temp);
+
     $emailCount = count(variable_get('simpletest_emails', array()));
     if ($emailCount) {
       $message = format_plural($emailCount, t('!count e-mail was sent during this test.'), t('!count e-mails were sent during this test.'), array('!count' => $emailCount));
Index: modules/block/block.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.test,v
retrieving revision 1.20
diff -u -r1.20 block.test
--- modules/block/block.test	8 Jun 2009 09:23:50 -0000	1.20
+++ modules/block/block.test	11 Jul 2009 02:21:20 -0000
@@ -44,6 +44,8 @@
     $box['body'] = $this->randomName(32);
     $this->drupalPost('admin/build/block/add', $box, t('Save block'));
 
+    death();
+
     // Confirm that the box has been created, and then query the created bid.
     $this->assertText(t('The block has been created.'), t('Box successfully created.'));
     $bid = db_query("SELECT bid FROM {box} WHERE info = :info", array(':info' => $box['info']))->fetchField();
@@ -234,7 +236,7 @@
       'group' => t('Block'),
     );
   }
-  
+
   /**
    * Check the enabled Garland blocks are correctly copied over.
    */
@@ -278,7 +280,7 @@
       'group' => t('Block'),
     );
   }
-  
+
   /**
    * Check for the accessibility of the admin theme on the  block admin page.
    */
Index: modules/block/block.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v
retrieving revision 1.44
diff -u -r1.44 block.admin.inc
--- modules/block/block.admin.inc	1 Jul 2009 08:04:19 -0000	1.44
+++ modules/block/block.admin.inc	11 Jul 2009 02:21:20 -0000
@@ -15,6 +15,8 @@
   // If non-default theme configuration has been selected, set the custom theme.
   $custom_theme = isset($theme) ? $theme : variable_get('theme_default', 'garland');
 
+  boom();
+
   // Fetch and sort blocks.
   $blocks = _block_rehash();
   usort($blocks, '_block_compare');
@@ -392,12 +394,12 @@
         'visibility' => (int) $form_state['values']['visibility'],
         'pages' => trim($form_state['values']['pages']),
         'custom' => (int) $form_state['values']['custom'],
-        'title' => $form_state['values']['title'], 
+        'title' => $form_state['values']['title'],
         'module' => $form_state['values']['module'],
-        'theme' => $theme->name, 
+        'theme' => $theme->name,
         'status' => 0,
         'weight' => 0,
-        'delta' => $delta, 
+        'delta' => $delta,
         'cache' => BLOCK_NO_CACHE,
       ));
     }
