diff --git includes/batch.inc includes/batch.inc
index 36cfd14..aeff5ba 100644
--- includes/batch.inc
+++ includes/batch.inc
@@ -285,7 +285,7 @@ function _batch_process() {
       );
       call_user_func_array($function, array_merge($args, array(&$batch_context)));
 
-      if ($finished == 1) {
+      if ($finished >= 1) {
         // Make sure this step is not counted twice when computing $current.
         $finished = 0;
         // Remove the processed operation and clear the sandbox.
diff --git modules/simpletest/tests/batch.test modules/simpletest/tests/batch.test
index f9aa936..bcaa496 100644
--- modules/simpletest/tests/batch.test
+++ modules/simpletest/tests/batch.test
@@ -27,7 +27,7 @@ class BatchProcessingTestCase extends DrupalWebTestCase {
    */
   function testBatchNoForm() {
     // Displaying the page triggers batch 1.
-    $this->drupalGet('batch_test/no_form');
+    $this->drupalGet('batch-test/no-form');
     $this->assertBatchMessages($this->_resultMessages(1), t('Batch for step 2 performed successfully.'));
     $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_1'), t('Execution order was correct.'));
     $this->assertText('Redirection successful.', t('Redirection after batch execution is correct.'));
@@ -39,34 +39,34 @@ class BatchProcessingTestCase extends DrupalWebTestCase {
   function testBatchForm() {
     // Batch 0: no operation.
     $edit = array('batch' => 'batch_0');
-    $this->drupalPost('batch_test/simple', $edit, 'Submit');
+    $this->drupalPost('batch-test/simple', $edit, 'Submit');
     $this->assertBatchMessages($this->_resultMessages('batch_0'), t('Batch with no operation performed successfully.'));
     $this->assertText('Redirection successful.', t('Redirection after batch execution is correct.'));
 
     // Batch 1: several simple operations.
     $edit = array('batch' => 'batch_1');
-    $this->drupalPost('batch_test/simple', $edit, 'Submit');
+    $this->drupalPost('batch-test/simple', $edit, 'Submit');
     $this->assertBatchMessages($this->_resultMessages('batch_1'), t('Batch with simple operations performed successfully.'));
     $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_1'), t('Execution order was correct.'));
     $this->assertText('Redirection successful.', t('Redirection after batch execution is correct.'));
 
     // Batch 2: one multistep operation.
     $edit = array('batch' => 'batch_2');
-    $this->drupalPost('batch_test/simple', $edit, 'Submit');
+    $this->drupalPost('batch-test/simple', $edit, 'Submit');
     $this->assertBatchMessages($this->_resultMessages('batch_2'), t('Batch with multistep operation performed successfully.'));
     $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_2'), t('Execution order was correct.'));
     $this->assertText('Redirection successful.', t('Redirection after batch execution is correct.'));
 
     // Batch 3: simple + multistep combined.
     $edit = array('batch' => 'batch_3');
-    $this->drupalPost('batch_test/simple', $edit, 'Submit');
+    $this->drupalPost('batch-test/simple', $edit, 'Submit');
     $this->assertBatchMessages($this->_resultMessages('batch_3'), t('Batch with simple and multistep operations performed successfully.'));
     $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_3'), t('Execution order was correct.'));
     $this->assertText('Redirection successful.', t('Redirection after batch execution is correct.'));
 
     // Batch 4: nested batch.
     $edit = array('batch' => 'batch_4');
-    $this->drupalPost('batch_test/simple', $edit, 'Submit');
+    $this->drupalPost('batch-test/simple', $edit, 'Submit');
     $this->assertBatchMessages($this->_resultMessages('batch_4'), t('Nested batch performed successfully.'));
     $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_4'), t('Execution order was correct.'));
     $this->assertText('Redirection successful.', t('Redirection after batch execution is correct.'));
@@ -76,7 +76,7 @@ class BatchProcessingTestCase extends DrupalWebTestCase {
    * Test batches defined in a multistep form.
    */
   function testBatchFormMultistep() {
-    $this->drupalGet('batch_test/multistep');
+    $this->drupalGet('batch-test/multistep');
     $this->assertText('step 1', t('Form is displayed in step 1.'));
 
     // First step triggers batch 1.
@@ -100,7 +100,7 @@ class BatchProcessingTestCase extends DrupalWebTestCase {
     // handlers. Each submit handler modify the submitted 'value'.
     $value = rand(0, 255);
     $edit = array('value' => $value);
-    $this->drupalPost('batch_test/chained', $edit, 'Submit');
+    $this->drupalPost('batch-test/chained', $edit, 'Submit');
     // Check that result messages are present and in the correct order.
     $this->assertBatchMessages($this->_resultMessages('chained'), t('Batches defined in separate submit handlers performed successfully.'));
     // The stack contains execution order of batch callbacks and submit
@@ -118,7 +118,7 @@ class BatchProcessingTestCase extends DrupalWebTestCase {
     // Batches 1, 2 and 3 are triggered in sequence by different submit
     // handlers. Each submit handler modify the submitted 'value'.
     $value = rand(0, 255);
-    $this->drupalGet('batch_test/programmatic/' . $value);
+    $this->drupalGet('batch-test/programmatic/' . $value);
     // Check that result messages are present and in the correct order.
     $this->assertBatchMessages($this->_resultMessages('chained'), t('Batches defined in separate submit handlers performed successfully.'));
     // The stack contains execution order of batch callbacks and submit
@@ -134,11 +134,24 @@ class BatchProcessingTestCase extends DrupalWebTestCase {
     // Displaying the page triggers a batch that programmatically submits a
     // form.
     $value = rand(0, 255);
-    $this->drupalGet('batch_test/nested_programmatic/' . $value);
+    $this->drupalGet('batch-test/nested-programmatic/' . $value);
     $this->assertEqual(batch_test_stack(), array('mock form submitted with value = ' . $value), t('drupal_form_submit() ran successfully within a batch operation.'));
   }
 
   /**
+   * Test batches that return $context['finished'] > 1 do in fact complete.
+   * See http://drupal.org/node/600836
+   */
+  function testBatchLargePercentage() {
+    // Displaying the page triggers batch 5.
+    $this->drupalGet('batch-test/large-percentage');
+    $this->assertBatchMessages($this->_resultMessages(1), t('Batch for step 2 performed successfully.'));
+    $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_5'), t('Execution order was correct.'));
+    $this->assertText('Redirection successful.', t('Redirection after batch execution is correct.'));
+  }
+
+
+  /**
    * Will trigger a pass if the texts were found in order in the raw content.
    *
    * @param $texts
@@ -197,6 +210,12 @@ class BatchProcessingTestCase extends DrupalWebTestCase {
         $stack = array_merge($stack, $this->_resultStack('batch_2'));
         break;
 
+      case 'batch_5':
+        for ($i = 1; $i <= 10; $i++) {
+          $stack[] = "op 5 id $i";
+        }
+        break;
+
       case 'chained':
         $stack[] = 'submit handler 1';
         $stack[] = 'value = ' . $value;
@@ -242,6 +261,10 @@ class BatchProcessingTestCase extends DrupalWebTestCase {
         $messages = array_merge($messages, $this->_resultMessages('batch_2'));
         break;
 
+      case 'batch_5':
+        $messages[] = 'results for batch 5<br />op 1: processed 10 elements. $context[\'finished\'] > 1 returned from batch process, with success.';
+        break;
+
       case 'chained':
         $messages = array_merge($messages, $this->_resultMessages('batch_1'));
         $messages = array_merge($messages, $this->_resultMessages('batch_2'));
@@ -280,7 +303,7 @@ class BatchPageTestCase extends DrupalWebTestCase {
     // theme that was used during batch execution (which the batch callback
     // function saved as a variable) matches the theme used on the
     // administrative page.
-    $this->drupalGet('admin/batch_test/test_theme');
+    $this->drupalGet('admin/batch-test/test-theme');
     // The stack should contain the name of the the used on the progress page.
     $this->assertEqual(batch_test_stack(), array('seven'), t('A progressive batch correctly uses the theme of the page that started the batch.'));
   }
diff --git modules/simpletest/tests/batch_test.callbacks.inc modules/simpletest/tests/batch_test.callbacks.inc
index a96c133..eddb6ed 100644
--- modules/simpletest/tests/batch_test.callbacks.inc
+++ modules/simpletest/tests/batch_test.callbacks.inc
@@ -12,6 +12,7 @@
  */
 function _batch_test_callback_1($id, $sleep, &$context) {
   // No-op, but ensure the batch take a couple iterations.
+  // Batch needs time to run for the test, so sleep a bit.
   usleep($sleep);
   // Track execution, and store some result for post-processing in the
   // 'finished' callback.
@@ -33,6 +34,7 @@ function _batch_test_callback_2($start, $total, $sleep, &$context) {
   $limit = 5;
   for ($i = 0; $i < $limit && $context['sandbox']['count'] < $total; $i++) {
     // No-op, but ensure the batch take a couple iterations.
+    // Batch needs time to run for the test, so sleep a bit.
     usleep($sleep);
     // Track execution, and store some result for post-processing in the
     // 'finished' callback.
@@ -52,6 +54,21 @@ function _batch_test_callback_2($start, $total, $sleep, &$context) {
 }
 
 /**
+ * Simple batch operation.
+ */
+function _batch_test_callback_5($id, $sleep, &$context) {
+  // No-op, but ensure the batch take a couple iterations.
+  // Batch needs time to run for the test, so sleep a bit.
+  usleep($sleep);
+  // Track execution, and store some result for post-processing in the
+  // 'finished' callback.
+  batch_test_stack("op 5 id $id");
+  $context['results'][5][] = $id;
+  // This test is to test finished > 1
+  $context['finished'] = 3.14;
+}
+
+/**
  * Batch operation setting up its own batch.
  */
 function _batch_test_nested_batch_callback() {
@@ -116,3 +133,10 @@ function _batch_test_finished_3($success, $results, $operations) {
 function _batch_test_finished_4($success, $results, $operations) {
   _batch_test_finished_helper(4, $success, $results, $operations);
 }
+
+/**
+ * 'finished' callback for batch 5.
+ */
+function _batch_test_finished_5($success, $results, $operations) {
+  _batch_test_finished_helper(5, $success, $results, $operations);
+}
diff --git modules/simpletest/tests/batch_test.module modules/simpletest/tests/batch_test.module
index 14e7931..3cf38c5 100644
--- modules/simpletest/tests/batch_test.module
+++ modules/simpletest/tests/batch_test.module
@@ -12,20 +12,20 @@
 function batch_test_menu() {
   $items = array();
 
-  $items['batch_test'] = array(
+  $items['batch-test'] = array(
     'title' => 'Batch test',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('batch_test_simple_form'),
     'access callback' => TRUE,
   );
   // Simple form: one submit handler, setting a batch.
-  $items['batch_test/simple'] = array(
+  $items['batch-test/simple'] = array(
     'title' => 'Simple',
     'type' => MENU_DEFAULT_LOCAL_TASK,
     'weight' => 0,
   );
   // Multistep form: two steps, each setting a batch.
-  $items['batch_test/multistep'] = array(
+  $items['batch-test/multistep'] = array(
     'title' => 'Multistep',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('batch_test_multistep_form'),
@@ -34,7 +34,7 @@ function batch_test_menu() {
     'weight' => 1,
   );
   // Chained form: four submit handlers, several of which set a batch.
-  $items['batch_test/chained'] = array(
+  $items['batch-test/chained'] = array(
     'title' => 'Chained',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('batch_test_chained_form'),
@@ -44,7 +44,7 @@ function batch_test_menu() {
   );
   // Programmatic form: the page submits the 'Chained' form through
   // drupal_form_submit().
-  $items['batch_test/programmatic'] = array(
+  $items['batch-test/programmatic'] = array(
     'title' => 'Programmatic',
     'page callback' => 'batch_test_programmatic',
     'access callback' => TRUE,
@@ -52,32 +52,39 @@ function batch_test_menu() {
     'weight' => 3,
   );
   // No form: fire a batch simply by accessing a page.
-  $items['batch_test/no_form'] = array(
+  $items['batch-test/no-form'] = array(
     'title' => 'Simple page',
     'page callback' => 'batch_test_no_form',
     'access callback' => TRUE,
     'type' => MENU_LOCAL_TASK,
     'weight' => 4,
   );
+  // No form: fire a batch; return > 100% complete
+  $items['batch-test/large-percentage'] = array(
+    'title' => 'Simple page with batch over 100% complete',
+    'page callback' => 'batch_test_large_percentage',
+    'access callback' => TRUE,
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 5,
+  );
   // Tests programmatic form submission within a batch operation.
-  $items['batch_test/nested_programmatic'] = array(
+  $items['batch-test/nested-programmatic'] = array(
     'title' => 'Nested programmatic',
     'page callback' => 'batch_test_nested_drupal_form_submit',
     'access callback' => TRUE,
     'type' => MENU_LOCAL_TASK,
-    'weight' => 5,
+    'weight' => 6,
   );
   // Landing page to test redirects.
-  $items['batch_test/redirect'] = array(
+  $items['batch-test/redirect'] = array(
     'title' => 'Redirect',
     'page callback' => 'batch_test_redirect_page',
     'access callback' => TRUE,
     'type' => MENU_LOCAL_TASK,
-    'weight' => 6,
+    'weight' => 7,
   );
-  //
   // This item lives under 'admin' so that the page uses the admin theme.
-  $items['admin/batch_test/test_theme'] = array(
+  $items['admin/batch-test/test-theme'] = array(
     'page callback' => 'batch_test_theme_batch',
     'access callback' => TRUE,
     'type' => MENU_CALLBACK,
@@ -118,7 +125,7 @@ function batch_test_simple_form_submit($form, &$form_state) {
   $function = '_batch_test_' . $form_state['values']['batch'];
   batch_set($function());
 
-  $form_state['redirect'] = 'batch_test/redirect';
+  $form_state['redirect'] = 'batch-test/redirect';
 }
 
 
@@ -162,7 +169,7 @@ function batch_test_multistep_form_submit($form, &$form_state) {
   }
 
   // This will only be effective on the last step.
-  $form_state['redirect'] = 'batch_test/redirect';
+  $form_state['redirect'] = 'batch-test/redirect';
 }
 
 /**
@@ -244,7 +251,7 @@ function batch_test_chained_form_submit_4($form, &$form_state) {
   batch_set(_batch_test_batch_3());
 
   // This is the redirect that should prevail.
-  $form_state['redirect'] = 'batch_test/redirect';
+  $form_state['redirect'] = 'batch-test/redirect';
 }
 
 /**
@@ -267,7 +274,7 @@ function batch_test_nested_drupal_form_submit($value = 1) {
     array('_batch_test_nested_drupal_form_submit_callback', array($value)),
   );
   batch_set($batch);
-  batch_process('batch_test/redirect');
+  batch_process('batch-test/redirect');
 }
 
 /**
@@ -307,7 +314,17 @@ function batch_test_no_form() {
   batch_test_stack(NULL, TRUE);
 
   batch_set(_batch_test_batch_1());
-  batch_process('batch_test/redirect');
+  batch_process('batch-test/redirect');
+}
+
+/**
+ * Menu callback: fire a batch process without a form submission.
+ */
+function batch_test_large_percentage() {
+  batch_test_stack(NULL, TRUE);
+
+  batch_set(_batch_test_batch_5());
+  batch_process('batch-test/redirect');
 }
 
 /**
@@ -433,6 +450,28 @@ function _batch_test_batch_4() {
 }
 
 /**
+ * Batch 5: repeats a simple operation.
+ *
+ * Operations: op 1 from 1 to 10.
+ */
+function _batch_test_batch_5() {
+  // Ensure the batch takes at least two iterations.
+  $total = 10;
+  $sleep = (1000000 / $total) * 2;
+
+  $operations = array();
+  for ($i = 1; $i <= $total; $i++) {
+    $operations[] = array('_batch_test_callback_5', array($i, $sleep));
+  }
+  $batch = array(
+    'operations' => $operations,
+    'finished' => '_batch_test_finished_5',
+    'file' => drupal_get_path('module', 'batch_test'). '/batch_test.callbacks.inc',
+  );
+  return $batch;
+}
+
+/**
  * Menu callback: run a batch for testing theme used on the progress page.
  */
 function batch_test_theme_batch() {
@@ -443,7 +482,7 @@ function batch_test_theme_batch() {
     ),
   );
   batch_set($batch);
-  batch_process('batch_test/redirect');
+  batch_process('batch-test/redirect');
 }
 
 /**
