EnvironmentCleaner.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. namespace Drupal\Core\Test;
  3. use Drupal\Core\Database\Connection;
  4. use Drupal\Core\File\FileSystemInterface;
  5. use Symfony\Component\Console\Output\OutputInterface;
  6. /**
  7. * Helper class for cleaning test environments.
  8. */
  9. class EnvironmentCleaner implements EnvironmentCleanerInterface {
  10. /**
  11. * Path to Drupal root directory.
  12. *
  13. * @var string
  14. */
  15. protected $root;
  16. /**
  17. * Connection to the database being used for tests.
  18. *
  19. * @var \Drupal\Core\Database\Connection
  20. */
  21. protected $testDatabase;
  22. /**
  23. * Connection to the database where test results are stored.
  24. *
  25. * This could be the same as $testDatabase, or it could be different.
  26. * run-tests.sh allows you to specify a different results database with the
  27. * --sqlite parameter.
  28. *
  29. * @var \Drupal\Core\Database\Connection
  30. */
  31. protected $resultsDatabase;
  32. /**
  33. * The file system service.
  34. *
  35. * @var \Drupal\Core\File\FileSystemInterface
  36. */
  37. protected $fileSystem;
  38. /**
  39. * Console output.
  40. *
  41. * @var \Symfony\Component\Console\Output\OutputInterface
  42. */
  43. protected $output;
  44. /**
  45. * Construct an environment cleaner.
  46. *
  47. * @param string $root
  48. * The path to the root of the Drupal installation.
  49. * @param \Drupal\Core\Database\Connection $test_database
  50. * Connection to the database against which tests were run.
  51. * @param \Drupal\Core\Database\Connection $results_database
  52. * Connection to the database where test results were stored. This could be
  53. * the same as $test_database, or it could be different.
  54. * @param \Symfony\Component\Console\Output\OutputInterface $output
  55. * A symfony console output object.
  56. * @param \Drupal\Core\File\FileSystemInterface $file_system
  57. * The file_system service.
  58. */
  59. public function __construct($root, Connection $test_database, Connection $results_database, OutputInterface $output, FileSystemInterface $file_system) {
  60. $this->root = $root;
  61. $this->testDatabase = $test_database;
  62. $this->resultsDatabase = $results_database;
  63. $this->output = $output;
  64. $this->fileSystem = $file_system;
  65. }
  66. /**
  67. * {@inheritdoc}
  68. */
  69. public function cleanEnvironment($clear_results = TRUE, $clear_temp_directories = TRUE, $clear_database = TRUE) {
  70. $count = 0;
  71. if ($clear_database) {
  72. $this->doCleanDatabase();
  73. }
  74. if ($clear_temp_directories) {
  75. $this->doCleanTemporaryDirectories();
  76. }
  77. if ($clear_results) {
  78. $count = $this->cleanResultsTable();
  79. $this->output->write('Test results removed: ' . $count);
  80. }
  81. else {
  82. $this->output->write('Test results were not removed.');
  83. }
  84. }
  85. /**
  86. * {@inheritdoc}
  87. */
  88. public function cleanDatabase() {
  89. $count = $this->doCleanDatabase();
  90. if ($count > 0) {
  91. $this->output->write('Leftover tables removed: ' . $count);
  92. }
  93. else {
  94. $this->output->write('No leftover tables to remove.');
  95. }
  96. }
  97. /**
  98. * Performs the fixture database cleanup.
  99. *
  100. * @return int
  101. * The number of tables that were removed.
  102. */
  103. protected function doCleanDatabase() {
  104. /* @var $schema \Drupal\Core\Database\Schema */
  105. $schema = $this->testDatabase->schema();
  106. $tables = $schema->findTables('test%');
  107. $count = 0;
  108. foreach ($tables as $table) {
  109. // Only drop tables which begin wih 'test' followed by digits, for example,
  110. // {test12345678node__body}.
  111. if (preg_match('/^test\d+.*/', $table, $matches)) {
  112. $schema->dropTable($matches[0]);
  113. $count++;
  114. }
  115. }
  116. return $count;
  117. }
  118. /**
  119. * {@inheritdoc}
  120. */
  121. public function cleanTemporaryDirectories() {
  122. $count = $this->doCleanTemporaryDirectories();
  123. if ($count > 0) {
  124. $this->output->write('Temporary directories removed: ' . $count);
  125. }
  126. else {
  127. $this->output->write('No temporary directories to remove.');
  128. }
  129. }
  130. /**
  131. * Performs the cleanup of temporary test directories.
  132. *
  133. * @return int
  134. * The count of temporary directories removed.
  135. */
  136. protected function doCleanTemporaryDirectories() {
  137. $count = 0;
  138. $simpletest_dir = $this->root . '/sites/simpletest';
  139. if (is_dir($simpletest_dir)) {
  140. $files = scandir($simpletest_dir);
  141. foreach ($files as $file) {
  142. if ($file[0] != '.') {
  143. $path = $simpletest_dir . '/' . $file;
  144. $this->fileSystem->deleteRecursive($path, function ($any_path) {
  145. @chmod($any_path, 0700);
  146. });
  147. $count++;
  148. }
  149. }
  150. }
  151. return $count;
  152. }
  153. /**
  154. * {@inheritdoc}
  155. */
  156. public function cleanResultsTable($test_id = NULL) {
  157. $count = 0;
  158. if ($test_id) {
  159. $count = $this->resultsDatabase->query('SELECT COUNT(test_id) FROM {simpletest_test_id} WHERE test_id = :test_id', [':test_id' => $test_id])->fetchField();
  160. $this->resultsDatabase->delete('simpletest')
  161. ->condition('test_id', $test_id)
  162. ->execute();
  163. $this->resultsDatabase->delete('simpletest_test_id')
  164. ->condition('test_id', $test_id)
  165. ->execute();
  166. }
  167. else {
  168. $count = $this->resultsDatabase->query('SELECT COUNT(test_id) FROM {simpletest_test_id}')->fetchField();
  169. // Clear test results.
  170. $this->resultsDatabase->delete('simpletest')->execute();
  171. $this->resultsDatabase->delete('simpletest_test_id')->execute();
  172. }
  173. return $count;
  174. }
  175. }