Legoktm has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/405573 )
Change subject: [WIP] Run tests in parallel
......................................................................
[WIP] Run tests in parallel
Change-Id: I48d787e3f84bd543c5d21b98a9ae74454bad19e1
---
M composer.json
M src/CheckCommand.php
2 files changed, 80 insertions(+), 19 deletions(-)
git pull
ssh://gerrit.wikimedia.org:29418/mediawiki/tools/phpunit-patch-coverage
refs/changes/73/405573/1
diff --git a/composer.json b/composer.json
index b7d7f39..e2cb101 100644
--- a/composer.json
+++ b/composer.json
@@ -12,8 +12,10 @@
],
"require": {
"php": ">=5.5.9",
+ "jagandecapri/symfony-parallel-process": "^2.0",
"legoktm/clover-diff": "^1.0.0",
"nikic/php-parser": "^3.1.3",
+ "phpunit/php-code-coverage": "^2.2.4",
"symfony/console": "^3.3",
"symfony/finder": "^3.3",
"symfony/process": "^3.3",
diff --git a/src/CheckCommand.php b/src/CheckCommand.php
index 587f2e7..e976615 100644
--- a/src/CheckCommand.php
+++ b/src/CheckCommand.php
@@ -18,8 +18,11 @@
namespace MediaWiki\Tool\PatchCoverage;
+use Jack\Symfony\ProcessManager;
use Legoktm\CloverDiff\Differ;
use Legoktm\CloverDiff\DiffPrinter;
+use PHP_CodeCoverage;
+use PHP_CodeCoverage_Report_Clover;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -57,6 +60,11 @@
null, InputOption::VALUE_REQUIRED,
'Command to run to execute PHPUnit tests',
'php vendor/bin/phpunit'
+ )->addOption(
+ 'parallel',
+ null, InputOption::VALUE_REQUIRED,
+ 'Number of processes to use',
+ '1'
);
}
@@ -69,38 +77,81 @@
return $newPaths;
}
- private function getFilterRegex( $tests ) {
+ private function getFilterRegexes( $tests ) {
// PHPUnit requires filename to be the same as the classname,
// so we can use that as a shortcut.
$filter = [];
foreach ( $tests as $test ) {
$base = basename( $test );
// Strip extension
- $filter[] = preg_quote(
+ $filter[] = '\'/' . preg_quote(
substr( $base, 0, strlen( $base ) - 4 )
+ . '/\''
);
}
- return '\'/' . implode( '|', $filter ) . '/\'';
+ return $filter;
}
- private function runTests( $output, $command, $tests ) {
- // TODO: Run this in parallel?
- $clover = tempnam( sys_get_temp_dir(), 'clover' );
- $cmd = $command .
- " --coverage-clover $clover --filter " .
- $this->getFilterRegex( $tests );
- $process = new CommandProcess( $cmd );
- // Disable timeout
- $process->setTimeout( null );
- // Run and buffer output for progress
- $process->runWithOutput( $output );
-
+ private function getTempFile() {
+ $fname = tempnam( sys_get_temp_dir(), 'phpcover' );
$this->scopedCallbacks[] = new ScopedCallback(
- function () use ( $clover ) {
- unlink( $clover );
+ function () use ( $fname ) {
+ // unlink( $fname );
}
);
+
+ return $fname;
+ }
+
+ /**
+ * @param int $parallel
+ * @param OutputInterface $output
+ * @param $command
+ * @param $tests
+ *
+ * @return string
+ */
+ private function runTests( $parallel, $output, $command, $tests ) {
+ // TODO: Run this in parallel?
+
+ $regexes = $this->getFilterRegexes( $tests );
+ $toMerge = [];
+ $toRun = [];
+ foreach ( $regexes as $regex ) {
+ $tmp = $this->getTempFile();
+ $cmd = $command . " --coverage-php $tmp --filter " .
+ $regex;
+ $process = new Process( $cmd );
+ $output->writeln( $cmd );
+ $process->setTimeout( null );
+ $toRun[] = $process;
+ $toMerge[] = $tmp;
+ }
+
+ $manager = new ProcessManager();
+ $manager->runParallel( $toRun, $parallel );
+
+ /** @var PHP_CodeCoverage $coverage */
+ $coverage = null;
+ foreach ( $toMerge as $merge ) {
+ if ( $coverage ) {
+ $coverage->merge( include $merge );
+ } else {
+ $coverage = include $merge;
+ if ( !$coverage instanceof PHP_CodeCoverage ) {
+ throw new \Exception();
+ }
+ }
+ }
+ $clover = $this->getTempFile();
+ if ( $coverage ) {
+ $writer = new PHP_CodeCoverage_Report_Clover();
+ $writer->process( $coverage, $clover );
+ $output->writeln( $clover );
+ } else {
+ $clover = null;
+ }
return $clover;
}
@@ -150,10 +201,16 @@
// TODO: We need to trim suite.xml coverage filter, because
that takes forever
+ $parallel = (int)$input->getOption( 'parallel' );
+ if ( $parallel < 1 ) {
+ $parallel = 1;
+ }
$command = $input->getOption( 'command' );
if ( $testsToRun ) {
// Run it!
- $newClover = $this->runTests( $output, $command,
$testsToRun );
+ $newClover = $this->runTests(
+ $parallel, $output, $command, $testsToRun
+ );
} else {
$newClover = null;
}
@@ -172,7 +229,9 @@
$this->absolutify( $changedTests->deleted )
) );
if ( $testsOldToRun ) {
- $oldClover = $this->runTests( $output, $command,
$testsOldToRun );
+ $oldClover = $this->runTests(
+ $parallel, $output, $command, $testsOldToRun
+ );
} else {
$oldClover = null;
}
--
To view, visit https://gerrit.wikimedia.org/r/405573
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I48d787e3f84bd543c5d21b98a9ae74454bad19e1
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/tools/phpunit-patch-coverage
Gerrit-Branch: master
Gerrit-Owner: Legoktm <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits