comparison core/lib/Drupal/Core/Test/TestDatabase.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents 4c8ae668cc8c
children
comparison
equal deleted inserted replaced
16:c2387f117808 17:129ea1e6d783
60 /** 60 /**
61 * TestDatabase constructor. 61 * TestDatabase constructor.
62 * 62 *
63 * @param string|null $db_prefix 63 * @param string|null $db_prefix
64 * If not provided a new test lock is generated. 64 * If not provided a new test lock is generated.
65 * @param bool $create_lock
66 * (optional) Whether or not to create a lock file. Defaults to FALSE. If
67 * the environment variable RUN_TESTS_CONCURRENCY is greater than 1 it will
68 * be overridden to TRUE regardless of its initial value.
65 * 69 *
66 * @throws \InvalidArgumentException 70 * @throws \InvalidArgumentException
67 * Thrown when $db_prefix does not match the regular expression. 71 * Thrown when $db_prefix does not match the regular expression.
68 */ 72 */
69 public function __construct($db_prefix = NULL) { 73 public function __construct($db_prefix = NULL, $create_lock = FALSE) {
70 if ($db_prefix === NULL) { 74 if ($db_prefix === NULL) {
71 $this->lockId = $this->getTestLock(); 75 $this->lockId = $this->getTestLock($create_lock);
72 $this->databasePrefix = 'test' . $this->lockId; 76 $this->databasePrefix = 'test' . $this->lockId;
73 } 77 }
74 else { 78 else {
75 $this->databasePrefix = $db_prefix; 79 $this->databasePrefix = $db_prefix;
76 // It is possible that we're running a test inside a test. In which case 80 // It is possible that we're running a test inside a test. In which case
105 } 109 }
106 110
107 /** 111 /**
108 * Generates a unique lock ID for the test method. 112 * Generates a unique lock ID for the test method.
109 * 113 *
114 * @param bool $create_lock
115 * (optional) Whether or not to create a lock file. Defaults to FALSE.
116 *
110 * @return int 117 * @return int
111 * The unique lock ID for the test method. 118 * The unique lock ID for the test method.
112 */ 119 */
113 protected function getTestLock() { 120 protected function getTestLock($create_lock = FALSE) {
114 // Ensure that the generated lock ID is not in use, which may happen when 121 // There is a risk that the generated random number is a duplicate. This
115 // tests are run concurrently. 122 // would cause different tests to try to use the same database prefix.
123 // Therefore, if running with a concurrency of greater than 1, we need to
124 // create a lock.
125 if (getenv('RUN_TESTS_CONCURRENCY') > 1) {
126 $create_lock = TRUE;
127 }
128
116 do { 129 do {
117 $lock_id = mt_rand(10000000, 99999999); 130 $lock_id = mt_rand(10000000, 99999999);
118 // If we're only running with a concurrency of 1 there's no need to create 131 if ($create_lock && @symlink(__FILE__, $this->getLockFile($lock_id)) === FALSE) {
119 // a test lock file as there is no chance of the random number generated 132 // If we can't create a symlink, the lock ID is in use. Generate another
120 // clashing. 133 // one. Symlinks are used because they are atomic and reliable.
121 if (getenv('RUN_TESTS_CONCURRENCY') > 1 && @symlink(__FILE__, $this->getLockFile($lock_id)) === FALSE) {
122 $lock_id = NULL; 134 $lock_id = NULL;
123 } 135 }
124 } while ($lock_id === NULL); 136 } while ($lock_id === NULL);
125 return $lock_id; 137 return $lock_id;
138 }
139
140 /**
141 * Releases a lock.
142 *
143 * @return bool
144 * TRUE if successful, FALSE if not.
145 */
146 public function releaseLock() {
147 return unlink($this->getLockFile($this->lockId));
126 } 148 }
127 149
128 /** 150 /**
129 * Releases all test locks. 151 * Releases all test locks.
130 * 152 *
131 * This should only be called once all the test fixtures have been cleaned up. 153 * This should only be called once all the test fixtures have been cleaned up.
132 */ 154 */
133 public static function releaseAllTestLocks() { 155 public static function releaseAllTestLocks() {
134 $tmp = file_directory_os_temp(); 156 $tmp = FileSystem::getOsTemporaryDirectory();
135 $dir = dir($tmp); 157 $dir = dir($tmp);
136 while (($entry = $dir->read()) !== FALSE) { 158 while (($entry = $dir->read()) !== FALSE) {
137 if ($entry === '.' || $entry === '..') { 159 if ($entry === '.' || $entry === '..') {
138 continue; 160 continue;
139 } 161 }