Index: includes/batch.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/batch.inc,v
retrieving revision 1.50
diff -u -p -r1.50 batch.inc
--- includes/batch.inc 17 Feb 2010 22:44:51 -0000 1.50
+++ includes/batch.inc 22 Apr 2010 21:06:14 -0000
@@ -203,7 +203,7 @@ function _batch_progress_page_nojs() {
// Perform actual processing.
list($percentage, $message) = _batch_process($batch);
- if ($percentage == 100) {
+ if ($percentage >= 100) {
$new_op = 'finished';
}
@@ -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.
Index: modules/simpletest/tests/batch.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/batch.test,v
retrieving revision 1.8
diff -u -p -r1.8 batch.test
--- modules/simpletest/tests/batch.test 8 Jan 2010 06:36:34 -0000 1.8
+++ modules/simpletest/tests/batch.test 22 Apr 2010 21:06:14 -0000
@@ -139,6 +139,19 @@ class BatchProcessingTestCase extends Dr
}
/**
+ * 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
@@ -196,6 +209,12 @@ class BatchProcessingTestCase extends Dr
}
$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';
@@ -241,6 +260,10 @@ class BatchProcessingTestCase extends Dr
$messages[] = 'results for batch 4
op 1: processed 10 elements';
$messages = array_merge($messages, $this->_resultMessages('batch_2'));
break;
+
+ case 'batch_5':
+ $messages[] = 'results for batch 5
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'));
Index: modules/simpletest/tests/batch_test.callbacks.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/batch_test.callbacks.inc,v
retrieving revision 1.1
diff -u -p -r1.1 batch_test.callbacks.inc
--- modules/simpletest/tests/batch_test.callbacks.inc 8 Jan 2010 06:36:34 -0000 1.1
+++ modules/simpletest/tests/batch_test.callbacks.inc 22 Apr 2010 21:06:14 -0000
@@ -52,6 +52,20 @@ function _batch_test_callback_2($start,
}
/**
+ * Simple batch operation.
+ */
+function _batch_test_callback_5($id, $sleep, &$context) {
+ // No-op, but ensure the batch take a couple iterations.
+ 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 +130,10 @@ function _batch_test_finished_3($success
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);
+}
Index: modules/simpletest/tests/batch_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/batch_test.module,v
retrieving revision 1.1
diff -u -p -r1.1 batch_test.module
--- modules/simpletest/tests/batch_test.module 8 Jan 2010 06:36:34 -0000 1.1
+++ modules/simpletest/tests/batch_test.module 22 Apr 2010 21:06:14 -0000
@@ -59,13 +59,21 @@ function batch_test_menu() {
'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(
'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(
@@ -73,7 +81,7 @@ function batch_test_menu() {
'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.
@@ -311,6 +319,16 @@ function batch_test_no_form() {
}
/**
+ * 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');
+}
+
+/**
* Menu callback: successful redirection.
*/
function batch_test_redirect_page() {
@@ -433,6 +451,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() {