| 1 |
<?php |
| 2 |
namespace GuzzleHttp\Tests; |
| 3 |
|
| 4 |
use GuzzleHttp\Client; |
| 5 |
use GuzzleHttp\Handler\MockHandler; |
| 6 |
use GuzzleHttp\Middleware; |
| 7 |
use GuzzleHttp\Psr7; |
| 8 |
use GuzzleHttp\Psr7\Request; |
| 9 |
use GuzzleHttp\Psr7\Response; |
| 10 |
use GuzzleHttp\RetryMiddleware; |
| 11 |
use PHPUnit\Framework\TestCase; |
| 12 |
|
| 13 |
class RetryMiddlewareTest extends TestCase |
| 14 |
{ |
| 15 |
public function testRetriesWhenDeciderReturnsTrue() |
| 16 |
{ |
| 17 |
$delayCalls = 0; |
| 18 |
$calls = []; |
| 19 |
$decider = function ($retries, $request, $response, $error) use (&$calls) { |
| 20 |
$calls[] = func_get_args(); |
| 21 |
return count($calls) < 3; |
| 22 |
}; |
| 23 |
$delay = function ($retries, $response) use (&$delayCalls) { |
| 24 |
$delayCalls++; |
| 25 |
self::assertSame($retries, $delayCalls); |
| 26 |
self::assertInstanceOf(Response::class, $response); |
| 27 |
return 1; |
| 28 |
}; |
| 29 |
$m = Middleware::retry($decider, $delay); |
| 30 |
$h = new MockHandler([new Response(200), new Response(201), new Response(202)]); |
| 31 |
$f = $m($h); |
| 32 |
$c = new Client(['handler' => $f]); |
| 33 |
$p = $c->sendAsync(new Request('GET', 'http://test.com'), []); |
| 34 |
$p->wait(); |
| 35 |
self::assertCount(3, $calls); |
| 36 |
self::assertSame(2, $delayCalls); |
| 37 |
self::assertSame(202, $p->wait()->getStatusCode()); |
| 38 |
} |
| 39 |
|
| 40 |
public function testDoesNotRetryWhenDeciderReturnsFalse() |
| 41 |
{ |
| 42 |
$decider = function () { |
| 43 |
return false; |
| 44 |
}; |
| 45 |
$m = Middleware::retry($decider); |
| 46 |
$h = new MockHandler([new Response(200)]); |
| 47 |
$c = new Client(['handler' => $m($h)]); |
| 48 |
$p = $c->sendAsync(new Request('GET', 'http://test.com'), []); |
| 49 |
self::assertSame(200, $p->wait()->getStatusCode()); |
| 50 |
} |
| 51 |
|
| 52 |
public function testCanRetryExceptions() |
| 53 |
{ |
| 54 |
$calls = []; |
| 55 |
$decider = function ($retries, $request, $response, $error) use (&$calls) { |
| 56 |
$calls[] = func_get_args(); |
| 57 |
return $error instanceof \Exception; |
| 58 |
}; |
| 59 |
$m = Middleware::retry($decider); |
| 60 |
$h = new MockHandler([new \Exception(), new Response(201)]); |
| 61 |
$c = new Client(['handler' => $m($h)]); |
| 62 |
$p = $c->sendAsync(new Request('GET', 'http://test.com'), []); |
| 63 |
self::assertSame(201, $p->wait()->getStatusCode()); |
| 64 |
self::assertCount(2, $calls); |
| 65 |
self::assertSame(0, $calls[0][0]); |
| 66 |
self::assertNull($calls[0][2]); |
| 67 |
self::assertInstanceOf('Exception', $calls[0][3]); |
| 68 |
self::assertSame(1, $calls[1][0]); |
| 69 |
self::assertInstanceOf(Response::class, $calls[1][2]); |
| 70 |
self::assertNull($calls[1][3]); |
| 71 |
} |
| 72 |
|
| 73 |
public function testBackoffCalculateDelay() |
| 74 |
{ |
| 75 |
self::assertSame(0, RetryMiddleware::exponentialDelay(0)); |
| 76 |
self::assertSame(1, RetryMiddleware::exponentialDelay(1)); |
| 77 |
self::assertSame(2, RetryMiddleware::exponentialDelay(2)); |
| 78 |
self::assertSame(4, RetryMiddleware::exponentialDelay(3)); |
| 79 |
self::assertSame(8, RetryMiddleware::exponentialDelay(4)); |
| 80 |
} |
| 81 |
} |
| 82 |
|