[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/behat/ -> lib.php (source)

   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   * Behat basic functions
  19   *
  20   * It does not include MOODLE_INTERNAL because is part of the bootstrap
  21   *
  22   * @package    core
  23   * @category   test
  24   * @copyright  2012 David Monllaó
  25   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  26   */
  27  
  28  require_once (__DIR__ . '/../testing/lib.php');
  29  
  30  define('BEHAT_EXITCODE_CONFIG', 250);
  31  define('BEHAT_EXITCODE_REQUIREMENT', 251);
  32  define('BEHAT_EXITCODE_PERMISSIONS', 252);
  33  define('BEHAT_EXITCODE_REINSTALL', 253);
  34  define('BEHAT_EXITCODE_INSTALL', 254);
  35  define('BEHAT_EXITCODE_COMPOSER', 255);
  36  define('BEHAT_EXITCODE_INSTALLED', 256);
  37  
  38  /**
  39   * Exits with an error code
  40   *
  41   * @param  mixed $errorcode
  42   * @param  string $text
  43   * @return void Stops execution with error code
  44   */
  45  function behat_error($errorcode, $text = '') {
  46  
  47      // Adding error prefixes.
  48      switch ($errorcode) {
  49          case BEHAT_EXITCODE_CONFIG:
  50              $text = 'Behat config error: ' . $text;
  51              break;
  52          case BEHAT_EXITCODE_REQUIREMENT:
  53              $text = 'Behat requirement not satisfied: ' . $text;
  54              break;
  55          case BEHAT_EXITCODE_PERMISSIONS:
  56              $text = 'Behat permissions problem: ' . $text . ', check the permissions';
  57              break;
  58          case BEHAT_EXITCODE_REINSTALL:
  59              $path = testing_cli_argument_path('/admin/tool/behat/cli/init.php');
  60              $text = "Reinstall Behat: ".$text.", use:\n php ".$path;
  61              break;
  62          case BEHAT_EXITCODE_INSTALL:
  63              $path = testing_cli_argument_path('/admin/tool/behat/cli/init.php');
  64              $text = "Install Behat before enabling it, use:\n php ".$path;
  65              break;
  66          case BEHAT_EXITCODE_INSTALLED:
  67              $text = "The Behat site is already installed";
  68              break;
  69          default:
  70              $text = 'Unknown error ' . $errorcode . ' ' . $text;
  71              break;
  72      }
  73  
  74      testing_error($errorcode, $text);
  75  }
  76  
  77  /**
  78   * PHP errors handler to use when running behat tests.
  79   *
  80   * Adds specific CSS classes to identify
  81   * the messages.
  82   *
  83   * @param int $errno
  84   * @param string $errstr
  85   * @param string $errfile
  86   * @param int $errline
  87   * @param array $errcontext
  88   * @return bool
  89   */
  90  function behat_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
  91  
  92      // If is preceded by an @ we don't show it.
  93      if (!error_reporting()) {
  94          return true;
  95      }
  96  
  97      // This error handler receives E_ALL | E_STRICT, running the behat test site the debug level is
  98      // set to DEVELOPER and will always include E_NOTICE,E_USER_NOTICE... as part of E_ALL, if the current
  99      // error_reporting() value does not include one of those levels is because it has been forced through
 100      // the moodle code (see fix_utf8() for example) in that cases we respect the forced error level value.
 101      $respect = array(E_NOTICE, E_USER_NOTICE, E_STRICT, E_WARNING, E_USER_WARNING);
 102      foreach ($respect as $respectable) {
 103  
 104          // If the current value does not include this kind of errors and the reported error is
 105          // at that level don't print anything.
 106          if ($errno == $respectable && !(error_reporting() & $respectable)) {
 107              return true;
 108          }
 109      }
 110  
 111      // Using the default one in case there is a fatal catchable error.
 112      default_error_handler($errno, $errstr, $errfile, $errline, $errcontext);
 113  
 114      switch ($errno) {
 115          case E_USER_ERROR:
 116              $errnostr = 'Fatal error';
 117              break;
 118          case E_WARNING:
 119          case E_USER_WARNING:
 120              $errnostr = 'Warning';
 121              break;
 122          case E_NOTICE:
 123          case E_USER_NOTICE:
 124          case E_STRICT:
 125              $errnostr = 'Notice';
 126              break;
 127          case E_RECOVERABLE_ERROR:
 128              $errnostr = 'Catchable';
 129              break;
 130          default:
 131              $errnostr = 'Unknown error type';
 132      }
 133  
 134      // Wrapping the output.
 135      echo '<div class="phpdebugmessage" data-rel="phpdebugmessage">' . PHP_EOL;
 136      echo "$errnostr: $errstr in $errfile on line $errline" . PHP_EOL;
 137      echo '</div>';
 138  
 139      // Also use the internal error handler so we keep the usual behaviour.
 140      return false;
 141  }
 142  
 143  /**
 144   * Restrict the config.php settings allowed.
 145   *
 146   * When running the behat features the config.php
 147   * settings should not affect the results.
 148   *
 149   * @return void
 150   */
 151  function behat_clean_init_config() {
 152      global $CFG;
 153  
 154      $allowed = array_flip(array(
 155          'wwwroot', 'dataroot', 'dirroot', 'admin', 'directorypermissions', 'filepermissions',
 156          'umaskpermissions', 'dbtype', 'dblibrary', 'dbhost', 'dbname', 'dbuser', 'dbpass', 'prefix',
 157          'dboptions', 'proxyhost', 'proxyport', 'proxytype', 'proxyuser', 'proxypassword',
 158          'proxybypass', 'theme', 'pathtogs', 'pathtoclam', 'pathtodu', 'aspellpath', 'pathtodot', 'skiplangupgrade'
 159      ));
 160  
 161      // Add extra allowed settings.
 162      if (!empty($CFG->behat_extraallowedsettings)) {
 163          $allowed = array_merge($allowed, array_flip($CFG->behat_extraallowedsettings));
 164      }
 165  
 166      // Also allowing behat_ prefixed attributes.
 167      foreach ($CFG as $key => $value) {
 168          if (!isset($allowed[$key]) && strpos($key, 'behat_') !== 0) {
 169              unset($CFG->{$key});
 170          }
 171      }
 172  
 173      // Here we are forcing the navbar to be absolutely positioned in Chrome, Safari and IE in order to
 174      // avoid a driver bug whereby when the browser scrolls something into view it doesn't account
 175      // for fixed positioned elements that end up obscuring the item thus leading to errors that
 176      // could be avoided by scrolling an additional amount.
 177      // This should be removed as soon as the affected drivers have been fixed.
 178      $CFG->forced_plugin_settings['theme_clean'] = array(
 179          'customcss' => 'body.safari .navbar-fixed-top, body.ie .navbar-fixed-top {position: absolute;}'
 180      );
 181  }
 182  
 183  /**
 184   * Checks that the behat config vars are properly set.
 185   *
 186   * @return void Stops execution with error code if something goes wrong.
 187   */
 188  function behat_check_config_vars() {
 189      global $CFG;
 190  
 191      // Verify prefix value.
 192      if (empty($CFG->behat_prefix)) {
 193          behat_error(BEHAT_EXITCODE_CONFIG,
 194              'Define $CFG->behat_prefix in config.php');
 195      }
 196      if (!empty($CFG->prefix) and $CFG->behat_prefix == $CFG->prefix) {
 197          behat_error(BEHAT_EXITCODE_CONFIG,
 198              '$CFG->behat_prefix in config.php must be different from $CFG->prefix');
 199      }
 200      if (!empty($CFG->phpunit_prefix) and $CFG->behat_prefix == $CFG->phpunit_prefix) {
 201          behat_error(BEHAT_EXITCODE_CONFIG,
 202              '$CFG->behat_prefix in config.php must be different from $CFG->phpunit_prefix');
 203      }
 204  
 205      // Verify behat wwwroot value.
 206      if (empty($CFG->behat_wwwroot)) {
 207          behat_error(BEHAT_EXITCODE_CONFIG,
 208              'Define $CFG->behat_wwwroot in config.php');
 209      }
 210      if (!empty($CFG->wwwroot) and $CFG->behat_wwwroot == $CFG->wwwroot) {
 211          behat_error(BEHAT_EXITCODE_CONFIG,
 212              '$CFG->behat_wwwroot in config.php must be different from $CFG->wwwroot');
 213      }
 214  
 215      // Verify behat dataroot value.
 216      if (empty($CFG->behat_dataroot)) {
 217          behat_error(BEHAT_EXITCODE_CONFIG,
 218              'Define $CFG->behat_dataroot in config.php');
 219      }
 220      if (!file_exists($CFG->behat_dataroot)) {
 221          $permissions = isset($CFG->directorypermissions) ? $CFG->directorypermissions : 02777;
 222          umask(0);
 223          if (!mkdir($CFG->behat_dataroot, $permissions, true)) {
 224              behat_error(BEHAT_EXITCODE_PERMISSIONS, '$CFG->behat_dataroot directory can not be created');
 225          }
 226      }
 227      $CFG->behat_dataroot = realpath($CFG->behat_dataroot);
 228      if (empty($CFG->behat_dataroot) or !is_dir($CFG->behat_dataroot) or !is_writable($CFG->behat_dataroot)) {
 229          behat_error(BEHAT_EXITCODE_CONFIG,
 230              '$CFG->behat_dataroot in config.php must point to an existing writable directory');
 231      }
 232      if (!empty($CFG->dataroot) and $CFG->behat_dataroot == realpath($CFG->dataroot)) {
 233          behat_error(BEHAT_EXITCODE_CONFIG,
 234              '$CFG->behat_dataroot in config.php must be different from $CFG->dataroot');
 235      }
 236      if (!empty($CFG->phpunit_dataroot) and $CFG->behat_dataroot == realpath($CFG->phpunit_dataroot)) {
 237          behat_error(BEHAT_EXITCODE_CONFIG,
 238              '$CFG->behat_dataroot in config.php must be different from $CFG->phpunit_dataroot');
 239      }
 240  }
 241  
 242  /**
 243   * Should we switch to the test site data?
 244   * @return bool
 245   */
 246  function behat_is_test_site() {
 247      global $CFG;
 248  
 249      if (defined('BEHAT_UTIL')) {
 250          // This is the admin tool that installs/drops the test site install.
 251          return true;
 252      }
 253      if (defined('BEHAT_TEST')) {
 254          // This is the main vendor/bin/behat script.
 255          return true;
 256      }
 257      if (empty($CFG->behat_wwwroot)) {
 258          return false;
 259      }
 260      if (isset($_SERVER['REMOTE_ADDR']) and behat_is_requested_url($CFG->behat_wwwroot)) {
 261          // Something is accessing the web server like a real browser.
 262          return true;
 263      }
 264  
 265      return false;
 266  }
 267  
 268  /**
 269   * Checks if the URL requested by the user matches the provided argument
 270   *
 271   * @param string $url
 272   * @return bool Returns true if it matches.
 273   */
 274  function behat_is_requested_url($url) {
 275  
 276      $parsedurl = parse_url($url . '/');
 277      $parsedurl['port'] = isset($parsedurl['port']) ? $parsedurl['port'] : 80;
 278      $parsedurl['path'] = rtrim($parsedurl['path'], '/');
 279  
 280      // Removing the port.
 281      $pos = strpos($_SERVER['HTTP_HOST'], ':');
 282      if ($pos !== false) {
 283          $requestedhost = substr($_SERVER['HTTP_HOST'], 0, $pos);
 284      } else {
 285          $requestedhost = $_SERVER['HTTP_HOST'];
 286      }
 287  
 288      // The path should also match.
 289      if (empty($parsedurl['path'])) {
 290          $matchespath = true;
 291      } else if (strpos($_SERVER['SCRIPT_NAME'], $parsedurl['path']) === 0) {
 292          $matchespath = true;
 293      }
 294  
 295      // The host and the port should match
 296      if ($parsedurl['host'] == $requestedhost && $parsedurl['port'] == $_SERVER['SERVER_PORT'] && !empty($matchespath)) {
 297          return true;
 298      }
 299  
 300      return false;
 301  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1