RetryMiddlewareTest.php 2.9 KB

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