| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- <?php
- namespace React\Tests\Dns\Query;
- use React\Dns\Model\Message;
- use React\Dns\Query\CancellationException;
- use React\Dns\Query\Query;
- use React\Dns\Query\TimeoutException;
- use React\Dns\Query\TimeoutExecutor;
- use React\Promise;
- use React\Promise\Deferred;
- use React\Tests\Dns\TestCase;
- class TimeoutExecutorTest extends TestCase
- {
- private $wrapped;
- private $executor;
- private $loop;
- /**
- * @before
- */
- public function setUpExecutor()
- {
- $this->wrapped = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock();
- $this->loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $this->executor = new TimeoutExecutor($this->wrapped, 5.0, $this->loop);
- }
- public function testCtorWithoutLoopShouldAssignDefaultLoop()
- {
- $executor = new TimeoutExecutor($this->executor, 5.0);
- $ref = new \ReflectionProperty($executor, 'loop');
- $ref->setAccessible(true);
- $loop = $ref->getValue($executor);
- $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop);
- }
- public function testCancellingPromiseWillCancelWrapped()
- {
- $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock();
- $this->loop->expects($this->once())->method('addTimer')->with(5.0, $this->anything())->willReturn($timer);
- $this->loop->expects($this->once())->method('cancelTimer')->with($timer);
- $cancelled = 0;
- $this->wrapped
- ->expects($this->once())
- ->method('query')
- ->will($this->returnCallback(function ($query) use (&$cancelled) {
- $deferred = new Deferred(function ($resolve, $reject) use (&$cancelled) {
- ++$cancelled;
- $reject(new CancellationException('Cancelled'));
- });
- return $deferred->promise();
- }));
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $promise = $this->executor->query($query);
- $this->assertEquals(0, $cancelled);
- $promise->cancel();
- $this->assertEquals(1, $cancelled);
- $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
- }
- public function testResolvesPromiseWithoutStartingTimerWhenWrappedReturnsResolvedPromise()
- {
- $this->loop->expects($this->never())->method('addTimer');
- $this->loop->expects($this->never())->method('cancelTimer');
- $this->wrapped
- ->expects($this->once())
- ->method('query')
- ->willReturn(Promise\resolve('0.0.0.0'));
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $promise = $this->executor->query($query);
- $promise->then($this->expectCallableOnce(), $this->expectCallableNever());
- }
- public function testResolvesPromiseAfterCancellingTimerWhenWrappedReturnsPendingPromiseThatResolves()
- {
- $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock();
- $this->loop->expects($this->once())->method('addTimer')->with(5.0, $this->anything())->willReturn($timer);
- $this->loop->expects($this->once())->method('cancelTimer')->with($timer);
- $deferred = new Deferred();
- $this->wrapped
- ->expects($this->once())
- ->method('query')
- ->willReturn($deferred->promise());
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $promise = $this->executor->query($query);
- $deferred->resolve('0.0.0.0');
- $promise->then($this->expectCallableOnce(), $this->expectCallableNever());
- }
- public function testRejectsPromiseWithoutStartingTimerWhenWrappedReturnsRejectedPromise()
- {
- $this->loop->expects($this->never())->method('addTimer');
- $this->loop->expects($this->never())->method('cancelTimer');
- $this->wrapped
- ->expects($this->once())
- ->method('query')
- ->willReturn(Promise\reject(new \RuntimeException()));
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $promise = $this->executor->query($query);
- $promise->then($this->expectCallableNever(), $this->expectCallableOnceWith(new \RuntimeException()));
- }
- public function testRejectsPromiseAfterCancellingTimerWhenWrappedReturnsPendingPromiseThatRejects()
- {
- $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock();
- $this->loop->expects($this->once())->method('addTimer')->with(5.0, $this->anything())->willReturn($timer);
- $this->loop->expects($this->once())->method('cancelTimer')->with($timer);
- $deferred = new Deferred();
- $this->wrapped
- ->expects($this->once())
- ->method('query')
- ->willReturn($deferred->promise());
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $promise = $this->executor->query($query);
- $deferred->reject(new \RuntimeException());
- $promise->then($this->expectCallableNever(), $this->expectCallableOnceWith(new \RuntimeException()));
- }
- public function testRejectsPromiseAndCancelsPendingQueryWhenTimeoutTriggers()
- {
- $timerCallback = null;
- $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock();
- $this->loop->expects($this->once())->method('addTimer')->with(5.0, $this->callback(function ($callback) use (&$timerCallback) {
- $timerCallback = $callback;
- return true;
- }))->willReturn($timer);
- $this->loop->expects($this->once())->method('cancelTimer')->with($timer);
- $cancelled = 0;
- $this->wrapped
- ->expects($this->once())
- ->method('query')
- ->will($this->returnCallback(function ($query) use (&$cancelled) {
- $deferred = new Deferred(function ($resolve, $reject) use (&$cancelled) {
- ++$cancelled;
- $reject(new CancellationException('Cancelled'));
- });
- return $deferred->promise();
- }));
- $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN);
- $promise = $this->executor->query($query);
- $this->assertEquals(0, $cancelled);
- $this->assertNotNull($timerCallback);
- $timerCallback();
- $this->assertEquals(1, $cancelled);
- $exception = null;
- $promise->then(null, function ($reason) use (&$exception) {
- $exception = $reason;
- });
- assert($exception instanceof TimeoutException);
- $this->assertInstanceOf('React\Dns\Query\TimeoutException', $exception);
- $this->assertEquals('DNS query for igor.io (A) timed out' , $exception->getMessage());
- }
- }
|