https://www.mediawiki.org/wiki/Special:Code/MediaWiki/105767
Revision: 105767 Author: aaron Date: 2011-12-10 18:22:14 +0000 (Sat, 10 Dec 2011) Log Message: ----------- * Fixed checkContainerName() as it should be alphaNUMERIC * Moved default getLocalReference() implementation down to FileBackend * Removed overkill sanity check from img_auth.php * Made NewParserTest delete the table rows it makes * Added NullLockManager to autoloader * Fixed 'rmdir(...\Temp/mwParser-1353610175-images/thumb/3/3a/Foobar.jpg)' error in tests * EXIF & metadata test fixes * Added MTO::getLocalCopyPath() and let backend instances be passed in as repo config (useful for tests) Modified Paths: -------------- branches/FileBackend/phase3/img_auth.php branches/FileBackend/phase3/includes/AutoLoader.php branches/FileBackend/phase3/includes/filerepo/FileRepo.php branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php branches/FileBackend/phase3/includes/filerepo/backend/LockManager.php branches/FileBackend/phase3/includes/media/Generic.php branches/FileBackend/phase3/includes/media/MediaTransformOutput.php branches/FileBackend/phase3/tests/phpunit/includes/filerepo/FileBackendTest.php branches/FileBackend/phase3/tests/phpunit/includes/media/ExifRotationTest.php branches/FileBackend/phase3/tests/phpunit/includes/media/FormatMetadataTest.php branches/FileBackend/phase3/tests/phpunit/includes/media/GIFTest.php branches/FileBackend/phase3/tests/phpunit/includes/media/PNGTest.php branches/FileBackend/phase3/tests/phpunit/includes/parser/NewParserTest.php Modified: branches/FileBackend/phase3/img_auth.php =================================================================== --- branches/FileBackend/phase3/img_auth.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/img_auth.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -74,9 +74,6 @@ // Get the local file repository $repo = RepoGroup::singleton()->getRepo( 'local' ); - if ( !$repo ) { - return; // wtf? - } // Get the full file storage path and extract the source file name. // (e.g. 120px-Foo.png => Foo.png or page2-120px-Foo.png => Foo.png). Modified: branches/FileBackend/phase3/includes/AutoLoader.php =================================================================== --- branches/FileBackend/phase3/includes/AutoLoader.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/includes/AutoLoader.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -499,6 +499,7 @@ 'LockManager' => 'includes/filerepo/backend/LockManager.php', 'FSLockManager' => 'includes/filerepo/backend/LockManager.php', 'DBLockManager' => 'includes/filerepo/backend/LockManager.php', + 'NullLockManager' => 'includes/filerepo/backend/LockManager.php', 'FileOp' => 'includes/filerepo/backend/FileOp.php', 'StoreFileOp' => 'includes/filerepo/backend/FileOp.php', 'CopyFileOp' => 'includes/filerepo/backend/FileOp.php', Modified: branches/FileBackend/phase3/includes/filerepo/FileRepo.php =================================================================== --- branches/FileBackend/phase3/includes/filerepo/FileRepo.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/includes/filerepo/FileRepo.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -44,7 +44,11 @@ $this->url = isset( $info['url'] ) ? $info['url'] : false; // a subclass will need to set the URL (e.g. ForeignAPIRepo) - $this->backend = FileBackendGroup::singleton()->get( $info['backend'] ); + if ( $info['backend'] instanceof FileBackendBase ) { + $this->backend = $info['backend']; // useful for testing + } else { + $this->backend = FileBackendGroup::singleton()->get( $info['backend'] ); + } // Optional settings that can have no value $optionalSettings = array( @@ -94,7 +98,7 @@ } /** - * Get the file backend + * Get the file backend instance * * @return FileBackendBase */ Modified: branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php =================================================================== --- branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -289,9 +289,7 @@ * @param $params Array * @return FSFile|null Returns null on failure */ - public function getLocalReference( array $params ) { - return $this->getLocalCopy( $params ); - } + abstract public function getLocalReference( array $params ); /** * Get a local copy on disk of the file at a storage path in the backend. @@ -477,6 +475,10 @@ return 'internal'; } + public function getLocalReference( array $params ) { + return $this->getLocalCopy( $params ); + } + function streamFile( array $params ) { $status = Status::newGood(); @@ -736,7 +738,7 @@ // This accounts for Swift and S3 restrictions. Also note // that these urlencode to the same string, which is useful // since the Swift size limit is *after* URL encoding. - return preg_match( '/^[a-zA-Z._-]{1,256}$/u', $container ); + return preg_match( '/^[a-zA-Z0-9._-]{1,256}$/u', $container ); } /** Modified: branches/FileBackend/phase3/includes/filerepo/backend/LockManager.php =================================================================== --- branches/FileBackend/phase3/includes/filerepo/backend/LockManager.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/includes/filerepo/backend/LockManager.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -260,6 +260,7 @@ * All lock requests for a resource, identified by a hash string, will * map to one bucket. Each bucket maps to one or several peer DB servers, * each having a `file_locks` table with row-level locking. + * This does not use GET_LOCK() per http://bugs.mysql.com/bug.php?id=1118. * * A majority of peer servers must agree for a lock to be acquired. * As long as one peer server is up, lock requests will not be blocked Modified: branches/FileBackend/phase3/includes/media/Generic.php =================================================================== --- branches/FileBackend/phase3/includes/media/Generic.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/includes/media/Generic.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -216,7 +216,7 @@ $out = $this->doFSTransform( $image, $tmpDest, $dstUrl, $params, $flags ); // Copy any thumbnail from FS into storage at $dstpath // Note: no file is created if it's to be rendered client-side. - if ( !$out->isError() && $out->hasFile() ) { + if ( !$out->isError() && $out->hasFile() && !$out->fileIsSource() ) { $op = array( 'op' => 'store', 'src' => $tmpDest, 'dst' => $dstPath, 'overwriteDest' => true ); if ( !$image->getRepo()->getBackend()->doOperation( $op )->isOK() ) { Modified: branches/FileBackend/phase3/includes/media/MediaTransformOutput.php =================================================================== --- branches/FileBackend/phase3/includes/media/MediaTransformOutput.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/includes/media/MediaTransformOutput.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -78,8 +78,8 @@ * @return Bool */ public function hasFile() { - // If TRANSFORM_LATER, a 0-byte temp file be at the path (not purged yet) - return ( !$this->isError() && $this->path && filesize( $this->path ) ); + // If TRANSFORM_LATER, $this->path will be false + return ( !$this->isError() && $this->path ); } /** @@ -93,6 +93,15 @@ } /** + * Get the path of a file system copy of the thumbnail + * + * @return string|false Returns false if there isn't one + */ + public function getLocalCopyPath() { + return $this->path; + } + + /** * Stream the file if there were no errors * * @param $headers Array Additional HTTP headers to send on success Modified: branches/FileBackend/phase3/tests/phpunit/includes/filerepo/FileBackendTest.php =================================================================== --- branches/FileBackend/phase3/tests/phpunit/includes/filerepo/FileBackendTest.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/tests/phpunit/includes/filerepo/FileBackendTest.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -287,7 +287,7 @@ } /** - * @dataProvider provider_testConcatenate + * @dataProvider provider_testCreate */ public function provider_testCreate() { $cases = array(); @@ -324,47 +324,17 @@ return $cases; } - /** - * @dataProvider provider_testConcatenate - */ - public function testConcatenate() { - - } + // @TODO: testConcatenate - /** - * @dataProvider provider_testPrepare - */ - public function testPrepare() { - - } + // @TODO: testPrepare - /** - * @dataProvider provider_testSecure - */ - public function testSecure() { - - } + // @TODO: testSecure - /** - * @dataProvider provider_testClean - */ - public function testClean() { - - } + // @TODO: testClean - /** - * @dataProvider provider_testGetLocalCopy - */ - public function testGetLocalCopy() { - - } + // @TODO: testGetLocalCopy - /** - * @dataProvider provider_testDoOperations - */ - public function testDoOperations() { - - } + // @TODO: testDoOperations public function testGetFileList() { $base = $this->singleBasePath(); Modified: branches/FileBackend/phase3/tests/phpunit/includes/media/ExifRotationTest.php =================================================================== --- branches/FileBackend/phase3/tests/phpunit/includes/media/ExifRotationTest.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/tests/phpunit/includes/media/ExifRotationTest.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -7,13 +7,19 @@ function setUp() { parent::setUp(); - $this->filePath = dirname( __FILE__ ) . '/../../data/media/'; $this->handler = new BitmapHandler(); - $this->repo = new FSRepo(array( - 'name' => 'temp', - 'directory' => wfTempDir() . '/exif-test-' . time() . '-' . mt_rand(), - 'url' => 'http://localhost/thumbtest' - )); + $filePath = dirname( __FILE__ ) . '/../../data/media'; + $tmpDir = wfTempDir() . '/exif-test-' . time() . '-' . mt_rand(); + $this->backend = new FSFileBackend( array( + 'name' => 'localtesting', + 'lockManager' => 'nullLockManager', + 'containerPaths' => array( 'images-thumb' => $tmpDir, 'data' => $filePath ) + ) ); + $this->repo = new FSRepo( array( + 'name' => 'temp', + 'url' => 'http://localhost/thumbtest', + 'backend' => $this->backend + ) ); if ( !wfDl( 'exif' ) ) { $this->markTestSkipped( "This test needs the exif extension." ); } @@ -39,7 +45,7 @@ if ( !BitmapHandler::canRotate() ) { $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); } - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $name, $type ); + $file = $this->dataFile( $name, $type ); $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" ); $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" ); } @@ -66,13 +72,13 @@ throw new MWException('bogus test data format ' . $size); } - $file = $this->localFile( $name, $type ); + $file = $this->dataFile( $name, $type ); $thumb = $file->transform( $params, File::RENDER_NOW ); $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" ); $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" ); - $gis = getimagesize( $thumb->getPath() ); + $gis = getimagesize( $thumb->getLocalCopyPath() ); if ($out[0] > $info['width']) { // Physical image won't be scaled bigger than the original. $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size"); @@ -84,8 +90,9 @@ } } - private function localFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, $this->filePath . $name, $type ); + private function dataFile( $name, $type ) { + return new UnregisteredLocalFile( false, $this->repo, + "mwstore://localtesting/data/$name", $type ); } function providerFiles() { @@ -129,7 +136,7 @@ global $wgEnableAutoRotation; $wgEnableAutoRotation = false; - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $name, $type ); + $file = $this->dataFile( $name, $type ); $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" ); $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" ); @@ -158,13 +165,13 @@ throw new MWException('bogus test data format ' . $size); } - $file = $this->localFile( $name, $type ); + $file = $this->dataFile( $name, $type ); $thumb = $file->transform( $params, File::RENDER_NOW ); $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" ); $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" ); - $gis = getimagesize( $thumb->getPath() ); + $gis = getimagesize( $thumb->getLocalCopyPath() ); if ($out[0] > $info['width']) { // Physical image won't be scaled bigger than the original. $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size"); @@ -242,7 +249,7 @@ array( 270, array( self::TEST_HEIGHT, self::TEST_WIDTH ) - ), + ), ); } } Modified: branches/FileBackend/phase3/tests/phpunit/includes/media/FormatMetadataTest.php =================================================================== --- branches/FileBackend/phase3/tests/phpunit/includes/media/FormatMetadataTest.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/tests/phpunit/includes/media/FormatMetadataTest.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -4,6 +4,17 @@ if ( !wfDl( 'exif' ) ) { $this->markTestSkipped( "This test needs the exif extension." ); } + $filePath = dirname( __FILE__ ) . '/../../data/media'; + $this->backend = new FSFileBackend( array( + 'name' => 'localtesting', + 'lockManager' => 'nullLockManager', + 'containerPaths' => array( 'data' => $filePath ) + ) ); + $this->repo = new FSRepo( array( + 'name' => 'temp', + 'url' => 'http://localhost/thumbtest', + 'backend' => $this->backend + ) ); global $wgShowEXIF; $this->show = $wgShowEXIF; $wgShowEXIF = true; @@ -14,8 +25,7 @@ } public function testInvalidDate() { - $file = UnregisteredLocalFile::newFromPath( dirname( __FILE__ ) . - '/../../data/media/broken_exif_date.jpg', 'image/jpeg' ); + $file = $this->dataFile( 'broken_exif_date.jpg', 'image/jpeg' ); // Throws an error if bug hit $meta = $file->formatMetadata(); @@ -34,4 +44,9 @@ $meta['visible'][$dateIndex]['value'], 'File with invalid date metadata (bug 29471)' ); } + + private function dataFile( $name, $type ) { + return new UnregisteredLocalFile( false, $this->repo, + "mwstore://localtesting/data/$name", $type ); + } } Modified: branches/FileBackend/phase3/tests/phpunit/includes/media/GIFTest.php =================================================================== --- branches/FileBackend/phase3/tests/phpunit/includes/media/GIFTest.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/tests/phpunit/includes/media/GIFTest.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -2,12 +2,22 @@ class GIFHandlerTest extends MediaWikiTestCase { public function setUp() { - $this->filePath = dirname( __FILE__ ) . '/../../data/media/'; + $this->filePath = dirname( __FILE__ ) . '/../../data/media'; + $this->backend = new FSFileBackend( array( + 'name' => 'localtesting', + 'lockManager' => 'nullLockManager', + 'containerPaths' => array( 'data' => $this->filePath ) + ) ); + $this->repo = new FSRepo( array( + 'name' => 'temp', + 'url' => 'http://localhost/thumbtest', + 'backend' => $this->backend + ) ); $this->handler = new GIFHandler(); } public function testInvalidFile() { - $res = $this->handler->getMetadata( null, $this->filePath . 'README' ); + $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); $this->assertEquals( GIFHandler::BROKEN_FILE, $res ); } /** @@ -16,8 +26,7 @@ * @dataProvider dataIsAnimated */ public function testIsAnimanted( $filename, $expected ) { - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, - 'image/gif' ); + $file = $this->dataFile( $filename, 'image/gif' ); $actual = $this->handler->isAnimatedImage( $file ); $this->assertEquals( $expected, $actual ); } @@ -34,8 +43,7 @@ * @dataProvider dataGetImageArea */ public function testGetImageArea( $filename, $expected ) { - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, - 'image/gif' ); + $file = $this->dataFile( $filename, 'image/gif' ); $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() ); $this->assertEquals( $expected, $actual ); } @@ -71,15 +79,20 @@ * @dataProvider dataGetMetadata */ public function testGetMetadata( $filename, $expected ) { - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, - 'image/gif' ); - $actual = $this->handler->getMetadata( $file, $this->filePath . $filename ); + $file = $this->dataFile( $filename, 'image/gif' ); + $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" ); $this->assertEquals( unserialize( $expected ), unserialize( $actual ) ); } + public function dataGetMetadata() { return array( array( 'nonanimated.gif', 'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}' ), array( 'animated-xmp.gif', 'a:4:{s:10:"frameCount";i:4;s:6:"looped";b:1;s:8:"duration";d:2.399999999999999911182158029987476766109466552734375;s:8:"metadata";a:5:{s:6:"Artist";s:7:"Bawolff";s:16:"ImageDescription";a:2:{s:9:"x-default";s:18:"A file to test GIF";s:5:"_type";s:4:"lang";}s:15:"SublocationDest";s:13:"The interwebs";s:14:"GIFFileComment";a:1:{i:0;s:16:"GIƒ·test·file";}s:15:"_MW_GIF_VERSION";i:1;}}' ), ); } + + private function dataFile( $name, $type ) { + return new UnregisteredLocalFile( false, $this->repo, + "mwstore://localtesting/data/$name", $type ); + } } Modified: branches/FileBackend/phase3/tests/phpunit/includes/media/PNGTest.php =================================================================== --- branches/FileBackend/phase3/tests/phpunit/includes/media/PNGTest.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/tests/phpunit/includes/media/PNGTest.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -2,12 +2,22 @@ class PNGHandlerTest extends MediaWikiTestCase { public function setUp() { - $this->filePath = dirname( __FILE__ ) . '/../../data/media/'; + $this->filePath = dirname( __FILE__ ) . '/../../data/media'; + $this->backend = new FSFileBackend( array( + 'name' => 'localtesting', + 'lockManager' => 'nullLockManager', + 'containerPaths' => array( 'data' => $this->filePath ) + ) ); + $this->repo = new FSRepo( array( + 'name' => 'temp', + 'url' => 'http://localhost/thumbtest', + 'backend' => $this->backend + ) ); $this->handler = new PNGHandler(); } public function testInvalidFile() { - $res = $this->handler->getMetadata( null, $this->filePath . 'README' ); + $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); $this->assertEquals( PNGHandler::BROKEN_FILE, $res ); } /** @@ -16,8 +26,7 @@ * @dataProvider dataIsAnimated */ public function testIsAnimanted( $filename, $expected ) { - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, - 'image/png' ); + $file = $this->dataFile( $filename, 'image/png' ); $actual = $this->handler->isAnimatedImage( $file ); $this->assertEquals( $expected, $actual ); } @@ -34,8 +43,7 @@ * @dataProvider dataGetImageArea */ public function testGetImageArea( $filename, $expected ) { - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, - 'image/png' ); + $file = $this->dataFile($filename, 'image/png' ); $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() ); $this->assertEquals( $expected, $actual ); } @@ -73,9 +81,8 @@ * @dataProvider dataGetMetadata */ public function testGetMetadata( $filename, $expected ) { - $file = UnregisteredLocalFile::newFromPath( $this->filePath . $filename, - 'image/png' ); - $actual = $this->handler->getMetadata( $file, $this->filePath . $filename ); + $file = $this->dataFile( $filename, 'image/png' ); + $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" ); // $this->assertEquals( unserialize( $expected ), unserialize( $actual ) ); $this->assertEquals( ( $expected ), ( $actual ) ); } @@ -85,4 +92,9 @@ array( 'xmp.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}' ), ); } + + private function dataFile( $name, $type ) { + return new UnregisteredLocalFile( false, $this->repo, + "mwstore://localtesting/data/$name", $type ); + } } Modified: branches/FileBackend/phase3/tests/phpunit/includes/parser/NewParserTest.php =================================================================== --- branches/FileBackend/phase3/tests/phpunit/includes/parser/NewParserTest.php 2011-12-10 17:45:55 UTC (rev 105766) +++ branches/FileBackend/phase3/tests/phpunit/includes/parser/NewParserTest.php 2011-12-10 18:22:14 UTC (rev 105767) @@ -119,6 +119,7 @@ } function addDBData() { + $this->tablesUsed[] = 'image'; # Hack: insert a few Wikipedia in-project interwiki prefixes, # for testing inter-language links $this->db->insert( 'interwiki', array( _______________________________________________ MediaWiki-CVS mailing list MediaWiki-CVS@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs