Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Core/Test/TestDatabase.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 129ea1e6d783 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Core\Test; | |
4 | |
5 use Drupal\Component\FileSystem\FileSystem; | |
6 use Drupal\Core\Database\ConnectionNotDefinedException; | |
7 use Drupal\Core\Database\Database; | |
8 | |
9 /** | |
10 * Provides helper methods for interacting with the Simpletest database. | |
11 */ | |
12 class TestDatabase { | |
13 | |
14 /** | |
15 * A random number used to ensure that test fixtures are unique to each test | |
16 * method. | |
17 * | |
18 * @var int | |
19 */ | |
20 protected $lockId; | |
21 | |
22 /** | |
23 * The test database prefix. | |
24 * | |
25 * @var string | |
26 */ | |
27 protected $databasePrefix; | |
28 | |
29 /** | |
30 * Returns the database connection to the site running Simpletest. | |
31 * | |
32 * @return \Drupal\Core\Database\Connection | |
33 * The database connection to use for inserting assertions. | |
34 * | |
35 * @see \Drupal\simpletest\TestBase::prepareEnvironment() | |
36 */ | |
37 public static function getConnection() { | |
38 // Check whether there is a test runner connection. | |
39 // @see run-tests.sh | |
40 // @todo Convert Simpletest UI runner to create + use this connection, too. | |
41 try { | |
42 $connection = Database::getConnection('default', 'test-runner'); | |
43 } | |
44 catch (ConnectionNotDefinedException $e) { | |
45 // Check whether there is a backup of the original default connection. | |
46 // @see TestBase::prepareEnvironment() | |
47 try { | |
48 $connection = Database::getConnection('default', 'simpletest_original_default'); | |
49 } | |
50 catch (ConnectionNotDefinedException $e) { | |
51 // If TestBase::prepareEnvironment() or TestBase::restoreEnvironment() | |
52 // failed, the test-specific database connection does not exist | |
53 // yet/anymore, so fall back to the default of the (UI) test runner. | |
54 $connection = Database::getConnection('default', 'default'); | |
55 } | |
56 } | |
57 return $connection; | |
58 } | |
59 | |
60 /** | |
61 * TestDatabase constructor. | |
62 * | |
63 * @param string|null $db_prefix | |
64 * If not provided a new test lock is generated. | |
65 * | |
66 * @throws \InvalidArgumentException | |
67 * Thrown when $db_prefix does not match the regular expression. | |
68 */ | |
69 public function __construct($db_prefix = NULL) { | |
70 if ($db_prefix === NULL) { | |
71 $this->lockId = $this->getTestLock(); | |
72 $this->databasePrefix = 'test' . $this->lockId; | |
73 } | |
74 else { | |
75 $this->databasePrefix = $db_prefix; | |
76 // It is possible that we're running a test inside a test. In which case | |
77 // $db_prefix will be something like test12345678test90123456 and the | |
78 // generated lock ID for the running test method would be 90123456. | |
79 preg_match('/test(\d+)$/', $db_prefix, $matches); | |
80 if (!isset($matches[1])) { | |
81 throw new \InvalidArgumentException("Invalid database prefix: $db_prefix"); | |
82 } | |
83 $this->lockId = $matches[1]; | |
84 } | |
85 } | |
86 | |
87 /** | |
88 * Gets the relative path to the test site directory. | |
89 * | |
90 * @return string | |
91 * The relative path to the test site directory. | |
92 */ | |
93 public function getTestSitePath() { | |
94 return 'sites/simpletest/' . $this->lockId; | |
95 } | |
96 | |
97 /** | |
98 * Gets the test database prefix. | |
99 * | |
100 * @return string | |
101 * The test database prefix. | |
102 */ | |
103 public function getDatabasePrefix() { | |
104 return $this->databasePrefix; | |
105 } | |
106 | |
107 /** | |
108 * Generates a unique lock ID for the test method. | |
109 * | |
110 * @return int | |
111 * The unique lock ID for the test method. | |
112 */ | |
113 protected function getTestLock() { | |
114 // Ensure that the generated lock ID is not in use, which may happen when | |
115 // tests are run concurrently. | |
116 do { | |
117 $lock_id = mt_rand(10000000, 99999999); | |
118 // If we're only running with a concurrency of 1 there's no need to create | |
119 // a test lock file as there is no chance of the random number generated | |
120 // clashing. | |
121 if (getenv('RUN_TESTS_CONCURRENCY') > 1 && @symlink(__FILE__, $this->getLockFile($lock_id)) === FALSE) { | |
122 $lock_id = NULL; | |
123 } | |
124 } while ($lock_id === NULL); | |
125 return $lock_id; | |
126 } | |
127 | |
128 /** | |
129 * Releases all test locks. | |
130 * | |
131 * This should only be called once all the test fixtures have been cleaned up. | |
132 */ | |
133 public static function releaseAllTestLocks() { | |
134 $tmp = file_directory_os_temp(); | |
135 $dir = dir($tmp); | |
136 while (($entry = $dir->read()) !== FALSE) { | |
137 if ($entry === '.' || $entry === '..') { | |
138 continue; | |
139 } | |
140 $entry_path = $tmp . '/' . $entry; | |
141 if (preg_match('/^test_\d+/', $entry) && is_link($entry_path)) { | |
142 unlink($entry_path); | |
143 } | |
144 } | |
145 } | |
146 | |
147 /** | |
148 * Gets the lock file path. | |
149 * | |
150 * @param int $lock_id | |
151 * The test method lock ID. | |
152 * | |
153 * @return string | |
154 * A file path to the symbolic link that prevents the lock ID being re-used. | |
155 */ | |
156 protected function getLockFile($lock_id) { | |
157 return FileSystem::getOsTemporaryDirectory() . '/test_' . $lock_id; | |
158 } | |
159 | |
160 } |