6 class FileBackendTest
extends MediaWikiTestCase
{
7 private $backend, $multiBackend;
8 private $filesToPrune, $pathsToPrune;
12 $tmpDir = wfTempDir() . '/file-backend-test-' . time() . '-' . mt_rand();
13 $this->singleBackend
= new FSFileBackend( array(
14 'name' => 'localtesting',
15 'lockManager' => 'fsLockManager',
16 'containerPaths' => array(
17 'cont1' => "$tmpDir/localtesting/cont1",
18 'cont2' => "$tmpDir/localtesting/cont2" )
20 $this->multiBackend
= new FileBackendMultiWrite( array(
21 'name' => 'localtesting',
22 'lockManager' => 'fsLockManager',
25 'name' => 'localmutlitesting1',
26 'class' => 'FSFileBackend',
27 'lockManager' => 'nullLockManager',
28 'containerPaths' => array(
29 'cont1' => "$tmpDir/localtestingmulti1/cont1",
30 'cont2' => "$tmpDir/localtestingmulti1/cont2" ),
31 'isMultiMaster' => false
34 'name' => 'localmutlitesting2',
35 'class' => 'FSFileBackend',
36 'lockManager' => 'nullLockManager',
37 'containerPaths' => array(
38 'cont1' => "$tmpDir/localtestingmulti2/cont1",
39 'cont2' => "$tmpDir/localtestingmulti2/cont2" ),
40 'isMultiMaster' => true
44 $this->filesToPrune
= $this->pathsToPrune
= array();
47 private function baseStorePath() {
48 return 'mwstore://localtesting';
51 private function backendClass() {
52 return get_class( $this->backend
);
56 * @dataProvider provider_testStore
58 public function testStore( $op, $source, $dest ) {
59 $this->filesToPrune
[] = $source;
60 $this->pathsToPrune
[] = $dest;
62 $this->backend
= $this->singleBackend
;
63 $this->doTestStore( $op, $source, $dest );
64 $this->tearDownFiles();
66 $this->backend
= $this->multiBackend
;
67 $this->doTestStore( $op, $source, $dest );
68 $this->tearDownFiles();
71 function doTestStore( $op, $source, $dest ) {
72 $backendName = $this->backendClass();
74 $this->backend
->prepare( array( 'dir' => dirname( $dest ) ) );
76 file_put_contents( $source, "Unit test file" );
77 $status = $this->backend
->doOperation( $op );
79 $this->assertEquals( array(), $status->errors
,
80 "Store from $source to $dest succeeded without warnings ($backendName)." );
81 $this->assertEquals( true, $status->isOK(),
82 "Store from $source to $dest succeeded ($backendName)." );
83 $this->assertEquals( array( 0 => true ), $status->success
,
84 "Store from $source to $dest has proper 'success' field in Status ($backendName)." );
85 $this->assertEquals( true, file_exists( $source ),
86 "Source file $source still exists ($backendName)." );
87 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
88 "Destination file $dest exists ($backendName)." );
90 $this->assertEquals( filesize( $source ),
91 $this->backend
->getFileSize( array( 'src' => $dest ) ),
92 "Destination file $dest has correct size ($backendName)." );
94 $props1 = FSFile
::getPropsFromPath( $source );
95 $props2 = $this->backend
->getFileProps( array( 'src' => $dest ) );
96 $this->assertEquals( $props1, $props2,
97 "Source and destination have the same props ($backendName)." );
100 public function provider_testStore() {
103 $tmpName = TempFSFile
::factory( "unittests_", 'txt' )->getPath();
104 $toPath = $this->baseStorePath() . '/cont1/fun/obj1.txt';
105 $op = array( 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath );
112 $op['overwrite'] = true;
123 * @dataProvider provider_testCopy
125 public function testCopy( $op, $source, $dest ) {
126 $this->pathsToPrune
[] = $source;
127 $this->pathsToPrune
[] = $dest;
129 $this->backend
= $this->singleBackend
;
130 $this->doTestCopy( $op, $source, $dest );
131 $this->tearDownFiles();
133 $this->backend
= $this->multiBackend
;
134 $this->doTestCopy( $op, $source, $dest );
135 $this->tearDownFiles();
138 function doTestCopy( $op, $source, $dest ) {
139 $backendName = $this->backendClass();
141 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
142 $this->backend
->prepare( array( 'dir' => dirname( $dest ) ) );
144 $status = $this->backend
->doOperation(
145 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
146 $this->assertEquals( true, $status->isOK(),
147 "Creation of file at $source succeeded ($backendName)." );
149 $status = $this->backend
->doOperation( $op );
150 $this->assertEquals( array(), $status->errors
,
151 "Copy from $source to $dest succeeded without warnings ($backendName)." );
152 $this->assertEquals( true, $status->isOK(),
153 "Copy from $source to $dest succeeded ($backendName)." );
154 $this->assertEquals( array( 0 => true ), $status->success
,
155 "Copy from $source to $dest has proper 'success' field in Status ($backendName)." );
156 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $source ) ),
157 "Source file $source still exists ($backendName)." );
158 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
159 "Destination file $dest exists after copy ($backendName)." );
162 $this->backend
->getFileSize( array( 'src' => $source ) ),
163 $this->backend
->getFileSize( array( 'src' => $dest ) ),
164 "Destination file $dest has correct size ($backendName)." );
166 $props1 = $this->backend
->getFileProps( array( 'src' => $source ) );
167 $props2 = $this->backend
->getFileProps( array( 'src' => $dest ) );
168 $this->assertEquals( $props1, $props2,
169 "Source and destination have the same props ($backendName)." );
172 public function provider_testCopy() {
175 $source = $this->baseStorePath() . '/cont1/file.txt';
176 $dest = $this->baseStorePath() . '/cont2/fileMoved.txt';
178 $op = array( 'op' => 'copy', 'src' => $source, 'dst' => $dest );
185 $op['overwrite'] = true;
196 * @dataProvider provider_testMove
198 public function testMove( $op, $source, $dest ) {
199 $this->pathsToPrune
[] = $source;
200 $this->pathsToPrune
[] = $dest;
202 $this->backend
= $this->singleBackend
;
203 $this->doTestMove( $op, $source, $dest );
204 $this->tearDownFiles();
206 $this->backend
= $this->multiBackend
;
207 $this->doTestMove( $op, $source, $dest );
208 $this->tearDownFiles();
211 public function doTestMove( $op, $source, $dest ) {
212 $backendName = $this->backendClass();
214 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
215 $this->backend
->prepare( array( 'dir' => dirname( $dest ) ) );
217 $status = $this->backend
->doOperation(
218 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
219 $this->assertEquals( true, $status->isOK(),
220 "Creation of file at $source succeeded ($backendName)." );
222 $status = $this->backend
->doOperation( $op );
223 $this->assertEquals( array(), $status->errors
,
224 "Move from $source to $dest succeeded without warnings ($backendName)." );
225 $this->assertEquals( true, $status->isOK(),
226 "Move from $source to $dest succeeded ($backendName)." );
227 $this->assertEquals( array( 0 => true ), $status->success
,
228 "Move from $source to $dest has proper 'success' field in Status ($backendName)." );
229 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $source ) ),
230 "Source file $source does not still exists ($backendName)." );
231 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
232 "Destination file $dest exists after move ($backendName)." );
234 $this->assertNotEquals(
235 $this->backend
->getFileSize( array( 'src' => $source ) ),
236 $this->backend
->getFileSize( array( 'src' => $dest ) ),
237 "Destination file $dest has correct size ($backendName)." );
239 $props1 = $this->backend
->getFileProps( array( 'src' => $source ) );
240 $props2 = $this->backend
->getFileProps( array( 'src' => $dest ) );
241 $this->assertEquals( false, $props1['fileExists'],
242 "Source file does not exist accourding to props ($backendName)." );
243 $this->assertEquals( true, $props2['fileExists'],
244 "Destination file exists accourding to props ($backendName)." );
247 public function provider_testMove() {
250 $source = $this->baseStorePath() . '/cont1/file.txt';
251 $dest = $this->baseStorePath() . '/cont2/fileMoved.txt';
253 $op = array( 'op' => 'move', 'src' => $source, 'dst' => $dest );
260 $op['overwrite'] = true;
271 * @dataProvider provider_testDelete
273 public function testDelete( $op, $source, $withSource, $okStatus ) {
274 $this->pathsToPrune
[] = $source;
276 $this->backend
= $this->singleBackend
;
277 $this->doTestDelete( $op, $source, $withSource, $okStatus );
278 $this->tearDownFiles();
280 $this->backend
= $this->multiBackend
;
281 $this->doTestDelete( $op, $source, $withSource, $okStatus );
282 $this->tearDownFiles();
285 public function doTestDelete( $op, $source, $withSource, $okStatus ) {
286 $backendName = $this->backendClass();
288 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
291 $status = $this->backend
->doOperation(
292 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
293 $this->assertEquals( true, $status->isOK(),
294 "Creation of file at $source succeeded ($backendName)." );
297 $status = $this->backend
->doOperation( $op );
299 $this->assertEquals( array(), $status->errors
,
300 "Deletion of file at $source succeeded without warnings ($backendName)." );
301 $this->assertEquals( true, $status->isOK(),
302 "Deletion of file at $source succeeded ($backendName)." );
303 $this->assertEquals( array( 0 => true ), $status->success
,
304 "Deletion of file at $source has proper 'success' field in Status ($backendName)." );
306 $this->assertEquals( false, $status->isOK(),
307 "Deletion of file at $source failed ($backendName)." );
310 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $source ) ),
311 "Source file $source does not exist after move ($backendName)." );
314 $this->backend
->getFileSize( array( 'src' => $source ) ),
315 "Source file $source has correct size (false) ($backendName)." );
317 $props1 = $this->backend
->getFileProps( array( 'src' => $source ) );
318 $this->assertFalse( $props1['fileExists'],
319 "Source file $source does not exist according to props ($backendName)." );
322 public function provider_testDelete() {
325 $source = $this->baseStorePath() . '/cont1/myfacefile.txt';
327 $op = array( 'op' => 'delete', 'src' => $source );
338 false, // without source
342 $op['ignoreMissingSource'] = true;
346 false, // without source
354 * @dataProvider provider_testCreate
356 public function testCreate( $op, $dest, $alreadyExists, $okStatus, $newSize ) {
357 $this->pathsToPrune
[] = $dest;
359 $this->backend
= $this->singleBackend
;
360 $this->doTestCreate( $op, $dest, $alreadyExists, $okStatus, $newSize );
361 $this->tearDownFiles();
363 $this->backend
= $this->multiBackend
;
364 $this->doTestCreate( $op, $dest, $alreadyExists, $okStatus, $newSize );
365 $this->tearDownFiles();
368 public function doTestCreate( $op, $dest, $alreadyExists, $okStatus, $newSize ) {
369 $backendName = $this->backendClass();
371 $this->backend
->prepare( array( 'dir' => dirname( $dest ) ) );
373 $oldText = 'blah...blah...waahwaah';
374 if ( $alreadyExists ) {
375 $status = $this->backend
->doOperation(
376 array( 'op' => 'create', 'content' => $oldText, 'dst' => $dest ) );
377 $this->assertEquals( true, $status->isOK(),
378 "Creation of file at $dest succeeded ($backendName)." );
381 $status = $this->backend
->doOperation( $op );
383 $this->assertEquals( array(), $status->errors
,
384 "Creation of file at $dest succeeded without warnings ($backendName)." );
385 $this->assertEquals( true, $status->isOK(),
386 "Creation of file at $dest succeeded ($backendName)." );
387 $this->assertEquals( array( 0 => true ), $status->success
,
388 "Creation of file at $dest has proper 'success' field in Status ($backendName)." );
390 $this->assertEquals( false, $status->isOK(),
391 "Creation of file at $dest failed ($backendName)." );
394 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
395 "Destination file $dest exists after creation ($backendName)." );
397 $props1 = $this->backend
->getFileProps( array( 'src' => $dest ) );
398 $this->assertEquals( true, $props1['fileExists'],
399 "Destination file $dest exists according to props ($backendName)." );
400 if ( $okStatus ) { // file content is what we saved
401 $this->assertEquals( $newSize, $props1['size'],
402 "Destination file $dest has expected size according to props ($backendName)." );
403 $this->assertEquals( $newSize,
404 $this->backend
->getFileSize( array( 'src' => $dest ) ),
405 "Destination file $dest has correct size ($backendName)." );
406 } else { // file content is some other previous text
407 $this->assertEquals( strlen( $oldText ), $props1['size'],
408 "Destination file $dest has original size according to props ($backendName)." );
409 $this->assertEquals( strlen( $oldText ),
410 $this->backend
->getFileSize( array( 'src' => $dest ) ),
411 "Destination file $dest has original size according to props ($backendName)." );
416 * @dataProvider provider_testCreate
418 public function provider_testCreate() {
421 $source = $this->baseStorePath() . '/cont2/myspacefile.txt';
423 $dummyText = 'hey hey';
424 $op = array( 'op' => 'create', 'content' => $dummyText, 'dst' => $source );
428 false, // no dest already exists
436 true, // dest already exists
441 $op['overwrite'] = true;
445 true, // dest already exists
454 * @dataProvider provider_testConcatenate
456 public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
457 $this->pathsToPrune
= array_merge( $this->pathsToPrune
, $srcs );
458 $this->filesToPrune
[] = $op['dst'];
460 $this->backend
= $this->singleBackend
;
461 $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus );
462 $this->tearDownFiles();
464 $this->backend
= $this->multiBackend
;
465 $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus );
466 $this->tearDownFiles();
469 public function doTestConcatenate( $params, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
470 $backendName = $this->backendClass();
475 foreach ( $srcs as $i => $source ) {
476 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
478 'op' => 'create', // operation
479 'dst' => $source, // source
480 'content' => $srcsContent[$i]
482 $expContent .= $srcsContent[$i];
484 $status = $this->backend
->doOperations( $ops );
486 $this->assertEquals( true, $status->isOK(),
487 "Creation of source files succeeded ($backendName)." );
489 $dest = $params['dst'];
490 if ( $alreadyExists ) {
491 $ok = file_put_contents( $dest, 'blah...blah...waahwaah' ) !== false;
492 $this->assertEquals( true, $ok,
493 "Creation of file at $dest succeeded ($backendName)." );
495 $ok = file_put_contents( $dest, '' ) !== false;
496 $this->assertEquals( true, $ok,
497 "Creation of 0-byte file at $dest succeeded ($backendName)." );
500 // Combine the files into one
501 $status = $this->backend
->concatenate( $params );
503 $this->assertEquals( array(), $status->errors
,
504 "Creation of concat file at $dest succeeded without warnings ($backendName)." );
505 $this->assertEquals( true, $status->isOK(),
506 "Creation of concat file at $dest succeeded ($backendName)." );
508 $this->assertEquals( false, $status->isOK(),
509 "Creation of concat file at $dest failed ($backendName)." );
513 $this->assertEquals( true, is_file( $dest ),
514 "Dest concat file $dest exists after creation ($backendName)." );
516 $this->assertEquals( true, is_file( $dest ),
517 "Dest concat file $dest exists after failed creation ($backendName)." );
520 $contents = file_get_contents( $dest );
521 $this->assertNotEquals( false, $contents, "File at $dest exists ($backendName)." );
524 $this->assertEquals( $expContent, $contents,
525 "Concat file at $dest has correct contents ($backendName)." );
527 $this->assertNotEquals( $expContent, $contents,
528 "Concat file at $dest has correct contents ($backendName)." );
532 function provider_testConcatenate() {
535 $rand = mt_rand( 0, 2000000000 ) . time();
536 $dest = wfTempDir() . "/randomfile!$rand.txt";
538 $this->baseStorePath() . '/cont1/file1.txt',
539 $this->baseStorePath() . '/cont1/file2.txt',
540 $this->baseStorePath() . '/cont1/file3.txt',
541 $this->baseStorePath() . '/cont1/file4.txt',
542 $this->baseStorePath() . '/cont1/file5.txt',
543 $this->baseStorePath() . '/cont1/file6.txt',
544 $this->baseStorePath() . '/cont1/file7.txt',
545 $this->baseStorePath() . '/cont1/file8.txt',
546 $this->baseStorePath() . '/cont1/file9.txt',
547 $this->baseStorePath() . '/cont1/file10.txt'
561 $params = array( 'srcs' => $srcs, 'dst' => $dest );
564 $params, // operation
566 $content, // content for each source
567 false, // no dest already exists
572 $params, // operation
574 $content, // content for each source
575 true, // dest already exists
583 * @dataProvider provider_testGetFileContents
585 public function testGetFileContents( $src, $content ) {
586 $this->pathsToPrune
[] = $src;
588 $this->backend
= $this->singleBackend
;
589 $this->doTestGetFileContents( $src, $content );
590 $this->tearDownFiles();
592 $this->backend
= $this->multiBackend
;
593 $this->doTestGetFileContents( $src, $content );
594 $this->tearDownFiles();
598 * @dataProvider provider_testGetFileContents
600 public function doTestGetFileContents( $source, $content ) {
601 $backendName = $this->backendClass();
603 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
605 $status = $this->backend
->doOperation(
606 array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
607 $this->assertEquals( true, $status->isOK(),
608 "Creation of file at $source succeeded ($backendName)." );
610 $newContents = $this->backend
->getFileContents( array( 'src' => $source ) );
611 $this->assertNotEquals( false, $newContents,
612 "Read of file at $source succeeded ($backendName)." );
614 $this->assertEquals( $content, $newContents,
615 "Contents read match data at $source ($backendName)." );
618 function provider_testGetFileContents() {
621 $base = $this->baseStorePath();
622 $cases[] = array( "$base/cont1/b/z/some_file.txt", "some file contents" );
623 $cases[] = array( "$base/cont1/b/some-other_file.txt", "more file contents" );
629 * @dataProvider provider_testGetLocalCopy
631 public function testGetLocalCopy( $src, $content ) {
632 $this->pathsToPrune
[] = $src;
634 $this->backend
= $this->singleBackend
;
635 $this->doTestGetLocalCopy( $src, $content );
636 $this->tearDownFiles();
638 $this->backend
= $this->multiBackend
;
639 $this->doTestGetLocalCopy( $src, $content );
640 $this->tearDownFiles();
643 public function doTestGetLocalCopy( $source, $content ) {
644 $backendName = $this->backendClass();
646 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
648 $status = $this->backend
->doOperation(
649 array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
650 $this->assertEquals( true, $status->isOK(),
651 "Creation of file at $source succeeded ($backendName)." );
653 $tmpFile = $this->backend
->getLocalCopy( array( 'src' => $source ) );
654 $this->assertNotNull( $tmpFile,
655 "Creation of local copy of $source succeeded ($backendName)." );
657 $contents = file_get_contents( $tmpFile->getPath() );
658 $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." );
661 function provider_testGetLocalCopy() {
664 $base = $this->baseStorePath();
665 $cases[] = array( "$base/cont1/a/z/some_file.txt", "some file contents" );
666 $cases[] = array( "$base/cont1/a/some-other_file.txt", "more file contents" );
672 * @dataProvider provider_testGetLocalReference
674 public function testGetLocalReference( $src, $content ) {
675 $this->pathsToPrune
[] = $src;
677 $this->backend
= $this->singleBackend
;
678 $this->doTestGetLocalReference( $src, $content );
679 $this->tearDownFiles();
681 $this->backend
= $this->multiBackend
;
682 $this->doTestGetLocalReference( $src, $content );
683 $this->tearDownFiles();
686 public function doTestGetLocalReference( $source, $content ) {
687 $backendName = $this->backendClass();
689 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
691 $status = $this->backend
->doOperation(
692 array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
693 $this->assertEquals( true, $status->isOK(),
694 "Creation of file at $source succeeded ($backendName)." );
696 $tmpFile = $this->backend
->getLocalReference( array( 'src' => $source ) );
697 $this->assertNotNull( $tmpFile,
698 "Creation of local copy of $source succeeded ($backendName)." );
700 $contents = file_get_contents( $tmpFile->getPath() );
701 $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." );
704 function provider_testGetLocalReference() {
707 $base = $this->baseStorePath();
708 $cases[] = array( "$base/cont1/a/z/some_file.txt", "some file contents" );
709 $cases[] = array( "$base/cont1/a/some-other_file.txt", "more file contents" );
715 * @dataProvider provider_testPrepareAndClean
717 public function testPrepareAndClean( $path, $isOK ) {
718 $this->backend
= $this->singleBackend
;
719 $this->doTestPrepareAndClean( $path, $isOK );
721 $this->backend
= $this->multiBackend
;
722 $this->doTestPrepareAndClean( $path, $isOK );
725 function provider_testPrepareAndClean() {
726 $base = $this->baseStorePath();
728 array( "$base/cont1/a/z/some_file1.txt", true ),
729 array( "$base/cont2/a/z/some_file2.txt", true ),
730 array( "$base/cont3/a/z/some_file3.txt", false ),
734 function doTestPrepareAndClean( $path, $isOK ) {
735 $backendName = $this->backendClass();
737 $status = $this->backend
->prepare( array( 'dir' => $path ) );
739 $this->assertEquals( array(), $status->errors
,
740 "Preparing dir $path succeeded without warnings ($backendName)." );
741 $this->assertEquals( true, $status->isOK(),
742 "Preparing dir $path succeeded ($backendName)." );
744 $this->assertEquals( false, $status->isOK(),
745 "Preparing dir $path failed ($backendName)." );
748 $status = $this->backend
->clean( array( 'dir' => $path ) );
750 $this->assertEquals( array(), $status->errors
,
751 "Cleaning dir $path succeeded without warnings ($backendName)." );
752 $this->assertEquals( true, $status->isOK(),
753 "Cleaning dir $path succeeded ($backendName)." );
755 $this->assertEquals( false, $status->isOK(),
756 "Cleaning dir $path failed ($backendName)." );
762 public function testDoOperations() {
763 $this->backend
= $this->singleBackend
;
764 $this->doTestDoOperations();
766 $this->backend
= $this->multiBackend
;
767 $this->doTestDoOperations();
770 function doTestDoOperations() {
771 $base = $this->baseStorePath();
773 $fileA = "$base/cont1/a/b/fileA.txt";
774 $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq';
775 $fileB = "$base/cont1/a/b/fileB.txt";
776 $fileBContents = 'g-jmq3gpqgt3qtg q3GT ';
777 $fileC = "$base/cont1/a/b/fileC.txt";
778 $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag';
779 $fileD = "$base/cont1/a/b/fileD.txt";
781 $this->pathsToPrune
[] = $fileA;
782 $this->pathsToPrune
[] = $fileB;
783 $this->pathsToPrune
[] = $fileC;
784 $this->pathsToPrune
[] = $fileD;
786 $this->backend
->prepare( array( 'dir' => dirname( $fileA ) ) );
787 $this->backend
->create( array( 'dst' => $fileA, 'content' => $fileAContents ) );
788 $this->backend
->prepare( array( 'dir' => dirname( $fileB ) ) );
789 $this->backend
->create( array( 'dst' => $fileB, 'content' => $fileBContents ) );
790 $this->backend
->prepare( array( 'dir' => dirname( $fileC ) ) );
791 $this->backend
->create( array( 'dst' => $fileC, 'content' => $fileCContents ) );
793 $status = $this->backend
->doOperations( array(
794 array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ),
795 // Now: A:<A>, B:<B>, C:<A>, D:<D> (file:<orginal contents>)
796 array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ),
797 // Now: A:<A>, B:<B>, C:<A>, D:<D>
798 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD, 'overwrite' => 1 ),
799 // Now: A:<A>, B:<B>, C:<empty>, D:<A>
800 array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC ),
801 // Now: A:<A>, B:<empty>, C:<B>, D:<A>
802 array( 'op' => 'move', 'src' => $fileD, 'dst' => $fileA, 'overwriteSame' => 1 ),
803 // Now: A:<A>, B:<empty>, C:<B>, D:<empty>
804 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileA, 'overwrite' => 1 ),
805 // Now: A:<B>, B:<empty>, C:<empty>, D:<empty>
806 array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC ),
807 // Now: A:<B>, B:<empty>, C:<B>, D:<empty>
808 array( 'op' => 'move', 'src' => $fileA, 'dst' => $fileC, 'overwriteSame' => 1 ),
809 // Now: A:<empty>, B:<empty>, C:<B>, D:<empty>
810 array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ),
812 array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ),
814 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ),
816 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ),
820 $this->assertEquals( array(), $status->errors
, "Operation batch succeeded" );
821 $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" );
822 $this->assertEquals( 12, count( $status->success
),
823 "Operation batch has correct success array" );
825 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $fileA ) ),
826 "File does not exist at $fileA" );
827 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $fileB ) ),
828 "File does not exist at $fileB" );
829 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $fileD ) ),
830 "File does not exist at $fileD" );
832 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $fileC ) ),
833 "File exists at $fileC" );
834 $this->assertEquals( $fileBContents,
835 $this->backend
->getFileContents( array( 'src' => $fileC ) ),
836 "Correct file contents of $fileC" );
837 $this->assertEquals( strlen( $fileBContents ),
838 $this->backend
->getFileSize( array( 'src' => $fileC ) ),
839 "Correct file size of $fileC" );
840 $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ),
841 $this->backend
->getFileSha1Base36( array( 'src' => $fileC ) ),
842 "Correct file SHA-1 of $fileC" );
844 // @TODO: test some cases where the ops should fail
847 public function testGetFileList() {
848 $this->backend
= $this->singleBackend
;
849 $this->doTestGetFileList();
850 $this->tearDownFiles();
852 $this->backend
= $this->multiBackend
;
853 $this->doTestGetFileList();
854 $this->tearDownFiles();
857 public function doTestGetFileList() {
858 $backendName = $this->backendClass();
860 $base = $this->baseStorePath();
862 "$base/cont1/test1.txt",
863 "$base/cont1/test2.txt",
864 "$base/cont1/test3.txt",
865 "$base/cont1/subdir1/test1.txt",
866 "$base/cont1/subdir1/test2.txt",
867 "$base/cont1/subdir2/test3.txt",
868 "$base/cont1/subdir2/test4.txt",
869 "$base/cont1/subdir2/subdir/test1.txt",
870 "$base/cont1/subdir2/subdir/test2.txt",
871 "$base/cont1/subdir2/subdir/test3.txt",
872 "$base/cont1/subdir2/subdir/test4.txt",
873 "$base/cont1/subdir2/subdir/test5.txt",
874 "$base/cont1/subdir2/subdir/sub/test0.txt",
875 "$base/cont1/subdir2/subdir/sub/120-px-file.txt",
877 $this->pathsToPrune
= array_merge( $this->pathsToPrune
, $files );
881 foreach ( $files as $file ) {
882 $ops[] = array( 'op' => 'create', 'content' => 'xxy', 'dst' => $file );
883 $this->backend
->prepare( array( 'dir' => dirname( $file ) ) );
885 $status = $this->backend
->doOperations( $ops );
886 $this->assertEquals( true, $status->isOK(),
887 "Creation of files succeeded ($backendName)." );
898 "subdir2/subdir/test1.txt",
899 "subdir2/subdir/test2.txt",
900 "subdir2/subdir/test3.txt",
901 "subdir2/subdir/test4.txt",
902 "subdir2/subdir/test5.txt",
903 "subdir2/subdir/sub/test0.txt",
904 "subdir2/subdir/sub/120-px-file.txt",
908 // Actual listing (no trailing slash)
910 $iter = $this->backend
->getFileList( array( 'dir' => "$base/cont1" ) );
911 foreach ( $iter as $file ) {
916 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
918 // Actual listing (with trailing slash)
920 $iter = $this->backend
->getFileList( array( 'dir' => "$base/cont1/" ) );
921 foreach ( $iter as $file ) {
926 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
928 foreach ( $files as $file ) {
929 $this->backend
->doOperation( array( 'op' => 'delete', 'src' => "$base/$file" ) );
932 $iter = $this->backend
->getFileList( array( 'dir' => "$base/cont1/not/exists" ) );
933 foreach ( $iter as $iter ) {} // no errors
936 function tearDownFiles() {
937 foreach ( $this->filesToPrune
as $file ) {
940 foreach ( $this->pathsToPrune
as $file ) {
941 $this->backend
->doOperation( array( 'op' => 'delete', 'src' => $file ) );
943 while ( $tmp = FileBackend
::parentStoragePath( $tmp ) ) {
944 $this->backend
->clean( array( 'dir' => $tmp ) );
949 function tearDown() {