diff options
author | Angie Byron <webchick@24967.no-reply.drupal.org> | 2010-01-08 06:36:34 +0000 |
---|---|---|
committer | Angie Byron <webchick@24967.no-reply.drupal.org> | 2010-01-08 06:36:34 +0000 |
commit | 0dd161277046bab1ec994e8d756c4e99c717421e (patch) | |
tree | 5f33a4f472b6b5e10544924e5bf6cfc0348b8d08 /modules/simpletest/tests/batch_test.module | |
parent | e07b9d35a1f4dcb1678c4d3bb6482daaebea6350 (diff) | |
download | brdo-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.module | 475 |
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); +} |