3 use Wikimedia\TestingAccessWrapper;
62 if ( $this->
getCliArg(
'use-filebackend' ) ) {
63 if ( self::$backendToUse ) {
69 if ( $conf[
'name'] ==
$name ) {
74 $useConfig[
'name'] =
'localtesting';
75 $useConfig[
'shardViaHashLevels'] = [
76 'unittest-cont1' => [
'levels' => 1,
'base' => 16,
'repeat' => 1 ]
78 if ( isset( $useConfig[
'fileJournal'] ) ) {
82 $class = $useConfig[
'class'];
83 self::$backendToUse =
new $class( $useConfig );
88 'name' =>
'localtesting',
92 'unittest-cont1' =>
"{$tmpDir}/localtesting-cont1",
93 'unittest-cont2' =>
"{$tmpDir}/localtesting-cont2" ]
97 'name' =>
'localtesting',
99 'parallelize' =>
'implicit',
103 'name' =>
'localmultitesting1',
104 'class' =>
'FSFileBackend',
105 'containerPaths' => [
106 'unittest-cont1' =>
"{$tmpDir}/localtestingmulti1-cont1",
107 'unittest-cont2' =>
"{$tmpDir}/localtestingmulti1-cont2" ],
108 'isMultiMaster' =>
false
111 'name' =>
'localmultitesting2',
112 'class' =>
'FSFileBackend',
113 'containerPaths' => [
114 'unittest-cont1' =>
"{$tmpDir}/localtestingmulti2-cont1",
115 'unittest-cont2' =>
"{$tmpDir}/localtestingmulti2-cont2" ],
116 'isMultiMaster' =>
true
123 return 'mwstore://localtesting';
127 return get_class( $this->backend );
135 "FileBackend::isStoragePath on path '$path'" );
140 [
'mwstore://',
true ],
141 [
'mwstore://backend',
true ],
142 [
'mwstore://backend/container',
true ],
143 [
'mwstore://backend/container/',
true ],
144 [
'mwstore://backend/container/path',
true ],
145 [
'mwstore://backend//container/',
true ],
146 [
'mwstore://backend//container//',
true ],
147 [
'mwstore://backend//container//path',
true ],
148 [
'mwstore:///',
true ],
149 [
'mwstore:/',
false ],
150 [
'mwstore:',
false ],
159 "FileBackend::splitStoragePath on path '$path'" );
164 [
'mwstore://backend/container', [
'backend',
'container',
'' ] ],
165 [
'mwstore://backend/container/', [
'backend',
'container',
'' ] ],
166 [
'mwstore://backend/container/path', [
'backend',
'container',
'path' ] ],
167 [
'mwstore://backend/container//path', [
'backend',
'container',
'/path' ] ],
168 [
'mwstore://backend//container/path', [
null,
null, null ] ],
169 [
'mwstore://backend//container//path', [
null,
null, null ] ],
170 [
'mwstore://', [
null,
null, null ] ],
171 [
'mwstore://backend', [
null,
null, null ] ],
172 [
'mwstore:///', [
null,
null, null ] ],
173 [
'mwstore:/', [
null,
null, null ] ],
174 [
'mwstore:', [
null,
null, null ] ]
183 "FileBackend::normalizeStoragePath on path '$path'" );
188 [
'mwstore://backend/container',
'mwstore://backend/container' ],
189 [
'mwstore://backend/container/',
'mwstore://backend/container' ],
190 [
'mwstore://backend/container/path',
'mwstore://backend/container/path' ],
191 [
'mwstore://backend/container//path',
'mwstore://backend/container/path' ],
192 [
'mwstore://backend/container///path',
'mwstore://backend/container/path' ],
194 'mwstore://backend/container///path//to///obj',
195 'mwstore://backend/container/path/to/obj'
197 [
'mwstore://', null ],
198 [
'mwstore://backend', null ],
199 [
'mwstore://backend//container/path', null ],
200 [
'mwstore://backend//container//path', null ],
201 [
'mwstore:///', null ],
202 [
'mwstore:/', null ],
203 [
'mwstore:', null ],
212 "FileBackend::parentStoragePath on path '$path'" );
217 [
'mwstore://backend/container/path/to/obj',
'mwstore://backend/container/path/to' ],
218 [
'mwstore://backend/container/path/to',
'mwstore://backend/container/path' ],
219 [
'mwstore://backend/container/path',
'mwstore://backend/container' ],
220 [
'mwstore://backend/container', null ],
221 [
'mwstore://backend/container/path/to/obj/',
'mwstore://backend/container/path/to' ],
222 [
'mwstore://backend/container/path/to/',
'mwstore://backend/container/path' ],
223 [
'mwstore://backend/container/path/',
'mwstore://backend/container' ],
224 [
'mwstore://backend/container/', null ],
233 "FileBackend::extensionFromPath on path '$path'" );
238 [
'mwstore://backend/container/path.txt',
'txt' ],
239 [
'mwstore://backend/container/path.svg.png',
'png' ],
240 [
'mwstore://backend/container/path',
'' ],
241 [
'mwstore://backend/container/path.',
'' ],
267 $this->
prepare( [
'dir' => dirname( $dest ) ] );
269 file_put_contents(
$source,
"Unit test file" );
271 if ( isset( $op[
'overwrite'] ) || isset( $op[
'overwriteSame'] ) ) {
272 $this->backend->store( $op );
275 $status = $this->backend->doOperation( $op );
278 "Store from $source to $dest succeeded without warnings ($backendName)." );
279 $this->assertEquals(
true,
$status->isOK(),
280 "Store from $source to $dest succeeded ($backendName)." );
281 $this->assertEquals( [ 0 =>
true ],
$status->success,
282 "Store from $source to $dest has proper 'success' field in Status ($backendName)." );
283 $this->assertEquals(
true, file_exists(
$source ),
284 "Source file $source still exists ($backendName)." );
285 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $dest ] ),
286 "Destination file $dest exists ($backendName)." );
288 $this->assertEquals( filesize(
$source ),
289 $this->backend->getFileSize( [
'src' => $dest ] ),
290 "Destination file $dest has correct size ($backendName)." );
293 $props2 = $this->backend->getFileProps( [
'src' => $dest ] );
294 $this->assertEquals( $props1, $props2,
295 "Source and destination have the same props ($backendName)." );
305 $op = [
'op' =>
'store',
'src' => $tmpName,
'dst' => $toPath ];
309 $op2[
'overwrite'] =
true;
313 $op3[
'overwriteSame'] =
true;
340 $this->
prepare( [
'dir' => dirname( $dest ) ] );
342 if ( isset( $op[
'ignoreMissingSource'] ) ) {
343 $status = $this->backend->doOperation( $op );
345 "Move from $source to $dest succeeded without warnings ($backendName)." );
346 $this->assertEquals( [ 0 =>
true ],
$status->success,
347 "Move from $source to $dest has proper 'success' field in Status ($backendName)." );
348 $this->assertEquals(
false, $this->backend->fileExists( [
'src' =>
$source ] ),
349 "Source file $source does not exist ($backendName)." );
350 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $dest ] ),
351 "Destination file $dest does not exist ($backendName)." );
356 $status = $this->backend->doOperation(
357 [
'op' =>
'create',
'content' =>
'blahblah',
'dst' =>
$source ] );
359 "Creation of file at $source succeeded ($backendName)." );
361 if ( isset( $op[
'overwrite'] ) || isset( $op[
'overwriteSame'] ) ) {
362 $this->backend->copy( $op );
365 $status = $this->backend->doOperation( $op );
368 "Copy from $source to $dest succeeded without warnings ($backendName)." );
369 $this->assertEquals(
true,
$status->isOK(),
370 "Copy from $source to $dest succeeded ($backendName)." );
371 $this->assertEquals( [ 0 =>
true ],
$status->success,
372 "Copy from $source to $dest has proper 'success' field in Status ($backendName)." );
373 $this->assertEquals(
true, $this->backend->fileExists( [
'src' =>
$source ] ),
374 "Source file $source still exists ($backendName)." );
375 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $dest ] ),
376 "Destination file $dest exists after copy ($backendName)." );
379 $this->backend->getFileSize( [
'src' =>
$source ] ),
380 $this->backend->getFileSize( [
'src' => $dest ] ),
381 "Destination file $dest has correct size ($backendName)." );
383 $props1 = $this->backend->getFileProps( [
'src' =>
$source ] );
384 $props2 = $this->backend->getFileProps( [
'src' => $dest ] );
385 $this->assertEquals( $props1, $props2,
386 "Source and destination have the same props ($backendName)." );
397 $op = [
'op' =>
'copy',
'src' =>
$source,
'dst' => $dest ];
405 $op2[
'overwrite'] =
true;
413 $op2[
'overwriteSame'] =
true;
421 $op2[
'ignoreMissingSource'] =
true;
429 $op2[
'ignoreMissingSource'] =
true;
460 $this->
prepare( [
'dir' => dirname( $dest ) ] );
462 if ( isset( $op[
'ignoreMissingSource'] ) ) {
463 $status = $this->backend->doOperation( $op );
465 "Move from $source to $dest succeeded without warnings ($backendName)." );
466 $this->assertEquals( [ 0 =>
true ],
$status->success,
467 "Move from $source to $dest has proper 'success' field in Status ($backendName)." );
468 $this->assertEquals(
false, $this->backend->fileExists( [
'src' =>
$source ] ),
469 "Source file $source does not exist ($backendName)." );
470 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $dest ] ),
471 "Destination file $dest does not exist ($backendName)." );
476 $status = $this->backend->doOperation(
477 [
'op' =>
'create',
'content' =>
'blahblah',
'dst' =>
$source ] );
479 "Creation of file at $source succeeded ($backendName)." );
481 if ( isset( $op[
'overwrite'] ) || isset( $op[
'overwriteSame'] ) ) {
482 $this->backend->copy( $op );
485 $status = $this->backend->doOperation( $op );
487 "Move from $source to $dest succeeded without warnings ($backendName)." );
488 $this->assertEquals(
true,
$status->isOK(),
489 "Move from $source to $dest succeeded ($backendName)." );
490 $this->assertEquals( [ 0 =>
true ],
$status->success,
491 "Move from $source to $dest has proper 'success' field in Status ($backendName)." );
492 $this->assertEquals(
false, $this->backend->fileExists( [
'src' =>
$source ] ),
493 "Source file $source does not still exists ($backendName)." );
494 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $dest ] ),
495 "Destination file $dest exists after move ($backendName)." );
497 $this->assertNotEquals(
498 $this->backend->getFileSize( [
'src' =>
$source ] ),
499 $this->backend->getFileSize( [
'src' => $dest ] ),
500 "Destination file $dest has correct size ($backendName)." );
502 $props1 = $this->backend->getFileProps( [
'src' =>
$source ] );
503 $props2 = $this->backend->getFileProps( [
'src' => $dest ] );
504 $this->assertEquals(
false, $props1[
'fileExists'],
505 "Source file does not exist accourding to props ($backendName)." );
506 $this->assertEquals(
true, $props2[
'fileExists'],
507 "Destination file exists accourding to props ($backendName)." );
518 $op = [
'op' =>
'move',
'src' =>
$source,
'dst' => $dest ];
526 $op2[
'overwrite'] =
true;
534 $op2[
'overwriteSame'] =
true;
542 $op2[
'ignoreMissingSource'] =
true;
550 $op2[
'ignoreMissingSource'] =
true;
582 $status = $this->backend->doOperation(
583 [
'op' =>
'create',
'content' =>
'blahblah',
'dst' =>
$source ] );
585 "Creation of file at $source succeeded ($backendName)." );
588 $status = $this->backend->doOperation( $op );
591 "Deletion of file at $source succeeded without warnings ($backendName)." );
592 $this->assertEquals(
true,
$status->isOK(),
593 "Deletion of file at $source succeeded ($backendName)." );
594 $this->assertEquals( [ 0 =>
true ],
$status->success,
595 "Deletion of file at $source has proper 'success' field in Status ($backendName)." );
597 $this->assertEquals(
false,
$status->isOK(),
598 "Deletion of file at $source failed ($backendName)." );
601 $this->assertEquals(
false, $this->backend->fileExists( [
'src' =>
$source ] ),
602 "Source file $source does not exist after move ($backendName)." );
605 $this->backend->getFileSize( [
'src' =>
$source ] ),
606 "Source file $source has correct size (false) ($backendName)." );
608 $props1 = $this->backend->getFileProps( [
'src' =>
$source ] );
609 $this->assertFalse( $props1[
'fileExists'],
610 "Source file $source does not exist according to props ($backendName)." );
620 $op = [
'op' =>
'delete',
'src' =>
$source ];
633 $op[
'ignoreMissingSource'] =
true;
640 $op[
'ignoreMissingSource'] =
true;
673 $status = $this->backend->doOperation(
674 [
'op' =>
'create',
'content' =>
'blahblah',
'dst' =>
$source,
675 'headers' => [
'Content-Disposition' =>
'xxx' ] ] );
677 "Creation of file at $source succeeded ($backendName)." );
679 $attr = $this->backend->getFileXAttributes( [
'src' =>
$source ] );
684 'headers' => [
'Content-Disposition' =>
'' ] ] );
686 "Removal of header for $source succeeded ($backendName)." );
689 $attr = $this->backend->getFileXAttributes( [
'src' =>
$source ] );
690 $this->assertFalse( isset( $attr[
'headers'][
'content-disposition'] ),
691 "File 'Content-Disposition' header removed." );
695 $status = $this->backend->doOperation( $op );
698 "Describe of file at $source succeeded without warnings ($backendName)." );
699 $this->assertEquals(
true,
$status->isOK(),
700 "Describe of file at $source succeeded ($backendName)." );
701 $this->assertEquals( [ 0 =>
true ],
$status->success,
702 "Describe of file at $source has proper 'success' field in Status ($backendName)." );
704 $attr = $this->backend->getFileXAttributes( [
'src' =>
$source ] );
708 $this->assertEquals(
false,
$status->isOK(),
709 "Describe of file at $source failed ($backendName)." );
716 foreach ( $headers
as $n => $v ) {
718 $this->assertTrue( isset( $attr[
'headers'][strtolower( $n )] ),
719 "File has '$n' header." );
720 $this->assertEquals( $v, $attr[
'headers'][strtolower( $n )],
721 "File has '$n' header value." );
723 $this->assertFalse( isset( $attr[
'headers'][strtolower( $n )] ),
724 "File does not have '$n' header." );
734 $op = [
'op' =>
'describe',
'src' =>
$source,
735 'headers' => [
'Content-Disposition' =>
'inline' ], ];
754 public function testCreate( $op, $alreadyExists, $okStatus, $newSize ) {
757 $this->
doTestCreate( $op, $alreadyExists, $okStatus, $newSize );
762 $this->
doTestCreate( $op, $alreadyExists, $okStatus, $newSize );
766 private function doTestCreate( $op, $alreadyExists, $okStatus, $newSize ) {
770 $this->
prepare( [
'dir' => dirname( $dest ) ] );
772 $oldText =
'blah...blah...waahwaah';
773 if ( $alreadyExists ) {
774 $status = $this->backend->doOperation(
775 [
'op' =>
'create',
'content' => $oldText,
'dst' => $dest ] );
777 "Creation of file at $dest succeeded ($backendName)." );
780 $status = $this->backend->doOperation( $op );
783 "Creation of file at $dest succeeded without warnings ($backendName)." );
784 $this->assertEquals(
true,
$status->isOK(),
785 "Creation of file at $dest succeeded ($backendName)." );
786 $this->assertEquals( [ 0 =>
true ],
$status->success,
787 "Creation of file at $dest has proper 'success' field in Status ($backendName)." );
789 $this->assertEquals(
false,
$status->isOK(),
790 "Creation of file at $dest failed ($backendName)." );
793 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $dest ] ),
794 "Destination file $dest exists after creation ($backendName)." );
796 $props1 = $this->backend->getFileProps( [
'src' => $dest ] );
797 $this->assertEquals(
true, $props1[
'fileExists'],
798 "Destination file $dest exists according to props ($backendName)." );
800 $this->assertEquals( $newSize, $props1[
'size'],
801 "Destination file $dest has expected size according to props ($backendName)." );
802 $this->assertEquals( $newSize,
803 $this->backend->getFileSize( [
'src' => $dest ] ),
804 "Destination file $dest has correct size ($backendName)." );
806 $this->assertEquals( strlen( $oldText ), $props1[
'size'],
807 "Destination file $dest has original size according to props ($backendName)." );
808 $this->assertEquals( strlen( $oldText ),
809 $this->backend->getFileSize( [
'src' => $dest ] ),
810 "Destination file $dest has original size according to props ($backendName)." );
824 $op = [
'op' =>
'create',
'content' =>
'test test testing',
'dst' => $dest ];
829 strlen( $op[
'content'] )
833 $op2[
'content'] =
"\n";
838 strlen( $op2[
'content'] )
842 $op2[
'content'] =
"fsf\n waf 3kt";
847 strlen( $op2[
'content'] )
851 $op2[
'content'] =
"egm'g gkpe gpqg eqwgwqg";
852 $op2[
'overwrite'] =
true;
857 strlen( $op2[
'content'] )
861 $op2[
'content'] =
"39qjmg3-qg";
862 $op2[
'overwriteSame'] =
true;
867 strlen( $op2[
'content'] )
888 "$base/unittest-cont1/e/fileA.a",
889 "$base/unittest-cont1/e/fileB.a",
890 "$base/unittest-cont1/e/fileC.a"
897 "Preparing $path succeeded without warnings ($backendName)." );
898 $createOps[] = [
'op' =>
'create',
'dst' =>
$path,
'content' => mt_rand( 0, 50000 ) ];
899 $copyOps[] = [
'op' =>
'copy',
'src' =>
$path,
'dst' =>
"$path-2" ];
900 $moveOps[] = [
'op' =>
'move',
'src' =>
"$path-2",
'dst' =>
"$path-3" ];
901 $purgeOps[] = [
'op' =>
'delete',
'src' =>
$path ];
902 $purgeOps[] = [
'op' =>
'delete',
'src' =>
"$path-3" ];
904 $purgeOps[] = [
'op' =>
'null' ];
907 $this->backend->doQuickOperations( $createOps ),
908 "Creation of source files succeeded ($backendName)." );
909 foreach ( $files
as $file ) {
910 $this->assertTrue( $this->backend->fileExists( [
'src' => $file ] ),
911 "File $file exists." );
915 $this->backend->doQuickOperations( $copyOps ),
916 "Quick copy of source files succeeded ($backendName)." );
917 foreach ( $files
as $file ) {
918 $this->assertTrue( $this->backend->fileExists( [
'src' =>
"$file-2" ] ),
919 "File $file-2 exists." );
923 $this->backend->doQuickOperations( $moveOps ),
924 "Quick move of source files succeeded ($backendName)." );
925 foreach ( $files
as $file ) {
926 $this->assertTrue( $this->backend->fileExists( [
'src' =>
"$file-3" ] ),
927 "File $file-3 move in." );
928 $this->assertFalse( $this->backend->fileExists( [
'src' =>
"$file-2" ] ),
929 "File $file-2 moved away." );
933 $this->backend->quickCopy( [
'src' => $files[0],
'dst' => $files[0] ] ),
934 "Copy of file {$files[0]} over itself succeeded ($backendName)." );
935 $this->assertTrue( $this->backend->fileExists( [
'src' => $files[0] ] ),
936 "File {$files[0]} still exists." );
939 $this->backend->quickMove( [
'src' => $files[0],
'dst' => $files[0] ] ),
940 "Move of file {$files[0]} over itself succeeded ($backendName)." );
941 $this->assertTrue( $this->backend->fileExists( [
'src' => $files[0] ] ),
942 "File {$files[0]} still exists." );
945 $this->backend->doQuickOperations( $purgeOps ),
946 "Quick deletion of source files succeeded ($backendName)." );
947 foreach ( $files
as $file ) {
948 $this->assertFalse( $this->backend->fileExists( [
'src' => $file ] ),
949 "File $file purged." );
950 $this->assertFalse( $this->backend->fileExists( [
'src' =>
"$file-3" ] ),
951 "File $file-3 purged." );
958 public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
981 'content' => $srcsContent[$i]
983 $expContent .= $srcsContent[$i];
985 $status = $this->backend->doOperations( $ops );
988 "Creation of source files succeeded ($backendName)." );
991 if ( $alreadyExists ) {
992 $ok = file_put_contents( $dest,
'blah...blah...waahwaah' ) !==
false;
993 $this->assertEquals(
true, $ok,
994 "Creation of file at $dest succeeded ($backendName)." );
996 $ok = file_put_contents( $dest,
'' ) !==
false;
997 $this->assertEquals(
true, $ok,
998 "Creation of 0-byte file at $dest succeeded ($backendName)." );
1005 "Creation of concat file at $dest succeeded without warnings ($backendName)." );
1006 $this->assertEquals(
true,
$status->isOK(),
1007 "Creation of concat file at $dest succeeded ($backendName)." );
1009 $this->assertEquals(
false,
$status->isOK(),
1010 "Creation of concat file at $dest failed ($backendName)." );
1014 $this->assertEquals(
true, is_file( $dest ),
1015 "Dest concat file $dest exists after creation ($backendName)." );
1017 $this->assertEquals(
true, is_file( $dest ),
1018 "Dest concat file $dest exists after failed creation ($backendName)." );
1021 $contents = file_get_contents( $dest );
1022 $this->assertNotEquals(
false, $contents,
"File at $dest exists ($backendName)." );
1025 $this->assertEquals( $expContent, $contents,
1026 "Concat file at $dest has correct contents ($backendName)." );
1028 $this->assertNotEquals( $expContent, $contents,
1029 "Concat file at $dest has correct contents ($backendName)." );
1060 $params = [
'srcs' => $srcs ];
1099 if ( $alreadyExists ) {
1103 "Creation of file at $path succeeded ($backendName)." );
1105 $size = $this->backend->getFileSize( [
'src' =>
$path ] );
1106 $time = $this->backend->getFileTimestamp( [
'src' =>
$path ] );
1107 $stat = $this->backend->getFileStat( [
'src' =>
$path ] );
1109 $this->assertEquals( strlen( $content ), $size,
1110 "Correct file size of '$path'" );
1112 "Correct file timestamp of '$path'" );
1114 $size = $stat[
'size'];
1115 $time = $stat[
'mtime'];
1116 $this->assertEquals( strlen( $content ), $size,
1117 "Correct file size of '$path'" );
1119 "Correct file timestamp of '$path'" );
1121 $this->backend->clearCache( [
$path ] );
1123 $size = $this->backend->getFileSize( [
'src' =>
$path ] );
1125 $this->assertEquals( strlen( $content ), $size,
1126 "Correct file size of '$path'" );
1128 $this->backend->preloadCache( [
$path ] );
1130 $size = $this->backend->getFileSize( [
'src' =>
$path ] );
1132 $this->assertEquals( strlen( $content ), $size,
1133 "Correct file size of '$path'" );
1135 $size = $this->backend->getFileSize( [
'src' =>
$path ] );
1136 $time = $this->backend->getFileTimestamp( [
'src' =>
$path ] );
1137 $stat = $this->backend->getFileStat( [
'src' =>
$path ] );
1139 $this->assertFalse( $size,
"Correct file size of '$path'" );
1140 $this->assertFalse(
$time,
"Correct file timestamp of '$path'" );
1141 $this->assertFalse( $stat,
"Correct file stat of '$path'" );
1149 $cases[] = [
"$base/unittest-cont1/e/b/z/some_file.txt",
"some file contents",
true ];
1150 $cases[] = [
"$base/unittest-cont1/e/b/some-other_file.txt",
"",
true ];
1151 $cases[] = [
"$base/unittest-cont1/e/b/some-diff_file.txt",
null,
false ];
1174 if ( $content !==
null ) {
1178 "Creation of file at $path succeeded ($backendName)." );
1181 $this->backend->streamFile( [
'src' =>
$path,
'headless' => 1,
'allowOB' => 1 ] );
1182 $data = ob_get_contents();
1185 $this->assertEquals( $content, $data,
"Correct content streamed from '$path'" );
1188 $this->backend->streamFile( [
'src' =>
$path,
'headless' => 1,
'allowOB' => 1 ] );
1189 $data = ob_get_contents();
1192 $this->assertRegExp(
'#<h1>File not found</h1>#', $data,
1193 "Correct content streamed from '$path' ($backendName)" );
1201 $cases[] = [
"$base/unittest-cont1/e/b/z/some_file.txt",
"some file contents" ];
1202 $cases[] = [
"$base/unittest-cont1/e/b/some-other_file.txt", null ];
1223 $path =
"$base/unittest-cont1/e/b/z/range_file.txt";
1224 $content =
"0123456789ABCDEF";
1229 "Creation of file at $path succeeded ($backendName)." );
1233 'bytes=0-3' =>
'0123',
1234 'bytes=4-8' =>
'45678',
1235 'bytes=15-15' =>
'F',
1236 'bytes=14-15' =>
'EF',
1237 'bytes=-5' =>
'BCDEF',
1239 'bytes=10-16' =>
'ABCDEF',
1240 'bytes=10-99' =>
'ABCDEF',
1243 foreach ( $ranges
as $range => $chunk ) {
1245 $this->backend->streamFile( [
'src' =>
$path,
'headless' => 1,
'allowOB' => 1,
1246 'options' => [
'range' => $range ] ] );
1247 $data = ob_get_contents();
1250 $this->assertEquals( $chunk, $data,
"Correct chunk streamed from '$path' for '$range'" );
1273 $content = (
array)$content;
1274 foreach ( $srcs
as $i => $src ) {
1275 $this->
prepare( [
'dir' => dirname( $src ) ] );
1276 $status = $this->backend->doOperation(
1277 [
'op' =>
'create',
'content' => $content[$i],
'dst' => $src ] );
1279 "Creation of file at $src succeeded ($backendName)." );
1283 $contents = $this->backend->getFileContentsMulti( [
'srcs' =>
$source ] );
1284 foreach ( $contents
as $path => $data ) {
1285 $this->assertNotEquals(
false, $data,
"Contents of $path exists ($backendName)." );
1286 $this->assertEquals(
1287 current( $content ),
1289 "Contents of $path is correct ($backendName)."
1293 $this->assertEquals(
1295 array_keys( $contents ),
1296 "Contents in right order ($backendName)."
1298 $this->assertEquals(
1301 "Contents array size correct ($backendName)."
1304 $data = $this->backend->getFileContents( [
'src' =>
$source ] );
1305 $this->assertNotEquals(
false, $data,
"Contents of $source exists ($backendName)." );
1306 $this->assertEquals( $content[0], $data,
"Contents of $source is correct ($backendName)." );
1314 $cases[] = [
"$base/unittest-cont1/e/b/z/some_file.txt",
"some file contents" ];
1315 $cases[] = [
"$base/unittest-cont1/e/b/some-other_file.txt",
"more file contents" ];
1317 [
"$base/unittest-cont1/e/a/x.txt",
"$base/unittest-cont1/e/a/y.txt",
1318 "$base/unittest-cont1/e/a/z.txt" ],
1319 [
"contents xx",
"contents xy",
"contents xz" ]
1344 $content = (
array)$content;
1345 foreach ( $srcs
as $i => $src ) {
1346 $this->
prepare( [
'dir' => dirname( $src ) ] );
1347 $status = $this->backend->doOperation(
1348 [
'op' =>
'create',
'content' => $content[$i],
'dst' => $src ] );
1350 "Creation of file at $src succeeded ($backendName)." );
1356 $this->assertNotNull( $tmpFile,
1357 "Creation of local copy of $path succeeded ($backendName)." );
1358 $contents = file_get_contents( $tmpFile->getPath() );
1359 $this->assertNotEquals(
false, $contents,
"Local copy of $path exists ($backendName)." );
1360 $this->assertEquals(
1361 current( $content ),
1363 "Local copy of $path is correct ($backendName)."
1367 $this->assertEquals(
1370 "Local copies in right order ($backendName)."
1372 $this->assertEquals(
1375 "Local copies array size correct ($backendName)."
1378 $tmpFile = $this->backend->getLocalCopy( [
'src' =>
$source ] );
1379 $this->assertNotNull( $tmpFile,
1380 "Creation of local copy of $source succeeded ($backendName)." );
1381 $contents = file_get_contents( $tmpFile->getPath() );
1382 $this->assertNotEquals(
false, $contents,
"Local copy of $source exists ($backendName)." );
1383 $this->assertEquals(
1386 "Local copy of $source is correct ($backendName)."
1390 $obj =
new stdClass();
1391 $tmpFile->bind( $obj );
1398 $cases[] = [
"$base/unittest-cont1/e/a/z/some_file.txt",
"some file contents" ];
1399 $cases[] = [
"$base/unittest-cont1/e/a/some-other_file.txt",
"more file contents" ];
1400 $cases[] = [
"$base/unittest-cont1/e/a/\$odd&.txt",
"test file contents" ];
1402 [
"$base/unittest-cont1/e/a/x.txt",
"$base/unittest-cont1/e/a/y.txt",
1403 "$base/unittest-cont1/e/a/z.txt" ],
1404 [
"contents xx $",
"contents xy 111",
"contents xz" ]
1429 $content = (
array)$content;
1430 foreach ( $srcs
as $i => $src ) {
1431 $this->
prepare( [
'dir' => dirname( $src ) ] );
1432 $status = $this->backend->doOperation(
1433 [
'op' =>
'create',
'content' => $content[$i],
'dst' => $src ] );
1435 "Creation of file at $src succeeded ($backendName)." );
1439 $tmpFiles = $this->backend->getLocalReferenceMulti( [
'srcs' =>
$source ] );
1441 $this->assertNotNull( $tmpFile,
1442 "Creation of local copy of $path succeeded ($backendName)." );
1443 $contents = file_get_contents( $tmpFile->getPath() );
1444 $this->assertNotEquals(
false, $contents,
"Local ref of $path exists ($backendName)." );
1445 $this->assertEquals(
1446 current( $content ),
1448 "Local ref of $path is correct ($backendName)."
1452 $this->assertEquals(
1455 "Local refs in right order ($backendName)."
1457 $this->assertEquals(
1460 "Local refs array size correct ($backendName)."
1463 $tmpFile = $this->backend->getLocalReference( [
'src' =>
$source ] );
1464 $this->assertNotNull( $tmpFile,
1465 "Creation of local copy of $source succeeded ($backendName)." );
1466 $contents = file_get_contents( $tmpFile->getPath() );
1467 $this->assertNotEquals(
false, $contents,
"Local ref of $source exists ($backendName)." );
1468 $this->assertEquals( $content[0], $contents,
"Local ref of $source is correct ($backendName)." );
1476 $cases[] = [
"$base/unittest-cont1/e/a/z/some_file.txt",
"some file contents" ];
1477 $cases[] = [
"$base/unittest-cont1/e/a/some-other_file.txt",
"more file contents" ];
1478 $cases[] = [
"$base/unittest-cont1/e/a/\$odd&.txt",
"test file contents" ];
1480 [
"$base/unittest-cont1/e/a/x.txt",
"$base/unittest-cont1/e/a/y.txt",
1481 "$base/unittest-cont1/e/a/z.txt" ],
1482 [
"contents xx 1111",
"contents xy %",
"contents xz $" ]
1505 $tmpFile = $this->backend->getLocalCopy( [
1506 'src' =>
"$base/unittest-cont1/not-there" ] );
1507 $this->assertEquals(
null, $tmpFile,
"Local copy of not existing file is null ($backendName)." );
1509 $tmpFile = $this->backend->getLocalReference( [
1510 'src' =>
"$base/unittest-cont1/not-there" ] );
1511 $this->assertEquals(
null, $tmpFile,
"Local ref of not existing file is null ($backendName)." );
1533 $status = $this->backend->doOperation(
1534 [
'op' =>
'create',
'content' => $content,
'dst' =>
$source ] );
1536 "Creation of file at $source succeeded ($backendName)." );
1538 $url = $this->backend->getFileHttpUrl( [
'src' =>
$source ] );
1540 if ( $url !==
null ) {
1542 $this->assertEquals( $content, $data,
1543 "HTTP GET of URL has right contents ($backendName)." );
1551 $cases[] = [
"$base/unittest-cont1/e/a/z/some_file.txt",
"some file contents" ];
1552 $cases[] = [
"$base/unittest-cont1/e/a/some-other_file.txt",
"more file contents" ];
1553 $cases[] = [
"$base/unittest-cont1/e/a/\$odd&.txt",
"test file contents" ];
1575 [
"$base/unittest-cont1/e/a/z/some_file1.txt",
true ],
1576 [
"$base/unittest-cont2/a/z/some_file2.txt",
true ],
1577 # Specific to FS backend with no basePath field set
1578 # [ "$base/unittest-cont3/a/z/some_file3.txt", false ],
1588 "Preparing dir $path succeeded without warnings ($backendName)." );
1589 $this->assertEquals(
true,
$status->isOK(),
1590 "Preparing dir $path succeeded ($backendName)." );
1592 $this->assertEquals(
false,
$status->isOK(),
1593 "Preparing dir $path failed ($backendName)." );
1596 $status = $this->backend->secure( [
'dir' => dirname(
$path ) ] );
1599 "Securing dir $path succeeded without warnings ($backendName)." );
1600 $this->assertEquals(
true,
$status->isOK(),
1601 "Securing dir $path succeeded ($backendName)." );
1603 $this->assertEquals(
false,
$status->isOK(),
1604 "Securing dir $path failed ($backendName)." );
1607 $status = $this->backend->publish( [
'dir' => dirname(
$path ) ] );
1610 "Publishing dir $path succeeded without warnings ($backendName)." );
1611 $this->assertEquals(
true,
$status->isOK(),
1612 "Publishing dir $path succeeded ($backendName)." );
1614 $this->assertEquals(
false,
$status->isOK(),
1615 "Publishing dir $path failed ($backendName)." );
1618 $status = $this->backend->clean( [
'dir' => dirname(
$path ) ] );
1621 "Cleaning dir $path succeeded without warnings ($backendName)." );
1622 $this->assertEquals(
true,
$status->isOK(),
1623 "Cleaning dir $path succeeded ($backendName)." );
1625 $this->assertEquals(
false,
$status->isOK(),
1626 "Cleaning dir $path failed ($backendName)." );
1645 "$base/unittest-cont1",
1646 "$base/unittest-cont1/e",
1647 "$base/unittest-cont1/e/a",
1648 "$base/unittest-cont1/e/a/b",
1649 "$base/unittest-cont1/e/a/b/c",
1650 "$base/unittest-cont1/e/a/b/c/d0",
1651 "$base/unittest-cont1/e/a/b/c/d1",
1652 "$base/unittest-cont1/e/a/b/c/d2",
1653 "$base/unittest-cont1/e/a/b/c/d0/1",
1654 "$base/unittest-cont1/e/a/b/c/d0/2",
1655 "$base/unittest-cont1/e/a/b/c/d1/3",
1656 "$base/unittest-cont1/e/a/b/c/d1/4",
1657 "$base/unittest-cont1/e/a/b/c/d2/5",
1658 "$base/unittest-cont1/e/a/b/c/d2/6"
1663 "Preparing dir $dir succeeded without warnings ($backendName)." );
1668 $this->assertEquals(
true, $this->backend->directoryExists( [
'dir' =>
$dir ] ),
1669 "Dir $dir exists ($backendName)." );
1673 $status = $this->backend->clean(
1674 [
'dir' =>
"$base/unittest-cont1",
'recursive' => 1 ] );
1676 "Recursive cleaning of dir $dir succeeded without warnings ($backendName)." );
1679 $this->assertEquals(
false, $this->backend->directoryExists( [
'dir' =>
$dir ] ),
1680 "Dir $dir no longer exists ($backendName)." );
1699 $fileA =
"$base/unittest-cont1/e/a/b/fileA.txt";
1700 $fileAContents =
'3tqtmoeatmn4wg4qe-mg3qt3 tq';
1701 $fileB =
"$base/unittest-cont1/e/a/b/fileB.txt";
1702 $fileBContents =
'g-jmq3gpqgt3qtg q3GT ';
1703 $fileC =
"$base/unittest-cont1/e/a/b/fileC.txt";
1704 $fileCContents =
'eigna[ogmewt 3qt g3qg flew[ag';
1705 $fileD =
"$base/unittest-cont1/e/a/b/fileD.txt";
1707 $this->
prepare( [
'dir' => dirname( $fileA ) ] );
1708 $this->
create( [
'dst' => $fileA,
'content' => $fileAContents ] );
1709 $this->
prepare( [
'dir' => dirname( $fileB ) ] );
1710 $this->
create( [
'dst' => $fileB,
'content' => $fileBContents ] );
1711 $this->
prepare( [
'dir' => dirname( $fileC ) ] );
1712 $this->
create( [
'dst' => $fileC,
'content' => $fileCContents ] );
1713 $this->
prepare( [
'dir' => dirname( $fileD ) ] );
1715 $status = $this->backend->doOperations( [
1716 [
'op' =>
'describe',
'src' => $fileA,
1717 'headers' => [
'X-Content-Length' =>
'91.3' ],
'disposition' =>
'inline' ],
1718 [
'op' =>
'copy',
'src' => $fileA,
'dst' => $fileC,
'overwrite' => 1 ],
1720 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileA,
'overwriteSame' => 1 ],
1722 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileD,
'overwrite' => 1 ],
1724 [
'op' =>
'move',
'src' => $fileB,
'dst' => $fileC ],
1726 [
'op' =>
'move',
'src' => $fileD,
'dst' => $fileA,
'overwriteSame' => 1 ],
1728 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileA,
'overwrite' => 1 ],
1730 [
'op' =>
'copy',
'src' => $fileA,
'dst' => $fileC ],
1732 [
'op' =>
'move',
'src' => $fileA,
'dst' => $fileC,
'overwriteSame' => 1 ],
1734 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileC,
'overwrite' => 1 ],
1736 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileC,
'overwriteSame' => 1 ],
1738 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileC,
'overwrite' => 1 ],
1740 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileC,
'overwriteSame' => 1 ],
1747 $this->assertEquals(
true,
$status->isOK(),
"Operation batch succeeded" );
1749 "Operation batch has correct success array" );
1751 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileA ] ),
1752 "File does not exist at $fileA" );
1753 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileB ] ),
1754 "File does not exist at $fileB" );
1755 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileD ] ),
1756 "File does not exist at $fileD" );
1758 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $fileC ] ),
1759 "File exists at $fileC" );
1760 $this->assertEquals( $fileBContents,
1761 $this->backend->getFileContents( [
'src' => $fileC ] ),
1762 "Correct file contents of $fileC" );
1763 $this->assertEquals( strlen( $fileBContents ),
1764 $this->backend->getFileSize( [
'src' => $fileC ] ),
1765 "Correct file size of $fileC" );
1766 $this->assertEquals(
Wikimedia\base_convert( sha1( $fileBContents ), 16, 36, 31 ),
1767 $this->backend->getFileSha1Base36( [
'src' => $fileC ] ),
1768 "Correct file SHA-1 of $fileC" );
1787 $fileAContents =
'3tqtmoeatmn4wg4qe-mg3qt3 tq';
1788 $fileBContents =
'g-jmq3gpqgt3qtg q3GT ';
1789 $fileCContents =
'eigna[ogmewt 3qt g3qg flew[ag';
1794 $this->
addTmpFiles( [ $tmpNameA, $tmpNameB, $tmpNameC ] );
1795 file_put_contents( $tmpNameA, $fileAContents );
1796 file_put_contents( $tmpNameB, $fileBContents );
1797 file_put_contents( $tmpNameC, $fileCContents );
1799 $fileA =
"$base/unittest-cont1/e/a/b/fileA.txt";
1800 $fileB =
"$base/unittest-cont1/e/a/b/fileB.txt";
1801 $fileC =
"$base/unittest-cont1/e/a/b/fileC.txt";
1802 $fileD =
"$base/unittest-cont1/e/a/b/fileD.txt";
1804 $this->
prepare( [
'dir' => dirname( $fileA ) ] );
1805 $this->
create( [
'dst' => $fileA,
'content' => $fileAContents ] );
1806 $this->
prepare( [
'dir' => dirname( $fileB ) ] );
1807 $this->
prepare( [
'dir' => dirname( $fileC ) ] );
1808 $this->
prepare( [
'dir' => dirname( $fileD ) ] );
1810 $status = $this->backend->doOperations( [
1811 [
'op' =>
'store',
'src' => $tmpNameA,
'dst' => $fileA,
'overwriteSame' => 1 ],
1812 [
'op' =>
'store',
'src' => $tmpNameB,
'dst' => $fileB,
'overwrite' => 1 ],
1813 [
'op' =>
'store',
'src' => $tmpNameC,
'dst' => $fileC,
'overwrite' => 1 ],
1814 [
'op' =>
'copy',
'src' => $fileA,
'dst' => $fileC,
'overwrite' => 1 ],
1816 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileA,
'overwriteSame' => 1 ],
1818 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileD,
'overwrite' => 1 ],
1820 [
'op' =>
'move',
'src' => $fileB,
'dst' => $fileC ],
1822 [
'op' =>
'move',
'src' => $fileD,
'dst' => $fileA,
'overwriteSame' => 1 ],
1824 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileA,
'overwrite' => 1 ],
1826 [
'op' =>
'copy',
'src' => $fileA,
'dst' => $fileC ],
1828 [
'op' =>
'move',
'src' => $fileA,
'dst' => $fileC,
'overwriteSame' => 1 ],
1830 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileC,
'overwrite' => 1 ],
1832 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileC,
'overwriteSame' => 1 ],
1834 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileC,
'overwrite' => 1 ],
1836 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileC,
'overwriteSame' => 1 ],
1843 $this->assertEquals(
true,
$status->isOK(),
"Operation batch succeeded" );
1845 "Operation batch has correct success array" );
1847 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileA ] ),
1848 "File does not exist at $fileA" );
1849 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileB ] ),
1850 "File does not exist at $fileB" );
1851 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileD ] ),
1852 "File does not exist at $fileD" );
1854 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $fileC ] ),
1855 "File exists at $fileC" );
1856 $this->assertEquals( $fileBContents,
1857 $this->backend->getFileContents( [
'src' => $fileC ] ),
1858 "Correct file contents of $fileC" );
1859 $this->assertEquals( strlen( $fileBContents ),
1860 $this->backend->getFileSize( [
'src' => $fileC ] ),
1861 "Correct file size of $fileC" );
1862 $this->assertEquals(
Wikimedia\base_convert( sha1( $fileBContents ), 16, 36, 31 ),
1863 $this->backend->getFileSha1Base36( [
'src' => $fileC ] ),
1864 "Correct file SHA-1 of $fileC" );
1882 $fileA =
"$base/unittest-cont2/a/b/fileA.txt";
1883 $fileAContents =
'3tqtmoeatmn4wg4qe-mg3qt3 tq';
1884 $fileB =
"$base/unittest-cont2/a/b/fileB.txt";
1885 $fileBContents =
'g-jmq3gpqgt3qtg q3GT ';
1886 $fileC =
"$base/unittest-cont2/a/b/fileC.txt";
1887 $fileCContents =
'eigna[ogmewt 3qt g3qg flew[ag';
1888 $fileD =
"$base/unittest-cont2/a/b/fileD.txt";
1890 $this->
prepare( [
'dir' => dirname( $fileA ) ] );
1891 $this->
create( [
'dst' => $fileA,
'content' => $fileAContents ] );
1892 $this->
prepare( [
'dir' => dirname( $fileB ) ] );
1893 $this->
create( [
'dst' => $fileB,
'content' => $fileBContents ] );
1894 $this->
prepare( [
'dir' => dirname( $fileC ) ] );
1895 $this->
create( [
'dst' => $fileC,
'content' => $fileCContents ] );
1897 $status = $this->backend->doOperations( [
1898 [
'op' =>
'copy',
'src' => $fileA,
'dst' => $fileC,
'overwrite' => 1 ],
1900 [
'op' =>
'copy',
'src' => $fileC,
'dst' => $fileA,
'overwriteSame' => 1 ],
1902 [
'op' =>
'copy',
'src' => $fileB,
'dst' => $fileD,
'overwrite' => 1 ],
1904 [
'op' =>
'move',
'src' => $fileC,
'dst' => $fileD ],
1906 [
'op' =>
'move',
'src' => $fileB,
'dst' => $fileC,
'overwriteSame' => 1 ],
1908 [
'op' =>
'move',
'src' => $fileB,
'dst' => $fileA,
'overwrite' => 1 ],
1910 [
'op' =>
'delete',
'src' => $fileD ],
1914 ], [
'force' => 1 ] );
1916 $this->assertNotEquals( [],
$status->getErrors(),
"Operation had warnings" );
1917 $this->assertEquals(
true,
$status->isOK(),
"Operation batch succeeded" );
1919 "Operation batch has correct success array" );
1921 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileB ] ),
1922 "File does not exist at $fileB" );
1923 $this->assertEquals(
false, $this->backend->fileExists( [
'src' => $fileD ] ),
1924 "File does not exist at $fileD" );
1926 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $fileA ] ),
1927 "File does not exist at $fileA" );
1928 $this->assertEquals(
true, $this->backend->fileExists( [
'src' => $fileC ] ),
1929 "File exists at $fileC" );
1930 $this->assertEquals( $fileBContents,
1931 $this->backend->getFileContents( [
'src' => $fileA ] ),
1932 "Correct file contents of $fileA" );
1933 $this->assertEquals( strlen( $fileBContents ),
1934 $this->backend->getFileSize( [
'src' => $fileA ] ),
1935 "Correct file size of $fileA" );
1936 $this->assertEquals(
Wikimedia\base_convert( sha1( $fileBContents ), 16, 36, 31 ),
1937 $this->backend->getFileSha1Base36( [
'src' => $fileA ] ),
1938 "Correct file SHA-1 of $fileA" );
1958 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont-notexists" ] );
1961 "$base/unittest-cont1/e/test1.txt",
1962 "$base/unittest-cont1/e/test2.txt",
1963 "$base/unittest-cont1/e/test3.txt",
1964 "$base/unittest-cont1/e/subdir1/test1.txt",
1965 "$base/unittest-cont1/e/subdir1/test2.txt",
1966 "$base/unittest-cont1/e/subdir2/test3.txt",
1967 "$base/unittest-cont1/e/subdir2/test4.txt",
1968 "$base/unittest-cont1/e/subdir2/subdir/test1.txt",
1969 "$base/unittest-cont1/e/subdir2/subdir/test2.txt",
1970 "$base/unittest-cont1/e/subdir2/subdir/test3.txt",
1971 "$base/unittest-cont1/e/subdir2/subdir/test4.txt",
1972 "$base/unittest-cont1/e/subdir2/subdir/test5.txt",
1973 "$base/unittest-cont1/e/subdir2/subdir/sub/test0.txt",
1974 "$base/unittest-cont1/e/subdir2/subdir/sub/120-px-file.txt",
1979 foreach ( $files
as $file ) {
1980 $this->
prepare( [
'dir' => dirname( $file ) ] );
1981 $ops[] = [
'op' =>
'create',
'content' =>
'xxy',
'dst' => $file ];
1983 $status = $this->backend->doQuickOperations( $ops );
1985 "Creation of files succeeded ($backendName)." );
1986 $this->assertEquals(
true,
$status->isOK(),
1987 "Creation of files succeeded with OK status ($backendName)." );
1994 "e/subdir1/test1.txt",
1995 "e/subdir1/test2.txt",
1996 "e/subdir2/test3.txt",
1997 "e/subdir2/test4.txt",
1998 "e/subdir2/subdir/test1.txt",
1999 "e/subdir2/subdir/test2.txt",
2000 "e/subdir2/subdir/test3.txt",
2001 "e/subdir2/subdir/test4.txt",
2002 "e/subdir2/subdir/test5.txt",
2003 "e/subdir2/subdir/sub/test0.txt",
2004 "e/subdir2/subdir/sub/120-px-file.txt",
2009 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont1" ] );
2012 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2015 $iter = $this->backend->getFileList( [
2016 'dir' =>
"$base/unittest-cont1",
2021 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2025 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont1/" ] );
2026 foreach ( $iter
as $file ) {
2030 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2040 "sub/120-px-file.txt",
2045 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont1/e/subdir2/subdir" ] );
2048 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2051 $iter = $this->backend->getFileList( [
2052 'dir' =>
"$base/unittest-cont1/e/subdir2/subdir",
2057 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2061 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont1/e/subdir2/subdir/" ] );
2062 foreach ( $iter
as $file ) {
2066 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName)." );
2071 $this->assertEquals( $expected, $list,
"Correct file listing ($backendName), second iteration." );
2074 $iter = $this->backend->getTopFileList( [
'dir' =>
"$base/unittest-cont1" ] );
2077 $this->assertEquals( [], $list,
"Correct top file listing ($backendName)." );
2090 $iter = $this->backend->getTopFileList(
2091 [
'dir' =>
"$base/unittest-cont1/e/subdir2/subdir" ]
2095 $this->assertEquals( $expected, $list,
"Correct top file listing ($backendName)." );
2098 $iter = $this->backend->getTopFileList( [
2099 'dir' =>
"$base/unittest-cont1/e/subdir2/subdir",
2104 $this->assertEquals( $expected, $list,
"Correct top file listing ($backendName)." );
2106 foreach ( $files
as $file ) {
2107 $this->backend->doOperation( [
'op' =>
'delete',
'src' => $file ] );
2110 $iter = $this->backend->getFileList( [
'dir' =>
"$base/unittest-cont1/not/exists" ] );
2111 foreach ( $iter
as $iter ) {
2133 "$base/unittest-cont1/e/test1.txt",
2134 "$base/unittest-cont1/e/test2.txt",
2135 "$base/unittest-cont1/e/test3.txt",
2136 "$base/unittest-cont1/e/subdir1/test1.txt",
2137 "$base/unittest-cont1/e/subdir1/test2.txt",
2138 "$base/unittest-cont1/e/subdir2/test3.txt",
2139 "$base/unittest-cont1/e/subdir2/test4.txt",
2140 "$base/unittest-cont1/e/subdir2/subdir/test1.txt",
2141 "$base/unittest-cont1/e/subdir3/subdir/test2.txt",
2142 "$base/unittest-cont1/e/subdir4/subdir/test3.txt",
2143 "$base/unittest-cont1/e/subdir4/subdir/test4.txt",
2144 "$base/unittest-cont1/e/subdir4/subdir/test5.txt",
2145 "$base/unittest-cont1/e/subdir4/subdir/sub/test0.txt",
2146 "$base/unittest-cont1/e/subdir4/subdir/sub/120-px-file.txt",
2151 foreach ( $files
as $file ) {
2152 $this->
prepare( [
'dir' => dirname( $file ) ] );
2153 $ops[] = [
'op' =>
'create',
'content' =>
'xxy',
'dst' => $file ];
2155 $status = $this->backend->doQuickOperations( $ops );
2157 "Creation of files succeeded ($backendName)." );
2158 $this->assertEquals(
true,
$status->isOK(),
2159 "Creation of files succeeded with OK status ($backendName)." );
2161 $this->assertEquals(
true,
2162 $this->backend->directoryExists( [
'dir' =>
"$base/unittest-cont1/e/subdir1" ] ),
2163 "Directory exists in ($backendName)." );
2164 $this->assertEquals(
true,
2165 $this->backend->directoryExists( [
'dir' =>
"$base/unittest-cont1/e/subdir2/subdir" ] ),
2166 "Directory exists in ($backendName)." );
2167 $this->assertEquals(
false,
2168 $this->backend->directoryExists( [
'dir' =>
"$base/unittest-cont1/e/subdir2/test1.txt" ] ),
2169 "Directory does not exists in ($backendName)." );
2179 $iter = $this->backend->getTopDirectoryList( [
'dir' =>
"$base/unittest-cont1" ] );
2180 foreach ( $iter
as $file ) {
2185 $this->assertEquals( $expected, $list,
"Correct top dir listing ($backendName)." );
2198 $iter = $this->backend->getTopDirectoryList( [
'dir' =>
"$base/unittest-cont1/e" ] );
2199 foreach ( $iter
as $file ) {
2204 $this->assertEquals( $expected, $list,
"Correct top dir listing ($backendName)." );
2208 $iter = $this->backend->getTopDirectoryList( [
'dir' =>
"$base/unittest-cont1/e/" ] );
2209 foreach ( $iter
as $file ) {
2214 $this->assertEquals( $expected, $list,
"Correct top dir listing ($backendName)." );
2224 $iter = $this->backend->getTopDirectoryList( [
'dir' =>
"$base/unittest-cont1/e/subdir2" ] );
2225 foreach ( $iter
as $file ) {
2230 $this->assertEquals( $expected, $list,
"Correct top dir listing ($backendName)." );
2234 $iter = $this->backend->getTopDirectoryList(
2235 [
'dir' =>
"$base/unittest-cont1/e/subdir2/" ]
2238 foreach ( $iter
as $file ) {
2243 $this->assertEquals( $expected, $list,
"Correct top dir listing ($backendName)." );
2247 foreach ( $iter
as $file ) {
2252 $this->assertEquals(
2255 "Correct top dir listing ($backendName), second iteration."
2268 "e/subdir4/subdir/sub",
2274 $iter = $this->backend->getDirectoryList( [
'dir' =>
"$base/unittest-cont1/" ] );
2275 foreach ( $iter
as $file ) {
2280 $this->assertEquals( $expected, $list,
"Correct dir listing ($backendName)." );
2291 $iter = $this->backend->getDirectoryList( [
'dir' =>
"$base/unittest-cont1/e/subdir4" ] );
2292 foreach ( $iter
as $file ) {
2297 $this->assertEquals( $expected, $list,
"Correct dir listing ($backendName)." );
2301 foreach ( $iter
as $file ) {
2306 $this->assertEquals( $expected, $list,
"Correct dir listing ($backendName)." );
2308 $iter = $this->backend->getDirectoryList( [
'dir' =>
"$base/unittest-cont1/e/subdir1" ] );
2310 $this->assertEquals( [], $items,
"Directory listing is empty." );
2312 foreach ( $files
as $file ) {
2313 $this->backend->doOperation( [
'op' =>
'delete',
'src' => $file ] );
2316 $iter = $this->backend->getDirectoryList( [
'dir' =>
"$base/unittest-cont1/not/exists" ] );
2317 foreach ( $iter
as $file ) {
2322 $this->assertEquals( [], $items,
"Directory listing is empty." );
2324 $iter = $this->backend->getDirectoryList( [
'dir' =>
"$base/unittest-cont1/e/not/exists" ] );
2326 $this->assertEquals( [], $items,
"Directory listing is empty." );
2343 "subdir1/test1.txt",
2344 "subdir1/test2.txt",
2347 "subdir2/test3.txt",
2348 "subdir2/test4.txt",
2350 "subdir2/subdir/test1.txt",
2351 "subdir2/subdir/test2.txt",
2352 "subdir2/subdir/test3.txt",
2353 "subdir2/subdir/test4.txt",
2354 "subdir2/subdir/test5.txt",
2355 "subdir2/subdir/sub",
2356 "subdir2/subdir/sub/test0.txt",
2357 "subdir2/subdir/sub/120-px-file.txt",
2360 for ( $i = 0; $i < 25; $i++ ) {
2362 $this->assertEquals( print_r( [],
true ), print_r(
$status->getErrors(),
true ),
2363 "Locking of files succeeded ($backendName) ($i)." );
2364 $this->assertEquals(
true,
$status->isOK(),
2365 "Locking of files succeeded with OK status ($backendName) ($i)." );
2368 $this->assertEquals( print_r( [],
true ), print_r(
$status->getErrors(),
true ),
2369 "Locking of files succeeded ($backendName) ($i)." );
2370 $this->assertEquals(
true,
$status->isOK(),
2371 "Locking of files succeeded with OK status ($backendName) ($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)." );
2385 # # Flip the acquire/release ordering around ##
2388 $this->assertEquals( print_r( [],
true ), print_r(
$status->getErrors(),
true ),
2389 "Locking of files succeeded ($backendName) ($i)." );
2390 $this->assertEquals(
true,
$status->isOK(),
2391 "Locking of files succeeded with OK status ($backendName) ($i)." );
2394 $this->assertEquals( print_r( [],
true ), print_r(
$status->getErrors(),
true ),
2395 "Locking of files succeeded ($backendName) ($i)." );
2396 $this->assertEquals(
true,
$status->isOK(),
2397 "Locking of files succeeded with OK status ($backendName) ($i)." );
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)." );
2414 $this->assertInstanceOf(
'ScopedLock', $sl,
2415 "Scoped locking of files succeeded ($backendName)." );
2416 $this->assertEquals( [],
$status->getErrors(),
2417 "Scoped locking of files succeeded ($backendName)." );
2418 $this->assertEquals(
true,
$status->isOK(),
2419 "Scoped locking of files succeeded with OK status ($backendName)." );
2422 $this->assertEquals(
null, $sl,
2423 "Scoped unlocking of files succeeded ($backendName)." );
2424 $this->assertEquals( [],
$status->getErrors(),
2425 "Scoped unlocking of files succeeded ($backendName)." );
2426 $this->assertEquals(
true,
$status->isOK(),
2427 "Scoped unlocking of files succeeded with OK status ($backendName)." );
2438 'name' =>
'testing',
2439 'class' =>
'MemoryFileBackend',
2441 'mimeCallback' => $mimeCallback
2445 $dst =
'mwstore://testing/container/path/to/file_no_ext';
2446 $src =
"$IP/tests/phpunit/data/media/srgb.jpg";
2447 $this->assertEquals(
'image/jpeg', $be->getContentType( $dst,
null, $src ) );
2448 $this->assertEquals(
2449 $mimeFromString ?
'image/jpeg' :
'unknown/unknown',
2450 $be->getContentType( $dst, file_get_contents( $src ),
null ) );
2452 $src =
"$IP/tests/phpunit/data/media/Png-native-test.png";
2453 $this->assertEquals(
'image/png', $be->getContentType( $dst,
null, $src ) );
2454 $this->assertEquals(
2455 $mimeFromString ?
'image/png' :
'unknown/unknown',
2456 $be->getContentType( $dst, file_get_contents( $src ),
null ) );
2467 $be = TestingAccessWrapper::newFromObject(
2469 'name' =>
'localtesting',
2470 'wikiId' =>
wfWikiID() . mt_rand(),
2473 'name' =>
'multitesting0',
2474 'class' =>
'MemoryFileBackend',
2475 'isMultiMaster' =>
false,
2476 'readAffinity' =>
true
2479 'name' =>
'multitesting1',
2480 'class' =>
'MemoryFileBackend',
2481 'isMultiMaster' =>
true
2487 $this->assertEquals(
2489 $be->getReadIndexFromParams( [
'latest' => 1 ] ),
2490 'Reads with "latest" flag use backend 1'
2492 $this->assertEquals(
2494 $be->getReadIndexFromParams( [
'latest' => 0 ] ),
2495 'Reads without "latest" flag use backend 0'
2498 $p =
'container/test-cont/file.txt';
2499 $be->backends[0]->quickCreate( [
2500 'dst' =>
"mwstore://multitesting0/$p",
'content' =>
'cattitude' ] );
2501 $be->backends[1]->quickCreate( [
2502 'dst' =>
"mwstore://multitesting1/$p",
'content' =>
'princess of power' ] );
2504 $this->assertEquals(
2506 $be->getFileContents( [
'src' =>
"mwstore://localtesting/$p" ] ),
2507 "Non-latest read came from backend 0"
2509 $this->assertEquals(
2510 'princess of power',
2511 $be->getFileContents( [
'src' =>
"mwstore://localtesting/$p",
'latest' => 1 ] ),
2512 "Latest read came from backend1"
2517 $be = TestingAccessWrapper::newFromObject(
2519 'name' =>
'localtesting',
2520 'wikiId' =>
wfWikiID() . mt_rand(),
2523 'name' =>
'multitesting0',
2524 'class' =>
'MemoryFileBackend',
2525 'isMultiMaster' =>
false
2528 'name' =>
'multitesting1',
2529 'class' =>
'MemoryFileBackend',
2530 'isMultiMaster' =>
true
2533 'replication' =>
'async'
2539 $p =
'container/test-cont/file.txt';
2541 'dst' =>
"mwstore://localtesting/$p",
'content' =>
'cattitude' ] );
2543 $this->assertEquals(
2545 $be->backends[0]->getFileContents( [
'src' =>
"mwstore://multitesting0/$p" ] ),
2546 "File not yet written to backend 0"
2548 $this->assertEquals(
2550 $be->backends[1]->getFileContents( [
'src' =>
"mwstore://multitesting1/$p" ] ),
2551 "File already written to backend 1"
2556 $this->assertEquals(
2558 $be->backends[0]->getFileContents( [
'src' =>
"mwstore://multitesting0/$p" ] ),
2559 "File now written to backend 0"
2565 'name' =>
'localtesting',
2574 'Content-dUration' => 25.6,
2575 'X-LONG-VALUE' => str_pad(
'0', 300 ),
2576 'CONTENT-LENGTH' => 855055,
2582 'content-duration' => 25.6,
2583 'content-length' => 855055
2587 MediaWiki\suppressWarnings();
2588 $actual = $be->sanitizeOpHeaders(
$input );
2589 MediaWiki\restoreWarnings();
2591 $this->assertEquals( $expected, $actual,
"Header sanitized properly" );
2596 return is_array( $iter ) ? $iter : iterator_to_array( $iter );
2601 return $this->backend->prepare(
$params );
2608 return $this->backend->doQuickOperations( [
$params ] );
2612 $containers = [
'unittest-cont1',
'unittest-cont2',
'unittest-cont-bad' ];
2613 foreach ( $containers
as $container ) {
2620 $iter = $this->backend->getFileList( [
'dir' =>
"$base/$container" ] );
2622 foreach ( $iter
as $file ) {
2623 $this->backend->quickDelete( [
'src' =>
"$base/$container/$file" ] );
2628 $this->backend->clean( [
'dir' =>
"$base/$container",
'recursive' => 1 ] );
2633 $status = $this->backend->consistencyCheck( $paths );
2639 $this->assertEquals( print_r( [], 1 ), print_r(
$status->getErrors(), 1 ), $msg );