Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set XDEBUG_MODE for processes with coverage #1518

Merged
merged 43 commits into from Nov 10, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5390f63
Set XDEBUG_MODE for processes with coverage
sanmai May 4, 2021
317e5ce
Don't even mention XDEBUG_MODE
sanmai May 4, 2021
f71de68
Add a test
sanmai May 4, 2021
fd77c35
Address PCOV
sanmai May 4, 2021
90017c6
Simplify Dockerfiles
sanmai May 4, 2021
6dd84fe
Fix PHPStan
sanmai May 4, 2021
a8a3db7
Fix tests in Windows
sanmai May 4, 2021
a645bee
Reduce epsilon
sanmai May 4, 2021
99162ef
Should use XDEBUG_MODE=coverage
sanmai May 4, 2021
6f72869
Add Xdebug 2 to CI
sanmai May 4, 2021
4999b9a
Fix tests on Windows by not assuming a new line
sanmai May 4, 2021
97ba8e1
cs
sanmai May 4, 2021
5fd95df
Merge branch 'master' into pr/2020-05/autodetect-XDEBUG_MODE
sanmai Oct 15, 2021
41433ee
Revert everything to where it was
sanmai Oct 15, 2021
aa1e089
Disable XDebug on CI
sanmai Oct 15, 2021
fd56f5d
Put everything back together after we proved it works
sanmai Oct 16, 2021
8af83b2
Merge branch 'master' into pr/2020-05/autodetect-XDEBUG_MODE
sanmai Oct 16, 2021
7b12fc4
We can know that Xdebug was offloaded
sanmai Oct 16, 2021
8070082
Return useful notices
sanmai Oct 16, 2021
ceee8e2
Fix tests
sanmai Oct 16, 2021
9f6d313
Fix it
sanmai Oct 16, 2021
ae72703
Another check for Xdebug
sanmai Oct 16, 2021
c3aa985
Code Style
sanmai Oct 16, 2021
9925caf
Update OriginalPhpProcess
sanmai Oct 16, 2021
cccb00f
Fix SA issues
sanmai Oct 16, 2021
51f3d8f
Also check for PCOV and PHPDBG
sanmai Oct 16, 2021
ba71b3b
composer.lock: update deps
sanmai Oct 16, 2021
b59fe4f
Actually, undo the update
sanmai Oct 16, 2021
2d9435e
No quotes required here apparently
sanmai Oct 16, 2021
2b6b4d0
Fix e2e tests collecting coverage outside of Infection
sanmai Oct 16, 2021
a7c2f2f
Skip E2ETest if Xdebug isn't enabled
sanmai Oct 16, 2021
394e1dc
There's something wrong on Windows
sanmai Oct 16, 2021
4597545
Explain the why
sanmai Oct 16, 2021
eec4a33
Move override close to the point of use
sanmai Oct 16, 2021
e958091
Fix negation
sanmai Oct 17, 2021
db7bd12
Rename xdebug-coverage.ini
sanmai Oct 17, 2021
2b7aa7b
Merge branch 'master' into pr/2020-05/autodetect-XDEBUG_MODE
sanmai Oct 19, 2021
e363c79
Merge branch 'master' into pr/2020-05/autodetect-XDEBUG_MODE
sanmai Nov 10, 2021
50ee06f
Make it all more readable
sanmai Nov 10, 2021
17f84ee
Merge branch 'pr/2020-05/autodetect-XDEBUG_MODE' of github.com:sanmai…
sanmai Nov 10, 2021
4270a9b
Patch up to master
sanmai Nov 10, 2021
2b8a324
Fix tests
sanmai Nov 10, 2021
20a9b99
Fix this
sanmai Nov 10, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yaml
Expand Up @@ -24,6 +24,7 @@ jobs:
- { operating-system: 'windows-latest', php-version: '7.4', dependencies: '', coverage-driver: 'xdebug' }
- { operating-system: 'ubuntu-latest', php-version: '7.4', dependencies: '--prefer-lowest', coverage-driver: 'pcov' }
- { operating-system: 'ubuntu-latest', php-version: '8.0', dependencies: '--ignore-platform-req=php', coverage-driver: 'pcov' }
- { operating-system: 'ubuntu-latest', php-version: '7.4', dependencies: '', coverage-driver: 'xdebug2' }
sanmai marked this conversation as resolved.
Show resolved Hide resolved

continue-on-error: ${{ matrix.php-version == '8.0' }}
name: CI on ${{ matrix.operating-system }} with PHP ${{ matrix.php-version }}, using ${{ matrix.coverage-driver }} ${{ matrix.dependencies }}
Expand Down
2 changes: 1 addition & 1 deletion devTools/Dockerfile-php74-xdebug
Expand Up @@ -28,7 +28,7 @@ RUN apk add --no-cache \
zip

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
COPY devTools/memory-limit.ini devTools/xdebug-coverage.ini ${PHP_INI_DIR}/conf.d/
COPY devTools/memory-limit.ini ${PHP_INI_DIR}/conf.d/

RUN adduser -h /opt/infection -s /bin/bash -D infection

Expand Down
2 changes: 1 addition & 1 deletion devTools/Dockerfile-php80-xdebug
Expand Up @@ -27,7 +27,7 @@ RUN apk add --no-cache \
zip

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
COPY devTools/memory-limit.ini devTools/xdebug-coverage.ini ${PHP_INI_DIR}/conf.d/
COPY devTools/memory-limit.ini ${PHP_INI_DIR}/conf.d/

RUN adduser -h /opt/infection -s /bin/bash -D infection

Expand Down
5 changes: 5 additions & 0 deletions devTools/phpstan-src-baseline.neon
Expand Up @@ -255,6 +255,11 @@ parameters:
count: 1
path: ../src/PhpParser/Visitor/ReflectionVisitor.php

-
message: "#^Parameter \\#2 \\$env \\(array\\<bool\\|string\\>\\|null\\) of method Infection\\\\Process\\\\CoveredPhpProcess\\:\\:start\\(\\) should be contravariant with parameter \\$env \\(array\\) of method Symfony\\\\Component\\\\Process\\\\Process\\:\\:start\\(\\)$#"
count: 1
path: ../src/Process/CoveredPhpProcess.php

-
message: "#^Parameter \\#2 \\$env \\(array\\<bool\\|string\\>\\|null\\) of method Infection\\\\Process\\\\OriginalPhpProcess\\:\\:start\\(\\) should be contravariant with parameter \\$env \\(array\\) of method Symfony\\\\Component\\\\Process\\\\Process\\:\\:start\\(\\)$#"
count: 1
Expand Down
2 changes: 1 addition & 1 deletion devTools/phpstan-tests.neon
Expand Up @@ -16,7 +16,7 @@ parameters:
- '#^Cannot call method (willReturn|shouldBeCalledTimes)\(\) on iterable<Infection\\Mutation\\Mutation>\.$#'
- '#Offset .*\\.* does not exist on array<class-string<.*>.*#'
- '#Dynamic call to static method PHPUnit\\Framework\\.*::.*#'
- '#Call to method PHPUnit\\Framework\\Assert::.* with array.* and array.* will always evaluate to false#'
- '#Call to method PHPUnit\\Framework\\Assert::.* with .* and .* will always evaluate to (false|true)#'
- '#^PHPDoc tag @var for variable \$sourceFilesCollectorProphecy contains unresolvable type#'
-
path: '../tests/phpunit/TestFramework/PhpUnit/Config/Builder/InitialConfigBuilderTest.php'
Expand Down
1 change: 0 additions & 1 deletion devTools/xdebug-coverage.ini

This file was deleted.

68 changes: 68 additions & 0 deletions src/Process/CoveredPhpProcess.php
@@ -0,0 +1,68 @@
<?php
/**
* This code is licensed under the BSD 3-Clause License.
*
* Copyright (c) 2017, Maks Rafalko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

declare(strict_types=1);

namespace Infection\Process;

use function array_merge;
use function extension_loaded;
use Symfony\Component\Process\Process;

/**
* @internal
*
* Process which setups necessary environment variables to make coverage reporting happen
* without any extra user interaction.
*
* As of now we only cover Xdebug, adding XDEBUG_MODE environment variable to ensure it
* is properly activated. Since we can't know if Xdebug was offloaded, we add this env
* variable at most times, except when there's PCOV loaded: chances are Xdebug is not
* required when PCOV already used for coverage.
*/
final class CoveredPhpProcess extends Process
{
/**
* @param array<string|bool>|null $env
*/
public function start(?callable $callback = null, ?array $env = null): void
{
if (!extension_loaded('pcov')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also support phpdbg

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add a check for it, but they are mutually exclusive. You can't use Xdebug with PHPDBG, IIRC, so whenever we export or not this variable does not matter.

On the contrary, you can have both Xdebug and PCOV. And that's why we're making sure of not breaking stuff.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm voting to add add phpdbg check to this condition.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. Added.

$env = array_merge($env ?? [], [
'XDEBUG_MODE' => 'coverage',
]);
}

parent::start($callback, $env ?? []);
}
}
3 changes: 2 additions & 1 deletion src/Process/Factory/InitialTestsRunProcessFactory.php
Expand Up @@ -36,6 +36,7 @@
namespace Infection\Process\Factory;

use Infection\AbstractTestFramework\TestFrameworkAdapter;
use Infection\Process\CoveredPhpProcess;
use Infection\Process\OriginalPhpProcess;
use function method_exists;
use Symfony\Component\Process\Process;
Expand Down Expand Up @@ -64,7 +65,7 @@ public function createProcess(
bool $skipCoverage
): Process {
// If we're expecting to receive a code coverage, test process must run in a vanilla environment
$processClass = $skipCoverage ? Process::class : OriginalPhpProcess::class;
$processClass = $skipCoverage ? CoveredPhpProcess::class : OriginalPhpProcess::class;

/** @var Process $process */
$process = new $processClass(
Expand Down
2 changes: 1 addition & 1 deletion src/TestFramework/Coverage/CoverageChecker.php
Expand Up @@ -103,7 +103,7 @@ public function checkCoverageRequirements(): void
Coverage needs to be generated but no code coverage generator (pcov, phpdbg or xdebug) has been detected. Please either:
- Enable pcov and run Infection again
- Use phpdbg, e.g. `phpdbg -qrr infection`
- Enable Xdebug (in case of using Xdebug 3 check that `xdebug.mode` or environment variable XDEBUG_MODE set to `coverage`) and run Infection again
- Enable Xdebug and run Infection again
- Use the "--coverage" option with path to the existing coverage report
- Enable the code generator tool for the initial test run only, e.g. with `--initial-tests-php-options -d zend_extension=xdebug.so`
TXT
Expand Down
72 changes: 72 additions & 0 deletions tests/phpunit/Process/CoveredPhpProcessTest.php
@@ -0,0 +1,72 @@
<?php
/**
* This code is licensed under the BSD 3-Clause License.
*
* Copyright (c) 2017, Maks Rafalko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

declare(strict_types=1);

namespace Infection\Tests\Process;

use function extension_loaded;
use Infection\Process\CoveredPhpProcess;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Process;

final class CoveredPhpProcessTest extends TestCase
{
public function test_it_extends_symfony_process(): void
{
$process = new CoveredPhpProcess([]);

$this->assertInstanceOf(Process::class, $process);
}

public function test_it_takes_command_line(): void
{
$process = new CoveredPhpProcess(['foo']);
$this->assertStringContainsString('foo', $process->getCommandLine());
}

/**
* @group integration
*/
public function test_it_injects_xdebug_env_vars(): void
{
$process = new CoveredPhpProcess(['env']);
$process->run();

if (!extension_loaded('pcov')) {
$this->assertStringContainsString('XDEBUG_MODE=coverage', $process->getOutput());
} else {
$this->assertStringNotContainsString('XDEBUG_MODE=coverage', $process->getOutput());
}
}
}
Expand Up @@ -36,6 +36,7 @@
namespace Infection\Tests\Process\Factory;

use Infection\AbstractTestFramework\TestFrameworkAdapter;
use Infection\Process\CoveredPhpProcess;
use Infection\Process\Factory\InitialTestsRunProcessFactory;
use Infection\Process\OriginalPhpProcess;
use const PHP_OS_FAMILY;
Expand Down Expand Up @@ -86,6 +87,7 @@ public function test_it_creates_a_process_with_coverage_skipped(): void

$this->assertNull($process->getTimeout());
$this->assertNotInstanceOf(OriginalPhpProcess::class, $process);
$this->assertInstanceOf(CoveredPhpProcess::class, $process);
}

public function test_it_creates_a_process_with_coverage(): void
Expand Down
Expand Up @@ -142,7 +142,7 @@ public function test_it_needs_code_coverage_generator_enabled_if_coverage_is_not
Coverage needs to be generated but no code coverage generator (pcov, phpdbg or xdebug) has been detected. Please either:
- Enable pcov and run Infection again
- Use phpdbg, e.g. `phpdbg -qrr infection`
- Enable Xdebug (in case of using Xdebug 3 check that `xdebug.mode` or environment variable XDEBUG_MODE set to `coverage`) and run Infection again
- Enable Xdebug and run Infection again
- Use the "--coverage" option with path to the existing coverage report
- Enable the code generator tool for the initial test run only, e.g. with `--initial-tests-php-options -d zend_extension=xdebug.so`
TXT
Expand Down
Expand Up @@ -189,7 +189,7 @@ public function test_it_sorts_faster_than_quicksort(ArrayIterator $uniqueTestLoc
$totalQuickSort += microtime(true) - $start;
}

$this->assertGreaterThanOrEqual(0.01, abs($totalQuickSort - $totalBucketSort));
$this->assertGreaterThanOrEqual(0.001, abs($totalQuickSort - $totalBucketSort));
}

public static function locationsArrayProvider(): iterable
Expand Down