Index: pifr.review.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/pifr.review.inc,v
retrieving revision 1.18
diff -u -r1.18 pifr.review.inc
--- pifr.review.inc	9 Dec 2008 04:03:17 -0000	1.18
+++ pifr.review.inc	9 Dec 2008 05:43:46 -0000
@@ -331,6 +331,7 @@
  */
 function pifr_review_format_results($results) {
   if (preg_match_all('/^(.*?) (\d+) passes, (\d+) fails, and (\d+) exceptions$/m', $results, $matches, PREG_SET_ORDER)) {
+    $results = array('pass' => 0, 'fail' => 0, 'exception' => 0);
     $xml = new SimpleXMLElement('<results />');
     $classes = $xml->addChild('classes');
     foreach ($matches as $match) {
@@ -341,7 +342,17 @@
       $class->addChild('pass', $match[2]);
       $class->addChild('fail', $match[3]);
       $class->addChild('exception', $match[4]);
+
+      // Add to results count array.
+      $results['pass'] += $match[2];
+      $results['fail'] += $match[3];
+      $results['exception'] += $match[4];
     }
+    // Store the number of completed tests in a system variable so that
+    // the next time tests are run we have an idea of how many
+    // tests need to be run.
+    variable_set('pifr_last_test_count', array_sum($results));
+
     return gzdeflate($xml->asXML(), 9);
   }
   return FALSE;
Index: pifr.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/pifr.install,v
retrieving revision 1.18
diff -u -r1.18 pifr.install
--- pifr.install	4 Dec 2008 03:08:21 -0000	1.18
+++ pifr.install	9 Dec 2008 05:43:45 -0000
@@ -274,4 +274,6 @@
   variable_del('pifr_commit_last');
   variable_del('pifr_commit_last_author');
   variable_del('pifr_commit_head_passes');
+
+  variable_del('pifr_last_test_count');
 }
Index: pifr.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/pifr.pages.inc,v
retrieving revision 1.44
diff -u -r1.44 pifr.pages.inc
--- pifr.pages.inc	9 Dec 2008 03:57:37 -0000	1.44
+++ pifr.pages.inc	9 Dec 2008 05:43:46 -0000
@@ -416,6 +416,82 @@
 }
 
 /**
+ * View the status of testing.
+ *
+ * @return string HTML output.
+ */
+function pifr_view_slave_status() {
+  $output = '';
+  $num_tests = pifr_count_completed_tests();
+  // Note: $last_test_count is the total number of tests run when
+  // testing the *last* patch. It is possible that in the current test
+  // run there may be a different number of tests.
+  $last_test_count = variable_get('pifr_last_test_count', NULL);
+
+  if (variable_get('pifr_reviewing', FALSE)) {
+    if (!empty($last_test_count) && !empty($num_tests)) {
+      $output .= t('Completed !num_tests of about !total_num_tests tests.', array('!num_tests' => $num_tests, '!total_num_tests' => $last_test_count));
+      $output .= theme('pifr_progress_bar', $num_tests, $last_test_count);
+    }
+    else {
+      $output .= t('Completed !num_tests tests.', array('!num_tests' => $num_tests));
+    }
+  }
+  else {
+    $output .= t('No tests are running at this time.');
+  }
+
+  return $output;
+}
+
+/**
+ * Get the number of tests that have been completed.
+ *
+ * @return
+ *   The number of tests that have been completed on this testing
+ *   run, or null if tests are not currently being run.
+ */
+function pifr_count_completed_tests() {
+  global $db_url;
+
+  $original_db_url = $db_url;
+
+  // Parse the current $db_url into its pieces and reconstruct $db_url
+  // to use the database used for the Simpletest tests.
+  $url = parse_url(is_array($db_url) ? $db_url['default'] : $db_url);
+  $db_user = urldecode($url['user']);
+  $db_pass = isset($url['pass']) ? urldecode($url['pass']) : NULL;
+  $db_host = urldecode($url['host']);
+  $db_port = isset($url['port']) ? urldecode($url['port']) : '';
+  $db_path = ltrim(urldecode($url['path']), '/');
+
+  // Build new $db_url to use.
+  $db_type = substr($db_url, 0, strpos($db_url, '://'));
+  $checkout_db_url = $db_type .'://'. urlencode($db_user) . ($db_pass ? ':'. urlencode($db_pass) : '') .'@'. ($db_host ? urlencode($db_host) : 'localhost') . ($db_port ? ":$db_port" : '') .'/'. urlencode($db_path) . '_checkout';
+
+  if (is_array($db_url)) {
+    $db_url['pifr_checkout'] = $checkout_db_url;
+  }
+  else {
+    $db_url = array(
+      'default' => $db_url,
+      'pifr_checkout' => $checkout_db_url,
+    );
+  }
+  // Use the new database connection.
+  db_set_active('pifr_checkout');
+
+  // Count number of completed tests.
+  $num_tests = NULL;
+  $num_tests = @db_result(db_query('SELECT COUNT(*) FROM {simpletest}'));
+
+  // Restore previous value of $db_url;
+  $db_url = $original_db_url;
+  db_set_active();
+  return $num_tests;
+}
+
+/**
  * Reset slave confirmation form.
  */
 function pifr_reset_slave_form(&$form_state, $slave_id) {
@@ -724,3 +800,18 @@
     }
   }
 }
+
+function theme_pifr_progress_bar($numerator, $denominator) {
+    $output = '';
+
+  // Number of characters that will represent 10%.
+  $unit_width = 2;
+  $completed = $numerator / $denominator;
+  if (!empty($completed)) {
+    $completed_width = min(round($completed * $unit_width * 10), $unit_width * 10);
+    $progress = str_repeat('*', $completed_width) . str_repeat(' ', ($unit_width * 10) - $completed_width);
+
+    $output = '[' . $progress . ']';
+  }
+  return '<p><pre>' . $output . '</pre></p>';
+}
Index: pifr.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/pifr.module,v
retrieving revision 1.43
diff -u -r1.43 pifr.module
--- pifr.module	9 Dec 2008 05:08:33 -0000	1.43
+++ pifr.module	9 Dec 2008 05:43:45 -0000
@@ -161,13 +161,20 @@
       'type' => MENU_CALLBACK,
       'file' => 'pifr.review.inc'
     );
-    $items['admin/reports/pifr'] = array(
+    $items['admin/reports/pifr/configuration'] = array(
       'title' => 'PIFR server check',
       'description' => 'Check the configuration of the server.',
       'page callback' => 'pifr_client_check_configuration',
       'access arguments' => array('manage pifr'),
       'file' => 'pifr.client.inc',
     );
+    $items['admin/reports/pifr/status'] = array(
+      'title' => 'PIFR slave status',
+      'desctipyion' => 'View the status of the current test suite.',
+      'page callback' => 'pifr_view_slave_status',
+      'access arguments' => array('manage pifr'),
+      'file' => 'pifr.pages.inc'
+    );
   }
 
   $items['admin/settings/pifr'] = array(
@@ -231,6 +238,18 @@
 }
 
 /**
+ * Implementation of hook_theme().
+ */
+function pifr_theme() {
+  return array(
+    'pifr_progress_bar' => array(
+      'file' => 'pifr.pages.inc',
+      'arguments' => array('numerator' => NULL, 'denominator' => NULL)
+    )
+  );
+}
+
+/**
  * Implementation of hook_action_info().
  */
 function pifr_action_info() {
