RetryMiddlewareTest.php 2.9 KB

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