2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Utils for behat-related stuff
22 * @copyright 2012 David Monllaó
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
28 require_once(__DIR__ . '/../lib.php');
29 require_once(__DIR__ . '/../../testing/classes/util.php');
30 require_once(__DIR__ . '/behat_command.php');
31 require_once(__DIR__ . '/behat_config_manager.php');
33 require_once(__DIR__ . '/../../filelib.php');
36 * Init/reset utilities for Behat database and dataroot
40 * @copyright 2013 David Monllaó
41 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43 class behat_util extends testing_util {
46 * The behat test site fullname and shortname.
48 const BEHATSITENAME = "Acceptance test site";
51 * @var array Files to skip when resetting dataroot folder
53 protected static $datarootskiponreset = array('.', '..', 'behat', 'behattestdir.txt');
56 * @var array Files to skip when dropping dataroot folder
58 protected static $datarootskipondrop = array('.', '..', 'lock');
61 * Installs a site using $CFG->dataroot and $CFG->prefix
62 * @throws coding_exception
65 public static function install_site() {
67 require_once($CFG->dirroot.'/user/lib.php');
68 if (!defined('BEHAT_UTIL')) {
69 throw new coding_exception('This method can be only used by Behat CLI tool');
72 $tables = $DB->get_tables(false);
73 if (!empty($tables)) {
74 behat_error(BEHAT_EXITCODE_INSTALLED);
78 self::reset_dataroot();
81 $options['adminuser'] = 'admin';
82 $options['adminpass'] = 'admin';
83 $options['fullname'] = self::BEHATSITENAME;
84 $options['shortname'] = self::BEHATSITENAME;
86 install_cli_database($options, false);
88 // We need to keep the installed dataroot filedir files.
89 // So each time we reset the dataroot before running a test, the default files are still installed.
90 self::save_original_data_files();
92 $frontpagesummary = new admin_setting_special_frontpagedesc();
93 $frontpagesummary->write_setting(self::BEHATSITENAME);
95 // Update admin user info.
96 $user = $DB->get_record('user', array('username' => 'admin'));
97 $user->email = 'moodle@example.com';
98 $user->firstname = 'Admin';
99 $user->lastname = 'User';
100 $user->city = 'Perth';
101 $user->country = 'AU';
102 user_update_user($user, false);
104 // Disable email message processor.
105 $DB->set_field('message_processors', 'enabled', '0', array('name' => 'email'));
107 // Sets maximum debug level.
108 set_config('debug', DEBUG_DEVELOPER);
109 set_config('debugdisplay', 1);
111 // Disable some settings that are not wanted on test sites.
112 set_config('noemailever', 1);
115 set_config('cronclionly', 0);
117 // Keeps the current version of database and dataroot.
118 self::store_versions_hash();
120 // Stores the database contents for fast reset.
121 self::store_database_state();
125 * Drops dataroot and remove test database tables
126 * @throws coding_exception
129 public static function drop_site() {
131 if (!defined('BEHAT_UTIL')) {
132 throw new coding_exception('This method can be only used by Behat CLI tool');
135 self::reset_dataroot();
136 self::drop_dataroot();
137 self::drop_database(true);
141 * Checks if $CFG->behat_wwwroot is available and using same versions for cli and web.
145 public static function check_server_status() {
148 $url = $CFG->behat_wwwroot . '/admin/tool/behat/tests/behat/fixtures/environment.php';
150 // Get web versions used by behat site.
151 $ch = curl_init($url);
152 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
153 $result = curl_exec($ch);
154 $statuscode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
157 if ($statuscode !== 200 || empty($result) || (!$result = json_decode($result, true))) {
159 behat_error (BEHAT_EXITCODE_REQUIREMENT, $CFG->behat_wwwroot . ' is not available, ensure you specified ' .
160 'correct url and that the server is set up and started.' . PHP_EOL . ' More info in ' .
161 behat_command::DOCS_URL . '#Running_tests' . PHP_EOL);
164 // Check if cli version is same as web version.
165 $clienv = self::get_environment();
166 if ($result != $clienv) {
167 $output = 'Differences detected between cli and webserver...'.PHP_EOL;
168 foreach ($result as $key => $version) {
169 if ($clienv[$key] != $version) {
170 $output .= ' ' . $key . ': ' . PHP_EOL;
171 $output .= ' - web server: ' . $version . PHP_EOL;
172 $output .= ' - cli: ' . $clienv[$key] . PHP_EOL;
181 * Checks whether the test database and dataroot is ready
182 * Stops execution if something went wrong
183 * @throws coding_exception
186 protected static function test_environment_problem() {
189 if (!defined('BEHAT_UTIL')) {
190 throw new coding_exception('This method can be only used by Behat CLI tool');
193 if (!self::is_test_site()) {
194 behat_error(1, 'This is not a behat test site!');
197 $tables = $DB->get_tables(false);
198 if (empty($tables)) {
199 behat_error(BEHAT_EXITCODE_INSTALL, '');
202 if (!self::is_test_data_updated()) {
203 behat_error(BEHAT_EXITCODE_REINSTALL, 'The test environment was initialised for a different version');
210 * It uses CFG->behat_dataroot
212 * Starts the test mode checking the composer installation and
213 * the test environment and updating the available
214 * features and steps definitions.
216 * Stores a file in dataroot/behat to allow Moodle to switch
217 * to the test environment when using cli-server.
218 * @throws coding_exception
221 public static function start_test_mode() {
224 if (!defined('BEHAT_UTIL')) {
225 throw new coding_exception('This method can be only used by Behat CLI tool');
228 // Checks the behat set up and the PHP version.
229 if ($errorcode = behat_command::behat_setup_problem()) {
233 // Check that test environment is correctly set up.
234 self::test_environment_problem();
236 // Updates all the Moodle features and steps definitions.
237 behat_config_manager::update_config_file();
239 if (self::is_test_mode_enabled()) {
243 $contents = '$CFG->behat_wwwroot, $CFG->behat_prefix and $CFG->behat_dataroot' .
244 ' are currently used as $CFG->wwwroot, $CFG->prefix and $CFG->dataroot';
245 $filepath = self::get_test_file_path();
246 if (!file_put_contents($filepath, $contents)) {
247 behat_error(BEHAT_EXITCODE_PERMISSIONS, 'File ' . $filepath . ' can not be created');
252 * Returns the status of the behat test environment
254 * @return int Error code
256 public static function get_behat_status() {
258 if (!defined('BEHAT_UTIL')) {
259 throw new coding_exception('This method can be only used by Behat CLI tool');
262 // Checks the behat set up and the PHP version, returning an error code if something went wrong.
263 if ($errorcode = behat_command::behat_setup_problem()) {
267 // Check that test environment is correctly set up, stops execution.
268 self::test_environment_problem();
273 * @throws coding_exception
276 public static function stop_test_mode() {
278 if (!defined('BEHAT_UTIL')) {
279 throw new coding_exception('This method can be only used by Behat CLI tool');
282 $testenvfile = self::get_test_file_path();
284 if (!self::is_test_mode_enabled()) {
285 echo "Test environment was already disabled\n";
287 if (!unlink($testenvfile)) {
288 behat_error(BEHAT_EXITCODE_PERMISSIONS, 'Can not delete test environment file');
294 * Checks whether test environment is enabled or disabled
296 * To check is the current script is running in the test
301 public static function is_test_mode_enabled() {
303 $testenvfile = self::get_test_file_path();
304 if (file_exists($testenvfile)) {
312 * Returns the path to the file which specifies if test environment is enabled
315 protected final static function get_test_file_path() {
316 return behat_command::get_behat_dir() . '/test_environment_enabled.txt';
320 * Reset contents of all database tables to initial values, reset caches, etc.
322 public static function reset_all_data() {
324 self::reset_database();
326 // Purge dataroot directory.
327 self::reset_dataroot();
329 // Reset all static caches.
330 accesslib_clear_all_caches(true);
331 // Reset the nasty strings list used during the last test.
332 nasty_strings::reset_used_strings();
334 filter_manager::reset_caches();
336 // Reset course and module caches.
337 if (class_exists('format_base')) {
338 // If file containing class is not loaded, there is no cache there anyway.
339 format_base::reset_course_cache(0);
341 get_fast_modinfo(0, 0, true);
343 // Inform data generator.
344 self::get_data_generator()->reset();