MDL-37458 testing lock externalization

This commit is contained in:
David Monllao 2013-01-11 13:57:19 +08:00
parent 6b21986911
commit 3f7211f45a
5 changed files with 103 additions and 35 deletions

View File

@ -136,7 +136,7 @@ if ($diag) {
} else if ($drop) {
// make sure tests do not run in parallel
phpunit_util::acquire_test_lock();
test_lock::acquire('phpunit');
phpunit_util::drop_site(true);
// note: we must stop here because $CFG is messed up and we can not reinstall, sorry
exit(0);

View File

@ -54,9 +54,6 @@ class phpunit_util {
/** @var testing_data_generator */
protected static $generator = null;
/** @var resource used for prevention of parallel test execution */
protected static $lockhandle = null;
/** @var array list of debugging messages triggered during the last test execution */
protected static $debuggings = array();
@ -73,30 +70,7 @@ class phpunit_util {
* @return void
*/
public static function acquire_test_lock() {
global $CFG;
if (!file_exists("$CFG->phpunit_dataroot/phpunit")) {
// dataroot not initialised yet
return;
}
if (!file_exists("$CFG->phpunit_dataroot/phpunit/lock")) {
file_put_contents("$CFG->phpunit_dataroot/phpunit/lock", 'This file prevents concurrent execution of Moodle PHPUnit tests');
phpunit_boostrap_fix_file_permissions("$CFG->phpunit_dataroot/phpunit/lock");
}
if (self::$lockhandle = fopen("$CFG->phpunit_dataroot/phpunit/lock", 'r')) {
$wouldblock = null;
$locked = flock(self::$lockhandle, (LOCK_EX | LOCK_NB), $wouldblock);
if (!$locked) {
if ($wouldblock) {
echo "Waiting for other test execution to complete...\n";
}
$locked = flock(self::$lockhandle, LOCK_EX);
}
if (!$locked) {
fclose(self::$lockhandle);
self::$lockhandle = null;
}
}
register_shutdown_function(array('phpunit_util', 'release_test_lock'));
test_lock::acquire('phpunit');
}
/**
@ -106,11 +80,7 @@ class phpunit_util {
* @return void
*/
public static function release_test_lock() {
if (self::$lockhandle) {
flock(self::$lockhandle, LOCK_UN);
fclose(self::$lockhandle);
self::$lockhandle = null;
}
test_lock::release('phpunit');
}
/**

View File

@ -36,4 +36,4 @@ require_once(__DIR__.'/classes/arraydataset.php');
require_once(__DIR__.'/classes/advanced_testcase.php');
require_once(__DIR__.'/classes/unittestcase.php');
require_once(__DIR__.'/classes/hint_resultprinter.php'); // Loaded here because phpunit.xml does not support relative links for printerFile
require_once(__DIR__.'/../testing/classes/test_lock.php');

View File

@ -488,7 +488,7 @@ setup_DB();
if (PHPUNIT_TEST and !PHPUNIT_UTIL) {
// make sure tests do not run in parallel
phpunit_util::acquire_test_lock();
test_lock::acquire('phpunit');
$dbhash = null;
try {
if ($dbhash = $DB->get_field('config', 'value', array('name'=>'phpunittest'))) {

View File

@ -0,0 +1,98 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Tests lock
*
* @package core
* @category test
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__.'/lib.php');
/**
* Tests lock to prevent concurrent executions of the same test suite
*
* @package core
* @category test
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class test_lock {
/**
* @var array Array of resource used for prevention of parallel test execution
*/
protected static $lockhandles = array();
/**
* Prevent parallel test execution - this can not work in Moodle because we modify database and dataroot.
*
* Note: do not call manually!
*
* @internal
* @static
* @param string $framework Test framework
* @return void
*/
public static function acquire($framework) {
global $CFG;
$datarootpath = $CFG->{$framework . '_dataroot'} . '/' . $framework;
$lockfile = $datarootpath . '/lock';
if (!file_exists($datarootpath)) {
// Dataroot not initialised yet.
return;
}
if (!file_exists($lockfile)) {
file_put_contents($lockfile, 'This file prevents concurrent execution of Moodle ' . $framework . ' tests');
testing_fix_file_permissions($lockfile);
}
if (self::$lockhandles[$framework] = fopen($lockfile, 'r')) {
$wouldblock = null;
$locked = flock(self::$lockhandles[$framework], (LOCK_EX | LOCK_NB), $wouldblock);
if (!$locked) {
if ($wouldblock) {
echo "Waiting for other test execution to complete...\n";
}
$locked = flock(self::$lockhandles[$framework], LOCK_EX);
}
if (!$locked) {
fclose(self::$lockhandles[$framework]);
self::$lockhandles[$framework] = null;
}
}
register_shutdown_function(array('test_lock', 'release'), $framework);
}
/**
* Note: do not call manually!
* @internal
* @static
* @param string $framework phpunit|behat
* @return void
*/
public static function release($framework) {
if (self::$lockhandles[$framework]) {
flock(self::$lockhandles[$framework], LOCK_UN);
fclose(self::$lockhandles[$framework]);
self::$lockhandles[$framework] = null;
}
}
}