Skip to content

Commit 5f19f52

Browse files
committed
refactor: refactor RetryMiddlewareTest to use backoff option
1 parent 69dd200 commit 5f19f52

File tree

1 file changed

+54
-12
lines changed

1 file changed

+54
-12
lines changed

tests/Downloader/Middleware/RetryMiddlewareTest.php

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313

1414
namespace RoachPHP\Tests\Downloader\Middleware;
1515

16+
use InvalidArgumentException;
17+
use PHPUnit\Framework\Attributes\DataProvider;
1618
use PHPUnit\Framework\TestCase;
1719
use RoachPHP\Downloader\Middleware\RetryMiddleware;
1820
use RoachPHP\Scheduling\ArrayRequestScheduler;
1921
use RoachPHP\Scheduling\Timing\ClockInterface;
20-
use RoachPHP\Scheduling\Timing\FakeClock;
2122
use RoachPHP\Testing\Concerns\InteractsWithRequestsAndResponses;
2223
use RoachPHP\Testing\FakeLogger;
2324

@@ -69,7 +70,7 @@ public function testRetriesARetryableResponse(): void
6970
$this->middleware->configure([
7071
'retryOnStatus' => [503],
7172
'maxRetries' => 2,
72-
'initialDelay' => 500,
73+
'backoff' => [1, 2, 3],
7374
]);
7475

7576
$result = $this->middleware->handleResponse($response);
@@ -82,14 +83,14 @@ public function testRetriesARetryableResponse(): void
8283
$retriedRequest = $retriedRequests[0];
8384
self::assertSame(1, $retriedRequest->getMeta('retry_count'));
8485
self::assertSame('https://example.com', $retriedRequest->getUri());
85-
self::assertSame(500, $retriedRequest->getOptions()['delay']);
86+
self::assertSame(1000, $retriedRequest->getOptions()['delay']);
8687
}
8788

8889
public function testStopsRetryingAfterMaxRetries(): void
8990
{
9091
$request = $this->makeRequest()->withMeta('retry_count', 3);
9192
$response = $this->makeResponse(request: $request, status: 500);
92-
$this->middleware->configure(['maxRetries' => 3]);
93+
$this->middleware->configure(['maxRetries' => 3, 'backoff' => [1, 2, 3]]);
9394

9495
$result = $this->middleware->handleResponse($response);
9596

@@ -98,20 +99,61 @@ public function testStopsRetryingAfterMaxRetries(): void
9899
self::assertCount(0, $this->scheduler->forceNextRequests(10));
99100
}
100101

101-
public function testCalculatesExponentialBackoffCorrectly(): void
102+
public function testUsesBackoffArrayForDelay(): void
102103
{
103104
$request = $this->makeRequest()->withMeta('retry_count', 2);
104105
$response = $this->makeResponse(request: $request, status: 500);
105-
$this->middleware->configure([
106-
'initialDelay' => 1000, // 1s
107-
'delayMultiplier' => 2.0,
108-
]);
106+
$this->middleware->configure(['backoff' => [1, 5, 10]]);
107+
108+
$this->middleware->handleResponse($response);
109+
110+
$retriedRequest = $this->scheduler->forceNextRequests(10)[0];
111+
self::assertSame(10000, $retriedRequest->getOptions()['delay']);
112+
}
113+
114+
public function testUsesLastBackoffValueIfRetriesExceedBackoffCount(): void
115+
{
116+
$request = $this->makeRequest()->withMeta('retry_count', 5);
117+
$response = $this->makeResponse(request: $request, status: 500);
118+
$this->middleware->configure(['backoff' => [1, 5, 10], 'maxRetries' => 6]);
119+
120+
$this->middleware->handleResponse($response);
121+
122+
$retriedRequest = $this->scheduler->forceNextRequests(10)[0];
123+
self::assertSame(10000, $retriedRequest->getOptions()['delay']);
124+
}
125+
126+
public function testUsesIntegerBackoffForDelay(): void
127+
{
128+
$request = $this->makeRequest()->withMeta('retry_count', 2);
129+
$response = $this->makeResponse(request: $request, status: 500);
130+
$this->middleware->configure(['backoff' => 5]);
109131

110132
$this->middleware->handleResponse($response);
111133

112-
// initialDelay * (delayMultiplier ^ retry_count)
113-
// 1000 * (2.0 ^ 2) = 1000 * 4 = 4000ms
114134
$retriedRequest = $this->scheduler->forceNextRequests(10)[0];
115-
self::assertSame(4000, $retriedRequest->getOptions()['delay']);
135+
self::assertSame(5000, $retriedRequest->getOptions()['delay']);
136+
}
137+
138+
public static function invalidBackoffProvider(): array
139+
{
140+
return [
141+
'empty array' => [[], 'backoff array cannot be empty.'],
142+
'array with non-int' => [[1, 'a', 3], 'backoff array must contain only integers. Found: string'],
143+
'string' => ['not-an-array', 'backoff must be an integer or array, string given.'],
144+
'float' => [1.23, 'backoff must be an integer or array, double given.'],
145+
];
146+
}
147+
148+
#[DataProvider('invalidBackoffProvider')]
149+
public function testThrowsExceptionOnInvalidBackoff(mixed $backoff, string $expectedMessage): void
150+
{
151+
$this->expectException(InvalidArgumentException::class);
152+
$this->expectExceptionMessage($expectedMessage);
153+
154+
$response = $this->makeResponse(status: 500);
155+
$this->middleware->configure(['backoff' => $backoff]);
156+
157+
$this->middleware->handleResponse($response);
116158
}
117159
}

0 commit comments

Comments
 (0)