6 class FileBackendTest
extends MediaWikiTestCase
{
7 private $backend, $multiBackend;
11 global $wgFileBackends;
13 $tmpDir = wfTempDir() . '/file-backend-test-' . time() . '-' . mt_rand();
14 if ( $this->getCliArg( 'use-filebackend=' ) ) {
15 $name = $this->getCliArg( 'use-filebackend=' );
17 foreach ( $wgFileBackends as $conf ) {
18 if ( $conf['name'] == $name ) {
22 $useConfig['name'] = 'localtesting'; // swap name
23 $this->singleBackend
= new $conf['class']( $useConfig );
25 $this->singleBackend
= new FSFileBackend( array(
26 'name' => 'localtesting',
27 'lockManager' => 'fsLockManager',
28 'containerPaths' => array(
29 'unittest-cont1' => "$tmpDir/localtesting/unittest-cont1",
30 'unittest-cont2' => "$tmpDir/localtesting/unittest-cont2" )
33 $this->multiBackend
= new FileBackendMultiWrite( array(
34 'name' => 'localtesting',
35 'lockManager' => 'fsLockManager',
38 'name' => 'localmutlitesting1',
39 'class' => 'FSFileBackend',
40 'lockManager' => 'nullLockManager',
41 'containerPaths' => array(
42 'unittest-cont1' => "$tmpDir/localtestingmulti1/cont1",
43 'unittest-cont2' => "$tmpDir/localtestingmulti1/unittest-cont2" ),
44 'isMultiMaster' => false
47 'name' => 'localmutlitesting2',
48 'class' => 'FSFileBackend',
49 'lockManager' => 'nullLockManager',
50 'containerPaths' => array(
51 'unittest-cont1' => "$tmpDir/localtestingmulti2/cont1",
52 'unittest-cont2' => "$tmpDir/localtestingmulti2/unittest-cont2" ),
53 'isMultiMaster' => true
57 $this->filesToPrune
= array();
60 private function baseStorePath() {
61 return 'mwstore://localtesting';
64 private function backendClass() {
65 return get_class( $this->backend
);
69 * @dataProvider provider_testStore
71 public function testStore( $op, $source, $dest ) {
72 $this->filesToPrune
[] = $source;
74 $this->backend
= $this->singleBackend
;
75 $this->tearDownFiles();
76 $this->doTestStore( $op, $source, $dest );
77 $this->tearDownFiles();
79 $this->backend
= $this->multiBackend
;
80 $this->tearDownFiles();
81 $this->doTestStore( $op, $source, $dest );
82 $this->tearDownFiles();
85 function doTestStore( $op, $source, $dest ) {
86 $backendName = $this->backendClass();
88 $this->backend
->prepare( array( 'dir' => dirname( $dest ) ) );
90 file_put_contents( $source, "Unit test file" );
91 $status = $this->backend
->doOperation( $op );
93 $this->assertEquals( array(), $status->errors
,
94 "Store from $source to $dest succeeded without warnings ($backendName)." );
95 $this->assertEquals( true, $status->isOK(),
96 "Store from $source to $dest succeeded ($backendName)." );
97 $this->assertEquals( array( 0 => true ), $status->success
,
98 "Store from $source to $dest has proper 'success' field in Status ($backendName)." );
99 $this->assertEquals( true, file_exists( $source ),
100 "Source file $source still exists ($backendName)." );
101 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
102 "Destination file $dest exists ($backendName)." );
104 $this->assertEquals( filesize( $source ),
105 $this->backend
->getFileSize( array( 'src' => $dest ) ),
106 "Destination file $dest has correct size ($backendName)." );
108 $props1 = FSFile
::getPropsFromPath( $source );
109 $props2 = $this->backend
->getFileProps( array( 'src' => $dest ) );
110 $this->assertEquals( $props1, $props2,
111 "Source and destination have the same props ($backendName)." );
114 public function provider_testStore() {
117 $tmpName = TempFSFile
::factory( "unittests_", 'txt' )->getPath();
118 $toPath = $this->baseStorePath() . '/unittest-cont1/fun/obj1.txt';
119 $op = array( 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath );
126 $op['overwrite'] = true;
133 // @TODO: test overwriteSame
139 * @dataProvider provider_testCopy
141 public function testCopy( $op, $source, $dest ) {
142 $this->backend
= $this->singleBackend
;
143 $this->tearDownFiles();
144 $this->doTestCopy( $op, $source, $dest );
145 $this->tearDownFiles();
147 $this->backend
= $this->multiBackend
;
148 $this->tearDownFiles();
149 $this->doTestCopy( $op, $source, $dest );
150 $this->tearDownFiles();
153 function doTestCopy( $op, $source, $dest ) {
154 $backendName = $this->backendClass();
156 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
157 $this->backend
->prepare( array( 'dir' => dirname( $dest ) ) );
159 $status = $this->backend
->doOperation(
160 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
161 $this->assertEquals( true, $status->isOK(),
162 "Creation of file at $source succeeded ($backendName)." );
164 $status = $this->backend
->doOperation( $op );
165 $this->assertEquals( array(), $status->errors
,
166 "Copy from $source to $dest succeeded without warnings ($backendName)." );
167 $this->assertEquals( true, $status->isOK(),
168 "Copy from $source to $dest succeeded ($backendName)." );
169 $this->assertEquals( array( 0 => true ), $status->success
,
170 "Copy from $source to $dest has proper 'success' field in Status ($backendName)." );
171 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $source ) ),
172 "Source file $source still exists ($backendName)." );
173 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
174 "Destination file $dest exists after copy ($backendName)." );
177 $this->backend
->getFileSize( array( 'src' => $source ) ),
178 $this->backend
->getFileSize( array( 'src' => $dest ) ),
179 "Destination file $dest has correct size ($backendName)." );
181 $props1 = $this->backend
->getFileProps( array( 'src' => $source ) );
182 $props2 = $this->backend
->getFileProps( array( 'src' => $dest ) );
183 $this->assertEquals( $props1, $props2,
184 "Source and destination have the same props ($backendName)." );
187 public function provider_testCopy() {
190 $source = $this->baseStorePath() . '/unittest-cont1/file.txt';
191 $dest = $this->baseStorePath() . '/unittest-cont2/fileMoved.txt';
193 $op = array( 'op' => 'copy', 'src' => $source, 'dst' => $dest );
200 $op['overwrite'] = true;
211 * @dataProvider provider_testMove
213 public function testMove( $op, $source, $dest ) {
214 $this->backend
= $this->singleBackend
;
215 $this->tearDownFiles();
216 $this->doTestMove( $op, $source, $dest );
217 $this->tearDownFiles();
219 $this->backend
= $this->multiBackend
;
220 $this->tearDownFiles();
221 $this->doTestMove( $op, $source, $dest );
222 $this->tearDownFiles();
225 private function doTestMove( $op, $source, $dest ) {
226 $backendName = $this->backendClass();
228 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
229 $this->backend
->prepare( array( 'dir' => dirname( $dest ) ) );
231 $status = $this->backend
->doOperation(
232 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
233 $this->assertEquals( true, $status->isOK(),
234 "Creation of file at $source succeeded ($backendName)." );
236 $status = $this->backend
->doOperation( $op );
237 $this->assertEquals( array(), $status->errors
,
238 "Move from $source to $dest succeeded without warnings ($backendName)." );
239 $this->assertEquals( true, $status->isOK(),
240 "Move from $source to $dest succeeded ($backendName)." );
241 $this->assertEquals( array( 0 => true ), $status->success
,
242 "Move from $source to $dest has proper 'success' field in Status ($backendName)." );
243 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $source ) ),
244 "Source file $source does not still exists ($backendName)." );
245 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
246 "Destination file $dest exists after move ($backendName)." );
248 $this->assertNotEquals(
249 $this->backend
->getFileSize( array( 'src' => $source ) ),
250 $this->backend
->getFileSize( array( 'src' => $dest ) ),
251 "Destination file $dest has correct size ($backendName)." );
253 $props1 = $this->backend
->getFileProps( array( 'src' => $source ) );
254 $props2 = $this->backend
->getFileProps( array( 'src' => $dest ) );
255 $this->assertEquals( false, $props1['fileExists'],
256 "Source file does not exist accourding to props ($backendName)." );
257 $this->assertEquals( true, $props2['fileExists'],
258 "Destination file exists accourding to props ($backendName)." );
261 public function provider_testMove() {
264 $source = $this->baseStorePath() . '/unittest-cont1/file.txt';
265 $dest = $this->baseStorePath() . '/unittest-cont2/fileMoved.txt';
267 $op = array( 'op' => 'move', 'src' => $source, 'dst' => $dest );
274 $op['overwrite'] = true;
285 * @dataProvider provider_testDelete
287 public function testDelete( $op, $source, $withSource, $okStatus ) {
288 $this->backend
= $this->singleBackend
;
289 $this->tearDownFiles();
290 $this->doTestDelete( $op, $source, $withSource, $okStatus );
291 $this->tearDownFiles();
293 $this->backend
= $this->multiBackend
;
294 $this->tearDownFiles();
295 $this->doTestDelete( $op, $source, $withSource, $okStatus );
296 $this->tearDownFiles();
299 private function doTestDelete( $op, $source, $withSource, $okStatus ) {
300 $backendName = $this->backendClass();
302 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
305 $status = $this->backend
->doOperation(
306 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
307 $this->assertEquals( true, $status->isOK(),
308 "Creation of file at $source succeeded ($backendName)." );
311 $status = $this->backend
->doOperation( $op );
313 $this->assertEquals( array(), $status->errors
,
314 "Deletion of file at $source succeeded without warnings ($backendName)." );
315 $this->assertEquals( true, $status->isOK(),
316 "Deletion of file at $source succeeded ($backendName)." );
317 $this->assertEquals( array( 0 => true ), $status->success
,
318 "Deletion of file at $source has proper 'success' field in Status ($backendName)." );
320 $this->assertEquals( false, $status->isOK(),
321 "Deletion of file at $source failed ($backendName)." );
324 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $source ) ),
325 "Source file $source does not exist after move ($backendName)." );
328 $this->backend
->getFileSize( array( 'src' => $source ) ),
329 "Source file $source has correct size (false) ($backendName)." );
331 $props1 = $this->backend
->getFileProps( array( 'src' => $source ) );
332 $this->assertFalse( $props1['fileExists'],
333 "Source file $source does not exist according to props ($backendName)." );
336 public function provider_testDelete() {
339 $source = $this->baseStorePath() . '/unittest-cont1/myfacefile.txt';
341 $op = array( 'op' => 'delete', 'src' => $source );
352 false, // without source
356 $op['ignoreMissingSource'] = true;
360 false, // without source
368 * @dataProvider provider_testCreate
370 public function testCreate( $op, $dest, $alreadyExists, $okStatus, $newSize ) {
371 $this->backend
= $this->singleBackend
;
372 $this->tearDownFiles();
373 $this->doTestCreate( $op, $dest, $alreadyExists, $okStatus, $newSize );
374 $this->tearDownFiles();
376 $this->backend
= $this->multiBackend
;
377 $this->tearDownFiles();
378 $this->doTestCreate( $op, $dest, $alreadyExists, $okStatus, $newSize );
379 $this->tearDownFiles();
382 private function doTestCreate( $op, $dest, $alreadyExists, $okStatus, $newSize ) {
383 $backendName = $this->backendClass();
385 $this->backend
->prepare( array( 'dir' => dirname( $dest ) ) );
387 $oldText = 'blah...blah...waahwaah';
388 if ( $alreadyExists ) {
389 $status = $this->backend
->doOperation(
390 array( 'op' => 'create', 'content' => $oldText, 'dst' => $dest ) );
391 $this->assertEquals( true, $status->isOK(),
392 "Creation of file at $dest succeeded ($backendName)." );
395 $status = $this->backend
->doOperation( $op );
397 $this->assertEquals( array(), $status->errors
,
398 "Creation of file at $dest succeeded without warnings ($backendName)." );
399 $this->assertEquals( true, $status->isOK(),
400 "Creation of file at $dest succeeded ($backendName)." );
401 $this->assertEquals( array( 0 => true ), $status->success
,
402 "Creation of file at $dest has proper 'success' field in Status ($backendName)." );
404 $this->assertEquals( false, $status->isOK(),
405 "Creation of file at $dest failed ($backendName)." );
408 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $dest ) ),
409 "Destination file $dest exists after creation ($backendName)." );
411 $props1 = $this->backend
->getFileProps( array( 'src' => $dest ) );
412 $this->assertEquals( true, $props1['fileExists'],
413 "Destination file $dest exists according to props ($backendName)." );
414 if ( $okStatus ) { // file content is what we saved
415 $this->assertEquals( $newSize, $props1['size'],
416 "Destination file $dest has expected size according to props ($backendName)." );
417 $this->assertEquals( $newSize,
418 $this->backend
->getFileSize( array( 'src' => $dest ) ),
419 "Destination file $dest has correct size ($backendName)." );
420 } else { // file content is some other previous text
421 $this->assertEquals( strlen( $oldText ), $props1['size'],
422 "Destination file $dest has original size according to props ($backendName)." );
423 $this->assertEquals( strlen( $oldText ),
424 $this->backend
->getFileSize( array( 'src' => $dest ) ),
425 "Destination file $dest has original size according to props ($backendName)." );
430 * @dataProvider provider_testCreate
432 public function provider_testCreate() {
435 $source = $this->baseStorePath() . '/unittest-cont2/myspacefile.txt';
437 $dummyText = 'hey hey';
438 $op = array( 'op' => 'create', 'content' => $dummyText, 'dst' => $source );
442 false, // no dest already exists
450 true, // dest already exists
455 $op['overwrite'] = true;
459 true, // dest already exists
468 * @dataProvider provider_testConcatenate
470 public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
471 $this->filesToPrune
[] = $op['dst'];
473 $this->backend
= $this->singleBackend
;
474 $this->tearDownFiles();
475 $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus );
476 $this->tearDownFiles();
478 $this->backend
= $this->multiBackend
;
479 $this->tearDownFiles();
480 $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus );
481 $this->tearDownFiles();
484 public function doTestConcatenate( $params, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
485 $backendName = $this->backendClass();
490 foreach ( $srcs as $i => $source ) {
491 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
493 'op' => 'create', // operation
494 'dst' => $source, // source
495 'content' => $srcsContent[$i]
497 $expContent .= $srcsContent[$i];
499 $status = $this->backend
->doOperations( $ops );
501 $this->assertEquals( true, $status->isOK(),
502 "Creation of source files succeeded ($backendName)." );
504 $dest = $params['dst'];
505 if ( $alreadyExists ) {
506 $ok = file_put_contents( $dest, 'blah...blah...waahwaah' ) !== false;
507 $this->assertEquals( true, $ok,
508 "Creation of file at $dest succeeded ($backendName)." );
510 $ok = file_put_contents( $dest, '' ) !== false;
511 $this->assertEquals( true, $ok,
512 "Creation of 0-byte file at $dest succeeded ($backendName)." );
515 // Combine the files into one
516 $status = $this->backend
->concatenate( $params );
518 $this->assertEquals( array(), $status->errors
,
519 "Creation of concat file at $dest succeeded without warnings ($backendName)." );
520 $this->assertEquals( true, $status->isOK(),
521 "Creation of concat file at $dest succeeded ($backendName)." );
523 $this->assertEquals( false, $status->isOK(),
524 "Creation of concat file at $dest failed ($backendName)." );
528 $this->assertEquals( true, is_file( $dest ),
529 "Dest concat file $dest exists after creation ($backendName)." );
531 $this->assertEquals( true, is_file( $dest ),
532 "Dest concat file $dest exists after failed creation ($backendName)." );
535 $contents = file_get_contents( $dest );
536 $this->assertNotEquals( false, $contents, "File at $dest exists ($backendName)." );
539 $this->assertEquals( $expContent, $contents,
540 "Concat file at $dest has correct contents ($backendName)." );
542 $this->assertNotEquals( $expContent, $contents,
543 "Concat file at $dest has correct contents ($backendName)." );
547 function provider_testConcatenate() {
550 $rand = mt_rand( 0, 2000000000 ) . time();
551 $dest = wfTempDir() . "/randomfile!$rand.txt";
553 $this->baseStorePath() . '/unittest-cont1/file1.txt',
554 $this->baseStorePath() . '/unittest-cont1/file2.txt',
555 $this->baseStorePath() . '/unittest-cont1/file3.txt',
556 $this->baseStorePath() . '/unittest-cont1/file4.txt',
557 $this->baseStorePath() . '/unittest-cont1/file5.txt',
558 $this->baseStorePath() . '/unittest-cont1/file6.txt',
559 $this->baseStorePath() . '/unittest-cont1/file7.txt',
560 $this->baseStorePath() . '/unittest-cont1/file8.txt',
561 $this->baseStorePath() . '/unittest-cont1/file9.txt',
562 $this->baseStorePath() . '/unittest-cont1/file10.txt'
576 $params = array( 'srcs' => $srcs, 'dst' => $dest );
579 $params, // operation
581 $content, // content for each source
582 false, // no dest already exists
587 $params, // operation
589 $content, // content for each source
590 true, // dest already exists
598 * @dataProvider provider_testGetFileContents
600 public function testGetFileContents( $src, $content ) {
601 $this->backend
= $this->singleBackend
;
602 $this->tearDownFiles();
603 $this->doTestGetFileContents( $src, $content );
604 $this->tearDownFiles();
606 $this->backend
= $this->multiBackend
;
607 $this->tearDownFiles();
608 $this->doTestGetFileContents( $src, $content );
609 $this->tearDownFiles();
613 * @dataProvider provider_testGetFileContents
615 public function doTestGetFileContents( $source, $content ) {
616 $backendName = $this->backendClass();
618 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
620 $status = $this->backend
->doOperation(
621 array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
622 $this->assertEquals( array(), $status->errors
,
623 "Creation of file at $source succeeded ($backendName)." );
624 $this->assertEquals( true, $status->isOK(),
625 "Creation of file at $source succeeded with OK status ($backendName)." );
627 $newContents = $this->backend
->getFileContents( array( 'src' => $source ) );
628 $this->assertNotEquals( false, $newContents,
629 "Read of file at $source succeeded ($backendName)." );
631 $this->assertEquals( $content, $newContents,
632 "Contents read match data at $source ($backendName)." );
635 function provider_testGetFileContents() {
638 $base = $this->baseStorePath();
639 $cases[] = array( "$base/unittest-cont1/b/z/some_file.txt", "some file contents" );
640 $cases[] = array( "$base/unittest-cont1/b/some-other_file.txt", "more file contents" );
646 * @dataProvider provider_testGetLocalCopy
648 public function testGetLocalCopy( $src, $content ) {
649 $this->backend
= $this->singleBackend
;
650 $this->tearDownFiles();
651 $this->doTestGetLocalCopy( $src, $content );
652 $this->tearDownFiles();
654 $this->backend
= $this->multiBackend
;
655 $this->tearDownFiles();
656 $this->doTestGetLocalCopy( $src, $content );
657 $this->tearDownFiles();
660 public function doTestGetLocalCopy( $source, $content ) {
661 $backendName = $this->backendClass();
663 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
665 $status = $this->backend
->doOperation(
666 array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
667 $this->assertEquals( true, $status->isOK(),
668 "Creation of file at $source succeeded ($backendName)." );
670 $tmpFile = $this->backend
->getLocalCopy( array( 'src' => $source ) );
671 $this->assertNotNull( $tmpFile,
672 "Creation of local copy of $source succeeded ($backendName)." );
674 $contents = file_get_contents( $tmpFile->getPath() );
675 $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." );
678 function provider_testGetLocalCopy() {
681 $base = $this->baseStorePath();
682 $cases[] = array( "$base/unittest-cont1/a/z/some_file.txt", "some file contents" );
683 $cases[] = array( "$base/unittest-cont1/a/some-other_file.txt", "more file contents" );
689 * @dataProvider provider_testGetLocalReference
691 public function testGetLocalReference( $src, $content ) {
692 $this->backend
= $this->singleBackend
;
693 $this->tearDownFiles();
694 $this->doTestGetLocalReference( $src, $content );
695 $this->tearDownFiles();
697 $this->backend
= $this->multiBackend
;
698 $this->tearDownFiles();
699 $this->doTestGetLocalReference( $src, $content );
700 $this->tearDownFiles();
703 private function doTestGetLocalReference( $source, $content ) {
704 $backendName = $this->backendClass();
706 $this->backend
->prepare( array( 'dir' => dirname( $source ) ) );
708 $status = $this->backend
->doOperation(
709 array( 'op' => 'create', 'content' => $content, 'dst' => $source ) );
710 $this->assertEquals( true, $status->isOK(),
711 "Creation of file at $source succeeded ($backendName)." );
713 $tmpFile = $this->backend
->getLocalReference( array( 'src' => $source ) );
714 $this->assertNotNull( $tmpFile,
715 "Creation of local copy of $source succeeded ($backendName)." );
717 $contents = file_get_contents( $tmpFile->getPath() );
718 $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." );
721 function provider_testGetLocalReference() {
724 $base = $this->baseStorePath();
725 $cases[] = array( "$base/unittest-cont1/a/z/some_file.txt", "some file contents" );
726 $cases[] = array( "$base/unittest-cont1/a/some-other_file.txt", "more file contents" );
732 * @dataProvider provider_testPrepareAndClean
734 public function testPrepareAndClean( $path, $isOK ) {
735 $this->backend
= $this->singleBackend
;
736 $this->doTestPrepareAndClean( $path, $isOK );
738 $this->backend
= $this->multiBackend
;
739 $this->doTestPrepareAndClean( $path, $isOK );
742 function provider_testPrepareAndClean() {
743 $base = $this->baseStorePath();
745 array( "$base/unittest-cont1/a/z/some_file1.txt", true ),
746 array( "$base/unittest-cont2/a/z/some_file2.txt", true ),
747 # Specific to FS backend with no basePath field set
748 #array( "$base/unittest-cont3/a/z/some_file3.txt", false ),
752 function doTestPrepareAndClean( $path, $isOK ) {
753 $backendName = $this->backendClass();
755 $status = $this->backend
->prepare( array( 'dir' => $path ) );
757 $this->assertEquals( array(), $status->errors
,
758 "Preparing dir $path succeeded without warnings ($backendName)." );
759 $this->assertEquals( true, $status->isOK(),
760 "Preparing dir $path succeeded ($backendName)." );
762 $this->assertEquals( false, $status->isOK(),
763 "Preparing dir $path failed ($backendName)." );
766 $status = $this->backend
->clean( array( 'dir' => $path ) );
768 $this->assertEquals( array(), $status->errors
,
769 "Cleaning dir $path succeeded without warnings ($backendName)." );
770 $this->assertEquals( true, $status->isOK(),
771 "Cleaning dir $path succeeded ($backendName)." );
773 $this->assertEquals( false, $status->isOK(),
774 "Cleaning dir $path failed ($backendName)." );
780 public function testDoOperations() {
781 $this->backend
= $this->singleBackend
;
782 $this->doTestDoOperations();
784 $this->backend
= $this->multiBackend
;
785 $this->doTestDoOperations();
788 function doTestDoOperations() {
789 $base = $this->baseStorePath();
791 $fileA = "$base/unittest-cont1/a/b/fileA.txt";
792 $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq';
793 $fileB = "$base/unittest-cont1/a/b/fileB.txt";
794 $fileBContents = 'g-jmq3gpqgt3qtg q3GT ';
795 $fileC = "$base/unittest-cont1/a/b/fileC.txt";
796 $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag';
797 $fileD = "$base/unittest-cont1/a/b/fileD.txt";
799 $this->backend
->prepare( array( 'dir' => dirname( $fileA ) ) );
800 $this->backend
->create( array( 'dst' => $fileA, 'content' => $fileAContents ) );
801 $this->backend
->prepare( array( 'dir' => dirname( $fileB ) ) );
802 $this->backend
->create( array( 'dst' => $fileB, 'content' => $fileBContents ) );
803 $this->backend
->prepare( array( 'dir' => dirname( $fileC ) ) );
804 $this->backend
->create( array( 'dst' => $fileC, 'content' => $fileCContents ) );
806 $status = $this->backend
->doOperations( array(
807 array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ),
808 // Now: A:<A>, B:<B>, C:<A>, D:<D> (file:<orginal contents>)
809 array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ),
810 // Now: A:<A>, B:<B>, C:<A>, D:<D>
811 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD, 'overwrite' => 1 ),
812 // Now: A:<A>, B:<B>, C:<empty>, D:<A>
813 array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC ),
814 // Now: A:<A>, B:<empty>, C:<B>, D:<A>
815 array( 'op' => 'move', 'src' => $fileD, 'dst' => $fileA, 'overwriteSame' => 1 ),
816 // Now: A:<A>, B:<empty>, C:<B>, D:<empty>
817 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileA, 'overwrite' => 1 ),
818 // Now: A:<B>, B:<empty>, C:<empty>, D:<empty>
819 array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC ),
820 // Now: A:<B>, B:<empty>, C:<B>, D:<empty>
821 array( 'op' => 'move', 'src' => $fileA, 'dst' => $fileC, 'overwriteSame' => 1 ),
822 // Now: A:<empty>, B:<empty>, C:<B>, D:<empty>
823 array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ),
825 array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ),
827 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ),
829 array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ),
833 $this->assertEquals( array(), $status->errors
, "Operation batch succeeded" );
834 $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" );
835 $this->assertEquals( 12, count( $status->success
),
836 "Operation batch has correct success array" );
838 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $fileA ) ),
839 "File does not exist at $fileA" );
840 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $fileB ) ),
841 "File does not exist at $fileB" );
842 $this->assertEquals( false, $this->backend
->fileExists( array( 'src' => $fileD ) ),
843 "File does not exist at $fileD" );
845 $this->assertEquals( true, $this->backend
->fileExists( array( 'src' => $fileC ) ),
846 "File exists at $fileC" );
847 $this->assertEquals( $fileBContents,
848 $this->backend
->getFileContents( array( 'src' => $fileC ) ),
849 "Correct file contents of $fileC" );
850 $this->assertEquals( strlen( $fileBContents ),
851 $this->backend
->getFileSize( array( 'src' => $fileC ) ),
852 "Correct file size of $fileC" );
853 $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ),
854 $this->backend
->getFileSha1Base36( array( 'src' => $fileC ) ),
855 "Correct file SHA-1 of $fileC" );
857 // @TODO: test some cases where the ops should fail
860 public function testGetFileList() {
861 $this->backend
= $this->singleBackend
;
862 $this->tearDownFiles();
863 $this->doTestGetFileList();
864 $this->tearDownFiles();
866 $this->backend
= $this->multiBackend
;
867 $this->tearDownFiles();
868 $this->doTestGetFileList();
869 $this->tearDownFiles();
872 private function doTestGetFileList() {
873 $backendName = $this->backendClass();
875 $base = $this->baseStorePath();
877 "$base/unittest-cont1/test1.txt",
878 "$base/unittest-cont1/test2.txt",
879 "$base/unittest-cont1/test3.txt",
880 "$base/unittest-cont1/subdir1/test1.txt",
881 "$base/unittest-cont1/subdir1/test2.txt",
882 "$base/unittest-cont1/subdir2/test3.txt",
883 "$base/unittest-cont1/subdir2/test4.txt",
884 "$base/unittest-cont1/subdir2/subdir/test1.txt",
885 "$base/unittest-cont1/subdir2/subdir/test2.txt",
886 "$base/unittest-cont1/subdir2/subdir/test3.txt",
887 "$base/unittest-cont1/subdir2/subdir/test4.txt",
888 "$base/unittest-cont1/subdir2/subdir/test5.txt",
889 "$base/unittest-cont1/subdir2/subdir/sub/test0.txt",
890 "$base/unittest-cont1/subdir2/subdir/sub/120-px-file.txt",
895 foreach ( $files as $file ) {
896 $ops[] = array( 'op' => 'create', 'content' => 'xxy', 'dst' => $file );
897 $this->backend
->prepare( array( 'dir' => dirname( $file ) ) );
899 $status = $this->backend
->doOperations( $ops );
900 $this->assertEquals( array(), $status->errors
,
901 "Creation of files succeeded ($backendName)." );
902 $this->assertEquals( true, $status->isOK(),
903 "Creation of files succeeded with OK status ($backendName)." );
914 "subdir2/subdir/test1.txt",
915 "subdir2/subdir/test2.txt",
916 "subdir2/subdir/test3.txt",
917 "subdir2/subdir/test4.txt",
918 "subdir2/subdir/test5.txt",
919 "subdir2/subdir/sub/test0.txt",
920 "subdir2/subdir/sub/120-px-file.txt",
924 // Actual listing (no trailing slash)
926 $iter = $this->backend
->getFileList( array( 'dir' => "$base/unittest-cont1" ) );
927 foreach ( $iter as $file ) {
932 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
934 // Actual listing (with trailing slash)
936 $iter = $this->backend
->getFileList( array( 'dir' => "$base/unittest-cont1/" ) );
937 foreach ( $iter as $file ) {
942 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
952 "sub/120-px-file.txt",
956 // Actual listing (no trailing slash)
958 $iter = $this->backend
->getFileList( array( 'dir' => "$base/unittest-cont1/subdir2/subdir" ) );
959 foreach ( $iter as $file ) {
964 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
966 // Actual listing (with trailing slash)
968 $iter = $this->backend
->getFileList( array( 'dir' => "$base/unittest-cont1/subdir2/subdir/" ) );
969 foreach ( $iter as $file ) {
974 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
976 foreach ( $files as $file ) {
977 $this->backend
->doOperation( array( 'op' => 'delete', 'src' => "$base/$file" ) );
980 $iter = $this->backend
->getFileList( array( 'dir' => "$base/unittest-cont1/not/exists" ) );
981 foreach ( $iter as $iter ) {} // no errors
984 function tearDownFiles() {
985 foreach ( $this->filesToPrune
as $file ) {
988 $containers = array( 'unittest-cont1', 'unittest-cont2', 'unittest-cont3' );
989 foreach ( $containers as $container ) {
990 $this->deleteFiles( $this->backend
, $container );
994 private function deleteFiles( $backend, $container ) {
995 $base = $this->baseStorePath();
996 $iter = $backend->getFileList( array( 'dir' => "$base/$container" ) );
998 foreach ( $iter as $file ) {
999 $backend->doOperation( array( 'op' => 'delete', 'src' => "$base/$container/$file" ) );
1001 while ( $tmp = FileBackend
::parentStoragePath( $tmp ) ) {
1002 $backend->clean( array( 'dir' => $tmp ) );
1008 function tearDown() {