Split up testHelpers.inc, break off fuzz testing
[lhc/web/wiklou.git] / tests / phpunit / includes / parser / NewParserTest.php
index c56626f..097e413 100644 (file)
@@ -1,4 +1,7 @@
 <?php
+
+use MediaWiki\MediaWikiServices;
+
 /**
  * Although marked as a stub, can work independently.
  *
@@ -26,11 +29,6 @@ class NewParserTest extends MediaWikiTestCase {
        public $functionHooks = [];
        public $transparentHooks = [];
 
-       // Fuzz test
-       public $maxFuzzTestLength = 300;
-       public $fuzzSeed = 0;
-       public $memoryLimit = 50;
-
        /**
         * @var DjVuSupport
         */
@@ -127,22 +125,6 @@ class NewParserTest extends MediaWikiTestCase {
                        $tmpGlobals['wgStyleDirectory'] = "$IP/skins";
                }
 
-               # Replace all media handlers with a mock. We do not need to generate
-               # actual thumbnails to do parser testing, we only care about receiving
-               # a ThumbnailImage properly initialized.
-               global $wgMediaHandlers;
-               foreach ( $wgMediaHandlers as $type => $handler ) {
-                       $tmpGlobals['wgMediaHandlers'][$type] = 'MockBitmapHandler';
-               }
-               // Vector images have to be handled slightly differently
-               $tmpGlobals['wgMediaHandlers']['image/svg+xml'] = 'MockSvgHandler';
-
-               // DjVu images have to be handled slightly differently
-               $tmpGlobals['wgMediaHandlers']['image/vnd.djvu'] = 'MockDjVuHandler';
-
-               // Ogg video/audio increasingly more differently
-               $tmpGlobals['wgMediaHandlers']['application/ogg'] = 'MockOggHandler';
-
                $tmpHooks = $wgHooks;
                $tmpHooks['ParserTestParser'][] = 'ParserTestParserHook::setup';
                $tmpHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp';
@@ -177,6 +159,13 @@ class NewParserTest extends MediaWikiTestCase {
                MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
                $wgContLang->resetNamespaces(); # reset namespace cache
                ParserTest::resetTitleServices();
+               MediaWikiServices::getInstance()->disableService( 'MediaHandlerFactory' );
+               MediaWikiServices::getInstance()->redefineService(
+                       'MediaHandlerFactory',
+                       function() {
+                               return new MockMediaHandlerFactory();
+                       }
+               );
        }
 
        protected function tearDown() {
@@ -196,6 +185,7 @@ class NewParserTest extends MediaWikiTestCase {
 
                // Restore message cache (temporary pages and $wgUseDatabaseMessages)
                MessageCache::destroyInstance();
+               MediaWikiServices::getInstance()->resetServiceForTesting( 'MediaHandlerFactory' );
 
                parent::tearDown();
 
@@ -717,6 +707,7 @@ class NewParserTest extends MediaWikiTestCase {
                if ( $this->regex != '' && !preg_match( '/' . $this->regex . '/', $desc ) ) {
                        $this->assertTrue( true ); // XXX: don't flood output with "test made no assertions"
                        // $this->markTestSkipped( 'Filtered out by the user' );
+                       $this->teardownGlobals();
                        return;
                }
 
@@ -724,6 +715,7 @@ class NewParserTest extends MediaWikiTestCase {
                        // parser tests frequently assume that the main namespace contains wikitext.
                        // @todo When setting up pages, force the content model. Only skip if
                        //        $wgtContentModelUseDB is false.
+                       $this->teardownGlobals();
                        $this->markTestSkipped( "Main namespace does not support wikitext,"
                                . "skipping parser test: $desc" );
                }
@@ -754,8 +746,10 @@ class NewParserTest extends MediaWikiTestCase {
                        global $wgTexvc;
 
                        if ( !isset( $wgTexvc ) ) {
+                               $this->teardownGlobals();
                                $this->markTestSkipped( "SKIPPED: \$wgTexvc is not set" );
                        } elseif ( !is_executable( $wgTexvc ) ) {
+                               $this->teardownGlobals();
                                $this->markTestSkipped( "SKIPPED: texvc binary does not exist"
                                        . " or is not executable.\n"
                                        . "Current configuration is:\n\$wgTexvc = '$wgTexvc'" );
@@ -764,12 +758,14 @@ class NewParserTest extends MediaWikiTestCase {
 
                if ( isset( $opts['djvu'] ) ) {
                        if ( !$this->djVuSupport->isEnabled() ) {
+                               $this->teardownGlobals();
                                $this->markTestSkipped( "SKIPPED: djvu binaries do not exist or are not executable.\n" );
                        }
                }
 
                if ( isset( $opts['tidy'] ) ) {
                        if ( !$this->tidySupport->isEnabled() ) {
+                               $this->teardownGlobals();
                                $this->markTestSkipped( "SKIPPED: tidy extension is not installed.\n" );
                        } else {
                                $options->setTidy( true );
@@ -836,144 +832,6 @@ class NewParserTest extends MediaWikiTestCase {
                $this->assertEquals( $result, $out, $desc );
        }
 
-       /**
-        * Run a fuzz test series
-        * Draw input from a set of test files
-        *
-        * @todo fixme Needs some work to not eat memory until the world explodes
-        *
-        * @group ParserFuzz
-        */
-       public function testFuzzTests() {
-               global $wgParserTestFiles;
-
-               $files = $wgParserTestFiles;
-
-               if ( $this->getCliArg( 'file' ) ) {
-                       $files = [ $this->getCliArg( 'file' ) ];
-               }
-
-               $dict = $this->getFuzzInput( $files );
-               $dictSize = strlen( $dict );
-               $logMaxLength = log( $this->maxFuzzTestLength );
-
-               ini_set( 'memory_limit', $this->memoryLimit * 1048576 );
-
-               $user = new User;
-               $opts = ParserOptions::newFromUser( $user );
-               $title = Title::makeTitle( NS_MAIN, 'Parser_test' );
-
-               $id = 1;
-
-               while ( true ) {
-
-                       // Generate test input
-                       mt_srand( ++$this->fuzzSeed );
-                       $totalLength = mt_rand( 1, $this->maxFuzzTestLength );
-                       $input = '';
-
-                       while ( strlen( $input ) < $totalLength ) {
-                               $logHairLength = mt_rand( 0, 1000000 ) / 1000000 * $logMaxLength;
-                               $hairLength = min( intval( exp( $logHairLength ) ), $dictSize );
-                               $offset = mt_rand( 0, $dictSize - $hairLength );
-                               $input .= substr( $dict, $offset, $hairLength );
-                       }
-
-                       $this->setupGlobals();
-                       $parser = $this->getParser();
-
-                       // Run the test
-                       try {
-                               $parser->parse( $input, $title, $opts );
-                               $this->assertTrue( true, "Test $id, fuzz seed {$this->fuzzSeed}" );
-                       } catch ( Exception $exception ) {
-                               $input_dump = sprintf( "string(%d) \"%s\"\n", strlen( $input ), $input );
-
-                               $this->assertTrue( false, "Test $id, fuzz seed {$this->fuzzSeed}. \n\n" .
-                                       "Input: $input_dump\n\nError: {$exception->getMessage()}\n\n" .
-                                       "Backtrace: {$exception->getTraceAsString()}" );
-                       }
-
-                       $this->teardownGlobals();
-                       $parser->__destruct();
-
-                       if ( $id % 100 == 0 ) {
-                               $usage = intval( memory_get_usage( true ) / $this->memoryLimit / 1048576 * 100 );
-                               // echo "{$this->fuzzSeed}: $numSuccess/$numTotal (mem: $usage%)\n";
-                               if ( $usage > 90 ) {
-                                       $ret = "Out of memory:\n";
-                                       $memStats = $this->getMemoryBreakdown();
-
-                                       foreach ( $memStats as $name => $usage ) {
-                                               $ret .= "$name: $usage\n";
-                                       }
-
-                                       throw new MWException( $ret );
-                               }
-                       }
-
-                       $id++;
-               }
-       }
-
-       // Various getter functions
-
-       /**
-        * Get an input dictionary from a set of parser test files
-        * @param array $filenames
-        * @return string
-        */
-       function getFuzzInput( $filenames ) {
-               $dict = '';
-
-               foreach ( $filenames as $filename ) {
-                       $contents = file_get_contents( $filename );
-                       preg_match_all( '/!!\s*input\n(.*?)\n!!\s*result/s', $contents, $matches );
-
-                       foreach ( $matches[1] as $match ) {
-                               $dict .= $match . "\n";
-                       }
-               }
-
-               return $dict;
-       }
-
-       /**
-        * Get a memory usage breakdown
-        * @return array
-        */
-       function getMemoryBreakdown() {
-               $memStats = [];
-
-               foreach ( $GLOBALS as $name => $value ) {
-                       $memStats['$' . $name] = strlen( serialize( $value ) );
-               }
-
-               $classes = get_declared_classes();
-
-               foreach ( $classes as $class ) {
-                       $rc = new ReflectionClass( $class );
-                       $props = $rc->getStaticProperties();
-                       $memStats[$class] = strlen( serialize( $props ) );
-                       $methods = $rc->getMethods();
-
-                       foreach ( $methods as $method ) {
-                               $memStats[$class] += strlen( serialize( $method->getStaticVariables() ) );
-                       }
-               }
-
-               $functions = get_defined_functions();
-
-               foreach ( $functions['user'] as $function ) {
-                       $rf = new ReflectionFunction( $function );
-                       $memStats["$function()"] = strlen( serialize( $rf->getStaticVariables() ) );
-               }
-
-               asort( $memStats );
-
-               return $memStats;
-       }
-
        /**
         * Get a Parser object
         * @param Preprocessor $preprocessor