public function run($request)
 {
     $db = DB::getConn();
     if (!$db instanceof MySQLDatabase) {
         echo '<h3>This task only appies to MySQL databases. This installation is using a ' . get_class($db) . '</h3>';
         return;
     }
     $oldschema = array();
     $newschema = array();
     $renamed = 0;
     $current = DB::getConn()->currentDatabase();
     foreach (DB::getConn()->tableList() as $lowercase => $dbtablename) {
         $oldschema[] = $dbtablename;
     }
     DB::getConn()->selectDatabase('tmpdb');
     $test = new SapphireTest();
     $test->create_temp_db();
     foreach (DB::getConn()->tableList() as $lowercase => $dbtablename) {
         $newschema[] = $dbtablename;
     }
     $test->kill_temp_db();
     DB::getConn()->selectDatabase($current);
     echo "<ul>\n";
     foreach ($newschema as $table) {
         if (in_array(strtolower($table), $oldschema)) {
             echo "<li>renaming {$table}</li>";
             $db->renameTable(strtolower($table), $table);
             $renamed++;
         }
     }
     echo "</ul>\n";
     echo "<p>{$renamed} tables renamed.</p>\n";
 }
 /**
  * @return array
  */
 private function artefacts()
 {
     $oldschema = [];
     $newschema = [];
     $current = DB::get_conn()->getSelectedDatabase();
     foreach (DB::table_list() as $lowercase => $dbtablename) {
         $oldschema[$dbtablename] = DB::field_list($dbtablename);
     }
     $test = new SapphireTest();
     $test->create_temp_db();
     foreach (DB::table_list() as $lowercase => $dbtablename) {
         $newschema[$lowercase] = DB::field_list($dbtablename);
     }
     $test->kill_temp_db();
     DB::get_conn()->selectDatabase($current);
     $artefacts = [];
     foreach ($oldschema as $table => $fields) {
         if (!isset($newschema[strtolower($table)])) {
             $artefacts[$table] = $table;
             continue;
         }
         foreach ($fields as $field => $spec) {
             if (!isset($newschema[strtolower($table)][$field])) {
                 $artefacts[$table][$field] = $field;
             }
         }
     }
     return $artefacts;
 }
 function Artefacts()
 {
     $oldschema = array();
     $newschema = array();
     $current = DB::getConn()->currentDatabase();
     foreach (DB::getConn()->tableList() as $lowercase => $dbtablename) {
         $oldschema[$dbtablename] = DB::getConn()->fieldList($dbtablename);
     }
     DB::getConn()->selectDatabase('tmpdb');
     $test = new SapphireTest();
     $test->create_temp_db();
     foreach (DB::getConn()->tableList() as $lowercase => $dbtablename) {
         $newschema[$lowercase] = DB::getConn()->fieldList($dbtablename);
     }
     $test->kill_temp_db();
     DB::getConn()->selectDatabase($current);
     $artefacts = array();
     foreach ($oldschema as $table => $fields) {
         if (!isset($newschema[strtolower($table)])) {
             $artefacts[$table] = $table;
             continue;
         }
         foreach ($fields as $field => $spec) {
             if (!isset($newschema[strtolower($table)][$field])) {
                 $artefacts[$table][$field] = $field;
             }
         }
     }
     return $artefacts;
 }
示例#4
0
    /**
     * Start a test session.
     * Usage: visit dev/tests/startsession?fixture=(fixturefile).  A test database will be constructed, and your browser session will be amended
     * to use this database.  This can only be run on dev and test sites.
     */
    function startsession()
    {
        if (!Director::isLive()) {
            if (SapphireTest::using_temp_db()) {
                $endLink = Director::baseURL() . "/dev/tests/endsession";
                return "<p><a id=\"end-session\" href=\"{$endLink}\">You're in the middle of a test session; click here to end it.</a></p>";
            } else {
                if (!isset($_GET['fixture'])) {
                    $me = Director::baseURL() . "/dev/tests/startsession";
                    return <<<HTML
<form action="{$me}">\t\t\t\t
\t<p>Enter a fixture file name to start a new test session.  Don't forget to visit dev/tests/endsession when you're done!</p>
\t<p>Fixture file (leave blank to start with default set-up): <input id="fixture-file" name="fixture" /></p>
\t<input type="hidden" name="flush" value="1">
\t<p><input id="start-session" value="Start test session" type="submit" /></p>
</form>
HTML;
                } else {
                    $fixtureFile = $_GET['fixture'];
                    if ($fixtureFile) {
                        // Validate fixture file
                        $realFile = realpath(BASE_PATH . '/' . $fixtureFile);
                        $baseDir = realpath(Director::baseFolder());
                        if (!$realFile || !file_exists($realFile)) {
                            return "<p>Fixture file doesn't exist</p>";
                        } else {
                            if (substr($realFile, 0, strlen($baseDir)) != $baseDir) {
                                return "<p>Fixture file must be inside {$baseDir}</p>";
                            } else {
                                if (substr($realFile, -4) != '.yml') {
                                    return "<p>Fixture file must be a .yml file</p>";
                                } else {
                                    if (!preg_match('/^([^\\/.][^\\/]+)\\/tests\\//', $fixtureFile)) {
                                        return "<p>Fixture file must be inside the tests subfolder of one of your modules.</p>";
                                    }
                                }
                            }
                        }
                    }
                    $dbname = SapphireTest::create_temp_db();
                    DB::set_alternative_database_name($dbname);
                    // Fixture
                    if ($fixtureFile) {
                        $fixture = new YamlFixture($fixtureFile);
                        $fixture->saveIntoDatabase();
                        // If no fixture, then use defaults
                    } else {
                        $dataClasses = ClassInfo::subclassesFor('DataObject');
                        array_shift($dataClasses);
                        foreach ($dataClasses as $dataClass) {
                            singleton($dataClass)->requireDefaultRecords();
                        }
                    }
                    return "<p>Started testing session with fixture '{$fixtureFile}'.  Time to start testing; where would you like to start?</p>\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a id=\"home-link\" href=\"" . Director::baseURL() . "\">Homepage - published site</a></li>\n\t\t\t\t\t\t<li><a id=\"draft-link\" href=\"" . Director::baseURL() . "?stage=Stage\">Homepage - draft site</a></li>\n\t\t\t\t\t\t<li><a id=\"admin-link\" href=\"" . Director::baseURL() . "admin/\">CMS Admin</a></li>\n\t\t\t\t\t\t<li><a id=\"endsession-link\" href=\"" . Director::baseURL() . "dev/tests/endsession\">End your test session</a></li>\n\t\t\t\t\t</ul>";
                }
            }
        } else {
            return "<p>startession can only be used on dev and test sites</p>";
        }
    }
 /**
  * Assumes the database has already been created in startTestSession(), as this method can be called from
  * _config.php where we don't yet have a DB connection.
  *
  * Persists the state to the filesystem.
  *
  * You can extend this by creating an Extension object and implementing either onBeforeApplyState() or
  * onAfterApplyState() to add your own test state handling in.
  *
  * @throws LogicException
  * @throws InvalidArgumentException
  */
 public function applyState($state)
 {
     $this->extend('onBeforeApplyState', $state);
     $database = isset($state->database) ? $state->database : null;
     // back up source
     global $databaseConfig;
     $this->oldDatabaseName = $databaseConfig['database'];
     // Load existing state from $this->state into $state, if there is any
     $oldState = $this->getState();
     if ($oldState) {
         foreach ($oldState as $k => $v) {
             if (!isset($state->{$k})) {
                 $state->{$k} = $v;
                 // Don't overwrite stuff in $state, as that's the new state
             }
         }
     }
     // ensure we have a connection to the database
     if (isset($state->database) && $state->database) {
         if (!DB::get_conn()) {
             // No connection, so try and connect to tmpdb if it exists
             if (isset($state->database)) {
                 $this->oldDatabaseName = $databaseConfig['database'];
                 $databaseConfig['database'] = $state->database;
             }
             // Connect to database
             DB::connect($databaseConfig);
         } else {
             // We've already connected to the database, do a fast check to see what database we're currently using
             $db = DB::get_conn()->getSelectedDatabase();
             if (isset($state->database) && $db != $state->database) {
                 $this->oldDatabaseName = $databaseConfig['database'];
                 $databaseConfig['database'] = $state->database;
                 DB::connect($databaseConfig);
             }
         }
     }
     // Database
     if (!$this->isRunningTests()) {
         $dbName = isset($state->database) ? $state->database : null;
         if ($dbName) {
             $dbExists = DB::get_conn()->databaseExists($dbName);
         } else {
             $dbExists = false;
         }
         if (!$dbExists) {
             // Create a new one with a randomized name
             $dbName = SapphireTest::create_temp_db();
             $state->database = $dbName;
             // In case it's changed by the call to SapphireTest::create_temp_db();
             // Set existing one, assumes it already has been created
             $prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
             $pattern = strtolower(sprintf('#^%stmpdb\\d{7}#', $prefix));
             if (!preg_match($pattern, $dbName)) {
                 throw new InvalidArgumentException("Invalid database name format");
             }
             $this->oldDatabaseName = $databaseConfig['database'];
             $databaseConfig['database'] = $dbName;
             // Instead of calling DB::set_alternative_db_name();
             // Connect to the new database, overwriting the old DB connection (if any)
             DB::connect($databaseConfig);
         }
     }
     // Mailer
     $mailer = isset($state->mailer) ? $state->mailer : null;
     if ($mailer) {
         if (!class_exists($mailer) || !is_subclass_of($mailer, 'Mailer')) {
             throw new InvalidArgumentException(sprintf('Class "%s" is not a valid class, or subclass of Mailer', $mailer));
         }
     }
     // Date and time
     if (isset($state->datetime)) {
         require_once 'Zend/Date.php';
         // Convert DatetimeField format
         if (!Zend_Date::isDate($state->datetime, 'yyyy-MM-dd HH:mm:ss')) {
             throw new LogicException(sprintf('Invalid date format "%s", use yyyy-MM-dd HH:mm:ss', $state->datetime));
         }
     }
     $this->saveState($state);
     $this->extend('onAfterApplyState');
 }
示例#6
0
	function setUp() {
		SapphireTest::create_temp_db();
		SSViewer::flush_template_cache();
	}