Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 80 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
FileOpPerfTest | |
0.00% |
0 / 80 |
|
0.00% |
0 / 3 |
240 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
doPerfTest | |
0.00% |
0 / 66 |
|
0.00% |
0 / 1 |
156 |
1 | <?php |
2 | /** |
3 | * Test for fileop performance. |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License along |
16 | * with this program; if not, write to the Free Software Foundation, Inc., |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
18 | * http://www.gnu.org/copyleft/gpl.html |
19 | * |
20 | * @file |
21 | * @ingroup Maintenance |
22 | */ |
23 | |
24 | use MediaWiki\Maintenance\Maintenance; |
25 | use Wikimedia\FileBackend\FileBackend; |
26 | |
27 | // @codeCoverageIgnoreStart |
28 | require_once __DIR__ . '/Maintenance.php'; |
29 | // @codeCoverageIgnoreEnd |
30 | |
31 | /** |
32 | * Maintenance script to test fileop performance. |
33 | * |
34 | * @ingroup Maintenance |
35 | */ |
36 | class FileOpPerfTest extends Maintenance { |
37 | public function __construct() { |
38 | parent::__construct(); |
39 | $this->addDescription( 'Test fileop performance' ); |
40 | $this->addOption( 'b1', 'Backend 1', true, true ); |
41 | $this->addOption( 'b2', 'Backend 2', false, true ); |
42 | $this->addOption( 'srcdir', 'File source directory', true, true ); |
43 | $this->addOption( 'maxfiles', 'Max files', false, true ); |
44 | $this->addOption( 'quick', 'Avoid operation pre-checks (use doQuickOperations())' ); |
45 | $this->addOption( 'parallelize', '"parallelize" flag for doOperations()', false, true ); |
46 | } |
47 | |
48 | public function execute() { |
49 | $backendGroup = $this->getServiceContainer()->getFileBackendGroup(); |
50 | $backend = $backendGroup->get( $this->getOption( 'b1' ) ); |
51 | $this->doPerfTest( $backend ); |
52 | |
53 | if ( $this->getOption( 'b2' ) ) { |
54 | $backend = $backendGroup->get( $this->getOption( 'b2' ) ); |
55 | $this->doPerfTest( $backend ); |
56 | } |
57 | } |
58 | |
59 | protected function doPerfTest( FileBackend $backend ) { |
60 | $ops1 = []; |
61 | $ops2 = []; |
62 | $ops3 = []; |
63 | $ops4 = []; |
64 | $ops5 = []; |
65 | |
66 | $baseDir = 'mwstore://' . $backend->getName() . '/testing-cont1'; |
67 | $backend->prepare( [ 'dir' => $baseDir ] ); |
68 | |
69 | $dirname = $this->getOption( 'srcdir' ); |
70 | $dir = opendir( $dirname ); |
71 | if ( !$dir ) { |
72 | return; |
73 | } |
74 | |
75 | // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition |
76 | while ( ( $file = readdir( $dir ) ) !== false ) { |
77 | if ( $file[0] != '.' ) { |
78 | $this->output( "Using '$dirname/$file' in operations.\n" ); |
79 | $dst = $baseDir . '/' . wfBaseName( $file ); |
80 | $ops1[] = [ 'op' => 'store', |
81 | 'src' => "$dirname/$file", 'dst' => $dst, 'overwrite' => true ]; |
82 | $ops2[] = [ 'op' => 'copy', |
83 | 'src' => "$dst", 'dst' => "$dst-1", 'overwrite' => true ]; |
84 | $ops3[] = [ 'op' => 'move', |
85 | 'src' => $dst, 'dst' => "$dst-2", 'overwrite' => true ]; |
86 | $ops4[] = [ 'op' => 'delete', 'src' => "$dst-1" ]; |
87 | $ops5[] = [ 'op' => 'delete', 'src' => "$dst-2" ]; |
88 | } |
89 | if ( count( $ops1 ) >= $this->getOption( 'maxfiles', 20 ) ) { |
90 | break; |
91 | } |
92 | } |
93 | closedir( $dir ); |
94 | $this->output( "\n" ); |
95 | |
96 | $method = $this->hasOption( 'quick' ) ? 'doQuickOperations' : 'doOperations'; |
97 | |
98 | $opts = [ 'force' => 1 ]; |
99 | if ( $this->hasOption( 'parallelize' ) ) { |
100 | $opts['parallelize'] = ( $this->getOption( 'parallelize' ) === 'true' ); |
101 | } |
102 | |
103 | $start = microtime( true ); |
104 | $status = $backend->$method( $ops1, $opts ); |
105 | $e = ( microtime( true ) - $start ) * 1000; |
106 | if ( !$status->isGood() ) { |
107 | $this->error( $status ); |
108 | return; |
109 | } |
110 | $this->output( $backend->getName() . ": Stored " . count( $ops1 ) . " files in $e ms.\n" ); |
111 | |
112 | $start = microtime( true ); |
113 | $status = $backend->$method( $ops2, $opts ); |
114 | $e = ( microtime( true ) - $start ) * 1000; |
115 | if ( !$status->isGood() ) { |
116 | $this->error( $status ); |
117 | return; |
118 | } |
119 | $this->output( $backend->getName() . ": Copied " . count( $ops2 ) . " files in $e ms.\n" ); |
120 | |
121 | $start = microtime( true ); |
122 | $status = $backend->$method( $ops3, $opts ); |
123 | $e = ( microtime( true ) - $start ) * 1000; |
124 | if ( !$status->isGood() ) { |
125 | $this->error( $status ); |
126 | return; |
127 | } |
128 | $this->output( $backend->getName() . ": Moved " . count( $ops3 ) . " files in $e ms.\n" ); |
129 | |
130 | $start = microtime( true ); |
131 | $status = $backend->$method( $ops4, $opts ); |
132 | $e = ( microtime( true ) - $start ) * 1000; |
133 | if ( !$status->isGood() ) { |
134 | $this->error( $status ); |
135 | return; |
136 | } |
137 | $this->output( $backend->getName() . ": Deleted " . count( $ops4 ) . " files in $e ms.\n" ); |
138 | |
139 | $start = microtime( true ); |
140 | $status = $backend->$method( $ops5, $opts ); |
141 | $e = ( microtime( true ) - $start ) * 1000; |
142 | if ( !$status->isGood() ) { |
143 | $this->error( $status ); |
144 | return; |
145 | } |
146 | $this->output( $backend->getName() . ": Deleted " . count( $ops5 ) . " files in $e ms.\n" ); |
147 | } |
148 | } |
149 | |
150 | // @codeCoverageIgnoreStart |
151 | $maintClass = FileOpPerfTest::class; |
152 | require_once RUN_MAINTENANCE_IF_MAIN; |
153 | // @codeCoverageIgnoreEnd |