From 2d68ba169d2503331d040a910791f5f57acdcfdd Mon Sep 17 00:00:00 2001 From: Aaron Barnes Date: Wed, 4 Sep 2013 20:35:50 +1200 Subject: [PATCH 1/3] MDL-41592 behat: Allow alt wwwroot to be set for acceptance testing To set add $CFG->behat_wwwroot = 'http://alturl'; in your config.php --- config-dist.php | 4 ++-- lib/behat/classes/behat_command.php | 2 +- lib/setup.php | 37 ++++++++++++++++------------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/config-dist.php b/config-dist.php index d50253d672a..2081ac23a6f 100644 --- a/config-dist.php +++ b/config-dist.php @@ -561,8 +561,8 @@ $CFG->admin = 'admin'; // $CFG->behat_prefix = 'bht_'; // $CFG->behat_dataroot = '/home/example/bht_moodledata'; // -// Behat uses http://localhost:8000 as default URL to run -// the acceptance tests, you can override this value. +// To set a seperate wwwroot for Behat to use, set it below. +// This is set automatically elsewhere when using PHP's built in webserver. // Example: // $CFG->behat_wwwroot = 'http://192.168.1.250:8000'; // diff --git a/lib/behat/classes/behat_command.php b/lib/behat/classes/behat_command.php index fb149ad4ffa..a40a71911a6 100644 --- a/lib/behat/classes/behat_command.php +++ b/lib/behat/classes/behat_command.php @@ -108,7 +108,7 @@ class behat_command { // We don't check the PHP version if $CFG->behat_switchcompletely has been enabled. // Here we are in CLI. - if (empty($CFG->behat_switchcompletely) && $checkphp && version_compare(PHP_VERSION, '5.4.0', '<')) { + if (empty($CFG->behat_switchcompletely) && empty($CFG->behat_wwwroot) && $checkphp && version_compare(PHP_VERSION, '5.4.0', '<')) { behat_error(BEHAT_EXITCODE_REQUIREMENT, 'PHP 5.4 is required. See config-dist.php for possible alternatives'); } diff --git a/lib/setup.php b/lib/setup.php index 3151a10f233..0178de43ae9 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -90,20 +90,11 @@ if (!isset($CFG->wwwroot) or $CFG->wwwroot === 'http://example.com/moodle') { exit(1); } -// Ignore $CFG->behat_wwwroot and use the same wwwroot. -if (!empty($CFG->behat_switchcompletely)) { - $CFG->behat_wwwroot = $CFG->wwwroot; - -} else if (empty($CFG->behat_wwwroot)) { - // Default URL for acceptance testing, only accessible from localhost. - $CFG->behat_wwwroot = 'http://localhost:8000'; -} - - // Test environment is requested if: -// * Behat is running (constant set hooking the behat init process before requiring config.php). -// * If we are accessing though the built-in web server (cli-server). // * If $CFG->behat_switchcompletely has been set (maintains CLI scripts behaviour, which ATM is only preventive). +// * If we are accessing though the built-in web server (cli-server). +// * Behat is running (constant set hooking the behat init process before requiring config.php). +// * If $CFG->behat_wwwroot has been set and the hostname/port match what the page was requested with. // Test environment is enabled if: // * User has previously enabled through admin/tool/behat/cli/util.php --enable. // Both are required to switch to test mode @@ -112,10 +103,24 @@ if (!defined('BEHAT_SITE_RUNNING') && !empty($CFG->behat_dataroot) && $CFG->behat_dataroot = realpath($CFG->behat_dataroot); - $switchcompletely = !empty($CFG->behat_switchcompletely) && php_sapi_name() !== 'cli'; - $builtinserver = php_sapi_name() === 'cli-server'; - $behatrunning = defined('BEHAT_TEST'); - $testenvironmentrequested = $switchcompletely || $builtinserver || $behatrunning; + if (!empty($CFG->behat_switchcompletely) && php_sapi_name() !== 'cli') { + $behatswitchcompletely = true; + $CFG->behat_wwwroot = $CFG->wwwroot; + + } elseif (php_sapi_name() === 'cli-server') { + $behatbuiltinserver = true; + $CFG->behat_wwwroot = 'http://localhost:'.$_SERVER['SERVER_PORT']; + + } elseif (defined('BEHAT_TEST')) { + $behatrunning = true; + + } elseif (!empty($CFG->behat_wwwroot) && !empty($_SERVER['HTTP_HOST'])) { + $behaturl = parse_url($CFG->behat_wwwroot.'/'); + $behaturl['port'] = isset($behaturl['port']) ? $behaturl['port'] : 80; + $behataltwww = ($behaturl['host'] == $_SERVER['HTTP_HOST']) && ($behaturl['port'] == $_SERVER['SERVER_PORT']); + } + + $testenvironmentrequested = !empty($behatswitchcompletely) || !empty($behatbuiltinserver) || !empty($behatrunning) || !empty($behataltwww); // Only switch to test environment if it has been enabled. $testenvironmentenabled = file_exists($CFG->behat_dataroot . '/behat/test_environment_enabled.txt'); From f016ecaebf8f37f2530498829799a0378f81f9db Mon Sep 17 00:00:00 2001 From: David Monllao Date: Thu, 21 Nov 2013 13:07:13 +0800 Subject: [PATCH 2/3] MDL-41592 behat: Config settings more flexible Adding the option to just set ->behat_wwwroot to allow switching to the behat test site. --- admin/tool/behat/cli/util.php | 26 ++++---- config-dist.php | 10 ++- lib/behat/classes/behat_command.php | 1 + lib/behat/lib.php | 94 +++++++++++++++++++++++++++++ lib/setup.php | 45 ++++++++++---- 5 files changed, 147 insertions(+), 29 deletions(-) diff --git a/admin/tool/behat/cli/util.php b/admin/tool/behat/cli/util.php index 5c24cf8c05d..9f8dede9563 100644 --- a/admin/tool/behat/cli/util.php +++ b/admin/tool/behat/cli/util.php @@ -92,21 +92,9 @@ ini_set('log_errors', '1'); // Getting $CFG data. require_once(__DIR__ . '/../../../../config.php'); -// CFG->behat_prefix must be set and with value different than CFG->prefix and phpunit_prefix. -if (empty($CFG->behat_prefix) || - ($CFG->behat_prefix == $CFG->prefix) || - (!empty($CFG->phpunit_prefix) && $CFG->behat_prefix == $CFG->phpunit_prefix)) { - behat_error(BEHAT_EXITCODE_CONFIG, - 'Define $CFG->behat_prefix in config.php with a value different than $CFG->prefix and $CFG->phpunit_prefix'); -} - -// CFG->behat_dataroot must be set and with value different than CFG->dataroot and phpunit_dataroot. -if (empty($CFG->behat_dataroot) || - ($CFG->behat_dataroot == $CFG->dataroot) || - (!empty($CFG->phpunit_dataroot) && $CFG->behat_dataroot == $CFG->phpunit_dataroot)) { - behat_error(BEHAT_EXITCODE_CONFIG, - 'Define $CFG->behat_dataroot in config.php with a value different than $CFG->dataroot and $CFG->phpunit_dataroot'); -} +// Checking the integrity of the provided $CFG->behat_* vars +// to prevent conflicts with production and phpunit environments. +behat_check_config_vars(); // Create behat_dataroot if it doesn't exists. if (!file_exists($CFG->behat_dataroot)) { @@ -136,6 +124,14 @@ if (!file_exists("$CFG->behat_dataroot/behattestdir.txt")) { testing_initdataroot($CFG->behat_dataroot, 'behat'); } +// When we use the utilities we don't know how the site +// will be accessed, so if neither $CFG->behat_switchcompletely or +// $CFG->behat_wwwroot are set we must think that the site will +// be accessed using the built-in server which is set by default +// to localhost:8000. We need to do this to prevent uses of the production +// wwwroot when the site is being installed / dropped... +$CFG->behat_wwwroot = behat_get_wwwroot(); + // Overrides vars with behat-test ones. $vars = array('wwwroot', 'prefix', 'dataroot'); foreach ($vars as $var) { diff --git a/config-dist.php b/config-dist.php index 2081ac23a6f..904205d4e96 100644 --- a/config-dist.php +++ b/config-dist.php @@ -561,10 +561,16 @@ $CFG->admin = 'admin'; // $CFG->behat_prefix = 'bht_'; // $CFG->behat_dataroot = '/home/example/bht_moodledata'; // -// To set a seperate wwwroot for Behat to use, set it below. -// This is set automatically elsewhere when using PHP's built in webserver. +// To set a seperate wwwroot for Behat to use, use $CFG->behat_wwwroot; this is set automatically +// to http://localhost:8000 as it is the proposed PHP built-in server URL. Instead of that you can, +// for example, use an alias, add a host to /etc/hosts or add a new virtual host having a URL +// poiting to your production site and another one poiting to your test site. Note that you need +// to ensure that this URL is not accessible from the www as the behat test site uses "sugar" +// credentials (admin/admin) and can be easily hackable. +// // Example: // $CFG->behat_wwwroot = 'http://192.168.1.250:8000'; +// $CFG->behat_wwwroot = 'http://localhost/moodlesitetesting'; // // You can override default Moodle configuration for Behat and add your own // params; here you can add more profiles, use different Mink drivers than Selenium... diff --git a/lib/behat/classes/behat_command.php b/lib/behat/classes/behat_command.php index a40a71911a6..20762ae1efe 100644 --- a/lib/behat/classes/behat_command.php +++ b/lib/behat/classes/behat_command.php @@ -148,6 +148,7 @@ class behat_command { } // Checking behat dataroot existence otherwise echo about admin/tool/behat/cli/init.php. + $CFG->behat_dataroot = realpath($CFG->behat_dataroot); if (empty($CFG->behat_dataroot) || !is_dir($CFG->behat_dataroot) || !is_writable($CFG->behat_dataroot)) { self::output_msg(get_string('runclitool', 'tool_behat', 'php admin/tool/behat/cli/init.php')); return BEHAT_EXITCODE_CONFIG; diff --git a/lib/behat/lib.php b/lib/behat/lib.php index bfdf07401b0..32a16639268 100644 --- a/lib/behat/lib.php +++ b/lib/behat/lib.php @@ -161,3 +161,97 @@ function behat_clean_init_config() { } } + +/** + * Checks that the behat config vars are properly set. + * + * @return void Stops execution with error code if something goes wrong. + */ +function behat_check_config_vars() { + global $CFG; + + // CFG->behat_prefix must be set and with value different than CFG->prefix and phpunit_prefix. + if (empty($CFG->behat_prefix) || + ($CFG->behat_prefix == $CFG->prefix) || + (!empty($CFG->phpunit_prefix) && $CFG->behat_prefix == $CFG->phpunit_prefix)) { + behat_error(BEHAT_EXITCODE_CONFIG, + 'Define $CFG->behat_prefix in config.php with a value different than $CFG->prefix and $CFG->phpunit_prefix'); + } + + // $CFG->behat_wwwroot must be different than CFG->wwwroot if it is set, it may not be set as + // it can take the default value and we should also consider that will have the same value than + // $CFG->wwwroot if $CFG->behat_switchcompletely is set. + if (!empty($CFG->behat_wwwroot) && $CFG->behat_wwwroot == $CFG->wwwroot && empty($CFG->behat_switchcompletely)) { + behat_error(BEHAT_EXITCODE_CONFIG, + 'Define $CFG->behat_wwwroot in config.php with a value different than $CFG->wwwroot'); + } + + // CFG->behat_dataroot must be set and with value different than CFG->dataroot and phpunit_dataroot. + $CFG->dataroot = realpath($CFG->dataroot); + if (!empty($CFG->behat_dataroot)) { + $CFG->behat_dataroot = realpath($CFG->behat_dataroot); + } + if (empty($CFG->behat_dataroot) || + ($CFG->behat_dataroot == $CFG->dataroot) || + (!empty($CFG->phpunit_dataroot) && $CFG->behat_dataroot == $CFG->phpunit_dataroot)) { + behat_error(BEHAT_EXITCODE_CONFIG, + 'Define $CFG->behat_dataroot in config.php with a value different than $CFG->dataroot and $CFG->phpunit_dataroot'); + } + +} + +/** + * Returns a URL based on the priorities between $CFG->behat_* vars. + * + * 1.- Switch completely wins and overwrites behat_wwwroot + * 2.- behat_wwwroot alternatively + * 3.- http://localhost:8000 if there is nothing else + * + * @return string + */ +function behat_get_wwwroot() { + global $CFG; + + if (!empty($CFG->behat_switchcompletely)) { + return $CFG->wwwroot; + } else if (!empty($CFG->behat_wwwroot)) { + return $CFG->behat_wwwroot; + } + + return 'http://localhost:8000'; +} + +/** + * Checks if the URL requested by the user matches the provided argument + * + * @param string $url + * @return bool Returns true if it matches. + */ +function behat_is_requested_url($url) { + + $parsedurl = parse_url($url . '/'); + $parsedurl['port'] = isset($parsedurl['port']) ? $parsedurl['port'] : 80; + $parsedurl['path'] = rtrim($parsedurl['path'], '/'); + + // Removing the port. + $pos = strpos($_SERVER['HTTP_HOST'], ':'); + if ($pos !== false) { + $requestedhost = substr($_SERVER['HTTP_HOST'], 0, $pos); + } else { + $requestedhost = $_SERVER['HTTP_HOST']; + } + + // The path should also match. + if (empty($parsedurl['path'])) { + $matchespath = true; + } else if (strpos($_SERVER['SCRIPT_NAME'], $parsedurl['path']) === 0) { + $matchespath = true; + } + + // The host and the port should match + if ($parsedurl['host'] == $requestedhost && $parsedurl['port'] == $_SERVER['SERVER_PORT'] && !empty($matchespath)) { + return true; + } + + return false; +} diff --git a/lib/setup.php b/lib/setup.php index 0178de43ae9..cf49e36616f 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -96,37 +96,58 @@ if (!isset($CFG->wwwroot) or $CFG->wwwroot === 'http://example.com/moodle') { // * Behat is running (constant set hooking the behat init process before requiring config.php). // * If $CFG->behat_wwwroot has been set and the hostname/port match what the page was requested with. // Test environment is enabled if: -// * User has previously enabled through admin/tool/behat/cli/util.php --enable. +// * User has previously enabled through admin/tool/behat/cli/util.php --enable or admin/tool/behat/cli/init.php // Both are required to switch to test mode if (!defined('BEHAT_SITE_RUNNING') && !empty($CFG->behat_dataroot) && !empty($CFG->behat_prefix) && file_exists($CFG->behat_dataroot)) { - $CFG->behat_dataroot = realpath($CFG->behat_dataroot); + // Only included if behat_* are set, it is not likely to be a production site. + require_once(__DIR__ . '/../lib/behat/lib.php'); + + $defaultbehatwwwroot = behat_get_wwwroot(); if (!empty($CFG->behat_switchcompletely) && php_sapi_name() !== 'cli') { - $behatswitchcompletely = true; - $CFG->behat_wwwroot = $CFG->wwwroot; + // Switch completely uses the production wwwroot as the test site URL. + $behatwwwroot = $defaultbehatwwwroot; } elseif (php_sapi_name() === 'cli-server') { - $behatbuiltinserver = true; - $CFG->behat_wwwroot = 'http://localhost:'.$_SERVER['SERVER_PORT']; + // If we are using the built-in server we use the provided $CFG->behat_wwwroot + // value or the default one if $CFG->behat_wwwroot is not set, only if it matches + // the requested URL. + if (behat_is_requested_url($defaultbehatwwwroot)) { + $behatwwwroot = $defaultbehatwwwroot; + } } elseif (defined('BEHAT_TEST')) { - $behatrunning = true; + // This is when moodle codebase runs through vendor/bin/behat, we "are not supposed" + // to need a wwwroot, but before using the production one we should set something else + // as an alternative. + $behatwwwroot = $defaultbehatwwwroot; } elseif (!empty($CFG->behat_wwwroot) && !empty($_SERVER['HTTP_HOST'])) { - $behaturl = parse_url($CFG->behat_wwwroot.'/'); - $behaturl['port'] = isset($behaturl['port']) ? $behaturl['port'] : 80; - $behataltwww = ($behaturl['host'] == $_SERVER['HTTP_HOST']) && ($behaturl['port'] == $_SERVER['SERVER_PORT']); + // If $CFG->behat_wwwroot was set and matches the requested URL we + // use $CFG->behat_wwwroot as our wwwroot. + if (behat_is_requested_url($CFG->behat_wwwroot)) { + $behatwwwroot = $CFG->behat_wwwroot; + } } - $testenvironmentrequested = !empty($behatswitchcompletely) || !empty($behatbuiltinserver) || !empty($behatrunning) || !empty($behataltwww); + // If we found a proper behatwwwroot then we consider the behat test as requested. + $testenvironmentrequested = !empty($behatwwwroot); // Only switch to test environment if it has been enabled. + $CFG->behat_dataroot = realpath($CFG->behat_dataroot); $testenvironmentenabled = file_exists($CFG->behat_dataroot . '/behat/test_environment_enabled.txt'); if ($testenvironmentenabled && $testenvironmentrequested) { + // Now we know which one will be our behat wwwroot. + $CFG->behat_wwwroot = $behatwwwroot; + + // Checking the integrity of the provided $CFG->behat_* vars and the + // selected wwwroot to prevent conflicts with production and phpunit environments. + behat_check_config_vars(); + // Constant used to inform that the behat test site is being used, // this includes all the processes executed by the behat CLI command like // the site reset, the steps executed by the browser drivers when simulating @@ -137,9 +158,9 @@ if (!defined('BEHAT_SITE_RUNNING') && !empty($CFG->behat_dataroot) && define('BEHAT_SITE_RUNNING', true); // Clean extra config.php settings. - require_once(__DIR__ . '/../lib/behat/lib.php'); behat_clean_init_config(); + // Now we can begin switching $CFG->X for $CFG->behat_X. $CFG->wwwroot = $CFG->behat_wwwroot; $CFG->passwordsaltmain = 'moodle'; $CFG->prefix = $CFG->behat_prefix; From 3efc96f546c88539a068fb36baa712a866d4b588 Mon Sep 17 00:00:00 2001 From: David Monllao Date: Thu, 21 Nov 2013 13:12:11 +0800 Subject: [PATCH 3/3] MDL-41592 general: Also checking the site path --- admin/tool/behat/cli/util.php | 16 ++++++++-------- lib/setuplib.php | 5 ++++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/admin/tool/behat/cli/util.php b/admin/tool/behat/cli/util.php index 9f8dede9563..0405b1f24ef 100644 --- a/admin/tool/behat/cli/util.php +++ b/admin/tool/behat/cli/util.php @@ -92,6 +92,14 @@ ini_set('log_errors', '1'); // Getting $CFG data. require_once(__DIR__ . '/../../../../config.php'); +// When we use the utilities we don't know how the site +// will be accessed, so if neither $CFG->behat_switchcompletely or +// $CFG->behat_wwwroot are set we must think that the site will +// be accessed using the built-in server which is set by default +// to localhost:8000. We need to do this to prevent uses of the production +// wwwroot when the site is being installed / dropped... +$CFG->behat_wwwroot = behat_get_wwwroot(); + // Checking the integrity of the provided $CFG->behat_* vars // to prevent conflicts with production and phpunit environments. behat_check_config_vars(); @@ -124,14 +132,6 @@ if (!file_exists("$CFG->behat_dataroot/behattestdir.txt")) { testing_initdataroot($CFG->behat_dataroot, 'behat'); } -// When we use the utilities we don't know how the site -// will be accessed, so if neither $CFG->behat_switchcompletely or -// $CFG->behat_wwwroot are set we must think that the site will -// be accessed using the built-in server which is set by default -// to localhost:8000. We need to do this to prevent uses of the production -// wwwroot when the site is being installed / dropped... -$CFG->behat_wwwroot = behat_get_wwwroot(); - // Overrides vars with behat-test ones. $vars = array('wwwroot', 'prefix', 'dataroot'); foreach ($vars as $var) { diff --git a/lib/setuplib.php b/lib/setuplib.php index bb28c0bee79..23058e8fd14 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -781,7 +781,10 @@ function initialise_fullme() { // Do not abuse this to try to solve lan/wan access problems!!!!! } else { - if (($rurl['host'] !== $wwwroot['host']) or (!empty($wwwroot['port']) and $rurl['port'] != $wwwroot['port'])) { + if (($rurl['host'] !== $wwwroot['host']) or + (!empty($wwwroot['port']) and $rurl['port'] != $wwwroot['port']) or + (strpos($rurl['path'], $wwwroot['path']) !== 0)) { + // Explain the problem and redirect them to the right URL if (!defined('NO_MOODLE_COOKIES')) { define('NO_MOODLE_COOKIES', true);