diff --git a/Monorepo/Benchmark/AsynchronousStackBenchmark.php b/Monorepo/Benchmark/AsynchronousStackBenchmark.php index e33203412..9ddbf9fa7 100644 --- a/Monorepo/Benchmark/AsynchronousStackBenchmark.php +++ b/Monorepo/Benchmark/AsynchronousStackBenchmark.php @@ -12,12 +12,14 @@ use Monorepo\ExampleApp\Common\Domain\Order\ShippingAddress; use Monorepo\ExampleApp\Common\Infrastructure\Configuration; use Monorepo\ExampleApp\ExampleAppCaseTrait; +use PHPUnit\Framework\Assert; use Psr\Container\ContainerInterface; use Ramsey\Uuid\Uuid; #[Warmup(1), Revs(10), Iterations(5)] -final class AsynchronousStackBenchmark extends FullAppBenchmarkCase +final class AsynchronousStackBenchmark extends Assert { + use FullAppBenchmarkCaseTrait; use ExampleAppCaseTrait; public function executeForSymfony(ContainerInterface $container, \Symfony\Component\HttpKernel\Kernel $kernel): void diff --git a/Monorepo/Benchmark/BootingEcotoneBenchmark.php b/Monorepo/Benchmark/BootingEcotoneBenchmark.php index f5a6e2a9b..c9511c6c5 100644 --- a/Monorepo/Benchmark/BootingEcotoneBenchmark.php +++ b/Monorepo/Benchmark/BootingEcotoneBenchmark.php @@ -8,11 +8,13 @@ use PhpBench\Attributes\Iterations; use PhpBench\Attributes\Revs; use PhpBench\Attributes\Warmup; +use PHPUnit\Framework\Assert; use Psr\Container\ContainerInterface; #[Warmup(1), Revs(10), Iterations(5)] -class BootingEcotoneBenchmark extends FullAppBenchmarkCase +class BootingEcotoneBenchmark extends Assert { + use FullAppBenchmarkCaseTrait; use ExampleAppCaseTrait; public function executeForSymfony(ContainerInterface $container, \Symfony\Component\HttpKernel\Kernel $kernel): void diff --git a/Monorepo/Benchmark/EventSourcingBenchmark.php b/Monorepo/Benchmark/EventSourcingBenchmark.php index 16d1b3b03..f5192507c 100644 --- a/Monorepo/Benchmark/EventSourcingBenchmark.php +++ b/Monorepo/Benchmark/EventSourcingBenchmark.php @@ -19,8 +19,9 @@ use Ramsey\Uuid\Uuid; #[Warmup(1), Revs(10), Iterations(5)] -class EventSourcingBenchmark extends FullAppBenchmarkCase +class EventSourcingBenchmark extends Assert { + use FullAppBenchmarkCaseTrait; use ExampleAppEventSourcingCaseTrait; public static function skippedPackages(): array diff --git a/Monorepo/Benchmark/FullAppBenchmarkCase.php b/Monorepo/Benchmark/FullAppBenchmarkCase.php index afa6b2598..0f486e5ae 100644 --- a/Monorepo/Benchmark/FullAppBenchmarkCase.php +++ b/Monorepo/Benchmark/FullAppBenchmarkCase.php @@ -2,269 +2,20 @@ namespace Monorepo\Benchmark; -use Ecotone\Messaging\Config\ConfiguredMessagingSystem; -use Ecotone\Messaging\Config\ModulePackageList; -use Ecotone\Messaging\Endpoint\ExecutionPollingMetadata; -use Illuminate\Foundation\Application; -use Illuminate\Foundation\Http\Kernel as LaravelKernel; -use Illuminate\Support\Facades\Artisan; - -use function json_encode; - -use PHPUnit\Framework\Assert; use PHPUnit\Framework\TestCase; -use Psr\Container\ContainerInterface; - -use function putenv; - -use Symfony\Bundle\FrameworkBundle\Console\Application as SymfonyConsoleApplication; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\NullOutput; -use Symfony\Component\HttpKernel\Kernel as SymfonyKernel; /** - * @BeforeClassMethods("clearAllCaches") + * Base for real PHPUnit test cases (run via `vendor/bin/phpunit`) that need the shared + * app-booting/cache-clearing/benchmark helpers in FullAppBenchmarkCaseTrait. PHPUnit + * constructs its TestCase subclasses itself (passing the test method name into + * TestCase::__construct(), which PHPUnit 12 made final), so extending TestCase here is safe. + * + * Pure PHPBench subjects (executed via `new $class()` with no constructor arguments, + * see phpbench's remote.template) must NOT extend this class — TestCase::__construct() + * requires a mandatory argument PHPBench never supplies. They should extend + * PHPUnit\Framework\Assert directly and `use FullAppBenchmarkCaseTrait;` instead. */ abstract class FullAppBenchmarkCase extends TestCase { - public function __construct(?string $name = 'benchmark') - { - parent::__construct($name); - } - public function bench_symfony_prod() - { - self::productionEnvironments(); - $kernel = self::bootSymfonyKernel(environment: 'prod', debug: false); - $container = $kernel->getContainer(); - - $this->executeForSymfony($container, $kernel); - } - - public function bench_symfony_dev() - { - self::developmentEnvironments(); - $kernel = self::bootSymfonyKernel(environment: 'dev', debug: true); - $container = $kernel->getContainer(); - - $this->executeForSymfony($container, $kernel); - } - - public function bench_laravel_prod(): void - { - self::productionEnvironments(); - $app = self::createLaravelApplication(); - - $this->executeForLaravel($app, $app->get(LaravelKernel::class)); - } - - public function bench_laravel_dev(): void - { - self::developmentEnvironments(); - $app = self::createLaravelApplication(); - - $this->executeForLaravel($app, $app->get(LaravelKernel::class)); - } - - public function bench_lite_application_prod() - { - self::productionEnvironments(); - $bootstrap = require static::getProjectDir() . '/LiteApplication/app.php'; - $messagingSystem = $bootstrap(true); - $this->executeForLiteApplication(new LiteContainerAccessor($messagingSystem)); - } - - public function bench_lite_application_dev() - { - self::developmentEnvironments(); - $bootstrap = require static::getProjectDir() . '/LiteApplication/app.php'; - $messagingSystem = $bootstrap(false); - $this->executeForLiteApplication(new LiteContainerAccessor($messagingSystem)); - } - - public function bench_lite_prod() - { - self::productionEnvironments(); - $bootstrap = require static::getProjectDir() . '/Lite/app.php'; - $messagingSystem = $bootstrap(true); - $this->executeForLite($messagingSystem); - } - - public function bench_lite_dev() - { - self::developmentEnvironments(); - $bootstrap = require static::getProjectDir() . '/Lite/app.php'; - $messagingSystem = $bootstrap(false); - $this->executeForLite($messagingSystem); - } - - public static function clearAllCaches(): void - { - self::clearLaravelCache(); - self::clearSymfonyCache(); - self::clearLiteApplicationCache(); - self::clearLiteCache(); - } - - public static function clearLiteCache(): void - { - self::deleteFiles( - static::getProjectDir() . '/Lite/var/cache', - false - ); - } - - public static function clearLiteApplicationCache(): void - { - self::deleteFiles( - static::getProjectDir() . '/LiteApplication/var/cache', - false - ); - } - - /** - * Calling config:cache always dumps the cache, - * this means we need to do it before the benchmark - */ - public function dumpLaravelCache(): void - { - self::productionEnvironments(); - self::createLaravelApplication(); - Artisan::call('route:cache'); - Artisan::call('config:cache'); - } - - public static function clearLaravelCache(): void - { - self::deleteFiles( - static::getProjectDir() . '/Laravel/storage/framework/cache/data', - false - ); - } - - public static function clearSymfonyCache(): void - { - self::deleteFiles( - static::getProjectDir() . '/Symfony/var/cache', - false - ); - } - - private static function deleteFiles(string $target, bool $deleteDirectory): void - { - if (is_dir($target)) { - \Ecotone\Messaging\Support\Assert::isTrue( - is_writable($target), - "Not enough permissions to delete from cache directory {$target}" - ); - $files = glob($target . '*', GLOB_MARK); - - foreach ($files as $file) { - self::deleteFiles($file, true); - } - - if ($deleteDirectory) { - rmdir($target); - } - } elseif (is_file($target)) { - Assert::isTrue( - is_writable($target), - "Not enough permissions to delete cache file {$target}" - ); - unlink($target); - } - } - - abstract public function executeForSymfony( - ContainerInterface $container, - SymfonyKernel $kernel - ): void; - - abstract public function executeForLaravel( - ContainerInterface $container, - LaravelKernel $kernel - ): void; - - abstract public function executeForLiteApplication( - ContainerInterface $container - ): void; - - abstract public function executeForLite( - ConfiguredMessagingSystem $messagingSystem - ): void; - - abstract protected static function getSymfonyKernelClass(): string; - abstract protected static function getProjectDir(): string; - - private static function productionEnvironments(): void - { - putenv('APP_ENV=prod'); - putenv('APP_DEBUG=false'); - putenv(sprintf('APP_SKIPPED_PACKAGES=%s', json_encode(static::skippedPackages(), JSON_THROW_ON_ERROR))); - } - - private static function developmentEnvironments(): void - { - putenv('APP_ENV=dev'); - putenv('APP_DEBUG=true'); - putenv(sprintf('APP_SKIPPED_PACKAGES=%s', json_encode(static::skippedPackages(), JSON_THROW_ON_ERROR))); - } - - public static function skippedPackages(): array - { - return ModulePackageList::allPackagesExcept([ModulePackageList::ASYNCHRONOUS_PACKAGE]); - } - - private static function createLaravelApplication(): Application - { - $app = require static::getProjectDir() . '/Laravel/bootstrap/app.php'; - - $app->make(LaravelKernel::class)->bootstrap(); - - return $app; - } - - public static function bootSymfonyKernel(string $environment, bool $debug): SymfonyKernel - { - $kernelClass = static::getSymfonyKernelClass(); - $kernel = new $kernelClass($environment, $debug); - $kernel->boot(); - return $kernel; - } - - public static function executeSymfonyConsoleCommand(SymfonyKernel $kernel, string $commandName, array $input): void - { - $application = new SymfonyConsoleApplication($kernel); - $result = $application->find($commandName)->run( - new ArrayInput($input), - new NullOutput() - ); - - Assert::assertSame(0, $result); - } - - public static function runConsumerForSymfony(string $consumerName, SymfonyKernel $kernel, bool $stopOnFailure = true): void - { - self::executeSymfonyConsoleCommand( - $kernel, - 'ecotone:run', - ['consumerName' => $consumerName, '--stopOnFailure' => $stopOnFailure, '--executionTimeLimit' => 2000, '--finishWhenNoMessages' => true] - ); - } - - public static function runConsumerForLaravel(string $consumerName, bool $stopOnFailure = true): void - { - Artisan::call( - 'ecotone:run', - ['consumerName' => $consumerName, '--stopOnFailure' => $stopOnFailure, '--executionTimeLimit' => 2000, '--finishWhenNoMessages' => true] - ); - } - - public static function runConsumerForMessaging(string $consumerName, ConfiguredMessagingSystem $messagingSystem, bool $stopOnFailure = true): void - { - $messagingSystem->run( - $consumerName, - ExecutionPollingMetadata::createWithFinishWhenNoMessages($stopOnFailure) - ->withExecutionTimeLimitInMilliseconds(2000) - ); - } + use FullAppBenchmarkCaseTrait; } diff --git a/Monorepo/Benchmark/FullAppBenchmarkCaseTrait.php b/Monorepo/Benchmark/FullAppBenchmarkCaseTrait.php new file mode 100644 index 000000000..51a848b3e --- /dev/null +++ b/Monorepo/Benchmark/FullAppBenchmarkCaseTrait.php @@ -0,0 +1,265 @@ +getContainer(); + + $this->executeForSymfony($container, $kernel); + } + + public function bench_symfony_dev() + { + self::developmentEnvironments(); + $kernel = self::bootSymfonyKernel(environment: 'dev', debug: true); + $container = $kernel->getContainer(); + + $this->executeForSymfony($container, $kernel); + } + + public function bench_laravel_prod(): void + { + self::productionEnvironments(); + $app = self::createLaravelApplication(); + + $this->executeForLaravel($app, $app->get(LaravelKernel::class)); + } + + public function bench_laravel_dev(): void + { + self::developmentEnvironments(); + $app = self::createLaravelApplication(); + + $this->executeForLaravel($app, $app->get(LaravelKernel::class)); + } + + public function bench_lite_application_prod() + { + self::productionEnvironments(); + $bootstrap = require static::getProjectDir() . '/LiteApplication/app.php'; + $messagingSystem = $bootstrap(true); + $this->executeForLiteApplication(new LiteContainerAccessor($messagingSystem)); + } + + public function bench_lite_application_dev() + { + self::developmentEnvironments(); + $bootstrap = require static::getProjectDir() . '/LiteApplication/app.php'; + $messagingSystem = $bootstrap(false); + $this->executeForLiteApplication(new LiteContainerAccessor($messagingSystem)); + } + + public function bench_lite_prod() + { + self::productionEnvironments(); + $bootstrap = require static::getProjectDir() . '/Lite/app.php'; + $messagingSystem = $bootstrap(true); + $this->executeForLite($messagingSystem); + } + + public function bench_lite_dev() + { + self::developmentEnvironments(); + $bootstrap = require static::getProjectDir() . '/Lite/app.php'; + $messagingSystem = $bootstrap(false); + $this->executeForLite($messagingSystem); + } + + public static function clearAllCaches(): void + { + self::clearLaravelCache(); + self::clearSymfonyCache(); + self::clearLiteApplicationCache(); + self::clearLiteCache(); + } + + public static function clearLiteCache(): void + { + self::deleteFiles( + static::getProjectDir() . '/Lite/var/cache', + false + ); + } + + public static function clearLiteApplicationCache(): void + { + self::deleteFiles( + static::getProjectDir() . '/LiteApplication/var/cache', + false + ); + } + + /** + * Calling config:cache always dumps the cache, + * this means we need to do it before the benchmark + */ + public function dumpLaravelCache(): void + { + self::productionEnvironments(); + self::createLaravelApplication(); + Artisan::call('route:cache'); + Artisan::call('config:cache'); + } + + public static function clearLaravelCache(): void + { + self::deleteFiles( + static::getProjectDir() . '/Laravel/storage/framework/cache/data', + false + ); + } + + public static function clearSymfonyCache(): void + { + self::deleteFiles( + static::getProjectDir() . '/Symfony/var/cache', + false + ); + } + + private static function deleteFiles(string $target, bool $deleteDirectory): void + { + if (is_dir($target)) { + \Ecotone\Messaging\Support\Assert::isTrue( + is_writable($target), + "Not enough permissions to delete from cache directory {$target}" + ); + $files = glob($target . '*', GLOB_MARK); + + foreach ($files as $file) { + self::deleteFiles($file, true); + } + + if ($deleteDirectory) { + rmdir($target); + } + } elseif (is_file($target)) { + Assert::isTrue( + is_writable($target), + "Not enough permissions to delete cache file {$target}" + ); + unlink($target); + } + } + + abstract public function executeForSymfony( + ContainerInterface $container, + SymfonyKernel $kernel + ): void; + + abstract public function executeForLaravel( + ContainerInterface $container, + LaravelKernel $kernel + ): void; + + abstract public function executeForLiteApplication( + ContainerInterface $container + ): void; + + abstract public function executeForLite( + ConfiguredMessagingSystem $messagingSystem + ): void; + + abstract protected static function getSymfonyKernelClass(): string; + abstract protected static function getProjectDir(): string; + + private static function productionEnvironments(): void + { + putenv('APP_ENV=prod'); + putenv('APP_DEBUG=false'); + putenv(sprintf('APP_SKIPPED_PACKAGES=%s', json_encode(static::skippedPackages(), JSON_THROW_ON_ERROR))); + } + + private static function developmentEnvironments(): void + { + putenv('APP_ENV=dev'); + putenv('APP_DEBUG=true'); + putenv(sprintf('APP_SKIPPED_PACKAGES=%s', json_encode(static::skippedPackages(), JSON_THROW_ON_ERROR))); + } + + public static function skippedPackages(): array + { + return ModulePackageList::allPackagesExcept([ModulePackageList::ASYNCHRONOUS_PACKAGE]); + } + + private static function createLaravelApplication(): Application + { + $app = require static::getProjectDir() . '/Laravel/bootstrap/app.php'; + + $app->make(LaravelKernel::class)->bootstrap(); + + return $app; + } + + public static function bootSymfonyKernel(string $environment, bool $debug): SymfonyKernel + { + $kernelClass = static::getSymfonyKernelClass(); + $kernel = new $kernelClass($environment, $debug); + $kernel->boot(); + return $kernel; + } + + public static function executeSymfonyConsoleCommand(SymfonyKernel $kernel, string $commandName, array $input): void + { + $application = new SymfonyConsoleApplication($kernel); + $result = $application->find($commandName)->run( + new ArrayInput($input), + new NullOutput() + ); + + Assert::assertSame(0, $result); + } + + public static function runConsumerForSymfony(string $consumerName, SymfonyKernel $kernel, bool $stopOnFailure = true): void + { + self::executeSymfonyConsoleCommand( + $kernel, + 'ecotone:run', + ['consumerName' => $consumerName, '--stopOnFailure' => $stopOnFailure, '--executionTimeLimit' => 2000, '--finishWhenNoMessages' => true] + ); + } + + public static function runConsumerForLaravel(string $consumerName, bool $stopOnFailure = true): void + { + Artisan::call( + 'ecotone:run', + ['consumerName' => $consumerName, '--stopOnFailure' => $stopOnFailure, '--executionTimeLimit' => 2000, '--finishWhenNoMessages' => true] + ); + } + + public static function runConsumerForMessaging(string $consumerName, ConfiguredMessagingSystem $messagingSystem, bool $stopOnFailure = true): void + { + $messagingSystem->run( + $consumerName, + ExecutionPollingMetadata::createWithFinishWhenNoMessages($stopOnFailure) + ->withExecutionTimeLimitInMilliseconds(2000) + ); + } +} diff --git a/Monorepo/Benchmark/HttpStackBenchmark.php b/Monorepo/Benchmark/HttpStackBenchmark.php index f83689fc6..b217b6697 100644 --- a/Monorepo/Benchmark/HttpStackBenchmark.php +++ b/Monorepo/Benchmark/HttpStackBenchmark.php @@ -19,8 +19,9 @@ use Symfony\Component\HttpFoundation\Request as SymfonyRequest; #[Warmup(1), Revs(10), Iterations(5)] -class HttpStackBenchmark extends FullAppBenchmarkCase +class HttpStackBenchmark extends Assert { + use FullAppBenchmarkCaseTrait; use ExampleAppCaseTrait; public function executeForSymfony(ContainerInterface $container, \Symfony\Component\HttpKernel\Kernel $kernel): void { diff --git a/Monorepo/Benchmark/KernelBootBenchmark.php b/Monorepo/Benchmark/KernelBootBenchmark.php index 81953069a..50f3ff61c 100644 --- a/Monorepo/Benchmark/KernelBootBenchmark.php +++ b/Monorepo/Benchmark/KernelBootBenchmark.php @@ -8,11 +8,13 @@ use PhpBench\Attributes\Iterations; use PhpBench\Attributes\Revs; use PhpBench\Attributes\Warmup; +use PHPUnit\Framework\Assert; use Psr\Container\ContainerInterface; #[Warmup(1), Revs(10), Iterations(5)] -class KernelBootBenchmark extends FullAppBenchmarkCase +class KernelBootBenchmark extends Assert { + use FullAppBenchmarkCaseTrait; use ExampleAppCaseTrait; public function executeForSymfony(ContainerInterface $container, \Symfony\Component\HttpKernel\Kernel $kernel): void diff --git a/composer.json b/composer.json index b65591abd..c48a9168e 100644 --- a/composer.json +++ b/composer.json @@ -164,21 +164,21 @@ "open-telemetry/sdk": "^1.0.0", "psr/container": "^1.1.1|^2.0.1", "psr/clock": "^1.0", - "symfony/uid": "^7.4" + "symfony/uid": "^7.4|^8.0" }, "require-dev": { "doctrine/annotations": "^1.13|^2.0", "doctrine/cache": "^1.0.0|^2.0", "doctrine/orm": "^2.11|^3.0", "friendsofphp/php-cs-fixer": "^3.9", - "guzzlehttp/psr7": "^2.0", + "guzzlehttp/psr7": "^2.0|^3.0", "orchestra/testbench": "^8.0|^9.0|^10.0|^11.0", "php-coveralls/php-coveralls": "^2.5", "phpstan/phpstan": "^1.8|^2.0", - "phpunit/phpunit": "^11.0", + "phpunit/phpunit": "^11.0|^12.0", "predis/predis": "^1.1.10", "symfony/expression-language": "^6.4|^7.0|^8.0", - "symplify/monorepo-builder": "11.1.21", + "symplify/monorepo-builder": "^12.0", "aws/aws-sdk-php": ">=3.340.5", "symfony/messenger": "^6.4|^7.0|^8.0", "symfony/amqp-messenger": "^6.4|^7.0|^8.0", @@ -193,7 +193,7 @@ "moneyphp/money": "^4.1.0", "timacdonald/log-fake": "^2.0", "symfony/monolog-bundle": "^3.10", - "kwn/php-rdkafka-stubs": "^2.2", + "kwn/php-rdkafka-stubs": "^2.2|^3.0", "symfony/var-exporter": "^6.4|^7.0|^8.0", "enqueue/dsn": "^0.10.27", "yoast/phpunit-polyfills": "^4.0.0", diff --git a/monorepo-builder.php b/monorepo-builder.php index 82aeaf76f..4944c2a00 100644 --- a/monorepo-builder.php +++ b/monorepo-builder.php @@ -29,10 +29,10 @@ "behat/behat" => "^3.10", "friendsofphp/php-cs-fixer" => "^3.9", "php-coveralls/php-coveralls" => "^2.5", - "phpstan/phpstan" => "^1.8", - "phpunit/phpunit" => "^9.6|^10.5|^11.0", + "phpstan/phpstan" => "^1.8|^2.0", + "phpunit/phpunit" => "^9.6|^10.5|^11.0|^12.0", "symfony/expression-language" => "^6.0|^7.0", - "symplify/monorepo-builder" => "11.1.21" + "symplify/monorepo-builder" => "^12.0" ], ]); $containerConfigurator->defaultBranch('main'); diff --git a/packages/Amqp/composer.json b/packages/Amqp/composer.json index 0219fb5e8..2467808e8 100644 --- a/packages/Amqp/composer.json +++ b/packages/Amqp/composer.json @@ -58,8 +58,8 @@ "enqueue/enqueue": "^0.10.0" }, "require-dev": { - "phpunit/phpunit": "^10.5|^11.0", - "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^10.5|^11.0|^12.0", + "phpstan/phpstan": "^1.8|^2.0", "doctrine/annotations": "^1.13|^2.0", "ext-amqp": "*", "enqueue/amqp-ext": "^0.10.18", diff --git a/packages/DataProtection/composer.json b/packages/DataProtection/composer.json index a171b22a1..ac702d7fb 100644 --- a/packages/DataProtection/composer.json +++ b/packages/DataProtection/composer.json @@ -57,7 +57,7 @@ }, "require-dev": { "ecotone/pdo-event-sourcing": "~1.325.0", - "phpunit/phpunit": "^11.0", + "phpunit/phpunit": "^11.0|^12.0", "phpstan/phpstan": "^2.1" }, "suggest": { diff --git a/packages/Dbal/composer.json b/packages/Dbal/composer.json index 10b63d9e5..51b6ab8d1 100644 --- a/packages/Dbal/composer.json +++ b/packages/Dbal/composer.json @@ -55,9 +55,9 @@ "enqueue/dsn": "^0.10.4" }, "require-dev": { - "phpunit/phpunit": "^10.5|^11.0", + "phpunit/phpunit": "^10.5|^11.0|^12.0", "doctrine/persistence": "^2.5|^3.4|^4.0", - "phpstan/phpstan": "^1.8", + "phpstan/phpstan": "^1.8|^2.0", "doctrine/orm": "^2.11|^3.0", "doctrine/cache": "^1.0.0|^2.0", "doctrine/annotations": "^1.13|^2.0", diff --git a/packages/Dbal/src/DbaBusinessMethod/DbaBusinessMethodModule.php b/packages/Dbal/src/DbaBusinessMethod/DbaBusinessMethodModule.php index 4f92b1fd2..de2b1bb4f 100644 --- a/packages/Dbal/src/DbaBusinessMethod/DbaBusinessMethodModule.php +++ b/packages/Dbal/src/DbaBusinessMethod/DbaBusinessMethodModule.php @@ -223,7 +223,7 @@ private static function getParameterConverters(DbalWrite|DbalQuery $attribute, I /** @var DbalParameter $dbalParameterAttribute */ $dbalParameterAttribute = $annotationsOfType[0]; - Assert::isFalse(isset($parameterConverters[$dbalParameterAttribute->getName()]), "Parameter {$dbalParameterAttribute->getName()} is defined twice"); + Assert::isFalse(isset($parameterConverters[$dbalParameterAttribute->getName() ?? $interfaceParameter->getName()]), "Parameter {$dbalParameterAttribute->getName()} is defined twice"); $parameterConverters[] = GatewayHeaderValueBuilder::create( DbalBusinessMethodHandler::HEADER_PARAMETER_TYPE_PREFIX . $interfaceParameter->getName(), self::dbalParameterConfig($dbalParameterAttribute, $interface, $interface->getMethodName(), $interfaceParameter->getName(), 0) diff --git a/packages/Dbal/tests/Integration/ClosureInAttribute/ClosureExpressionDbalTest.php b/packages/Dbal/tests/Integration/ClosureInAttribute/ClosureExpressionDbalTest.php index 3b271ab78..f9c5be164 100644 --- a/packages/Dbal/tests/Integration/ClosureInAttribute/ClosureExpressionDbalTest.php +++ b/packages/Dbal/tests/Integration/ClosureInAttribute/ClosureExpressionDbalTest.php @@ -32,7 +32,7 @@ * licence Enterprise * @internal */ -#[RequiresPhp('>= 8.5')] +#[RequiresPhp('>= 8.5.0')] final class ClosureExpressionDbalTest extends DbalMessagingTestCase { public function test_deduplication_with_closure_expression(): void diff --git a/packages/Dbal/tests/Integration/Consumer/GracefulShutdownOnSignalTest.php b/packages/Dbal/tests/Integration/Consumer/GracefulShutdownOnSignalTest.php index e76555167..0f161e475 100644 --- a/packages/Dbal/tests/Integration/Consumer/GracefulShutdownOnSignalTest.php +++ b/packages/Dbal/tests/Integration/Consumer/GracefulShutdownOnSignalTest.php @@ -37,7 +37,7 @@ public function test_consumer_stops_promptly_on_sigterm_despite_large_execution_ // this PHP process would duplicate the already-open DB connection's socket fd // (opened in DbalMessagingTestCase::setUp()) into the child and corrupt it. $parentPid = posix_getpid(); - exec(sprintf('(sleep 0.3 && kill -TERM %d) > /dev/null 2>&1 &', $parentPid)); + exec(sprintf('(sleep 1 && kill -TERM %d) > /dev/null 2>&1 &', $parentPid)); $ecotoneLite = EcotoneLite::bootstrapFlowTesting( containerOrAvailableServices: [ diff --git a/packages/Ecotone/composer.json b/packages/Ecotone/composer.json index bfea4ec23..e0022838b 100644 --- a/packages/Ecotone/composer.json +++ b/packages/Ecotone/composer.json @@ -61,9 +61,9 @@ "symfony/uid": "^6.4|^7.0|^8.0" }, "require-dev": { - "phpunit/phpunit": "^10.5|^11.0", + "phpunit/phpunit": "^10.5|^11.0|^12.0", "ramsey/uuid": "^4.0", - "phpstan/phpstan": "^1.8", + "phpstan/phpstan": "^1.8|^2.0", "symfony/console": "^6.4|^7.0|^8.0", "symfony/expression-language": "^6.4|^7.0|^8.0" }, diff --git a/packages/Ecotone/tests/Messaging/Unit/Handler/ClosureExpressionTest.php b/packages/Ecotone/tests/Messaging/Unit/Handler/ClosureExpressionTest.php index 9cab078f0..5939b6df3 100644 --- a/packages/Ecotone/tests/Messaging/Unit/Handler/ClosureExpressionTest.php +++ b/packages/Ecotone/tests/Messaging/Unit/Handler/ClosureExpressionTest.php @@ -27,7 +27,7 @@ * licence Enterprise * @internal */ -#[RequiresPhp('>= 8.5')] +#[RequiresPhp('>= 8.5.0')] final class ClosureExpressionTest extends TestCase { public function test_header_closure_expression_resolves_parameters_like_message_handler(): void diff --git a/packages/Ecotone/tests/SymfonyContainer/ClosureInAttributeTest.php b/packages/Ecotone/tests/SymfonyContainer/ClosureInAttributeTest.php index 8f5f09add..0043dd855 100644 --- a/packages/Ecotone/tests/SymfonyContainer/ClosureInAttributeTest.php +++ b/packages/Ecotone/tests/SymfonyContainer/ClosureInAttributeTest.php @@ -18,7 +18,7 @@ * licence Apache-2.0 * @internal */ -#[RequiresPhp('>= 8.5')] +#[RequiresPhp('>= 8.5.0')] final class ClosureInAttributeTest extends TestCase { public function test_intercepting_handler_with_attribute_containing_closure(): void diff --git a/packages/Enqueue/composer.json b/packages/Enqueue/composer.json index 38ddf0fd0..513ff6f8c 100644 --- a/packages/Enqueue/composer.json +++ b/packages/Enqueue/composer.json @@ -52,8 +52,8 @@ "enqueue/dsn": "^0.10.4" }, "require-dev": { - "phpunit/phpunit": "^10.5|^11.0", - "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^10.5|^11.0|^12.0", + "phpstan/phpstan": "^1.8|^2.0", "enqueue/null": "^0.10.18" }, "scripts": { diff --git a/packages/Enqueue/tests/InboundMessageConverterTest.php b/packages/Enqueue/tests/InboundMessageConverterTest.php index 6368743b7..1c3b2ec0b 100644 --- a/packages/Enqueue/tests/InboundMessageConverterTest.php +++ b/packages/Enqueue/tests/InboundMessageConverterTest.php @@ -45,7 +45,7 @@ public function test_it_will_map_automatically_core_headers(): void ), new NullConsumer(new NullQueue('some')), InMemoryConversionService::createWithoutConversion(), - $this->createMock(CachedConnectionFactory::class), + $this->createStub(CachedConnectionFactory::class), ) ->build(); diff --git a/packages/JmsConverter/composer.json b/packages/JmsConverter/composer.json index 4fc8a49f9..952b17275 100644 --- a/packages/JmsConverter/composer.json +++ b/packages/JmsConverter/composer.json @@ -55,8 +55,8 @@ }, "require-dev": { "ecotone/pdo-event-sourcing": "~1.325.0", - "phpunit/phpunit": "^10.5|^11.0", - "phpstan/phpstan": "^1.8" + "phpunit/phpunit": "^10.5|^11.0|^12.0", + "phpstan/phpstan": "^1.8|^2.0" }, "scripts": { "tests:phpstan": "vendor/bin/phpstan", diff --git a/packages/JmsConverter/phpunit.xml.dist b/packages/JmsConverter/phpunit.xml.dist index fc3ebe4f7..f46cbff43 100644 --- a/packages/JmsConverter/phpunit.xml.dist +++ b/packages/JmsConverter/phpunit.xml.dist @@ -1,20 +1,18 @@ - - - - ./src - - - - - - - - tests - - + + + + + + + + + tests + + + + + ./src + + diff --git a/packages/Kafka/composer.json b/packages/Kafka/composer.json index b58bde679..9e96603ed 100644 --- a/packages/Kafka/composer.json +++ b/packages/Kafka/composer.json @@ -51,10 +51,10 @@ "ecotone/ecotone": "~1.325.0" }, "require-dev": { - "phpunit/phpunit": "^10.5|^11.0", - "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^10.5|^11.0|^12.0", + "phpstan/phpstan": "^1.8|^2.0", "psr/container": "^1.1.1|^2.0.1", - "kwn/php-rdkafka-stubs": "^2.2", + "kwn/php-rdkafka-stubs": "^2.2|^3.0", "ecotone/dbal": "~1.325.0", "symfony/expression-language": "^6.4|^7.0|^8.0" }, diff --git a/packages/Laravel/composer.json b/packages/Laravel/composer.json index 34dc8c0e1..2c11192b4 100644 --- a/packages/Laravel/composer.json +++ b/packages/Laravel/composer.json @@ -57,9 +57,9 @@ "laravel/framework": "^9.5.2|^10.0|^11.0|^12.0|^13.0" }, "require-dev": { - "phpunit/phpunit": "^10.5|^11.0", - "guzzlehttp/psr7": "^2.0", - "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^10.5|^11.0|^12.0", + "guzzlehttp/psr7": "^2.0|^3.0", + "phpstan/phpstan": "^1.8|^2.0", "orchestra/testbench": "^8.0|^9.0|^10.0|^11.0", "symfony/expression-language": "^6.4|^7.0|^8.0", "nesbot/carbon": "^2.71|^3.0", diff --git a/packages/Laravel/tests/Application/config/database.php b/packages/Laravel/tests/Application/config/database.php index 69c54e41a..029ea29a5 100755 --- a/packages/Laravel/tests/Application/config/database.php +++ b/packages/Laravel/tests/Application/config/database.php @@ -88,7 +88,7 @@ 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ - PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + (class_exists(Pdo\Mysql::class) ? Pdo\Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'), ]) : [], ], diff --git a/packages/LiteApplication/composer.json b/packages/LiteApplication/composer.json index 7fd3d821d..c4532c174 100644 --- a/packages/LiteApplication/composer.json +++ b/packages/LiteApplication/composer.json @@ -52,9 +52,9 @@ "ecotone/jms-converter": "~1.325.0" }, "require-dev": { - "phpunit/phpunit": "^10.5|^11.0", - "guzzlehttp/psr7": "^2.0", - "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^10.5|^11.0|^12.0", + "guzzlehttp/psr7": "^2.0|^3.0", + "phpstan/phpstan": "^1.8|^2.0", "orchestra/testbench": "^8.0|^9.0|^10.0|^11.0" }, "extra": { diff --git a/packages/LiteApplication/phpunit.xml.dist b/packages/LiteApplication/phpunit.xml.dist index ded5bce80..02a9fbad9 100644 --- a/packages/LiteApplication/phpunit.xml.dist +++ b/packages/LiteApplication/phpunit.xml.dist @@ -1,39 +1,34 @@ - - - - - - - - - - - - - - - - - - - - - - ./src - - - - - - - - tests - - + + + + + + + + + + + + + + + + + + + + + + + + tests + + + + + ./src + + diff --git a/packages/OpenTelemetry/composer.json b/packages/OpenTelemetry/composer.json index f1dd2d4af..1ad59fe7a 100644 --- a/packages/OpenTelemetry/composer.json +++ b/packages/OpenTelemetry/composer.json @@ -51,12 +51,12 @@ "open-telemetry/sdk": "^1.0.0" }, "require-dev": { - "phpunit/phpunit": "^10.5|^11.0", - "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^10.5|^11.0|^12.0", + "phpstan/phpstan": "^1.8|^2.0", "open-telemetry/transport-grpc": "^1.0.0", "open-telemetry/exporter-otlp": "^1.0.0", "symfony/http-client": "^6.4|^7.0|^8.0", - "guzzlehttp/promises": "^1.5", + "guzzlehttp/promises": "^1.5|^2.0", "php-http/message-factory": "^1.0", "nyholm/psr7": "^1.5", "psr/http-client": "^1.0.1", diff --git a/packages/OpenTelemetry/phpunit.xml b/packages/OpenTelemetry/phpunit.xml index fc3ebe4f7..f46cbff43 100644 --- a/packages/OpenTelemetry/phpunit.xml +++ b/packages/OpenTelemetry/phpunit.xml @@ -1,20 +1,18 @@ - - - - ./src - - - - - - - - tests - - + + + + + + + + + tests + + + + + ./src + + diff --git a/packages/PdoEventSourcing/composer.json b/packages/PdoEventSourcing/composer.json index 34df0990e..064f69629 100644 --- a/packages/PdoEventSourcing/composer.json +++ b/packages/PdoEventSourcing/composer.json @@ -55,8 +55,8 @@ "prooph/pdo-event-store": "^1.16.3" }, "require-dev": { - "phpunit/phpunit": "^10.5|^11.0", - "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^10.5|^11.0|^12.0", + "phpstan/phpstan": "^1.8|^2.0", "symfony/process": "^6.4|^7.0|^8.0", "symfony/console": "^6.4|^7.0|^8.0", "doctrine/orm": "^2.11|^3.0", diff --git a/packages/Redis/composer.json b/packages/Redis/composer.json index 4ad1b6051..4f6bde983 100644 --- a/packages/Redis/composer.json +++ b/packages/Redis/composer.json @@ -55,9 +55,9 @@ "enqueue/redis": "^0.10.9" }, "require-dev": { - "phpstan/phpstan": "^1.8", - "phpunit/phpunit": "^10.5|^11.0", - "predis/predis": "^1.1.10" + "phpstan/phpstan": "^1.8|^2.0", + "phpunit/phpunit": "^10.5|^11.0|^12.0", + "predis/predis": "^1.1.10|^2.0" }, "scripts": { "tests:phpstan": "vendor/bin/phpstan", diff --git a/packages/Redis/phpunit.xml.dist b/packages/Redis/phpunit.xml.dist index fc3ebe4f7..f46cbff43 100644 --- a/packages/Redis/phpunit.xml.dist +++ b/packages/Redis/phpunit.xml.dist @@ -1,20 +1,18 @@ - - - - ./src - - - - - - - - tests - - + + + + + + + + + tests + + + + + ./src + + diff --git a/packages/Sqs/composer.json b/packages/Sqs/composer.json index b51f365e7..c58fc10a9 100644 --- a/packages/Sqs/composer.json +++ b/packages/Sqs/composer.json @@ -54,8 +54,8 @@ "aws/aws-sdk-php": ">=3.340.5" }, "require-dev": { - "phpunit/phpunit": "^10.5|^11.0", - "phpstan/phpstan": "^1.8" + "phpunit/phpunit": "^10.5|^11.0|^12.0", + "phpstan/phpstan": "^1.8|^2.0" }, "conflict": { "guzzlehttp/promises": "<1.4.0" diff --git a/packages/Sqs/phpunit.xml.dist b/packages/Sqs/phpunit.xml.dist index fc3ebe4f7..f46cbff43 100644 --- a/packages/Sqs/phpunit.xml.dist +++ b/packages/Sqs/phpunit.xml.dist @@ -1,20 +1,18 @@ - - - - ./src - - - - - - - - tests - - + + + + + + + + + tests + + + + + ./src + + diff --git a/packages/Symfony/composer.json b/packages/Symfony/composer.json index ac014625e..303c834dc 100644 --- a/packages/Symfony/composer.json +++ b/packages/Symfony/composer.json @@ -53,8 +53,8 @@ "ecotone/kafka": "~1.325.0", "ext-rdkafka": "*", "monolog/monolog": "^2.9|^3.3.1", - "phpstan/phpstan": "^1.8", - "phpunit/phpunit": "^10.5|^11.0", + "phpstan/phpstan": "^1.8|^2.0", + "phpunit/phpunit": "^10.5|^11.0|^12.0", "symfony/amqp-messenger": "^6.4|^7.0|^8.0", "symfony/doctrine-messenger": "^6.4|^7.0|^8.0", "symfony/expression-language": "^6.4|^7.0|^8.0", diff --git a/packages/Symfony/tests/phpunit/SymfonyMessengerMessageChannelUnitTest.php b/packages/Symfony/tests/phpunit/SymfonyMessengerMessageChannelUnitTest.php index da3d6a6d6..62257bde4 100644 --- a/packages/Symfony/tests/phpunit/SymfonyMessengerMessageChannelUnitTest.php +++ b/packages/Symfony/tests/phpunit/SymfonyMessengerMessageChannelUnitTest.php @@ -36,12 +36,12 @@ public function internalDisableErrorHandler(): void public function setUp(): void { $this->messageConverter = new SymfonyMessageConverter( - $this->createMock(HeaderMapper::class), + $this->createStub(HeaderMapper::class), 'mode', - $this->createMock(ConversionService::class) + $this->createStub(ConversionService::class) ); $this->envelope = new Envelope( - $this->createMock(stdClass::class), + $this->createStub(stdClass::class), [ new MetadataStamp([]), ], @@ -50,7 +50,7 @@ public function setUp(): void public function test_symfony_envelope_returns_array(): void { - $transport = $this->createMock(DoctrineTransport::class); + $transport = $this->createStub(DoctrineTransport::class); $transport->method('get')->willReturn([$this->envelope]); $transport->method('getMessageCount')->willReturn(1); $messageChannel = new SymfonyMessengerMessageChannel($transport, $this->messageConverter); @@ -65,7 +65,7 @@ private function singleMessageGenerator(): iterable public function test_symfony_envelope_returns_generator(): void { - $transport = $this->createMock(AmqpTransport::class); + $transport = $this->createStub(AmqpTransport::class); $transport->method('get')->willReturn($this->singleMessageGenerator()); $transport->method('getMessageCount')->willReturn(1); $messageChannel = new SymfonyMessengerMessageChannel($transport, $this->messageConverter); diff --git a/packages/Tempest/composer.json b/packages/Tempest/composer.json index b4d19dcba..0706defe3 100644 --- a/packages/Tempest/composer.json +++ b/packages/Tempest/composer.json @@ -59,7 +59,7 @@ "enqueue/dbal": "DBAL-backed message queue transport; required if you want durable async messaging over a relational database using ecotone/dbal." }, "require-dev": { - "phpunit/phpunit": "^11.0", + "phpunit/phpunit": "^11.0|^12.0", "phpstan/phpstan": "^1.8|^2.0", "symfony/expression-language": "^6.4|^7.0|^8.0", "ecotone/dbal": "~1.325.0",