| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- <?php
- namespace React\Tests\Dns\Query;
- use React\Dns\Model\Message;
- use React\Dns\Query\Query;
- use React\Dns\Query\SelectiveTransportExecutor;
- use React\Promise\Deferred;
- use React\Promise\Promise;
- use React\Tests\Dns\TestCase;
- class SelectiveTransportExecutorTest extends TestCase
- {
- private $datagram;
- private $stream;
- private $executor;
- /**
- * @before
- */
- public function setUpMocks()
- {
- $this->datagram = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock();
- $this->stream = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock();
- $this->executor = new SelectiveTransportExecutor($this->datagram, $this->stream);
- }
- public function testQueryResolvesWhenDatagramTransportResolvesWithoutUsingStreamTransport()
- {
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $response = new Message();
- $this->datagram
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(\React\Promise\resolve($response));
- $this->stream
- ->expects($this->never())
- ->method('query');
- $promise = $this->executor->query($query);
- $promise->then($this->expectCallableOnceWith($response));
- }
- public function testQueryResolvesWhenStreamTransportResolvesAfterDatagramTransportRejectsWithSizeError()
- {
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $response = new Message();
- $this->datagram
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(\React\Promise\reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90)));
- $this->stream
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(\React\Promise\resolve($response));
- $promise = $this->executor->query($query);
- $promise->then($this->expectCallableOnceWith($response));
- }
- public function testQueryRejectsWhenDatagramTransportRejectsWithRuntimeExceptionWithoutUsingStreamTransport()
- {
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $this->datagram
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(\React\Promise\reject(new \RuntimeException()));
- $this->stream
- ->expects($this->never())
- ->method('query');
- $promise = $this->executor->query($query);
- $promise->then(null, $this->expectCallableOnce());
- }
- public function testQueryRejectsWhenStreamTransportRejectsAfterDatagramTransportRejectsWithSizeError()
- {
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $this->datagram
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(\React\Promise\reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90)));
- $this->stream
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(\React\Promise\reject(new \RuntimeException()));
- $promise = $this->executor->query($query);
- $promise->then(null, $this->expectCallableOnce());
- }
- public function testCancelPromiseWillCancelPromiseFromDatagramExecutor()
- {
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $this->datagram
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(new Promise(function () {}, $this->expectCallableOnce()));
- $promise = $this->executor->query($query);
- $promise->cancel();
- }
- public function testCancelPromiseWillCancelPromiseFromStreamExecutorWhenDatagramExecutorRejectedWithTruncatedResponse()
- {
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $deferred = new Deferred();
- $this->datagram
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn($deferred->promise());
- $this->stream
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(new Promise(function () {}, $this->expectCallableOnce()));
- $promise = $this->executor->query($query);
- $deferred->reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90));
- $promise->cancel();
- }
- public function testCancelPromiseShouldNotCreateAnyGarbageReferences()
- {
- if (class_exists('React\Promise\When')) {
- $this->markTestSkipped('Not supported on legacy Promise v1 API');
- }
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $this->datagram
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(new Promise(function () {}, function () {
- throw new \RuntimeException('Cancelled');
- }));
- while (gc_collect_cycles()) {
- // collect all garbage cycles
- }
- $promise = $this->executor->query($query);
- $promise->cancel();
- unset($promise);
- $this->assertEquals(0, gc_collect_cycles());
- }
- public function testCancelPromiseAfterTruncatedResponseShouldNotCreateAnyGarbageReferences()
- {
- if (class_exists('React\Promise\When')) {
- $this->markTestSkipped('Not supported on legacy Promise v1 API');
- }
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $deferred = new Deferred();
- $this->datagram
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn($deferred->promise());
- $this->stream
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(new Promise(function () {}, function () {
- throw new \RuntimeException('Cancelled');
- }));
- while (gc_collect_cycles()) {
- // collect all garbage cycles
- }
- $promise = $this->executor->query($query);
- $deferred->reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90));
- $promise->cancel();
- unset($promise);
- $this->assertEquals(0, gc_collect_cycles());
- }
- public function testRejectedPromiseAfterTruncatedResponseShouldNotCreateAnyGarbageReferences()
- {
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $this->datagram
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(\React\Promise\reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90)));
- $this->stream
- ->expects($this->once())
- ->method('query')
- ->with($query)
- ->willReturn(\React\Promise\reject(new \RuntimeException()));
- while (gc_collect_cycles()) {
- // collect all garbage cycles
- }
- $promise = $this->executor->query($query);
- $promise->then(null, $this->expectCallableOnce()); // avoid reporting unhandled rejection
- unset($promise);
- $this->assertEquals(0, gc_collect_cycles());
- }
- }
|