PoolTest.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <?php
  2. namespace GuzzleHttp\Tests;
  3. use GuzzleHttp\Client;
  4. use GuzzleHttp\Exception\ClientException;
  5. use GuzzleHttp\Handler\MockHandler;
  6. use GuzzleHttp\HandlerStack;
  7. use GuzzleHttp\Pool;
  8. use GuzzleHttp\Promise\Promise;
  9. use GuzzleHttp\Psr7\Request;
  10. use GuzzleHttp\Psr7\Response;
  11. use PHPUnit\Framework\TestCase;
  12. use Psr\Http\Message\RequestInterface;
  13. class PoolTest extends TestCase
  14. {
  15. public function testValidatesIterable()
  16. {
  17. $p = new Pool(new Client(), 'foo');
  18. $this->expectException(\InvalidArgumentException::class);
  19. $p->promise()->wait();
  20. }
  21. public function testValidatesEachElement()
  22. {
  23. $c = new Client();
  24. $requests = ['foo'];
  25. $p = new Pool($c, new \ArrayIterator($requests));
  26. $this->expectException(\InvalidArgumentException::class);
  27. $p->promise()->wait();
  28. }
  29. /**
  30. * @doesNotPerformAssertions
  31. */
  32. public function testSendsAndRealizesFuture()
  33. {
  34. $c = $this->getClient();
  35. $p = new Pool($c, [new Request('GET', 'http://example.com')]);
  36. $p->promise()->wait();
  37. }
  38. /**
  39. * @doesNotPerformAssertions
  40. */
  41. public function testExecutesPendingWhenWaiting()
  42. {
  43. $r1 = new Promise(static function () use (&$r1) {
  44. $r1->resolve(new Response());
  45. });
  46. $r2 = new Promise(static function () use (&$r2) {
  47. $r2->resolve(new Response());
  48. });
  49. $r3 = new Promise(static function () use (&$r3) {
  50. $r3->resolve(new Response());
  51. });
  52. $handler = new MockHandler([$r1, $r2, $r3]);
  53. $c = new Client(['handler' => $handler]);
  54. $p = new Pool($c, [
  55. new Request('GET', 'http://example.com'),
  56. new Request('GET', 'http://example.com'),
  57. new Request('GET', 'http://example.com'),
  58. ], ['pool_size' => 2]);
  59. $p->promise()->wait();
  60. }
  61. public function testUsesRequestOptions()
  62. {
  63. $h = [];
  64. $handler = new MockHandler([
  65. static function (RequestInterface $request) use (&$h) {
  66. $h[] = $request;
  67. return new Response();
  68. },
  69. ]);
  70. $c = new Client(['handler' => $handler]);
  71. $opts = ['options' => ['headers' => ['x-foo' => 'bar']]];
  72. $p = new Pool($c, [new Request('GET', 'http://example.com')], $opts);
  73. $p->promise()->wait();
  74. self::assertCount(1, $h);
  75. self::assertTrue($h[0]->hasHeader('x-foo'));
  76. }
  77. public function testCanProvideCallablesThatReturnResponses()
  78. {
  79. $h = [];
  80. $handler = new MockHandler([
  81. static function (RequestInterface $request) use (&$h) {
  82. $h[] = $request;
  83. return new Response();
  84. },
  85. ]);
  86. $c = new Client(['handler' => $handler]);
  87. $optHistory = [];
  88. $fn = static function (array $opts) use (&$optHistory, $c) {
  89. $optHistory = $opts;
  90. return $c->request('GET', 'http://example.com', $opts);
  91. };
  92. $opts = ['options' => ['headers' => ['x-foo' => 'bar']]];
  93. $p = new Pool($c, [$fn], $opts);
  94. $p->promise()->wait();
  95. self::assertCount(1, $h);
  96. self::assertTrue($h[0]->hasHeader('x-foo'));
  97. }
  98. public function testBatchesResults()
  99. {
  100. $requests = [
  101. new Request('GET', 'http://foo.com/200'),
  102. new Request('GET', 'http://foo.com/201'),
  103. new Request('GET', 'http://foo.com/202'),
  104. new Request('GET', 'http://foo.com/404'),
  105. ];
  106. $fn = static function (RequestInterface $request) {
  107. return new Response(\substr($request->getUri()->getPath(), 1));
  108. };
  109. $mock = new MockHandler([$fn, $fn, $fn, $fn]);
  110. $handler = HandlerStack::create($mock);
  111. $client = new Client(['handler' => $handler]);
  112. $results = Pool::batch($client, $requests);
  113. self::assertCount(4, $results);
  114. self::assertSame([0, 1, 2, 3], \array_keys($results));
  115. self::assertSame(200, $results[0]->getStatusCode());
  116. self::assertSame(201, $results[1]->getStatusCode());
  117. self::assertSame(202, $results[2]->getStatusCode());
  118. self::assertInstanceOf(ClientException::class, $results[3]);
  119. }
  120. public function testBatchesResultsWithCallbacks()
  121. {
  122. $requests = [
  123. new Request('GET', 'http://foo.com/200'),
  124. new Request('GET', 'http://foo.com/201'),
  125. ];
  126. $mock = new MockHandler([
  127. static function (RequestInterface $request) {
  128. return new Response(\substr($request->getUri()->getPath(), 1));
  129. },
  130. ]);
  131. $client = new Client(['handler' => $mock]);
  132. $results = Pool::batch($client, $requests, [
  133. 'fulfilled' => static function ($value) use (&$called) {
  134. $called = true;
  135. },
  136. ]);
  137. self::assertCount(2, $results);
  138. self::assertTrue($called);
  139. }
  140. public function testUsesYieldedKeyInFulfilledCallback()
  141. {
  142. $r1 = new Promise(static function () use (&$r1) {
  143. $r1->resolve(new Response());
  144. });
  145. $r2 = new Promise(static function () use (&$r2) {
  146. $r2->resolve(new Response());
  147. });
  148. $r3 = new Promise(static function () use (&$r3) {
  149. $r3->resolve(new Response());
  150. });
  151. $handler = new MockHandler([$r1, $r2, $r3]);
  152. $c = new Client(['handler' => $handler]);
  153. $keys = [];
  154. $requests = [
  155. 'request_1' => new Request('GET', 'http://example.com'),
  156. 'request_2' => new Request('GET', 'http://example.com'),
  157. 'request_3' => new Request('GET', 'http://example.com'),
  158. ];
  159. $p = new Pool($c, $requests, [
  160. 'pool_size' => 2,
  161. 'fulfilled' => static function ($res, $index) use (&$keys) {
  162. $keys[] = $index;
  163. },
  164. ]);
  165. $p->promise()->wait();
  166. self::assertCount(3, $keys);
  167. self::assertSame($keys, \array_keys($requests));
  168. }
  169. private function getClient($total = 1)
  170. {
  171. $queue = [];
  172. for ($i = 0; $i < $total; ++$i) {
  173. $queue[] = new Response();
  174. }
  175. $handler = new MockHandler($queue);
  176. return new Client(['handler' => $handler]);
  177. }
  178. }