? sites/default/modules
? sites/default/settings.php
Index: includes/batch.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/batch.inc,v
retrieving revision 1.27
diff -u -p -r1.27 batch.inc
--- includes/batch.inc	1 Nov 2008 18:32:22 -0000	1.27
+++ includes/batch.inc	6 Nov 2008 08:17:46 -0000
@@ -224,7 +224,9 @@ function _batch_process() {
     // or all sets have been completed.
 
     // If we're in progressive mode, stop after 1 second.
-    if ($batch['progressive'] && timer_read('batch_processing') > 1000) {
+    if ($batch['progressive'] && ($timer = timer_read('batch_processing')) > 1000) {
+      // Accumulate total elapsed time.
+      $current_set['elapsed'] += $timer;
       break;
     }
   }
@@ -250,11 +252,16 @@ function _batch_process() {
 
     $current    = $total - $remaining + $finished;
     $percentage = $total ? floor($current / $total * 100) : 100;
+    $elapsed    = $current_set['elapsed'];
+    // Estimate remaining with percentage in floating format.
+    $estimate   = $elapsed * ($total - $current) / $current;
     $values = array(
       '@remaining'  => $remaining,
       '@total'      => $total,
       '@current'    => floor($current),
       '@percentage' => $percentage,
+      '@elapsed'    => format_interval($elapsed / 1000),
+      '@estimate'   => format_interval($estimate / 1000),
     );
     $message = strtr($progress_message, $values);
     if (!empty($message)) {
@@ -314,7 +321,8 @@ function _batch_finished() {
         include_once DRUPAL_ROOT . '/' . $batch_set['file'];
       }
       if (function_exists($batch_set['finished'])) {
-        $batch_set['finished']($batch_set['success'], $batch_set['results'], $batch_set['operations']);
+        // Format the elapsed time when batch complete.
+        $batch_set['finished']($batch_set['success'], $batch_set['results'], $batch_set['operations'], format_interval($batch_set['elapsed'] / 1000));
       }
     }
   }
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.301
diff -u -p -r1.301 form.inc
--- includes/form.inc	3 Nov 2008 09:54:43 -0000	1.301
+++ includes/form.inc	6 Nov 2008 08:17:47 -0000
@@ -2492,8 +2492,9 @@ function form_clean_id($id = NULL, $flus
  *     'init_message': message displayed while the processing is initialized.
  *       Defaults to t('Initializing.').
  *     'progress_message': message displayed while processing the batch.
- *       Available placeholders are @current, @remaining, @total and @percent.
- *       Defaults to t('Remaining @remaining of @total.').
+ *       Available placeholders are @current, @remaining, @total, @percentage,
+ *       @estimate and @elapsed.
+ *       Defaults to t('Completed @current of @total.').
  *     'error_message': message displayed if an error occurred while processing
  *       the batch.
  *       Defaults to t('An error has occurred.').
@@ -2530,6 +2531,7 @@ function batch_set($batch_definition) {
       'sandbox' => array(),
       'results' => array(),
       'success' => FALSE,
+      'elapsed' => 0,
     );
     // Use get_t() to allow batches at install time.
     $t = get_t();
Index: modules/simpletest/simpletest.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v
retrieving revision 1.26
diff -u -p -r1.26 simpletest.module
--- modules/simpletest/simpletest.module	1 Nov 2008 21:21:35 -0000	1.26
+++ modules/simpletest/simpletest.module	6 Nov 2008 08:17:47 -0000
@@ -426,12 +426,13 @@ function _simpletest_batch_operation($te
   $context['finished'] = 1 - $size / $max;
 }
 
-function _simpletest_batch_finished($success, $results, $operations) {
+function _simpletest_batch_finished($success, $results, $operations, $elapsed) {
   if (isset($results['test_id'])) {
     $_SESSION['test_id'] = $results['test_id'];
   }
   if ($success) {
     drupal_set_message(t('The tests have finished running.'));
+    drupal_set_message(t('Elapsed time: @elapsed.', array('@elapsed' => $elapsed)));
   }
   else {
     drupal_set_message(t('The tests did not successfully finish.'), 'error');
