/** * Returns contents of all tables right after installation. * @static * @return array $table=>$records */ protected static function get_tabledata() { global $CFG; if (!isset(self::$tabledata)) { $data = file_get_contents("{$CFG->dataroot}/phpunit/tabledata.ser"); self::$tabledata = unserialize($data); } if (!is_array(self::$tabledata)) { phpunit_bootstrap_error('Can not read dataroot/phpunit/tabledata.ser or invalid format!'); } return self::$tabledata; }
/** * Builds phpunit.xml files for all components using defaults from /phpunit.xml.dist * * @static * @return void, stops if can not write files */ public static function build_component_config_files() { global $CFG; $template = ' <testsuites> <testsuite name="@component@"> <directory suffix="_test.php">.</directory> </testsuite> </testsuites>'; // Use the upstream file as source for the distributed configurations $ftemplate = file_get_contents("{$CFG->dirroot}/phpunit.xml.dist"); $ftemplate = preg_replace('|<!--All core suites.*</testsuites>|s', '<!--@component_suite@-->', $ftemplate); // Gets all the components with tests $components = tests_finder::get_components_with_tests('phpunit'); // Create the corresponding phpunit.xml file for each component foreach ($components as $cname => $cpath) { // Calculate the component suite $ctemplate = $template; $ctemplate = str_replace('@component@', $cname, $ctemplate); // Apply it to the file template $fcontents = str_replace('<!--@component_suite@-->', $ctemplate, $ftemplate); // fix link to schema $level = substr_count(str_replace('\\', '/', $cpath), '/') - substr_count(str_replace('\\', '/', $CFG->dirroot), '/'); $fcontents = str_replace('lib/phpunit/', str_repeat('../', $level) . 'lib/phpunit/', $fcontents); // Write the file $result = false; if (is_writable($cpath)) { if ($result = (bool) file_put_contents("{$cpath}/phpunit.xml", $fcontents)) { testing_fix_file_permissions("{$cpath}/phpunit.xml"); } } // Problems writing file, throw error if (!$result) { phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGWARNING, "Can not create {$cpath}/phpunit.xml configuration file, verify dir permissions"); } } }
$CFG->debugdeveloper = true; $CFG->debugdisplay = 1; error_reporting($CFG->debug); ini_set('display_errors', '1'); ini_set('log_errors', '1'); $CFG->noemailever = true; // better not mail anybody from tests, override temporarily if necessary $CFG->cachetext = 0; // disable this very nasty setting // some ugly hacks $CFG->themerev = 1; $CFG->jsrev = 1; // load test case stub classes and other stuff require_once "{$CFG->dirroot}/lib/phpunit/lib.php"; // finish moodle init define('ABORT_AFTER_CONFIG_CANCEL', true); require "{$CFG->dirroot}/lib/setup.php"; raise_memory_limit(MEMORY_HUGE); if (PHPUNIT_UTIL) { // we are not going to do testing, this is 'true' in utility scripts that only init database return; } // is database and dataroot ready for testing? list($errorcode, $message) = phpunit_util::testing_ready_problem(); // print some version info phpunit_util::bootstrap_moodle_info(); if ($errorcode) { phpunit_bootstrap_error($errorcode, $message); } // prepare for the first test run - store fresh globals, reset database and dataroot, etc. phpunit_util::bootstrap_init();
$help = "Various PHPUnit utility functions\n\nOptions:\n--drop Drop database and dataroot\n--install Install database\n--diag Diagnose installation and return error code only\n--run Execute PHPUnit tests (alternative for standard phpunit binary)\n--buildconfig Build /phpunit.xml from /phpunit.xml.dist that runs all tests\n--buildcomponentconfigs\n Build distributed phpunit.xml files for each component\n\n-h, --help Print out this help\n\nExample:\n\$ php " . phpunit_bootstrap_cli_argument_path('/admin/tool/phpunit/cli/util.php') . " --install\n"; echo $help; exit(0); } if ($diag) { list($errorcode, $message) = phpunit_util::testing_ready_problem(); if ($errorcode) { phpunit_bootstrap_error($errorcode, $message); } exit(0); } else { if ($buildconfig) { if (phpunit_util::build_config_file()) { exit(0); } else { phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGWARNING, 'Can not create main /phpunit.xml configuration file, verify dirroot permissions'); } } else { if ($buildcomponentconfigs) { phpunit_util::build_component_config_files(); exit(0); } else { if ($drop) { // make sure tests do not run in parallel phpunit_util::acquire_test_lock(); phpunit_util::drop_site(true); // note: we must stop here because $CFG is messed up and we can not reinstall, sorry exit(0); } else { if ($install) { phpunit_util::install_site();
/** * Builds phpunit.xml files for all components using defaults from /phpunit.xml.dist * * @static * @return void, stops if can not write files */ public static function build_component_config_files() { global $CFG; $template = ' <testsuites> <testsuite name="@component@_testsuite"> <directory suffix="_test.php">.</directory> </testsuite> </testsuites>'; // Start a sequence between 100000 and 199000 to ensure each call to init produces // different ids in the database. This reduces the risk that hard coded values will // end up being placed in phpunit or behat test code. $sequencestart = 100000 + mt_rand(0, 99) * 1000; // Use the upstream file as source for the distributed configurations $ftemplate = file_get_contents("{$CFG->dirroot}/phpunit.xml.dist"); $ftemplate = preg_replace('|<!--All core suites.*</testsuites>|s', '<!--@component_suite@-->', $ftemplate); // Gets all the components with tests $components = tests_finder::get_components_with_tests('phpunit'); // Create the corresponding phpunit.xml file for each component foreach ($components as $cname => $cpath) { // Calculate the component suite $ctemplate = $template; $ctemplate = str_replace('@component@', $cname, $ctemplate); // Apply it to the file template $fcontents = str_replace('<!--@component_suite@-->', $ctemplate, $ftemplate); $fcontents = str_replace('<const name="PHPUNIT_SEQUENCE_START" value=""/>', '<const name="PHPUNIT_SEQUENCE_START" value="' . $sequencestart . '"/>', $fcontents); // fix link to schema $level = substr_count(str_replace('\\', '/', $cpath), '/') - substr_count(str_replace('\\', '/', $CFG->dirroot), '/'); $fcontents = str_replace('lib/phpunit/', str_repeat('../', $level) . 'lib/phpunit/', $fcontents); // Write the file $result = false; if (is_writable($cpath)) { if ($result = (bool) file_put_contents("{$cpath}/phpunit.xml", $fcontents)) { testing_fix_file_permissions("{$cpath}/phpunit.xml"); } } // Problems writing file, throw error if (!$result) { phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGWARNING, "Can not create {$cpath}/phpunit.xml configuration file, verify dir permissions"); } } }
* * @package tool_phpunit * @copyright 2012 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ if (isset($_SERVER['REMOTE_ADDR'])) { die; // no access from web! } require_once __DIR__ . '/../../../../lib/clilib.php'; require_once __DIR__ . '/../../../../lib/phpunit/bootstraplib.php'; echo "Initialising Moodle PHPUnit test environment...\n"; $output = null; exec('php --version', $output, $code); if ($code != 0) { phpunit_bootstrap_error(1, 'Can not execute \'php\' binary.'); } chdir(__DIR__); $output = null; exec("php util.php --diag", $output, $code); if ($code == 0) { // everything is ready } else { if ($code == 132) { passthru("php util.php --install", $code); if ($code != 0) { exit($code); } } else { if ($code == 133) { passthru("php util.php --drop", $code);
/** * Perform a fresh test site installation * * Note: To be used from CLI scripts only. * * @static * @return void may terminate execution with exit code */ public static function install_site() { global $DB, $CFG; if (!self::is_test_site()) { phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGERROR, 'Can not install on non-test site!!'); } if ($DB->get_tables()) { list($errorcode, $message) = phpunit_util::testing_ready_problem(); if ($errorcode) { phpunit_bootstrap_error(PHPUNIT_EXITCODE_REINSTALL, 'Database tables already present, Moodle PHPUnit test environment can not be initialised'); } else { phpunit_bootstrap_error(0, 'Moodle PHPUnit test environment is already initialised'); } } $options = array(); $options['adminpass'] = '******'; $options['shortname'] = 'phpunit'; $options['fullname'] = 'PHPUnit test site'; install_cli_database($options, false); // install timezone info $timezones = get_records_csv($CFG->libdir . '/timezone.txt', 'timezone'); update_timezone_records($timezones); // add test db flag $hash = phpunit_util::get_version_hash(); set_config('phpunittest', $hash); // store data for all tables $data = array(); $structure = array(); $tables = $DB->get_tables(); foreach ($tables as $table) { $columns = $DB->get_columns($table); $structure[$table] = $columns; if (isset($columns['id']) and $columns['id']->auto_increment) { $data[$table] = $DB->get_records($table, array(), 'id ASC'); } else { // there should not be many of these $data[$table] = $DB->get_records($table, array()); } } $data = serialize($data); file_put_contents("{$CFG->dataroot}/phpunit/tabledata.ser", $data); phpunit_boostrap_fix_file_permissions("{$CFG->dataroot}/phpunit/tabledata.ser"); $structure = serialize($structure); file_put_contents("{$CFG->dataroot}/phpunit/tablestructure.ser", $structure); phpunit_boostrap_fix_file_permissions("{$CFG->dataroot}/phpunit/tablestructure.ser"); // hash all plugin versions - helps with very fast detection of db structure changes file_put_contents("{$CFG->dataroot}/phpunit/versionshash.txt", $hash); phpunit_boostrap_fix_file_permissions("{$CFG->dataroot}/phpunit/versionshash.txt", $hash); }
// disable this very nasty setting // some ugly hacks $CFG->themerev = 1; $CFG->jsrev = 1; // load test case stub classes and other stuff require_once "{$CFG->dirroot}/lib/phpunit/lib.php"; // finish moodle init define('ABORT_AFTER_CONFIG_CANCEL', true); require "{$CFG->dirroot}/lib/setup.php"; raise_memory_limit(MEMORY_EXTRA); if (defined('PHPUNIT_CLI_UTIL')) { // all other tests are done in the CLI scripts... return; } if (!phpunit_util::is_testing_ready()) { phpunit_bootstrap_error('Database is not initialised to run unit tests, please use "php admin/tool/phpunit/cli/util.php --install"', 132); } // refresh data in all tables, clear caches, etc. phpunit_util::reset_all_data(); // store fresh globals phpunit_util::init_globals(); //========================================================= /** * Print error and stop execution * @param string $text An error message to display * @param int $errorcode The error code (see docblock for detailed list) * @return void stops code execution with error code */ function phpunit_bootstrap_error($text, $errorcode = 1) { fwrite(STDERR, $text . "\n");
$help = "Various PHPUnit utility functions\n\nOptions:\n--drop Drop database and dataroot\n--install Install database\n--buildconfig Build /phpunit.xml from /phpunit.xml.dist that includes suites for all plugins and core\n--diag Diagnose installation and return error code only\n--run Execute PHPUnit tests (alternative for standard phpunit binary)\n\n-h, --help Print out this help\n\nExample:\n\$/usr/bin/php lib/phpunit/tool.php --install\n"; echo $help; exit(0); } if ($diag) { list($errorcode, $message) = phpunit_util::testing_ready_problem(); if ($errorcode) { phpunit_bootstrap_error($errorcode, $message); } exit(0); } else { if ($buildconfig) { if (phpunit_util::build_config_file()) { exit(0); } else { phpunit_bootstrap_error(134); } } else { if ($drop) { // make sure tests do not run in parallel phpunit_util::acquire_test_lock(); phpunit_util::drop_site(); // note: we must stop here because $CFG is messed up and we can not reinstall, sorry exit(0); } else { if ($install) { phpunit_util::install_site(); exit(0); } } }