Load test data from database dumps

This commit is contained in:
Ingo Schommer 2013-12-12 14:18:18 +01:00
parent 89a429c6a5
commit 356446d4cb
3 changed files with 80 additions and 1 deletions

View File

@ -5,7 +5,7 @@
This module starts a testing session in a browser,
in order to test a SilverStripe application in a clean state.
Usually the session is started on a fresh database with only default records loaded.
Further data can be loaded from YAML fixtures.
Further data can be loaded from YAML fixtures or database dumps.
The module also serves as an initializer for the
[SilverStripe Behat Extension](https://github.com/silverstripe-labs/silverstripe-behat-extension/).
@ -47,6 +47,7 @@ Parameters for "dev/testsession/start":
(see [fixture format docs](http://doc.silverstripe.org/framework/en/topics/testing/fixtures)).
The path should be relative to the webroot.
* `createDatabase`: Create a temporary database.
* `createDatabaseTemplate`: Path to a database dump to load into a newly created temporary database.
* `database`: Set an alternative database name in the current
browser session as a cookie. Does not actually create the database,
that's usually handled by `SapphireTest::create_temp_db()`.

View File

@ -16,6 +16,11 @@ class TestSessionController extends Controller {
private static $alternative_database_name = -1;
/**
* @var String Absolute path to a folder containing *.sql dumps.
*/
private static $database_templates_path;
public function init() {
parent::init();
@ -24,6 +29,9 @@ class TestSessionController extends Controller {
&& (Director::isDev() || Director::isTest() || Director::is_cli() || Permission::check("ADMIN"))
);
if(!$canAccess) return Security::permissionFailure($this);
Requirements::javascript('framework/thirdparty/jquery/jquery.js');
Requirements::javascript('testsession/javascript/testsession.js');
}
public function Link($action = null) {
@ -51,9 +59,17 @@ class TestSessionController extends Controller {
}
public function StartForm() {
$databaseTemplates = $this->getDatabaseTemplates();
$fields = new FieldList(
new CheckboxField('createDatabase', 'Create temporary database?', 1)
);
if($databaseTemplates) {
$fields->push(
(new DropdownField('createDatabaseTemplate', false))
->setSource($databaseTemplates)
->setEmptyString('Empty database')
);
}
$fields->merge($this->getBaseFields());
$form = new Form(
$this,
@ -252,6 +268,27 @@ class TestSessionController extends Controller {
global $databaseConfig;
DB::connect(array_merge($databaseConfig, array('database' => $dbName)));
if(isset($data['database'])) unset($data['database']);
// Import database template if required
if(isset($data['createDatabaseTemplate']) && $data['createDatabaseTemplate']) {
$sql = file_get_contents($data['createDatabaseTemplate']);
// Split into individual query commands, removing comments
$sqlCmds = array_filter(
preg_split('/\s*;\s*/',
preg_replace(array('/^$\n/m', '/^(\/|#).*$\n/m'), '', $sql)
)
);
// Execute each query
foreach($sqlCmds as $sqlCmd) {
DB::query($sqlCmd);
}
// In case the dump involved CREATE TABLE commands, we need to ensure
// the schema is still up to date
$dbAdmin = new DatabaseAdmin();
$dbAdmin->doBuild(true /*quiet*/, false /*populate*/);
}
}
// Fixtures
@ -321,4 +358,34 @@ class TestSessionController extends Controller {
return new ArrayList($state);
}
/**
* Get all *.sql database files located in a specific path,
* keyed by their file name.
*
* @param String $path Absolute folder path
* @return array
*/
protected function getDatabaseTemplates($path = null) {
$templates = array();
if(!$path) {
$path = $this->config()->database_templates_path;
}
// TODO Remove once we can set BASE_PATH through the config layer
if($path && !Director::is_absolute($path)) {
$path = BASE_PATH . '/' . $path;
}
if($path && file_exists($path)) {
$it = new FilesystemIterator($path);
foreach($it as $fileinfo) {
if($fileinfo->getExtension() != 'sql') continue;
$templates[$fileinfo->getRealPath()] = $fileinfo->getFilename();
}
}
return $templates;
}
}

11
javascript/testsession.js Normal file
View File

@ -0,0 +1,11 @@
(function($) {
$(document).ready(function() {
// Only show database templates when "create database" is selected
var tmplField = $('#createDatabaseTemplate'),
createField = $('#createDatabase input'),
toggleFn = function() {tmplField.toggle(createField.is(':checked'));};
toggleFn();
createField.click(toggleFn);
});
}(jQuery));