MDL-54553 behat: check statuscode of http request
[moodle.git] / lib / behat / classes / util.php
CommitLineData
096858ed
DM
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/>.
16
17/**
18 * Utils for behat-related stuff
19 *
20 * @package core
21 * @category test
22 * @copyright 2012 David Monllaó
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28require_once(__DIR__ . '/../lib.php');
29require_once(__DIR__ . '/../../testing/classes/util.php');
30require_once(__DIR__ . '/behat_command.php');
31require_once(__DIR__ . '/behat_config_manager.php');
32
33require_once(__DIR__ . '/../../filelib.php');
34
35/**
36 * Init/reset utilities for Behat database and dataroot
37 *
38 * @package core
39 * @category test
40 * @copyright 2013 David Monllaó
41 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42 */
43class behat_util extends testing_util {
44
19f6703d
DM
45 /**
46 * The behat test site fullname and shortname.
47 */
48 const BEHATSITENAME = "Acceptance test site";
49
096858ed
DM
50 /**
51 * @var array Files to skip when resetting dataroot folder
52 */
53 protected static $datarootskiponreset = array('.', '..', 'behat', 'behattestdir.txt');
54
55 /**
56 * @var array Files to skip when dropping dataroot folder
57 */
58 protected static $datarootskipondrop = array('.', '..', 'lock');
59
60 /**
61 * Installs a site using $CFG->dataroot and $CFG->prefix
62 * @throws coding_exception
63 * @return void
64 */
65 public static function install_site() {
bb78e249
RT
66 global $DB, $CFG;
67 require_once($CFG->dirroot.'/user/lib.php');
096858ed
DM
68 if (!defined('BEHAT_UTIL')) {
69 throw new coding_exception('This method can be only used by Behat CLI tool');
70 }
71
0e825e5d
DM
72 $tables = $DB->get_tables(false);
73 if (!empty($tables)) {
74 behat_error(BEHAT_EXITCODE_INSTALLED);
75 }
76
096858ed
DM
77 // New dataroot.
78 self::reset_dataroot();
79
80 $options = array();
81 $options['adminuser'] = 'admin';
82 $options['adminpass'] = 'admin';
19f6703d
DM
83 $options['fullname'] = self::BEHATSITENAME;
84 $options['shortname'] = self::BEHATSITENAME;
096858ed
DM
85
86 install_cli_database($options, false);
87
c78f19d1
JM
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();
91
a0e89a8f
DM
92 $frontpagesummary = new admin_setting_special_frontpagedesc();
93 $frontpagesummary->write_setting(self::BEHATSITENAME);
94
096858ed
DM
95 // Update admin user info.
96 $user = $DB->get_record('user', array('username' => 'admin'));
0fe86bbd 97 $user->email = 'moodle@example.com';
096858ed
DM
98 $user->firstname = 'Admin';
99 $user->lastname = 'User';
100 $user->city = 'Perth';
101 $user->country = 'AU';
bb78e249 102 user_update_user($user, false);
096858ed 103
a34c0b13
DM
104 // Disable email message processor.
105 $DB->set_field('message_processors', 'enabled', '0', array('name' => 'email'));
106
096858ed
DM
107 // Sets maximum debug level.
108 set_config('debug', DEBUG_DEVELOPER);
60129d5d
PS
109 set_config('debugdisplay', 1);
110
111 // Disable some settings that are not wanted on test sites.
112 set_config('noemailever', 1);
096858ed 113
bbcd3083
AA
114 // Enable web cron.
115 set_config('cronclionly', 0);
116
096858ed
DM
117 // Keeps the current version of database and dataroot.
118 self::store_versions_hash();
119
120 // Stores the database contents for fast reset.
121 self::store_database_state();
122 }
123
124 /**
125 * Drops dataroot and remove test database tables
126 * @throws coding_exception
127 * @return void
128 */
129 public static function drop_site() {
130
131 if (!defined('BEHAT_UTIL')) {
132 throw new coding_exception('This method can be only used by Behat CLI tool');
133 }
134
135 self::reset_dataroot();
136 self::drop_dataroot();
137 self::drop_database(true);
138 }
139
140 /**
e891c838 141 * Checks if $CFG->behat_wwwroot is available and using same versions for cli and web.
096858ed 142 *
e891c838 143 * @return void
096858ed 144 */
e891c838 145 public static function check_server_status() {
096858ed
DM
146 global $CFG;
147
e891c838
RT
148 $url = $CFG->behat_wwwroot . '/admin/tool/behat/tests/behat/fixtures/environment.php';
149
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);
5c602bf5 154 $statuscode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
e891c838
RT
155 curl_close($ch);
156
5c602bf5 157 if ($statuscode !== 200 || empty($result) || (!$result = json_decode($result, true))) {
e891c838
RT
158
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);
162 }
475ac3f8 163
e891c838 164 // Check if cli version is same as web version.
e891c838
RT
165 $clienv = self::get_environment();
166 if ($result != $clienv) {
e45aac5f 167 $output = 'Differences detected between cli and webserver...'.PHP_EOL;
e891c838
RT
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;
173 }
174 }
175 echo $output;
80c3b484 176 ob_flush();
475ac3f8 177 }
096858ed
DM
178 }
179
180 /**
181 * Checks whether the test database and dataroot is ready
182 * Stops execution if something went wrong
183 * @throws coding_exception
184 * @return void
185 */
186 protected static function test_environment_problem() {
187 global $CFG, $DB;
188
189 if (!defined('BEHAT_UTIL')) {
190 throw new coding_exception('This method can be only used by Behat CLI tool');
191 }
192
193 if (!self::is_test_site()) {
194 behat_error(1, 'This is not a behat test site!');
195 }
196
197 $tables = $DB->get_tables(false);
198 if (empty($tables)) {
199 behat_error(BEHAT_EXITCODE_INSTALL, '');
200 }
201
202 if (!self::is_test_data_updated()) {
203 behat_error(BEHAT_EXITCODE_REINSTALL, 'The test environment was initialised for a different version');
204 }
205 }
206
207 /**
208 * Enables test mode
209 *
210 * It uses CFG->behat_dataroot
211 *
212 * Starts the test mode checking the composer installation and
213 * the test environment and updating the available
214 * features and steps definitions.
215 *
216 * Stores a file in dataroot/behat to allow Moodle to switch
60129d5d 217 * to the test environment when using cli-server.
096858ed
DM
218 * @throws coding_exception
219 * @return void
220 */
221 public static function start_test_mode() {
222 global $CFG;
223
224 if (!defined('BEHAT_UTIL')) {
225 throw new coding_exception('This method can be only used by Behat CLI tool');
226 }
227
228 // Checks the behat set up and the PHP version.
9bb80d20 229 if ($errorcode = behat_command::behat_setup_problem()) {
6fe3986d 230 exit($errorcode);
fa7e4e2b 231 }
096858ed
DM
232
233 // Check that test environment is correctly set up.
234 self::test_environment_problem();
235
236 // Updates all the Moodle features and steps definitions.
237 behat_config_manager::update_config_file();
238
239 if (self::is_test_mode_enabled()) {
240 return;
241 }
242
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');
248 }
249 }
250
fa7e4e2b
DM
251 /**
252 * Returns the status of the behat test environment
253 *
254 * @return int Error code
255 */
256 public static function get_behat_status() {
257
258 if (!defined('BEHAT_UTIL')) {
259 throw new coding_exception('This method can be only used by Behat CLI tool');
260 }
261
262 // Checks the behat set up and the PHP version, returning an error code if something went wrong.
9bb80d20 263 if ($errorcode = behat_command::behat_setup_problem()) {
6fe3986d 264 return $errorcode;
fa7e4e2b
DM
265 }
266
267 // Check that test environment is correctly set up, stops execution.
268 self::test_environment_problem();
269 }
270
096858ed
DM
271 /**
272 * Disables test mode
273 * @throws coding_exception
274 * @return void
275 */
276 public static function stop_test_mode() {
277
278 if (!defined('BEHAT_UTIL')) {
279 throw new coding_exception('This method can be only used by Behat CLI tool');
280 }
281
282 $testenvfile = self::get_test_file_path();
283
284 if (!self::is_test_mode_enabled()) {
285 echo "Test environment was already disabled\n";
286 } else {
287 if (!unlink($testenvfile)) {
288 behat_error(BEHAT_EXITCODE_PERMISSIONS, 'Can not delete test environment file');
289 }
290 }
291 }
292
293 /**
294 * Checks whether test environment is enabled or disabled
295 *
296 * To check is the current script is running in the test
297 * environment
298 *
096858ed
DM
299 * @return bool
300 */
301 public static function is_test_mode_enabled() {
302
303 $testenvfile = self::get_test_file_path();
304 if (file_exists($testenvfile)) {
305 return true;
306 }
307
308 return false;
309 }
310
096858ed
DM
311 /**
312 * Returns the path to the file which specifies if test environment is enabled
313 * @return string
314 */
315 protected final static function get_test_file_path() {
316 return behat_command::get_behat_dir() . '/test_environment_enabled.txt';
317 }
318
ef1d45b3
RT
319 /**
320 * Reset contents of all database tables to initial values, reset caches, etc.
321 */
322 public static function reset_all_data() {
064b8b7f
TL
323 // Reset database.
324 self::reset_database();
325
326 // Purge dataroot directory.
327 self::reset_dataroot();
328
ef1d45b3
RT
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();
333
334 filter_manager::reset_caches();
335
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);
340 }
341 get_fast_modinfo(0, 0, true);
342
343 // Inform data generator.
344 self::get_data_generator()->reset();
ef1d45b3 345 }
096858ed 346}