TestSetupTrait.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. namespace Drupal\Core\Test;
  3. use Drupal\Core\Database\Database;
  4. /**
  5. * Provides a trait for shared test setup functionality.
  6. */
  7. trait TestSetupTrait {
  8. /**
  9. * An array of config object names that are excluded from schema checking.
  10. *
  11. * @var string[]
  12. */
  13. protected static $configSchemaCheckerExclusions = [
  14. // Following are used to test lack of or partial schema. Where partial
  15. // schema is provided, that is explicitly tested in specific tests.
  16. 'config_schema_test.noschema',
  17. 'config_schema_test.someschema',
  18. 'config_schema_test.schema_data_types',
  19. 'config_schema_test.no_schema_data_types',
  20. // Used to test application of schema to filtering of configuration.
  21. 'config_test.dynamic.system',
  22. ];
  23. /**
  24. * The dependency injection container used in the test.
  25. *
  26. * @var \Symfony\Component\DependencyInjection\ContainerInterface
  27. */
  28. protected $container;
  29. /**
  30. * The site directory of this test run.
  31. *
  32. * @var string
  33. */
  34. protected $siteDirectory = NULL;
  35. /**
  36. * The public file directory for the test environment.
  37. *
  38. * @see \Drupal\simpletest\TestBase::prepareEnvironment()
  39. * @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
  40. *
  41. * @var string
  42. */
  43. protected $publicFilesDirectory;
  44. /**
  45. * The site directory of the original parent site.
  46. *
  47. * @var string
  48. */
  49. protected $originalSite;
  50. /**
  51. * The private file directory for the test environment.
  52. *
  53. * @see \Drupal\simpletest\TestBase::prepareEnvironment()
  54. * @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
  55. *
  56. * @var string
  57. */
  58. protected $privateFilesDirectory;
  59. /**
  60. * The original installation profile.
  61. *
  62. * @var string
  63. */
  64. protected $originalProfile;
  65. /**
  66. * Set to TRUE to strict check all configuration saved.
  67. *
  68. * @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
  69. *
  70. * @var bool
  71. */
  72. protected $strictConfigSchema = TRUE;
  73. /**
  74. * The DrupalKernel instance used in the test.
  75. *
  76. * @var \Drupal\Core\DrupalKernel
  77. */
  78. protected $kernel;
  79. /**
  80. * The temporary file directory for the test environment.
  81. *
  82. * This value has to match the temporary directory created in
  83. * install_base_system() for test installs.
  84. *
  85. * @see \Drupal\simpletest\TestBase::prepareEnvironment()
  86. * @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
  87. * @see install_base_system()
  88. *
  89. * @var string
  90. */
  91. protected $tempFilesDirectory;
  92. /**
  93. * The test run ID.
  94. *
  95. * @var string
  96. */
  97. protected $testId;
  98. /**
  99. * Returns the database connection to the site running Simpletest.
  100. *
  101. * @return \Drupal\Core\Database\Connection
  102. * The database connection to use for inserting assertions.
  103. */
  104. public static function getDatabaseConnection() {
  105. return TestDatabase::getConnection();
  106. }
  107. /**
  108. * Generates a database prefix for running tests.
  109. *
  110. * The database prefix is used by prepareEnvironment() to setup a public files
  111. * directory for the test to be run, which also contains the PHP error log,
  112. * which is written to in case of a fatal error. Since that directory is based
  113. * on the database prefix, all tests (even unit tests) need to have one, in
  114. * order to access and read the error log.
  115. *
  116. * The generated database table prefix is used for the Drupal installation
  117. * being performed for the test. It is also used as user agent HTTP header
  118. * value by the cURL-based browser of WebTestBase, which is sent to the Drupal
  119. * installation of the test. During early Drupal bootstrap, the user agent
  120. * HTTP header is parsed, and if it matches, all database queries use the
  121. * database table prefix that has been generated here.
  122. *
  123. * @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
  124. * @see \Drupal\simpletest\WebTestBase::curlInitialize()
  125. * @see \Drupal\simpletest\TestBase::prepareEnvironment()
  126. * @see drupal_valid_test_ua()
  127. */
  128. protected function prepareDatabasePrefix() {
  129. $test_db = new TestDatabase();
  130. $this->siteDirectory = $test_db->getTestSitePath();
  131. $this->databasePrefix = $test_db->getDatabasePrefix();
  132. }
  133. /**
  134. * Changes the database connection to the prefixed one.
  135. */
  136. protected function changeDatabasePrefix() {
  137. if (empty($this->databasePrefix)) {
  138. $this->prepareDatabasePrefix();
  139. }
  140. // If the test is run with argument dburl then use it.
  141. $db_url = getenv('SIMPLETEST_DB');
  142. if (!empty($db_url)) {
  143. $database = Database::convertDbUrlToConnectionInfo($db_url, isset($this->root) ? $this->root : DRUPAL_ROOT);
  144. Database::addConnectionInfo('default', 'default', $database);
  145. }
  146. // Clone the current connection and replace the current prefix.
  147. $connection_info = Database::getConnectionInfo('default');
  148. if (is_null($connection_info)) {
  149. throw new \InvalidArgumentException('There is no database connection so no tests can be run. You must provide a SIMPLETEST_DB environment variable to run PHPUnit based functional tests outside of run-tests.sh.');
  150. }
  151. else {
  152. Database::renameConnection('default', 'simpletest_original_default');
  153. foreach ($connection_info as $target => $value) {
  154. // Replace the full table prefix definition to ensure that no table
  155. // prefixes of the test runner leak into the test.
  156. $connection_info[$target]['prefix'] = [
  157. 'default' => $value['prefix']['default'] . $this->databasePrefix,
  158. ];
  159. }
  160. Database::addConnectionInfo('default', 'default', $connection_info['default']);
  161. }
  162. }
  163. /**
  164. * Gets the config schema exclusions for this test.
  165. *
  166. * @return string[]
  167. * An array of config object names that are excluded from schema checking.
  168. */
  169. protected function getConfigSchemaExclusions() {
  170. $class = get_class($this);
  171. $exceptions = [];
  172. while ($class) {
  173. if (property_exists($class, 'configSchemaCheckerExclusions')) {
  174. $exceptions = array_merge($exceptions, $class::$configSchemaCheckerExclusions);
  175. }
  176. $class = get_parent_class($class);
  177. }
  178. // Filter out any duplicates.
  179. return array_unique($exceptions);
  180. }
  181. }