6 class FileBackendTest
extends MediaWikiTestCase
{
7 private $backend, $multiBackend;
8 private $filesToPrune = array();
9 private $dirsToPrune = array();
10 private static $backendToUse;
13 global $wgFileBackends;
15 $tmpPrefix = wfTempDir() . '/filebackend-unittest-' . time() . '-' . mt_rand();
16 if ( $this->getCliArg( 'use-filebackend=' ) ) {
17 if ( self
::$backendToUse ) {
18 $this->singleBackend
= self
::$backendToUse;
20 $name = $this->getCliArg( 'use-filebackend=' );
22 foreach ( $wgFileBackends as $conf ) {
23 if ( $conf['name'] == $name ) {
27 $useConfig['name'] = 'localtesting'; // swap name
28 $class = $conf['class'];
29 self
::$backendToUse = new $class( $useConfig );
30 $this->singleBackend
= self
::$backendToUse;
33 $this->singleBackend
= new FSFileBackend( array(
34 'name' => 'localtesting',
35 'lockManager' => 'fsLockManager',
36 'containerPaths' => array(
37 'unittest-cont1' => "{$tmpPrefix}-localtesting-cont1",
38 'unittest-cont2' => "{$tmpPrefix}-localtesting-cont2" )
41 $this->multiBackend
= new FileBackendMultiWrite( array(
42 'name' => 'localtesting',
43 'lockManager' => 'fsLockManager',
46 'name' => 'localmutlitesting1',
47 'class' => 'FSFileBackend',
48 'lockManager' => 'nullLockManager',
49 'containerPaths' => array(
50 'unittest-cont1' => "{$tmpPrefix}-localtestingmulti1-cont1",
51 'unittest-cont2' => "{$tmpPrefix}-localtestingmulti1-cont2" ),
52 'isMultiMaster' => false
55 'name' => 'localmutlitesting2',
56 'class' => 'FSFileBackend',
57 'lockManager' => 'nullLockManager',
58 'containerPaths' => array(
59 'unittest-cont1' => "{$tmpPrefix}-localtestingmulti2-cont1",
60 'unittest-cont2' => "{$tmpPrefix}-localtestingmulti2-cont2" ),
61 'isMultiMaster' => true
65 $this->filesToPrune
= array();
68 private function baseStorePath() {
69 return 'mwstore://localtesting';
72 private function backendClass() {
73 return get_class( $this->backend
);
77 * @dataProvider provider_testStore
79 public function testStore( $op ) {
80 $this->filesToPrune
[] = $op['src'];
82 $this->backend
= $this->singleBackend
;
83 $this->tearDownFiles();
84 $this->doTestStore( $op );
85 $this->tearDownFiles();
87 $this->backend
= $this->multiBackend
;
88 $this->tearDownFiles();
89 $this->doTestStore( $op );
90 $this->tearDownFiles();
93 function doTestStore( $op ) {
94 $backendName = $this->backendClass();
98 $this->prepare( array( 'dir' => dirname( $dest ) ) );
100 file_put_contents( $source, "Unit test file" );
102 if ( isset( $op['overwrite'] ) ||
isset( $op['overwriteSame'] ) ) {
103 $this->backend
->store( $op );
106 $status = $this->backend
->doOperation( $op );
108 $this->assertEquals( array(), $status->errors
,
109 "Store from $source to $dest succeeded without warnings ($backendName)." );
110 $this->assertEquals( array(), $status->errors
,
111 "Store from $source to $dest succeeded ($backendName)." );
112 $this->assertEquals( array( 0 => true ), $status->success
,
113 "Store from $source to $dest has proper 'success' field in Status ($backendName)." );
114 $this->assertEquals( true, file_exists( $source ),
115 "Source file $source still exists ($backendName)." );
116 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
117 "Destination file $dest exists ($backendName)." );
119 $this->assertEquals( filesize( $source ),
120 $this->backend
->getFileSize( array( 'src' => $dest ) ),
121 "Destination file $dest has correct size ($backendName)." );
123 $props1 = FSFile
::getPropsFromPath( $source );
124 $props2 = $this->backend
->getFileProps( array( 'src' => $dest ) );
125 $this->assertEquals( $props1, $props2,
126 "Source and destination have the same props ($backendName)." );
129 public function provider_testStore() {
132 $tmpName = TempFSFile
::factory( "unittests_", 'txt' )->getPath();
133 $toPath = $this->baseStorePath() . '/unittest-cont1/fun/obj1.txt';
134 $op = array( 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath );
142 $op2['overwrite'] = true;
150 $op2['overwriteSame'] = true;
161 * @dataProvider provider_testCopy
163 public function testCopy( $op ) {
164 $this->backend
= $this->singleBackend
;
165 $this->tearDownFiles();
166 $this->doTestCopy( $op );
167 $this->tearDownFiles();
169 $this->backend
= $this->multiBackend
;
170 $this->tearDownFiles();
171 $this->doTestCopy( $op );
172 $this->tearDownFiles();
175 function doTestCopy( $op ) {
176 $backendName = $this->backendClass();
178 $source = $op['src'];
180 $this->prepare( array( 'dir' => dirname( $source ) ) );
181 $this->prepare( array( 'dir' => dirname( $dest ) ) );
183 $status = $this->backend
->doOperation(
184 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
185 $this->assertEquals( array(), $status->errors
,
186 "Creation of file at $source succeeded ($backendName)." );
188 if ( isset( $op['overwrite'] ) ||
isset( $op['overwriteSame'] ) ) {
189 $this->backend
->copy( $op );
192 $status = $this->backend
->doOperation( $op );
194 $this->assertEquals( array(), $status->errors
,
195 "Copy from $source to $dest succeeded without warnings ($backendName)." );
196 $this->assertEquals( true, $status->isOK(),
197 "Copy from $source to $dest succeeded ($backendName)." );
198 $this->assertEquals( array( 0 => true ), $status->success
,
199 "Copy from $source to $dest has proper 'success' field in Status ($backendName)." );
200 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $source ) ),
201 "Source file $source still exists ($backendName)." );
202 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
203 "Destination file $dest exists after copy ($backendName)." );
206 $this->backend
->getFileSize( array( 'src' => $source ) ),
207 $this->backend
->getFileSize( array( 'src' => $dest ) ),
208 "Destination file $dest has correct size ($backendName)." );
210 $props1 = $this->backend
->getFileProps( array( 'src' => $source ) );
211 $props2 = $this->backend
->getFileProps( array( 'src' => $dest ) );
212 $this->assertEquals( $props1, $props2,
213 "Source and destination have the same props ($backendName)." );
216 public function provider_testCopy() {
219 $source = $this->baseStorePath() . '/unittest-cont1/file.txt';
220 $dest = $this->baseStorePath() . '/unittest-cont2/fileMoved.txt';
222 $op = array( 'op' => 'copy', 'src' => $source, 'dst' => $dest );
230 $op2['overwrite'] = true;
238 $op2['overwriteSame'] = true;
249 * @dataProvider provider_testMove
251 public function testMove( $op ) {
252 $this->backend
= $this->singleBackend
;
253 $this->tearDownFiles();
254 $this->doTestMove( $op );
255 $this->tearDownFiles();
257 $this->backend
= $this->multiBackend
;
258 $this->tearDownFiles();
259 $this->doTestMove( $op );
260 $this->tearDownFiles();
263 private function doTestMove( $op ) {
264 $backendName = $this->backendClass();
266 $source = $op['src'];
268 $this->prepare( array( 'dir' => dirname( $source ) ) );
269 $this->prepare( array( 'dir' => dirname( $dest ) ) );
271 $status = $this->backend
->doOperation(
272 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
273 $this->assertEquals( array(), $status->errors
,
274 "Creation of file at $source succeeded ($backendName)." );
276 if ( isset( $op['overwrite'] ) ||
isset( $op['overwriteSame'] ) ) {
277 $this->backend
->copy( $op );
280 $status = $this->backend
->doOperation( $op );
281 $this->assertEquals( array(), $status->errors
,
282 "Move from $source to $dest succeeded without warnings ($backendName)." );
283 $this->assertEquals( true, $status->isOK(),
284 "Move from $source to $dest succeeded ($backendName)." );
285 $this->assertEquals( array( 0 => true ), $status->success
,
286 "Move from $source to $dest has proper 'success' field in Status ($backendName)." );
287 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $source ) ),
288 "Source file $source does not still exists ($backendName)." );
289 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
290 "Destination file $dest exists after move ($backendName)." );
292 $this->assertNotEquals(
293 $this->backend
->getFileSize( array( 'src' => $source ) ),
294 $this->backend
->getFileSize( array( 'src' => $dest ) ),
295 "Destination file $dest has correct size ($backendName)." );
297 $props1 = $this->backend
->getFileProps( array( 'src' => $source ) );
298 $props2 = $this->backend
->getFileProps( array( 'src' => $dest ) );
299 $this->assertEquals( false, $props1['fileExists'],
300 "Source file does not exist accourding to props ($backendName)." );
301 $this->assertEquals( true, $props2['fileExists'],
302 "Destination file exists accourding to props ($backendName)." );
305 public function provider_testMove() {
308 $source = $this->baseStorePath() . '/unittest-cont1/file.txt';
309 $dest = $this->baseStorePath() . '/unittest-cont2/fileMoved.txt';
311 $op = array( 'op' => 'move', 'src' => $source, 'dst' => $dest );
319 $op2['overwrite'] = true;
327 $op2['overwriteSame'] = true;
338 * @dataProvider provider_testDelete
340 public function testDelete( $op, $withSource, $okStatus ) {
341 $this->backend
= $this->singleBackend
;
342 $this->tearDownFiles();
343 $this->doTestDelete( $op, $withSource, $okStatus );
344 $this->tearDownFiles();
346 $this->backend
= $this->multiBackend
;
347 $this->tearDownFiles();
348 $this->doTestDelete( $op, $withSource, $okStatus );
349 $this->tearDownFiles();
352 private function doTestDelete( $op, $withSource, $okStatus ) {
353 $backendName = $this->backendClass();
355 $source = $op['src'];
356 $this->prepare( array( 'dir' => dirname( $source ) ) );
359 $status = $this->backend
->doOperation(
360 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
361 $this->assertEquals( array(), $status->errors
,
362 "Creation of file at $source succeeded ($backendName)." );
365 $status = $this->backend
->doOperation( $op );
367 $this->assertEquals( array(), $status->errors
,
368 "Deletion of file at $source succeeded without warnings ($backendName)." );
369 $this->assertEquals( true, $status->isOK(),
370 "Deletion of file at $source succeeded ($backendName)." );
371 $this->assertEquals( array( 0 => true ), $status->success
,
372 "Deletion of file at $source has proper 'success' field in Status ($backendName)." );
374 $this->assertEquals( false, $status->isOK(),
375 "Deletion of file at $source failed ($backendName)." );
378 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $source ) ),
379 "Source file $source does not exist after move ($backendName)." );
382 $this->backend
->getFileSize( array( 'src' => $source ) ),
383 "Source file $source has correct size (false) ($backendName)." );
385 $props1 = $this->backend
->getFileProps( array( 'src' => $source ) );
386 $this->assertFalse( $props1['fileExists'],
387 "Source file $source does not exist according to props ($backendName)." );
390 public function provider_testDelete() {
393 $source = $this->baseStorePath() . '/unittest-cont1/myfacefile.txt';
395 $op = array( 'op' => 'delete', 'src' => $source );
404 false, // without source
408 $op['ignoreMissingSource'] = true;
411 false, // without source
419 * @dataProvider provider_testCreate
421 public function testCreate( $op, $alreadyExists, $okStatus, $newSize ) {
422 $this->backend
= $this->singleBackend
;
423 $this->tearDownFiles();
424 $this->doTestCreate( $op, $alreadyExists, $okStatus, $newSize );
425 $this->tearDownFiles();
427 $this->backend
= $this->multiBackend
;
428 $this->tearDownFiles();
429 $this->doTestCreate( $op, $alreadyExists, $okStatus, $newSize );
430 $this->tearDownFiles();
433 private function doTestCreate( $op, $alreadyExists, $okStatus, $newSize ) {
434 $backendName = $this->backendClass();
437 $this->prepare( array( 'dir' => dirname( $dest ) ) );
439 $oldText = 'blah...blah...waahwaah';
440 if ( $alreadyExists ) {
441 $status = $this->backend
->doOperation(
442 array( 'op' => 'create', 'content' => $oldText, 'dst' => $dest ) );
443 $this->assertEquals( array(), $status->errors
,
444 "Creation of file at $dest succeeded ($backendName)." );
447 $status = $this->backend
->doOperation( $op );
449 $this->assertEquals( array(), $status->errors
,
450 "Creation of file at $dest succeeded without warnings ($backendName)." );
451 $this->assertEquals( true, $status->isOK(),
452 "Creation of file at $dest succeeded ($backendName)." );
453 $this->assertEquals( array( 0 => true ), $status->success
,
454 "Creation of file at $dest has proper 'success' field in Status ($backendName)." );
456 $this->assertEquals( false, $status->isOK(),
457 "Creation of file at $dest failed ($backendName)." );
460 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
461 "Destination file $dest exists after creation ($backendName)." );
463 $props1 = $this->backend
->getFileProps( array( 'src' => $dest ) );
464 $this->assertEquals( true, $props1['fileExists'],
465 "Destination file $dest exists according to props ($backendName)." );
466 if ( $okStatus ) { // file content is what we saved
467 $this->assertEquals( $newSize, $props1['size'],
468 "Destination file $dest has expected size according to props ($backendName)." );
469 $this->assertEquals( $newSize,
470 $this->backend
->getFileSize( array( 'src' => $dest ) ),
471 "Destination file $dest has correct size ($backendName)." );
472 } else { // file content is some other previous text
473 $this->assertEquals( strlen( $oldText ), $props1['size'],
474 "Destination file $dest has original size according to props ($backendName)." );
475 $this->assertEquals( strlen( $oldText ),
476 $this->backend
->getFileSize( array( 'src' => $dest ) ),
477 "Destination file $dest has original size according to props ($backendName)." );
482 * @dataProvider provider_testCreate
484 public function provider_testCreate() {
487 $dest = $this->baseStorePath() . '/unittest-cont2/myspacefile.txt';
489 $op = array( 'op' => 'create', 'content' => 'test test testing', 'dst' => $dest );
492 false, // no dest already exists
494 strlen( $op['content'] )
498 $op2['content'] = "\n";
501 false, // no dest already exists
503 strlen( $op2['content'] )
507 $op2['content'] = "fsf\n waf 3kt";
510 true, // dest already exists
512 strlen( $op2['content'] )
516 $op2['content'] = "egm'g gkpe gpqg eqwgwqg";
517 $op2['overwrite'] = true;
520 true, // dest already exists
522 strlen( $op2['content'] )
526 $op2['content'] = "39qjmg3-qg";
527 $op2['overwriteSame'] = true;
530 true, // dest already exists
532 strlen( $op2['content'] )
539 * @dataProvider provider_testConcatenate
541 public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
542 $this->filesToPrune
[] = $op['dst'];
544 $this->backend
= $this->singleBackend
;
545 $this->tearDownFiles();
546 $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus );
547 $this->tearDownFiles();
549 $this->backend
= $this->multiBackend
;
550 $this->tearDownFiles();
551 $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus );
552 $this->tearDownFiles();
555 public function doTestConcatenate( $params, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
556 $backendName = $this->backendClass();
561 foreach ( $srcs as $i => $source ) {
562 $this->prepare( array( 'dir' => dirname( $source ) ) );
564 'op' => 'create', // operation
565 'dst' => $source, // source
566 'content' => $srcsContent[$i]
568 $expContent .= $srcsContent[$i];
570 $status = $this->backend
->doOperations( $ops );
572 $this->assertEquals( array(), $status->errors
,
573 "Creation of source files succeeded ($backendName)." );
575 $dest = $params['dst'];
576 if ( $alreadyExists ) {
577 $ok = file_put_contents( $dest, 'blah...blah...waahwaah' ) !== false;
578 $this->assertEquals( true, $ok,
579 "Creation of file at $dest succeeded ($backendName)." );
581 $ok = file_put_contents( $dest, '' ) !== false;
582 $this->assertEquals( true, $ok,
583 "Creation of 0-byte file at $dest succeeded ($backendName)." );
586 // Combine the files into one
587 $status = $this->backend
->concatenate( $params );
589 $this->assertEquals( array(), $status->errors
,
590 "Creation of concat file at $dest succeeded without warnings ($backendName)." );
591 $this->assertEquals( true, $status->isOK(),
592 "Creation of concat file at $dest succeeded ($backendName)." );
594 $this->assertEquals( false, $status->isOK(),
595 "Creation of concat file at $dest failed ($backendName)." );
599 $this->assertEquals( true, is_file( $dest ),
600 "Dest concat file $dest exists after creation ($backendName)." );
602 $this->assertEquals( true, is_file( $dest ),
603 "Dest concat file $dest exists after failed creation ($backendName)." );
606 $contents = file_get_contents( $dest );
607 $this->assertNotEquals( false, $contents, "File at $dest exists ($backendName)." );
610 $this->assertEquals( $expContent, $contents,
611 "Concat file at $dest has correct contents ($backendName)." );
613 $this->assertNotEquals( $expContent, $contents,
614 "Concat file at $dest has correct contents ($backendName)." );
618 function provider_testConcatenate() {
621 $rand = mt_rand( 0, 2000000000 ) . time();
622 $dest = wfTempDir() . "/randomfile!$rand.txt";
624 $this->baseStorePath() . '/unittest-cont1/file1.txt',
625 $this->baseStorePath() . '/unittest-cont1/file2.txt',
626 $this->baseStorePath() . '/unittest-cont1/file3.txt',
627 $this->baseStorePath() . '/unittest-cont1/file4.txt',
628 $this->baseStorePath() . '/unittest-cont1/file5.txt',
629 $this->baseStorePath() . '/unittest-cont1/file6.txt',
630 $this->baseStorePath() . '/unittest-cont1/file7.txt',
631 $this->baseStorePath() . '/unittest-cont1/file8.txt',
632 $this->baseStorePath() . '/unittest-cont1/file9.txt',
633 $this->baseStorePath() . '/unittest-cont1/file10.txt'
647 $params = array( 'srcs' => $srcs, 'dst' => $dest );
650 $params, // operation
652 $content, // content for each source
653 false, // no dest already exists
658 $params, // operation
660 $content, // content for each source
661 true, // dest already exists
669 * @dataProvider provider_testGetFileContents
671 public function testGetFileContents( $source, $content ) {
672 $this->backend
= $this->singleBackend
;
673 $this->tearDownFiles();
674 $this->doTestGetFileContents( $source, $content );
675 $this->tearDownFiles();
677 $this->backend
= $this->multiBackend
;
678 $this->tearDownFiles();
679 $this->doTestGetFileContents( $source, $content );
680 $this->tearDownFiles();
684 * @dataProvider provider_testGetFileContents
686 public function doTestGetFileContents( $source, $content ) {
687 $backendName = $this->backendClass();
689 $this->prepare( array( 'dir' => dirname( $source ) ) );
691 $status = $this->backend
->doOperation(
692 array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
693 $this->assertEquals( array(), $status->errors
,
694 "Creation of file at $source succeeded ($backendName)." );
695 $this->assertEquals( true, $status->isOK(),
696 "Creation of file at $source succeeded with OK status ($backendName)." );
698 $newContents = $this->backend
->getFileContents( array( 'src' => $source ) );
699 $this->assertNotEquals( false, $newContents,
700 "Read of file at $source succeeded ($backendName)." );
702 $this->assertEquals( $content, $newContents,
703 "Contents read match data at $source ($backendName)." );
706 function provider_testGetFileContents() {
709 $base = $this->baseStorePath();
710 $cases[] = array( "$base/unittest-cont1/b/z/some_file.txt", "some file contents" );
711 $cases[] = array( "$base/unittest-cont1/b/some-other_file.txt", "more file contents" );
717 * @dataProvider provider_testGetLocalCopy
719 public function testGetLocalCopy( $source, $content ) {
720 $this->backend
= $this->singleBackend
;
721 $this->tearDownFiles();
722 $this->doTestGetLocalCopy( $source, $content );
723 $this->tearDownFiles();
725 $this->backend
= $this->multiBackend
;
726 $this->tearDownFiles();
727 $this->doTestGetLocalCopy( $source, $content );
728 $this->tearDownFiles();
731 public function doTestGetLocalCopy( $source, $content ) {
732 $backendName = $this->backendClass();
734 $this->prepare( array( 'dir' => dirname( $source ) ) );
736 $status = $this->backend
->doOperation(
737 array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
738 $this->assertEquals( array(), $status->errors
,
739 "Creation of file at $source succeeded ($backendName)." );
741 $tmpFile = $this->backend
->getLocalCopy( array( 'src' => $source ) );
742 $this->assertNotNull( $tmpFile,
743 "Creation of local copy of $source succeeded ($backendName)." );
745 $contents = file_get_contents( $tmpFile->getPath() );
746 $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." );
749 function provider_testGetLocalCopy() {
752 $base = $this->baseStorePath();
753 $cases[] = array( "$base/unittest-cont1/a/z/some_file.txt", "some file contents" );
754 $cases[] = array( "$base/unittest-cont1/a/some-other_file.txt", "more file contents" );
760 * @dataProvider provider_testGetLocalReference
762 public function testGetLocalReference( $source, $content ) {
763 $this->backend
= $this->singleBackend
;
764 $this->tearDownFiles();
765 $this->doTestGetLocalReference( $source, $content );
766 $this->tearDownFiles();
768 $this->backend
= $this->multiBackend
;
769 $this->tearDownFiles();
770 $this->doTestGetLocalReference( $source, $content );
771 $this->tearDownFiles();
774 private function doTestGetLocalReference( $source, $content ) {
775 $backendName = $this->backendClass();
777 $this->prepare( array( 'dir' => dirname( $source ) ) );
779 $status = $this->backend
->doOperation(
780 array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
781 $this->assertEquals( array(), $status->errors
,
782 "Creation of file at $source succeeded ($backendName)." );
784 $tmpFile = $this->backend
->getLocalReference( array( 'src' => $source ) );
785 $this->assertNotNull( $tmpFile,
786 "Creation of local copy of $source succeeded ($backendName)." );
788 $contents = file_get_contents( $tmpFile->getPath() );
789 $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." );
792 function provider_testGetLocalReference() {
795 $base = $this->baseStorePath();
796 $cases[] = array( "$base/unittest-cont1/a/z/some_file.txt", "some file contents" );
797 $cases[] = array( "$base/unittest-cont1/a/some-other_file.txt", "more file contents" );
803 * @dataProvider provider_testPrepareAndClean
805 public function testPrepareAndClean( $path, $isOK ) {
806 $this->backend
= $this->singleBackend
;
807 $this->doTestPrepareAndClean( $path, $isOK );
808 $this->tearDownFiles();
810 $this->backend
= $this->multiBackend
;
811 $this->doTestPrepareAndClean( $path, $isOK );
812 $this->tearDownFiles();
815 function provider_testPrepareAndClean() {
816 $base = $this->baseStorePath();
818 array( "$base/unittest-cont1/a/z/some_file1.txt", true ),
819 array( "$base/unittest-cont2/a/z/some_file2.txt", true ),
820 # Specific to FS backend with no basePath field set
821 #array( "$base/unittest-cont3/a/z/some_file3.txt", false ),
825 function doTestPrepareAndClean( $path, $isOK ) {
826 $backendName = $this->backendClass();
828 $status = $this->prepare( array( 'dir' => dirname( $path ) ) );
830 $this->assertEquals( array(), $status->errors
,
831 "Preparing dir $path succeeded without warnings ($backendName)." );
832 $this->assertEquals( true, $status->isOK(),
833 "Preparing dir $path succeeded ($backendName)." );
835 $this->assertEquals( false, $status->isOK(),
836 "Preparing dir $path failed ($backendName)." );
839 $status = $this->backend
->clean( array( 'dir' => dirname( $path ) ) );
841 $this->assertEquals( array(), $status->errors
,
842 "Cleaning dir $path succeeded without warnings ($backendName)." );
843 $this->assertEquals( true, $status->isOK(),
844 "Cleaning dir $path succeeded ($backendName)." );
846 $this->assertEquals( false, $status->isOK(),
847 "Cleaning dir $path failed ($backendName)." );
853 public function testDoOperations() {
854 $this->backend
= $this->singleBackend
;
855 $this->tearDownFiles();
856 $this->doTestDoOperations();
857 $this->tearDownFiles();
859 $this->backend
= $this->multiBackend
;
860 $this->tearDownFiles();
861 $this->doTestDoOperations();
862 $this->tearDownFiles();
864 // @TODO: test some cases where the ops should fail
867 function doTestDoOperations() {
868 $base = $this->baseStorePath();
870 $fileA = "$base/unittest-cont1/a/b/fileA.txt";
871 $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq';
872 $fileB = "$base/unittest-cont1/a/b/fileB.txt";
873 $fileBContents = 'g-jmq3gpqgt3qtg q3GT ';
874 $fileC = "$base/unittest-cont1/a/b/fileC.txt";
875 $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag';
876 $fileD = "$base/unittest-cont1/a/b/fileD.txt";
878 $this->prepare( array( 'dir' => dirname( $fileA ) ) );
879 $this->backend
->create( array( 'dst' => $fileA, 'content' => $fileAContents ) );
880 $this->prepare( array( 'dir' => dirname( $fileB ) ) );
881 $this->backend
->create( array( 'dst' => $fileB, 'content' => $fileBContents ) );
882 $this->prepare( array( 'dir' => dirname( $fileC ) ) );
883 $this->backend
->create( array( 'dst' => $fileC, 'content' => $fileCContents ) );
885 $status = $this->backend
->doOperations( array(
886 array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ),
887 // Now: A:<A>, B:<B>, C:<A>, D:<D> (file:<orginal contents>)
888 array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ),
889 // Now: A:<A>, B:<B>, C:<A>, D:<D>
890 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD, 'overwrite' => 1 ),
891 // Now: A:<A>, B:<B>, C:<empty>, D:<A>
892 array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC ),
893 // Now: A:<A>, B:<empty>, C:<B>, D:<A>
894 array( 'op' => 'move', 'src' => $fileD, 'dst' => $fileA, 'overwriteSame' => 1 ),
895 // Now: A:<A>, B:<empty>, C:<B>, D:<empty>
896 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileA, 'overwrite' => 1 ),
897 // Now: A:<B>, B:<empty>, C:<empty>, D:<empty>
898 array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC ),
899 // Now: A:<B>, B:<empty>, C:<B>, D:<empty>
900 array( 'op' => 'move', 'src' => $fileA, 'dst' => $fileC, 'overwriteSame' => 1 ),
901 // Now: A:<empty>, B:<empty>, C:<B>, D:<empty>
902 array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ),
904 array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ),
906 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ),
908 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ),
910 array( 'op' => 'null' ),
914 $this->assertEquals( array(), $status->errors
, "Operation batch succeeded" );
915 $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" );
916 $this->assertEquals( 13, count( $status->success
),
917 "Operation batch has correct success array" );
919 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $fileA ) ),
920 "File does not exist at $fileA" );
921 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $fileB ) ),
922 "File does not exist at $fileB" );
923 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $fileD ) ),
924 "File does not exist at $fileD" );
926 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $fileC ) ),
927 "File exists at $fileC" );
928 $this->assertEquals( $fileBContents,
929 $this->backend
->getFileContents( array( 'src' => $fileC ) ),
930 "Correct file contents of $fileC" );
931 $this->assertEquals( strlen( $fileBContents ),
932 $this->backend
->getFileSize( array( 'src' => $fileC ) ),
933 "Correct file size of $fileC" );
934 $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ),
935 $this->backend
->getFileSha1Base36( array( 'src' => $fileC ) ),
936 "Correct file SHA-1 of $fileC" );
939 public function testGetFileList() {
940 $this->backend
= $this->singleBackend
;
941 $this->tearDownFiles();
942 $this->doTestGetFileList();
943 $this->tearDownFiles();
945 $this->backend
= $this->multiBackend
;
946 $this->tearDownFiles();
947 $this->doTestGetFileList();
948 $this->tearDownFiles();
951 private function doTestGetFileList() {
952 $backendName = $this->backendClass();
954 $base = $this->baseStorePath();
956 "$base/unittest-cont1/test1.txt",
957 "$base/unittest-cont1/test2.txt",
958 "$base/unittest-cont1/test3.txt",
959 "$base/unittest-cont1/subdir1/test1.txt",
960 "$base/unittest-cont1/subdir1/test2.txt",
961 "$base/unittest-cont1/subdir2/test3.txt",
962 "$base/unittest-cont1/subdir2/test4.txt",
963 "$base/unittest-cont1/subdir2/subdir/test1.txt",
964 "$base/unittest-cont1/subdir2/subdir/test2.txt",
965 "$base/unittest-cont1/subdir2/subdir/test3.txt",
966 "$base/unittest-cont1/subdir2/subdir/test4.txt",
967 "$base/unittest-cont1/subdir2/subdir/test5.txt",
968 "$base/unittest-cont1/subdir2/subdir/sub/test0.txt",
969 "$base/unittest-cont1/subdir2/subdir/sub/120-px-file.txt",
974 foreach ( $files as $file ) {
975 $ops[] = array( 'op' => 'create', 'content' => 'xxy', 'dst' => $file );
976 $this->prepare( array( 'dir' => dirname( $file ) ) );
978 $status = $this->backend
->doOperations( $ops );
979 $this->assertEquals( array(), $status->errors
,
980 "Creation of files succeeded ($backendName)." );
981 $this->assertEquals( true, $status->isOK(),
982 "Creation of files succeeded with OK status ($backendName)." );
993 "subdir2/subdir/test1.txt",
994 "subdir2/subdir/test2.txt",
995 "subdir2/subdir/test3.txt",
996 "subdir2/subdir/test4.txt",
997 "subdir2/subdir/test5.txt",
998 "subdir2/subdir/sub/test0.txt",
999 "subdir2/subdir/sub/120-px-file.txt",
1003 // Actual listing (no trailing slash)
1005 $iter = $this->backend
->getFileList( array( 'dir' => "$base/unittest-cont1" ) );
1006 foreach ( $iter as $file ) {
1011 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
1013 // Actual listing (with trailing slash)
1015 $iter = $this->backend
->getFileList( array( 'dir' => "$base/unittest-cont1/" ) );
1016 foreach ( $iter as $file ) {
1021 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
1031 "sub/120-px-file.txt",
1035 // Actual listing (no trailing slash)
1037 $iter = $this->backend
->getFileList( array( 'dir' => "$base/unittest-cont1/subdir2/subdir" ) );
1038 foreach ( $iter as $file ) {
1043 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
1045 // Actual listing (with trailing slash)
1047 $iter = $this->backend
->getFileList( array( 'dir' => "$base/unittest-cont1/subdir2/subdir/" ) );
1048 foreach ( $iter as $file ) {
1053 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
1055 foreach ( $files as $file ) { // clean up
1056 $this->backend
->doOperation( array( 'op' => 'delete', 'src' => $file ) );
1058 foreach ( $files as $file ) { // clean up
1059 $this->recursiveClean( FileBackend
::parentStoragePath( $file ) );
1062 $iter = $this->backend
->getFileList( array( 'dir' => "$base/unittest-cont1/not/exists" ) );
1063 foreach ( $iter as $iter ) {} // no errors
1066 private function prepare( array $params ) {
1067 $this->dirsToPrune
[] = $params['dir'];
1068 return $this->backend
->prepare( $params );
1071 function tearDownFiles() {
1072 foreach ( $this->filesToPrune
as $file ) {
1075 $containers = array( 'unittest-cont1', 'unittest-cont2', 'unittest-cont3' );
1076 foreach ( $containers as $container ) {
1077 $this->deleteFiles( $container );
1079 foreach ( $this->dirsToPrune
as $dir ) {
1080 $this->recursiveClean( $dir );
1082 $this->filesToPrune
= $this->dirsToPrune
= array();
1085 private function deleteFiles( $container ) {
1086 $base = $this->baseStorePath();
1087 $iter = $this->backend
->getFileList( array( 'dir' => "$base/$container" ) );
1089 foreach ( $iter as $file ) {
1090 $this->backend
->delete( array( 'src' => "$base/$container/$file" ), array( 'force' => 1 ) );
1095 private function recursiveClean( $dir ) {
1097 if ( !$this->backend
->clean( array( 'dir' => $dir ) )->isOK() ) {
1100 } while ( $dir = FileBackend
::parentStoragePath( $dir ) );
1103 function tearDown() {