Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]
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 to set Behat config 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 26 defined('MOODLE_INTERNAL') || die(); 27 28 require_once (__DIR__ . '/behat_config_util.php'); 29 30 /** 31 * Behat configuration manager 32 * 33 * Creates/updates Behat config files getting tests 34 * and steps from Moodle codebase 35 * 36 * @package core 37 * @category test 38 * @copyright 2012 David MonllaĆ³ 39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 40 */ 41 class behat_config_manager { 42 43 /** 44 * @var bool Keep track of the automatic profile conversion. So we can notify user. 45 */ 46 public static $autoprofileconversion = false; 47 48 /** 49 * @var behat_config_util keep object of behat_config_util for use. 50 */ 51 public static $behatconfigutil = null; 52 53 /** 54 * Returns behat_config_util. 55 * 56 * @return behat_config_util 57 */ 58 private static function get_behat_config_util() { 59 if (!self::$behatconfigutil) { 60 self::$behatconfigutil = new behat_config_util(); 61 } 62 63 return self::$behatconfigutil; 64 } 65 66 /** 67 * Updates a config file 68 * 69 * The tests runner and the steps definitions list uses different 70 * config files to avoid problems with concurrent executions. 71 * 72 * The steps definitions list can be filtered by component so it's 73 * behat.yml is different from the $CFG->dirroot one. 74 * 75 * @param string $component Restricts the obtained steps definitions to the specified component 76 * @param string $testsrunner If the config file will be used to run tests 77 * @param string $tags features files including tags. 78 * @param bool $themesuitewithallfeatures if only theme specific features need to be included in the suite. 79 * @param int $parallelruns number of parallel runs. 80 * @param int $run current run for which config needs to be updated. 81 * @return void 82 */ 83 public static function update_config_file($component = '', $testsrunner = true, $tags = '', 84 $themesuitewithallfeatures = false, $parallelruns = 0, $run = 0) { 85 86 global $CFG; 87 88 // Behat must have a separate behat.yml to have access to the whole set of features and steps definitions. 89 if ($testsrunner === true) { 90 $configfilepath = behat_command::get_behat_dir($run) . '/behat.yml'; 91 } else { 92 // Alternative for steps definitions filtering, one for each user. 93 $configfilepath = self::get_steps_list_config_filepath(); 94 } 95 96 $behatconfigutil = self::get_behat_config_util(); 97 $behatconfigutil->set_theme_suite_to_include_core_features($themesuitewithallfeatures); 98 $behatconfigutil->set_tag_for_feature_filter($tags); 99 100 // Gets all the components with features, if running the tests otherwise not required. 101 $features = array(); 102 if ($testsrunner) { 103 $features = $behatconfigutil->get_components_features(); 104 } 105 106 // Gets all the components with steps definitions. 107 $stepsdefinitions = $behatconfigutil->get_components_contexts($component); 108 if (!$testsrunner) { 109 // Exclude deprecated steps definitions from the available steps list. 110 foreach (array_keys($stepsdefinitions) as $key) { 111 if (preg_match('/_deprecated$/', $key)) { 112 unset($stepsdefinitions[$key]); 113 } 114 } 115 } 116 117 // Get current run. 118 if (empty($run) && ($run !== false) && !empty($CFG->behatrunprocess)) { 119 $run = $CFG->behatrunprocess; 120 } 121 122 // Get number of parallel runs if not passed. 123 if (empty($parallelruns) && ($parallelruns !== false)) { 124 $parallelruns = self::get_behat_run_config_value('parallel'); 125 } 126 127 // Behat config file specifing the main context class, 128 // the required Behat extensions and Moodle test wwwroot. 129 $contents = $behatconfigutil->get_config_file_contents($features, $stepsdefinitions, $tags, $parallelruns, $run); 130 131 // Stores the file. 132 if (!file_put_contents($configfilepath, $contents)) { 133 behat_error(BEHAT_EXITCODE_PERMISSIONS, 'File ' . $configfilepath . ' can not be created'); 134 } 135 136 } 137 138 /** 139 * Returns the behat config file path used by the steps definition list 140 * 141 * @return string 142 */ 143 public static function get_steps_list_config_filepath() { 144 global $USER; 145 146 // We don't cygwin-it as it is called using exec() which uses cmd.exe. 147 $userdir = behat_command::get_behat_dir() . '/users/' . $USER->id; 148 make_writable_directory($userdir); 149 150 return $userdir . '/behat.yml'; 151 } 152 153 /** 154 * Returns the behat config file path used by the behat cli command. 155 * 156 * @param int $runprocess Runprocess. 157 * @return string 158 */ 159 public static function get_behat_cli_config_filepath($runprocess = 0) { 160 global $CFG; 161 162 if ($runprocess) { 163 if (isset($CFG->behat_parallel_run[$runprocess - 1 ]['behat_dataroot'])) { 164 $command = $CFG->behat_parallel_run[$runprocess - 1]['behat_dataroot']; 165 } else { 166 $command = $CFG->behat_dataroot . $runprocess; 167 } 168 } else { 169 $command = $CFG->behat_dataroot; 170 } 171 $command .= DIRECTORY_SEPARATOR . 'behat' . DIRECTORY_SEPARATOR . 'behat.yml'; 172 173 // Cygwin uses linux-style directory separators. 174 if (testing_is_cygwin()) { 175 $command = str_replace('\\', '/', $command); 176 } 177 178 return $command; 179 } 180 181 /** 182 * Returns the path to the parallel run file which specifies if parallel test environment is enabled 183 * and how many parallel runs to execute. 184 * 185 * @return string 186 */ 187 public final static function get_behat_run_config_file_path() { 188 return behat_command::get_parent_behat_dir() . '/run_environment.json'; 189 } 190 191 /** 192 * Get config for parallel run. 193 * 194 * @param string $key Key to store 195 * @return string|int|array value which is stored. 196 */ 197 public final static function get_behat_run_config_value($key) { 198 $parallelrunconfigfile = self::get_behat_run_config_file_path(); 199 200 if (file_exists($parallelrunconfigfile)) { 201 if ($parallelrunconfigs = @json_decode(file_get_contents($parallelrunconfigfile), true)) { 202 if (isset($parallelrunconfigs[$key])) { 203 return $parallelrunconfigs[$key]; 204 } 205 } 206 } 207 208 return false; 209 } 210 211 /** 212 * Save/update config for parallel run. 213 * 214 * @param string $key Key to store 215 * @param string|int|array $value to store. 216 */ 217 public final static function set_behat_run_config_value($key, $value) { 218 $parallelrunconfigs = array(); 219 $parallelrunconfigfile = self::get_behat_run_config_file_path(); 220 221 // Get any existing config first. 222 if (file_exists($parallelrunconfigfile)) { 223 $parallelrunconfigs = @json_decode(file_get_contents($parallelrunconfigfile), true); 224 } 225 $parallelrunconfigs[$key] = $value; 226 227 @file_put_contents($parallelrunconfigfile, json_encode($parallelrunconfigs, JSON_PRETTY_PRINT)); 228 } 229 230 /** 231 * Drops parallel site links. 232 * 233 * @return bool true on success else false. 234 */ 235 public final static function drop_parallel_site_links() { 236 global $CFG; 237 238 // Get parallel test runs. 239 $parallelrun = self::get_behat_run_config_value('parallel'); 240 241 if (empty($parallelrun)) { 242 return false; 243 } 244 245 // If parallel run then remove links and original file. 246 clearstatcache(); 247 for ($i = 1; $i <= $parallelrun; $i++) { 248 // Don't delete links for specified sites, as they should be accessible. 249 if (!empty($CFG->behat_parallel_run['behat_wwwroot'][$i - 1]['behat_wwwroot'])) { 250 continue; 251 } 252 $link = $CFG->dirroot . '/' . BEHAT_PARALLEL_SITE_NAME . $i; 253 if (file_exists($link) && is_link($link)) { 254 @unlink($link); 255 } 256 } 257 return true; 258 } 259 260 /** 261 * Create parallel site links. 262 * 263 * @param int $fromrun first run 264 * @param int $torun last run. 265 * @return bool true for sucess, else false. 266 */ 267 public final static function create_parallel_site_links($fromrun, $torun) { 268 global $CFG; 269 270 // Create site symlink if necessary. 271 clearstatcache(); 272 for ($i = $fromrun; $i <= $torun; $i++) { 273 // Don't create links for specified sites, as they should be accessible. 274 if (!empty($CFG->behat_parallel_run['behat_wwwroot'][$i - 1]['behat_wwwroot'])) { 275 continue; 276 } 277 $link = $CFG->dirroot.'/'.BEHAT_PARALLEL_SITE_NAME.$i; 278 clearstatcache(); 279 if (file_exists($link)) { 280 if (!is_link($link) || !is_dir($link)) { 281 echo "File exists at link location ($link) but is not a link or directory!" . PHP_EOL; 282 return false; 283 } 284 } else if (!symlink($CFG->dirroot, $link)) { 285 // Try create link in case it's not already present. 286 echo "Unable to create behat site symlink ($link)" . PHP_EOL; 287 return false; 288 } 289 } 290 return true; 291 } 292 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body