From 90997d6d6da3711e03bc46bf79ff08cdedfb2409 Mon Sep 17 00:00:00 2001 From: nicolasconnault Date: Thu, 18 Sep 2008 10:05:20 +0000 Subject: [PATCH] MDL-16486 changed unittest_prefix to unittestprefix --- admin/report/simpletest/index.php | 12 ++-- lib/simpletestlib.php | 113 +++++++++++++++++++++++------- 2 files changed, 94 insertions(+), 31 deletions(-) diff --git a/admin/report/simpletest/index.php b/admin/report/simpletest/index.php index 57590c120a..3550da488c 100644 --- a/admin/report/simpletest/index.php +++ b/admin/report/simpletest/index.php @@ -44,7 +44,7 @@ admin_externalpage_print_header(); $baseurl = $CFG->wwwroot . '/admin/report/simpletest/index.php'; // Add unittest prefix to config.php if needed -if ($addconfigprefix && !isset($CFG->unittest_prefix)) { +if ($addconfigprefix && !isset($CFG->unittestprefix)) { // Open config file, search for $CFG->prefix and append a new line under it $handle = fopen($CFG->dirroot.'/config.php', 'r+'); @@ -55,7 +55,7 @@ if ($addconfigprefix && !isset($CFG->unittest_prefix)) { $prefix_line = null; if (preg_match('/CFG\-\>prefix/', $line, $matches)) { - $prefix_line = "\$CFG->unittest_prefix = '$addconfigprefix';\n"; + $prefix_line = "\$CFG->unittestprefix = '$addconfigprefix';\n"; } $new_file .= $line; @@ -66,10 +66,10 @@ if ($addconfigprefix && !isset($CFG->unittest_prefix)) { $handle = fopen($CFG->dirroot.'/config.php', 'w'); fwrite($handle, $new_file); fclose($handle); - $CFG->unittest_prefix = $addconfigprefix; + $CFG->unittestprefix = $addconfigprefix; } -if (empty($CFG->unittest_prefix)) { +if (empty($CFG->unittestprefix)) { // TODO replace error with proper admin dialog print_box_start('generalbox', 'notice'); echo '

'.get_string("prefixnotset", 'simpletest').'

'; @@ -98,7 +98,7 @@ $CFG->dbuser = $real_cfg->dbuser; $CFG->dbpass = $real_cfg->dbpass; $CFG->dbname = $real_cfg->dbname; $CFG->dbpersist = $real_cfg->dbpersist; -$CFG->unittest_prefix = $real_cfg->unittest_prefix; +$CFG->unittestprefix = $real_cfg->unittestprefix; $CFG->wwwroot = $real_cfg->wwwroot; $CFG->dirroot = $real_cfg->dirroot; $CFG->libdir = $real_cfg->libdir; @@ -112,7 +112,7 @@ $CFG->footer = $real_cfg->footer; $CFG->debug = $real_cfg->debug; $DB = moodle_database::get_driver_instance($CFG->dbtype, $CFG->dblibrary); -$DB->connect($CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->dbpersist, $CFG->unittest_prefix); +$DB->connect($CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->dbpersist, $CFG->unittestprefix); if ($config = $DB->get_records('config')) { foreach ($config as $conf) { diff --git a/lib/simpletestlib.php b/lib/simpletestlib.php index 4646ee1541..0fa6469718 100644 --- a/lib/simpletestlib.php +++ b/lib/simpletestlib.php @@ -152,65 +152,128 @@ class CheckSpecifiedFieldsExpectation extends SimpleExpectation { class MoodleUnitTestCase extends UnitTestCase { public $real_db; public $tables = array(); + public $pkfile; + public $cfg; + /** + * In the constructor, record the max(id) of each test table into a csv file. + * If this file already exists, it means that a previous run of unit tests + * did not complete, and has left data undeleted in the DB. This data is then + * deleted and the file is retained. Otherwise it is created. + * @throws moodle_exception if CSV file cannot be created + */ public function __construct($label = false) { parent::UnitTestCase($label); + // MDL-16483 Get PKs and save data to text file + global $DB, $CFG; + $this->pkfile = $CFG->dataroot.'/testtablespks.csv'; + $this->cfg = $CFG; + + $tables = $DB->get_tables(); + + // The file exists, so use it to truncate tables (tests aborted before test data could be removed) + if (file_exists($this->pkfile)) { + $this->truncate_test_tables($this->get_table_data($this->pkfile)); + + } else { // Create the file + $tabledata = ''; + + foreach ($tables as $table) { + if ($table != 'sessions2') { + if (!$max_id = $DB->get_field_sql("SELECT MAX(id) FROM {$CFG->unittestprefix}{$table}")) { + $max_id = 0; + } + $tabledata .= "$table, $max_id\n"; + } + } + if (!file_put_contents($this->pkfile, $tabledata)) { + throw new moodle_exception('testtablescsvfileunwritable', 'error'); + } + } + } + + /** + * Given an array of tables and their max id, truncates all test table records whose id is higher than the ones in the $tabledata array. + * @param array $tabledata + */ + private function truncate_test_tables($tabledata) { + global $CFG, $DB; + + $tables = $DB->get_tables(); + + foreach ($tables as $table) { + if ($table != 'sessions2' && isset($tabledata[$table])) { + $DB->delete_records_select($table, "id > ?", array($tabledata[$table])); + } + } } + /** + * Given a filename, opens it and parses the csv contained therein. It expects two fields per line: + * 1. Table name + * 2. Max id + * @param string $filename + * @throws moodle_exception if file doesn't exist + */ + public function get_table_data($filename) { + if (file_exists($this->pkfile)) { + $handle = fopen($this->pkfile, 'r'); + $tabledata = array(); + + while (($data = fgetcsv($handle, 1000, ",")) !== false) { + $tabledata[$data[0]] = $data[1]; + } + return $tabledata; + } else { + throw new moodle_exception('testtablescsvfilemissing', 'error'); + return false; + } + } + + /** + * Method called before each test method. Replaces the real $DB with the one configured for unit tests (different prefix, $CFG->unittestprefix). + * Also detects if this config setting is properly set, and if the user table exists. + * TODO Improve detection of incorrectly built DB test tables (e.g. detect version discrepancy and offer to upgrade/rebuild) + */ public function setUp() { global $CFG, $DB; parent::setUp(); $this->real_db = $DB; - if (empty($CFG->unittest_prefix)) { + if (empty($CFG->unittestprefix)) { print_error("prefixnotset", 'simpletest'); } $DB = moodle_database::get_driver_instance($CFG->dbtype, $CFG->dblibrary); - $DB->connect($CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->dbpersist, $CFG->unittest_prefix); + $DB->connect($CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->dbpersist, $CFG->unittestprefix); $manager = $DB->get_manager(); - $tables = $DB->get_tables(); - if (!$manager->table_exists('user')) { print_error('tablesnotsetup', 'simpletest'); } - - $this->tables = $DB->get_tables(); - - foreach ($this->tables as $key => $table) { - if ($table == 'sessions2') { - unset($this->tables[$key]); - continue; - } - - if ($max_id = $DB->get_field_sql("SELECT MAX(id) FROM {$CFG->unittest_prefix}{$table}")) { - $this->tables[$table] = $max_id; - } else { - $this->tables[$table] = 0; - } - } } + /** + * Method called after each test method. Doesn't do anything extraordinary except restore the global $DB to the real one. + */ public function tearDown() { global $DB; parent::tearDown(); - // Truncate all data created during unit tests - foreach ($this->tables as $table => $max_pk) { - $DB->delete_records_select($table, "id > $max_pk"); - } - $DB = $this->real_db; } /** * This will execute once all the tests have been run. It should delete the text file holding info about database contents prior to the tests + * It should also detect if data is missing from the original tables. */ public function __destruct() { - + global $CFG; + $CFG = $this->cfg; + $this->truncate_test_tables($this->get_table_data($this->pkfile)); + fulldelete($this->pkfile); } } -- 2.39.5