Index: modules/simpletest/drupal_web_test_case.php =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v retrieving revision 1.210 diff -u -r1.210 drupal_web_test_case.php --- modules/simpletest/drupal_web_test_case.php 11 Apr 2010 18:33:44 -0000 1.210 +++ modules/simpletest/drupal_web_test_case.php 18 Apr 2010 22:50:17 -0000 @@ -1150,32 +1150,7 @@ $conf = array(); drupal_static_reset(); - include_once DRUPAL_ROOT . '/includes/install.inc'; - drupal_install_system(); - - $this->preloadRegistry(); - - // Include the default profile. - variable_set('install_profile', 'standard'); - $profile_details = install_profile_info('standard', 'en'); - - // Install the modules specified by the default profile. - module_enable($profile_details['dependencies'], FALSE); - - // Install modules needed for this test. This could have been passed in as - // either a single array argument or a variable number of string arguments. - // @todo Remove this compatibility layer in Drupal 8, and only accept - // $modules as a single array argument. - $modules = func_get_args(); - if (isset($modules[0]) && is_array($modules[0])) { - $modules = $modules[0]; - } - if ($modules) { - module_enable($modules, TRUE); - } - - // Run default profile tasks. - module_enable(array('standard'), FALSE); + $this->setUpInstall(func_get_args()); // Rebuild caches. drupal_static_reset(); @@ -1200,11 +1175,8 @@ drupal_save_session(FALSE); $user = user_load(1); - // Restore necessary variables. - variable_set('install_task', 'done'); - variable_set('clean_url', $clean_url_original); - variable_set('site_mail', 'simpletest@example.com'); - variable_set('date_default_timezone', date_default_timezone_get()); + $this->setUpVariables($clean_url_original); + // Set up English language. unset($GLOBALS['conf']['language_default']); $language = language_default(); @@ -1221,6 +1193,48 @@ } /** + * Perform Drupal installation. + */ + protected function setUpInstall(array $modules) { + include_once DRUPAL_ROOT . '/includes/install.inc'; + drupal_install_system(); + + $this->preloadRegistry(); + + // Include the default profile. + variable_set('install_profile', 'standard'); + $profile_details = install_profile_info('standard', 'en'); + + // Install the modules specified by the default profile. + module_enable($profile_details['dependencies'], FALSE); + + // Install modules needed for this test. This could have been passed in as + // either a single array argument or a variable number of string arguments. + // @todo Remove this compatibility layer in Drupal 8, and only accept + // $modules as a single array argument. + if (isset($modules[0]) && is_array($modules[0])) { + $modules = $modules[0]; + } + if ($modules) { + module_enable($modules, TRUE); + } + + // Run default profile tasks. + module_enable(array('standard'), FALSE); + } + + /** + * Set post-installation variables. + */ + protected function setUpVariables($clean_url_original) { + // Restore necessary variables. + variable_set('install_task', 'done'); + variable_set('clean_url', $clean_url_original); + variable_set('site_mail', 'simpletest@example.com'); + variable_set('date_default_timezone', date_default_timezone_get()); + } + + /** * This method is called by DrupalWebTestCase::setUp, and preloads the * registry from the testing site to cut down on the time it takes to * setup a clean environment for the current test run. @@ -2966,6 +2980,79 @@ } /** + * Clone an existing database and use it for testing. + */ +class DrupalCloneTestCase extends DrupalWebTestCase { + + /** + * Tables to exlude during data cloning, only their structure will be cloned. + * + * @var array + */ + protected $excludeTables = array( + 'cache', + 'cache_block', + 'cache_bootstrap', + 'cache_field', + 'cache_filter', + 'cache_form', + 'cache_image', + 'cache_menu', + 'cache_page', + 'cache_path', + 'cache_update', + 'watchdog', + ); + + protected function setUpInstall() { + global $db_prefix; + + // Store new database prefix. + $db_prefix_new = $db_prefix; + $db_prefix = $this->originalPrefix; + + // Rebuild schema based on prefixed database and such. + $schemas = drupal_get_schema(NULL, TRUE); + // Create a list of prefixed source table names. + $sources = array(); + foreach ($schemas as $name => $schema) { + $sources[$name] = Database::getConnection()->prefixTables('{' . $name . '}'); + } + + // Return to new prefix before performing cloning. + $db_prefix = $db_prefix_new; + + // Clone each table into the new database. + foreach ($schemas as $name => $schema) { + $this->cloneTable($name, $sources[$name], $schema); + } + } + + protected function setUpVariables() { + // Do nothing. + } + + /** + * Clone an existing table structure and data. + * + * @param $name + * Table name. + * @param $source + * Source table name. + * @param $schema + * A Schema API definition array. + */ + protected function cloneTable($name, $source, $schema) { + db_create_table($name, $schema); + + $target = Database::getConnection()->prefixTables('{' . $name . '}'); + if (!in_array($name, $this->excludeTables)) { + db_query('INSERT INTO ' . $target . ' SELECT * FROM ' . $source); + } + } +} + +/** * Log verbose message in a text file. * * If verbose mode is enabled then page requests will be dumped to a file and