Index: trunk/phase3/tests/phpunit/includes/filerepo/FileBackendTest.php |
— | — | @@ -690,12 +690,54 @@ |
691 | 691 | return $cases; |
692 | 692 | } |
693 | 693 | |
694 | | - // @TODO: testPrepare |
| 694 | + /** |
| 695 | + * @dataProvider provider_testPrepareAndClean |
| 696 | + */ |
| 697 | + public function testPrepareAndClean( $path, $isOK ) { |
| 698 | + $this->backend = $this->singleBackend; |
| 699 | + $this->doTestPrepareAndClean( $path, $isOK ); |
695 | 700 | |
| 701 | + $this->backend = $this->multiBackend; |
| 702 | + $this->doTestPrepareAndClean( $path, $isOK ); |
| 703 | + } |
| 704 | + |
| 705 | + function provider_testPrepareAndClean() { |
| 706 | + $base = $this->baseStorePath(); |
| 707 | + return array( |
| 708 | + array( "$base/cont1/a/z/some_file1.txt", true ), |
| 709 | + array( "$base/cont2/a/z/some_file2.txt", true ), |
| 710 | + array( "$base/cont3/a/z/some_file3.txt", false ), |
| 711 | + ); |
| 712 | + } |
| 713 | + |
| 714 | + function doTestPrepareAndClean( $path, $isOK ) { |
| 715 | + $backendName = $this->backendClass(); |
| 716 | + |
| 717 | + $status = $this->backend->prepare( array( 'dir' => $path ) ); |
| 718 | + if ( $isOK ) { |
| 719 | + $this->assertEquals( array(), $status->errors, |
| 720 | + "Preparing dir $path succeeded without warnings ($backendName)." ); |
| 721 | + $this->assertEquals( true, $status->isOK(), |
| 722 | + "Preparing dir $path succeeded ($backendName)." ); |
| 723 | + } else { |
| 724 | + $this->assertEquals( false, $status->isOK(), |
| 725 | + "Preparing dir $path failed ($backendName)." ); |
| 726 | + } |
| 727 | + |
| 728 | + $status = $this->backend->clean( array( 'dir' => $path ) ); |
| 729 | + if ( $isOK ) { |
| 730 | + $this->assertEquals( array(), $status->errors, |
| 731 | + "Cleaning dir $path succeeded without warnings ($backendName)." ); |
| 732 | + $this->assertEquals( true, $status->isOK(), |
| 733 | + "Cleaning dir $path succeeded ($backendName)." ); |
| 734 | + } else { |
| 735 | + $this->assertEquals( false, $status->isOK(), |
| 736 | + "Cleaning dir $path failed ($backendName)." ); |
| 737 | + } |
| 738 | + } |
| 739 | + |
696 | 740 | // @TODO: testSecure |
697 | 741 | |
698 | | - // @TODO: testClean |
699 | | - |
700 | 742 | // @TODO: testDoOperations |
701 | 743 | |
702 | 744 | public function testGetFileList() { |
Index: trunk/phase3/includes/filerepo/backend/FileBackendMultiWrite.php |
— | — | @@ -251,37 +251,37 @@ |
252 | 252 | } |
253 | 253 | |
254 | 254 | /** |
255 | | - * @see FileBackendBase::prepare() |
| 255 | + * @see FileBackendBase::doPrepare() |
256 | 256 | */ |
257 | | - public function prepare( array $params ) { |
| 257 | + public function doPrepare( array $params ) { |
258 | 258 | $status = Status::newGood(); |
259 | 259 | foreach ( $this->backends as $backend ) { |
260 | 260 | $realParams = $this->substOpPaths( $params, $backend ); |
261 | | - $status->merge( $backend->prepare( $realParams ) ); |
| 261 | + $status->merge( $backend->doPrepare( $realParams ) ); |
262 | 262 | } |
263 | 263 | return $status; |
264 | 264 | } |
265 | 265 | |
266 | 266 | /** |
267 | | - * @see FileBackendBase::secure() |
| 267 | + * @see FileBackendBase::doSecure() |
268 | 268 | */ |
269 | | - public function secure( array $params ) { |
| 269 | + public function doSecure( array $params ) { |
270 | 270 | $status = Status::newGood(); |
271 | 271 | foreach ( $this->backends as $backend ) { |
272 | 272 | $realParams = $this->substOpPaths( $params, $backend ); |
273 | | - $status->merge( $backend->secure( $realParams ) ); |
| 273 | + $status->merge( $backend->doSecure( $realParams ) ); |
274 | 274 | } |
275 | 275 | return $status; |
276 | 276 | } |
277 | 277 | |
278 | 278 | /** |
279 | | - * @see FileBackendBase::clean() |
| 279 | + * @see FileBackendBase::doClean() |
280 | 280 | */ |
281 | | - public function clean( array $params ) { |
| 281 | + public function doClean( array $params ) { |
282 | 282 | $status = Status::newGood(); |
283 | 283 | foreach ( $this->backends as $backend ) { |
284 | 284 | $realParams = $this->substOpPaths( $params, $backend ); |
285 | | - $status->merge( $backend->clean( $realParams ) ); |
| 285 | + $status->merge( $backend->doClean( $realParams ) ); |
286 | 286 | } |
287 | 287 | return $status; |
288 | 288 | } |
Index: trunk/phase3/includes/filerepo/backend/FSFileBackend.php |
— | — | @@ -274,9 +274,9 @@ |
275 | 275 | } |
276 | 276 | |
277 | 277 | /** |
278 | | - * @see FileBackend::doPrepare() |
| 278 | + * @see FileBackend::doPrepareInternal() |
279 | 279 | */ |
280 | | - protected function doPrepare( $container, $dir, array $params ) { |
| 280 | + protected function doPrepareInternal( $container, $dir, array $params ) { |
281 | 281 | $status = Status::newGood(); |
282 | 282 | if ( !wfMkdirParents( $dir ) ) { |
283 | 283 | $status->fatal( 'directorycreateerror', $params['dir'] ); |
— | — | @@ -289,9 +289,9 @@ |
290 | 290 | } |
291 | 291 | |
292 | 292 | /** |
293 | | - * @see FileBackend::doSecure() |
| 293 | + * @see FileBackend::doSecureInternal() |
294 | 294 | */ |
295 | | - protected function doSecure( $container, $dir, array $params ) { |
| 295 | + protected function doSecureInternal( $container, $dir, array $params ) { |
296 | 296 | $status = Status::newGood(); |
297 | 297 | if ( !wfMkdirParents( $dir ) ) { |
298 | 298 | $status->fatal( 'directorycreateerror', $params['dir'] ); |
— | — | @@ -308,25 +308,27 @@ |
309 | 309 | } |
310 | 310 | } |
311 | 311 | // Add a .htaccess file to the root of the container... |
312 | | - list( $b, $container, $r ) = FileBackend::splitStoragePath( $params['dir'] ); |
313 | | - $dirRoot = $this->containerPaths[$container]; // real path |
314 | | - if ( !empty( $params['noAccess'] ) && !file_exists( "{$dirRoot}/.htaccess" ) ) { |
315 | | - wfSuppressWarnings(); |
316 | | - $ok = file_put_contents( "{$dirRoot}/.htaccess", "Deny from all\n" ); |
317 | | - wfRestoreWarnings(); |
318 | | - if ( !$ok ) { |
319 | | - $storeDir = "mwstore://{$this->name}/{$container}"; |
320 | | - $status->fatal( 'backend-fail-create', "$storeDir/.htaccess" ); |
321 | | - return $status; |
| 312 | + if ( !empty( $params['noAccess'] ) ) { |
| 313 | + list( $b, $container, $r ) = FileBackend::splitStoragePath( $params['dir'] ); |
| 314 | + $dirRoot = $this->containerPaths[$container]; // real path |
| 315 | + if ( !file_exists( "{$dirRoot}/.htaccess" ) ) { |
| 316 | + wfSuppressWarnings(); |
| 317 | + $ok = file_put_contents( "{$dirRoot}/.htaccess", "Deny from all\n" ); |
| 318 | + wfRestoreWarnings(); |
| 319 | + if ( !$ok ) { |
| 320 | + $storeDir = "mwstore://{$this->name}/{$container}"; |
| 321 | + $status->fatal( 'backend-fail-create', "$storeDir/.htaccess" ); |
| 322 | + return $status; |
| 323 | + } |
322 | 324 | } |
323 | 325 | } |
324 | 326 | return $status; |
325 | 327 | } |
326 | 328 | |
327 | 329 | /** |
328 | | - * @see FileBackend::doClean() |
| 330 | + * @see FileBackend::doCleanInternal() |
329 | 331 | */ |
330 | | - protected function doClean( $container, $dir, array $params ) { |
| 332 | + protected function doCleanInternal( $container, $dir, array $params ) { |
331 | 333 | $status = Status::newGood(); |
332 | 334 | wfSuppressWarnings(); |
333 | 335 | if ( is_dir( $dir ) ) { |
Index: trunk/phase3/includes/filerepo/backend/FileBackend.php |
— | — | @@ -292,9 +292,19 @@ |
293 | 293 | * @param $params Array |
294 | 294 | * @return Status |
295 | 295 | */ |
296 | | - abstract public function prepare( array $params ); |
| 296 | + final public function prepare( array $params ) { |
| 297 | + if ( $this->readOnly != '' ) { |
| 298 | + return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly ); |
| 299 | + } |
| 300 | + return $this->doPrepare( $params ); |
| 301 | + } |
297 | 302 | |
298 | 303 | /** |
| 304 | + * @see FileBackendBase::prepare() |
| 305 | + */ |
| 306 | + abstract protected function doPrepare( array $params ); |
| 307 | + |
| 308 | + /** |
299 | 309 | * Take measures to block web access to a directory and |
300 | 310 | * the container it belongs to. FS backends might add .htaccess |
301 | 311 | * files wheras backends like Swift this might restrict container |
— | — | @@ -309,9 +319,19 @@ |
310 | 320 | * @param $params Array |
311 | 321 | * @return Status |
312 | 322 | */ |
313 | | - abstract public function secure( array $params ); |
| 323 | + final public function secure( array $params ) { |
| 324 | + if ( $this->readOnly != '' ) { |
| 325 | + return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly ); |
| 326 | + } |
| 327 | + return $this->doSecure( $params ); |
| 328 | + } |
314 | 329 | |
315 | 330 | /** |
| 331 | + * @see FileBackendBase::secure() |
| 332 | + */ |
| 333 | + abstract protected function doSecure( array $params ); |
| 334 | + |
| 335 | + /** |
316 | 336 | * Clean up an empty storage directory. |
317 | 337 | * On FS backends, the directory will be deleted. Others may do nothing. |
318 | 338 | * |
— | — | @@ -321,9 +341,19 @@ |
322 | 342 | * @param $params Array |
323 | 343 | * @return Status |
324 | 344 | */ |
325 | | - abstract public function clean( array $params ); |
| 345 | + final public function clean( array $params ) { |
| 346 | + if ( $this->readOnly != '' ) { |
| 347 | + return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly ); |
| 348 | + } |
| 349 | + return $this->doClean( $params ); |
| 350 | + } |
326 | 351 | |
327 | 352 | /** |
| 353 | + * @see FileBackendBase::clean() |
| 354 | + */ |
| 355 | + abstract protected function doClean( array $params ); |
| 356 | + |
| 357 | + /** |
328 | 358 | * Check if a file exists at a storage path in the backend. |
329 | 359 | * This returns false if only a directory exists at the path. |
330 | 360 | * |
— | — | @@ -747,9 +777,9 @@ |
748 | 778 | } |
749 | 779 | |
750 | 780 | /** |
751 | | - * @see FileBackendBase::prepare() |
| 781 | + * @see FileBackendBase::doPrepare() |
752 | 782 | */ |
753 | | - final public function prepare( array $params ) { |
| 783 | + final protected function doPrepare( array $params ) { |
754 | 784 | $status = Status::newGood(); |
755 | 785 | list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] ); |
756 | 786 | if ( $dir === null ) { |
— | — | @@ -757,28 +787,28 @@ |
758 | 788 | return $status; // invalid storage path |
759 | 789 | } |
760 | 790 | if ( $shard !== null ) { // confined to a single container/shard |
761 | | - $status->merge( $this->doPrepare( $fullCont, $dir, $params ) ); |
| 791 | + $status->merge( $this->doPrepareInternal( $fullCont, $dir, $params ) ); |
762 | 792 | } else { // directory is on several shards |
763 | 793 | wfDebug( __METHOD__ . ": iterating over all container shards.\n" ); |
764 | 794 | list( $b, $shortCont, $r ) = self::splitStoragePath( $params['dir'] ); |
765 | 795 | foreach ( $this->getContainerSuffixes( $shortCont ) as $suffix ) { |
766 | | - $status->merge( $this->doPrepare( "{$fullCont}{$suffix}", $dir, $params ) ); |
| 796 | + $status->merge( $this->doPrepareInternal( "{$fullCont}{$suffix}", $dir, $params ) ); |
767 | 797 | } |
768 | 798 | } |
769 | 799 | return $status; |
770 | 800 | } |
771 | 801 | |
772 | 802 | /** |
773 | | - * @see FileBackend::prepare() |
| 803 | + * @see FileBackend::doPrepare() |
774 | 804 | */ |
775 | | - protected function doPrepare( $container, $dir, array $params ) { |
| 805 | + protected function doPrepareInternal( $container, $dir, array $params ) { |
776 | 806 | return Status::newGood(); |
777 | 807 | } |
778 | 808 | |
779 | 809 | /** |
780 | | - * @see FileBackendBase::secure() |
| 810 | + * @see FileBackendBase::doSecure() |
781 | 811 | */ |
782 | | - final public function secure( array $params ) { |
| 812 | + final protected function doSecure( array $params ) { |
783 | 813 | $status = Status::newGood(); |
784 | 814 | list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] ); |
785 | 815 | if ( $dir === null ) { |
— | — | @@ -786,28 +816,28 @@ |
787 | 817 | return $status; // invalid storage path |
788 | 818 | } |
789 | 819 | if ( $shard !== null ) { // confined to a single container/shard |
790 | | - $status->merge( $this->doSecure( $fullCont, $dir, $params ) ); |
| 820 | + $status->merge( $this->doSecureInternal( $fullCont, $dir, $params ) ); |
791 | 821 | } else { // directory is on several shards |
792 | 822 | wfDebug( __METHOD__ . ": iterating over all container shards.\n" ); |
793 | 823 | list( $b, $shortCont, $r ) = self::splitStoragePath( $params['dir'] ); |
794 | 824 | foreach ( $this->getContainerSuffixes( $shortCont ) as $suffix ) { |
795 | | - $status->merge( $this->doSecure( "{$fullCont}{$suffix}", $dir, $params ) ); |
| 825 | + $status->merge( $this->doSecureInternal( "{$fullCont}{$suffix}", $dir, $params ) ); |
796 | 826 | } |
797 | 827 | } |
798 | 828 | return $status; |
799 | 829 | } |
800 | 830 | |
801 | 831 | /** |
802 | | - * @see FileBackend::secure() |
| 832 | + * @see FileBackend::doSecure() |
803 | 833 | */ |
804 | | - protected function doSecure( $container, $dir, array $params ) { |
| 834 | + protected function doSecureInternal( $container, $dir, array $params ) { |
805 | 835 | return Status::newGood(); |
806 | 836 | } |
807 | 837 | |
808 | 838 | /** |
809 | | - * @see FileBackendBase::clean() |
| 839 | + * @see FileBackendBase::doClean() |
810 | 840 | */ |
811 | | - final public function clean( array $params ) { |
| 841 | + final protected function doClean( array $params ) { |
812 | 842 | $status = Status::newGood(); |
813 | 843 | list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] ); |
814 | 844 | if ( $dir === null ) { |
— | — | @@ -815,21 +845,21 @@ |
816 | 846 | return $status; // invalid storage path |
817 | 847 | } |
818 | 848 | if ( $shard !== null ) { // confined to a single container/shard |
819 | | - $status->merge( $this->doClean( $fullCont, $dir, $params ) ); |
| 849 | + $status->merge( $this->doCleanInternal( $fullCont, $dir, $params ) ); |
820 | 850 | } else { // directory is on several shards |
821 | 851 | wfDebug( __METHOD__ . ": iterating over all container shards.\n" ); |
822 | 852 | list( $b, $shortCont, $r ) = self::splitStoragePath( $params['dir'] ); |
823 | 853 | foreach ( $this->getContainerSuffixes( $shortCont ) as $suffix ) { |
824 | | - $status->merge( $this->doClean( "{$fullCont}{$suffix}", $dir, $params ) ); |
| 854 | + $status->merge( $this->doCleanInternal( "{$fullCont}{$suffix}", $dir, $params ) ); |
825 | 855 | } |
826 | 856 | } |
827 | 857 | return $status; |
828 | 858 | } |
829 | 859 | |
830 | 860 | /** |
831 | | - * @see FileBackend::clean() |
| 861 | + * @see FileBackend::doClean() |
832 | 862 | */ |
833 | | - protected function doClean( $container, $dir, array $params ) { |
| 863 | + protected function doCleanInternal( $container, $dir, array $params ) { |
834 | 864 | return Status::newGood(); |
835 | 865 | } |
836 | 866 | |