From dfaf583d83d513631c7006659be0ab252a8c7c7d Mon Sep 17 00:00:00 2001 From: Antoine Musso Date: Sun, 28 Apr 2013 23:13:49 +0200 Subject: [PATCH] tests: mock parser tests file access I eventually got tired of our parser tests creating and deleting fixture files over and over. This patch mock the files in memory and just expose the file metadata which is all we need for parser tests. The mocked classes are under /tests/phpunit/mocks/ and respect the hierarchy of /includes/. The wiki.png and headbg.jpg files are still copied on each test :/ Change-Id: Iccdff67222e66d48d01dd1596d09df2ea24b8c2a --- tests/TestsAutoLoader.php | 5 + .../phpunit/includes/parser/NewParserTest.php | 19 ++- .../phpunit/mocks/filebackend/MockFSFile.php | 69 ++++++++++ .../mocks/filebackend/MockFileBackend.php | 122 ++++++++++++++++++ .../phpunit/mocks/media/MockBitmapHandler.php | 77 +++++++++++ 5 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/mocks/filebackend/MockFSFile.php create mode 100644 tests/phpunit/mocks/filebackend/MockFileBackend.php create mode 100644 tests/phpunit/mocks/media/MockBitmapHandler.php diff --git a/tests/TestsAutoLoader.php b/tests/TestsAutoLoader.php index ca92fe33d4..4a6e3fbfc9 100644 --- a/tests/TestsAutoLoader.php +++ b/tests/TestsAutoLoader.php @@ -79,6 +79,11 @@ $wgAutoloadClasses += array( 'SiteTest' => "$testDir/phpunit/includes/site/SiteTest.php", 'TestSites' => "$testDir/phpunit/includes/site/TestSites.php", + # tests/phpunit/mocks + 'MockFSFile' => "$testDir/phpunit/mocks/filebackend/MockFSFile.php", + 'MockFileBackend' => "$testDir/phpunit/mocks/filebackend/MockFileBackend.php", + 'MockBitmapHandler' => "$testDir/phpunit/mocks/media/MockBitmapHandler.php", + # tests/phpunit/languages 'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php", diff --git a/tests/phpunit/includes/parser/NewParserTest.php b/tests/phpunit/includes/parser/NewParserTest.php index d66fac77f1..f41c71cc76 100644 --- a/tests/phpunit/includes/parser/NewParserTest.php +++ b/tests/phpunit/includes/parser/NewParserTest.php @@ -110,6 +110,14 @@ 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'; + } + $tmpHooks = $wgHooks; $tmpHooks['ParserTestParser'][] = 'ParserTestParserHook::setup'; $tmpHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp'; @@ -301,7 +309,10 @@ class NewParserTest extends MediaWikiTestCase { $backend = self::$backendToUse; } } else { - $backend = new FSFileBackend( array( + # Replace with a mock. We do not care about generating real + # files on the filesystem, just need to expose the file + # informations. + $backend = new MockFileBackend( array( 'name' => 'local-backend', 'lockManager' => 'nullLockManager', 'containerPaths' => array( @@ -456,6 +467,12 @@ class NewParserTest extends MediaWikiTestCase { return; } + $backend = RepoGroup::singleton()->getLocalRepo()->getBackend(); + if( $backend instanceof MockFileBackend ) { + # In memory backend, so dont bother cleaning them up. + return; + } + $base = $this->getBaseDir(); // delete the files first, then the dirs. self::deleteFiles( diff --git a/tests/phpunit/mocks/filebackend/MockFSFile.php b/tests/phpunit/mocks/filebackend/MockFSFile.php new file mode 100644 index 0000000000..31deaf7a11 --- /dev/null +++ b/tests/phpunit/mocks/filebackend/MockFSFile.php @@ -0,0 +1,69 @@ + $this->exists(), + 'size' => $this->getSize(), + 'file-mime' => $this->getMimeType(), + 'sha1' => $this->getSha1Base36(), + ); + } + + public function getSha1Base36( $recache = false ) { + return '1234567890123456789012345678901'; + } +} diff --git a/tests/phpunit/mocks/filebackend/MockFileBackend.php b/tests/phpunit/mocks/filebackend/MockFileBackend.php new file mode 100644 index 0000000000..c681989c0f --- /dev/null +++ b/tests/phpunit/mocks/filebackend/MockFileBackend.php @@ -0,0 +1,122 @@ + + */ + +/** + * Class simulating a backend store. + * + * @ingroup FileBackend + * @since 1.22 + */ +class MockFileBackend extends FileBackendStore { + + protected $mocked = array(); + + /** Poor man debugging */ + protected function debug( $msg = '' ) { + wfDebug( wfGetCaller() . "$msg\n" ); + } + + public function isPathUsableInternal( $storagePath ) { + return true; + } + + protected function doCreateInternal( array $params ) { + if( isset( $params['content'] ) ) { + $content = $params['content']; + } else { + $content = 'Default mocked file content'; + } + $this->debug(serialize($params)); + $dst = $params['dst']; + $this->mocked[$dst] = $content; + return Status::newGood(); + } + + protected function doStoreInternal( array $params ) { + $this->debug(serialize($params)); + return $this->doCreateInternal( $params ); + } + + protected function doCopyInternal( array $params ) { + $this->debug(serialize($params)); + $src = $params['src']; + $dst = $params['dst']; + $this->mocked[$dst] = $this->mocked[$src]; + return Status::newGood(); + } + + protected function doDeleteInternal( array $params ) { + $this->debug(serialize($params)); + $src = $params['src']; + unset( $this->mocked[$src] ); + return Status::newGood(); + } + + protected function doGetFileStat( array $params ) { + $src = $params['src']; + if( array_key_exists( $src, $this->mocked ) ) { + $this->debug( "('$src') found" ); + return array( + 'mtime' => wfTimestamp( TS_MW ), + 'size' => strlen( $this->mocked[$src] ), + # No sha1, stat does not need it. + ); + } else { + $this->debug( "('$src') not found" ); + return false; + } + } + + protected function doGetLocalCopyMulti( array $params ) { + $tmpFiles = array(); // (path => MockFSFile) + + $this->debug( '(' . serialize($params) . ')' ); + foreach( $params['srcs'] as $src ) { + $tmpFiles[$src] = new MockFSFile( + wfTempDir() . '/' . wfRandomString(32) + ); + } + return $tmpFiles; + } + + protected function doDirectoryExists( $container, $dir, array $params ) { + $this->debug(); + return true; + } + + public function getDirectoryListInternal( $container, $dir, array $params ) { + $this->debug(); + return array(); + } + + public function getFileListInternal( $container, $dir, array $params ) { + $this->debug(); + return array(); + } + + protected function directoriesAreVirtual() { + $this->debug(); + return true; + } +} diff --git a/tests/phpunit/mocks/media/MockBitmapHandler.php b/tests/phpunit/mocks/media/MockBitmapHandler.php new file mode 100644 index 0000000000..2ae30a342c --- /dev/null +++ b/tests/phpunit/mocks/media/MockBitmapHandler.php @@ -0,0 +1,77 @@ +normaliseParams( $image, $params ); + + $scalerParams = array( + # The size to which the image will be resized + 'physicalWidth' => $params['physicalWidth'], + 'physicalHeight' => $params['physicalHeight'], + 'physicalDimensions' => "{$params['physicalWidth']}x{$params['physicalHeight']}", + # The size of the image on the page + 'clientWidth' => $params['width'], + 'clientHeight' => $params['height'], + # Comment as will be added to the EXIF of the thumbnail + 'comment' => isset( $params['descriptionUrl'] ) ? + "File source: {$params['descriptionUrl']}" : '', + # Properties of the original image + 'srcWidth' => $image->getWidth(), + 'srcHeight' => $image->getHeight(), + 'mimeType' => $image->getMimeType(), + 'dstPath' => $dstPath, + 'dstUrl' => $dstUrl, + ); + + # In some cases, we do not bother generating a thumbnail. + if ( !$image->mustRender() && + $scalerParams['physicalWidth'] == $scalerParams['srcWidth'] + && $scalerParams['physicalHeight'] == $scalerParams['srcHeight'] ) { + wfDebug( __METHOD__ . ": returning unscaled image\n" ); + return $this->getClientScalingThumbnailImage( $image, $scalerParams ); + } + + return new ThumbnailImage( $image, $dstUrl, false, $params ); + } +} -- 2.20.1