diff --git a/CHANGELOG.md b/CHANGELOG.md index 59c3e34..b26241b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ ## Changes -## 0.13.0 - 10/04/2024 +## 0.13.0 - 12/04/2024 +* Add commaand line argument to configure default http client configuration +* Fixed allow self signed certificate not used * **[BC BREAK]** HTTP test case now rely exclusively on amp http client (no more psr7 or psr18) * Fix assertions count * Add a new attribute to configure HttpClient (allow to set timeout) diff --git a/src/Attribute/HttpClientConfiguration.php b/src/Attribute/HttpClientConfiguration.php index 154432f..4a8622c 100644 --- a/src/Attribute/HttpClientConfiguration.php +++ b/src/Attribute/HttpClientConfiguration.php @@ -8,6 +8,7 @@ public function __construct( public float $timeout = 10, public int $retry = 0, + public bool $allowSelfSignedCertificate = false, ) { } } diff --git a/src/Command/AsynitCommand.php b/src/Command/AsynitCommand.php index 0f59e7d..301615e 100644 --- a/src/Command/AsynitCommand.php +++ b/src/Command/AsynitCommand.php @@ -2,6 +2,7 @@ namespace Asynit\Command; +use Asynit\Attribute\HttpClientConfiguration; use Asynit\Output\OutputFactory; use Asynit\Parser\TestPoolBuilder; use Asynit\Parser\TestsFinder; @@ -27,6 +28,8 @@ protected function configure(): void ->addOption('host', null, InputOption::VALUE_REQUIRED, 'Base host to use', null) ->addOption('allow-self-signed-certificate', null, InputOption::VALUE_NONE, 'Allow self signed ssl certificate') ->addOption('concurrency', null, InputOption::VALUE_REQUIRED, 'Max number of parallels requests', 10) + ->addOption('timeout', null, InputOption::VALUE_REQUIRED, 'Default timeout for http request', 10) + ->addOption('retry', null, InputOption::VALUE_REQUIRED, 'Default retry number for http request', 0) ->addOption('bootstrap', null, InputOption::VALUE_REQUIRED, 'A PHP file to include before anything else', $this->defaultBootstrapFilename) ->addOption('order', null, InputOption::VALUE_NONE, 'Output tests execution order') ; @@ -47,8 +50,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int list($chainOutput, $countOutput) = (new OutputFactory($input->getOption('order')))->buildOutput(\count($testMethods)); + $defaultHttpConfiguration = new HttpClientConfiguration( + timeout: $input->getOption('timeout'), + retry: $input->getOption('retry'), + allowSelfSignedCertificate: $input->hasOption('allow-self-signed-certificate'), + ); + $builder = new TestPoolBuilder(); - $runner = new PoolRunner(new TestWorkflow($chainOutput), $input->getOption('concurrency')); + $runner = new PoolRunner($defaultHttpConfiguration, new TestWorkflow($chainOutput), $input->getOption('concurrency')); // Build a list of tests from the directory $pool = $builder->build($testMethods); diff --git a/src/HttpClient/ConfigurationInterceptor.php b/src/HttpClient/ConfigurationInterceptor.php new file mode 100644 index 0000000..fc88054 --- /dev/null +++ b/src/HttpClient/ConfigurationInterceptor.php @@ -0,0 +1,27 @@ +setInactivityTimeout($this->configuration->timeout); + $request->setTcpConnectTimeout($this->configuration->timeout); + $request->setTlsHandshakeTimeout($this->configuration->timeout); + $request->setTransferTimeout($this->configuration->timeout); + + return $httpClient->request($request, $cancellation); + } +} diff --git a/src/HttpClient/HttpClientCaseTrait.php b/src/HttpClient/HttpClientCaseTrait.php index 1cc4cf4..f47516e 100644 --- a/src/HttpClient/HttpClientCaseTrait.php +++ b/src/HttpClient/HttpClientCaseTrait.php @@ -21,15 +21,11 @@ trait HttpClientCaseTrait private ?HttpClient $httpClient = null; - private ?\Closure $configureRequest = null; - - protected $allowSelfSignedCertificate = false; - - protected function createHttpClient(bool $allowSelfSignedCertificate = false, HttpClientConfiguration $httpClientConfiguration = new HttpClientConfiguration()): HttpClient + protected function createHttpClient(HttpClientConfiguration $httpClientConfiguration = new HttpClientConfiguration()): HttpClient { $tlsContext = new ClientTlsContext(''); - if ($allowSelfSignedCertificate) { + if ($httpClientConfiguration->allowSelfSignedCertificate) { $tlsContext = $tlsContext->withoutPeerVerification(); } @@ -39,31 +35,23 @@ protected function createHttpClient(bool $allowSelfSignedCertificate = false, Ht $builder = new HttpClientBuilder(); $builder = $builder->retry($httpClientConfiguration->retry); $builder = $builder->usingPool(new UnlimitedConnectionPool(new DefaultConnectionFactory(null, $connectContext))); + $builder = $builder->intercept(new ConfigurationInterceptor($httpClientConfiguration)); return $builder->build(); } #[OnCreate] - final public function setUpHttpClient(): void + final public function setUpHttpClient(HttpClientConfiguration $httpClientConfiguration): void { $reflection = new \ReflectionClass($this); - $httpClientConfiguration = $reflection->getAttributes(HttpClientConfiguration::class); + $httpClientConfigurationAttribute = $reflection->getAttributes(HttpClientConfiguration::class); - if (!$httpClientConfiguration) { - $httpClientConfiguration = new HttpClientConfiguration(); - } else { - $httpClientConfiguration = $httpClientConfiguration[0]->newInstance(); + if ($httpClientConfigurationAttribute) { + $httpClientConfiguration = $httpClientConfigurationAttribute[0]->newInstance(); } - $this->httpClient = $this->createHttpClient($this->allowSelfSignedCertificate, $httpClientConfiguration); - - $this->configureRequest = function (Request $request) use ($httpClientConfiguration) { - $request->setInactivityTimeout($httpClientConfiguration->timeout); - $request->setTcpConnectTimeout($httpClientConfiguration->timeout); - $request->setTlsHandshakeTimeout($httpClientConfiguration->timeout); - $request->setTransferTimeout($httpClientConfiguration->timeout); - }; + $this->httpClient = $this->createHttpClient($httpClientConfiguration); } /** @@ -71,11 +59,6 @@ final public function setUpHttpClient(): void */ final protected function sendRequest(Request $request): Response { - if (null !== $this->configureRequest) { - $configureRequest = $this->configureRequest; - $configureRequest($request); - } - return $this->httpClient->request($request); } } diff --git a/src/Runner/PoolRunner.php b/src/Runner/PoolRunner.php index 6167653..fbbacd8 100644 --- a/src/Runner/PoolRunner.php +++ b/src/Runner/PoolRunner.php @@ -5,6 +5,7 @@ use Amp\Future; use Amp\Sync\LocalSemaphore; use Amp\Sync\Semaphore; +use Asynit\Attribute\HttpClientConfiguration; use Asynit\Attribute\OnCreate; use Asynit\Pool; use Asynit\Test; @@ -22,8 +23,11 @@ class PoolRunner /** * @param positive-int $concurrency */ - public function __construct(private TestWorkflow $workflow, int $concurrency = 10) - { + public function __construct( + private HttpClientConfiguration $defaultHttpConfiguration, + private TestWorkflow $workflow, + int $concurrency = 10 + ) { $this->semaphore = new LocalSemaphore($concurrency); } @@ -102,7 +106,7 @@ private function getTestCase(Test $test): object continue; } - $testCase->{$reflectionMethod->getName()}(); + $testCase->{$reflectionMethod->getName()}($this->defaultHttpConfiguration); } $this->testCases[$reflectionClass->getName()] = $testCase;