Merge branch 'MDL-52333_master' of git://github.com/dmonllao/moodle
[moodle.git] / lib / phpunit / classes / database_driver_testcase.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Database driver test case.
19  *
20  * @package    core
21  * @category   phpunit
22  * @copyright  2012 Petr Skoda {@link http://skodak.org}
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
27 /**
28  * Special test case for testing of DML drivers and DDL layer.
29  *
30  * Note: Use only 'test_table*' names when creating new tables.
31  *
32  * For DML/DDL developers: you can add following settings to config.php if you want to test different driver than the main one,
33  *                         the reason is to allow testing of incomplete drivers that do not allow full PHPUnit environment
34  *                         initialisation (the database can be empty).
35  * $CFG->phpunit_extra_drivers = array(
36  *      1=>array('dbtype'=>'mysqli', 'dbhost'=>'localhost', 'dbname'=>'moodle', 'dbuser'=>'root', 'dbpass'=>'', 'prefix'=>'phpu2_'),
37  *      2=>array('dbtype'=>'pgsql', 'dbhost'=>'localhost', 'dbname'=>'moodle', 'dbuser'=>'postgres', 'dbpass'=>'', 'prefix'=>'phpu2_'),
38  *      3=>array('dbtype'=>'sqlsrv', 'dbhost'=>'127.0.0.1', 'dbname'=>'moodle', 'dbuser'=>'sa', 'dbpass'=>'', 'prefix'=>'phpu2_'),
39  *      4=>array('dbtype'=>'oci', 'dbhost'=>'127.0.0.1', 'dbname'=>'XE', 'dbuser'=>'sa', 'dbpass'=>'', 'prefix'=>'t_'),
40  * );
41  * define('PHPUNIT_TEST_DRIVER')=1; //number is index in the previous array
42  *
43  * @package    core
44  * @category   phpunit
45  * @copyright  2012 Petr Skoda {@link http://skodak.org}
46  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
47  */
48 abstract class database_driver_testcase extends base_testcase {
49     /** @var moodle_database connection to extra database */
50     private static $extradb = null;
52     /** @var moodle_database used in these tests*/
53     protected $tdb;
55     /**
56      * Constructs a test case with the given name.
57      *
58      * @param string $name
59      * @param array  $data
60      * @param string $dataName
61      */
62     final public function __construct($name = null, array $data = array(), $dataName = '') {
63         parent::__construct($name, $data, $dataName);
65         $this->setBackupGlobals(false);
66         $this->setBackupStaticAttributes(false);
67         $this->setRunTestInSeparateProcess(false);
68     }
70     public static function setUpBeforeClass() {
71         global $CFG;
72         parent::setUpBeforeClass();
74         if (!defined('PHPUNIT_TEST_DRIVER')) {
75             // use normal $DB
76             return;
77         }
79         if (!isset($CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER])) {
80             throw new exception('Can not find driver configuration options with index: '.PHPUNIT_TEST_DRIVER);
81         }
83         $dblibrary = empty($CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dblibrary']) ? 'native' : $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dblibrary'];
84         $dbtype = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbtype'];
85         $dbhost = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbhost'];
86         $dbname = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbname'];
87         $dbuser = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbuser'];
88         $dbpass = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbpass'];
89         $prefix = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['prefix'];
90         $dboptions = empty($CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dboptions']) ? array() : $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dboptions'];
92         $classname = "{$dbtype}_{$dblibrary}_moodle_database";
93         require_once("$CFG->libdir/dml/$classname.php");
94         $d = new $classname();
95         if (!$d->driver_installed()) {
96             throw new exception('Database driver for '.$classname.' is not installed');
97         }
99         $d->connect($dbhost, $dbuser, $dbpass, $dbname, $prefix, $dboptions);
101         self::$extradb = $d;
102     }
104     protected function setUp() {
105         global $DB;
106         parent::setUp();
108         if (self::$extradb) {
109             $this->tdb = self::$extradb;
110         } else {
111             $this->tdb = $DB;
112         }
113     }
115     protected function tearDown() {
116         // delete all test tables
117         $dbman = $this->tdb->get_manager();
118         $tables = $this->tdb->get_tables(false);
119         foreach($tables as $tablename) {
120             if (strpos($tablename, 'test_table') === 0) {
121                 $table = new xmldb_table($tablename);
122                 $dbman->drop_table($table);
123             }
124         }
125         parent::tearDown();
126     }
128     public static function tearDownAfterClass() {
129         if (self::$extradb) {
130             self::$extradb->dispose();
131             self::$extradb = null;
132         }
133         phpunit_util::reset_all_data(null);
134         parent::tearDownAfterClass();
135     }
137     /**
138      * Runs the bare test sequence.
139      * @return void
140      */
141     public function runBare() {
142         try {
143             parent::runBare();
145         } catch (Exception $e) {
146             if ($this->tdb->is_transaction_started()) {
147                 $this->tdb->force_transaction_rollback();
148             }
149             $this->tearDown();
150             throw $e;
151         }
152     }
154     /**
155      * Return debugging messages from the current test.
156      * @return array with instances having 'message', 'level' and 'stacktrace' property.
157      */
158     public function getDebuggingMessages() {
159         return phpunit_util::get_debugging_messages();
160     }
162     /**
163      * Clear all previous debugging messages in current test.
164      */
165     public function resetDebugging() {
166         phpunit_util::reset_debugging();
167     }
169     /**
170      * Assert that exactly debugging was just called once.
171      *
172      * Discards the debugging message if successful.
173      *
174      * @param null|string $debugmessage null means any
175      * @param null|string $debuglevel null means any
176      * @param string $message
177      */
178     public function assertDebuggingCalled($debugmessage = null, $debuglevel = null, $message = '') {
179         $debugging = $this->getDebuggingMessages();
180         $count = count($debugging);
182         if ($count == 0) {
183             if ($message === '') {
184                 $message = 'Expectation failed, debugging() not triggered.';
185             }
186             $this->fail($message);
187         }
188         if ($count > 1) {
189             if ($message === '') {
190                 $message = 'Expectation failed, debugging() triggered '.$count.' times.';
191             }
192             $this->fail($message);
193         }
194         $this->assertEquals(1, $count);
196         $debug = reset($debugging);
197         if ($debugmessage !== null) {
198             $this->assertSame($debugmessage, $debug->message, $message);
199         }
200         if ($debuglevel !== null) {
201             $this->assertSame($debuglevel, $debug->level, $message);
202         }
204         $this->resetDebugging();
205     }
207     /**
208      * Call when no debugging() messages expected.
209      * @param string $message
210      */
211     public function assertDebuggingNotCalled($message = '') {
212         $debugging = $this->getDebuggingMessages();
213         $count = count($debugging);
215         if ($message === '') {
216             $message = 'Expectation failed, debugging() was triggered.';
217         }
218         $this->assertEquals(0, $count, $message);
219     }