22 if ( $this->
getCliArg(
'use-filebackend' ) ) {
23 if ( self::$backendToUse ) {
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 );
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)." );
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)." );
366 $op = [
'op' =>
'copy',
'src' =>
$source,
'dst' => $dest ];
374 $op2[
'overwrite'] =
true;
382 $op2[
'overwriteSame'] =
true;
390 $op2[
'ignoreMissingSource'] =
true;
398 $op2[
'ignoreMissingSource'] =
true;
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)." );
488 $op = [
'op' =>
'move',
'src' =>
$source,
'dst' => $dest ];
496 $op2[
'overwrite'] =
true;
504 $op2[
'overwriteSame'] =
true;
512 $op2[
'ignoreMissingSource'] =
true;
520 $op2[
'ignoreMissingSource'] =
true;
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)." );
591 $op = [
'op' =>
'delete',
'src' =>
$source ];
604 $op[
'ignoreMissingSource'] =
true;
611 $op[
'ignoreMissingSource'] =
true;
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." );
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)." );
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'] )
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)." );
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'" );
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)" );
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 ];
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)." );
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 );
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)." );
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 $" ]
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)." );
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" ];
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)." );
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)." );
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" );
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" );
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" );
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 ) {
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 );
2620 return $this->backend->doQuickOperations( [
$params ] );
2624 $containers = [
'unittest-cont1',
'unittest-cont2',
'unittest-cont-bad' ];
2625 foreach ( $containers
as $container ) {
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 );