22 if ( $this->
getCliArg(
'use-filebackend' ) ) {
23 if ( self::$backendToUse ) {
24 $this->singleBackend = self::$backendToUse;
28 foreach ( $wgFileBackends
as $conf ) {
29 if ( $conf[
'name'] ==
$name ) {
34 $useConfig[
'name'] =
'localtesting';
35 $useConfig[
'shardViaHashLevels'] = [
36 'unittest-cont1' => [
'levels' => 1,
'base' => 16,
'repeat' => 1 ]
38 if ( isset( $useConfig[
'fileJournal'] ) ) {
42 $class = $useConfig[
'class'];
43 self::$backendToUse =
new $class( $useConfig );
44 $this->singleBackend = self::$backendToUse;
48 'name' =>
'localtesting',
52 'unittest-cont1' =>
"{$tmpDir}/localtesting-cont1",
53 'unittest-cont2' =>
"{$tmpDir}/localtesting-cont2" ]
57 'name' =>
'localtesting',
59 'parallelize' =>
'implicit',
63 'name' =>
'localmultitesting1',
64 'class' =>
'FSFileBackend',
66 'unittest-cont1' =>
"{$tmpDir}/localtestingmulti1-cont1",
67 'unittest-cont2' =>
"{$tmpDir}/localtestingmulti1-cont2" ],
68 'isMultiMaster' =>
false
71 'name' =>
'localmultitesting2',
72 'class' =>
'FSFileBackend',
74 'unittest-cont1' =>
"{$tmpDir}/localtestingmulti2-cont1",
75 'unittest-cont2' =>
"{$tmpDir}/localtestingmulti2-cont2" ],
76 'isMultiMaster' =>
true
83 return 'mwstore://localtesting';
87 return get_class( $this->backend );
96 "FileBackend::isStoragePath on path '$path'" );
101 [
'mwstore://',
true ],
102 [
'mwstore://backend',
true ],
103 [
'mwstore://backend/container',
true ],
104 [
'mwstore://backend/container/',
true ],
105 [
'mwstore://backend/container/path',
true ],
106 [
'mwstore://backend//container/',
true ],
107 [
'mwstore://backend//container//',
true ],
108 [
'mwstore://backend//container//path',
true ],
109 [
'mwstore:///',
true ],
110 [
'mwstore:/',
false ],
111 [
'mwstore:',
false ],
121 "FileBackend::splitStoragePath on path '$path'" );
126 [
'mwstore://backend/container', [
'backend',
'container',
'' ] ],
127 [
'mwstore://backend/container/', [
'backend',
'container',
'' ] ],
128 [
'mwstore://backend/container/path', [
'backend',
'container',
'path' ] ],
129 [
'mwstore://backend/container//path', [
'backend',
'container',
'/path' ] ],
130 [
'mwstore://backend//container/path', [ null, null, null ] ],
131 [
'mwstore://backend//container//path', [ null, null, null ] ],
132 [
'mwstore://', [ null, null, null ] ],
133 [
'mwstore://backend', [ null, null, null ] ],
134 [
'mwstore:///', [ null, null, null ] ],
135 [
'mwstore:/', [ null, null, null ] ],
136 [
'mwstore:', [ null, null, null ] ]
146 "FileBackend::normalizeStoragePath on path '$path'" );
151 [
'mwstore://backend/container',
'mwstore://backend/container' ],
152 [
'mwstore://backend/container/',
'mwstore://backend/container' ],
153 [
'mwstore://backend/container/path',
'mwstore://backend/container/path' ],
154 [
'mwstore://backend/container//path',
'mwstore://backend/container/path' ],
155 [
'mwstore://backend/container///path',
'mwstore://backend/container/path' ],
157 'mwstore://backend/container///path//to///obj',
158 'mwstore://backend/container/path/to/obj'
160 [
'mwstore://', null ],
161 [
'mwstore://backend', null ],
162 [
'mwstore://backend//container/path', null ],
163 [
'mwstore://backend//container//path', null ],
164 [
'mwstore:///', null ],
165 [
'mwstore:/', null ],
166 [
'mwstore:', null ],
176 "FileBackend::parentStoragePath on path '$path'" );
181 [
'mwstore://backend/container/path/to/obj',
'mwstore://backend/container/path/to' ],
182 [
'mwstore://backend/container/path/to',
'mwstore://backend/container/path' ],
183 [
'mwstore://backend/container/path',
'mwstore://backend/container' ],
184 [
'mwstore://backend/container', null ],
185 [
'mwstore://backend/container/path/to/obj/',
'mwstore://backend/container/path/to' ],
186 [
'mwstore://backend/container/path/to/',
'mwstore://backend/container/path' ],
187 [
'mwstore://backend/container/path/',
'mwstore://backend/container' ],
188 [
'mwstore://backend/container/', null ],
198 "FileBackend::extensionFromPath on path '$path'" );
203 [
'mwstore://backend/container/path.txt',
'txt' ],
204 [
'mwstore://backend/container/path.svg.png',
'png' ],
205 [
'mwstore://backend/container/path',
'' ],
206 [
'mwstore://backend/container/path.',
'' ],
235 $this->
prepare( [
'dir' => dirname( $dest ) ] );
237 file_put_contents(
$source,
"Unit test file" );
239 if ( isset( $op[
'overwrite'] ) || isset( $op[
'overwriteSame'] ) ) {
240 $this->backend->store( $op );
243 $status = $this->backend->doOperation( $op );
246 "Store from $source to $dest succeeded without warnings ($backendName)." );
247 $this->assertEquals(
true,
$status->isOK(),
248 "Store from $source to $dest succeeded ($backendName)." );
249 $this->assertEquals( [ 0 =>
true ],
$status->success,
250 "Store from $source to $dest has proper 'success' field in Status ($backendName)." );
251 $this->assertEquals(
true, file_exists(
$source ),
252 "Source file $source still exists ($backendName)." );
253 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $dest ] ),
254 "Destination file $dest exists ($backendName)." );
256 $this->assertEquals( filesize(
$source ),
257 $this->backend->getFileSize( [
'src' => $dest ] ),
258 "Destination file $dest has correct size ($backendName)." );
261 $props2 = $this->backend->getFileProps( [
'src' => $dest ] );
262 $this->assertEquals( $props1, $props2,
263 "Source and destination have the same props ($backendName)." );
272 $toPath = self::baseStorePath() .
'/unittest-cont1/e/fun/obj1.txt';
273 $op = [
'op' =>
'store',
'src' => $tmpName,
'dst' => $toPath ];
277 $op2[
'overwrite'] =
true;
281 $op3[
'overwriteSame'] =
true;
309 $this->
prepare( [
'dir' => dirname( $dest ) ] );
311 if ( isset( $op[
'ignoreMissingSource'] ) ) {
312 $status = $this->backend->doOperation( $op );
314 "Move from $source to $dest succeeded without warnings ($backendName)." );
315 $this->assertEquals( [ 0 =>
true ],
$status->success,
316 "Move from $source to $dest has proper 'success' field in Status ($backendName)." );
317 $this->assertEquals(
false, $this->backend->fileExists( [
'src' =>
$source ] ),
318 "Source file $source does not exist ($backendName)." );
319 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $dest ] ),
320 "Destination file $dest does not exist ($backendName)." );
325 $status = $this->backend->doOperation(
326 [
'op' =>
'create',
'content' =>
'blahblah',
'dst' =>
$source ] );
328 "Creation of file at $source succeeded ($backendName)." );
330 if ( isset( $op[
'overwrite'] ) || isset( $op[
'overwriteSame'] ) ) {
331 $this->backend->copy( $op );
334 $status = $this->backend->doOperation( $op );
337 "Copy from $source to $dest succeeded without warnings ($backendName)." );
338 $this->assertEquals(
true,
$status->isOK(),
339 "Copy from $source to $dest succeeded ($backendName)." );
340 $this->assertEquals( [ 0 =>
true ],
$status->success,
341 "Copy from $source to $dest has proper 'success' field in Status ($backendName)." );
342 $this->assertEquals(
true, $this->backend->fileExists( [
'src' =>
$source ] ),
343 "Source file $source still exists ($backendName)." );
344 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $dest ] ),
345 "Destination file $dest exists after copy ($backendName)." );
348 $this->backend->getFileSize( [
'src' =>
$source ] ),
349 $this->backend->getFileSize( [
'src' => $dest ] ),
350 "Destination file $dest has correct size ($backendName)." );
352 $props1 = $this->backend->getFileProps( [
'src' =>
$source ] );
353 $props2 = $this->backend->getFileProps( [
'src' => $dest ] );
354 $this->assertEquals( $props1, $props2,
355 "Source and destination have the same props ($backendName)." );
363 $source = self::baseStorePath() .
'/unittest-cont1/e/file.txt';
364 $dest = self::baseStorePath() .
'/unittest-cont2/a/fileMoved.txt';
366 $op = [
'op' =>
'copy',
'src' =>
$source,
'dst' => $dest ];
374 $op2[
'overwrite'] =
true;
382 $op2[
'overwriteSame'] =
true;
390 $op2[
'ignoreMissingSource'] =
true;
398 $op2[
'ignoreMissingSource'] =
true;
401 self::baseStorePath() .
'/unittest-cont-bad/e/file.txt',
430 $this->
prepare( [
'dir' => dirname( $dest ) ] );
432 if ( isset( $op[
'ignoreMissingSource'] ) ) {
433 $status = $this->backend->doOperation( $op );
435 "Move from $source to $dest succeeded without warnings ($backendName)." );
436 $this->assertEquals( [ 0 =>
true ],
$status->success,
437 "Move from $source to $dest has proper 'success' field in Status ($backendName)." );
438 $this->assertEquals(
false, $this->backend->fileExists( [
'src' =>
$source ] ),
439 "Source file $source does not exist ($backendName)." );
440 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $dest ] ),
441 "Destination file $dest does not exist ($backendName)." );
446 $status = $this->backend->doOperation(
447 [
'op' =>
'create',
'content' =>
'blahblah',
'dst' =>
$source ] );
449 "Creation of file at $source succeeded ($backendName)." );
451 if ( isset( $op[
'overwrite'] ) || isset( $op[
'overwriteSame'] ) ) {
452 $this->backend->copy( $op );
455 $status = $this->backend->doOperation( $op );
457 "Move from $source to $dest succeeded without warnings ($backendName)." );
458 $this->assertEquals(
true,
$status->isOK(),
459 "Move from $source to $dest succeeded ($backendName)." );
460 $this->assertEquals( [ 0 =>
true ],
$status->success,
461 "Move from $source to $dest has proper 'success' field in Status ($backendName)." );
462 $this->assertEquals(
false, $this->backend->fileExists( [
'src' =>
$source ] ),
463 "Source file $source does not still exists ($backendName)." );
464 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $dest ] ),
465 "Destination file $dest exists after move ($backendName)." );
467 $this->assertNotEquals(
468 $this->backend->getFileSize( [
'src' =>
$source ] ),
469 $this->backend->getFileSize( [
'src' => $dest ] ),
470 "Destination file $dest has correct size ($backendName)." );
472 $props1 = $this->backend->getFileProps( [
'src' =>
$source ] );
473 $props2 = $this->backend->getFileProps( [
'src' => $dest ] );
474 $this->assertEquals(
false, $props1[
'fileExists'],
475 "Source file does not exist accourding to props ($backendName)." );
476 $this->assertEquals(
true, $props2[
'fileExists'],
477 "Destination file exists accourding to props ($backendName)." );
485 $source = self::baseStorePath() .
'/unittest-cont1/e/file.txt';
486 $dest = self::baseStorePath() .
'/unittest-cont2/a/fileMoved.txt';
488 $op = [
'op' =>
'move',
'src' =>
$source,
'dst' => $dest ];
496 $op2[
'overwrite'] =
true;
504 $op2[
'overwriteSame'] =
true;
512 $op2[
'ignoreMissingSource'] =
true;
520 $op2[
'ignoreMissingSource'] =
true;
523 self::baseStorePath() .
'/unittest-cont-bad/e/file.txt',
553 $status = $this->backend->doOperation(
554 [
'op' =>
'create',
'content' =>
'blahblah',
'dst' =>
$source ] );
556 "Creation of file at $source succeeded ($backendName)." );
559 $status = $this->backend->doOperation( $op );
562 "Deletion of file at $source succeeded without warnings ($backendName)." );
563 $this->assertEquals(
true,
$status->isOK(),
564 "Deletion of file at $source succeeded ($backendName)." );
565 $this->assertEquals( [ 0 =>
true ],
$status->success,
566 "Deletion of file at $source has proper 'success' field in Status ($backendName)." );
568 $this->assertEquals(
false,
$status->isOK(),
569 "Deletion of file at $source failed ($backendName)." );
572 $this->assertEquals(
false, $this->backend->fileExists( [
'src' =>
$source ] ),
573 "Source file $source does not exist after move ($backendName)." );
576 $this->backend->getFileSize( [
'src' =>
$source ] ),
577 "Source file $source has correct size (false) ($backendName)." );
579 $props1 = $this->backend->getFileProps( [
'src' =>
$source ] );
580 $this->assertFalse( $props1[
'fileExists'],
581 "Source file $source does not exist according to props ($backendName)." );
589 $source = self::baseStorePath() .
'/unittest-cont1/e/myfacefile.txt';
591 $op = [
'op' =>
'delete',
'src' =>
$source ];
604 $op[
'ignoreMissingSource'] =
true;
611 $op[
'ignoreMissingSource'] =
true;
612 $op[
'src'] = self::baseStorePath() .
'/unittest-cont-bad/e/file.txt';
645 $status = $this->backend->doOperation(
646 [
'op' =>
'create',
'content' =>
'blahblah',
'dst' =>
$source,
647 'headers' => [
'Content-Disposition' =>
'xxx' ] ] );
649 "Creation of file at $source succeeded ($backendName)." );
651 $attr = $this->backend->getFileXAttributes( [
'src' =>
$source ] );
656 'headers' => [
'Content-Disposition' =>
'' ] ] );
658 "Removal of header for $source succeeded ($backendName)." );
661 $attr = $this->backend->getFileXAttributes( [
'src' =>
$source ] );
662 $this->assertFalse( isset( $attr[
'headers'][
'content-disposition'] ),
663 "File 'Content-Disposition' header removed." );
667 $status = $this->backend->doOperation( $op );
670 "Describe of file at $source succeeded without warnings ($backendName)." );
671 $this->assertEquals(
true,
$status->isOK(),
672 "Describe of file at $source succeeded ($backendName)." );
673 $this->assertEquals( [ 0 =>
true ],
$status->success,
674 "Describe of file at $source has proper 'success' field in Status ($backendName)." );
676 $attr = $this->backend->getFileXAttributes( [
'src' =>
$source ] );
680 $this->assertEquals(
false,
$status->isOK(),
681 "Describe of file at $source failed ($backendName)." );
688 foreach ( $headers
as $n => $v ) {
690 $this->assertTrue( isset( $attr[
'headers'][strtolower( $n )] ),
691 "File has '$n' header." );
692 $this->assertEquals( $v, $attr[
'headers'][strtolower( $n )],
693 "File has '$n' header value." );
695 $this->assertFalse( isset( $attr[
'headers'][strtolower( $n )] ),
696 "File does not have '$n' header." );
704 $source = self::baseStorePath() .
'/unittest-cont1/e/myfacefile.txt';
706 $op = [
'op' =>
'describe',
'src' =>
$source,
707 'headers' => [
'Content-Disposition' =>
'inline' ], ];
727 public function testCreate( $op, $alreadyExists, $okStatus, $newSize ) {
730 $this->
doTestCreate( $op, $alreadyExists, $okStatus, $newSize );
735 $this->
doTestCreate( $op, $alreadyExists, $okStatus, $newSize );
739 private function doTestCreate( $op, $alreadyExists, $okStatus, $newSize ) {
743 $this->
prepare( [
'dir' => dirname( $dest ) ] );
745 $oldText =
'blah...blah...waahwaah';
746 if ( $alreadyExists ) {
747 $status = $this->backend->doOperation(
748 [
'op' =>
'create',
'content' => $oldText,
'dst' => $dest ] );
750 "Creation of file at $dest succeeded ($backendName)." );
753 $status = $this->backend->doOperation( $op );
756 "Creation of file at $dest succeeded without warnings ($backendName)." );
757 $this->assertEquals(
true,
$status->isOK(),
758 "Creation of file at $dest succeeded ($backendName)." );
759 $this->assertEquals( [ 0 =>
true ],
$status->success,
760 "Creation of file at $dest has proper 'success' field in Status ($backendName)." );
762 $this->assertEquals(
false,
$status->isOK(),
763 "Creation of file at $dest failed ($backendName)." );
766 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $dest ] ),
767 "Destination file $dest exists after creation ($backendName)." );
769 $props1 = $this->backend->getFileProps( [
'src' => $dest ] );
770 $this->assertEquals(
true, $props1[
'fileExists'],
771 "Destination file $dest exists according to props ($backendName)." );
773 $this->assertEquals( $newSize, $props1[
'size'],
774 "Destination file $dest has expected size according to props ($backendName)." );
775 $this->assertEquals( $newSize,
776 $this->backend->getFileSize( [
'src' => $dest ] ),
777 "Destination file $dest has correct size ($backendName)." );
779 $this->assertEquals( strlen( $oldText ), $props1[
'size'],
780 "Destination file $dest has original size according to props ($backendName)." );
781 $this->assertEquals( strlen( $oldText ),
782 $this->backend->getFileSize( [
'src' => $dest ] ),
783 "Destination file $dest has original size according to props ($backendName)." );
795 $dest = self::baseStorePath() .
'/unittest-cont2/a/myspacefile.txt';
797 $op = [
'op' =>
'create',
'content' =>
'test test testing',
'dst' => $dest ];
802 strlen( $op[
'content'] )
806 $op2[
'content'] =
"\n";
811 strlen( $op2[
'content'] )
815 $op2[
'content'] =
"fsf\n waf 3kt";
820 strlen( $op2[
'content'] )
824 $op2[
'content'] =
"egm'g gkpe gpqg eqwgwqg";
825 $op2[
'overwrite'] =
true;
830 strlen( $op2[
'content'] )
834 $op2[
'content'] =
"39qjmg3-qg";
835 $op2[
'overwriteSame'] =
true;
840 strlen( $op2[
'content'] )
862 $base = self::baseStorePath();
864 "$base/unittest-cont1/e/fileA.a",
865 "$base/unittest-cont1/e/fileB.a",
866 "$base/unittest-cont1/e/fileC.a"
873 "Preparing $path succeeded without warnings ($backendName)." );
874 $createOps[] = [
'op' =>
'create',
'dst' =>
$path,
'content' => mt_rand( 0, 50000 ) ];
875 $copyOps[] = [
'op' =>
'copy',
'src' =>
$path,
'dst' =>
"$path-2" ];
876 $moveOps[] = [
'op' =>
'move',
'src' =>
"$path-2",
'dst' =>
"$path-3" ];
877 $purgeOps[] = [
'op' =>
'delete',
'src' =>
$path ];
878 $purgeOps[] = [
'op' =>
'delete',
'src' =>
"$path-3" ];
880 $purgeOps[] = [
'op' =>
'null' ];
883 $this->backend->doQuickOperations( $createOps ),
884 "Creation of source files succeeded ($backendName)." );
886 $this->assertTrue( $this->backend->fileExists( [
'src' => $file ] ),
887 "File $file exists." );
891 $this->backend->doQuickOperations( $copyOps ),
892 "Quick copy of source files succeeded ($backendName)." );
894 $this->assertTrue( $this->backend->fileExists( [
'src' =>
"$file-2" ] ),
895 "File $file-2 exists." );
899 $this->backend->doQuickOperations( $moveOps ),
900 "Quick move of source files succeeded ($backendName)." );
902 $this->assertTrue( $this->backend->fileExists( [
'src' =>
"$file-3" ] ),
903 "File $file-3 move in." );
904 $this->assertFalse( $this->backend->fileExists( [
'src' =>
"$file-2" ] ),
905 "File $file-2 moved away." );
909 $this->backend->quickCopy( [
'src' =>
$files[0],
'dst' =>
$files[0] ] ),
910 "Copy of file {$files[0]} over itself succeeded ($backendName)." );
911 $this->assertTrue( $this->backend->fileExists( [
'src' =>
$files[0] ] ),
912 "File {$files[0]} still exists." );
915 $this->backend->quickMove( [
'src' =>
$files[0],
'dst' =>
$files[0] ] ),
916 "Move of file {$files[0]} over itself succeeded ($backendName)." );
917 $this->assertTrue( $this->backend->fileExists( [
'src' =>
$files[0] ] ),
918 "File {$files[0]} still exists." );
921 $this->backend->doQuickOperations( $purgeOps ),
922 "Quick deletion of source files succeeded ($backendName)." );
924 $this->assertFalse( $this->backend->fileExists( [
'src' => $file ] ),
925 "File $file purged." );
926 $this->assertFalse( $this->backend->fileExists( [
'src' =>
"$file-3" ] ),
927 "File $file-3 purged." );
934 public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
957 'content' => $srcsContent[$i]
959 $expContent .= $srcsContent[$i];
961 $status = $this->backend->doOperations( $ops );
964 "Creation of source files succeeded ($backendName)." );
967 if ( $alreadyExists ) {
968 $ok = file_put_contents( $dest,
'blah...blah...waahwaah' ) !==
false;
969 $this->assertEquals(
true, $ok,
970 "Creation of file at $dest succeeded ($backendName)." );
972 $ok = file_put_contents( $dest,
'' ) !==
false;
973 $this->assertEquals(
true, $ok,
974 "Creation of 0-byte file at $dest succeeded ($backendName)." );
981 "Creation of concat file at $dest succeeded without warnings ($backendName)." );
982 $this->assertEquals(
true,
$status->isOK(),
983 "Creation of concat file at $dest succeeded ($backendName)." );
985 $this->assertEquals(
false,
$status->isOK(),
986 "Creation of concat file at $dest failed ($backendName)." );
990 $this->assertEquals(
true, is_file( $dest ),
991 "Dest concat file $dest exists after creation ($backendName)." );
993 $this->assertEquals(
true, is_file( $dest ),
994 "Dest concat file $dest exists after failed creation ($backendName)." );
997 $contents = file_get_contents( $dest );
998 $this->assertNotEquals(
false, $contents,
"File at $dest exists ($backendName)." );
1001 $this->assertEquals( $expContent, $contents,
1002 "Concat file at $dest has correct contents ($backendName)." );
1004 $this->assertNotEquals( $expContent, $contents,
1005 "Concat file at $dest has correct contents ($backendName)." );
1013 self::baseStorePath() .
'/unittest-cont1/e/file1.txt',
1014 self::baseStorePath() .
'/unittest-cont1/e/file2.txt',
1015 self::baseStorePath() .
'/unittest-cont1/e/file3.txt',
1016 self::baseStorePath() .
'/unittest-cont1/e/file4.txt',
1017 self::baseStorePath() .
'/unittest-cont1/e/file5.txt',
1018 self::baseStorePath() .
'/unittest-cont1/e/file6.txt',
1019 self::baseStorePath() .
'/unittest-cont1/e/file7.txt',
1020 self::baseStorePath() .
'/unittest-cont1/e/file8.txt',
1021 self::baseStorePath() .
'/unittest-cont1/e/file9.txt',
1022 self::baseStorePath() .
'/unittest-cont1/e/file10.txt'
1036 $params = [
'srcs' => $srcs ];
1076 if ( $alreadyExists ) {
1080 "Creation of file at $path succeeded ($backendName)." );
1082 $size = $this->backend->getFileSize( [
'src' =>
$path ] );
1083 $time = $this->backend->getFileTimestamp( [
'src' =>
$path ] );
1084 $stat = $this->backend->getFileStat( [
'src' =>
$path ] );
1086 $this->assertEquals( strlen(
$content ), $size,
1087 "Correct file size of '$path'" );
1089 "Correct file timestamp of '$path'" );
1091 $size = $stat[
'size'];
1092 $time = $stat[
'mtime'];
1093 $this->assertEquals( strlen(
$content ), $size,
1094 "Correct file size of '$path'" );
1096 "Correct file timestamp of '$path'" );
1098 $this->backend->clearCache( [
$path ] );
1100 $size = $this->backend->getFileSize( [
'src' =>
$path ] );
1102 $this->assertEquals( strlen(
$content ), $size,
1103 "Correct file size of '$path'" );
1105 $this->backend->preloadCache( [
$path ] );
1107 $size = $this->backend->getFileSize( [
'src' =>
$path ] );
1109 $this->assertEquals( strlen(
$content ), $size,
1110 "Correct file size of '$path'" );
1112 $size = $this->backend->getFileSize( [
'src' =>
$path ] );
1113 $time = $this->backend->getFileTimestamp( [
'src' =>
$path ] );
1114 $stat = $this->backend->getFileStat( [
'src' =>
$path ] );
1116 $this->assertFalse( $size,
"Correct file size of '$path'" );
1117 $this->assertFalse(
$time,
"Correct file timestamp of '$path'" );
1118 $this->assertFalse( $stat,
"Correct file stat of '$path'" );
1125 $base = self::baseStorePath();
1126 $cases[] = [
"$base/unittest-cont1/e/b/z/some_file.txt",
"some file contents",
true ];
1127 $cases[] = [
"$base/unittest-cont1/e/b/some-other_file.txt",
"",
true ];
1128 $cases[] = [
"$base/unittest-cont1/e/b/some-diff_file.txt", null,
false ];
1156 "Creation of file at $path succeeded ($backendName)." );
1159 $this->backend->streamFile( [
'src' =>
$path,
'headless' => 1,
'allowOB' => 1 ] );
1160 $data = ob_get_contents();
1163 $this->assertEquals(
$content, $data,
"Correct content streamed from '$path'" );
1166 $this->backend->streamFile( [
'src' =>
$path,
'headless' => 1,
'allowOB' => 1 ] );
1167 $data = ob_get_contents();
1170 $this->assertRegExp(
'#<h1>File not found</h1>#', $data,
1171 "Correct content streamed from '$path' ($backendName)" );
1178 $base = self::baseStorePath();
1179 $cases[] = [
"$base/unittest-cont1/e/b/z/some_file.txt",
"some file contents" ];
1180 $cases[] = [
"$base/unittest-cont1/e/b/some-other_file.txt", null ];
1200 $base = self::baseStorePath();
1201 $path =
"$base/unittest-cont1/e/b/z/range_file.txt";
1207 "Creation of file at $path succeeded ($backendName)." );
1211 'bytes=0-3' =>
'0123',
1212 'bytes=4-8' =>
'45678',
1213 'bytes=15-15' =>
'F',
1214 'bytes=14-15' =>
'EF',
1215 'bytes=-5' =>
'BCDEF',
1217 'bytes=10-16' =>
'ABCDEF',
1218 'bytes=10-99' =>
'ABCDEF',
1221 foreach ( $ranges
as $range => $chunk ) {
1223 $this->backend->streamFile( [
'src' =>
$path,
'headless' => 1,
'allowOB' => 1,
1224 'options' => [
'range' => $range ] ] );
1225 $data = ob_get_contents();
1228 $this->assertEquals( $chunk, $data,
"Correct chunk streamed from '$path' for '$range'" );
1254 foreach ( $srcs
as $i => $src ) {
1255 $this->
prepare( [
'dir' => dirname( $src ) ] );
1256 $status = $this->backend->doOperation(
1257 [
'op' =>
'create',
'content' =>
$content[$i],
'dst' => $src ] );
1259 "Creation of file at $src succeeded ($backendName)." );
1263 $contents = $this->backend->getFileContentsMulti( [
'srcs' =>
$source ] );
1264 foreach ( $contents
as $path => $data ) {
1265 $this->assertNotEquals(
false, $data,
"Contents of $path exists ($backendName)." );
1266 $this->assertEquals(
1269 "Contents of $path is correct ($backendName)."
1273 $this->assertEquals(
1275 array_keys( $contents ),
1276 "Contents in right order ($backendName)."
1278 $this->assertEquals(
1281 "Contents array size correct ($backendName)."
1284 $data = $this->backend->getFileContents( [
'src' =>
$source ] );
1285 $this->assertNotEquals(
false, $data,
"Contents of $source exists ($backendName)." );
1286 $this->assertEquals(
$content[0], $data,
"Contents of $source is correct ($backendName)." );
1293 $base = self::baseStorePath();
1294 $cases[] = [
"$base/unittest-cont1/e/b/z/some_file.txt",
"some file contents" ];
1295 $cases[] = [
"$base/unittest-cont1/e/b/some-other_file.txt",
"more file contents" ];
1297 [
"$base/unittest-cont1/e/a/x.txt",
"$base/unittest-cont1/e/a/y.txt",
1298 "$base/unittest-cont1/e/a/z.txt" ],
1299 [
"contents xx",
"contents xy",
"contents xz" ]
1326 foreach ( $srcs
as $i => $src ) {
1327 $this->
prepare( [
'dir' => dirname( $src ) ] );
1328 $status = $this->backend->doOperation(
1329 [
'op' =>
'create',
'content' =>
$content[$i],
'dst' => $src ] );
1331 "Creation of file at $src succeeded ($backendName)." );
1337 $this->assertNotNull( $tmpFile,
1338 "Creation of local copy of $path succeeded ($backendName)." );
1339 $contents = file_get_contents( $tmpFile->getPath() );
1340 $this->assertNotEquals(
false, $contents,
"Local copy of $path exists ($backendName)." );
1341 $this->assertEquals(
1344 "Local copy of $path is correct ($backendName)."
1348 $this->assertEquals(
1351 "Local copies in right order ($backendName)."
1353 $this->assertEquals(
1356 "Local copies array size correct ($backendName)."
1359 $tmpFile = $this->backend->getLocalCopy( [
'src' =>
$source ] );
1360 $this->assertNotNull( $tmpFile,
1361 "Creation of local copy of $source succeeded ($backendName)." );
1362 $contents = file_get_contents( $tmpFile->getPath() );
1363 $this->assertNotEquals(
false, $contents,
"Local copy of $source exists ($backendName)." );
1364 $this->assertEquals(
1367 "Local copy of $source is correct ($backendName)."
1371 $obj =
new stdClass();
1372 $tmpFile->bind( $obj );
1378 $base = self::baseStorePath();
1379 $cases[] = [
"$base/unittest-cont1/e/a/z/some_file.txt",
"some file contents" ];
1380 $cases[] = [
"$base/unittest-cont1/e/a/some-other_file.txt",
"more file contents" ];
1381 $cases[] = [
"$base/unittest-cont1/e/a/\$odd&.txt",
"test file contents" ];
1383 [
"$base/unittest-cont1/e/a/x.txt",
"$base/unittest-cont1/e/a/y.txt",
1384 "$base/unittest-cont1/e/a/z.txt" ],
1385 [
"contents xx $",
"contents xy 111",
"contents xz" ]
1412 foreach ( $srcs
as $i => $src ) {
1413 $this->
prepare( [
'dir' => dirname( $src ) ] );
1414 $status = $this->backend->doOperation(
1415 [
'op' =>
'create',
'content' =>
$content[$i],
'dst' => $src ] );
1417 "Creation of file at $src succeeded ($backendName)." );
1421 $tmpFiles = $this->backend->getLocalReferenceMulti( [
'srcs' =>
$source ] );
1423 $this->assertNotNull( $tmpFile,
1424 "Creation of local copy of $path succeeded ($backendName)." );
1425 $contents = file_get_contents( $tmpFile->getPath() );
1426 $this->assertNotEquals(
false, $contents,
"Local ref of $path exists ($backendName)." );
1427 $this->assertEquals(
1430 "Local ref of $path is correct ($backendName)."
1434 $this->assertEquals(
1437 "Local refs in right order ($backendName)."
1439 $this->assertEquals(
1442 "Local refs array size correct ($backendName)."
1445 $tmpFile = $this->backend->getLocalReference( [
'src' =>
$source ] );
1446 $this->assertNotNull( $tmpFile,
1447 "Creation of local copy of $source succeeded ($backendName)." );
1448 $contents = file_get_contents( $tmpFile->getPath() );
1449 $this->assertNotEquals(
false, $contents,
"Local ref of $source exists ($backendName)." );
1450 $this->assertEquals(
$content[0], $contents,
"Local ref of $source is correct ($backendName)." );
1457 $base = self::baseStorePath();
1458 $cases[] = [
"$base/unittest-cont1/e/a/z/some_file.txt",
"some file contents" ];
1459 $cases[] = [
"$base/unittest-cont1/e/a/some-other_file.txt",
"more file contents" ];
1460 $cases[] = [
"$base/unittest-cont1/e/a/\$odd&.txt",
"test file contents" ];
1462 [
"$base/unittest-cont1/e/a/x.txt",
"$base/unittest-cont1/e/a/y.txt",
1463 "$base/unittest-cont1/e/a/z.txt" ],
1464 [
"contents xx 1111",
"contents xy %",
"contents xz $" ]
1489 $base = self::baseStorePath();
1491 $tmpFile = $this->backend->getLocalCopy( [
1492 'src' =>
"$base/unittest-cont1/not-there" ] );
1493 $this->assertEquals( null, $tmpFile,
"Local copy of not existing file is null ($backendName)." );
1495 $tmpFile = $this->backend->getLocalReference( [
1496 'src' =>
"$base/unittest-cont1/not-there" ] );
1497 $this->assertEquals( null, $tmpFile,
"Local ref of not existing file is null ($backendName)." );
1520 $status = $this->backend->doOperation(
1523 "Creation of file at $source succeeded ($backendName)." );
1525 $url = $this->backend->getFileHttpUrl( [
'src' =>
$source ] );
1527 if ( $url !== null ) {
1529 $this->assertEquals(
$content, $data,
1530 "HTTP GET of URL has right contents ($backendName)." );
1537 $base = self::baseStorePath();
1538 $cases[] = [
"$base/unittest-cont1/e/a/z/some_file.txt",
"some file contents" ];
1539 $cases[] = [
"$base/unittest-cont1/e/a/some-other_file.txt",
"more file contents" ];
1540 $cases[] = [
"$base/unittest-cont1/e/a/\$odd&.txt",
"test file contents" ];
1561 $base = self::baseStorePath();
1564 [
"$base/unittest-cont1/e/a/z/some_file1.txt",
true ],
1565 [
"$base/unittest-cont2/a/z/some_file2.txt",
true ],
1566 # Specific to FS backend with no basePath field set
1567 # [ "$base/unittest-cont3/a/z/some_file3.txt", false ],
1577 "Preparing dir $path succeeded without warnings ($backendName)." );
1578 $this->assertEquals(
true,
$status->isOK(),
1579 "Preparing dir $path succeeded ($backendName)." );
1581 $this->assertEquals(
false,
$status->isOK(),
1582 "Preparing dir $path failed ($backendName)." );
1585 $status = $this->backend->secure( [
'dir' => dirname(
$path ) ] );
1588 "Securing dir $path succeeded without warnings ($backendName)." );
1589 $this->assertEquals(
true,
$status->isOK(),
1590 "Securing dir $path succeeded ($backendName)." );
1592 $this->assertEquals(
false,
$status->isOK(),
1593 "Securing dir $path failed ($backendName)." );
1596 $status = $this->backend->publish( [
'dir' => dirname(
$path ) ] );
1599 "Publishing dir $path succeeded without warnings ($backendName)." );
1600 $this->assertEquals(
true,
$status->isOK(),
1601 "Publishing dir $path succeeded ($backendName)." );
1603 $this->assertEquals(
false,
$status->isOK(),
1604 "Publishing dir $path failed ($backendName)." );
1607 $status = $this->backend->clean( [
'dir' => dirname(
$path ) ] );
1610 "Cleaning dir $path succeeded without warnings ($backendName)." );
1611 $this->assertEquals(
true,
$status->isOK(),
1612 "Cleaning dir $path succeeded ($backendName)." );
1614 $this->assertEquals(
false,
$status->isOK(),
1615 "Cleaning dir $path failed ($backendName)." );
1635 $base = self::baseStorePath();
1637 "$base/unittest-cont1",
1638 "$base/unittest-cont1/e",
1639 "$base/unittest-cont1/e/a",
1640 "$base/unittest-cont1/e/a/b",
1641 "$base/unittest-cont1/e/a/b/c",
1642 "$base/unittest-cont1/e/a/b/c/d0",
1643 "$base/unittest-cont1/e/a/b/c/d1",
1644 "$base/unittest-cont1/e/a/b/c/d2",
1645 "$base/unittest-cont1/e/a/b/c/d0/1",
1646 "$base/unittest-cont1/e/a/b/c/d0/2",
1647 "$base/unittest-cont1/e/a/b/c/d1/3",
1648 "$base/unittest-cont1/e/a/b/c/d1/4",
1649 "$base/unittest-cont1/e/a/b/c/d2/5",
1650 "$base/unittest-cont1/e/a/b/c/d2/6"
1655 "Preparing dir $dir succeeded without warnings ($backendName)." );
1660 $this->assertEquals(
true, $this->backend->directoryExists( [
'dir' => $dir ] ),
1661 "Dir $dir exists ($backendName)." );
1665 $status = $this->backend->clean(
1666 [
'dir' =>
"$base/unittest-cont1",
'recursive' => 1 ] );
1668 "Recursive cleaning of dir $dir succeeded without warnings ($backendName)." );
1671 $this->assertEquals(
false, $this->backend->directoryExists( [
'dir' => $dir ] ),
1672 "Dir $dir no longer exists ($backendName)." );
1692 $base = self::baseStorePath();
1694 $fileA =
"$base/unittest-cont1/e/a/b/fileA.txt";
1695 $fileAContents =
'3tqtmoeatmn4wg4qe-mg3qt3 tq';
1696 $fileB =
"$base/unittest-cont1/e/a/b/fileB.txt";
1697 $fileBContents =
'g-jmq3gpqgt3qtg q3GT ';
1698 $fileC =
"$base/unittest-cont1/e/a/b/fileC.txt";
1699 $fileCContents =
'eigna[ogmewt 3qt g3qg flew[ag';
1700 $fileD =
"$base/unittest-cont1/e/a/b/fileD.txt";
1702 $this->
prepare( [
'dir' => dirname( $fileA ) ] );
1703 $this->
create( [
'dst' => $fileA,
'content' => $fileAContents ] );
1704 $this->
prepare( [
'dir' => dirname( $fileB ) ] );
1705 $this->
create( [
'dst' => $fileB,
'content' => $fileBContents ] );
1706 $this->
prepare( [
'dir' => dirname( $fileC ) ] );
1707 $this->
create( [
'dst' => $fileC,
'content' => $fileCContents ] );
1708 $this->
prepare( [
'dir' => dirname( $fileD ) ] );
1710 $status = $this->backend->doOperations( [
1711 [
'op' =>
'describe',
'src' => $fileA,
1712 'headers' => [
'X-Content-Length' =>
'91.3' ],
'disposition' =>
'inline' ],
1713 [
'op' =>
'copy',
'src' => $fileA,
'dst' => $fileC,
'overwrite' => 1 ],
1715 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileA,
'overwriteSame' => 1 ],
1717 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileD,
'overwrite' => 1 ],
1719 [
'op' =>
'move',
'src' => $fileB,
'dst' => $fileC ],
1721 [
'op' =>
'move',
'src' => $fileD,
'dst' => $fileA,
'overwriteSame' => 1 ],
1723 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileA,
'overwrite' => 1 ],
1725 [
'op' =>
'copy',
'src' => $fileA,
'dst' => $fileC ],
1727 [
'op' =>
'move',
'src' => $fileA,
'dst' => $fileC,
'overwriteSame' => 1 ],
1729 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileC,
'overwrite' => 1 ],
1731 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileC,
'overwriteSame' => 1 ],
1733 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileC,
'overwrite' => 1 ],
1735 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileC,
'overwriteSame' => 1 ],
1742 $this->assertEquals(
true,
$status->isOK(),
"Operation batch succeeded" );
1743 $this->assertEquals( 14, count(
$status->success ),
1744 "Operation batch has correct success array" );
1746 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileA ] ),
1747 "File does not exist at $fileA" );
1748 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileB ] ),
1749 "File does not exist at $fileB" );
1750 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileD ] ),
1751 "File does not exist at $fileD" );
1753 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $fileC ] ),
1754 "File exists at $fileC" );
1755 $this->assertEquals( $fileBContents,
1756 $this->backend->getFileContents( [
'src' => $fileC ] ),
1757 "Correct file contents of $fileC" );
1758 $this->assertEquals( strlen( $fileBContents ),
1759 $this->backend->getFileSize( [
'src' => $fileC ] ),
1760 "Correct file size of $fileC" );
1761 $this->assertEquals( Wikimedia\base_convert( sha1( $fileBContents ), 16, 36, 31 ),
1762 $this->backend->getFileSha1Base36( [
'src' => $fileC ] ),
1763 "Correct file SHA-1 of $fileC" );
1783 $base = self::baseStorePath();
1785 $fileAContents =
'3tqtmoeatmn4wg4qe-mg3qt3 tq';
1786 $fileBContents =
'g-jmq3gpqgt3qtg q3GT ';
1787 $fileCContents =
'eigna[ogmewt 3qt g3qg flew[ag';
1792 $this->
addTmpFiles( [ $tmpNameA, $tmpNameB, $tmpNameC ] );
1793 file_put_contents( $tmpNameA, $fileAContents );
1794 file_put_contents( $tmpNameB, $fileBContents );
1795 file_put_contents( $tmpNameC, $fileCContents );
1797 $fileA =
"$base/unittest-cont1/e/a/b/fileA.txt";
1798 $fileB =
"$base/unittest-cont1/e/a/b/fileB.txt";
1799 $fileC =
"$base/unittest-cont1/e/a/b/fileC.txt";
1800 $fileD =
"$base/unittest-cont1/e/a/b/fileD.txt";
1802 $this->
prepare( [
'dir' => dirname( $fileA ) ] );
1803 $this->
create( [
'dst' => $fileA,
'content' => $fileAContents ] );
1804 $this->
prepare( [
'dir' => dirname( $fileB ) ] );
1805 $this->
prepare( [
'dir' => dirname( $fileC ) ] );
1806 $this->
prepare( [
'dir' => dirname( $fileD ) ] );
1808 $status = $this->backend->doOperations( [
1809 [
'op' =>
'store',
'src' => $tmpNameA,
'dst' => $fileA,
'overwriteSame' => 1 ],
1810 [
'op' =>
'store',
'src' => $tmpNameB,
'dst' => $fileB,
'overwrite' => 1 ],
1811 [
'op' =>
'store',
'src' => $tmpNameC,
'dst' => $fileC,
'overwrite' => 1 ],
1812 [
'op' =>
'copy',
'src' => $fileA,
'dst' => $fileC,
'overwrite' => 1 ],
1814 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileA,
'overwriteSame' => 1 ],
1816 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileD,
'overwrite' => 1 ],
1818 [
'op' =>
'move',
'src' => $fileB,
'dst' => $fileC ],
1820 [
'op' =>
'move',
'src' => $fileD,
'dst' => $fileA,
'overwriteSame' => 1 ],
1822 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileA,
'overwrite' => 1 ],
1824 [
'op' =>
'copy',
'src' => $fileA,
'dst' => $fileC ],
1826 [
'op' =>
'move',
'src' => $fileA,
'dst' => $fileC,
'overwriteSame' => 1 ],
1828 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileC,
'overwrite' => 1 ],
1830 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileC,
'overwriteSame' => 1 ],
1832 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileC,
'overwrite' => 1 ],
1834 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileC,
'overwriteSame' => 1 ],
1841 $this->assertEquals(
true,
$status->isOK(),
"Operation batch succeeded" );
1842 $this->assertEquals( 16, count(
$status->success ),
1843 "Operation batch has correct success array" );
1845 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileA ] ),
1846 "File does not exist at $fileA" );
1847 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileB ] ),
1848 "File does not exist at $fileB" );
1849 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileD ] ),
1850 "File does not exist at $fileD" );
1852 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $fileC ] ),
1853 "File exists at $fileC" );
1854 $this->assertEquals( $fileBContents,
1855 $this->backend->getFileContents( [
'src' => $fileC ] ),
1856 "Correct file contents of $fileC" );
1857 $this->assertEquals( strlen( $fileBContents ),
1858 $this->backend->getFileSize( [
'src' => $fileC ] ),
1859 "Correct file size of $fileC" );
1860 $this->assertEquals( Wikimedia\base_convert( sha1( $fileBContents ), 16, 36, 31 ),
1861 $this->backend->getFileSha1Base36( [
'src' => $fileC ] ),
1862 "Correct file SHA-1 of $fileC" );
1881 $base = self::baseStorePath();
1883 $fileA =
"$base/unittest-cont2/a/b/fileA.txt";
1884 $fileAContents =
'3tqtmoeatmn4wg4qe-mg3qt3 tq';
1885 $fileB =
"$base/unittest-cont2/a/b/fileB.txt";
1886 $fileBContents =
'g-jmq3gpqgt3qtg q3GT ';
1887 $fileC =
"$base/unittest-cont2/a/b/fileC.txt";
1888 $fileCContents =
'eigna[ogmewt 3qt g3qg flew[ag';
1889 $fileD =
"$base/unittest-cont2/a/b/fileD.txt";
1891 $this->
prepare( [
'dir' => dirname( $fileA ) ] );
1892 $this->
create( [
'dst' => $fileA,
'content' => $fileAContents ] );
1893 $this->
prepare( [
'dir' => dirname( $fileB ) ] );
1894 $this->
create( [
'dst' => $fileB,
'content' => $fileBContents ] );
1895 $this->
prepare( [
'dir' => dirname( $fileC ) ] );
1896 $this->
create( [
'dst' => $fileC,
'content' => $fileCContents ] );
1898 $status = $this->backend->doOperations( [
1899 [
'op' =>
'copy',
'src' => $fileA,
'dst' => $fileC,
'overwrite' => 1 ],
1901 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileA,
'overwriteSame' => 1 ],
1903 [
'op' =>
'copy',
'src' => $fileB,
'dst' => $fileD,
'overwrite' => 1 ],
1905 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileD ],
1907 [
'op' =>
'move',
'src' => $fileB,
'dst' => $fileC,
'overwriteSame' => 1 ],
1909 [
'op' =>
'move',
'src' => $fileB,
'dst' => $fileA,
'overwrite' => 1 ],
1911 [
'op' =>
'delete',
'src' => $fileD ],
1915 ], [
'force' => 1 ] );
1917 $this->assertNotEquals( [],
$status->getErrors(),
"Operation had warnings" );
1918 $this->assertEquals(
true,
$status->isOK(),
"Operation batch succeeded" );
1919 $this->assertEquals( 8, count(
$status->success ),
1920 "Operation batch has correct success array" );
1922 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileB ] ),
1923 "File does not exist at $fileB" );
1924 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileD ] ),
1925 "File does not exist at $fileD" );
1927 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $fileA ] ),
1928 "File does not exist at $fileA" );
1929 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $fileC ] ),
1930 "File exists at $fileC" );
1931 $this->assertEquals( $fileBContents,
1932 $this->backend->getFileContents( [
'src' => $fileA ] ),
1933 "Correct file contents of $fileA" );
1934 $this->assertEquals( strlen( $fileBContents ),
1935 $this->backend->getFileSize( [
'src' => $fileA ] ),
1936 "Correct file size of $fileA" );
1937 $this->assertEquals( Wikimedia\base_convert( sha1( $fileBContents ), 16, 36, 31 ),
1938 $this->backend->getFileSha1Base36( [
'src' => $fileA ] ),
1939 "Correct file SHA-1 of $fileA" );
1959 $base = self::baseStorePath();
1962 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont-notexists" ] );
1965 "$base/unittest-cont1/e/test1.txt",
1966 "$base/unittest-cont1/e/test2.txt",
1967 "$base/unittest-cont1/e/test3.txt",
1968 "$base/unittest-cont1/e/subdir1/test1.txt",
1969 "$base/unittest-cont1/e/subdir1/test2.txt",
1970 "$base/unittest-cont1/e/subdir2/test3.txt",
1971 "$base/unittest-cont1/e/subdir2/test4.txt",
1972 "$base/unittest-cont1/e/subdir2/subdir/test1.txt",
1973 "$base/unittest-cont1/e/subdir2/subdir/test2.txt",
1974 "$base/unittest-cont1/e/subdir2/subdir/test3.txt",
1975 "$base/unittest-cont1/e/subdir2/subdir/test4.txt",
1976 "$base/unittest-cont1/e/subdir2/subdir/test5.txt",
1977 "$base/unittest-cont1/e/subdir2/subdir/sub/test0.txt",
1978 "$base/unittest-cont1/e/subdir2/subdir/sub/120-px-file.txt",
1984 $this->
prepare( [
'dir' => dirname( $file ) ] );
1985 $ops[] = [
'op' =>
'create',
'content' =>
'xxy',
'dst' => $file ];
1987 $status = $this->backend->doQuickOperations( $ops );
1989 "Creation of files succeeded ($backendName)." );
1990 $this->assertEquals(
true,
$status->isOK(),
1991 "Creation of files succeeded with OK status ($backendName)." );
1998 "e/subdir1/test1.txt",
1999 "e/subdir1/test2.txt",
2000 "e/subdir2/test3.txt",
2001 "e/subdir2/test4.txt",
2002 "e/subdir2/subdir/test1.txt",
2003 "e/subdir2/subdir/test2.txt",
2004 "e/subdir2/subdir/test3.txt",
2005 "e/subdir2/subdir/test4.txt",
2006 "e/subdir2/subdir/test5.txt",
2007 "e/subdir2/subdir/sub/test0.txt",
2008 "e/subdir2/subdir/sub/120-px-file.txt",
2013 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont1" ] );
2016 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2019 $iter = $this->backend->getFileList( [
2020 'dir' =>
"$base/unittest-cont1",
2025 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2029 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont1/" ] );
2030 foreach ( $iter
as $file ) {
2034 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2044 "sub/120-px-file.txt",
2049 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont1/e/subdir2/subdir" ] );
2052 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2055 $iter = $this->backend->getFileList( [
2056 'dir' =>
"$base/unittest-cont1/e/subdir2/subdir",
2061 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2065 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont1/e/subdir2/subdir/" ] );
2066 foreach ( $iter
as $file ) {
2070 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2075 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName), second iteration." );
2078 $iter = $this->backend->getTopFileList( [
'dir' =>
"$base/unittest-cont1" ] );
2081 $this->assertEquals( [], $list,
"Correct top file listing ($backendName)." );
2094 $iter = $this->backend->getTopFileList(
2095 [
'dir' =>
"$base/unittest-cont1/e/subdir2/subdir" ]
2099 $this->assertEquals( $expected, $list,
"Correct top file listing ($backendName)." );
2102 $iter = $this->backend->getTopFileList( [
2103 'dir' =>
"$base/unittest-cont1/e/subdir2/subdir",
2108 $this->assertEquals( $expected, $list,
"Correct top file listing ($backendName)." );
2111 $this->backend->doOperation( [
'op' =>
'delete',
'src' => $file ] );
2114 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont1/not/exists" ] );
2115 foreach ( $iter
as $iter ) {
2139 $base = self::baseStorePath();
2141 "$base/unittest-cont1/e/test1.txt",
2142 "$base/unittest-cont1/e/test2.txt",
2143 "$base/unittest-cont1/e/test3.txt",
2144 "$base/unittest-cont1/e/subdir1/test1.txt",
2145 "$base/unittest-cont1/e/subdir1/test2.txt",
2146 "$base/unittest-cont1/e/subdir2/test3.txt",
2147 "$base/unittest-cont1/e/subdir2/test4.txt",
2148 "$base/unittest-cont1/e/subdir2/subdir/test1.txt",
2149 "$base/unittest-cont1/e/subdir3/subdir/test2.txt",
2150 "$base/unittest-cont1/e/subdir4/subdir/test3.txt",
2151 "$base/unittest-cont1/e/subdir4/subdir/test4.txt",
2152 "$base/unittest-cont1/e/subdir4/subdir/test5.txt",
2153 "$base/unittest-cont1/e/subdir4/subdir/sub/test0.txt",
2154 "$base/unittest-cont1/e/subdir4/subdir/sub/120-px-file.txt",
2160 $this->
prepare( [
'dir' => dirname( $file ) ] );
2161 $ops[] = [
'op' =>
'create',
'content' =>
'xxy',
'dst' => $file ];
2163 $status = $this->backend->doQuickOperations( $ops );
2165 "Creation of files succeeded ($backendName)." );
2166 $this->assertEquals(
true,
$status->isOK(),
2167 "Creation of files succeeded with OK status ($backendName)." );
2169 $this->assertEquals(
true,
2170 $this->backend->directoryExists( [
'dir' =>
"$base/unittest-cont1/e/subdir1" ] ),
2171 "Directory exists in ($backendName)." );
2172 $this->assertEquals(
true,
2173 $this->backend->directoryExists( [
'dir' =>
"$base/unittest-cont1/e/subdir2/subdir" ] ),
2174 "Directory exists in ($backendName)." );
2175 $this->assertEquals(
false,
2176 $this->backend->directoryExists( [
'dir' =>
"$base/unittest-cont1/e/subdir2/test1.txt" ] ),
2177 "Directory does not exists in ($backendName)." );
2187 $iter = $this->backend->getTopDirectoryList( [
'dir' =>
"$base/unittest-cont1" ] );
2188 foreach ( $iter
as $file ) {
2193 $this->assertEquals( $expected, $list,
"Correct top dir listing ($backendName)." );
2206 $iter = $this->backend->getTopDirectoryList( [
'dir' =>
"$base/unittest-cont1/e" ] );
2207 foreach ( $iter
as $file ) {
2212 $this->assertEquals( $expected, $list,
"Correct top dir listing ($backendName)." );
2216 $iter = $this->backend->getTopDirectoryList( [
'dir' =>
"$base/unittest-cont1/e/" ] );
2217 foreach ( $iter
as $file ) {
2222 $this->assertEquals( $expected, $list,
"Correct top dir listing ($backendName)." );
2232 $iter = $this->backend->getTopDirectoryList( [
'dir' =>
"$base/unittest-cont1/e/subdir2" ] );
2233 foreach ( $iter
as $file ) {
2238 $this->assertEquals( $expected, $list,
"Correct top dir listing ($backendName)." );
2242 $iter = $this->backend->getTopDirectoryList(
2243 [
'dir' =>
"$base/unittest-cont1/e/subdir2/" ]
2246 foreach ( $iter
as $file ) {
2251 $this->assertEquals( $expected, $list,
"Correct top dir listing ($backendName)." );
2255 foreach ( $iter
as $file ) {
2260 $this->assertEquals(
2263 "Correct top dir listing ($backendName), second iteration."
2276 "e/subdir4/subdir/sub",
2282 $iter = $this->backend->getDirectoryList( [
'dir' =>
"$base/unittest-cont1/" ] );
2283 foreach ( $iter
as $file ) {
2288 $this->assertEquals( $expected, $list,
"Correct dir listing ($backendName)." );
2299 $iter = $this->backend->getDirectoryList( [
'dir' =>
"$base/unittest-cont1/e/subdir4" ] );
2300 foreach ( $iter
as $file ) {
2305 $this->assertEquals( $expected, $list,
"Correct dir listing ($backendName)." );
2309 foreach ( $iter
as $file ) {
2314 $this->assertEquals( $expected, $list,
"Correct dir listing ($backendName)." );
2316 $iter = $this->backend->getDirectoryList( [
'dir' =>
"$base/unittest-cont1/e/subdir1" ] );
2318 $this->assertEquals( [], $items,
"Directory listing is empty." );
2321 $this->backend->doOperation( [
'op' =>
'delete',
'src' => $file ] );
2324 $iter = $this->backend->getDirectoryList( [
'dir' =>
"$base/unittest-cont1/not/exists" ] );
2325 foreach ( $iter
as $file ) {
2330 $this->assertEquals( [], $items,
"Directory listing is empty." );
2332 $iter = $this->backend->getDirectoryList( [
'dir' =>
"$base/unittest-cont1/e/not/exists" ] );
2334 $this->assertEquals( [], $items,
"Directory listing is empty." );
2355 "subdir1/test1.txt",
2356 "subdir1/test2.txt",
2359 "subdir2/test3.txt",
2360 "subdir2/test4.txt",
2362 "subdir2/subdir/test1.txt",
2363 "subdir2/subdir/test2.txt",
2364 "subdir2/subdir/test3.txt",
2365 "subdir2/subdir/test4.txt",
2366 "subdir2/subdir/test5.txt",
2367 "subdir2/subdir/sub",
2368 "subdir2/subdir/sub/test0.txt",
2369 "subdir2/subdir/sub/120-px-file.txt",
2372 for ( $i = 0; $i < 25; $i++ ) {
2374 $this->assertEquals( print_r( [],
true ), print_r(
$status->getErrors(),
true ),
2375 "Locking of files succeeded ($backendName) ($i)." );
2376 $this->assertEquals(
true,
$status->isOK(),
2377 "Locking of files succeeded with OK status ($backendName) ($i)." );
2380 $this->assertEquals( print_r( [],
true ), print_r( $status->getErrors(),
true ),
2381 "Locking of files succeeded ($backendName) ($i)." );
2382 $this->assertEquals(
true, $status->isOK(),
2383 "Locking of files succeeded with OK status ($backendName) ($i)." );
2386 $this->assertEquals( print_r( [],
true ), print_r( $status->getErrors(),
true ),
2387 "Locking of files succeeded ($backendName) ($i)." );
2388 $this->assertEquals(
true, $status->isOK(),
2389 "Locking of files succeeded with OK status ($backendName) ($i)." );
2392 $this->assertEquals( print_r( [],
true ), print_r( $status->getErrors(),
true ),
2393 "Locking of files succeeded ($backendName). ($i)" );
2394 $this->assertEquals(
true, $status->isOK(),
2395 "Locking of files succeeded with OK status ($backendName) ($i)." );
2397 # # Flip the acquire/release ordering around ##
2400 $this->assertEquals( print_r( [],
true ), print_r( $status->getErrors(),
true ),
2401 "Locking of files succeeded ($backendName) ($i)." );
2402 $this->assertEquals(
true, $status->isOK(),
2403 "Locking of files succeeded with OK status ($backendName) ($i)." );
2406 $this->assertEquals( print_r( [],
true ), print_r( $status->getErrors(),
true ),
2407 "Locking of files succeeded ($backendName) ($i)." );
2408 $this->assertEquals(
true, $status->isOK(),
2409 "Locking of files succeeded with OK status ($backendName) ($i)." );
2412 $this->assertEquals( print_r( [],
true ), print_r( $status->getErrors(),
true ),
2413 "Locking of files succeeded ($backendName). ($i)" );
2414 $this->assertEquals(
true, $status->isOK(),
2415 "Locking of files succeeded with OK status ($backendName) ($i)." );
2418 $this->assertEquals( print_r( [],
true ), print_r( $status->getErrors(),
true ),
2419 "Locking of files succeeded ($backendName) ($i)." );
2420 $this->assertEquals(
true, $status->isOK(),
2421 "Locking of files succeeded with OK status ($backendName) ($i)." );
2426 $this->assertInstanceOf(
'ScopedLock', $sl,
2427 "Scoped locking of files succeeded ($backendName)." );
2428 $this->assertEquals( [],
$status->getErrors(),
2429 "Scoped locking of files succeeded ($backendName)." );
2430 $this->assertEquals(
true,
$status->isOK(),
2431 "Scoped locking of files succeeded with OK status ($backendName)." );
2434 $this->assertEquals( null, $sl,
2435 "Scoped unlocking of files succeeded ($backendName)." );
2436 $this->assertEquals( [],
$status->getErrors(),
2437 "Scoped unlocking of files succeeded ($backendName)." );
2438 $this->assertEquals(
true,
$status->isOK(),
2439 "Scoped unlocking of files succeeded with OK status ($backendName)." );
2450 'name' =>
'testing',
2451 'class' =>
'MemoryFileBackend',
2453 'mimeCallback' => $mimeCallback
2457 $dst =
'mwstore://testing/container/path/to/file_no_ext';
2458 $src =
"$IP/tests/phpunit/data/media/srgb.jpg";
2459 $this->assertEquals(
'image/jpeg', $be->getContentType( $dst, null, $src ) );
2460 $this->assertEquals(
2461 $mimeFromString ?
'image/jpeg' :
'unknown/unknown',
2462 $be->getContentType( $dst, file_get_contents( $src ), null ) );
2464 $src =
"$IP/tests/phpunit/data/media/Png-native-test.png";
2465 $this->assertEquals(
'image/png', $be->getContentType( $dst, null, $src ) );
2466 $this->assertEquals(
2467 $mimeFromString ?
'image/png' :
'unknown/unknown',
2468 $be->getContentType( $dst, file_get_contents( $src ), null ) );
2481 'name' =>
'localtesting',
2482 'wikiId' =>
wfWikiID() . mt_rand(),
2485 'name' =>
'multitesting0',
2486 'class' =>
'MemoryFileBackend',
2487 'isMultiMaster' =>
false,
2488 'readAffinity' =>
true
2491 'name' =>
'multitesting1',
2492 'class' =>
'MemoryFileBackend',
2493 'isMultiMaster' =>
true
2499 $this->assertEquals(
2501 $be->getReadIndexFromParams( [
'latest' => 1 ] ),
2502 'Reads with "latest" flag use backend 1'
2504 $this->assertEquals(
2506 $be->getReadIndexFromParams( [
'latest' => 0 ] ),
2507 'Reads without "latest" flag use backend 0'
2510 $p =
'container/test-cont/file.txt';
2511 $be->backends[0]->quickCreate( [
2512 'dst' =>
"mwstore://multitesting0/$p",
'content' =>
'cattitude' ] );
2513 $be->backends[1]->quickCreate( [
2514 'dst' =>
"mwstore://multitesting1/$p",
'content' =>
'princess of power' ] );
2516 $this->assertEquals(
2518 $be->getFileContents( [
'src' =>
"mwstore://localtesting/$p" ] ),
2519 "Non-latest read came from backend 0"
2521 $this->assertEquals(
2522 'princess of power',
2523 $be->getFileContents( [
'src' =>
"mwstore://localtesting/$p",
'latest' => 1 ] ),
2524 "Latest read came from backend1"
2531 'name' =>
'localtesting',
2532 'wikiId' =>
wfWikiID() . mt_rand(),
2535 'name' =>
'multitesting0',
2536 'class' =>
'MemoryFileBackend',
2537 'isMultiMaster' =>
false
2540 'name' =>
'multitesting1',
2541 'class' =>
'MemoryFileBackend',
2542 'isMultiMaster' =>
true
2545 'replication' =>
'async'
2551 $p =
'container/test-cont/file.txt';
2553 'dst' =>
"mwstore://localtesting/$p",
'content' =>
'cattitude' ] );
2555 $this->assertEquals(
2557 $be->backends[0]->getFileContents( [
'src' =>
"mwstore://multitesting0/$p" ] ),
2558 "File not yet written to backend 0"
2560 $this->assertEquals(
2562 $be->backends[1]->getFileContents( [
'src' =>
"mwstore://multitesting1/$p" ] ),
2563 "File already written to backend 1"
2568 $this->assertEquals(
2570 $be->backends[0]->getFileContents( [
'src' =>
"mwstore://multitesting0/$p" ] ),
2571 "File now written to backend 0"
2577 'name' =>
'localtesting',
2586 'Content-dUration' => 25.6,
2587 'X-LONG-VALUE' => str_pad(
'0', 300 ),
2588 'CONTENT-LENGTH' => 855055,
2594 'content-duration' => 25.6,
2595 'content-length' => 855055
2599 MediaWiki\suppressWarnings();
2600 $actual = $be->sanitizeOpHeaders( $input );
2601 MediaWiki\restoreWarnings();
2603 $this->assertEquals( $expected, $actual,
"Header sanitized properly" );
2608 return is_array( $iter ) ? $iter : iterator_to_array( $iter );
2613 return $this->backend->prepare( $params );
2618 $params[
'op'] =
'create';
2620 return $this->backend->doQuickOperations( [ $params ] );
2624 $containers = [
'unittest-cont1',
'unittest-cont2',
'unittest-cont-bad' ];
2625 foreach ( $containers
as $container ) {
2631 $base = self::baseStorePath();
2632 $iter = $this->backend->getFileList( [
'dir' =>
"$base/$container" ] );
2634 foreach ( $iter
as $file ) {
2635 $this->backend->quickDelete( [
'src' =>
"$base/$container/$file" ] );
2640 $this->backend->clean( [
'dir' =>
"$base/$container",
'recursive' => 1 ] );
2645 $status = $this->backend->consistencyCheck( $paths );
2651 $this->assertEquals( print_r( [], 1 ), print_r( $status->
getErrors(), 1 ), $msg );
testGetContentType($mimeCallback, $mimeFromString)
provider_testGetContentType
the array() calling protocol came about after MediaWiki 1.4rc1.
testGetFileHttpUrl($source, $content)
provider_testGetFileHttpUrl FileBackend::getFileHttpUrl
static provider_testParentStoragePath()
FSFileBackend $singleBackend
testDescribe($op, $withSource, $okStatus)
provider_testDescribe FileBackend::doOperation
static singleton($domain=false)
processing should stop and the error should be shown to the user * false
testExtensionFromPath($path, $res)
provider_testExtensionFromPath FileBackend::extensionFromPath
testSplitStoragePath($path, $res)
provider_testSplitStoragePath FileBackend::splitStoragePath
static provider_testGetLocalReference()
static provider_testGetFileContents()
testDoOperations()
FileBackend::doOperations.
assertHasHeaders(array $headers, array $attr)
static doUpdates($mode= 'run', $stage=self::ALL)
Do any deferred updates and clear the list.
$wgFileBackends
File backend structure configuration.
const ATTR_HEADERS
Bitfield flags for supported features.
static provider_testExtensionFromPath()
assertBackendPathsConsistent(array $paths)
doTestCreate($op, $alreadyExists, $okStatus, $newSize)
testIsStoragePath($path, $isStorePath)
provider_testIsStoragePath FileBackend::isStoragePath
testLockCalls()
FileBackend::lockFiles FileBackend::unlockFiles.
doTestDoOperationsFailing()
doTestPrepareAndClean($path, $isOK)
doTestGetLocalCopy($source, $content)
static provider_testCopy()
testGetFileList()
FileBackend::getFileList.
doTestGetFileHttpUrl($source, $content)
doTestDelete($op, $withSource, $okStatus)
testStore($op)
provider_testStore
when a variable name is used in a it is silently declared as a new local masking the global
static extensionFromPath($path, $case= 'lowercase')
Get the final extension from a storage or FS path.
static provider_testConcatenate()
wfRandomString($length=32)
Get a random string containing a number of pseudo-random hex characters.
static request($method, $url, $options=[], $caller=__METHOD__)
Perform an HTTP request.
static factory($prefix, $extension= '', $tmpDirectory=null)
Make a new temporary file on the file system.
static provider_normalizeStoragePath()
const TS_UNIX
Unix time - the number of seconds since 1970-01-01 00:00:00 UTC.
wfTimestamp($outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
static provider_testCreate()
provider_testCreate
wfTempDir()
Tries to get the system directory for temporary files.
static provider_testGetLocalCopy()
testCopy($op)
provider_testCopy FileBackend::doOperation
static isStoragePath($path)
Check if a given path is a "mwstore://" path.
static provider_testIsStoragePath()
static provider_testMove()
static provider_testGetFileStat()
testGetLocalReference($source, $content)
provider_testGetLocalReference FileBackend::getLocalReference
doTestGetFileContents($source, $content)
static provider_testDelete()
FileRepo FileBackend medium.
testNormalizeStoragePath($path, $res)
provider_normalizeStoragePath FileBackend::normalizeStoragePath
static provider_testPrepareAndClean()
doTestGetLocalReference($source, $content)
const LOCK_SH
Lock types; stronger locks have higher values.
static newGood($value=null)
Factory function for good results.
doTestConcatenate($params, $srcs, $srcsContent, $alreadyExists, $okStatus)
static provider_testDescribe()
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
assertGoodStatus(StatusValue $status, $msg)
testGetFileStat($path, $content, $alreadyExists)
provider_testGetFileStat FileBackend::getFileStat
testGetDirectoryList()
FileBackend::getTopDirectoryList FileBackend::getDirectoryList.
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
static provider_testSplitStoragePath()
static provider_testStore()
testDoQuickOperations()
FileBackend::doQuickOperations.
static normalizeStoragePath($storagePath)
Normalize a storage path by cleaning up directory separators.
static provider_testStreamFile()
doTestGetFileStat($path, $content, $alreadyExists)
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
doTestStore($op)
FileBackend::doOperation.
testGetLocalCopy($source, $content)
provider_testGetLocalCopy FileBackend::getLocalCopy
testGetLocalCopyAndReference404()
FileBackend::getLocalCopy FileBackend::getLocalReference.
doTestDescribe($op, $withSource, $okStatus)
testDoOperationsPipeline()
FileBackend::doOperations.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content $content
testCreate($op, $alreadyExists, $okStatus, $newSize)
provider_testCreate FileBackend::doOperation
Simulation of a backend storage in memory.
testStreamFile($path, $content, $alreadyExists)
provider_testGetFileStat FileBackend::streamFile
doTestDoQuickOperations()
Proxy backend that mirrors writes to several internal backends.
getErrors()
Get the list of errors.
static provider_testGetContentType()
testConcatenate($op, $srcs, $srcsContent, $alreadyExists, $okStatus)
provider_testConcatenate
static makeContentDisposition($type, $filename= '')
Build a Content-Disposition header value per RFC 6266.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set $status
doTestDoOperationsPipeline()
FileBackendMultiWrite $multiBackend
testPrepareAndClean($path, $isOK)
provider_testPrepareAndClean FileBackend::prepare FileBackend::clean
testDelete($op, $withSource, $okStatus)
provider_testDelete FileBackend::doOperation
static splitStoragePath($storagePath)
Split a storage path into a backend name, a container name, and a relative file path.
static newFromObject($object)
Return the same object, without access restrictions.
doTestGetLocalCopyAndReference404()
doTestRecursiveClean()
FileBackend::clean.
Class for a file system (FS) based file backend.
testGetFileContents($source, $content)
provider_testGetFileContents FileBackend::getFileContents FileBackend::getFileContentsMulti ...
static release(ScopedLock &$lock=null)
Release a scoped lock and set any errors in the attatched StatusValue object.
static getPropsFromPath($path, $ext=true)
Get an associative array containing information about a file in the local filesystem.
see documentation in includes Linker php for Linker::makeImageLink & $time
static factory(array $config, $backend)
Create an appropriate FileJournal object from config.
testMove($op)
provider_testMove FileBackend::doOperation
doTestStreamFile($path, $content)
testDoOperationsFailing()
FileBackend::doOperations.
testParentStoragePath($path, $res)
provider_testParentStoragePath FileBackend::parentStoragePath
static provider_testGetFileHttpUrl()
static parentStoragePath($storagePath)
Get the parent storage directory of a storage path.
Allows to change the fields on the form that will be generated $name