Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions patches/paratest.patch → .github/php72-paratest400.diff
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
@package brianium/paratest
@version ^4.0

--- src/Runners/PHPUnit/Worker/BaseWorker.php 2020-02-07 23:07:07.000000000 +0100
+++ src/Runners/PHPUnit/Worker/BaseWorker.php 2022-03-27 17:35:45.000000000 +0200
@@ -28,17 +28,18 @@
diff --git a/vendor/brianium/paratest/src/Runners/PHPUnit/Worker/BaseWorker.php b/vendor/brianium/paratest/src/Runners/PHPUnit/Worker/BaseWorker.php
index f96dc0a..b038ee2 100644
--- a/vendor/brianium/paratest/src/Runners/PHPUnit/Worker/BaseWorker.php
+++ b/vendor/brianium/paratest/src/Runners/PHPUnit/Worker/BaseWorker.php
@@ -28,17 +28,18 @@ abstract class BaseWorker
array $parameters = [],
?Options $options = null
) {
Expand All @@ -27,7 +26,7 @@
if ($options && $options->passthruPhp) {
$bin .= $options->passthruPhp . ' ';
}
@@ -50,7 +51,7 @@
@@ -50,7 +51,7 @@ abstract class BaseWorker
if ($options && $options->verbose) {
echo "Starting WrapperWorker via: $bin\n";
}
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,8 @@ jobs:
- name: "Downgrade PHPUnit"
run: "composer require --dev phpunit/phpunit:^7.5.20 brianium/paratest:^4.0 --update-with-dependencies --ignore-platform-reqs"

- name: "Apply ParaTest patch to allow WrapperRunner"
run: "git apply --ignore-whitespace .github/php72-paratest400.diff"

- name: "Tests"
run: "${{ matrix.script }}"
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ tests:
php vendor/bin/paratest --runner WrapperRunner --no-coverage

tests-integration:
php vendor/bin/paratest --runner WrapperRunner --no-coverage --group exec
php vendor/bin/phpunit --no-coverage --group exec

tests-static-reflection:
php vendor/bin/paratest --runner WrapperRunner --no-coverage --bootstrap tests/bootstrap-static-reflection.php
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
],
"require": {
"php": "^8.0",
"clue/block-react": "^1.4",
"clue/block-react": "^1.5",
"clue/ndjson-react": "^1.0",
"composer/ca-bundle": "^1.2",
"composer/xdebug-handler": "^3.0.3",
Expand Down
4 changes: 2 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions src/Process/ProcessCrashedException.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,24 @@
class ProcessCrashedException extends Exception
{

public function __construct(private ?int $exitCode, private string $stdOut, private string $stdErr)
{
parent::__construct($this->stdOut . $this->stdErr);
}

public function getExitCode(): ?int
{
return $this->exitCode;
}

public function getStdOut(): string
{
return $this->stdOut;
}

public function getStdErr(): string
{
return $this->stdErr;
}

}
4 changes: 2 additions & 2 deletions src/Process/ProcessPromise.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function run(): CancellablePromiseInterface
fclose($tmpStdErrResource);

if ($exitCode === null) {
$this->deferred->reject(new ProcessCrashedException($stdOut . $stdErr));
$this->deferred->reject(new ProcessCrashedException($exitCode, $stdOut, $stdErr));
return;
}

Expand All @@ -77,7 +77,7 @@ public function run(): CancellablePromiseInterface
return;
}

$this->deferred->reject(new ProcessCrashedException($stdOut . $stdErr));
$this->deferred->reject(new ProcessCrashedException($exitCode, $stdOut, $stdErr));
});

/** @var ExtendedPromiseInterface&CancellablePromiseInterface */
Expand Down
42 changes: 39 additions & 3 deletions src/Testing/LevelsTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,26 @@
use Nette\Utils\JsonException;
use PHPStan\File\FileHelper;
use PHPStan\File\FileWriter;
use PHPStan\Process\CpuCoreCounter;
use PHPStan\Process\ProcessCrashedException;
use PHPStan\Process\ProcessPromise;
use PHPStan\Process\Runnable\RunnableQueue;
use PHPStan\Process\Runnable\RunnableQueueLogger;
use PHPStan\ShouldNotHappenException;
use PHPUnit\Framework\AssertionFailedError;
use PHPUnit\Framework\TestCase;
use React\EventLoop\StreamSelectLoop;
use React\Promise\Deferred;
use function array_merge;
use function Clue\React\Block\await;
use function count;
use function escapeshellarg;
use function escapeshellcmd;
use function exec;
use function implode;
use function method_exists;
use function range;
use function React\Promise\all;
use function sprintf;
use function unlink;
use const DIRECTORY_SEPARATOR;
Expand Down Expand Up @@ -68,12 +77,39 @@ public function testLevels(
throw new ShouldNotHappenException('Could not clear result cache: ' . implode("\n", $clearResultCacheOutputLines));
}

$loop = new StreamSelectLoop();
$cpuCoreCounter = new CpuCoreCounter();
$queue = new RunnableQueue(new class implements RunnableQueueLogger {

public function log(string $message): void
{
}

}, $cpuCoreCounter->getNumberOfCpuCores());
$promises = [];
foreach (range(0, 9) as $level) {
unset($outputLines);
exec(sprintf('%s %s analyse --no-progress --error-format=prettyJson --level=%d %s %s %s', escapeshellarg(PHP_BINARY), $command, $level, $configPath !== null ? '--configuration ' . escapeshellarg($configPath) : '', $this->shouldAutoloadAnalysedFile() ? sprintf('--autoload-file %s', escapeshellarg($file)) : '', escapeshellarg($file)), $outputLines);
$process = new ProcessPromise($loop, 'level-' . $level, sprintf('%s %s analyse --no-progress --error-format=prettyJson --level=%d %s %s %s', escapeshellarg(PHP_BINARY), $command, $level, $configPath !== null ? '--configuration ' . escapeshellarg($configPath) : '', $this->shouldAutoloadAnalysedFile() ? sprintf('--autoload-file %s', escapeshellarg($file)) : '', escapeshellarg($file)));
$deferred = new Deferred();
$queue->queue($process, 1)->then(static function (string $output) use ($deferred): void {
$deferred->resolve($output);
}, static function (ProcessCrashedException $crash) use ($deferred): void {
$exitCode = $crash->getExitCode();
if ($exitCode !== 1) {
$deferred->reject($crash);
}
try {
Json::decode($crash->getStdOut());
} catch (JsonException) {
$deferred->reject($crash);
return;
}

$output = implode("\n", $outputLines);
$deferred->resolve($crash->getStdOut());
});
$promises[$level] = $deferred->promise();
}

foreach (await(all($promises), $loop) as $level => $output) {
try {
$actualJson = Json::decode($output, Json::FORCE_ARRAY);
} catch (JsonException) {
Expand Down