summaryrefslogtreecommitdiff
path: root/modules/simpletest/tests/batch_test.module
diff options
context:
space:
mode:
authorAngie Byron <webchick@24967.no-reply.drupal.org>2010-01-08 06:36:34 +0000
committerAngie Byron <webchick@24967.no-reply.drupal.org>2010-01-08 06:36:34 +0000
commit0dd161277046bab1ec994e8d756c4e99c717421e (patch)
tree5f33a4f472b6b5e10544924e5bf6cfc0348b8d08 /modules/simpletest/tests/batch_test.module
parente07b9d35a1f4dcb1678c4d3bb6482daaebea6350 (diff)
downloadbrdo-0dd161277046bab1ec994e8d756c4e99c717421e.tar.gz
brdo-0dd161277046bab1ec994e8d756c4e99c717421e.tar.bz2
#629794 by yched: Fix Scaling issues with batch API. (with tests)
Diffstat (limited to 'modules/simpletest/tests/batch_test.module')
-rw-r--r--modules/simpletest/tests/batch_test.module475
1 files changed, 475 insertions, 0 deletions
diff --git a/modules/simpletest/tests/batch_test.module b/modules/simpletest/tests/batch_test.module
new file mode 100644
index 000000000..03938aaa8
--- /dev/null
+++ b/modules/simpletest/tests/batch_test.module
@@ -0,0 +1,475 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Helper module for the Batch API tests.
+ */
+
+/**
+ * Implement hook_menu().
+ */
+function batch_test_menu() {
+ $items = 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(
+ 'title' => 'Simple',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => 0,
+ );
+ // Multistep form: two steps, each setting a batch.
+ $items['batch_test/multistep'] = array(
+ 'title' => 'Multistep',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('batch_test_multistep_form'),
+ 'access callback' => TRUE,
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 1,
+ );
+ // Chained form: four submit handlers, several of which set a batch.
+ $items['batch_test/chained'] = array(
+ 'title' => 'Chained',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('batch_test_chained_form'),
+ 'access callback' => TRUE,
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 2,
+ );
+ // Programmatic form: the page submits the 'Chained' form through
+ // drupal_form_submit().
+ $items['batch_test/programmatic'] = array(
+ 'title' => 'Programmatic',
+ 'page callback' => 'batch_test_programmatic',
+ 'access callback' => TRUE,
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 3,
+ );
+ // No form: fire a batch simply by accessing a page.
+ $items['batch_test/no_form'] = array(
+ 'title' => 'Simple page',
+ 'page callback' => 'batch_test_no_form',
+ 'access callback' => TRUE,
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 4,
+ );
+ // 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,
+ );
+ // Landing page to test redirects.
+ $items['batch_test/redirect'] = array(
+ 'title' => 'Redirect',
+ 'page callback' => 'batch_test_redirect_page',
+ 'access callback' => TRUE,
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 6,
+ );
+ //
+ // This item lives under 'admin' so that the page uses the admin theme.
+ $items['admin/batch_test/test_theme'] = array(
+ 'page callback' => 'batch_test_theme_batch',
+ 'access callback' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+
+ return $items;
+}
+
+/**
+ * Simple form.
+ */
+function batch_test_simple_form() {
+ $form['batch'] = array(
+ '#type' => 'select',
+ '#title' => 'Choose batch',
+ '#options' => array(
+ 'batch_0' => 'batch 0',
+ 'batch_1' => 'batch 1',
+ 'batch_2' => 'batch 2',
+ 'batch_3' => 'batch 3',
+ 'batch_4' => 'batch 4',
+ ),
+ );
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => 'Submit',
+ );
+
+ return $form;
+}
+
+/**
+ * Submit handler for the simple form.
+ */
+function batch_test_simple_form_submit($form, &$form_state) {
+ batch_test_stack(NULL, TRUE);
+
+ $function = '_batch_test_' . $form_state['values']['batch'];
+ batch_set($function());
+
+ $form_state['redirect'] = 'batch_test/redirect';
+}
+
+
+/**
+ * Multistep form.
+ */
+function batch_test_multistep_form($form, &$form_state) {
+ if (empty($form_state['storage']['step'])) {
+ $form_state['storage']['step'] = 1;
+ }
+
+ $form['step_display'] = array(
+ '#markup' => 'step ' . $form_state['storage']['step'] . '<br/>',
+ );
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => 'Submit',
+ );
+
+ return $form;
+}
+
+/**
+ * Submit handler for the multistep form.
+ */
+function batch_test_multistep_form_submit($form, &$form_state) {
+ batch_test_stack(NULL, TRUE);
+
+ switch ($form_state['storage']['step']) {
+ case 1:
+ batch_set(_batch_test_batch_1());
+ break;
+ case 2:
+ batch_set(_batch_test_batch_2());
+ break;
+ }
+
+ if ($form_state['storage']['step'] < 2) {
+ $form_state['storage']['step']++;
+ $form_state['rebuild'] = TRUE;
+ }
+
+ // This will only be effective on the last step.
+ $form_state['redirect'] = 'batch_test/redirect';
+}
+
+/**
+ * Form with chained submit callbacks.
+ */
+function batch_test_chained_form() {
+ // This value is used to test that $form_state persists through batched
+ // submit handlers.
+ $form['value'] = array(
+ '#type' => 'textfield',
+ '#title' => 'Value',
+ '#default_value' => 1,
+ );
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => 'Submit',
+ );
+ $form['#submit'] = array(
+ 'batch_test_chained_form_submit_1',
+ 'batch_test_chained_form_submit_2',
+ 'batch_test_chained_form_submit_3',
+ 'batch_test_chained_form_submit_4',
+ );
+
+ return $form;
+}
+
+/**
+ * Submit handler #1 for the chained form.
+ */
+function batch_test_chained_form_submit_1($form, &$form_state) {
+ batch_test_stack(NULL, TRUE);
+
+ batch_test_stack('submit handler 1');
+ batch_test_stack('value = ' . $form_state['values']['value']);
+
+ $form_state['values']['value']++;
+ batch_set(_batch_test_batch_1());
+
+ // This redirect should not be taken into account.
+ $form_state['redirect'] = 'should/be/discarded';
+}
+
+/**
+ * Submit handler #2 for the chained form.
+ */
+function batch_test_chained_form_submit_2($form, &$form_state) {
+ batch_test_stack('submit handler 2');
+ batch_test_stack('value = ' . $form_state['values']['value']);
+
+ $form_state['values']['value']++;
+ batch_set(_batch_test_batch_2());
+
+ // This redirect should not be taken into account.
+ $form_state['redirect'] = 'should/be/discarded';
+}
+
+/**
+ * Submit handler #3 for the chained form.
+ */
+function batch_test_chained_form_submit_3($form, &$form_state) {
+ batch_test_stack('submit handler 3');
+ batch_test_stack('value = ' . $form_state['values']['value']);
+
+ $form_state['values']['value']++;
+
+ // This redirect should not be taken into account.
+ $form_state['redirect'] = 'should/be/discarded';
+}
+
+/**
+ * Submit handler #4 for the chained form.
+ */
+function batch_test_chained_form_submit_4($form, &$form_state) {
+ batch_test_stack('submit handler 4');
+ batch_test_stack('value = ' . $form_state['values']['value']);
+
+ $form_state['values']['value']++;
+ batch_set(_batch_test_batch_3());
+
+ // This is the redirect that should prevail.
+ $form_state['redirect'] = 'batch_test/redirect';
+}
+
+/**
+ * Menu callback: programmatically submits the 'Chained' form.
+ */
+function batch_test_programmatic($value = 1) {
+ $form_state = array(
+ 'values' => array('value' => $value)
+ );
+ drupal_form_submit('batch_test_chained_form', $form_state);
+ return 'Got out of a programmatic batched form.';
+}
+
+/**
+ * Menu callback: programmatically submits a form within a batch.
+ */
+function batch_test_nested_drupal_form_submit($value = 1) {
+ // Set the batch and process it.
+ $batch['operations'] = array(
+ array('_batch_test_nested_drupal_form_submit_callback', array($value)),
+ );
+ batch_set($batch);
+ batch_process('batch_test/redirect');
+}
+
+/**
+ * Batch operation: submits form_test_mock_form using drupal_form_submit().
+ */
+function _batch_test_nested_drupal_form_submit_callback($value) {
+ $state['values']['test_value'] = $value;
+ drupal_form_submit('batch_test_mock_form', $state);
+}
+
+/**
+ * A simple form with a textfield and submit button.
+ */
+function batch_test_mock_form($form, $form_state) {
+ $form['test_value'] = array(
+ '#type' => 'textfield',
+ );
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Submit'),
+ );
+
+ return $form;
+}
+
+/**
+ * Submit handler for the batch_test_mock form.
+ */
+function batch_test_mock_form_submit($form, &$form_state) {
+ batch_test_stack('mock form submitted with value = ' . $form_state['values']['test_value']);
+}
+
+/**
+ * Menu callback: fire a batch process without a form submission.
+ */
+function batch_test_no_form() {
+ batch_test_stack(NULL, TRUE);
+
+ batch_set(_batch_test_batch_1());
+ batch_process('batch_test/redirect');
+}
+
+/**
+ * Menu callback: successful redirection.
+ */
+function batch_test_redirect_page() {
+ return 'Redirection successful.';
+}
+
+/**
+ * Batch 0: no operation.
+ */
+function _batch_test_batch_0() {
+ $batch = array(
+ 'operations' => array(),
+ 'finished' => '_batch_test_finished_0',
+ 'file' => drupal_get_path('module', 'batch_test'). '/batch_test.callbacks.inc',
+ );
+ return $batch;
+}
+
+/**
+ * Batch 1: repeats a simple operation.
+ *
+ * Operations: op 1 from 1 to 10.
+ */
+function _batch_test_batch_1() {
+ // 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_1', array($i, $sleep));
+ }
+ $batch = array(
+ 'operations' => $operations,
+ 'finished' => '_batch_test_finished_1',
+ 'file' => drupal_get_path('module', 'batch_test'). '/batch_test.callbacks.inc',
+ );
+ return $batch;
+}
+
+/**
+ * Batch 2: single multistep operation.
+ *
+ * Operations: op 2 from 1 to 10.
+ */
+function _batch_test_batch_2() {
+ // Ensure the batch takes at least two iterations.
+ $total = 10;
+ $sleep = (1000000 / $total) * 2;
+
+ $operations = array(
+ array('_batch_test_callback_2', array(1, $total, $sleep)),
+ );
+ $batch = array(
+ 'operations' => $operations,
+ 'finished' => '_batch_test_finished_2',
+ 'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
+ );
+ return $batch;
+}
+
+/**
+ * Batch 3: both single and multistep operations.
+ *
+ * Operations:
+ * - op 1 from 1 to 5,
+ * - op 2 from 1 to 5,
+ * - op 1 from 6 to 10,
+ * - op 2 from 6 to 10.
+ */
+function _batch_test_batch_3() {
+ // Ensure the batch takes at least two iterations.
+ $total = 10;
+ $sleep = (1000000 / $total) * 2;
+
+ $operations = array();
+ for ($i = 1; $i <= round($total / 2); $i++) {
+ $operations[] = array('_batch_test_callback_1', array($i, $sleep));
+ }
+ $operations[] = array('_batch_test_callback_2', array(1, $total / 2, $sleep));
+ for ($i = round($total / 2) + 1; $i <= $total; $i++) {
+ $operations[] = array('_batch_test_callback_1', array($i, $sleep));
+ }
+ $operations[] = array('_batch_test_callback_2', array(6, $total / 2, $sleep));
+ $batch = array(
+ 'operations' => $operations,
+ 'finished' => '_batch_test_finished_3',
+ 'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
+ );
+ return $batch;
+}
+
+/**
+ * Batch 4: batch within a batch.
+ *
+ * Operations:
+ * - op 1 from 1 to 5,
+ * - set batch 2 (op 2 from 1 to 10, should run at the end)
+ * - op 1 from 6 to 10,
+ */
+function _batch_test_batch_4() {
+ // Ensure the batch takes at least two iterations.
+ $total = 10;
+ $sleep = (1000000 / $total) * 2;
+
+ $operations = array();
+ for ($i = 1; $i <= round($total / 2); $i++) {
+ $operations[] = array('_batch_test_callback_1', array($i, $sleep));
+ }
+ $operations[] = array('_batch_test_nested_batch_callback', array());
+ for ($i = round($total / 2) + 1; $i <= $total; $i++) {
+ $operations[] = array('_batch_test_callback_1', array($i, $sleep));
+ }
+ $batch = array(
+ 'operations' => $operations,
+ 'finished' => '_batch_test_finished_4',
+ '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() {
+ batch_test_stack(NULL, TRUE);
+ $batch = array(
+ 'operations' => array(
+ array('_batch_test_theme_callback', array()),
+ ),
+ );
+ batch_set($batch);
+ batch_process('batch_test/redirect');
+}
+
+/**
+ * Batch callback function for testing the theme used on the progress page.
+ */
+function _batch_test_theme_callback() {
+ // Because drupalGet() steps through the full progressive batch before
+ // returning control to the test function, we cannot test that the correct
+ // theme is being used on the batch processing page by viewing that page
+ // directly. Instead, we save the theme being used in a variable here, so
+ // that it can be loaded and inspected in the thread running the test.
+ global $theme;
+ batch_test_stack($theme);
+}
+
+/**
+ * Helper function: store or retrieve traced execution data.
+ */
+function batch_test_stack($data = NULL, $reset = FALSE) {
+ if ($reset) {
+ variable_del('batch_test_stack');
+ }
+ if (is_null($data)) {
+ return variable_get('batch_test_stack', array());
+ }
+ $stack = variable_get('batch_test_stack', array());
+ $stack[] = $data;
+ variable_set('batch_test_stack', $stack);
+}