From: Aaron Date: Wed, 13 Jun 2012 00:23:53 +0000 (-0700) Subject: [FileBackend] Rewrote FileBackendStoreShardListIterator to actually work. X-Git-Tag: 1.31.0-rc.0~23193^2 X-Git-Url: http://git.cyclocoop.org/%22%20.%20generer_url_ecrire%28%22auteur_infos%22%2C%20%22id_auteur=%24id%22%29%20.%20%22?a=commitdiff_plain;h=0bcd30cc63f48360f2266c3a73805c0d3c0daad9;p=lhc%2Fweb%2Fwiklou.git [FileBackend] Rewrote FileBackendStoreShardListIterator to actually work. * Beefed up the relevant file backend unit tests. Change-Id: I62e741fada1197a7fa253a418829dd8f4728a9cd --- diff --git a/includes/filerepo/backend/FileBackendStore.php b/includes/filerepo/backend/FileBackendStore.php index 2080639e10..955a7e25ac 100644 --- a/includes/filerepo/backend/FileBackendStore.php +++ b/includes/filerepo/backend/FileBackendStore.php @@ -1574,23 +1574,34 @@ abstract class FileBackendStoreShardListIterator implements Iterator { } /** - * @see Iterator::current() - * @return string|bool String or false + * @see Iterator::key() + * @return integer */ - public function current() { - if ( is_array( $this->iter ) ) { - return current( $this->iter ); - } else { - return $this->iter->current(); + public function key() { + return $this->pos; + } + + /** + * @see Iterator::valid() + * @return bool + */ + public function valid() { + if ( $this->iter instanceof Iterator ) { + return $this->iter->valid(); + } elseif ( is_array( $this->iter ) ) { + return ( current( $this->iter ) !== false ); // no paths can have this value } + return false; // some failure? } /** - * @see Iterator::key() - * @return integer + * @see Iterator::current() + * @return string|bool String or false */ - public function key() { - return $this->pos; + public function current() { + return ( $this->iter instanceof Iterator ) + ? $this->iter->current() + : current( $this->iter ); } /** @@ -1599,15 +1610,16 @@ abstract class FileBackendStoreShardListIterator implements Iterator { */ public function next() { ++$this->pos; - if ( is_array( $this->iter ) ) { - next( $this->iter ); - } else { - $this->iter->next(); - } - // Filter out items that we already listed - $this->filterViaNext(); - // Find the next non-empty shard if no elements are left - $this->nextShardIteratorIfNotValid(); + ( $this->iter instanceof Iterator ) ? $this->iter->next() : next( $this->iter ); + do { + $continue = false; // keep scanning shards? + $this->filterViaNext(); // filter out duplicates + // Find the next non-empty shard if no elements are left + if ( !$this->valid() ) { + $this->nextShardIteratorIfNotValid(); + $continue = $this->valid(); // re-filter unless we ran out of shards + } + } while ( $continue ); } /** @@ -1618,41 +1630,32 @@ abstract class FileBackendStoreShardListIterator implements Iterator { $this->pos = 0; $this->curShard = 0; $this->setIteratorFromCurrentShard(); - // Filter out items that we already listed - $this->filterViaNext(); - // Find the next non-empty shard if this one has no elements - $this->nextShardIteratorIfNotValid(); - } - - /** - * @see Iterator::valid() - * @return bool - */ - public function valid() { - if ( $this->iter === null ) { - return false; // some failure? - } elseif ( is_array( $this->iter ) ) { - return ( current( $this->iter ) !== false ); // no paths can have this value - } else { - return $this->iter->valid(); - } + do { + $continue = false; // keep scanning shards? + $this->filterViaNext(); // filter out duplicates + // Find the next non-empty shard if no elements are left + if ( !$this->valid() ) { + $this->nextShardIteratorIfNotValid(); + $continue = $this->valid(); // re-filter unless we ran out of shards + } + } while ( $continue ); } /** * Filter out duplicate items by advancing to the next ones */ protected function filterViaNext() { - while ( $this->iter->valid() ) { + while ( $this->valid() ) { $rel = $this->iter->current(); // path relative to given directory $path = $this->params['dir'] . "/{$rel}"; // full storage path - if ( !$this->backend->isSingleShardPathInternal( $path ) ) { + if ( $this->backend->isSingleShardPathInternal( $path ) ) { + break; // path is only on one shard; no issue with duplicates + } elseif ( isset( $this->multiShardPaths[$rel] ) ) { // Don't keep listing paths that are on multiple shards - if ( isset( $this->multiShardPaths[$rel] ) ) { - $this->iter->next(); // we already listed this path - } else { - $this->multiShardPaths[$rel] = 1; - break; - } + ( $this->iter instanceof Iterator ) ? $this->iter->next() : next( $this->iter ); + } else { + $this->multiShardPaths[$rel] = 1; + break; } } } @@ -1663,10 +1666,7 @@ abstract class FileBackendStoreShardListIterator implements Iterator { * If there are none, then it advances to the last container. */ protected function nextShardIteratorIfNotValid() { - while ( !$this->valid() ) { - if ( ++$this->curShard >= count( $this->shardSuffixes ) ) { - break; // no more container shards - } + while ( !$this->valid() && ++$this->curShard < count( $this->shardSuffixes ) ) { $this->setIteratorFromCurrentShard(); } } @@ -1675,9 +1675,13 @@ abstract class FileBackendStoreShardListIterator implements Iterator { * Set the list iterator to that of the current container shard */ protected function setIteratorFromCurrentShard() { - $suffix = $this->shardSuffixes[$this->curShard]; $this->iter = $this->listFromShard( - "{$this->container}{$suffix}", $this->directory, $this->params ); + $this->container . $this->shardSuffixes[$this->curShard], + $this->directory, $this->params ); + // Start loading results so that current() works + if ( $this->iter ) { + ( $this->iter instanceof Iterator ) ? $this->iter->rewind() : reset( $this->iter ); + } } /** @@ -1696,9 +1700,7 @@ abstract class FileBackendStoreShardListIterator implements Iterator { */ class FileBackendStoreShardDirIterator extends FileBackendStoreShardListIterator { /** - * @param string $container - * @param string $dir - * @param array $params + * @see FileBackendStoreShardListIterator::listFromShard() * @return Array|null|Traversable */ protected function listFromShard( $container, $dir, array $params ) { @@ -1711,9 +1713,7 @@ class FileBackendStoreShardDirIterator extends FileBackendStoreShardListIterator */ class FileBackendStoreShardFileIterator extends FileBackendStoreShardListIterator { /** - * @param string $container - * @param string $dir - * @param array $params + * @see FileBackendStoreShardListIterator::listFromShard() * @return Array|null|Traversable */ protected function listFromShard( $container, $dir, array $params ) { diff --git a/tests/phpunit/includes/filerepo/FileBackendTest.php b/tests/phpunit/includes/filerepo/FileBackendTest.php index 710ad83e71..61507f5480 100644 --- a/tests/phpunit/includes/filerepo/FileBackendTest.php +++ b/tests/phpunit/includes/filerepo/FileBackendTest.php @@ -26,6 +26,9 @@ class FileBackendTest extends MediaWikiTestCase { } } $useConfig['name'] = 'localtesting'; // swap name + $useConfig['shardViaHashLevels'] = array( // test sharding + 'unittest-cont1' => array( 'levels' => 1, 'base' => 16, 'repeat' => 1 ) + ); $class = $useConfig['class']; self::$backendToUse = new $class( $useConfig ); $this->singleBackend = self::$backendToUse; @@ -246,7 +249,7 @@ class FileBackendTest extends MediaWikiTestCase { $cases = array(); $tmpName = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - $toPath = $this->baseStorePath() . '/unittest-cont1/fun/obj1.txt'; + $toPath = $this->baseStorePath() . '/unittest-cont1/e/fun/obj1.txt'; $op = array( 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath ); $cases[] = array( $op, // operation @@ -332,8 +335,8 @@ class FileBackendTest extends MediaWikiTestCase { public function provider_testCopy() { $cases = array(); - $source = $this->baseStorePath() . '/unittest-cont1/file.txt'; - $dest = $this->baseStorePath() . '/unittest-cont2/fileMoved.txt'; + $source = $this->baseStorePath() . '/unittest-cont1/e/file.txt'; + $dest = $this->baseStorePath() . '/unittest-cont2/a/fileMoved.txt'; $op = array( 'op' => 'copy', 'src' => $source, 'dst' => $dest ); $cases[] = array( @@ -421,8 +424,8 @@ class FileBackendTest extends MediaWikiTestCase { public function provider_testMove() { $cases = array(); - $source = $this->baseStorePath() . '/unittest-cont1/file.txt'; - $dest = $this->baseStorePath() . '/unittest-cont2/fileMoved.txt'; + $source = $this->baseStorePath() . '/unittest-cont1/e/file.txt'; + $dest = $this->baseStorePath() . '/unittest-cont2/a/fileMoved.txt'; $op = array( 'op' => 'move', 'src' => $source, 'dst' => $dest ); $cases[] = array( @@ -506,7 +509,7 @@ class FileBackendTest extends MediaWikiTestCase { public function provider_testDelete() { $cases = array(); - $source = $this->baseStorePath() . '/unittest-cont1/myfacefile.txt'; + $source = $this->baseStorePath() . '/unittest-cont1/e/myfacefile.txt'; $op = array( 'op' => 'delete', 'src' => $source ); $cases[] = array( @@ -600,7 +603,7 @@ class FileBackendTest extends MediaWikiTestCase { public function provider_testCreate() { $cases = array(); - $dest = $this->baseStorePath() . '/unittest-cont2/myspacefile.txt'; + $dest = $this->baseStorePath() . '/unittest-cont2/a/myspacefile.txt'; $op = array( 'op' => 'create', 'content' => 'test test testing', 'dst' => $dest ); $cases[] = array( @@ -666,9 +669,9 @@ class FileBackendTest extends MediaWikiTestCase { $base = $this->baseStorePath(); $files = array( - "$base/unittest-cont1/fileA.a", - "$base/unittest-cont1/fileB.a", - "$base/unittest-cont1/fileC.a" + "$base/unittest-cont1/e/fileA.a", + "$base/unittest-cont1/e/fileB.a", + "$base/unittest-cont1/e/fileC.a" ); $ops = array(); $purgeOps = array(); @@ -786,16 +789,16 @@ class FileBackendTest extends MediaWikiTestCase { $rand = mt_rand( 0, 2000000000 ) . time(); $dest = wfTempDir() . "/randomfile!$rand.txt"; $srcs = array( - $this->baseStorePath() . '/unittest-cont1/file1.txt', - $this->baseStorePath() . '/unittest-cont1/file2.txt', - $this->baseStorePath() . '/unittest-cont1/file3.txt', - $this->baseStorePath() . '/unittest-cont1/file4.txt', - $this->baseStorePath() . '/unittest-cont1/file5.txt', - $this->baseStorePath() . '/unittest-cont1/file6.txt', - $this->baseStorePath() . '/unittest-cont1/file7.txt', - $this->baseStorePath() . '/unittest-cont1/file8.txt', - $this->baseStorePath() . '/unittest-cont1/file9.txt', - $this->baseStorePath() . '/unittest-cont1/file10.txt' + $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' ); $content = array( 'egfage', @@ -884,9 +887,9 @@ class FileBackendTest extends MediaWikiTestCase { $cases = array(); $base = $this->baseStorePath(); - $cases[] = array( "$base/unittest-cont1/b/z/some_file.txt", "some file contents", true ); - $cases[] = array( "$base/unittest-cont1/b/some-other_file.txt", "", true ); - $cases[] = array( "$base/unittest-cont1/b/some-diff_file.txt", null, false ); + $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 ); return $cases; } @@ -930,8 +933,8 @@ class FileBackendTest extends MediaWikiTestCase { $cases = array(); $base = $this->baseStorePath(); - $cases[] = array( "$base/unittest-cont1/b/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/b/some-other_file.txt", "more file contents" ); + $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" ); return $cases; } @@ -973,8 +976,8 @@ class FileBackendTest extends MediaWikiTestCase { $cases = array(); $base = $this->baseStorePath(); - $cases[] = array( "$base/unittest-cont1/a/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/a/some-other_file.txt", "more file contents" ); + $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" ); return $cases; } @@ -1015,8 +1018,8 @@ class FileBackendTest extends MediaWikiTestCase { $cases = array(); $base = $this->baseStorePath(); - $cases[] = array( "$base/unittest-cont1/a/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/a/some-other_file.txt", "more file contents" ); + $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" ); return $cases; } @@ -1037,7 +1040,7 @@ class FileBackendTest extends MediaWikiTestCase { function provider_testPrepareAndClean() { $base = $this->baseStorePath(); return array( - array( "$base/unittest-cont1/a/z/some_file1.txt", true ), + array( "$base/unittest-cont1/e/a/z/some_file1.txt", true ), array( "$base/unittest-cont2/a/z/some_file2.txt", true ), # Specific to FS backend with no basePath field set #array( "$base/unittest-cont3/a/z/some_file3.txt", false ), @@ -1085,18 +1088,18 @@ class FileBackendTest extends MediaWikiTestCase { $base = $this->baseStorePath(); $dirs = array( - "$base/unittest-cont1/a", - "$base/unittest-cont1/a/b", - "$base/unittest-cont1/a/b/c", - "$base/unittest-cont1/a/b/c/d0", - "$base/unittest-cont1/a/b/c/d1", - "$base/unittest-cont1/a/b/c/d2", - "$base/unittest-cont1/a/b/c/d0/1", - "$base/unittest-cont1/a/b/c/d0/2", - "$base/unittest-cont1/a/b/c/d1/3", - "$base/unittest-cont1/a/b/c/d1/4", - "$base/unittest-cont1/a/b/c/d2/5", - "$base/unittest-cont1/a/b/c/d2/6" + "$base/unittest-cont1/e/a", + "$base/unittest-cont1/e/a/b", + "$base/unittest-cont1/e/a/b/c", + "$base/unittest-cont1/e/a/b/c/d0", + "$base/unittest-cont1/e/a/b/c/d1", + "$base/unittest-cont1/e/a/b/c/d2", + "$base/unittest-cont1/e/a/b/c/d0/1", + "$base/unittest-cont1/e/a/b/c/d0/2", + "$base/unittest-cont1/e/a/b/c/d1/3", + "$base/unittest-cont1/e/a/b/c/d1/4", + "$base/unittest-cont1/e/a/b/c/d2/5", + "$base/unittest-cont1/e/a/b/c/d2/6" ); foreach ( $dirs as $dir ) { $status = $this->prepare( array( 'dir' => $dir ) ); @@ -1159,13 +1162,13 @@ class FileBackendTest extends MediaWikiTestCase { private function doTestDoOperations() { $base = $this->baseStorePath(); - $fileA = "$base/unittest-cont1/a/b/fileA.txt"; + $fileA = "$base/unittest-cont1/e/a/b/fileA.txt"; $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq'; - $fileB = "$base/unittest-cont1/a/b/fileB.txt"; + $fileB = "$base/unittest-cont1/e/a/b/fileB.txt"; $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; - $fileC = "$base/unittest-cont1/a/b/fileC.txt"; + $fileC = "$base/unittest-cont1/e/a/b/fileC.txt"; $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - $fileD = "$base/unittest-cont1/a/b/fileD.txt"; + $fileD = "$base/unittest-cont1/e/a/b/fileD.txt"; $this->prepare( array( 'dir' => dirname( $fileA ) ) ); $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); @@ -1248,10 +1251,10 @@ class FileBackendTest extends MediaWikiTestCase { $this->filesToPrune[] = $tmpNameB; # avoid file leaking $this->filesToPrune[] = $tmpNameC; # avoid file leaking - $fileA = "$base/unittest-cont1/a/b/fileA.txt"; - $fileB = "$base/unittest-cont1/a/b/fileB.txt"; - $fileC = "$base/unittest-cont1/a/b/fileC.txt"; - $fileD = "$base/unittest-cont1/a/b/fileD.txt"; + $fileA = "$base/unittest-cont1/e/a/b/fileA.txt"; + $fileB = "$base/unittest-cont1/e/a/b/fileB.txt"; + $fileC = "$base/unittest-cont1/e/a/b/fileC.txt"; + $fileD = "$base/unittest-cont1/e/a/b/fileD.txt"; $this->prepare( array( 'dir' => dirname( $fileA ) ) ); $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); @@ -1398,20 +1401,20 @@ class FileBackendTest extends MediaWikiTestCase { $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont-notexists" ) ); $files = array( - "$base/unittest-cont1/test1.txt", - "$base/unittest-cont1/test2.txt", - "$base/unittest-cont1/test3.txt", - "$base/unittest-cont1/subdir1/test1.txt", - "$base/unittest-cont1/subdir1/test2.txt", - "$base/unittest-cont1/subdir2/test3.txt", - "$base/unittest-cont1/subdir2/test4.txt", - "$base/unittest-cont1/subdir2/subdir/test1.txt", - "$base/unittest-cont1/subdir2/subdir/test2.txt", - "$base/unittest-cont1/subdir2/subdir/test3.txt", - "$base/unittest-cont1/subdir2/subdir/test4.txt", - "$base/unittest-cont1/subdir2/subdir/test5.txt", - "$base/unittest-cont1/subdir2/subdir/sub/test0.txt", - "$base/unittest-cont1/subdir2/subdir/sub/120-px-file.txt", + "$base/unittest-cont1/e/test1.txt", + "$base/unittest-cont1/e/test2.txt", + "$base/unittest-cont1/e/test3.txt", + "$base/unittest-cont1/e/subdir1/test1.txt", + "$base/unittest-cont1/e/subdir1/test2.txt", + "$base/unittest-cont1/e/subdir2/test3.txt", + "$base/unittest-cont1/e/subdir2/test4.txt", + "$base/unittest-cont1/e/subdir2/subdir/test1.txt", + "$base/unittest-cont1/e/subdir2/subdir/test2.txt", + "$base/unittest-cont1/e/subdir2/subdir/test3.txt", + "$base/unittest-cont1/e/subdir2/subdir/test4.txt", + "$base/unittest-cont1/e/subdir2/subdir/test5.txt", + "$base/unittest-cont1/e/subdir2/subdir/sub/test0.txt", + "$base/unittest-cont1/e/subdir2/subdir/sub/120-px-file.txt", ); // Add the files @@ -1428,20 +1431,20 @@ class FileBackendTest extends MediaWikiTestCase { // Expected listing $expected = array( - "test1.txt", - "test2.txt", - "test3.txt", - "subdir1/test1.txt", - "subdir1/test2.txt", - "subdir2/test3.txt", - "subdir2/test4.txt", - "subdir2/subdir/test1.txt", - "subdir2/subdir/test2.txt", - "subdir2/subdir/test3.txt", - "subdir2/subdir/test4.txt", - "subdir2/subdir/test5.txt", - "subdir2/subdir/sub/test0.txt", - "subdir2/subdir/sub/120-px-file.txt", + "e/test1.txt", + "e/test2.txt", + "e/test3.txt", + "e/subdir1/test1.txt", + "e/subdir1/test2.txt", + "e/subdir2/test3.txt", + "e/subdir2/test4.txt", + "e/subdir2/subdir/test1.txt", + "e/subdir2/subdir/test2.txt", + "e/subdir2/subdir/test3.txt", + "e/subdir2/subdir/test4.txt", + "e/subdir2/subdir/test5.txt", + "e/subdir2/subdir/sub/test0.txt", + "e/subdir2/subdir/sub/120-px-file.txt", ); sort( $expected ); @@ -1479,7 +1482,7 @@ class FileBackendTest extends MediaWikiTestCase { // Actual listing (no trailing slash) $list = array(); - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/subdir2/subdir" ) ); + $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); foreach ( $iter as $file ) { $list[] = $file; } @@ -1489,7 +1492,7 @@ class FileBackendTest extends MediaWikiTestCase { // Actual listing (with trailing slash) $list = array(); - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/subdir2/subdir/" ) ); + $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir/" ) ); foreach ( $iter as $file ) { $list[] = $file; } @@ -1518,7 +1521,7 @@ class FileBackendTest extends MediaWikiTestCase { // Actual listing (top files only) $list = array(); - $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1/subdir2/subdir" ) ); + $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); foreach ( $iter as $file ) { $list[] = $file; } @@ -1551,20 +1554,20 @@ class FileBackendTest extends MediaWikiTestCase { $base = $this->baseStorePath(); $files = array( - "$base/unittest-cont1/test1.txt", - "$base/unittest-cont1/test2.txt", - "$base/unittest-cont1/test3.txt", - "$base/unittest-cont1/subdir1/test1.txt", - "$base/unittest-cont1/subdir1/test2.txt", - "$base/unittest-cont1/subdir2/test3.txt", - "$base/unittest-cont1/subdir2/test4.txt", - "$base/unittest-cont1/subdir2/subdir/test1.txt", - "$base/unittest-cont1/subdir3/subdir/test2.txt", - "$base/unittest-cont1/subdir4/subdir/test3.txt", - "$base/unittest-cont1/subdir4/subdir/test4.txt", - "$base/unittest-cont1/subdir4/subdir/test5.txt", - "$base/unittest-cont1/subdir4/subdir/sub/test0.txt", - "$base/unittest-cont1/subdir4/subdir/sub/120-px-file.txt", + "$base/unittest-cont1/e/test1.txt", + "$base/unittest-cont1/e/test2.txt", + "$base/unittest-cont1/e/test3.txt", + "$base/unittest-cont1/e/subdir1/test1.txt", + "$base/unittest-cont1/e/subdir1/test2.txt", + "$base/unittest-cont1/e/subdir2/test3.txt", + "$base/unittest-cont1/e/subdir2/test4.txt", + "$base/unittest-cont1/e/subdir2/subdir/test1.txt", + "$base/unittest-cont1/e/subdir3/subdir/test2.txt", + "$base/unittest-cont1/e/subdir4/subdir/test3.txt", + "$base/unittest-cont1/e/subdir4/subdir/test4.txt", + "$base/unittest-cont1/e/subdir4/subdir/test5.txt", + "$base/unittest-cont1/e/subdir4/subdir/sub/test0.txt", + "$base/unittest-cont1/e/subdir4/subdir/sub/120-px-file.txt", ); // Add the files @@ -1579,6 +1582,32 @@ class FileBackendTest extends MediaWikiTestCase { $this->assertEquals( true, $status->isOK(), "Creation of files succeeded with OK status ($backendName)." ); + $this->assertEquals( true, + $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir1" ) ), + "Directory exists in ($backendName)." ); + $this->assertEquals( true, + $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ), + "Directory exists in ($backendName)." ); + $this->assertEquals( false, + $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir2/test1.txt" ) ), + "Directory does not exists in ($backendName)." ); + + // Expected listing + $expected = array( + "e", + ); + sort( $expected ); + + // Actual listing (no trailing slash) + $list = array(); + $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1" ) ); + foreach ( $iter as $file ) { + $list[] = $file; + } + sort( $list ); + + $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); + // Expected listing $expected = array( "subdir1", @@ -1588,19 +1617,9 @@ class FileBackendTest extends MediaWikiTestCase { ); sort( $expected ); - $this->assertEquals( true, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/subdir1" ) ), - "Directory exists in ($backendName)." ); - $this->assertEquals( true, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/subdir2/subdir" ) ), - "Directory exists in ($backendName)." ); - $this->assertEquals( false, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/subdir2/test1.txt" ) ), - "Directory does not exists in ($backendName)." ); - // Actual listing (no trailing slash) $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1" ) ); + $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e" ) ); foreach ( $iter as $file ) { $list[] = $file; } @@ -1610,7 +1629,7 @@ class FileBackendTest extends MediaWikiTestCase { // Actual listing (with trailing slash) $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/" ) ); + $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/" ) ); foreach ( $iter as $file ) { $list[] = $file; } @@ -1626,7 +1645,7 @@ class FileBackendTest extends MediaWikiTestCase { // Actual listing (no trailing slash) $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/subdir2" ) ); + $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir2" ) ); foreach ( $iter as $file ) { $list[] = $file; } @@ -1636,7 +1655,7 @@ class FileBackendTest extends MediaWikiTestCase { // Actual listing (with trailing slash) $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/subdir2/" ) ); + $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir2/" ) ); foreach ( $iter as $file ) { $list[] = $file; } @@ -1655,14 +1674,15 @@ class FileBackendTest extends MediaWikiTestCase { // Expected listing (recursive) $expected = array( - "subdir1", - "subdir2", - "subdir3", - "subdir4", - "subdir2/subdir", - "subdir3/subdir", - "subdir4/subdir", - "subdir4/subdir/sub", + "e", + "e/subdir1", + "e/subdir2", + "e/subdir3", + "e/subdir4", + "e/subdir2/subdir", + "e/subdir3/subdir", + "e/subdir4/subdir", + "e/subdir4/subdir/sub", ); sort( $expected ); @@ -1685,7 +1705,7 @@ class FileBackendTest extends MediaWikiTestCase { // Actual listing (recursive) $list = array(); - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/subdir4" ) ); + $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir4" ) ); foreach ( $iter as $file ) { $list[] = $file; }