Index: modules/simpletest/simpletest.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.info,v
retrieving revision 1.7
diff -u -r1.7 simpletest.info
--- modules/simpletest/simpletest.info	1 Jul 2009 13:44:53 -0000	1.7
+++ modules/simpletest/simpletest.info	4 Aug 2009 05:58:12 -0000
@@ -8,6 +8,7 @@
 files[] = simpletest.pages.inc
 files[] = simpletest.install
 files[] = simpletest.test
+files[] = simpletest.test.inc
 files[] = drupal_web_test_case.php
 
 ; Tests in tests directory.
Index: modules/simpletest/simpletest.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v
retrieving revision 1.63
diff -u -r1.63 simpletest.module
--- modules/simpletest/simpletest.module	30 Jul 2009 10:46:53 -0000	1.63
+++ modules/simpletest/simpletest.module	4 Aug 2009 05:58:12 -0000
@@ -276,76 +276,6 @@
 }
 
 /**
- * Get a list of all of the tests provided by the system.
- *
- * The list of test classes is loaded from the registry where it looks for
- * files ending in ".test". Once loaded the test list is cached and stored in
- * a static variable. In order to list tests provided by disabled modules
- * hook_registry_files_alter() is used to forcefully add them to the registry.
- *
- * @return
- *   An array of tests keyed with the groups specified in each of the tests
- *   getInfo() method and then keyed by the test class. An example of the array
- *   structure is provided below.
- *
- *   @code
- *     $groups['Blog'] => array(
- *       'BlogTestCase' => array(
- *         'name' => 'Blog functionality',
- *         'description' => 'Create, view, edit, delete, ...',
- *         'group' => 'Blog',
- *       ),
- *     );
- *   @endcode
- * @see simpletest_registry_files_alter()
- */
-function simpletest_test_get_all() {
-  $groups = &drupal_static(__FUNCTION__);
-
-  if (!$groups) {
-    // Load test information from cache if available, otherwise retrieve the
-    // information from each tests getInfo() method.
-    if ($cache = cache_get('simpletest', 'cache')) {
-      $groups = $cache->data;
-    }
-    else {
-      // Select all clases in files ending with .test.
-      $classes = db_select('registry')
-        ->fields('registry', array('name'))
-        ->condition('type', 'class')
-        ->condition('filename', '%.test', 'LIKE')
-        ->execute();
-
-      $groups = array();
-
-      // Check that each class has a getInfo() method and store the information
-      // in an array keyed with the group specified in the test information.
-      foreach ($classes as $class) {
-        $class = $class->name;
-        if (class_exists($class) && method_exists($class, 'getInfo')) {
-          // Valid test class, retrieve test information.
-          $info = call_user_func(array($class, 'getInfo'));
-
-          // Initialize test groups.
-          if (!isset($groups[$info['group']])) {
-            $groups[$info['group']] = array();
-          }
-          $groups[$info['group']][$class] = $info;
-        }
-      }
-      // Sort the groups and tests within the groups by name.
-      uksort($groups, 'strnatcasecmp');
-      foreach ($groups as $group => &$tests) {
-        uksort($tests, 'strnatcasecmp');
-      }
-
-      cache_set('simpletest', $groups);
-    }
-  }
-  return $groups;
-}
-
-/**
  * Implementation of hook_registry_files_alter().
  *
  * Add the test files for disabled modules so that we get a list containing
Index: modules/simpletest/simpletest.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.pages.inc,v
retrieving revision 1.10
diff -u -r1.10 simpletest.pages.inc
--- modules/simpletest/simpletest.pages.inc	29 Jul 2009 06:39:34 -0000	1.10
+++ modules/simpletest/simpletest.pages.inc	4 Aug 2009 05:58:13 -0000
@@ -23,6 +23,7 @@
   );
 
   // Generate the list of tests arranged by group.
+  drupal_function_exists('simpletest_test_get_all');
   $groups = simpletest_test_get_all();
   foreach ($groups as $group => $tests) {
     $form['tests']['table'][$group] = array(
@@ -260,8 +261,8 @@
       $form['result']['summary']['#' . $assertion->status]++;
     }
     $form['result']['results'][$group]['table'] = array(
-      '#theme' => 'table', 
-      '#header' => $header, 
+      '#theme' => 'table',
+      '#header' => $header,
       '#rows' => $rows,
     );
 
Index: modules/simpletest/simpletest.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.install,v
retrieving revision 1.25
diff -u -r1.25 simpletest.install
--- modules/simpletest/simpletest.install	22 Jul 2009 04:45:35 -0000	1.25
+++ modules/simpletest/simpletest.install	4 Aug 2009 05:58:12 -0000
@@ -171,11 +171,11 @@
         'not null' => TRUE,
         'description' => 'Primary Key: Unique simpletest message ID.',
       ),
-      'test_id' => array(
+      'batch_id' => array(
         'type' => 'int',
         'not null' => TRUE,
         'default' => 0,
-        'description' => 'Test ID, messages belonging to the same ID are reported together',
+        'description' => 'Batch ID, messages belonging to the same batch are reported together',
       ),
       'test_class' => array(
         'type' => 'varchar',
@@ -229,10 +229,10 @@
       'reporter' => array('test_class', 'message_id'),
     ),
   );
-  $schema['simpletest_test_id'] = array(
-    'description' => 'Stores simpletest test IDs, used to auto-incrament the test ID so that a fresh test ID is used.',
+  $schema['simpletest_batch'] = array(
+    'description' => 'Stores simpletest batch IDs, used to auto-incrament the batch ID so that a fresh batch ID is used.',
     'fields' => array(
-      'test_id'  => array(
+      'batch_id'  => array(
         'type' => 'serial',
         'not null' => TRUE,
         'description' => 'Primary Key: Unique simpletest ID used to group test results together. Each time a set of tests
@@ -246,7 +246,7 @@
         'description' => 'The last database prefix used during testing.',
       ),
     ),
-    'primary key' => array('test_id'),
+    'primary key' => array('batch_id'),
   );
   return $schema;
 }
Index: install.php
===================================================================
RCS file: /cvs/drupal/drupal/install.php,v
retrieving revision 1.190
diff -u -r1.190 install.php
--- install.php	30 Jul 2009 19:32:19 -0000	1.190
+++ install.php	4 Aug 2009 05:58:12 -0000
@@ -237,6 +237,18 @@
   // This must go after drupal_bootstrap(), which unsets globals!
   global $conf;
 
+  if (isset($install_state['parameters']['force']) && $install_state['parameters']['force']) {
+    global $databases, $db_prefix;
+    $databases = array(
+      'default' => array(
+        'default' => array(),
+      ),
+    );
+    $databases['default']['default'] = $install_state['forms']['install_settings_form'];
+    unset($databases['default']['default']['db_prefix']);
+    $db_prefix = $install_state['forms']['install_settings_form']['prefix'];
+  }
+
   require_once DRUPAL_ROOT . '/modules/system/system.install';
   require_once DRUPAL_ROOT . '/includes/common.inc';
   require_once DRUPAL_ROOT . '/includes/file.inc';
@@ -946,7 +958,7 @@
     $databases['default']['default'] = $database;
     try {
       db_run_tasks($database['driver']);
-    } 
+    }
     catch (DatabaseTaskException $e) {
       // These are generic errors, so we do not have any specific key of the
       // database connection array to attach them to; therefore, we just put
@@ -1064,7 +1076,7 @@
 
   foreach ($profile_files as $profile) {
     include_once DRUPAL_ROOT . '/' . $profile->filepath;
-    
+
     $details = install_profile_info($profile->name);
     $profiles[$profile->name] = $details;
 
@@ -1654,7 +1666,7 @@
   // Enable update.module if this option was selected.
   if ($form_state['values']['update_status_module'][1]) {
     drupal_install_modules(array('update'));
- 
+
     // Add the administrator's email address to the list of addresses to be
     // notified when updates are available, if selected.
     if ($form_state['values']['update_status_module'][2]) {
Index: modules/simpletest/simpletest.test.inc
===================================================================
RCS file: modules/simpletest/simpletest.test.inc
diff -N modules/simpletest/simpletest.test.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/simpletest.test.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,136 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Shared test running API.
+ */
+
+/**
+ * Get a list of all of the tests provided by the system.
+ *
+ * The list of test classes is loaded from the registry where it looks for
+ * files ending in ".test". Once loaded the test list is cached and stored in
+ * a static variable. In order to list tests provided by disabled modules
+ * hook_registry_files_alter() is used to forcefully add them to the registry.
+ *
+ * @return
+ *   An array of tests keyed with the groups specified in each of the tests
+ *   getInfo() method and then keyed by the test class. An example of the array
+ *   structure is provided below.
+ *
+ *   @code
+ *     $groups['Blog'] => array(
+ *       'BlogTestCase' => array(
+ *         'name' => 'Blog functionality',
+ *         'description' => 'Create, view, edit, delete, ...',
+ *         'group' => 'Blog',
+ *       ),
+ *     );
+ *   @endcode
+ * @see simpletest_registry_files_alter()
+ */
+function simpletest_test_get_all() {
+  $groups = &drupal_static(__FUNCTION__);
+
+  if (!$groups) {
+    // Load test information from cache if available, otherwise retrieve the
+    // information from each tests getInfo() method.
+    if ($cache = cache_get('simpletest', 'cache')) {
+      $groups = $cache->data;
+    }
+    else {
+      // Select all clases in files ending with .test.
+      $classes = db_select('registry')
+        ->fields('registry', array('name'))
+        ->condition('type', 'class')
+        ->condition('filename', '%.test', 'LIKE')
+        ->execute();
+
+      $groups = array();
+
+      // Check that each class has a getInfo() method and store the information
+      // in an array keyed with the group specified in the test information.
+      foreach ($classes as $class) {
+        $class = $class->name;
+        if (class_exists($class) && method_exists($class, 'getInfo')) {
+          // Valid test class, retrieve test information.
+          $info = call_user_func(array($class, 'getInfo'));
+
+          // Initialize test groups.
+          if (!isset($groups[$info['group']])) {
+            $groups[$info['group']] = array();
+          }
+          $groups[$info['group']][$class] = $info;
+        }
+      }
+      // Sort the groups and tests within the groups by name.
+      uksort($groups, 'strnatcasecmp');
+      foreach ($groups as $group => &$tests) {
+        uksort($tests, 'strnatcasecmp');
+      }
+
+      cache_set('simpletest', $groups);
+    }
+  }
+  return $groups;
+}
+
+function simpletest_batch_reserve() {
+  return db_insert('simpletest_batch')
+    ->useDefaults(array('batch_id'))
+    ->execute();
+}
+
+function simpletest_batch_queue(array $tests) {
+  $batch_id = simpletest_batch_reserve();
+
+  $queue = DrupalQueue::get('simpletest_' . $batch_id);
+  $queue->createQueue();
+
+  foreach ($tests as $test) {
+    $queue->createItem($test);
+  }
+}
+
+function simpletest_batch_execute_next($batch_id) {
+  $queue = DrupalQueue::get('simpletest_' . $batch_id);
+
+  if ($test = $queue->claimItem()) {
+    $args = array(
+      'op' => 'install',
+    );
+    $info = Database::getConnectionInfo();
+    $args += $info['default'];
+
+    $out = array();
+    foreach ($args as $key => $value) {
+      $out[$key] = "$key=$value";
+    }
+
+    exec('php ./scripts/simpletest.sh ' . implode(' ', $out));
+
+
+    exec('php ./scripts/simpletest.sh op=run ' . $out['prefix']);
+  }
+
+  return $queue->numberOfItems();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: scripts/simpletest.sh
===================================================================
RCS file: scripts/simpletest.sh
diff -N scripts/simpletest.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ scripts/simpletest.sh	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,66 @@
+#!/usr/bin/env php
+<?php
+// $Id$
+
+/**
+ * @file
+ *
+ */
+
+// Process arguments.
+$args = array();
+foreach ($_SERVER['argv'] as $arg) {
+  $parts = explode('=', $arg);
+  if (count($parts) == 2) {
+    $args[$parts[0]] = $parts[1];
+  }
+}
+
+print_r($args); // TODO
+
+// TODO Add security.
+$op = isset($args['op']) ? $args['op'] : '';
+
+if ($op == 'install') {
+  $settings = array(
+    'parameters' => array(
+      'profile' => 'default',
+      'locale' => 'en',
+      'force' => TRUE,
+    ),
+    'forms' => array(
+      'install_settings_form' => array(
+        'driver' => $args['driver'],
+        'database' => $args['database'],
+        'username' => $args['username'],
+        'password' => $args['password'],
+        'prefix' => $args['prefix'],
+        'host' => $args['host'],
+        'port' => $args['port'],
+      ),
+      'install_configure_form' => array(
+        'site_name' => 'Drupal SimpleTest Installation',
+        'site_mail' => 'admin@example.com',
+        'account' => array(
+          'name' => 'admin',
+          'mail' => 'admin@example.com',
+          'pass' => array(
+            'pass1' => 'bigcheese',
+            'pass2' => 'bigcheese',
+          ),
+        ),
+        'update_status_module' => array(1 => FALSE),
+        'clean_url' => $args['clean_url'],
+      ),
+    ),
+  );
+
+  require_once 'install.php';
+  install_drupal($settings);
+}
+elseif ($op == 'run') {
+
+}
+else {
+  echo "\nUnknown operation: $op\n";
+}
Index: modules/simpletest/simpletest.install.inc
===================================================================
RCS file: modules/simpletest/simpletest.install.inc
diff -N modules/simpletest/simpletest.install.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/simpletest.install.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,43 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ *
+ */
+
+define('DRUPAL_ROOT', realpath('../../'));
+define('MAINTENANCE_MODE', 'install');
+
+$settings = array(
+  'parameters' => array(
+    'profile' => 'default',
+    'locale' => 'en',
+  ),
+  'forms' => array(
+    'install_settings_form' => array(
+      'driver' => $_GET['db_driver'],
+      'database' => $_GET['db_database'],
+      'username' => $_GET['db_username'],
+      'password' => $_GET['db_password'],
+    ),
+    'install_configure_form' => array(
+      'site_name' => 'Drupal SimpleTest Installation',
+      'site_mail' => 'admin@example.com',
+      'account' => array(
+        'name' => 'admin',
+        'mail' => 'admin@example.com',
+        'pass' => array(
+          'pass1' => 'bigcheese',
+          'pass2' => 'bigcheese',
+        ),
+      ),
+      'update_status_module' => array(1 => FALSE),
+      'clean_url' => $_GET['clean_url'],
+    ),
+  ),
+);
+
+// Start the installer.
+require_once DRUPAL_ROOT . '/includes/installer.inc';
+install_drupal($settings);
