示例#1
0
 function connectDatabase()
 {
     $this->enum_map = array();
     $parameters = $this->parameters;
     $dbName = !isset($this->database) ? $parameters['database'] : ($dbName = $this->database);
     //assumes that the path to dbname will always be provided:
     $file = $parameters['path'] . '/' . $dbName;
     // use the very lightspeed SQLite In-Memory feature for testing
     if (SapphireTest::using_temp_db() && $parameters['memory']) {
         $file = ':memory:';
         $this->lives_in_memory = true;
     } else {
         $this->lives_in_memory = false;
     }
     if (!file_exists($parameters['path'])) {
         SQLiteDatabaseConfigurationHelper::create_db_dir($parameters['path']);
         SQLiteDatabaseConfigurationHelper::secure_db_dir($parameters['path']);
     }
     $this->dbConn = new PDO("sqlite:{$file}");
     //By virtue of getting here, the connection is active:
     $this->active = true;
     $this->database = $dbName;
     if (!$this->dbConn) {
         $this->databaseError("Couldn't connect to SQLite3 database");
         return false;
     }
     foreach (self::$default_pragma as $pragma => $value) {
         $this->pragma($pragma, $value);
     }
     if (empty(self::$default_pragma['locking_mode'])) {
         self::$default_pragma['locking_mode'] = $this->pragma('locking_mode');
     }
     return true;
 }
示例#2
0
    function sessionloadyml()
    {
        // Load incremental YAML fixtures
        // TODO: We will probably have to filter out the admin member here,
        // as it is supplied by Bare.yml
        if (Director::isLive()) {
            return "<p>sessionloadyml can only be used on dev and test sites</p>";
        }
        if (!SapphireTest::using_temp_db()) {
            return "<p>Please load /dev/tests/startsession first</p>";
        }
        $fixtureFile = isset($_GET['fixture']) ? $_GET['fixture'] : null;
        if (empty($fixtureFile)) {
            $me = Director::baseURL() . "/dev/tests/sessionloadyml";
            return <<<HTML
\t\t\t\t<form action="{$me}">
\t\t\t\t\t<p>Enter a fixture file name to load a new YAML fixture into the session.</p>
\t\t\t\t\t<p>Fixture file <input id="fixture-file" name="fixture" /></p>
\t\t\t\t\t<input type="hidden" name="flush" value="1">
\t\t\t\t\t<p><input id="session-load-yaml" value="Load yml fixture" type="submit" /></p>
\t\t\t\t</form>
HTML;
        }
        // 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>";
                    }
                }
            }
        }
        // Fixture
        $fixture = new YamlFixture($fixtureFile);
        $fixture->saveIntoDatabase();
        return "<p>Loaded fixture '{$fixtureFile}' into session</p>";
    }
 /**
  * Cleans up the test session state by restoring the normal database connect (for the rest of this request, if any)
  * and removes the {@link self::$test_state_file} so that future requests don't use this test state.
  *
  * Can be extended by implementing either onBeforeEndTestSession() or onAfterEndTestSession().
  *
  * This should implement itself cleanly in case it is called twice (e.g. don't throw errors when the state file
  * doesn't exist anymore because it's already been cleaned up etc.) This is because during behat test runs where
  * a queueing system (e.g. silverstripe-resque) is used, the behat module may call this first, and then the forked
  * worker will call it as well - but there is only one state file that is created.
  */
 public function endTestSession()
 {
     $this->extend('onBeforeEndTestSession');
     if (SapphireTest::using_temp_db()) {
         $state = $this->getState();
         $dbConn = DB::getConn();
         $dbExists = $dbConn->databaseExists($state->database);
         if ($dbExists) {
             // Clean up temp database
             $dbConn->dropDatabase();
             file_put_contents('php://stdout', "Deleted temp database: {$state->database}" . PHP_EOL);
         }
         // End test session mode
         $this->resetDatabaseName();
         SapphireTest::set_is_running_test(false);
     }
     $this->removeStateFile();
     $this->extend('onAfterEndTestSession');
 }
示例#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">				
	<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>
	<p>Fixture file: <input id="fixture-file" name="fixture" /></p>
	<input type="hidden" name="flush" value="1">
	<p><input id="start-session" value="Start test session" type="submit" /></p>
</form>
HTML;
			} else {
				$fixtureFile = $_GET['fixture'];
			
				// Validate fixture file
				$realFile = realpath('../' . $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 = new YamlFixture($_GET['fixture']);
				$fixture->saveIntoDatabase();
				
				return "<p>Started testing session with fixture '$fixtureFile'.  Time to start testing; where would you like to start?</p>
					<ul>
						<li><a id=\"home-link\" href=\"" .Director::baseURL() . "\">Homepage - published site</a></li>
						<li><a id=\"draft-link\" href=\"" .Director::baseURL() . "?stage=Stage\">Homepage - draft site</a></li>
						<li><a id=\"admin-link\" href=\"" .Director::baseURL() . "admin/\">CMS Admin</a></li>
					</ul>";
			}
						
		} else {
			return "<p>startession can only be used on dev and test sites</p>";
		}
	}
 /**
  * Cleans up the test session state by restoring the normal database connect (for the rest of this request, if any)
  * and removes the {@link self::$test_state_file} so that future requests don't use this test state.
  *
  * Can be extended by implementing either onBeforeEndTestSession() or onAfterEndTestSession().
  *
  * This should implement itself cleanly in case it is called twice (e.g. don't throw errors when the state file
  * doesn't exist anymore because it's already been cleaned up etc.) This is because during behat test runs where
  * a queueing system (e.g. silverstripe-resque) is used, the behat module may call this first, and then the forked
  * worker will call it as well - but there is only one state file that is created.
  */
 public function endTestSession()
 {
     $this->extend('onBeforeEndTestSession');
     if (SapphireTest::using_temp_db()) {
         $this->resetDatabaseName();
         SapphireTest::set_is_running_test(false);
     }
     $this->removeStateFile();
     $this->extend('onAfterEndTestSession');
 }
 /**
  * @return boolean
  */
 public function isTesting()
 {
     return SapphireTest::using_temp_db();
 }
 public function checkAndRepairTable($tableName = null)
 {
     $ok = true;
     if (!SapphireTest::using_temp_db() && !self::$checked_and_repaired) {
         $this->alterationMessage("Checking database integrity", "repaired");
         // Check for any tables with failed integrity
         if ($messages = $this->query('PRAGMA integrity_check')) {
             foreach ($messages as $message) {
                 if ($message['integrity_check'] != 'ok') {
                     Debug::show($message['integrity_check']);
                     $ok = false;
                 }
             }
         }
         // If enabled vacuum (clean and rebuild) the database
         if (self::$vacuum) {
             $this->query('VACUUM', E_USER_NOTICE);
             $message = $this->database->getConnector()->getLastError();
             if (preg_match('/authoriz/', $message)) {
                 $this->alterationMessage("VACUUM | {$message}", "error");
             } else {
                 $this->alterationMessage("VACUUMing", "repaired");
             }
         }
         self::$checked_and_repaired = true;
     }
     return $ok;
 }
 /**
  * Repairs and reindexes the table.  This might take a long time on a very large table.
  * @var string $tableName The name of the table.
  * @return boolean Return true if the table has integrity after the method is complete.
  */
 public function checkAndRepairTable($tableName = null)
 {
     $ok = true;
     if (!SapphireTest::using_temp_db() && !self::$checked_and_repaired) {
         $this->alterationMessage("Checking database integrity", "repaired");
         if ($msgs = $this->query('PRAGMA integrity_check')) {
             foreach ($msgs as $msg) {
                 if ($msg['integrity_check'] != 'ok') {
                     Debug::show($msg['integrity_check']);
                     $ok = false;
                 }
             }
         }
         if (self::$vacuum) {
             $this->query('VACUUM', E_USER_NOTICE);
             if ($this instanceof SQLitePDODatabase) {
                 $msg = $this->dbConn->errorInfo();
                 $msg = isset($msg[2]) ? $msg[2] : 'no errors';
             } else {
                 $msg = $this->dbConn->lastErrorMsg();
             }
             if (preg_match('/authoriz/', $msg)) {
                 $this->alterationMessage('VACUUM | ' . $msg, "error");
             } else {
                 $this->alterationMessage("VACUUMing", "repaired");
             }
         }
         self::$checked_and_repaired = true;
     }
     return $ok;
 }