PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/behat/classes/behat_command.php

https://gitlab.com/unofficial-mirrors/moodle
PHP | 268 lines | 119 code | 43 blank | 106 comment | 38 complexity | a6f129fe8a0cf5de4bbe43afbb98dcb2 MD5 | raw file
  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. * Behat command utils
  18. *
  19. * @package core
  20. * @category test
  21. * @copyright 2012 David MonllaĆ³
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. defined('MOODLE_INTERNAL') || die();
  25. require_once(__DIR__ . '/../lib.php');
  26. /**
  27. * Behat command related utils
  28. *
  29. * @package core
  30. * @category test
  31. * @copyright 2013 David MonllaĆ³
  32. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33. */
  34. class behat_command {
  35. /**
  36. * Docs url
  37. */
  38. const DOCS_URL = 'http://docs.moodle.org/dev/Acceptance_testing';
  39. /**
  40. * Ensures the behat dir exists in moodledata
  41. *
  42. * @return string Full path
  43. */
  44. public static function get_parent_behat_dir() {
  45. global $CFG;
  46. // If not set then return empty string.
  47. if (!isset($CFG->behat_dataroot_parent)) {
  48. return "";
  49. }
  50. return $CFG->behat_dataroot_parent;
  51. }
  52. /**
  53. * Ensures the behat dir exists in moodledata
  54. * @param int $runprocess run process for which behat dir is returned.
  55. * @return string Full path
  56. */
  57. public static function get_behat_dir($runprocess = 0) {
  58. global $CFG;
  59. // If not set then return empty string.
  60. if (!isset($CFG->behat_dataroot)) {
  61. return "";
  62. }
  63. // If $CFG->behat_parallel_run starts with index 0 and $runprocess for parallel run starts with 1.
  64. if (!empty($runprocess) && isset($CFG->behat_parallel_run[$runprocess - 1]['behat_dataroot'])) {
  65. $behatdir = $CFG->behat_parallel_run[$runprocess - 1]['behat_dataroot'] . '/behat';;
  66. } else {
  67. $behatdir = $CFG->behat_dataroot . '/behat';
  68. }
  69. if (!is_dir($behatdir)) {
  70. if (!mkdir($behatdir, $CFG->directorypermissions, true)) {
  71. behat_error(BEHAT_EXITCODE_PERMISSIONS, 'Directory ' . $behatdir . ' can not be created');
  72. }
  73. }
  74. if (!is_writable($behatdir)) {
  75. behat_error(BEHAT_EXITCODE_PERMISSIONS, 'Directory ' . $behatdir . ' is not writable');
  76. }
  77. return $behatdir;
  78. }
  79. /**
  80. * Returns the executable path
  81. *
  82. * Allows returning a customized command for cygwin when the
  83. * command is just displayed, when using exec(), system() and
  84. * friends we stay with DIRECTORY_SEPARATOR as they use the
  85. * normal cmd.exe (in Windows).
  86. *
  87. * @param bool $custombyterm If the provided command should depend on the terminal where it runs
  88. * @param bool $parallelrun If parallel run is installed.
  89. * @param bool $absolutepath return command with absolute path.
  90. * @return string
  91. */
  92. public final static function get_behat_command($custombyterm = false, $parallerun = false, $absolutepath = false) {
  93. $separator = DIRECTORY_SEPARATOR;
  94. $exec = 'behat';
  95. // Cygwin uses linux-style directory separators.
  96. if ($custombyterm && testing_is_cygwin()) {
  97. $separator = '/';
  98. // MinGW can not execute .bat scripts.
  99. if (!testing_is_mingw()) {
  100. $exec = 'behat.bat';
  101. }
  102. }
  103. // If relative path then prefix relative path.
  104. if ($absolutepath) {
  105. $pathprefix = testing_cli_argument_path('/');
  106. if (!empty($pathprefix)) {
  107. $pathprefix .= $separator;
  108. }
  109. } else {
  110. $pathprefix = '';
  111. }
  112. if (!$parallerun) {
  113. $command = $pathprefix . 'vendor' . $separator . 'bin' . $separator . $exec;
  114. } else {
  115. $command = 'php ' . $pathprefix . 'admin' . $separator . 'tool' . $separator . 'behat' . $separator . 'cli'
  116. . $separator . 'run.php';
  117. }
  118. return $command;
  119. }
  120. /**
  121. * Runs behat command with provided options
  122. *
  123. * Execution continues when the process finishes
  124. *
  125. * @param string $options Defaults to '' so tests would be executed
  126. * @return array CLI command outputs [0] => string, [1] => integer
  127. */
  128. public final static function run($options = '') {
  129. global $CFG;
  130. $currentcwd = getcwd();
  131. chdir($CFG->dirroot);
  132. exec(self::get_behat_command() . ' ' . $options, $output, $code);
  133. chdir($currentcwd);
  134. return array($output, $code);
  135. }
  136. /**
  137. * Checks if behat is set up and working
  138. *
  139. * Notifies failures both from CLI and web interface.
  140. *
  141. * It checks behat dependencies have been installed and runs
  142. * the behat help command to ensure it works as expected
  143. *
  144. * @return int Error code or 0 if all ok
  145. */
  146. public static function behat_setup_problem() {
  147. global $CFG;
  148. // Moodle setting.
  149. if (!self::are_behat_dependencies_installed()) {
  150. // Returning composer error code to avoid conflicts with behat and moodle error codes.
  151. self::output_msg(get_string('errorcomposer', 'tool_behat'));
  152. return TESTING_EXITCODE_COMPOSER;
  153. }
  154. // Behat test command.
  155. list($output, $code) = self::run(' --help');
  156. if ($code != 0) {
  157. // Returning composer error code to avoid conflicts with behat and moodle error codes.
  158. self::output_msg(get_string('errorbehatcommand', 'tool_behat', self::get_behat_command()));
  159. return TESTING_EXITCODE_COMPOSER;
  160. }
  161. // No empty values.
  162. if (empty($CFG->behat_dataroot) || empty($CFG->behat_prefix) || empty($CFG->behat_wwwroot)) {
  163. self::output_msg(get_string('errorsetconfig', 'tool_behat'));
  164. return BEHAT_EXITCODE_CONFIG;
  165. }
  166. // Not repeated values.
  167. // We only need to check this when the behat site is not running as
  168. // at this point, when it is running, all $CFG->behat_* vars have
  169. // already been copied to $CFG->dataroot, $CFG->prefix and $CFG->wwwroot.
  170. if (!defined('BEHAT_SITE_RUNNING') &&
  171. ($CFG->behat_prefix == $CFG->prefix ||
  172. $CFG->behat_dataroot == $CFG->dataroot ||
  173. $CFG->behat_wwwroot == $CFG->wwwroot ||
  174. (!empty($CFG->phpunit_prefix) && $CFG->phpunit_prefix == $CFG->behat_prefix) ||
  175. (!empty($CFG->phpunit_dataroot) && $CFG->phpunit_dataroot == $CFG->behat_dataroot)
  176. )) {
  177. self::output_msg(get_string('erroruniqueconfig', 'tool_behat'));
  178. return BEHAT_EXITCODE_CONFIG;
  179. }
  180. // Checking behat dataroot existence otherwise echo about admin/tool/behat/cli/init.php.
  181. if (!empty($CFG->behat_dataroot)) {
  182. $CFG->behat_dataroot = realpath($CFG->behat_dataroot);
  183. }
  184. if (empty($CFG->behat_dataroot) || !is_dir($CFG->behat_dataroot) || !is_writable($CFG->behat_dataroot)) {
  185. self::output_msg(get_string('errordataroot', 'tool_behat'));
  186. return BEHAT_EXITCODE_CONFIG;
  187. }
  188. return 0;
  189. }
  190. /**
  191. * Has the site installed composer.
  192. * @return bool
  193. */
  194. public static function are_behat_dependencies_installed() {
  195. if (!is_dir(__DIR__ . '/../../../vendor/behat')) {
  196. return false;
  197. }
  198. return true;
  199. }
  200. /**
  201. * Outputs a message.
  202. *
  203. * Used in CLI + web UI methods. Stops the
  204. * execution in web.
  205. *
  206. * @param string $msg
  207. * @return void
  208. */
  209. protected static function output_msg($msg) {
  210. global $CFG, $PAGE;
  211. // If we are using the web interface we want pretty messages.
  212. if (!CLI_SCRIPT) {
  213. $renderer = $PAGE->get_renderer('tool_behat');
  214. echo $renderer->render_error($msg);
  215. // Stopping execution.
  216. exit(1);
  217. } else {
  218. // We continue execution after this.
  219. $clibehaterrorstr = "Ensure you set \$CFG->behat_* vars in config.php " .
  220. "and you ran admin/tool/behat/cli/init.php.\n" .
  221. "More info in " . self::DOCS_URL . "#Installation\n\n";
  222. echo 'Error: ' . $msg . "\n\n" . $clibehaterrorstr;
  223. }
  224. }
  225. }