From: Tim Starling Date: Fri, 25 Jun 2010 02:55:51 +0000 (+0000) Subject: * Removed require/require_once from maintenance scripts where possible, replaced... X-Git-Tag: 1.31.0-rc.0~36395 X-Git-Url: http://git.cyclocoop.org/%40spipnet%40?a=commitdiff_plain;h=752046eecf1a5cf71b640be3c42bf2a02c03d9d8;p=lhc%2Fweb%2Fwiklou.git * Removed require/require_once from maintenance scripts where possible, replaced by the AutoLoader, since register_globals vulnerabilities and inappropriate include_path dependencies are so common. * Rearranged PHPUnit startup so that MediaWiki can be started from the file scope, as required by Setup.php and other core MediaWiki startup files. The custom entry point maintenance/tests/phpunit starts MediaWiki and then passes its arguments through to PHPUnit. * Moved the parser test tag hooks into classes and moved their registration to parserTests.inc, to allow autoloading. * Renamed ApiSetup to ApiTestSetup, MediaWiki_Setup to MediaWikiTestSetup, PTShell to ParserTestSuiteBackend. * Moved command-line initialisation code from the file scope of parserTests.inc to parserTests.php to allow autoloading * Rewrote the interface between PHPUnit and the parser tests. Removed all the hacks designed to make the rest of the PHPUnit tests work without proper teardown of the parser test environment. Moved the PHPUnit_Framework_TestSuite subclass to a file that's not scanned by PHPUnit, to avoid "no tests found" warnings". * Removed the {{NUMBEROFARTICLES}} parser test, too hard to make it work consistently. --- diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 4732d77779..186dc21b58 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -636,13 +636,31 @@ $wgAutoloadLocalClasses = array( 'FakeConverter' => 'languages/Language.php', 'LanguageConverter' => 'languages/LanguageConverter.php', - # maintenance/language + # maintenance + 'AnsiTermColorer' => 'maintenance/parserTests.inc', + 'ApiTestSetup' => 'maintenance/tests/ApiSetup.php', + 'DbTestPreviewer' => 'maintenance/parserTests.inc', + 'DbTestRecorder' => 'maintenance/parserTests.inc', + 'DeleteArchivedFilesImplementation' => 'maintenance/deleteArchivedFiles.inc', + 'DeleteArchivedRevisionsImplementation' => 'maintenance/deleteArchivedRevisions.inc', + 'DummyTermColorer' => 'maintenance/parserTests.inc', + 'MediaWikiTestSetup' => 'maintenance/tests/MediaWiki_Setup.php', + 'PHPUnitTestRecorder' => 'maintenance/tests/ParserHelpers.php', + 'ParserTest' => 'maintenance/parserTests.inc', + 'ParserTestParserHook' => 'maintenance/parserTestsParserHook.php', + 'ParserTestStaticParserHook' => 'maintenance/parserTestsStaticParserHook.php', + 'ParserTestSuiteBackend' => 'maintenance/tests/ParserHelpers.php', + 'ParserUnitTest' => 'maintenance/tests/ParserHelpers.php', + 'RemoteTestRecorder' => 'maintenance/parserTests.inc', + 'SearchEngineTest' => 'maintenance/tests/SearchEngineTest.php', + 'SevenZipStream' => 'maintenance/7zip.inc', + 'TestFileIterator' => 'maintenance/parserTests.inc', + 'TestRecorder' => 'maintenance/parserTests.inc', + 'UploadFromUrlTest' => 'maintenance/tests/UploadFromUrlTest.php', + 'csvStatsOutput' => 'maintenance/language/StatOutputs.php', 'statsOutput' => 'maintenance/language/StatOutputs.php', - 'wikiStatsOutput' => 'maintenance/language/StatOutputs.php', 'textStatsOutput' => 'maintenance/language/StatOutputs.php', - 'csvStatsOutput' => 'maintenance/language/StatOutputs.php', - 'SevenZipStream' => 'maintenance/7zip.inc', - + 'wikiStatsOutput' => 'maintenance/language/StatOutputs.php', ); class AutoLoader { diff --git a/maintenance/language/diffLanguage.php b/maintenance/language/diffLanguage.php index 1260e5e88b..4ead2cee23 100644 --- a/maintenance/language/diffLanguage.php +++ b/maintenance/language/diffLanguage.php @@ -40,7 +40,6 @@ */ /** This script run from the commandline */ -require_once( dirname( __FILE__ ) . '/../parserTests.inc' ); require_once( dirname( __FILE__ ) . '/../commandLine.inc' ); if ( isset( $options['help'] ) ) { usage(); wfDie(); } diff --git a/maintenance/parserTests.inc b/maintenance/parserTests.inc index b76ee5e6f9..18ffb34971 100644 --- a/maintenance/parserTests.inc +++ b/maintenance/parserTests.inc @@ -24,17 +24,6 @@ * @ingroup Maintenance */ -/** */ -$options = array( 'quick', 'color', 'quiet', 'help', 'show-output', 'record', 'run-disabled' ); -$optionsWithArgs = array( 'regex', 'seed', 'setversion' ); - -if ( !defined( "NO_COMMAND_LINE" ) ) { - require_once( dirname( __FILE__ ) . '/commandLine.inc' ); -} -require_once( "$IP/maintenance/parserTestsParserHook.php" ); -require_once( "$IP/maintenance/parserTestsStaticParserHook.php" ); -require_once( "$IP/maintenance/parserTestsParserTime.php" ); - /** * @ingroup Maintenance */ @@ -114,17 +103,7 @@ class ParserTest { $this->regex = ''; } - if ( isset( $options['record'] ) ) { - $this->recorder = new DbTestRecorder( $this ); - } elseif ( isset( $options['compare'] ) ) { - $this->recorder = new DbTestPreviewer( $this ); - } elseif ( isset( $options['upload'] ) ) { - $this->recorder = new RemoteTestRecorder( $this ); - } elseif ( class_exists( 'PHPUnitTestRecorder' ) ) { - $this->recorder = new PHPUnitTestRecorder( $this ); - } else { - $this->recorder = new TestRecorder( $this ); - } + $this->setupRecorder(); $this->keepUploads = isset( $options['keep-uploads'] ); if ( isset( $options['seed'] ) ) { @@ -137,6 +116,18 @@ class ParserTest { $this->functionHooks = array(); } + public function setupRecorder() { + if ( isset( $options['record'] ) ) { + $this->recorder = new DbTestRecorder( $this ); + } elseif ( isset( $options['compare'] ) ) { + $this->recorder = new DbTestPreviewer( $this ); + } elseif ( isset( $options['upload'] ) ) { + $this->recorder = new RemoteTestRecorder( $this ); + } else { + $this->recorder = new TestRecorder( $this ); + } + } + /** * Remove last character if it is a newline */ @@ -589,6 +580,11 @@ class ParserTest { $GLOBALS['wgMemc'] = new FakeMemCachedClient; $GLOBALS['wgOut'] = new OutputPage; + global $wgHooks; + $wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup'; + $wgHooks['ParserTestParser'][] = 'ParserTestStaticParserHook::setup'; + $wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp'; + MagicWord::clearCache(); global $wgUser; @@ -626,7 +622,7 @@ class ParserTest { * Currently this will only be done once per run, and any changes to * the db will be visible to later tests in the run. */ - function setupDatabase() { + public function setupDatabase() { global $wgDBprefix, $wgDBtype; if ( $this->databaseSetupDone ) { return; @@ -771,7 +767,7 @@ class ParserTest { $db->tablePrefix( $prefix ); } - private function teardownDatabase() { + public function teardownDatabase() { global $wgDBtype; if ( !$this->databaseSetupDone ) { return; @@ -1146,6 +1142,11 @@ class ParserTest { $this->term->color( 0 ); return "$display\n$caret"; } + + function getFakeTimestamp( &$parser, &$ts ) { + $ts = 123; + return true; + } } class AnsiTermColorer { @@ -1733,3 +1734,4 @@ class TestFileIterator implements Iterator { return false; } } + diff --git a/maintenance/parserTests.php b/maintenance/parserTests.php index 66b3e228a5..e47a367b5b 100644 --- a/maintenance/parserTests.php +++ b/maintenance/parserTests.php @@ -22,8 +22,11 @@ * @ingroup Maintenance */ -/** */ -require( 'parserTests.inc' ); +$options = array( 'quick', 'color', 'quiet', 'help', 'show-output', 'record', 'run-disabled' ); +$optionsWithArgs = array( 'regex', 'seed', 'setversion' ); + +require_once( dirname( __FILE__ ) . '/commandLine.inc' ); +require_once( dirname( __FILE__ ) . '/parserTests.inc' ); if ( isset( $options['help'] ) ) { echo << !! end -!! test -Magic Word: {{NUMBEROFARTICLES}} -!! input -{{NUMBEROFARTICLES}} -!! result -

2 -

-!! end - !! test Magic Word: {{NUMBEROFFILES}} !! input diff --git a/maintenance/parserTestsParserHook.php b/maintenance/parserTestsParserHook.php index f55cd0e4d7..53b7c98f35 100644 --- a/maintenance/parserTestsParserHook.php +++ b/maintenance/parserTestsParserHook.php @@ -1,6 +1,4 @@ setHook( 'tag', 'wfParserTestParserHookHook' ); + static function setup( &$parser ) { + $parser->setHook( 'tag', array( __CLASS__, 'hook' ) ); - return true; -} + return true; + } -function wfParserTestParserHookHook( $in, $argv ) { - ob_start(); - var_dump( - $in, - $argv - ); - $ret = ob_get_clean(); + function hook( $in, $argv ) { + ob_start(); + var_dump( + $in, + $argv + ); + $ret = ob_get_clean(); - return "
\n$ret
"; + return "
\n$ret
"; + } } - diff --git a/maintenance/parserTestsStaticParserHook.php b/maintenance/parserTestsStaticParserHook.php index 59964c67b5..63230fa310 100644 --- a/maintenance/parserTestsStaticParserHook.php +++ b/maintenance/parserTestsStaticParserHook.php @@ -1,6 +1,4 @@ setHook( 'statictag', array( __CLASS__, 'hook' ) ); -function wfParserTestStaticParserHookSetup( &$parser ) { - $parser->setHook( 'statictag', 'wfParserTestStaticParserHookHook' ); + return true; + } - return true; + static function hook( $in, $argv, $parser ) { + if ( ! count( $argv ) ) { + $parser->static_tag_buf = $in; + return ''; + } else if ( count( $argv ) === 1 && isset( $argv['action'] ) + && $argv['action'] === 'flush' && $in === null ) + { + // Clear the buffer, we probably don't need to + if ( isset( $parser->static_tag_buf ) ) { + $tmp = $parser->static_tag_buf; + } else { + $tmp = ''; + } + $parser->static_tag_buf = null; + return $tmp; + } else + // wtf? + return + "\nCall this extension as string or as" . + " , not in any other way.\n" . + "text: " . var_export( $in, true ) . "\n" . + "argv: " . var_export( $argv, true ) . "\n"; + } } - -function wfParserTestStaticParserHookHook( $in, $argv, $parser ) { - if ( ! count( $argv ) ) { - $parser->static_tag_buf = $in; - return ''; - } else if ( count( $argv ) === 1 && isset( $argv['action'] ) - && $argv['action'] === 'flush' && $in === null ) - { - // Clear the buffer, we probably don't need to - if ( isset( $parser->static_tag_buf ) ) { - $tmp = $parser->static_tag_buf; - } else { - $tmp = ''; - } - $parser->static_tag_buf = null; - return $tmp; - } else - // wtf? - return - "\nCall this extension as string or as" . - " , not in any other way.\n" . - "text: " . var_export( $in, true ) . "\n" . - "argv: " . var_export( $argv, true ) . "\n"; -} - diff --git a/maintenance/tests/ApiSetup.php b/maintenance/tests/ApiSetup.php index 9bc88ea4e7..e4c1765a7d 100644 --- a/maintenance/tests/ApiSetup.php +++ b/maintenance/tests/ApiSetup.php @@ -1,6 +1,6 @@ total++; - $this->success += $result; - - } - - function reportPercentage( $success, $total ) { } -} - class MediaWikiParserTestSuite extends PHPUnit_Framework_TestSuite { - static private $count; - static public $parser; - static public $iter; - - public static function addTables( &$tables ) { - $tables[] = 'user_properties'; - $tables[] = 'filearchive'; - $tables[] = 'logging'; - $tables[] = 'updatelog'; - $tables[] = 'iwlinks'; - $tables[] = 'searchindex'; - return true; - } + private $count; + public $backend; public static function suite() { - $suite = new PHPUnit_Framework_TestSuite(); - - global $wgHooks; - $wgHooks['ParserTestTables'][] = "MediaWikiParserTestSuite::addTables"; - - self::$iter = new TestFileIterator( PARSER_TESTS ); - - foreach ( self::$iter as $i => $test ) { - $suite->addTest( new ParserUnitTest( $i, $test['test'] ) ); - self::$count++; - } - unset( $tests ); - - self::$parser = new PTShell; - self::$iter->setParser( self::$parser ); - self::$parser->recorder->start(); - self::$parser->setupDatabase(); - self::$iter->rewind(); - /* } */ - /* function setUp() { */ - global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgDeferredUpdateList, - $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, - $wgMessageCache, $wgUseDatabaseMessages, $wgMsgCacheExpiry, $parserMemc, - $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, - $wgNamespacesWithSubpages, $wgThumbnailScriptPath, $wgScriptPath, - $wgArticlePath, $wgStyleSheetPath, $wgScript, $wgStylePath; - - $wgScript = '/index.php'; - $wgScriptPath = '/'; - $wgArticlePath = '/wiki/$1'; - $wgStyleSheetPath = '/skins'; - $wgStylePath = '/skins'; - $wgThumbnailScriptPath = false; - $wgLocalFileRepo = array( - 'class' => 'LocalRepo', - 'name' => 'local', - 'directory' => 'test-repo', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - ); - $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; - $wgNamespaceAliases['Image'] = NS_FILE; - $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; - - - $wgEnableParserCache = false; - $wgDeferredUpdateList = array(); - $wgMemc =& wfGetMainCache(); - $messageMemc =& wfGetMessageCacheStorage(); - $parserMemc =& wfGetParserCacheStorage(); - - $wgContLang = new StubContLang; - $wgUser = new StubUser; - $wgLang = new StubUserLang; - $wgOut = new StubObject( 'wgOut', 'OutputPage' ); - $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) ); - $wgRequest = new WebRequest; - - $wgMessageCache = new StubObject( 'wgMessageCache', 'MessageCache', - array( $messageMemc, $wgUseDatabaseMessages, - $wgMsgCacheExpiry, wfWikiID() ) ); - if ( $wgStyleDirectory === false ) $wgStyleDirectory = "$IP/skins"; - - return $suite; + return new self; } - public function tearDown() { - /* $this->teardownDatabase(); */ - $this->recorder->report(); - $this->recorder->end(); - $this->teardownUploadDir( $this->uploadDir ); + public function __construct() { + $this->backend = new ParserTestSuiteBackend; + parent::__construct(); } - public function count() { return self::$count; } - - public function toString() { - return "MediaWiki Parser Tests"; - } - - - private $uploadDir; - private $keepUploads; - - /** - * Remove the dummy uploads directory - */ - private function teardownUploadDir( $dir ) { - if ( $this->keepUploads ) { - return; - } - - // delete the files first, then the dirs. - self::deleteFiles( - array ( - "$dir/3/3a/Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg", - - "$dir/0/09/Bad.jpg", - ) - ); - - self::deleteDirs( - array ( - "$dir/3/3a", - "$dir/3", - "$dir/thumb/6/65", - "$dir/thumb/6", - "$dir/thumb/3/3a/Foobar.jpg", - "$dir/thumb/3/3a", - "$dir/thumb/3", - - "$dir/0/09/", - "$dir/0/", - - "$dir/thumb", - "$dir", - ) - ); - } - - /** - * Delete the specified files, if they exist. - * - * @param $files Array: full paths to files to delete. - */ - private static function deleteFiles( $files ) { - foreach ( $files as $file ) { - if ( file_exists( $file ) ) { - unlink( $file ); - } - } - } - - /** - * Delete the specified directories, if they exist. Must be empty. - * - * @param $dirs Array: full paths to directories to delete. - */ - private static function deleteDirs( $dirs ) { - foreach ( $dirs as $dir ) { - if ( is_dir( $dir ) ) { - rmdir( $dir ); - } - } - } - - /** - * Create a dummy uploads directory which will contain a couple - * of files in order to pass existence tests. - * - * @return String: the directory - */ - private function setupUploadDir() { + public function run( PHPUnit_Framework_TestResult $result = null, $filter = false, + array $groups = array(), array $excludeGroups = array(), $processIsolation = false + ) { global $IP; - if ( $this->keepUploads ) { - $dir = wfTempDir() . '/mwParser-images'; - if ( is_dir( $dir ) ) { - return $dir; - } - } else { - $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; - } - - wfDebug( "Creating upload directory $dir\n" ); - if ( file_exists( $dir ) ) { - wfDebug( "Already exists!\n" ); - return $dir; - } - wfMkdirParents( $dir . '/3/3a' ); - copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); - - wfMkdirParents( $dir . '/0/09' ); - copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" ); - return $dir; - } -} - -/** - * @group Stub - */ -class ParserUnitTest extends PHPUnit_Framework_TestCase { - private $number = 0; - private $test = ""; - - public function testBogus() { - $this->markTestSkipped( "This is a stub" ); - } - - public function __construct( $number = null, $test = null ) { - $this->number = $number; - $this->test = $test; - } - - function count() { return 1; } - - public function run( PHPUnit_Framework_TestResult $result = NULL ) { - PHPUnit_Framework_Assert::resetCount(); - if ( $result === NULL ) { - $result = new PHPUnit_Framework_TestResult; - } + $this->backend->setupDatabase(); - $t = MediaWikiParserTestSuite::$iter->current(); - $k = MediaWikiParserTestSuite::$iter->key(); - - if ( !MediaWikiParserTestSuite::$iter->valid() ) { - return; - } + $iter = new TestFileIterator( "$IP/maintenance/parserTests.txt" ); + $iter->setParser( $this->backend ); + $this->count = 0; - // The only way this should happen is if the parserTest.txt - // file were modified while the script is running. - if ( $k != $this->number ) { - $i = $this->number; - wfDie( "I got confused!\n" ); + foreach ( $iter as $test ) { + $this->addTest( new ParserUnitTest( $this, $test ) ); + $this->count++; } - $result->startTest( $this ); - PHPUnit_Util_Timer::start(); - - $r = false; - try { - $r = MediaWikiParserTestSuite::$parser->runTest( - $t['test'], $t['input'], $t['result'], $t['options'], $t['config'] - ); - PHPUnit_Framework_Assert::assertTrue( true, $t['test'] ); - } - catch ( PHPUnit_Framework_AssertionFailedError $e ) { - $result->addFailure( $this, $e, PHPUnit_Util_Timer::stop() ); - } - catch ( Exception $e ) { - $result->addError( $this, $e, PHPUnit_Util_Timer::stop() ); - } - PHPUnit_Framework_Assert::assertTrue( true, $t['test'] ); + parent::run( $result, $filter, $groups, $excludeGroups, $processIsolation ); - $result->endTest( $this, PHPUnit_Util_Timer::stop() ); - - MediaWikiParserTestSuite::$parser->recorder->record( $t['test'], $r ); - MediaWikiParserTestSuite::$iter->next(); - $this->addToAssertionCount( PHPUnit_Framework_Assert::getCount() ); - - return $result; + $this->backend->teardownDatabase(); } -} - -class PTShell extends ParserTest { - function showTesting( $desc ) { + public function count() { + return $this->count; } - function showRunFile( $path ) { + public function toString() { + return "MediaWiki Parser Tests"; } - function showSuccess( $desc ) { - PHPUnit_Framework_Assert::assertTrue( true, $desc ); - return true; + public function getBackend() { + return $this->backend; } - function showFailure( $desc, $expected, $got ) { - PHPUnit_Framework_Assert::assertEquals( $expected, $got, $desc ); + public function getIterator() { + return $this->iterator; } - } - diff --git a/maintenance/tests/MediaWiki_Setup.php b/maintenance/tests/MediaWiki_Setup.php index 8f3b1ca816..85c43d18aa 100644 --- a/maintenance/tests/MediaWiki_Setup.php +++ b/maintenance/tests/MediaWiki_Setup.php @@ -1,6 +1,6 @@ suite = $suite; + $this->test = $test; + } + + function count() { return 1; } + + public function run( PHPUnit_Framework_TestResult $result = null ) { + PHPUnit_Framework_Assert::resetCount(); + if ( $result === NULL ) { + $result = new PHPUnit_Framework_TestResult; + } + + $backend = $this->suite->getBackend(); + $result->startTest( $this ); + PHPUnit_Util_Timer::start(); + + $r = false; + try { + # Run the test. + # On failure, the subclassed backend will throw an exception with + # the details. + $r = $backend->runTest( + $this->test['test'], + $this->test['input'], + $this->test['result'], + $this->test['options'], + $this->test['config'] + ); + } + catch ( PHPUnit_Framework_AssertionFailedError $e ) { + $result->addFailure( $this, $e, PHPUnit_Util_Timer::stop() ); + } + catch ( Exception $e ) { + $result->addError( $this, $e, PHPUnit_Util_Timer::stop() ); + } + + $result->endTest( $this, PHPUnit_Util_Timer::stop() ); + + $backend->recorder->record( $this->test['test'], $r ); + $this->addToAssertionCount( PHPUnit_Framework_Assert::getCount() ); + + return $result; + } + +} + +class ParserTestSuiteBackend extends ParserTest { + function showTesting( $desc ) { + } + + function showRunFile( $path ) { + } + + function showSuccess( $desc ) { + PHPUnit_Framework_Assert::assertTrue( true, $desc ); + return true; + } + + function showFailure( $desc, $expected, $got ) { + PHPUnit_Framework_Assert::assertEquals( $expected, $got, $desc ); + } + + public function setupRecorder() { + $this->recorder = new PHPUnitTestRecorder( $this ); + } +} + +class PHPUnitTestRecorder extends TestRecorder { + function record( $test, $result ) { + $this->total++; + $this->success += $result; + + } + + function reportPercentage( $success, $total ) { } +} + diff --git a/maintenance/tests/SearchDbTest.php b/maintenance/tests/SearchDbTest.php index 6e3e274c96..e9884b32c1 100644 --- a/maintenance/tests/SearchDbTest.php +++ b/maintenance/tests/SearchDbTest.php @@ -1,6 +1,4 @@ " ) ) { - echo <<" ) ) { + echo <<run( $argv ); + diff --git a/maintenance/tests/phpunit.xml b/maintenance/tests/phpunit.xml index 1ba58c8198..1cf7277fea 100644 --- a/maintenance/tests/phpunit.xml +++ b/maintenance/tests/phpunit.xml @@ -14,7 +14,7 @@ DatabaseSqliteTest.php DatabaseTest.php GlobalTest.php - HttpTest.php + IPTest.php ImageFunctionsTest.php LanguageConverterTest.php @@ -41,4 +41,4 @@ Stub - \ No newline at end of file +