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 ) {
1528 $data = Http::request(
"GET", $url, [], __METHOD__ );
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 ) );
2479 $be = TestingAccessWrapper::newFromObject(
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"
2529 $be = TestingAccessWrapper::newFromObject(
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"
2566 DeferredUpdates::doUpdates();
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 );
$wgFileBackends
File backend structure configuration.
wfTempDir()
Tries to get the system directory for temporary files.
wfRandomString( $length=32)
Get a random string containing a number of pseudo-random hex characters.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
Class for a file system (FS) based file backend.
static getPropsFromPath( $path, $ext=true)
Get an associative array containing information about a file in the local filesystem.
Proxy backend that mirrors writes to several internal backends.
FileRepo FileBackend medium.
static provider_testStreamFile()
static provider_testGetFileStat()
doTestGetFileHttpUrl( $source, $content)
testDoOperationsPipeline()
FileBackend::doOperations.
static provider_testSplitStoragePath()
testStreamFile( $path, $content, $alreadyExists)
provider_testGetFileStat FileBackend::streamFile
doTestRecursiveClean()
FileBackend::clean.
testMove( $op)
provider_testMove FileBackend::doOperation
testDelete( $op, $withSource, $okStatus)
provider_testDelete FileBackend::doOperation
testGetFileList()
FileBackend::getFileList.
doTestDoQuickOperations()
testGetLocalCopy( $source, $content)
provider_testGetLocalCopy FileBackend::getLocalCopy
static provider_testIsStoragePath()
FSFileBackend $singleBackend
doTestPrepareAndClean( $path, $isOK)
doTestStreamFile( $path, $content)
testGetFileHttpUrl( $source, $content)
provider_testGetFileHttpUrl FileBackend::getFileHttpUrl
testDoOperationsFailing()
FileBackend::doOperations.
FileBackendMultiWrite $multiBackend
testDoOperations()
FileBackend::doOperations.
doTestGetFileStat( $path, $content, $alreadyExists)
testGetDirectoryList()
FileBackend::getTopDirectoryList FileBackend::getDirectoryList.
testGetLocalCopyAndReference404()
FileBackend::getLocalCopy FileBackend::getLocalReference.
testGetLocalReference( $source, $content)
provider_testGetLocalReference FileBackend::getLocalReference
testGetContentType( $mimeCallback, $mimeFromString)
provider_testGetContentType
doTestGetLocalReference( $source, $content)
doTestDescribe( $op, $withSource, $okStatus)
testPrepareAndClean( $path, $isOK)
provider_testPrepareAndClean FileBackend::prepare FileBackend::clean
testDoQuickOperations()
FileBackend::doQuickOperations.
assertBackendPathsConsistent(array $paths)
doTestConcatenate( $params, $srcs, $srcsContent, $alreadyExists, $okStatus)
testExtensionFromPath( $path, $res)
provider_testExtensionFromPath FileBackend::extensionFromPath
static provider_testStore()
assertGoodStatus(StatusValue $status, $msg)
static provider_testGetFileHttpUrl()
testGetFileContents( $source, $content)
provider_testGetFileContents FileBackend::getFileContents FileBackend::getFileContentsMulti
doTestDoOperationsPipeline()
static provider_testGetContentType()
static provider_testParentStoragePath()
testLockCalls()
FileBackend::lockFiles FileBackend::unlockFiles.
doTestGetFileContents( $source, $content)
doTestGetLocalCopyAndReference404()
static provider_testDescribe()
assertHasHeaders(array $headers, array $attr)
testStore( $op)
provider_testStore
testGetFileStat( $path, $content, $alreadyExists)
provider_testGetFileStat FileBackend::getFileStat
doTestDoOperationsFailing()
doTestCreate( $op, $alreadyExists, $okStatus, $newSize)
static provider_testMove()
static provider_testConcatenate()
doTestStore( $op)
FileBackend::doOperation.
testNormalizeStoragePath( $path, $res)
provider_normalizeStoragePath FileBackend::normalizeStoragePath
testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus)
provider_testConcatenate
testCreate( $op, $alreadyExists, $okStatus, $newSize)
provider_testCreate FileBackend::doOperation
testCopy( $op)
provider_testCopy FileBackend::doOperation
static provider_testGetLocalCopy()
testDescribe( $op, $withSource, $okStatus)
provider_testDescribe FileBackend::doOperation
static provider_testCopy()
doTestDelete( $op, $withSource, $okStatus)
static provider_testPrepareAndClean()
doTestGetLocalCopy( $source, $content)
static provider_normalizeStoragePath()
static provider_testCreate()
provider_testCreate
static provider_testGetFileContents()
testSplitStoragePath( $path, $res)
provider_testSplitStoragePath FileBackend::splitStoragePath
static provider_testGetLocalReference()
static provider_testDelete()
testIsStoragePath( $path, $isStorePath)
provider_testIsStoragePath FileBackend::isStoragePath
static provider_testExtensionFromPath()
testParentStoragePath( $path, $res)
provider_testParentStoragePath FileBackend::parentStoragePath
Base class for all file backend classes (including multi-write backends).
static parentStoragePath( $storagePath)
Get the parent storage directory of a storage path.
static isStoragePath( $path)
Check if a given path is a "mwstore://" path.
static splitStoragePath( $storagePath)
Split a storage path into a backend name, a container name, and a relative file path.
static extensionFromPath( $path, $case='lowercase')
Get the final extension from a storage or FS path.
static makeContentDisposition( $type, $filename='')
Build a Content-Disposition header value per RFC 6266.
static normalizeStoragePath( $storagePath)
Normalize a storage path by cleaning up directory separators.
const ATTR_HEADERS
Bitfield flags for supported features.
static factory(array $config, $backend)
Create an appropriate FileJournal object from config.
static singleton( $domain=false)
const LOCK_SH
Lock types; stronger locks have higher values.
Simulation of a backend storage in memory.
static release(ScopedLock &$lock=null)
Release a scoped lock and set any errors in the attatched StatusValue object.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
static factory( $prefix, $extension='', $tmpDirectory=null)
Make a new temporary file on the file system.
when a variable name is used in a it is silently declared as a new local masking the global
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set $status
the array() calling protocol came about after MediaWiki 1.4rc1.
see documentation in includes Linker php for Linker::makeImageLink & $time
namespace are movable Hooks may change this value to override the return value of MWNamespace::isMovable(). 'NewDifferenceEngine' do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached one of create
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content $content
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
Allows to change the fields on the form that will be generated $name
processing should stop and the error should be shown to the user * false
if(count( $args)==0) $dir
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
const TS_UNIX
Unix time - the number of seconds since 1970-01-01 00:00:00 UTC.