/**
* @group FileRepo
* @group FileBackend
+ * @group medium
*/
class FileBackendTest extends MediaWikiTestCase {
private $backend, $multiBackend;
private $filesToPrune = array();
private static $backendToUse;
- function setUp() {
+ protected function setUp() {
global $wgFileBackends;
parent::setUp();
$tmpPrefix = wfTempDir() . '/filebackend-unittest-' . time() . '-' . mt_rand();
'parallelize' => 'implicit',
'backends' => array(
array(
- 'name' => 'localmutlitesting1',
+ 'name' => 'localmultitesting1',
'class' => 'FSFileBackend',
'lockManager' => 'nullLockManager',
'containerPaths' => array(
'isMultiMaster' => false
),
array(
- 'name' => 'localmutlitesting2',
+ 'name' => 'localmultitesting2',
'class' => 'FSFileBackend',
'lockManager' => 'nullLockManager',
'containerPaths' => array(
$this->filesToPrune = array();
}
- private function baseStorePath() {
+ private static function baseStorePath() {
return 'mwstore://localtesting';
}
"FileBackend::extensionFromPath on path '$path'" );
}
- function provider_testExtensionFromPath() {
+ public static function provider_testExtensionFromPath() {
return array(
array( 'mwstore://backend/container/path.txt', 'txt' ),
array( 'mwstore://backend/container/path.svg.png', 'png' ),
$this->assertBackendPathsConsistent( array( $dest ) );
}
- public function provider_testStore() {
+ public static function provider_testStore() {
$cases = array();
$tmpName = TempFSFile::factory( "unittests_", 'txt' )->getPath();
- $toPath = $this->baseStorePath() . '/unittest-cont1/e/fun/obj1.txt';
+ $toPath = self::baseStorePath() . '/unittest-cont1/e/fun/obj1.txt';
$op = array( 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath );
$cases[] = array(
$op, // operation
$this->assertBackendPathsConsistent( array( $source, $dest ) );
}
- public function provider_testCopy() {
+ public static function provider_testCopy() {
$cases = array();
- $source = $this->baseStorePath() . '/unittest-cont1/e/file.txt';
- $dest = $this->baseStorePath() . '/unittest-cont2/a/fileMoved.txt';
+ $source = self::baseStorePath() . '/unittest-cont1/e/file.txt';
+ $dest = self::baseStorePath() . '/unittest-cont2/a/fileMoved.txt';
$op = array( 'op' => 'copy', 'src' => $source, 'dst' => $dest );
$cases[] = array(
$this->assertBackendPathsConsistent( array( $source, $dest ) );
}
- public function provider_testMove() {
+ public static function provider_testMove() {
$cases = array();
- $source = $this->baseStorePath() . '/unittest-cont1/e/file.txt';
- $dest = $this->baseStorePath() . '/unittest-cont2/a/fileMoved.txt';
+ $source = self::baseStorePath() . '/unittest-cont1/e/file.txt';
+ $dest = self::baseStorePath() . '/unittest-cont2/a/fileMoved.txt';
$op = array( 'op' => 'move', 'src' => $source, 'dst' => $dest );
$cases[] = array(
$this->assertBackendPathsConsistent( array( $source ) );
}
- public function provider_testDelete() {
+ public static function provider_testDelete() {
$cases = array();
- $source = $this->baseStorePath() . '/unittest-cont1/e/myfacefile.txt';
+ $source = self::baseStorePath() . '/unittest-cont1/e/myfacefile.txt';
$op = array( 'op' => 'delete', 'src' => $source );
$cases[] = array(
/**
* @dataProvider provider_testCreate
*/
- public function provider_testCreate() {
+ public static function provider_testCreate() {
$cases = array();
- $dest = $this->baseStorePath() . '/unittest-cont2/a/myspacefile.txt';
+ $dest = self::baseStorePath() . '/unittest-cont2/a/myspacefile.txt';
$op = array( 'op' => 'create', 'content' => 'test test testing', 'dst' => $dest );
$cases[] = array(
private function doTestDoQuickOperations() {
$backendName = $this->backendClass();
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
$files = array(
"$base/unittest-cont1/e/fileA.a",
"$base/unittest-cont1/e/fileB.a",
$rand = mt_rand( 0, 2000000000 ) . time();
$dest = wfTempDir() . "/randomfile!$rand.txt";
$srcs = array(
- $this->baseStorePath() . '/unittest-cont1/e/file1.txt',
- $this->baseStorePath() . '/unittest-cont1/e/file2.txt',
- $this->baseStorePath() . '/unittest-cont1/e/file3.txt',
- $this->baseStorePath() . '/unittest-cont1/e/file4.txt',
- $this->baseStorePath() . '/unittest-cont1/e/file5.txt',
- $this->baseStorePath() . '/unittest-cont1/e/file6.txt',
- $this->baseStorePath() . '/unittest-cont1/e/file7.txt',
- $this->baseStorePath() . '/unittest-cont1/e/file8.txt',
- $this->baseStorePath() . '/unittest-cont1/e/file9.txt',
- $this->baseStorePath() . '/unittest-cont1/e/file10.txt'
+ self::baseStorePath() . '/unittest-cont1/e/file1.txt',
+ self::baseStorePath() . '/unittest-cont1/e/file2.txt',
+ self::baseStorePath() . '/unittest-cont1/e/file3.txt',
+ self::baseStorePath() . '/unittest-cont1/e/file4.txt',
+ self::baseStorePath() . '/unittest-cont1/e/file5.txt',
+ self::baseStorePath() . '/unittest-cont1/e/file6.txt',
+ self::baseStorePath() . '/unittest-cont1/e/file7.txt',
+ self::baseStorePath() . '/unittest-cont1/e/file8.txt',
+ self::baseStorePath() . '/unittest-cont1/e/file9.txt',
+ self::baseStorePath() . '/unittest-cont1/e/file10.txt'
);
$content = array(
'egfage',
"Correct file size of '$path'" );
$this->assertTrue( abs( time() - wfTimestamp( TS_UNIX, $time ) ) < 10,
"Correct file timestamp of '$path'" );
+
+ $this->backend->clearCache( array( $path ) );
+
+ $size = $this->backend->getFileSize( array( 'src' => $path ) );
+
+ $this->assertEquals( strlen( $content ), $size,
+ "Correct file size of '$path'" );
+
+ $this->backend->preloadCache( array( $path ) );
+
+ $size = $this->backend->getFileSize( array( 'src' => $path ) );
+
+ $this->assertEquals( strlen( $content ), $size,
+ "Correct file size of '$path'" );
} else {
$size = $this->backend->getFileSize( array( 'src' => $path ) );
$time = $this->backend->getFileTimestamp( array( 'src' => $path ) );
function provider_testGetFileStat() {
$cases = array();
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
$cases[] = array( "$base/unittest-cont1/e/b/z/some_file.txt", "some file contents", true );
$cases[] = array( "$base/unittest-cont1/e/b/some-other_file.txt", "", true );
$cases[] = array( "$base/unittest-cont1/e/b/some-diff_file.txt", null, false );
private function doTestGetFileContents( $source, $content ) {
$backendName = $this->backendClass();
- $this->prepare( array( 'dir' => dirname( $source ) ) );
-
- $status = $this->backend->doOperation(
- array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
- $this->assertGoodStatus( $status,
- "Creation of file at $source succeeded ($backendName)." );
- $this->assertEquals( true, $status->isOK(),
- "Creation of file at $source succeeded with OK status ($backendName)." );
-
- $newContents = $this->backend->getFileContents( array( 'src' => $source, 'latest' => 1 ) );
- $this->assertNotEquals( false, $newContents,
- "Read of file at $source succeeded ($backendName)." );
+ $srcs = (array)$source;
+ $content = (array)$content;
+ foreach ( $srcs as $i => $src ) {
+ $this->prepare( array( 'dir' => dirname( $src ) ) );
+ $status = $this->backend->doOperation(
+ array( 'op' => 'create', 'content' => $content[$i], 'dst' => $src ) );
+ $this->assertGoodStatus( $status,
+ "Creation of file at $src succeeded ($backendName)." );
+ }
- $this->assertEquals( $content, $newContents,
- "Contents read match data at $source ($backendName)." );
+ if ( is_array( $source ) ) {
+ $contents = $this->backend->getFileContentsMulti( array( 'srcs' => $source ) );
+ foreach ( $contents as $path => $data ) {
+ $this->assertNotEquals( false, $data, "Contents of $path exists ($backendName)." );
+ $this->assertEquals( current( $content ), $data, "Contents of $path is correct ($backendName)." );
+ next( $content );
+ }
+ $this->assertEquals( $source, array_keys( $contents ), "Contents in right order ($backendName)." );
+ $this->assertEquals( count( $source ), count( $contents ), "Contents array size correct ($backendName)." );
+ } else {
+ $data = $this->backend->getFileContents( array( 'src' => $source ) );
+ $this->assertNotEquals( false, $data, "Contents of $source exists ($backendName)." );
+ $this->assertEquals( $content[0], $data, "Contents of $source is correct ($backendName)." );
+ }
}
function provider_testGetFileContents() {
$cases = array();
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
$cases[] = array( "$base/unittest-cont1/e/b/z/some_file.txt", "some file contents" );
$cases[] = array( "$base/unittest-cont1/e/b/some-other_file.txt", "more file contents" );
+ $cases[] = array(
+ array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt",
+ "$base/unittest-cont1/e/a/z.txt" ),
+ array( "contents xx", "contents xy", "contents xz" )
+ );
return $cases;
}
private function doTestGetLocalCopy( $source, $content ) {
$backendName = $this->backendClass();
- $this->prepare( array( 'dir' => dirname( $source ) ) );
-
- $status = $this->backend->doOperation(
- array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
- $this->assertGoodStatus( $status,
- "Creation of file at $source succeeded ($backendName)." );
+ $srcs = (array)$source;
+ $content = (array)$content;
+ foreach ( $srcs as $i => $src ) {
+ $this->prepare( array( 'dir' => dirname( $src ) ) );
+ $status = $this->backend->doOperation(
+ array( 'op' => 'create', 'content' => $content[$i], 'dst' => $src ) );
+ $this->assertGoodStatus( $status,
+ "Creation of file at $src succeeded ($backendName)." );
+ }
- $tmpFile = $this->backend->getLocalCopy( array( 'src' => $source ) );
- $this->assertNotNull( $tmpFile,
- "Creation of local copy of $source succeeded ($backendName)." );
+ if ( is_array( $source ) ) {
+ $tmpFiles = $this->backend->getLocalCopyMulti( array( 'srcs' => $source ) );
+ foreach ( $tmpFiles as $path => $tmpFile ) {
+ $this->assertNotNull( $tmpFile,
+ "Creation of local copy of $path succeeded ($backendName)." );
+ $contents = file_get_contents( $tmpFile->getPath() );
+ $this->assertNotEquals( false, $contents, "Local copy of $path exists ($backendName)." );
+ $this->assertEquals( current( $content ), $contents, "Local copy of $path is correct ($backendName)." );
+ next( $content );
+ }
+ $this->assertEquals( $source, array_keys( $tmpFiles ), "Local copies in right order ($backendName)." );
+ $this->assertEquals( count( $source ), count( $tmpFiles ), "Local copies array size correct ($backendName)." );
+ } else {
+ $tmpFile = $this->backend->getLocalCopy( array( 'src' => $source ) );
+ $this->assertNotNull( $tmpFile,
+ "Creation of local copy of $source succeeded ($backendName)." );
+ $contents = file_get_contents( $tmpFile->getPath() );
+ $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." );
+ $this->assertEquals( $content[0], $contents, "Local copy of $source is correct ($backendName)." );
+ }
- $contents = file_get_contents( $tmpFile->getPath() );
- $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." );
+ $obj = new stdClass();
+ $tmpFile->bind( $obj );
}
function provider_testGetLocalCopy() {
$cases = array();
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
$cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" );
$cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" );
+ $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" );
+ $cases[] = array(
+ array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt",
+ "$base/unittest-cont1/e/a/z.txt" ),
+ array( "contents xx", "contents xy", "contents xz" )
+ );
return $cases;
}
private function doTestGetLocalReference( $source, $content ) {
$backendName = $this->backendClass();
- $this->prepare( array( 'dir' => dirname( $source ) ) );
-
- $status = $this->create( array( 'content' => $content, 'dst' => $source ) );
- $this->assertGoodStatus( $status,
- "Creation of file at $source succeeded ($backendName)." );
-
- $tmpFile = $this->backend->getLocalReference( array( 'src' => $source ) );
- $this->assertNotNull( $tmpFile,
- "Creation of local copy of $source succeeded ($backendName)." );
+ $srcs = (array)$source;
+ $content = (array)$content;
+ foreach ( $srcs as $i => $src ) {
+ $this->prepare( array( 'dir' => dirname( $src ) ) );
+ $status = $this->backend->doOperation(
+ array( 'op' => 'create', 'content' => $content[$i], 'dst' => $src ) );
+ $this->assertGoodStatus( $status,
+ "Creation of file at $src succeeded ($backendName)." );
+ }
- $contents = file_get_contents( $tmpFile->getPath() );
- $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." );
+ if ( is_array( $source ) ) {
+ $tmpFiles = $this->backend->getLocalReferenceMulti( array( 'srcs' => $source ) );
+ foreach ( $tmpFiles as $path => $tmpFile ) {
+ $this->assertNotNull( $tmpFile,
+ "Creation of local copy of $path succeeded ($backendName)." );
+ $contents = file_get_contents( $tmpFile->getPath() );
+ $this->assertNotEquals( false, $contents, "Local ref of $path exists ($backendName)." );
+ $this->assertEquals( current( $content ), $contents, "Local ref of $path is correct ($backendName)." );
+ next( $content );
+ }
+ $this->assertEquals( $source, array_keys( $tmpFiles ), "Local refs in right order ($backendName)." );
+ $this->assertEquals( count( $source ), count( $tmpFiles ), "Local refs array size correct ($backendName)." );
+ } else {
+ $tmpFile = $this->backend->getLocalReference( array( 'src' => $source ) );
+ $this->assertNotNull( $tmpFile,
+ "Creation of local copy of $source succeeded ($backendName)." );
+ $contents = file_get_contents( $tmpFile->getPath() );
+ $this->assertNotEquals( false, $contents, "Local ref of $source exists ($backendName)." );
+ $this->assertEquals( $content[0], $contents, "Local ref of $source is correct ($backendName)." );
+ }
}
function provider_testGetLocalReference() {
$cases = array();
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
$cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" );
$cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" );
+ $cases[] = array( "$base/unittest-cont1/e/a/\$odd&.txt", "test file contents" );
+ $cases[] = array(
+ array( "$base/unittest-cont1/e/a/x.txt", "$base/unittest-cont1/e/a/y.txt",
+ "$base/unittest-cont1/e/a/z.txt" ),
+ array( "contents xx", "contents xy", "contents xz" )
+ );
return $cases;
}
}
function provider_testPrepareAndClean() {
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
return array(
array( "$base/unittest-cont1/e/a/z/some_file1.txt", true ),
array( "$base/unittest-cont2/a/z/some_file2.txt", true ),
private function doTestRecursiveClean() {
$backendName = $this->backendClass();
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
$dirs = array(
"$base/unittest-cont1/e/a",
"$base/unittest-cont1/e/a/b",
$this->tearDownFiles();
$this->doTestDoOperations();
$this->tearDownFiles();
-
- $this->backend = $this->singleBackend;
- $this->tearDownFiles();
- $this->doTestDoOperations2();
- $this->tearDownFiles();
-
- $this->backend = $this->multiBackend;
- $this->tearDownFiles();
- $this->doTestDoOperations2();
- $this->tearDownFiles();
-
- $this->backend = $this->singleBackend;
- $this->tearDownFiles();
- $this->doTestDoOperationsFailing();
- $this->tearDownFiles();
-
- $this->backend = $this->multiBackend;
- $this->tearDownFiles();
- $this->doTestDoOperationsFailing();
- $this->tearDownFiles();
}
private function doTestDoOperations() {
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
$fileA = "$base/unittest-cont1/e/a/b/fileA.txt";
$fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq';
"Correct file SHA-1 of $fileC" );
}
+ public function testDoOperationsPipeline() {
+ $this->backend = $this->singleBackend;
+ $this->tearDownFiles();
+ $this->doTestDoOperationsPipeline();
+ $this->tearDownFiles();
+
+ $this->backend = $this->multiBackend;
+ $this->tearDownFiles();
+ $this->doTestDoOperationsPipeline();
+ $this->tearDownFiles();
+ }
+
// concurrency orientated
- private function doTestDoOperations2() {
- $base = $this->baseStorePath();
+ private function doTestDoOperationsPipeline() {
+ $base = self::baseStorePath();
$fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq';
$fileBContents = 'g-jmq3gpqgt3qtg q3GT ';
"Correct file SHA-1 of $fileC" );
}
+ public function testDoOperationsFailing() {
+ $this->backend = $this->singleBackend;
+ $this->tearDownFiles();
+ $this->doTestDoOperationsFailing();
+ $this->tearDownFiles();
+
+ $this->backend = $this->multiBackend;
+ $this->tearDownFiles();
+ $this->doTestDoOperationsFailing();
+ $this->tearDownFiles();
+ }
+
private function doTestDoOperationsFailing() {
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
$fileA = "$base/unittest-cont2/a/b/fileA.txt";
$fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq';
private function doTestGetFileList() {
$backendName = $this->backendClass();
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
// Should have no errors
$iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont-notexists" ) );
private function doTestGetDirectoryList() {
$backendName = $this->backendClass();
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
$files = array(
"$base/unittest-cont1/e/test1.txt",
"$base/unittest-cont1/e/test2.txt",
foreach ( $this->filesToPrune as $file ) {
@unlink( $file );
}
- $containers = array( 'unittest-cont1', 'unittest-cont2', 'unittest-cont3' );
+ $containers = array( 'unittest-cont1', 'unittest-cont2' );
foreach ( $containers as $container ) {
$this->deleteFiles( $container );
}
}
private function deleteFiles( $container ) {
- $base = $this->baseStorePath();
+ $base = self::baseStorePath();
$iter = $this->backend->getFileList( array( 'dir' => "$base/$container" ) );
if ( $iter ) {
foreach ( $iter as $file ) {
- $this->backend->delete( array( 'src' => "$base/$container/$file" ),
- array( 'force' => 1, 'nonLocking' => 1 ) );
+ $this->backend->quickDelete( array( 'src' => "$base/$container/$file" ) );
}
}
$this->backend->clean( array( 'dir' => "$base/$container", 'recursive' => 1 ) );
function assertGoodStatus( $status, $msg ) {
$this->assertEquals( print_r( array(), 1 ), print_r( $status->errors, 1 ), $msg );
}
-
- function tearDown() {
- parent::tearDown();
- }
}