diff --git a/lib/private/fileproxy.php b/lib/private/fileproxy.php index 52ec79b4bd..2997aaf81b 100644 --- a/lib/private/fileproxy.php +++ b/lib/private/fileproxy.php @@ -67,7 +67,11 @@ class OC_FileProxy{ self::$proxies[]=$proxy; } - public static function getProxies($operation) { + public static function getProxies($operation = null) { + if ($operation === null) { + // return all + return self::$proxies; + } $proxies=array(); foreach(self::$proxies as $proxy) { if(method_exists($proxy, $operation)) { diff --git a/lib/private/hook.php b/lib/private/hook.php index 8516cf0dcf..b63b442c31 100644 --- a/lib/private/hook.php +++ b/lib/private/hook.php @@ -97,4 +97,12 @@ class OC_Hook{ self::$registered=array(); } } + + /** + * DO NOT USE! + * For unit tests ONLY! + */ + static public function getHooks() { + return self::$registered; + } } diff --git a/tests/phpunit-autotest.xml b/tests/phpunit-autotest.xml index a893e96ad9..1a2ab35491 100644 --- a/tests/phpunit-autotest.xml +++ b/tests/phpunit-autotest.xml @@ -35,5 +35,12 @@ + + + + detail + + + diff --git a/tests/testcleanuplistener.php b/tests/testcleanuplistener.php new file mode 100644 index 0000000000..368ea7bc8f --- /dev/null +++ b/tests/testcleanuplistener.php @@ -0,0 +1,139 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +/** + * Detects tests that didn't clean up properly, show a warning, then clean up after them. + */ +class TestCleanupListener implements PHPUnit_Framework_TestListener { + private $verbosity; + + public function __construct($verbosity = 'verbose') { + $this->verbosity = $verbosity; + } + + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) { + } + + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) { + } + + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) { + } + + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) { + } + + public function startTest(PHPUnit_Framework_Test $test) { + } + + public function endTest(PHPUnit_Framework_Test $test, $time) { + } + + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) { + } + + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) { + if ($this->cleanStrayDataFiles() && $this->isShowSuiteWarning()) { + printf("TestSuite '%s': Did not clean up data dir\n", $suite->getName()); + } + if ($this->cleanStrayHooks() && $this->isShowSuiteWarning()) { + printf("TestSuite '%s': Did not clean up hooks\n", $suite->getName()); + } + if ($this->cleanProxies() && $this->isShowSuiteWarning()) { + printf("TestSuite '%s': Did not clean up proxies\n", $suite->getName()); + } + } + + private function isShowSuiteWarning() { + return $this->verbosity === 'suite' || $this->verbosity === 'detail'; + } + + private function isShowDetail() { + return $this->verbosity === 'detail'; + } + + private function unlinkDir($dir) { + if ($dh = opendir($dir)) { + while (($file = readdir($dh)) !== false) { + if ($file === '..' || $file === '.') { + continue; + } + $path = $dir . '/' . $file; + if (is_dir($path)) { + $this->unlinkDir($path); + } + else { + unlink($path); + } + } + closedir($dh); + } + rmdir($dir); + } + + private function cleanStrayDataFiles() { + $knownEntries = array( + 'owncloud.log' => true, + 'owncloud.db' => true, + '..' => true, + '.' => true + ); + $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data'); + $entries = array(); + if ($dh = opendir($datadir)) { + while (($file = readdir($dh)) !== false) { + if (!isset($knownEntries[$file])) { + $entries[] = $file; + } + } + closedir($dh); + } + + if (count($entries) > 0) { + foreach ($entries as $entry) { + $this->unlinkDir($datadir . '/' . $entry); + if ($this->isShowDetail()) { + printf("Stray datadir entry: %s\n", $entry); + } + } + return true; + } + + return false; + } + + private function cleanStrayHooks() { + $hasHooks = false; + $hooks = OC_Hook::getHooks(); + if (!$hooks || sizeof($hooks) === 0) { + return false; + } + + foreach ($hooks as $signalClass => $signals) { + if (sizeof($signals)) { + foreach ($signals as $signalName => $handlers ) { + if (sizeof($handlers) > 0) { + $hasHooks = true; + OC_Hook::clear($signalClass, $signalName); + if ($this->isShowDetail()) { + printf("Stray hook: \"%s\" \"%s\"\n", $signalClass, $signalName); + } + } + } + } + } + return $hasHooks; + } + + private function cleanProxies() { + $proxies = OC_FileProxy::getProxies(); + OC_FileProxy::clearProxies(); + return count($proxies) > 0; + } +} +?>