mirror of
https://github.com/shlinkio/shlink.git
synced 2024-12-23 07:33:58 -06:00
Move E2E coverage collectors to shlink-test-utils
This commit is contained in:
parent
9296013596
commit
dd7545afdf
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -133,8 +133,8 @@ jobs:
|
|||||||
- run: mv build/coverage-db/coverage-db.cov build/coverage-db.cov
|
- run: mv build/coverage-db/coverage-db.cov build/coverage-db.cov
|
||||||
- run: mv build/coverage-api/coverage-api.cov build/coverage-api.cov
|
- run: mv build/coverage-api/coverage-api.cov build/coverage-api.cov
|
||||||
- run: mv build/coverage-cli/coverage-cli.cov build/coverage-cli.cov
|
- run: mv build/coverage-cli/coverage-cli.cov build/coverage-cli.cov
|
||||||
- run: wget https://phar.phpunit.de/phpcov-9.0.0.phar
|
- run: wget https://phar.phpunit.de/phpcov-10.0.0.phar
|
||||||
- run: php phpcov-9.0.0.phar merge build --clover build/clover.xml
|
- run: php phpcov-10.0.0.phar merge build --clover build/clover.xml
|
||||||
- name: Publish coverage
|
- name: Publish coverage
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v1
|
||||||
with:
|
with:
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,3 +15,4 @@ docs/mercure.html
|
|||||||
docker-compose.override.yml
|
docker-compose.override.yml
|
||||||
.phpunit.result.cache
|
.phpunit.result.cache
|
||||||
docs/swagger/swagger-inlined.json
|
docs/swagger/swagger-inlined.json
|
||||||
|
phpcov*
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
"phpunit/phpunit": "^10.4",
|
"phpunit/phpunit": "^10.4",
|
||||||
"roave/security-advisories": "dev-master",
|
"roave/security-advisories": "dev-master",
|
||||||
"shlinkio/php-coding-standard": "~2.3.0",
|
"shlinkio/php-coding-standard": "~2.3.0",
|
||||||
"shlinkio/shlink-test-utils": "^3.8.1",
|
"shlinkio/shlink-test-utils": "^3.9",
|
||||||
"symfony/var-dumper": "^6.4",
|
"symfony/var-dumper": "^6.4",
|
||||||
"veewee/composer-run-parallel": "^1.3"
|
"veewee/composer-run-parallel": "^1.3"
|
||||||
},
|
},
|
||||||
|
@ -7,12 +7,6 @@ namespace Shlinkio\Shlink\TestUtils;
|
|||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
use function register_shutdown_function;
|
|
||||||
use function sprintf;
|
|
||||||
|
|
||||||
use const ShlinkioTest\Shlink\API_TESTS_HOST;
|
|
||||||
use const ShlinkioTest\Shlink\API_TESTS_PORT;
|
|
||||||
|
|
||||||
/** @var ContainerInterface $container */
|
/** @var ContainerInterface $container */
|
||||||
$container = require __DIR__ . '/../container.php';
|
$container = require __DIR__ . '/../container.php';
|
||||||
$testHelper = $container->get(Helper\TestHelper::class);
|
$testHelper = $container->get(Helper\TestHelper::class);
|
||||||
@ -20,14 +14,6 @@ $config = $container->get('config');
|
|||||||
$em = $container->get(EntityManager::class);
|
$em = $container->get(EntityManager::class);
|
||||||
$httpClient = $container->get('shlink_test_api_client');
|
$httpClient = $container->get('shlink_test_api_client');
|
||||||
|
|
||||||
// Dump code coverage when process shuts down
|
|
||||||
register_shutdown_function(function () use ($httpClient): void {
|
|
||||||
$httpClient->request(
|
|
||||||
'GET',
|
|
||||||
sprintf('http://%s:%s/api-tests/stop-coverage', API_TESTS_HOST, API_TESTS_PORT),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
$testHelper->createTestDb(
|
$testHelper->createTestDb(
|
||||||
createDbCommand: ['bin/cli', 'db:create'],
|
createDbCommand: ['bin/cli', 'db:create'],
|
||||||
migrateDbCommand: ['bin/cli', 'db:migrate'],
|
migrateDbCommand: ['bin/cli', 'db:migrate'],
|
||||||
|
@ -6,15 +6,9 @@ namespace Shlinkio\Shlink;
|
|||||||
|
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use Laminas\ConfigAggregator\ConfigAggregator;
|
use Laminas\ConfigAggregator\ConfigAggregator;
|
||||||
use Laminas\Diactoros\Response\EmptyResponse;
|
|
||||||
use Laminas\ServiceManager\Factory\InvokableFactory;
|
use Laminas\ServiceManager\Factory\InvokableFactory;
|
||||||
use League\Event\EventDispatcher;
|
|
||||||
use Monolog\Level;
|
use Monolog\Level;
|
||||||
use PHPUnit\Runner\Version;
|
use PHPUnit\Runner\Version;
|
||||||
use Psr\Container\ContainerInterface;
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
|
||||||
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
use SebastianBergmann\CodeCoverage\CodeCoverage;
|
||||||
use SebastianBergmann\CodeCoverage\Driver\Selector;
|
use SebastianBergmann\CodeCoverage\Driver\Selector;
|
||||||
use SebastianBergmann\CodeCoverage\Filter;
|
use SebastianBergmann\CodeCoverage\Filter;
|
||||||
@ -22,13 +16,12 @@ use SebastianBergmann\CodeCoverage\Report\Html\Facade as Html;
|
|||||||
use SebastianBergmann\CodeCoverage\Report\PHP;
|
use SebastianBergmann\CodeCoverage\Report\PHP;
|
||||||
use SebastianBergmann\CodeCoverage\Report\Xml\Facade as Xml;
|
use SebastianBergmann\CodeCoverage\Report\Xml\Facade as Xml;
|
||||||
use Shlinkio\Shlink\Common\Logger\LoggerType;
|
use Shlinkio\Shlink\Common\Logger\LoggerType;
|
||||||
|
use Shlinkio\Shlink\TestUtils\ApiTest\CoverageMiddleware;
|
||||||
|
use Shlinkio\Shlink\TestUtils\CliTest\CliCoverageDelegator;
|
||||||
use Symfony\Component\Console\Application;
|
use Symfony\Component\Console\Application;
|
||||||
use Symfony\Component\Console\Event\ConsoleCommandEvent;
|
|
||||||
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
|
|
||||||
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
|
||||||
|
|
||||||
use function file_exists;
|
use function file_exists;
|
||||||
use function Laminas\Stratigility\middleware;
|
use function register_shutdown_function;
|
||||||
use function Shlinkio\Shlink\Config\env;
|
use function Shlinkio\Shlink\Config\env;
|
||||||
use function Shlinkio\Shlink\Core\ArrayUtils\contains;
|
use function Shlinkio\Shlink\Core\ArrayUtils\contains;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
@ -36,7 +29,7 @@ use function sprintf;
|
|||||||
use const ShlinkioTest\Shlink\API_TESTS_HOST;
|
use const ShlinkioTest\Shlink\API_TESTS_HOST;
|
||||||
use const ShlinkioTest\Shlink\API_TESTS_PORT;
|
use const ShlinkioTest\Shlink\API_TESTS_PORT;
|
||||||
|
|
||||||
$isApiTest = env('TEST_ENV') === 'api';
|
$isApiTest = env('TEST_ENV') === 'api' && env('RR_MODE') === 'http';
|
||||||
$isCliTest = env('TEST_ENV') === 'cli';
|
$isCliTest = env('TEST_ENV') === 'cli';
|
||||||
$isE2eTest = $isApiTest || $isCliTest;
|
$isE2eTest = $isApiTest || $isCliTest;
|
||||||
$coverageType = env('GENERATE_COVERAGE');
|
$coverageType = env('GENERATE_COVERAGE');
|
||||||
@ -75,6 +68,13 @@ $exportCoverage = static function (string $type = 'api') use (&$coverage, $cover
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Dump code coverage when process shuts down, only if running in HTTP mode
|
||||||
|
register_shutdown_function(function () use ($exportCoverage, $isApiTest): void {
|
||||||
|
if ($isApiTest) {
|
||||||
|
$exportCoverage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$buildDbConnection = static function (): array {
|
$buildDbConnection = static function (): array {
|
||||||
$driver = env('DB_DRIVER', 'sqlite');
|
$driver = env('DB_DRIVER', 'sqlite');
|
||||||
$isCi = env('CI', false);
|
$isCi = env('CI', false);
|
||||||
@ -135,34 +135,9 @@ return [
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
'routes' => !$isApiTest ? [] : [
|
|
||||||
[
|
|
||||||
'name' => 'dump_coverage',
|
|
||||||
'path' => '/api-tests/stop-coverage',
|
|
||||||
'middleware' => middleware(static function () use ($exportCoverage) {
|
|
||||||
// TODO I have tried moving this block to a listener so that it's invoked automatically,
|
|
||||||
// but then the coverage is generated empty ¯\_(ツ)_/¯
|
|
||||||
$exportCoverage();
|
|
||||||
return new EmptyResponse();
|
|
||||||
}),
|
|
||||||
'allowed_methods' => ['GET'],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
|
|
||||||
'middleware_pipeline' => !$isApiTest ? [] : [
|
'middleware_pipeline' => !$isApiTest ? [] : [
|
||||||
'capture_code_coverage' => [
|
'capture_code_coverage' => [
|
||||||
'middleware' => middleware(static function (
|
'middleware' => new CoverageMiddleware($coverage),
|
||||||
ServerRequestInterface $req,
|
|
||||||
RequestHandlerInterface $handler,
|
|
||||||
) use (&$coverage): ResponseInterface {
|
|
||||||
$coverage?->start($req->getHeaderLine('x-coverage-id'));
|
|
||||||
|
|
||||||
try {
|
|
||||||
return $handler->handle($req);
|
|
||||||
} finally {
|
|
||||||
$coverage?->stop();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
'priority' => 9999,
|
'priority' => 9999,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -185,58 +160,7 @@ return [
|
|||||||
],
|
],
|
||||||
'delegators' => $isCliTest ? [
|
'delegators' => $isCliTest ? [
|
||||||
Application::class => [
|
Application::class => [
|
||||||
static function (
|
new CliCoverageDelegator($exportCoverage(...), $coverage),
|
||||||
ContainerInterface $c,
|
|
||||||
string $serviceName,
|
|
||||||
callable $callback,
|
|
||||||
) use (
|
|
||||||
&$coverage,
|
|
||||||
$exportCoverage,
|
|
||||||
) {
|
|
||||||
/** @var Application $app */
|
|
||||||
$app = $callback();
|
|
||||||
$wrappedEventDispatcher = new EventDispatcher();
|
|
||||||
|
|
||||||
// When the command starts, start collecting coverage
|
|
||||||
$wrappedEventDispatcher->subscribeTo(
|
|
||||||
ConsoleCommandEvent::class,
|
|
||||||
static function () use (&$coverage): void {
|
|
||||||
$id = env('COVERAGE_ID');
|
|
||||||
if ($id === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$coverage?->start($id);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
// When the command ends, stop collecting coverage
|
|
||||||
$wrappedEventDispatcher->subscribeTo(
|
|
||||||
ConsoleTerminateEvent::class,
|
|
||||||
static function () use (&$coverage, $exportCoverage): void {
|
|
||||||
$id = env('COVERAGE_ID');
|
|
||||||
if ($id === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$coverage?->stop();
|
|
||||||
$exportCoverage('cli');
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
$app->setDispatcher(new class ($wrappedEventDispatcher) implements EventDispatcherInterface {
|
|
||||||
public function __construct(private EventDispatcher $wrappedDispatcher)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dispatch(object $event, ?string $eventName = null): object
|
|
||||||
{
|
|
||||||
$this->wrappedDispatcher->dispatch($event);
|
|
||||||
return $event;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return $app;
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
] : [],
|
] : [],
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user