testcleanuplistener.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <?php
  2. /**
  3. * Copyright (c) 2013 Vincent Petry <pvince81@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. /**
  9. * Detects tests that didn't clean up properly, show a warning, then clean up after them.
  10. */
  11. class TestCleanupListener implements PHPUnit_Framework_TestListener {
  12. private $verbosity;
  13. public function __construct($verbosity = 'verbose') {
  14. $this->verbosity = $verbosity;
  15. }
  16. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) {
  17. }
  18. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) {
  19. }
  20. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
  21. }
  22. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
  23. }
  24. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
  25. }
  26. public function startTest(PHPUnit_Framework_Test $test) {
  27. }
  28. public function endTest(PHPUnit_Framework_Test $test, $time) {
  29. }
  30. public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {
  31. }
  32. public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {
  33. // don't clean up the test environment if a data provider finished
  34. if (!($suite instanceof PHPUnit_Framework_TestSuite_DataProvider)) {
  35. if ($this->cleanStorages() && $this->isShowSuiteWarning()) {
  36. printf("TestSuite '%s': Did not clean up storages\n", $suite->getName());
  37. }
  38. if ($this->cleanFileCache() && $this->isShowSuiteWarning()) {
  39. printf("TestSuite '%s': Did not clean up file cache\n", $suite->getName());
  40. }
  41. if ($this->cleanStrayDataFiles() && $this->isShowSuiteWarning()) {
  42. printf("TestSuite '%s': Did not clean up data dir\n", $suite->getName());
  43. }
  44. if ($this->cleanStrayHooks() && $this->isShowSuiteWarning()) {
  45. printf("TestSuite '%s': Did not clean up hooks\n", $suite->getName());
  46. }
  47. if ($this->cleanProxies() && $this->isShowSuiteWarning()) {
  48. printf("TestSuite '%s': Did not clean up proxies\n", $suite->getName());
  49. }
  50. }
  51. }
  52. private function isShowSuiteWarning() {
  53. return $this->verbosity === 'suite' || $this->verbosity === 'detail';
  54. }
  55. private function isShowDetail() {
  56. return $this->verbosity === 'detail';
  57. }
  58. /**
  59. * @param string $dir
  60. */
  61. private function unlinkDir($dir) {
  62. if ($dh = @opendir($dir)) {
  63. while (($file = readdir($dh)) !== false) {
  64. if ($file === '..' || $file === '.') {
  65. continue;
  66. }
  67. $path = $dir . '/' . $file;
  68. if (is_dir($path)) {
  69. $this->unlinkDir($path);
  70. }
  71. else {
  72. @unlink($path);
  73. }
  74. }
  75. closedir($dh);
  76. }
  77. @rmdir($dir);
  78. }
  79. private function cleanStrayDataFiles() {
  80. $knownEntries = array(
  81. 'owncloud.log' => true,
  82. 'owncloud.db' => true,
  83. '.ocdata' => true,
  84. '..' => true,
  85. '.' => true
  86. );
  87. $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data');
  88. $entries = array();
  89. if ($dh = opendir($datadir)) {
  90. while (($file = readdir($dh)) !== false) {
  91. if (!isset($knownEntries[$file])) {
  92. $entries[] = $file;
  93. }
  94. }
  95. closedir($dh);
  96. }
  97. if (count($entries) > 0) {
  98. foreach ($entries as $entry) {
  99. $this->unlinkDir($datadir . '/' . $entry);
  100. if ($this->isShowDetail()) {
  101. printf("Stray datadir entry: %s\n", $entry);
  102. }
  103. }
  104. return true;
  105. }
  106. return false;
  107. }
  108. private function cleanStorages() {
  109. $sql = 'DELETE FROM `*PREFIX*storages`';
  110. $query = \OC_DB::prepare( $sql );
  111. $result = $query->execute();
  112. if ($result > 0) {
  113. return true;
  114. }
  115. return false;
  116. }
  117. private function cleanFileCache() {
  118. $sql = 'DELETE FROM `*PREFIX*filecache`';
  119. $query = \OC_DB::prepare( $sql );
  120. $result = $query->execute();
  121. if ($result > 0) {
  122. return true;
  123. }
  124. return false;
  125. }
  126. private function cleanStrayHooks() {
  127. $hasHooks = false;
  128. $hooks = OC_Hook::getHooks();
  129. if (!$hooks || sizeof($hooks) === 0) {
  130. return false;
  131. }
  132. foreach ($hooks as $signalClass => $signals) {
  133. if (sizeof($signals)) {
  134. foreach ($signals as $signalName => $handlers ) {
  135. if (sizeof($handlers) > 0) {
  136. $hasHooks = true;
  137. OC_Hook::clear($signalClass, $signalName);
  138. if ($this->isShowDetail()) {
  139. printf("Stray hook: \"%s\" \"%s\"\n", $signalClass, $signalName);
  140. }
  141. }
  142. }
  143. }
  144. }
  145. return $hasHooks;
  146. }
  147. private function cleanProxies() {
  148. $proxies = OC_FileProxy::getProxies();
  149. OC_FileProxy::clearProxies();
  150. // reenable in case some test failed to reenable them
  151. OC_FileProxy::$enabled = true;
  152. return count($proxies) > 0;
  153. }
  154. }