private function doTestGetLocalReference($source, $content) { $backendName = $this->backendClass(); $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})."); } 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})."); } }
/** * @param array $srcPathsRel * @param string $backendRel * @param FileBackend $src * @param FileBackend $dst * @return void */ protected function copyFileBatch( array $srcPathsRel, $backendRel, FileBackend $src, FileBackend $dst ) { $ops = array(); $fsFiles = array(); $copiedRel = array(); // for output message $wikiId = $src->getWikiId(); // Download the batch of source files into backend cache... if ( $this->hasOption( 'missingonly' ) ) { $srcPaths = array(); foreach ( $srcPathsRel as $srcPathRel ) { $srcPaths[] = $src->getRootStoragePath() . "/$backendRel/$srcPathRel"; } $t_start = microtime( true ); $fsFiles = $src->getLocalReferenceMulti( array( 'srcs' => $srcPaths, 'latest' => 1 ) ); $ellapsed_ms = floor( ( microtime( true ) - $t_start ) * 1000 ); $this->output( "\n\tDownloaded these file(s) [{$ellapsed_ms}ms]:\n\t" . implode( "\n\t", $srcPaths ) . "\n\n" ); } // Determine what files need to be copied over... foreach ( $srcPathsRel as $srcPathRel ) { $srcPath = $src->getRootStoragePath() . "/$backendRel/$srcPathRel"; $dstPath = $dst->getRootStoragePath() . "/$backendRel/$srcPathRel"; if ( $this->hasOption( 'utf8only' ) && !mb_check_encoding( $srcPath, 'UTF-8' ) ) { $this->error( "$wikiId: Detected illegal (non-UTF8) path for $srcPath." ); continue; } elseif ( !$this->hasOption( 'missingonly' ) && $this->filesAreSame( $src, $dst, $srcPath, $dstPath ) ) { $this->output( "\tAlready have $srcPathRel.\n" ); continue; // assume already copied... } $fsFile = array_key_exists( $srcPath, $fsFiles ) ? $fsFiles[$srcPath] : $src->getLocalReference( array( 'src' => $srcPath, 'latest' => 1 ) ); if ( !$fsFile ) { $src->clearCache( array( $srcPath ) ); if ( $src->fileExists( array( 'src' => $srcPath, 'latest' => 1 ) ) === false ) { $this->error( "$wikiId: File '$srcPath' was listed but does not exist." ); } else { $this->error( "$wikiId: Could not get local copy of $srcPath." ); } continue; } elseif ( !$fsFile->exists() ) { // FSFileBackends just return the path for getLocalReference() and paths with // illegal slashes may get normalized to a different path. This can cause the // local reference to not exist...skip these broken files. $this->error( "$wikiId: Detected possible illegal path for $srcPath." ); continue; } $fsFiles[] = $fsFile; // keep TempFSFile objects alive as needed // Note: prepare() is usually fast for key/value backends $status = $dst->prepare( array( 'dir' => dirname( $dstPath ), 'bypassReadOnly' => 1 ) ); if ( !$status->isOK() ) { $this->error( print_r( $status->getErrorsArray(), true ) ); $this->error( "$wikiId: Could not copy $srcPath to $dstPath.", 1 ); // die } $ops[] = array( 'op' => 'store', 'src' => $fsFile->getPath(), 'dst' => $dstPath, 'overwrite' => 1 ); $copiedRel[] = $srcPathRel; } // Copy in the batch of source files... $t_start = microtime( true ); $status = $dst->doQuickOperations( $ops, array( 'bypassReadOnly' => 1 ) ); if ( !$status->isOK() ) { sleep( 10 ); // wait and retry copy again $status = $dst->doQuickOperations( $ops, array( 'bypassReadOnly' => 1 ) ); } $ellapsed_ms = floor( ( microtime( true ) - $t_start ) * 1000 ); if ( !$status->isOK() ) { $this->error( print_r( $status->getErrorsArray(), true ) ); $this->error( "$wikiId: Could not copy file batch.", 1 ); // die } elseif ( count( $copiedRel ) ) { $this->output( "\n\tCopied these file(s) [{$ellapsed_ms}ms]:\n\t" . implode( "\n\t", $copiedRel ) . "\n\n" ); } }