Skip to content

Commit

Permalink
feat(http): add http timeout attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
joelwurtz committed Apr 10, 2024
1 parent c318579 commit 9b364b7
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 19 deletions.
13 changes: 13 additions & 0 deletions src/Attribute/HttpTimeout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Asynit\Attribute;

#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
final readonly class HttpTimeout
{
public function __construct(
public float $timeout,
)
{
}
}
34 changes: 31 additions & 3 deletions src/HttpClient/HttpClientCaseTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@
use Amp\Http\Client\HttpClient;
use Amp\Http\Client\HttpClientBuilder;
use Amp\Http\Client\Request;
use Amp\Http\HttpResponse;
use Amp\Http\Client\Response;
use Amp\Socket\ClientTlsContext;
use Amp\Socket\ConnectContext;
use Asynit\Assert\AssertWebCaseTrait;
use Asynit\Attribute\HttpTimeout;
use Asynit\Attribute\OnCreate;
use Asynit\Test;

trait HttpClientCaseTrait
{
use AssertWebCaseTrait;

private HttpClient|null $httpClient = null;

private \Closure|null $configureRequest = null;

protected $allowSelfSignedCertificate = false;

protected function createHttpClient(bool $allowSelfSignedCertificate = false): HttpClient
Expand All @@ -39,16 +43,40 @@ protected function createHttpClient(bool $allowSelfSignedCertificate = false): H
}

#[OnCreate]
final public function setUpHttpClient(): void
final public function setUpHttpClient(Test $test): void
{
$this->httpClient = $this->createHttpClient($this->allowSelfSignedCertificate);

$httpTimeout = $test->getMethod()->getAttributes(HttpTimeout::class);

if (!$httpTimeout) {
$httpTimeout = $test->getMethod()->getDeclaringClass()->getAttributes(HttpTimeout::class);
}

$timeout = 10;

if ($httpTimeout) {
$timeout = $httpTimeout[0]->newInstance()->timeout;
}

$this->configureRequest = function (Request $request) use ($timeout) {
$request->setInactivityTimeout($timeout);
$request->setTcpConnectTimeout($timeout);
$request->setTlsHandshakeTimeout($timeout);
$request->setTransferTimeout($timeout);
};
}

/**
* Allow to test a rejection or a resolution of an async call.
*/
final protected function sendRequest(Request $request): HttpResponse
final protected function sendRequest(Request $request): Response
{
if ($this->configureRequest !== null) {
$configureRequest = $this->configureRequest;
$configureRequest($request);
}

return $this->httpClient->request($request);
}
}
23 changes: 7 additions & 16 deletions src/Runner/PoolRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ class PoolRunner
{
private Semaphore $semaphore;

/** @var object[] */
private $testCases = [];

/**
* @param positive-int $concurrency
*/
Expand Down Expand Up @@ -88,24 +85,18 @@ protected function run(Test $test): void
private function getTestCase(Test $test): object
{
$reflectionClass = $test->getMethod()->getDeclaringClass();
$testCase = $reflectionClass->newInstance();

if (!isset($this->testCases[$reflectionClass->getName()])) {
$testCase = $reflectionClass->newInstance();

// Find all methods with attribute OnCreate
foreach ($reflectionClass->getMethods() as $reflectionMethod) {
$onCreate = $reflectionMethod->getAttributes(OnCreate::class);
foreach ($reflectionClass->getMethods() as $reflectionMethod) {
$onCreate = $reflectionMethod->getAttributes(OnCreate::class);

if (0 === count($onCreate)) {
continue;
}

$testCase->{$reflectionMethod->getName()}($test);
if (0 === count($onCreate)) {
continue;
}

$this->testCases[$reflectionClass->getName()] = $testCase;
$testCase->{$reflectionMethod->getName()}($test);
}

return $this->testCases[$reflectionClass->getName()];
return $testCase;
}
}
15 changes: 15 additions & 0 deletions tests/FunctionalHttpTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Amp\Http\HttpResponse;
use Asynit\Attribute\Depend;
use Asynit\Attribute\HttpTimeout;
use Asynit\Attribute\TestCase;
use Asynit\HttpClient\HttpClientWebCaseTrait;

Expand Down Expand Up @@ -120,6 +121,20 @@ public function test_c_with_d($a, $b, $d)
$this->assertSame('d', $d);
}

#[HttpTimeout(1)]
public function testTimeout()
{
try {
$this->get($this->createUri('/delay/2'));
$hasException = false;
} catch (\Exception $e) {
$this->assertInstanceOf(\Amp\Http\Client\HttpException::class, $e);
$hasException = true;
}

$this->assertTrue($hasException);
}

protected function createUri(string $uri): string
{
return 'http://127.0.0.1:8081'.$uri;
Expand Down

0 comments on commit 9b364b7

Please sign in to comment.