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 * Tests lock 19 * 20 * @package core 21 * @category test 22 * @copyright 2012 Petr Skoda {@link http://skodak.org} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 require_once (__DIR__.'/../lib.php'); 27 28 /** 29 * Tests lock to prevent concurrent executions of the same test suite 30 * 31 * @package core 32 * @category test 33 * @copyright 2012 Petr Skoda {@link http://skodak.org} 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 class test_lock { 37 38 /** 39 * @var array Array of resource used for prevention of parallel test execution 40 */ 41 protected static $lockhandles = array(); 42 43 /** 44 * Prevent parallel test execution - this can not work in Moodle because we modify database and dataroot. 45 * 46 * Note: do not call manually! 47 * 48 * @internal 49 * @static 50 * @param string $framework phpunit|behat 51 * @param string $lockfilesuffix A sub-type used by the framework 52 * @return void 53 */ 54 public static function acquire(string $framework, string $lockfilesuffix = '') { 55 global $CFG; 56 57 $datarootpath = $CFG->{$framework . '_dataroot'} . '/' . $framework; 58 $lockfile = "{$datarootpath}/lock{$lockfilesuffix}"; 59 if (!file_exists($datarootpath)) { 60 // Dataroot not initialised yet. 61 return; 62 } 63 if (!file_exists($lockfile)) { 64 file_put_contents($lockfile, 'This file prevents concurrent execution of Moodle ' . $framework . ' tests'); 65 testing_fix_file_permissions($lockfile); 66 } 67 68 $lockhandlename = self::get_lock_handle_name($framework, $lockfilesuffix); 69 if (self::$lockhandles[$lockhandlename] = fopen($lockfile, 'r')) { 70 $wouldblock = null; 71 $locked = flock(self::$lockhandles[$lockhandlename], (LOCK_EX | LOCK_NB), $wouldblock); 72 if (!$locked) { 73 if ($wouldblock) { 74 echo "Waiting for other test execution to complete...\n"; 75 } 76 $locked = flock(self::$lockhandles[$lockhandlename], LOCK_EX); 77 } 78 if (!$locked) { 79 fclose(self::$lockhandles[$lockhandlename]); 80 self::$lockhandles[$lockhandlename] = null; 81 } 82 } 83 register_shutdown_function(['test_lock', 'release'], $framework, $lockfilesuffix); 84 } 85 86 /** 87 * Note: do not call manually! 88 * @internal 89 * @static 90 * @param string $framework phpunit|behat 91 * @param string $lockfilesuffix A sub-type used by the framework 92 * @return void 93 */ 94 public static function release(string $framework, string $lockfilesuffix = '') { 95 $lockhandlename = self::get_lock_handle_name($framework, $lockfilesuffix); 96 97 if (self::$lockhandles[$lockhandlename]) { 98 flock(self::$lockhandles[$lockhandlename], LOCK_UN); 99 fclose(self::$lockhandles[$lockhandlename]); 100 self::$lockhandles[$lockhandlename] = null; 101 } 102 } 103 104 /** 105 * Get the name of the lock handle stored in the class. 106 * 107 * @param string $framework 108 * @param string $lockfilesuffix 109 * @return string 110 */ 111 protected static function get_lock_handle_name(string $framework, string $lockfilesuffix): string { 112 $lockhandlepieces = [$framework]; 113 114 if (!empty($lockfilesuffix)) { 115 $lockhandlepieces[] = $lockfilesuffix; 116 } 117 118 return implode('%', $lockhandlepieces); 119 } 120 121 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body