diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65fe5d47..7f3a7a1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,11 +19,6 @@ jobs: - 7.3 - 7.2 - 7.1 - - 7.0 - - 5.6 - - 5.5 - - 5.4 - - 5.3 steps: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 @@ -50,19 +45,3 @@ jobs: ini-file: development - run: composer install - run: vendor/bin/phpunit --coverage-text - - PHPUnit-hhvm: - name: PHPUnit (HHVM) - runs-on: ubuntu-22.04 - continue-on-error: true - steps: - - uses: actions/checkout@v4 - - run: cp "$(which composer)" composer.phar && ./composer.phar self-update --2.2 # downgrade Composer for HHVM - - name: Run hhvm composer.phar install - uses: docker://hhvm/hhvm:3.30-lts-latest - with: - args: hhvm composer.phar install - - name: Run hhvm vendor/bin/phpunit - uses: docker://hhvm/hhvm:3.30-lts-latest - with: - args: hhvm vendor/bin/phpunit diff --git a/README.md b/README.md index 2df8d224..73ea2fb6 100644 --- a/README.md +++ b/README.md @@ -424,8 +424,7 @@ composer require react/dns:^3@dev See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. This project aims to run on any platform and thus does not require any PHP -extensions and supports running on legacy PHP 5.3 through current PHP 8+ and -HHVM. +extensions and supports running on PHP 7.1 through current PHP 8+. It's *highly recommended to use the latest supported PHP version* for this project. ## Tests diff --git a/composer.json b/composer.json index de22b26f..8fe3697d 100644 --- a/composer.json +++ b/composer.json @@ -26,13 +26,13 @@ } ], "require": { - "php": ">=5.3.0", + "php": ">=7.1", "react/cache": "^1.0 || ^0.6 || ^0.5", "react/event-loop": "^1.2", "react/promise": "^3.0 || ^2.7 || ^1.2.1" }, "require-dev": { - "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "phpunit/phpunit": "^9.6 || ^7.5", "react/async": "^4 || ^3 || ^2", "react/promise-timer": "^1.9" }, diff --git a/examples/01-one.php b/examples/01-one.php index df8dda2a..3396087c 100644 --- a/examples/01-one.php +++ b/examples/01-one.php @@ -13,7 +13,7 @@ $factory = new Factory(); $resolver = $factory->create($config); -$name = isset($argv[1]) ? $argv[1] : 'www.google.com'; +$name = $argv[1] ?? 'www.google.com'; $resolver->resolve($name)->then(function ($ip) use ($name) { echo 'IP for ' . $name . ': ' . $ip . PHP_EOL; diff --git a/examples/02-concurrent.php b/examples/02-concurrent.php index 1810f0f7..780b52ab 100644 --- a/examples/02-concurrent.php +++ b/examples/02-concurrent.php @@ -15,7 +15,7 @@ $names = array_slice($argv, 1); if (!$names) { - $names = array('google.com', 'www.google.com', 'gmail.com'); + $names = ['google.com', 'www.google.com', 'gmail.com']; } foreach ($names as $name) { diff --git a/examples/03-cached.php b/examples/03-cached.php index fc800f54..e90eee27 100644 --- a/examples/03-cached.php +++ b/examples/03-cached.php @@ -14,7 +14,7 @@ $factory = new Factory(); $resolver = $factory->createCached($config); -$name = isset($argv[1]) ? $argv[1] : 'www.google.com'; +$name = $argv[1] ?? 'www.google.com'; $resolver->resolve($name)->then(function ($ip) use ($name) { echo 'IP for ' . $name . ': ' . $ip . PHP_EOL; diff --git a/examples/11-all-ips.php b/examples/11-all-ips.php index 85a008c1..cf8019a6 100644 --- a/examples/11-all-ips.php +++ b/examples/11-all-ips.php @@ -14,7 +14,7 @@ $factory = new Factory(); $resolver = $factory->create($config); -$name = isset($argv[1]) ? $argv[1] : 'www.google.com'; +$name = $argv[1] ?? 'www.google.com'; $resolver->resolveAll($name, Message::TYPE_A)->then(function (array $ips) use ($name) { echo 'IPv4 addresses for ' . $name . ': ' . implode(', ', $ips) . PHP_EOL; diff --git a/examples/12-all-types.php b/examples/12-all-types.php index fbb75ca2..acccbce9 100644 --- a/examples/12-all-types.php +++ b/examples/12-all-types.php @@ -16,8 +16,8 @@ $factory = new Factory(); $resolver = $factory->create($config); -$name = isset($argv[1]) ? $argv[1] : 'google.com'; -$type = constant('React\Dns\Model\Message::TYPE_' . (isset($argv[2]) ? $argv[2] : 'TXT')); +$name = $argv[1] ?? 'google.com'; +$type = constant('React\Dns\Model\Message::TYPE_' . ($argv[2] ?? 'TXT')); $resolver->resolveAll($name, $type)->then(function (array $values) { var_dump($values); diff --git a/examples/13-reverse-dns.php b/examples/13-reverse-dns.php index 859e3011..dfd89337 100644 --- a/examples/13-reverse-dns.php +++ b/examples/13-reverse-dns.php @@ -14,7 +14,7 @@ $factory = new Factory(); $resolver = $factory->create($config); -$ip = isset($argv[1]) ? $argv[1] : '8.8.8.8'; +$ip = $argv[1] ?? '8.8.8.8'; if (@inet_pton($ip) === false) { exit('Error: Given argument is not a valid IP' . PHP_EOL); diff --git a/examples/91-query-a-and-aaaa.php b/examples/91-query-a-and-aaaa.php index ccc322de..44fdee8e 100644 --- a/examples/91-query-a-and-aaaa.php +++ b/examples/91-query-a-and-aaaa.php @@ -9,7 +9,7 @@ $executor = new UdpTransportExecutor('8.8.8.8:53'); -$name = isset($argv[1]) ? $argv[1] : 'www.google.com'; +$name = $argv[1] ?? 'www.google.com'; $ipv4Query = new Query($name, Message::TYPE_A, Message::CLASS_IN); $ipv6Query = new Query($name, Message::TYPE_AAAA, Message::CLASS_IN); diff --git a/examples/92-query-any.php b/examples/92-query-any.php index ed61a758..036a7ded 100644 --- a/examples/92-query-any.php +++ b/examples/92-query-any.php @@ -13,7 +13,7 @@ $executor = new TcpTransportExecutor('8.8.8.8:53'); -$name = isset($argv[1]) ? $argv[1] : 'google.com'; +$name = $argv[1] ?? 'google.com'; $any = new Query($name, Message::TYPE_ANY, Message::CLASS_IN); diff --git a/phpunit.xml.legacy b/phpunit.xml.legacy index 89161168..00868603 100644 --- a/phpunit.xml.legacy +++ b/phpunit.xml.legacy @@ -2,7 +2,7 @@ diff --git a/src/Config/Config.php b/src/Config/Config.php index 9677ee57..0b19e9af 100644 --- a/src/Config/Config.php +++ b/src/Config/Config.php @@ -82,7 +82,7 @@ public static function loadResolvConfBlocking($path = null) throw new RuntimeException('Unable to load resolv.conf file "' . $path . '"'); } - $matches = array(); + $matches = []; preg_match_all('/^nameserver\s+(\S+)\s*$/m', $contents, $matches); $config = new self(); @@ -133,5 +133,5 @@ public static function loadWmicBlocking($command = null) return $config; } - public $nameservers = array(); + public $nameservers = []; } diff --git a/src/Config/HostsFile.php b/src/Config/HostsFile.php index 1060231a..1333102d 100644 --- a/src/Config/HostsFile.php +++ b/src/Config/HostsFile.php @@ -98,7 +98,7 @@ public function getIpsForHost($name) { $name = strtolower($name); - $ips = array(); + $ips = []; foreach (preg_split('/\r?\n/', $this->contents) as $line) { $parts = preg_split('/\s+/', $line); $ip = array_shift($parts); @@ -128,10 +128,10 @@ public function getHostsForIp($ip) // check binary representation of IP to avoid string case and short notation $ip = @inet_pton($ip); if ($ip === false) { - return array(); + return []; } - $names = array(); + $names = []; foreach (preg_split('/\r?\n/', $this->contents) as $line) { $parts = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY); $addr = (string) array_shift($parts); diff --git a/src/Model/Message.php b/src/Model/Message.php index bac2b10d..56cc65b8 100644 --- a/src/Model/Message.php +++ b/src/Model/Message.php @@ -126,23 +126,13 @@ public static function createResponseWithAnswersForQuery(Query $query, array $an * DNS response messages can not guess the message ID to avoid possible * cache poisoning attacks. * - * The `random_int()` function is only available on PHP 7+ or when - * https://github.com/paragonie/random_compat is installed. As such, using - * the latest supported PHP version is highly recommended. This currently - * falls back to a less secure random number generator on older PHP versions - * in the hope that this system is properly protected against outside - * attackers, for example by using one of the common local DNS proxy stubs. - * * @return int * @see self::getId() * @codeCoverageIgnore */ private static function generateId() { - if (function_exists('random_int')) { - return random_int(0, 0xffff); - } - return mt_rand(0, 0xffff); + return random_int(0, 0xffff); } /** @@ -200,31 +190,31 @@ private static function generateId() * An array of Query objects * * ```php - * $questions = array( + * $questions = [ * new Query( * 'reactphp.org', * Message::TYPE_A, * Message::CLASS_IN * ) - * ); + * ]; * ``` * * @var Query[] */ - public $questions = array(); + public $questions = []; /** * @var Record[] */ - public $answers = array(); + public $answers = []; /** * @var Record[] */ - public $authority = array(); + public $authority = []; /** * @var Record[] */ - public $additional = array(); + public $additional = []; } diff --git a/src/Protocol/Parser.php b/src/Protocol/Parser.php index 011a6e7f..64b45666 100644 --- a/src/Protocol/Parser.php +++ b/src/Protocol/Parser.php @@ -108,20 +108,20 @@ private function parseQuestion($data, $consumed) list($labels, $consumed) = $this->readLabels($data, $consumed); if ($labels === null || !isset($data[$consumed + 4 - 1])) { - return array(null, null); + return [null, null]; } list($type, $class) = array_values(unpack('n*', substr($data, $consumed, 4))); $consumed += 4; - return array( + return [ new Query( implode('.', $labels), $type, $class ), $consumed - ); + ]; } /** @@ -134,7 +134,7 @@ private function parseRecord($data, $consumed) list($name, $consumed) = $this->readDomain($data, $consumed); if ($name === null || !isset($data[$consumed + 10 - 1])) { - return array(null, null); + return [null, null]; } list($type, $class) = array_values(unpack('n*', substr($data, $consumed, 4))); @@ -152,7 +152,7 @@ private function parseRecord($data, $consumed) $consumed += 2; if (!isset($data[$consumed + $rdLength - 1])) { - return array(null, null); + return [null, null]; } $rdata = null; @@ -171,7 +171,7 @@ private function parseRecord($data, $consumed) } elseif (Message::TYPE_CNAME === $type || Message::TYPE_PTR === $type || Message::TYPE_NS === $type) { list($rdata, $consumed) = $this->readDomain($data, $consumed); } elseif (Message::TYPE_TXT === $type || Message::TYPE_SPF === $type) { - $rdata = array(); + $rdata = []; while ($consumed < $expected) { $len = ord($data[$consumed]); $rdata[] = (string)substr($data, $consumed + 1, $len); @@ -182,22 +182,22 @@ private function parseRecord($data, $consumed) list($priority) = array_values(unpack('n', substr($data, $consumed, 2))); list($target, $consumed) = $this->readDomain($data, $consumed + 2); - $rdata = array( + $rdata = [ 'priority' => $priority, 'target' => $target - ); + ]; } } elseif (Message::TYPE_SRV === $type) { if ($rdLength > 6) { list($priority, $weight, $port) = array_values(unpack('n*', substr($data, $consumed, 6))); list($target, $consumed) = $this->readDomain($data, $consumed + 6); - $rdata = array( + $rdata = [ 'priority' => $priority, 'weight' => $weight, 'port' => $port, 'target' => $target - ); + ]; } } elseif (Message::TYPE_SSHFP === $type) { if ($rdLength > 2) { @@ -205,11 +205,11 @@ private function parseRecord($data, $consumed) $fingerprint = \bin2hex(\substr($data, $consumed + 2, $rdLength - 2)); $consumed += $rdLength; - $rdata = array( + $rdata = [ 'algorithm' => $algorithm, 'type' => $hash, 'fingerprint' => $fingerprint - ); + ]; } } elseif (Message::TYPE_SOA === $type) { list($mname, $consumed) = $this->readDomain($data, $consumed); @@ -219,7 +219,7 @@ private function parseRecord($data, $consumed) list($serial, $refresh, $retry, $expire, $minimum) = array_values(unpack('N*', substr($data, $consumed, 20))); $consumed += 20; - $rdata = array( + $rdata = [ 'mname' => $mname, 'rname' => $rname, 'serial' => $serial, @@ -227,10 +227,10 @@ private function parseRecord($data, $consumed) 'retry' => $retry, 'expire' => $expire, 'minimum' => $minimum - ); + ]; } } elseif (Message::TYPE_OPT === $type) { - $rdata = array(); + $rdata = []; while (isset($data[$consumed + 4 - 1])) { list($code, $length) = array_values(unpack('n*', substr($data, $consumed, 4))); $value = (string) substr($data, $consumed + 4, $length); @@ -254,11 +254,11 @@ private function parseRecord($data, $consumed) $value = substr($data, $consumed + 2 + $tagLength, $rdLength - 2 - $tagLength); $consumed += $rdLength; - $rdata = array( + $rdata = [ 'flag' => $flag, 'tag' => $tag, 'value' => $value - ); + ]; } } } else { @@ -269,13 +269,13 @@ private function parseRecord($data, $consumed) // ensure parsing record data consumes expact number of bytes indicated in record length if ($consumed !== $expected || $rdata === null) { - return array(null, null); + return [null, null]; } - return array( + return [ new Record($name, $type, $class, $ttl, $rdata), $consumed - ); + ]; } private function readDomain($data, $consumed) @@ -283,11 +283,11 @@ private function readDomain($data, $consumed) list ($labels, $consumed) = $this->readLabels($data, $consumed); if ($labels === null) { - return array(null, null); + return [null, null]; } // use escaped notation for each label part, then join using dots - return array( + return [ \implode( '.', \array_map( @@ -298,7 +298,7 @@ function ($label) { ) ), $consumed - ); + ]; } /** @@ -309,11 +309,11 @@ function ($label) { */ private function readLabels($data, $consumed, $compressionDepth = 127) { - $labels = array(); + $labels = []; while (true) { if (!isset($data[$consumed])) { - return array(null, null); + return [null, null]; } $length = \ord($data[$consumed]); @@ -328,14 +328,14 @@ private function readLabels($data, $consumed, $compressionDepth = 127) if (($length & 0xc0) === 0xc0 && isset($data[$consumed + 1]) && $compressionDepth) { $offset = ($length & ~0xc0) << 8 | \ord($data[$consumed + 1]); if ($offset >= $consumed) { - return array(null, null); + return [null, null]; } $consumed += 2; list($newLabels) = $this->readLabels($data, $offset, $compressionDepth - 1); if ($newLabels === null) { - return array(null, null); + return [null, null]; } $labels = array_merge($labels, $newLabels); @@ -344,13 +344,13 @@ private function readLabels($data, $consumed, $compressionDepth = 127) // length MUST be 0-63 (6 bits only) and data has to be large enough if ($length & 0xc0 || !isset($data[$consumed + $length - 1])) { - return array(null, null); + return [null, null]; } $labels[] = substr($data, $consumed + 1, $length); $consumed += $length + 1; } - return array($labels, $consumed); + return [$labels, $consumed]; } } diff --git a/src/Query/CachingExecutor.php b/src/Query/CachingExecutor.php index e530b24c..03d56c95 100644 --- a/src/Query/CachingExecutor.php +++ b/src/Query/CachingExecutor.php @@ -27,25 +27,22 @@ public function __construct(ExecutorInterface $executor, CacheInterface $cache) public function query(Query $query) { $id = $query->name . ':' . $query->type . ':' . $query->class; - $cache = $this->cache; - $that = $this; - $executor = $this->executor; - $pending = $cache->get($id); - return new Promise(function ($resolve, $reject) use ($query, $id, $cache, $executor, &$pending, $that) { + $pending = $this->cache->get($id); + return new Promise(function ($resolve, $reject) use ($query, $id, &$pending) { $pending->then( - function ($message) use ($query, $id, $cache, $executor, &$pending, $that) { + function ($message) use ($query, $id, &$pending) { // return cached response message on cache hit if ($message !== null) { return $message; } // perform DNS lookup if not already cached - return $pending = $executor->query($query)->then( - function (Message $message) use ($cache, $id, $that) { + return $pending = $this->executor->query($query)->then( + function (Message $message) use ($id) { // DNS response message received => store in cache when not truncated and return if (!$message->tc) { - $cache->set($id, $message, $that->ttl($message)); + $this->cache->set($id, $message, $this->ttl($message)); } return $message; diff --git a/src/Query/CoopExecutor.php b/src/Query/CoopExecutor.php index e3f913ba..3ce41691 100644 --- a/src/Query/CoopExecutor.php +++ b/src/Query/CoopExecutor.php @@ -37,8 +37,8 @@ final class CoopExecutor implements ExecutorInterface { private $executor; - private $pending = array(); - private $counts = array(); + private $pending = []; + private $counts = []; public function __construct(ExecutorInterface $base) { @@ -58,25 +58,21 @@ public function query(Query $query) $this->pending[$key] = $promise; $this->counts[$key] = 1; - $pending =& $this->pending; - $counts =& $this->counts; - $promise->then(function () use ($key, &$pending, &$counts) { - unset($pending[$key], $counts[$key]); - }, function () use ($key, &$pending, &$counts) { - unset($pending[$key], $counts[$key]); + $promise->then(function () use ($key) { + unset($this->pending[$key], $this->counts[$key]); + }, function () use ($key) { + unset($this->pending[$key], $this->counts[$key]); }); } // Return a child promise awaiting the pending query. // Cancelling this child promise should only cancel the pending query // when no other child promise is awaiting the same query. - $pending =& $this->pending; - $counts =& $this->counts; return new Promise(function ($resolve, $reject) use ($promise) { $promise->then($resolve, $reject); - }, function () use (&$promise, $key, $query, &$pending, &$counts) { - if (--$counts[$key] < 1) { - unset($pending[$key], $counts[$key]); + }, function () use (&$promise, $key, $query) { + if (--$this->counts[$key] < 1) { + unset($this->pending[$key], $this->counts[$key]); $promise->cancel(); $promise = null; } diff --git a/src/Query/FallbackExecutor.php b/src/Query/FallbackExecutor.php index 83bd360b..6999e1b8 100644 --- a/src/Query/FallbackExecutor.php +++ b/src/Query/FallbackExecutor.php @@ -18,11 +18,10 @@ public function __construct(ExecutorInterface $executor, ExecutorInterface $fall public function query(Query $query) { $cancelled = false; - $fallback = $this->fallback; $promise = $this->executor->query($query); - return new Promise(function ($resolve, $reject) use (&$promise, $fallback, $query, &$cancelled) { - $promise->then($resolve, function (\Exception $e1) use ($fallback, $query, $resolve, $reject, &$cancelled, &$promise) { + return new Promise(function ($resolve, $reject) use (&$promise, $query, &$cancelled) { + $promise->then($resolve, function (\Exception $e1) use ($query, $resolve, $reject, &$cancelled, &$promise) { // reject if primary resolution rejected due to cancellation if ($cancelled) { $reject($e1); @@ -30,7 +29,7 @@ public function query(Query $query) } // start fallback query if primary query rejected - $promise = $fallback->query($query)->then($resolve, function (\Exception $e2) use ($e1, $reject) { + $promise = $this->fallback->query($query)->then($resolve, function (\Exception $e2) use ($e1, $reject) { $append = $e2->getMessage(); if (($pos = strpos($append, ':')) !== false) { $append = substr($append, $pos + 2); diff --git a/src/Query/HostsFileExecutor.php b/src/Query/HostsFileExecutor.php index d6e2d934..590f8abe 100644 --- a/src/Query/HostsFileExecutor.php +++ b/src/Query/HostsFileExecutor.php @@ -5,7 +5,7 @@ use React\Dns\Config\HostsFile; use React\Dns\Model\Message; use React\Dns\Model\Record; -use React\Promise; +use function React\Promise\resolve; /** * Resolves hosts from the given HostsFile or falls back to another executor @@ -29,7 +29,7 @@ public function query(Query $query) { if ($query->class === Message::CLASS_IN && ($query->type === Message::TYPE_A || $query->type === Message::TYPE_AAAA)) { // forward lookup for type A or AAAA - $records = array(); + $records = []; $expectsColon = $query->type === Message::TYPE_AAAA; foreach ($this->hosts->getIpsForHost($query->name) as $ip) { // ensure this is an IPv4/IPV6 address according to query type @@ -39,7 +39,7 @@ public function query(Query $query) } if ($records) { - return Promise\resolve( + return resolve( Message::createResponseWithAnswersForQuery($query, $records) ); } @@ -48,13 +48,13 @@ public function query(Query $query) $ip = $this->getIpFromHost($query->name); if ($ip !== null) { - $records = array(); + $records = []; foreach ($this->hosts->getHostsForIp($ip) as $host) { $records[] = new Record($query->name, $query->type, $query->class, 0, $host); } if ($records) { - return Promise\resolve( + return resolve( Message::createResponseWithAnswersForQuery($query, $records) ); } diff --git a/src/Query/Query.php b/src/Query/Query.php index a3dcfb58..4cdfe63f 100644 --- a/src/Query/Query.php +++ b/src/Query/Query.php @@ -56,7 +56,7 @@ public function describe() $class = $this->class !== Message::CLASS_IN ? 'CLASS' . $this->class . ' ' : ''; $type = 'TYPE' . $this->type; - $ref = new \ReflectionClass('React\Dns\Model\Message'); + $ref = new \ReflectionClass(Message::class); foreach ($ref->getConstants() as $name => $value) { if ($value === $this->type && \strpos($name, 'TYPE_') === 0) { $type = \substr($name, 5); diff --git a/src/Query/RetryExecutor.php b/src/Query/RetryExecutor.php index 880609b2..e68dcc61 100644 --- a/src/Query/RetryExecutor.php +++ b/src/Query/RetryExecutor.php @@ -34,8 +34,7 @@ public function tryQuery(Query $query, $retries) $deferred->resolve($value); }; - $executor = $this->executor; - $errorback = function ($e) use ($deferred, &$promise, $query, $success, &$errorback, &$retries, $executor) { + $errorback = function ($e) use ($deferred, &$promise, $query, $success, &$errorback, &$retries) { if (!$e instanceof TimeoutException) { $errorback = null; $deferred->reject($e); @@ -49,7 +48,7 @@ public function tryQuery(Query $query, $retries) // avoid garbage references by replacing all closures in call stack. // what a lovely piece of code! - $r = new \ReflectionProperty('Exception', 'trace'); + $r = new \ReflectionProperty(\Exception::class, 'trace'); $r->setAccessible(true); $trace = $r->getValue($e); @@ -68,7 +67,7 @@ public function tryQuery(Query $query, $retries) $r->setValue($e, $trace); } else { --$retries; - $promise = $executor->query($query)->then( + $promise = $this->executor->query($query)->then( $success, $errorback ); diff --git a/src/Query/SelectiveTransportExecutor.php b/src/Query/SelectiveTransportExecutor.php index 0f0ca5d0..b76632fd 100644 --- a/src/Query/SelectiveTransportExecutor.php +++ b/src/Query/SelectiveTransportExecutor.php @@ -63,15 +63,14 @@ public function __construct(ExecutorInterface $datagramExecutor, ExecutorInterfa public function query(Query $query) { - $stream = $this->streamExecutor; $pending = $this->datagramExecutor->query($query); - return new Promise(function ($resolve, $reject) use (&$pending, $stream, $query) { + return new Promise(function ($resolve, $reject) use (&$pending, $query) { $pending->then( $resolve, - function ($e) use (&$pending, $stream, $query, $resolve, $reject) { + function ($e) use (&$pending, $query, $resolve, $reject) { if ($e->getCode() === (\defined('SOCKET_EMSGSIZE') ? \SOCKET_EMSGSIZE : 90)) { - $pending = $stream->query($query)->then($resolve, $reject); + $pending = $this->streamExecutor->query($query)->then($resolve, $reject); } else { $reject($e); } diff --git a/src/Query/TcpTransportExecutor.php b/src/Query/TcpTransportExecutor.php index bfaedbae..d940da61 100644 --- a/src/Query/TcpTransportExecutor.php +++ b/src/Query/TcpTransportExecutor.php @@ -8,6 +8,7 @@ use React\EventLoop\Loop; use React\EventLoop\LoopInterface; use React\Promise\Deferred; +use function React\Promise\reject; /** * Send DNS queries over a TCP/IP stream transport. @@ -90,12 +91,12 @@ class TcpTransportExecutor implements ExecutorInterface /** * @var Deferred[] */ - private $pending = array(); + private $pending = []; /** * @var string[] */ - private $names = array(); + private $names = []; /** * Maximum idle time when socket is current unused (i.e. no pending queries outstanding) @@ -146,7 +147,7 @@ public function __construct($nameserver, LoopInterface $loop = null) throw new \InvalidArgumentException('Invalid nameserver address given'); } - $this->nameserver = 'tcp://' . $parts['host'] . ':' . (isset($parts['port']) ? $parts['port'] : 53); + $this->nameserver = 'tcp://' . $parts['host'] . ':' . ($parts['port'] ?? 53); $this->loop = $loop ?: Loop::get(); $this->parser = new Parser(); $this->dumper = new BinaryDumper(); @@ -164,7 +165,7 @@ public function query(Query $query) $queryData = $this->dumper->toBinary($request); $length = \strlen($queryData); if ($length > 0xffff) { - return \React\Promise\reject(new \RuntimeException( + return reject(new \RuntimeException( 'DNS query for ' . $query->describe() . ' failed: Query too large for TCP transport' )); } @@ -175,7 +176,7 @@ public function query(Query $query) // create async TCP/IP connection (may take a while) $socket = @\stream_socket_client($this->nameserver, $errno, $errstr, 0, \STREAM_CLIENT_CONNECT | \STREAM_CLIENT_ASYNC_CONNECT); if ($socket === false) { - return \React\Promise\reject(new \RuntimeException( + return reject(new \RuntimeException( 'DNS query for ' . $query->describe() . ' failed: Unable to connect to DNS server ' . $this->nameserver . ' (' . $errstr . ')', $errno )); @@ -198,16 +199,14 @@ public function query(Query $query) $this->writeBuffer .= $queryData; if (!$this->writePending) { $this->writePending = true; - $this->loop->addWriteStream($this->socket, array($this, 'handleWritable')); + $this->loop->addWriteStream($this->socket, [$this, 'handleWritable']); } - $names =& $this->names; - $that = $this; - $deferred = new Deferred(function () use ($that, &$names, $request) { + $deferred = new Deferred(function () use ($request) { // remove from list of pending names, but remember pending query - $name = $names[$request->id]; - unset($names[$request->id]); - $that->checkIdle(); + $name = $this->names[$request->id]; + unset($this->names[$request->id]); + $this->checkIdle(); throw new CancellationException('DNS query for ' . $name . ' has been cancelled'); }); @@ -243,7 +242,7 @@ public function handleWritable() } $this->readPending = true; - $this->loop->addReadStream($this->socket, array($this, 'handleRead')); + $this->loop->addReadStream($this->socket, [$this, 'handleRead']); } $errno = 0; @@ -252,8 +251,8 @@ public function handleWritable() // Match errstr from PHP's warning message. // fwrite(): Send of 327712 bytes failed with errno=32 Broken pipe \preg_match('/errno=(\d+) (.+)/', $error, $m); - $errno = isset($m[1]) ? (int) $m[1] : 0; - $errstr = isset($m[2]) ? $m[2] : $error; + $errno = (int) ($m[1] ?? 0); + $errstr = $m[2] ?? $error; }); $written = \fwrite($this->socket, $this->writeBuffer); @@ -360,7 +359,7 @@ public function closeError($reason, $code = 0) $code )); } - $this->pending = $this->names = array(); + $this->pending = $this->names = []; } /** @@ -369,9 +368,8 @@ public function closeError($reason, $code = 0) public function checkIdle() { if ($this->idleTimer === null && !$this->names) { - $that = $this; - $this->idleTimer = $this->loop->addTimer($this->idlePeriod, function () use ($that) { - $that->closeError('Idle timeout'); + $this->idleTimer = $this->loop->addTimer($this->idlePeriod, function () { + $this->closeError('Idle timeout'); }); } } diff --git a/src/Query/TimeoutExecutor.php b/src/Query/TimeoutExecutor.php index 06c51b15..d6a63211 100644 --- a/src/Query/TimeoutExecutor.php +++ b/src/Query/TimeoutExecutor.php @@ -23,19 +23,17 @@ public function query(Query $query) { $promise = $this->executor->query($query); - $loop = $this->loop; - $time = $this->timeout; - return new Promise(function ($resolve, $reject) use ($loop, $time, $promise, $query) { + return new Promise(function ($resolve, $reject) use ($promise, $query) { $timer = null; - $promise = $promise->then(function ($v) use (&$timer, $loop, $resolve) { + $promise = $promise->then(function ($v) use (&$timer, $resolve) { if ($timer) { - $loop->cancelTimer($timer); + $this->loop->cancelTimer($timer); } $timer = false; $resolve($v); - }, function ($v) use (&$timer, $loop, $reject) { + }, function ($v) use (&$timer, $reject) { if ($timer) { - $loop->cancelTimer($timer); + $this->loop->cancelTimer($timer); } $timer = false; $reject($v); @@ -47,7 +45,7 @@ public function query(Query $query) } // start timeout timer which will cancel the pending promise - $timer = $loop->addTimer($time, function () use ($time, &$promise, $reject, $query) { + $timer = $this->loop->addTimer($this->timeout, function () use (&$promise, $reject, $query) { $reject(new TimeoutException( 'DNS query for ' . $query->describe() . ' timed out' )); diff --git a/src/Query/UdpTransportExecutor.php b/src/Query/UdpTransportExecutor.php index 30a3d705..31290284 100644 --- a/src/Query/UdpTransportExecutor.php +++ b/src/Query/UdpTransportExecutor.php @@ -8,6 +8,7 @@ use React\EventLoop\Loop; use React\EventLoop\LoopInterface; use React\Promise\Deferred; +use function React\Promise\reject; /** * Send DNS queries over a UDP transport. @@ -110,7 +111,7 @@ public function __construct($nameserver, LoopInterface $loop = null) throw new \InvalidArgumentException('Invalid nameserver address given'); } - $this->nameserver = 'udp://' . $parts['host'] . ':' . (isset($parts['port']) ? $parts['port'] : 53); + $this->nameserver = 'udp://' . $parts['host'] . ':' . ($parts['port'] ?? 53); $this->loop = $loop ?: Loop::get(); $this->parser = new Parser(); $this->dumper = new BinaryDumper(); @@ -122,7 +123,7 @@ public function query(Query $query) $queryData = $this->dumper->toBinary($request); if (isset($queryData[$this->maxPacketSize])) { - return \React\Promise\reject(new \RuntimeException( + return reject(new \RuntimeException( 'DNS query for ' . $query->describe() . ' failed: Query too large for UDP transport', \defined('SOCKET_EMSGSIZE') ? \SOCKET_EMSGSIZE : 90 )); @@ -133,7 +134,7 @@ public function query(Query $query) $errstr = ''; $socket = @\stream_socket_client($this->nameserver, $errno, $errstr, 0); if ($socket === false) { - return \React\Promise\reject(new \RuntimeException( + return reject(new \RuntimeException( 'DNS query for ' . $query->describe() . ' failed: Unable to connect to DNS server ' . $this->nameserver . ' (' . $errstr . ')', $errno )); @@ -148,8 +149,8 @@ public function query(Query $query) // This can also be reproduced by writing data exceeding `stream_set_chunk_size()` to a server refusing UDP data. // fwrite(): send of 8192 bytes failed with errno=111 Connection refused \preg_match('/errno=(\d+) (.+)/', $error, $m); - $errno = isset($m[1]) ? (int) $m[1] : 0; - $errstr = isset($m[2]) ? $m[2] : $error; + $errno = (int) ($m[1] ?? 0); + $errstr = $m[2] ?? $error; }); $written = \fwrite($socket, $queryData); @@ -157,34 +158,30 @@ public function query(Query $query) \restore_error_handler(); if ($written !== \strlen($queryData)) { - return \React\Promise\reject(new \RuntimeException( + return reject(new \RuntimeException( 'DNS query for ' . $query->describe() . ' failed: Unable to send query to DNS server ' . $this->nameserver . ' (' . $errstr . ')', $errno )); } - $loop = $this->loop; - $deferred = new Deferred(function () use ($loop, $socket, $query) { + $deferred = new Deferred(function () use ($socket, $query) { // cancellation should remove socket from loop and close socket - $loop->removeReadStream($socket); + $this->loop->removeReadStream($socket); \fclose($socket); throw new CancellationException('DNS query for ' . $query->describe() . ' has been cancelled'); }); - $max = $this->maxPacketSize; - $parser = $this->parser; - $nameserver = $this->nameserver; - $loop->addReadStream($socket, function ($socket) use ($loop, $deferred, $query, $parser, $request, $max, $nameserver) { + $this->loop->addReadStream($socket, function ($socket) use ($deferred, $query, $request) { // try to read a single data packet from the DNS server // ignoring any errors, this is uses UDP packets and not a stream of data - $data = @\fread($socket, $max); + $data = @\fread($socket, $this->maxPacketSize); if ($data === false) { return; } try { - $response = $parser->parseMessage($data); + $response = $this->parser->parseMessage($data); } catch (\Exception $e) { // ignore and await next if we received an invalid message from remote server // this may as well be a fake response from an attacker (possible DOS) @@ -198,12 +195,12 @@ public function query(Query $query) } // we only react to the first valid message, so remove socket from loop and close - $loop->removeReadStream($socket); + $this->loop->removeReadStream($socket); \fclose($socket); if ($response->tc) { $deferred->reject(new \RuntimeException( - 'DNS query for ' . $query->describe() . ' failed: The DNS server ' . $nameserver . ' returned a truncated result for a UDP query', + 'DNS query for ' . $query->describe() . ' failed: The DNS server ' . $this->nameserver . ' returned a truncated result for a UDP query', \defined('SOCKET_EMSGSIZE') ? \SOCKET_EMSGSIZE : 90 )); return; diff --git a/src/Resolver/Resolver.php b/src/Resolver/Resolver.php index 92926f3f..6108b3da 100644 --- a/src/Resolver/Resolver.php +++ b/src/Resolver/Resolver.php @@ -29,12 +29,11 @@ public function resolve($domain) public function resolveAll($domain, $type) { $query = new Query($domain, $type, Message::CLASS_IN); - $that = $this; return $this->executor->query( $query - )->then(function (Message $response) use ($query, $that) { - return $that->extractValues($query, $response); + )->then(function (Message $response) use ($query) { + return $this->extractValues($query, $response); }); } diff --git a/tests/Config/ConfigTest.php b/tests/Config/ConfigTest.php index 224a87f7..46d2f53d 100644 --- a/tests/Config/ConfigTest.php +++ b/tests/Config/ConfigTest.php @@ -2,8 +2,8 @@ namespace React\Tests\Dns\Config; -use React\Tests\Dns\TestCase; use React\Dns\Config\Config; +use React\Tests\Dns\TestCase; class ConfigTest extends TestCase { @@ -11,7 +11,7 @@ public function testLoadsSystemDefault() { $config = Config::loadSystemConfigBlocking(); - $this->assertInstanceOf('React\Dns\Config\Config', $config); + $this->assertInstanceOf(Config::class, $config); } public function testLoadsDefaultPath() @@ -22,26 +22,26 @@ public function testLoadsDefaultPath() $config = Config::loadResolvConfBlocking(); - $this->assertInstanceOf('React\Dns\Config\Config', $config); + $this->assertInstanceOf(Config::class, $config); } public function testLoadsFromExplicitPath() { $config = Config::loadResolvConfBlocking(__DIR__ . '/../Fixtures/etc/resolv.conf'); - $this->assertEquals(array('8.8.8.8'), $config->nameservers); + $this->assertEquals(['8.8.8.8'], $config->nameservers); } public function testLoadThrowsWhenPathIsInvalid() { - $this->setExpectedException('RuntimeException'); + $this->expectException(\RuntimeException::class); Config::loadResolvConfBlocking(__DIR__ . '/invalid.conf'); } public function testParsesSingleEntryFile() { $contents = 'nameserver 8.8.8.8'; - $expected = array('8.8.8.8'); + $expected = ['8.8.8.8']; $config = Config::loadResolvConfBlocking('data://text/plain;base64,' . base64_encode($contents)); $this->assertEquals($expected, $config->nameservers); @@ -50,7 +50,7 @@ public function testParsesSingleEntryFile() public function testParsesNameserverWithoutIpv6ScopeId() { $contents = 'nameserver ::1%lo'; - $expected = array('::1'); + $expected = ['::1']; $config = Config::loadResolvConfBlocking('data://text/plain;base64,' . base64_encode($contents)); $this->assertEquals($expected, $config->nameservers); @@ -71,7 +71,7 @@ public function testParsesNameserverEntriesFromAverageFileCorrectly() nameserver 127.0.0.1 nameserver ::1 '; - $expected = array('127.0.0.1', '::1'); + $expected = ['127.0.0.1', '::1']; $config = Config::loadResolvConfBlocking('data://text/plain;base64,' . base64_encode($contents)); $this->assertEquals($expected, $config->nameservers); @@ -79,7 +79,7 @@ public function testParsesNameserverEntriesFromAverageFileCorrectly() public function testParsesEmptyFileWithoutNameserverEntries() { - $expected = array(); + $expected = []; $config = Config::loadResolvConfBlocking('data://text/plain;base64,'); $this->assertEquals($expected, $config->nameservers); @@ -97,7 +97,7 @@ public function testParsesFileAndIgnoresCommentsAndInvalidNameserverEntries() NameServer 7.8.9.10 nameserver localhost '; - $expected = array(); + $expected = []; $config = Config::loadResolvConfBlocking('data://text/plain;base64,' . base64_encode($contents)); $this->assertEquals($expected, $config->nameservers); @@ -115,7 +115,7 @@ public function testLoadsFromWmicOnWindows() $config = Config::loadWmicBlocking(); - $this->assertInstanceOf('React\Dns\Config\Config', $config); + $this->assertInstanceOf(Config::class, $config); } public function testLoadsSingleEntryFromWmicOutput() @@ -126,7 +126,7 @@ public function testLoadsSingleEntryFromWmicOutput() ACE,{192.168.2.1} ACE, '; - $expected = array('192.168.2.1'); + $expected = ['192.168.2.1']; $config = Config::loadWmicBlocking($this->echoCommand($contents)); @@ -139,7 +139,7 @@ public function testLoadsEmptyListFromWmicOutput() Node,DNSServerSearchOrder ACE, '; - $expected = array(); + $expected = []; $config = Config::loadWmicBlocking($this->echoCommand($contents)); @@ -156,7 +156,7 @@ public function testLoadsSingleEntryForMultipleNicsFromWmicOutput() ACE,{192.168.2.2} ACE, '; - $expected = array('192.168.2.1', '192.168.2.2'); + $expected = ['192.168.2.1', '192.168.2.2']; $config = Config::loadWmicBlocking($this->echoCommand($contents)); @@ -171,7 +171,7 @@ public function testLoadsMultipleEntriesForSingleNicWithSemicolonFromWmicOutput( ACE,{192.168.2.1;192.168.2.2} ACE, '; - $expected = array('192.168.2.1', '192.168.2.2'); + $expected = ['192.168.2.1', '192.168.2.2']; $config = Config::loadWmicBlocking($this->echoCommand($contents)); @@ -186,7 +186,7 @@ public function testLoadsMultipleEntriesForSingleNicWithQuotesFromWmicOutput() ACE,{"192.168.2.1","192.168.2.2"} ACE, '; - $expected = array('192.168.2.1', '192.168.2.2'); + $expected = ['192.168.2.1', '192.168.2.2']; $config = Config::loadWmicBlocking($this->echoCommand($contents)); diff --git a/tests/Config/HostsFileTest.php b/tests/Config/HostsFileTest.php index 8a7ab852..a8440896 100644 --- a/tests/Config/HostsFileTest.php +++ b/tests/Config/HostsFileTest.php @@ -2,8 +2,8 @@ namespace React\Tests\Dns\Config; -use React\Tests\Dns\TestCase; use React\Dns\Config\HostsFile; +use React\Tests\Dns\TestCase; class HostsFileTest extends TestCase { @@ -11,7 +11,7 @@ public function testLoadsFromDefaultPath() { $hosts = HostsFile::loadFromPathBlocking(); - $this->assertInstanceOf('React\Dns\Config\HostsFile', $hosts); + $this->assertInstanceOf(HostsFile::class, $hosts); } public function testDefaultShouldHaveLocalhostMapped() @@ -27,7 +27,7 @@ public function testDefaultShouldHaveLocalhostMapped() public function testLoadThrowsForInvalidPath() { - $this->setExpectedException('RuntimeException'); + $this->expectException(\RuntimeException::class); HostsFile::loadFromPathBlocking('does/not/exist'); } @@ -35,134 +35,134 @@ public function testContainsSingleLocalhostEntry() { $hosts = new HostsFile('127.0.0.1 localhost'); - $this->assertEquals(array('127.0.0.1'), $hosts->getIpsForHost('localhost')); - $this->assertEquals(array(), $hosts->getIpsForHost('example.com')); + $this->assertEquals(['127.0.0.1'], $hosts->getIpsForHost('localhost')); + $this->assertEquals([], $hosts->getIpsForHost('example.com')); } public function testNonIpReturnsNothingForInvalidHosts() { $hosts = new HostsFile('a b'); - $this->assertEquals(array(), $hosts->getIpsForHost('a')); - $this->assertEquals(array(), $hosts->getIpsForHost('b')); + $this->assertEquals([], $hosts->getIpsForHost('a')); + $this->assertEquals([], $hosts->getIpsForHost('b')); } public function testIgnoresIpv6ZoneId() { $hosts = new HostsFile('fe80::1%lo0 localhost'); - $this->assertEquals(array('fe80::1'), $hosts->getIpsForHost('localhost')); + $this->assertEquals(['fe80::1'], $hosts->getIpsForHost('localhost')); } public function testSkipsComments() { $hosts = new HostsFile('# start' . PHP_EOL .'#127.0.0.1 localhost' . PHP_EOL . '127.0.0.2 localhost # example.com'); - $this->assertEquals(array('127.0.0.2'), $hosts->getIpsForHost('localhost')); - $this->assertEquals(array(), $hosts->getIpsForHost('example.com')); + $this->assertEquals(['127.0.0.2'], $hosts->getIpsForHost('localhost')); + $this->assertEquals([], $hosts->getIpsForHost('example.com')); } public function testContainsSingleLocalhostEntryWithCaseIgnored() { $hosts = new HostsFile('127.0.0.1 LocalHost'); - $this->assertEquals(array('127.0.0.1'), $hosts->getIpsForHost('LOCALHOST')); + $this->assertEquals(['127.0.0.1'], $hosts->getIpsForHost('LOCALHOST')); } public function testEmptyFileContainsNothing() { $hosts = new HostsFile(''); - $this->assertEquals(array(), $hosts->getIpsForHost('example.com')); + $this->assertEquals([], $hosts->getIpsForHost('example.com')); } public function testSingleEntryWithMultipleNames() { $hosts = new HostsFile('127.0.0.1 localhost example.com'); - $this->assertEquals(array('127.0.0.1'), $hosts->getIpsForHost('example.com')); - $this->assertEquals(array('127.0.0.1'), $hosts->getIpsForHost('localhost')); + $this->assertEquals(['127.0.0.1'], $hosts->getIpsForHost('example.com')); + $this->assertEquals(['127.0.0.1'], $hosts->getIpsForHost('localhost')); } public function testMergesEntriesOverMultipleLines() { $hosts = new HostsFile("127.0.0.1 localhost\n127.0.0.2 localhost\n127.0.0.3 a localhost b\n127.0.0.4 a localhost"); - $this->assertEquals(array('127.0.0.1', '127.0.0.2', '127.0.0.3', '127.0.0.4'), $hosts->getIpsForHost('localhost')); + $this->assertEquals(['127.0.0.1', '127.0.0.2', '127.0.0.3', '127.0.0.4'], $hosts->getIpsForHost('localhost')); } public function testMergesIpv4AndIpv6EntriesOverMultipleLines() { $hosts = new HostsFile("127.0.0.1 localhost\n::1 localhost"); - $this->assertEquals(array('127.0.0.1', '::1'), $hosts->getIpsForHost('localhost')); + $this->assertEquals(['127.0.0.1', '::1'], $hosts->getIpsForHost('localhost')); } public function testReverseLookup() { $hosts = new HostsFile('127.0.0.1 localhost'); - $this->assertEquals(array('localhost'), $hosts->getHostsForIp('127.0.0.1')); - $this->assertEquals(array(), $hosts->getHostsForIp('192.168.1.1')); + $this->assertEquals(['localhost'], $hosts->getHostsForIp('127.0.0.1')); + $this->assertEquals([], $hosts->getHostsForIp('192.168.1.1')); } public function testReverseSkipsComments() { $hosts = new HostsFile("# start\n#127.0.0.1 localhosted\n127.0.0.2\tlocalhost\t# example.com\n\t127.0.0.3\t\texample.org\t\t"); - $this->assertEquals(array(), $hosts->getHostsForIp('127.0.0.1')); - $this->assertEquals(array('localhost'), $hosts->getHostsForIp('127.0.0.2')); - $this->assertEquals(array('example.org'), $hosts->getHostsForIp('127.0.0.3')); + $this->assertEquals([], $hosts->getHostsForIp('127.0.0.1')); + $this->assertEquals(['localhost'], $hosts->getHostsForIp('127.0.0.2')); + $this->assertEquals(['example.org'], $hosts->getHostsForIp('127.0.0.3')); } public function testReverseNonIpReturnsNothing() { $hosts = new HostsFile('127.0.0.1 localhost'); - $this->assertEquals(array(), $hosts->getHostsForIp('localhost')); - $this->assertEquals(array(), $hosts->getHostsForIp('127.0.0.1.1')); + $this->assertEquals([], $hosts->getHostsForIp('localhost')); + $this->assertEquals([], $hosts->getHostsForIp('127.0.0.1.1')); } public function testReverseNonIpReturnsNothingForInvalidHosts() { $hosts = new HostsFile('a b'); - $this->assertEquals(array(), $hosts->getHostsForIp('a')); - $this->assertEquals(array(), $hosts->getHostsForIp('b')); + $this->assertEquals([], $hosts->getHostsForIp('a')); + $this->assertEquals([], $hosts->getHostsForIp('b')); } public function testReverseLookupReturnsLowerCaseHost() { $hosts = new HostsFile('127.0.0.1 LocalHost'); - $this->assertEquals(array('localhost'), $hosts->getHostsForIp('127.0.0.1')); + $this->assertEquals(['localhost'], $hosts->getHostsForIp('127.0.0.1')); } public function testReverseLookupChecksNormalizedIpv6() { $hosts = new HostsFile('FE80::00a1 localhost'); - $this->assertEquals(array('localhost'), $hosts->getHostsForIp('fe80::A1')); + $this->assertEquals(['localhost'], $hosts->getHostsForIp('fe80::A1')); } public function testReverseLookupIgnoresIpv6ZoneId() { $hosts = new HostsFile('fe80::1%lo0 localhost'); - $this->assertEquals(array('localhost'), $hosts->getHostsForIp('fe80::1')); + $this->assertEquals(['localhost'], $hosts->getHostsForIp('fe80::1')); } public function testReverseLookupReturnsMultipleHostsOverSingleLine() { $hosts = new HostsFile("::1 ip6-localhost ip6-loopback"); - $this->assertEquals(array('ip6-localhost', 'ip6-loopback'), $hosts->getHostsForIp('::1')); + $this->assertEquals(['ip6-localhost', 'ip6-loopback'], $hosts->getHostsForIp('::1')); } public function testReverseLookupReturnsMultipleHostsOverMultipleLines() { $hosts = new HostsFile("::1 ip6-localhost\n::1 ip6-loopback"); - $this->assertEquals(array('ip6-localhost', 'ip6-loopback'), $hosts->getHostsForIp('::1')); + $this->assertEquals(['ip6-localhost', 'ip6-loopback'], $hosts->getHostsForIp('::1')); } } diff --git a/tests/FunctionalResolverTest.php b/tests/FunctionalResolverTest.php index 2e8690dd..25900cc0 100644 --- a/tests/FunctionalResolverTest.php +++ b/tests/FunctionalResolverTest.php @@ -2,8 +2,10 @@ namespace React\Tests\Dns; -use React\Dns\Resolver\Factory; use React\Dns\Model\Message; +use React\Dns\Query\CancellationException; +use React\Dns\RecordNotFoundException; +use React\Dns\Resolver\Factory; use React\EventLoop\Loop; class FunctionalResolverTest extends TestCase @@ -116,16 +118,13 @@ public function testResolveInvalidRejects() }); /** @var \React\Dns\RecordNotFoundException $exception */ - $this->assertInstanceOf('React\Dns\RecordNotFoundException', $exception); + $this->assertInstanceOf(RecordNotFoundException::class, $exception); $this->assertEquals('DNS query for example.invalid (A) returned an error response (Non-Existent Domain / NXDOMAIN)', $exception->getMessage()); $this->assertEquals(Message::RCODE_NAME_ERROR, $exception->getCode()); } public function testResolveCancelledRejectsImmediately() { - // max_nesting_level was set to 100 for PHP Versions < 5.4 which resulted in failing test for legacy PHP - ini_set('xdebug.max_nesting_level', 256); - $promise = $this->resolver->resolve('google.com'); $promise->cancel(); @@ -141,7 +140,7 @@ public function testResolveCancelledRejectsImmediately() }); /** @var \React\Dns\Query\CancellationException $exception */ - $this->assertInstanceOf('React\Dns\Query\CancellationException', $exception); + $this->assertInstanceOf(CancellationException::class, $exception); $this->assertEquals('DNS query for google.com (A) has been cancelled', $exception->getMessage()); } @@ -160,7 +159,7 @@ public function testResolveAllInvalidTypeRejects() }); /** @var \React\Dns\RecordNotFoundException $exception */ - $this->assertInstanceOf('React\Dns\RecordNotFoundException', $exception); + $this->assertInstanceOf(RecordNotFoundException::class, $exception); $this->assertEquals('DNS query for google.com (PTR) did not return a valid answer (NOERROR / NODATA)', $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); } diff --git a/tests/Model/MessageTest.php b/tests/Model/MessageTest.php index a52f6596..ba0abcc9 100644 --- a/tests/Model/MessageTest.php +++ b/tests/Model/MessageTest.php @@ -20,7 +20,7 @@ public function testCreateRequestDesiresRecusion() public function testCreateResponseWithNoAnswers() { $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN); - $answers = array(); + $answers = []; $request = Message::createResponseWithAnswersForQuery($query, $answers); $this->assertTrue($request->qr); diff --git a/tests/Protocol/BinaryDumperTest.php b/tests/Protocol/BinaryDumperTest.php index 9bd5f109..64d6b981 100644 --- a/tests/Protocol/BinaryDumperTest.php +++ b/tests/Protocol/BinaryDumperTest.php @@ -87,7 +87,7 @@ public function testToBinaryRequestMessageWithAdditionalOptForEdns0() Message::CLASS_IN ); - $request->additional[] = new Record('', Message::TYPE_OPT, 1000, 0, array()); + $request->additional[] = new Record('', Message::TYPE_OPT, 1000, 0, []); $dumper = new BinaryDumper(); $data = $dumper->toBinary($request); @@ -118,9 +118,9 @@ public function testToBinaryRequestMessageWithAdditionalOptForEdns0WithOptTcpKee Message::CLASS_IN ); - $request->additional[] = new Record('', Message::TYPE_OPT, 1000, 0, array( + $request->additional[] = new Record('', Message::TYPE_OPT, 1000, 0, [ Message::OPT_TCP_KEEPALIVE => null, - )); + ]); $dumper = new BinaryDumper(); $data = $dumper->toBinary($request); @@ -151,9 +151,9 @@ public function testToBinaryRequestMessageWithAdditionalOptForEdns0WithOptTcpKee Message::CLASS_IN ); - $request->additional[] = new Record('', Message::TYPE_OPT, 1000, 0, array( + $request->additional[] = new Record('', Message::TYPE_OPT, 1000, 0, [ Message::OPT_TCP_KEEPALIVE => 1.2, - )); + ]); $dumper = new BinaryDumper(); $data = $dumper->toBinary($request); @@ -184,9 +184,9 @@ public function testToBinaryRequestMessageWithAdditionalOptForEdns0WithOptPaddin Message::CLASS_IN ); - $request->additional[] = new Record('', Message::TYPE_OPT, 1000, 0, array( + $request->additional[] = new Record('', Message::TYPE_OPT, 1000, 0, [ Message::OPT_PADDING => "\x00\x00" - )); + ]); $dumper = new BinaryDumper(); $data = $dumper->toBinary($request); @@ -218,10 +218,10 @@ public function testToBinaryRequestMessageWithAdditionalOptForEdns0WithCustomOpt Message::CLASS_IN ); - $request->additional[] = new Record('', Message::TYPE_OPT, 1000, 0, array( + $request->additional[] = new Record('', Message::TYPE_OPT, 1000, 0, [ 0xa0 => 'foo', 0x01 => "\x00\x00" - )); + ]); $dumper = new BinaryDumper(); $data = $dumper->toBinary($request); @@ -282,12 +282,12 @@ public function testToBinaryForResponseWithSRVRecord() Message::CLASS_IN ); - $response->answers[] = new Record('igor.io', Message::TYPE_SRV, Message::CLASS_IN, 86400, array( + $response->answers[] = new Record('igor.io', Message::TYPE_SRV, Message::CLASS_IN, 86400, [ 'priority' => 10, 'weight' => 20, 'port' => 8080, 'target' => 'test' - )); + ]); $dumper = new BinaryDumper(); $data = $dumper->toBinary($response); @@ -324,7 +324,7 @@ public function testToBinaryForResponseWithSOARecord() Message::CLASS_IN ); - $response->answers[] = new Record('igor.io', Message::TYPE_SOA, Message::CLASS_IN, 86400, array( + $response->answers[] = new Record('igor.io', Message::TYPE_SOA, Message::CLASS_IN, 86400, [ 'mname' => 'ns.hello', 'rname' => 'e.hello', 'serial' => 2018060501, @@ -332,7 +332,7 @@ public function testToBinaryForResponseWithSOARecord() 'retry' => 3600, 'expire' => 605800, 'minimum' => 3600 - )); + ]); $dumper = new BinaryDumper(); $data = $dumper->toBinary($response); @@ -433,11 +433,11 @@ public function testToBinaryForResponseWithMultipleAnswerRecords() $response->answers[] = new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 0, '127.0.0.1'); $response->answers[] = new Record('igor.io', Message::TYPE_AAAA, Message::CLASS_IN, 0, '::1'); - $response->answers[] = new Record('igor.io', Message::TYPE_TXT, Message::CLASS_IN, 0, array('hello', 'world')); - $response->answers[] = new Record('igor.io', Message::TYPE_SPF, Message::CLASS_IN, 0, array('v=spf1 -all')); - $response->answers[] = new Record('igor.io', Message::TYPE_MX, Message::CLASS_IN, 0, array('priority' => 0, 'target' => '')); - $response->answers[] = new Record('igor.io', Message::TYPE_CAA, Message::CLASS_IN, 0, array('flag' => 0, 'tag' => 'issue', 'value' => 'letsencrypt.org')); - $response->answers[] = new Record('igor.io', Message::TYPE_SSHFP, Message::CLASS_IN, 0, array('algorithm' => 1, 'type' => '1', 'fingerprint' => '69ac090c')); + $response->answers[] = new Record('igor.io', Message::TYPE_TXT, Message::CLASS_IN, 0, ['hello', 'world']); + $response->answers[] = new Record('igor.io', Message::TYPE_SPF, Message::CLASS_IN, 0, ['v=spf1 -all']); + $response->answers[] = new Record('igor.io', Message::TYPE_MX, Message::CLASS_IN, 0, ['priority' => 0, 'target' => '']); + $response->answers[] = new Record('igor.io', Message::TYPE_CAA, Message::CLASS_IN, 0, ['flag' => 0, 'tag' => 'issue', 'value' => 'letsencrypt.org']); + $response->answers[] = new Record('igor.io', Message::TYPE_SSHFP, Message::CLASS_IN, 0, ['algorithm' => 1, 'type' => '1', 'fingerprint' => '69ac090c']); $dumper = new BinaryDumper(); $data = $dumper->toBinary($response); diff --git a/tests/Protocol/ParserTest.php b/tests/Protocol/ParserTest.php index 7cf9cbe7..dfd9e1c7 100644 --- a/tests/Protocol/ParserTest.php +++ b/tests/Protocol/ParserTest.php @@ -28,12 +28,10 @@ public function testConvertTcpDumpToBinary($expected, $data) public function provideConvertTcpDumpToBinary() { - return array( - array(chr(0x72).chr(0x62), "72 62"), - array(chr(0x72).chr(0x62).chr(0x01).chr(0x00), "72 62 01 00"), - array(chr(0x72).chr(0x62).chr(0x01).chr(0x00).chr(0x00).chr(0x01), "72 62 01 00 00 01"), - array(chr(0x01).chr(0x00).chr(0x01), "01 00 01"), - ); + yield [chr(0x72).chr(0x62), "72 62"]; + yield [chr(0x72).chr(0x62).chr(0x01).chr(0x00), "72 62 01 00"]; + yield [chr(0x72).chr(0x62).chr(0x01).chr(0x00).chr(0x00).chr(0x01), "72 62 01 00 00 01"]; + yield [chr(0x01).chr(0x00).chr(0x01), "01 00 01"]; } public function testParseRequest() @@ -304,7 +302,7 @@ public function testParseTXTResponse() $this->assertSame(Message::TYPE_TXT, $response->answers[0]->type); $this->assertSame(Message::CLASS_IN, $response->answers[0]->class); $this->assertSame(86400, $response->answers[0]->ttl); - $this->assertSame(array('hello'), $response->answers[0]->data); + $this->assertSame(['hello'], $response->answers[0]->data); } public function testParseSPFResponse() @@ -323,7 +321,7 @@ public function testParseSPFResponse() $this->assertSame(Message::TYPE_SPF, $response->answers[0]->type); $this->assertSame(Message::CLASS_IN, $response->answers[0]->class); $this->assertSame(86400, $response->answers[0]->ttl); - $this->assertSame(array('hello'), $response->answers[0]->data); + $this->assertSame(['hello'], $response->answers[0]->data); } public function testParseTXTResponseMultiple() @@ -342,7 +340,7 @@ public function testParseTXTResponseMultiple() $this->assertSame(Message::TYPE_TXT, $response->answers[0]->type); $this->assertSame(Message::CLASS_IN, $response->answers[0]->class); $this->assertSame(86400, $response->answers[0]->ttl); - $this->assertSame(array('hello', 'world'), $response->answers[0]->data); + $this->assertSame(['hello', 'world'], $response->answers[0]->data); } public function testParseMXResponse() @@ -361,7 +359,7 @@ public function testParseMXResponse() $this->assertSame(Message::TYPE_MX, $response->answers[0]->type); $this->assertSame(Message::CLASS_IN, $response->answers[0]->class); $this->assertSame(86400, $response->answers[0]->ttl); - $this->assertSame(array('priority' => 10, 'target' => 'hello'), $response->answers[0]->data); + $this->assertSame(['priority' => 10, 'target' => 'hello'], $response->answers[0]->data); } public function testParseSRVResponse() @@ -381,12 +379,12 @@ public function testParseSRVResponse() $this->assertSame(Message::CLASS_IN, $response->answers[0]->class); $this->assertSame(86400, $response->answers[0]->ttl); $this->assertSame( - array( + [ 'priority' => 10, 'weight' => 20, 'port' => 8080, 'target' => 'test' - ), + ], $response->answers[0]->data ); } @@ -557,7 +555,7 @@ public function testParseSSHFPResponse() $this->assertSame(Message::TYPE_SSHFP, $response->answers[0]->type); $this->assertSame(Message::CLASS_IN, $response->answers[0]->class); $this->assertSame(86400, $response->answers[0]->ttl); - $this->assertSame(array('algorithm' => 1, 'type' => 1, 'fingerprint' => '69ac090c'), $response->answers[0]->data); + $this->assertSame(['algorithm' => 1, 'type' => 1, 'fingerprint' => '69ac090c'], $response->answers[0]->data); } public function testParseOptResponseWithoutOptions() @@ -575,7 +573,7 @@ public function testParseOptResponseWithoutOptions() $this->assertSame(Message::TYPE_OPT, $response->answers[0]->type); $this->assertSame(1000, $response->answers[0]->class); $this->assertSame(0, $response->answers[0]->ttl); - $this->assertSame(array(), $response->answers[0]->data); + $this->assertSame([], $response->answers[0]->data); } public function testParseOptResponseWithOptTcpKeepaliveDesired() @@ -594,7 +592,7 @@ public function testParseOptResponseWithOptTcpKeepaliveDesired() $this->assertSame(Message::TYPE_OPT, $response->answers[0]->type); $this->assertSame(1000, $response->answers[0]->class); $this->assertSame(0, $response->answers[0]->ttl); - $this->assertSame(array(Message::OPT_TCP_KEEPALIVE => null), $response->answers[0]->data); + $this->assertSame([Message::OPT_TCP_KEEPALIVE => null], $response->answers[0]->data); } public function testParseOptResponseWithOptTcpKeepaliveGiven() @@ -613,7 +611,7 @@ public function testParseOptResponseWithOptTcpKeepaliveGiven() $this->assertSame(Message::TYPE_OPT, $response->answers[0]->type); $this->assertSame(1000, $response->answers[0]->class); $this->assertSame(0, $response->answers[0]->ttl); - $this->assertSame(array(Message::OPT_TCP_KEEPALIVE => 1.2), $response->answers[0]->data); + $this->assertSame([Message::OPT_TCP_KEEPALIVE => 1.2], $response->answers[0]->data); } public function testParseOptResponseWithCustomOptions() @@ -633,7 +631,7 @@ public function testParseOptResponseWithCustomOptions() $this->assertSame(Message::TYPE_OPT, $response->answers[0]->type); $this->assertSame(1000, $response->answers[0]->class); $this->assertSame(0, $response->answers[0]->ttl); - $this->assertSame(array(0xa0 => 'foo', 0x01 => ''), $response->answers[0]->data); + $this->assertSame([0xa0 => 'foo', 0x01 => ''], $response->answers[0]->data); } public function testParseSOAResponse() @@ -656,7 +654,7 @@ public function testParseSOAResponse() $this->assertSame(Message::CLASS_IN, $response->answers[0]->class); $this->assertSame(86400, $response->answers[0]->ttl); $this->assertSame( - array( + [ 'mname' => 'ns.hello', 'rname' => 'e.hello', 'serial' => 2018060501, @@ -664,7 +662,7 @@ public function testParseSOAResponse() 'retry' => 3600, 'expire' => 604800, 'minimum' => 3600 - ), + ], $response->answers[0]->data ); } @@ -686,7 +684,7 @@ public function testParseCAAResponse() $this->assertSame(Message::TYPE_CAA, $response->answers[0]->type); $this->assertSame(Message::CLASS_IN, $response->answers[0]->class); $this->assertSame(86400, $response->answers[0]->ttl); - $this->assertSame(array('flag' => 0, 'tag' => 'issue', 'value' => 'letsencrypt.org'), $response->answers[0]->data); + $this->assertSame(['flag' => 0, 'tag' => 'issue', 'value' => 'letsencrypt.org'], $response->answers[0]->data); } public function testParsePTRResponse() @@ -768,7 +766,7 @@ public function testParseIncompleteQuestionThrows() $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -780,7 +778,7 @@ public function testParseIncompleteQuestionLabelThrows() $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -792,7 +790,7 @@ public function testParseIncompleteQuestionNameThrows() $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -804,7 +802,7 @@ public function testParseIncompleteOffsetPointerInQuestionNameThrows() $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -816,7 +814,7 @@ public function testParseInvalidOffsetPointerInQuestionNameThrows() $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -828,7 +826,7 @@ public function testParseInvalidOffsetPointerToSameLabelInQuestionNameThrows() $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -840,7 +838,7 @@ public function testParseInvalidOffsetPointerToPreviousLabelInQuestionNameThrows $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -852,7 +850,7 @@ public function testParseInvalidOffsetPointerToStartOfMessageInQuestionNameThrow $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -866,7 +864,7 @@ public function testParseIncompleteAnswerFieldsThrows() $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -880,7 +878,7 @@ public function testParseMessageResponseWithIncompleteAuthorityRecordThrows() $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -894,7 +892,7 @@ public function testParseMessageResponseWithIncompleteAdditionalRecordThrows() $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -911,7 +909,7 @@ public function testParseIncompleteAnswerRecordDataThrows() $data = $this->convertTcpDumpToBinary($data); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parser->parseMessage($data); } @@ -923,7 +921,7 @@ public function testParseInvalidNSResponseWhereDomainNameIsMissing() $data .= "00 01 51 80"; // answer: ttl 86400 $data .= "00 00"; // answer: rdlength 0 - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -935,7 +933,7 @@ public function testParseInvalidAResponseWhereIPIsMissing() $data .= "00 01 51 80"; // answer: ttl 86400 $data .= "00 00"; // answer: rdlength 0 - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -947,7 +945,7 @@ public function testParseInvalidAAAAResponseWhereIPIsMissing() $data .= "00 01 51 80"; // answer: ttl 86400 $data .= "00 00"; // answer: rdlength 0 - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -960,7 +958,7 @@ public function testParseInvalidTXTResponseWhereTxtChunkExceedsLimit() $data .= "00 06"; // answer: rdlength 6 $data .= "06 68 65 6c 6c 6f 6f"; // answer: rdata length 6: helloo - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -973,7 +971,7 @@ public function testParseInvalidMXResponseWhereDomainNameIsIncomplete() $data .= "00 08"; // answer: rdlength 8 $data .= "00 0a 05 68 65 6c 6c 6f"; // answer: rdata priority 10: hello (missing label end) - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -986,7 +984,7 @@ public function testParseInvalidMXResponseWhereDomainNameIsMissing() $data .= "00 02"; // answer: rdlength 2 $data .= "00 0a"; // answer: rdata priority 10 - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -999,7 +997,7 @@ public function testParseInvalidSRVResponseWhereDomainNameIsIncomplete() $data .= "00 0b"; // answer: rdlength 11 $data .= "00 0a 00 14 1F 90 04 74 65 73 74"; // answer: rdata priority 10, weight 20, port 8080 test (missing label end) - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -1012,7 +1010,7 @@ public function testParseInvalidSRVResponseWhereDomainNameIsMissing() $data .= "00 06"; // answer: rdlength 6 $data .= "00 0a 00 14 1F 90"; // answer: rdata priority 10, weight 20, port 8080 - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -1025,7 +1023,7 @@ public function testParseInvalidSSHFPResponseWhereRecordIsTooSmall() $data .= "00 02"; // answer: rdlength 2 $data .= "01 01"; // answer: algorithm 1 (RSA), type 1 (SHA), missing fingerprint - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -1038,7 +1036,7 @@ public function testParseInvalidOPTResponseWhereRecordIsTooSmall() $data .= "00 03"; // answer: rdlength 3 $data .= "00 00 00"; // answer: type 0, length incomplete - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -1051,7 +1049,7 @@ public function testParseInvalidOPTResponseWhereRecordLengthDoesNotMatchOptType( $data .= "00 07"; // answer: rdlength 7 $data .= "00 0b 00 03 01 02 03"; // answer: type OPT_TCP_KEEPALIVE, length 3 instead of 2 - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -1065,7 +1063,7 @@ public function testParseInvalidSOAResponseWhereFlagsAreMissing() $data .= "02 6e 73 05 68 65 6c 6c 6f 00"; // answer: rdata ns.hello (mname) $data .= "01 65 05 68 65 6c 6c 6f 00"; // answer: rdata e.hello (rname) - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -1077,7 +1075,7 @@ public function testParseInvalidCAAResponseEmtpyData() $data .= "00 01 51 80"; // answer: ttl 86400 $data .= "00 00"; // answer: rdlength 0 - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -1090,7 +1088,7 @@ public function testParseInvalidCAAResponseMissingValue() $data .= "00 07"; // answer: rdlength 22 $data .= "00 05 69 73 73 75 65"; // answer: rdata 0, issue - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } @@ -1104,7 +1102,7 @@ public function testParseInvalidCAAResponseIncompleteTag() $data .= "00 ff 69 73 73 75 65"; // answer: rdata 0, issue (incomplete due to invalid tag length) $data .= "68 65 6c 6c 6f"; // answer: hello - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $this->parseAnswer($data); } diff --git a/tests/Query/CachingExecutorTest.php b/tests/Query/CachingExecutorTest.php index 2a4250fc..f51299f3 100644 --- a/tests/Query/CachingExecutorTest.php +++ b/tests/Query/CachingExecutorTest.php @@ -2,22 +2,26 @@ namespace React\Tests\Dns\Query; +use React\Cache\CacheInterface; use React\Dns\Model\Message; +use React\Dns\Model\Record; use React\Dns\Query\CachingExecutor; +use React\Dns\Query\ExecutorInterface; use React\Dns\Query\Query; use React\Promise\Promise; -use React\Tests\Dns\TestCase; use React\Promise\Deferred; -use React\Dns\Model\Record; +use React\Tests\Dns\TestCase; +use function React\Promise\reject; +use function React\Promise\resolve; class CachingExecutorTest extends TestCase { public function testQueryWillReturnPendingPromiseWhenCacheIsPendingWithoutSendingQueryToFallbackExecutor() { - $fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $fallback = $this->createMock(ExecutorInterface::class); $fallback->expects($this->never())->method('query'); - $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock(); + $cache = $this->createMock(CacheInterface::class); $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn(new Promise(function () { })); $executor = new CachingExecutor($fallback, $cache); @@ -33,11 +37,11 @@ public function testQueryWillReturnPendingPromiseWhenCacheReturnsMissAndWillSend { $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $fallback = $this->createMock(ExecutorInterface::class); $fallback->expects($this->once())->method('query')->with($query)->willReturn(new Promise(function () { })); - $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock(); - $cache->expects($this->once())->method('get')->willReturn(\React\Promise\resolve(null)); + $cache = $this->createMock(CacheInterface::class); + $cache->expects($this->once())->method('get')->willReturn(resolve(null)); $executor = new CachingExecutor($fallback, $cache); @@ -48,12 +52,12 @@ public function testQueryWillReturnPendingPromiseWhenCacheReturnsMissAndWillSend public function testQueryWillReturnResolvedPromiseWhenCacheReturnsHitWithoutSendingQueryToFallbackExecutor() { - $fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $fallback = $this->createMock(ExecutorInterface::class); $fallback->expects($this->never())->method('query'); $message = new Message(); - $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock(); - $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn(\React\Promise\resolve($message)); + $cache = $this->createMock(CacheInterface::class); + $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn(resolve($message)); $executor = new CachingExecutor($fallback, $cache); @@ -69,11 +73,11 @@ public function testQueryWillReturnResolvedPromiseWhenCacheReturnsMissAndFallbac $message = new Message(); $message->answers[] = new Record('reactphp.org', Message::TYPE_A, Message::CLASS_IN, 3700, '127.0.0.1'); $message->answers[] = new Record('reactphp.org', Message::TYPE_A, Message::CLASS_IN, 3600, '127.0.0.1'); - $fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $fallback->expects($this->once())->method('query')->willReturn(\React\Promise\resolve($message)); + $fallback = $this->createMock(ExecutorInterface::class); + $fallback->expects($this->once())->method('query')->willReturn(resolve($message)); - $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock(); - $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn(\React\Promise\resolve(null)); + $cache = $this->createMock(CacheInterface::class); + $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn(resolve(null)); $cache->expects($this->once())->method('set')->with('reactphp.org:1:1', $message, 3600); $executor = new CachingExecutor($fallback, $cache); @@ -88,11 +92,11 @@ public function testQueryWillReturnResolvedPromiseWhenCacheReturnsMissAndFallbac public function testQueryWillReturnResolvedPromiseWhenCacheReturnsMissAndFallbackExecutorResolvesAndSaveMessageToCacheWithDefaultTtl() { $message = new Message(); - $fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $fallback->expects($this->once())->method('query')->willReturn(\React\Promise\resolve($message)); + $fallback = $this->createMock(ExecutorInterface::class); + $fallback->expects($this->once())->method('query')->willReturn(resolve($message)); - $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock(); - $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn(\React\Promise\resolve(null)); + $cache = $this->createMock(CacheInterface::class); + $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn(resolve(null)); $cache->expects($this->once())->method('set')->with('reactphp.org:1:1', $message, 60); $executor = new CachingExecutor($fallback, $cache); @@ -108,11 +112,11 @@ public function testQueryWillReturnResolvedPromiseWhenCacheReturnsMissAndFallbac { $message = new Message(); $message->tc = true; - $fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $fallback->expects($this->once())->method('query')->willReturn(\React\Promise\resolve($message)); + $fallback = $this->createMock(ExecutorInterface::class); + $fallback->expects($this->once())->method('query')->willReturn(resolve($message)); - $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock(); - $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn(\React\Promise\resolve(null)); + $cache = $this->createMock(CacheInterface::class); + $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn(resolve(null)); $cache->expects($this->never())->method('set'); $executor = new CachingExecutor($fallback, $cache); @@ -128,11 +132,11 @@ public function testQueryWillReturnRejectedPromiseWhenCacheReturnsMissAndFallbac { $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $fallback->expects($this->once())->method('query')->willReturn(\React\Promise\reject($exception = new \RuntimeException())); + $fallback = $this->createMock(ExecutorInterface::class); + $fallback->expects($this->once())->method('query')->willReturn(reject($exception = new \RuntimeException())); - $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock(); - $cache->expects($this->once())->method('get')->willReturn(\React\Promise\resolve(null)); + $cache = $this->createMock(CacheInterface::class); + $cache->expects($this->once())->method('get')->willReturn(resolve(null)); $executor = new CachingExecutor($fallback, $cache); @@ -143,11 +147,11 @@ public function testQueryWillReturnRejectedPromiseWhenCacheReturnsMissAndFallbac public function testCancelQueryWillReturnRejectedPromiseAndCancelPendingPromiseFromCache() { - $fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $fallback = $this->createMock(ExecutorInterface::class); $fallback->expects($this->never())->method('query'); $pending = new Promise(function () { }, $this->expectCallableOnce()); - $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock(); + $cache = $this->createMock(CacheInterface::class); $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn($pending); $executor = new CachingExecutor($fallback, $cache); @@ -163,18 +167,18 @@ public function testCancelQueryWillReturnRejectedPromiseAndCancelPendingPromiseF }); /** @var \RuntimeException $exception */ - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for reactphp.org (A) has been cancelled', $exception->getMessage()); } public function testCancelQueryWillReturnRejectedPromiseAndCancelPendingPromiseFromFallbackExecutorWhenCacheReturnsMiss() { $pending = new Promise(function () { }, $this->expectCallableOnce()); - $fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $fallback = $this->createMock(ExecutorInterface::class); $fallback->expects($this->once())->method('query')->willReturn($pending); $deferred = new Deferred(); - $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock(); + $cache = $this->createMock(CacheInterface::class); $cache->expects($this->once())->method('get')->with('reactphp.org:1:1')->willReturn($deferred->promise()); $executor = new CachingExecutor($fallback, $cache); @@ -191,7 +195,7 @@ public function testCancelQueryWillReturnRejectedPromiseAndCancelPendingPromiseF }); /** @var \RuntimeException $exception */ - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for reactphp.org (A) has been cancelled', $exception->getMessage()); } } diff --git a/tests/Query/CoopExecutorTest.php b/tests/Query/CoopExecutorTest.php index 8fd191a8..52ab4104 100644 --- a/tests/Query/CoopExecutorTest.php +++ b/tests/Query/CoopExecutorTest.php @@ -1,11 +1,15 @@ getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->once())->method('query')->with($query)->willReturn($pending); $connector = new CoopExecutor($base); @@ -24,14 +28,14 @@ public function testQueryOnceWillResolveWhenBaseExecutorResolves() { $message = new Message(); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $base->expects($this->once())->method('query')->willReturn(\React\Promise\resolve($message)); + $base = $this->createMock(ExecutorInterface::class); + $base->expects($this->once())->method('query')->willReturn(resolve($message)); $connector = new CoopExecutor($base); $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); $promise = $connector->query($query); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $promise->then($this->expectCallableOnceWith($message)); } @@ -40,14 +44,14 @@ public function testQueryOnceWillRejectWhenBaseExecutorRejects() { $exception = new RuntimeException(); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $base->expects($this->once())->method('query')->willReturn(\React\Promise\reject($exception)); + $base = $this->createMock(ExecutorInterface::class); + $base->expects($this->once())->method('query')->willReturn(reject($exception)); $connector = new CoopExecutor($base); $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); $promise = $connector->query($query); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $promise->then(null, $this->expectCallableOnceWith($exception)); } @@ -57,10 +61,10 @@ public function testQueryTwoDifferentQueriesWillPassExactQueryToBaseExecutorTwic $pending = new Promise(function () { }); $query1 = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); $query2 = new Query('reactphp.org', Message::TYPE_AAAA, Message::CLASS_IN); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->exactly(2))->method('query')->withConsecutive( - array($query1), - array($query2) + [$query1], + [$query2] )->willReturn($pending); $connector = new CoopExecutor($base); @@ -72,7 +76,7 @@ public function testQueryTwiceWillPassExactQueryToBaseExecutorOnceWhenQueryIsSti { $pending = new Promise(function () { }); $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->once())->method('query')->with($query)->willReturn($pending); $connector = new CoopExecutor($base); @@ -85,7 +89,7 @@ public function testQueryTwiceWillPassExactQueryToBaseExecutorTwiceWhenFirstQuer $deferred = new Deferred(); $pending = new Promise(function () { }); $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->exactly(2))->method('query')->with($query)->willReturnOnConsecutiveCalls($deferred->promise(), $pending); $connector = new CoopExecutor($base); @@ -102,7 +106,7 @@ public function testQueryTwiceWillPassExactQueryToBaseExecutorTwiceWhenFirstQuer $deferred = new Deferred(); $pending = new Promise(function () { }); $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->exactly(2))->method('query')->with($query)->willReturnOnConsecutiveCalls($deferred->promise(), $pending); $connector = new CoopExecutor($base); @@ -120,7 +124,7 @@ public function testCancelQueryWillCancelPromiseFromBaseExecutorAndReject() { $promise = new Promise(function () { }, $this->expectCallableOnce()); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->once())->method('query')->willReturn($promise); $connector = new CoopExecutor($base); @@ -135,7 +139,7 @@ public function testCancelQueryWillCancelPromiseFromBaseExecutorAndReject() }); /** @var \RuntimeException $exception */ - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for reactphp.org (A) has been cancelled', $exception->getMessage()); } @@ -143,7 +147,7 @@ public function testCancelOneQueryWhenOtherQueryIsStillPendingWillNotCancelPromi { $promise = new Promise(function () { }, $this->expectCallableNever()); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->once())->method('query')->willReturn($promise); $connector = new CoopExecutor($base); @@ -161,7 +165,7 @@ public function testCancelSecondQueryWhenFirstQueryIsStillPendingWillNotCancelPr { $promise = new Promise(function () { }, $this->expectCallableNever()); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->once())->method('query')->willReturn($promise); $connector = new CoopExecutor($base); @@ -179,7 +183,7 @@ public function testCancelAllPendingQueriesWillCancelPromiseFromBaseExecutorAndR { $promise = new Promise(function () { }, $this->expectCallableOnce()); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->once())->method('query')->willReturn($promise); $connector = new CoopExecutor($base); @@ -199,7 +203,7 @@ public function testQueryTwiceWillQueryBaseExecutorTwiceIfFirstQueryHasAlreadyBe $promise = new Promise(function () { }, $this->expectCallableOnce()); $pending = new Promise(function () { }); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->exactly(2))->method('query')->willReturnOnConsecutiveCalls($promise, $pending); $connector = new CoopExecutor($base); @@ -225,7 +229,7 @@ public function testCancelQueryShouldNotCauseGarbageReferences() throw new \RuntimeException(); }); - $base = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $base = $this->createMock(ExecutorInterface::class); $base->expects($this->once())->method('query')->willReturn($deferred->promise()); $connector = new CoopExecutor($base); diff --git a/tests/Query/FallbackExecutorTest.php b/tests/Query/FallbackExecutorTest.php index b0dc053c..434aa71e 100644 --- a/tests/Query/FallbackExecutorTest.php +++ b/tests/Query/FallbackExecutorTest.php @@ -3,10 +3,14 @@ namespace React\Tests\Dns\Query; use React\Dns\Model\Message; +use React\Dns\Query\ExecutorInterface; use React\Dns\Query\FallbackExecutor; use React\Dns\Query\Query; use React\Promise\Promise; +use React\Promise\PromiseInterface; use React\Tests\Dns\TestCase; +use function React\Promise\reject; +use function React\Promise\resolve; class FallbackExecutorTest extends TestCase { @@ -14,16 +18,16 @@ public function testQueryWillReturnPendingPromiseWhenPrimaryExecutorIsStillPendi { $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $primary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $primary = $this->createMock(ExecutorInterface::class); $primary->expects($this->once())->method('query')->with($query)->willReturn(new Promise(function () { })); - $secondary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $secondary = $this->createMock(ExecutorInterface::class); $executor = new FallbackExecutor($primary, $secondary); $promise = $executor->query($query); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $promise->then($this->expectCallableNever(), $this->expectCallableNever()); } @@ -31,34 +35,34 @@ public function testQueryWillResolveWithMessageWhenPrimaryExecutorResolvesWithMe { $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $primary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $primary->expects($this->once())->method('query')->with($query)->willReturn(\React\Promise\resolve(new Message())); + $primary = $this->createMock(ExecutorInterface::class); + $primary->expects($this->once())->method('query')->with($query)->willReturn(resolve(new Message())); - $secondary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $secondary = $this->createMock(ExecutorInterface::class); $executor = new FallbackExecutor($primary, $secondary); $promise = $executor->query($query); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); - $promise->then($this->expectCallableOnceWith($this->isInstanceOf('React\Dns\Model\Message')), $this->expectCallableNever()); + $this->assertInstanceOf(PromiseInterface::class, $promise); + $promise->then($this->expectCallableOnceWith($this->isInstanceOf(Message::class)), $this->expectCallableNever()); } public function testQueryWillReturnPendingPromiseWhenPrimaryExecutorRejectsPromiseAndSecondaryExecutorIsStillPending() { $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $primary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $primary->expects($this->once())->method('query')->with($query)->willReturn(\React\Promise\reject(new \RuntimeException())); + $primary = $this->createMock(ExecutorInterface::class); + $primary->expects($this->once())->method('query')->with($query)->willReturn(reject(new \RuntimeException())); - $secondary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $secondary = $this->createMock(ExecutorInterface::class); $secondary->expects($this->once())->method('query')->with($query)->willReturn(new Promise(function () { })); $executor = new FallbackExecutor($primary, $secondary); $promise = $executor->query($query); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $promise->then($this->expectCallableNever(), $this->expectCallableNever()); } @@ -66,43 +70,43 @@ public function testQueryWillResolveWithMessageWhenPrimaryExecutorRejectsPromise { $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $primary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $primary->expects($this->once())->method('query')->with($query)->willReturn(\React\Promise\reject(new \RuntimeException())); + $primary = $this->createMock(ExecutorInterface::class); + $primary->expects($this->once())->method('query')->with($query)->willReturn(reject(new \RuntimeException())); - $secondary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $secondary->expects($this->once())->method('query')->with($query)->willReturn(\React\Promise\resolve(new Message())); + $secondary = $this->createMock(ExecutorInterface::class); + $secondary->expects($this->once())->method('query')->with($query)->willReturn(resolve(new Message())); $executor = new FallbackExecutor($primary, $secondary); $promise = $executor->query($query); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); - $promise->then($this->expectCallableOnceWith($this->isInstanceOf('React\Dns\Model\Message')), $this->expectCallableNever()); + $this->assertInstanceOf(PromiseInterface::class, $promise); + $promise->then($this->expectCallableOnceWith($this->isInstanceOf(Message::class)), $this->expectCallableNever()); } public function testQueryWillRejectWithExceptionMessagesConcatenatedAfterColonWhenPrimaryExecutorRejectsPromiseAndSecondaryExecutorRejectsPromiseWithMessageWithColon() { $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $primary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $primary->expects($this->once())->method('query')->with($query)->willReturn(\React\Promise\reject(new \RuntimeException('DNS query for reactphp.org (A) failed: Unable to connect to DNS server A'))); + $primary = $this->createMock(ExecutorInterface::class); + $primary->expects($this->once())->method('query')->with($query)->willReturn(reject(new \RuntimeException('DNS query for reactphp.org (A) failed: Unable to connect to DNS server A'))); - $secondary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $secondary->expects($this->once())->method('query')->with($query)->willReturn(\React\Promise\reject(new \RuntimeException('DNS query for reactphp.org (A) failed: Unable to connect to DNS server B'))); + $secondary = $this->createMock(ExecutorInterface::class); + $secondary->expects($this->once())->method('query')->with($query)->willReturn(reject(new \RuntimeException('DNS query for reactphp.org (A) failed: Unable to connect to DNS server B'))); $executor = new FallbackExecutor($primary, $secondary); $promise = $executor->query($query); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); - $promise->then($this->expectCallableNever(), $this->expectCallableOnce($this->isInstanceOf('Exception'))); + $this->assertInstanceOf(PromiseInterface::class, $promise); + $promise->then($this->expectCallableNever(), $this->expectCallableOnce($this->isInstanceOf(\Exception::class))); $exception = null; $promise->then(null, function ($reason) use (&$exception) { $exception = $reason; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for reactphp.org (A) failed: Unable to connect to DNS server A. Unable to connect to DNS server B', $exception->getMessage()); } @@ -110,25 +114,25 @@ public function testQueryWillRejectWithExceptionMessagesConcatenatedInFullWhenPr { $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $primary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $primary->expects($this->once())->method('query')->with($query)->willReturn(\React\Promise\reject(new \RuntimeException('Reason A'))); + $primary = $this->createMock(ExecutorInterface::class); + $primary->expects($this->once())->method('query')->with($query)->willReturn(reject(new \RuntimeException('Reason A'))); - $secondary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $secondary->expects($this->once())->method('query')->with($query)->willReturn(\React\Promise\reject(new \RuntimeException('Reason B'))); + $secondary = $this->createMock(ExecutorInterface::class); + $secondary->expects($this->once())->method('query')->with($query)->willReturn(reject(new \RuntimeException('Reason B'))); $executor = new FallbackExecutor($primary, $secondary); $promise = $executor->query($query); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); - $promise->then($this->expectCallableNever(), $this->expectCallableOnce($this->isInstanceOf('Exception'))); + $this->assertInstanceOf(PromiseInterface::class, $promise); + $promise->then($this->expectCallableNever(), $this->expectCallableOnce($this->isInstanceOf(\Exception::class))); $exception = null; $promise->then(null, function ($reason) use (&$exception) { $exception = $reason; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('Reason A. Reason B', $exception->getMessage()); } @@ -136,10 +140,10 @@ public function testCancelQueryWillReturnRejectedPromiseWithoutCallingSecondaryE { $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $primary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $primary = $this->createMock(ExecutorInterface::class); $primary->expects($this->once())->method('query')->with($query)->willReturn(new Promise(function () { }, function () { throw new \RuntimeException(); })); - $secondary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $secondary = $this->createMock(ExecutorInterface::class); $secondary->expects($this->never())->method('query'); $executor = new FallbackExecutor($primary, $secondary); @@ -147,7 +151,7 @@ public function testCancelQueryWillReturnRejectedPromiseWithoutCallingSecondaryE $promise = $executor->query($query); $promise->cancel(); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $promise->then($this->expectCallableNever(), $this->expectCallableOnce()); } @@ -155,10 +159,10 @@ public function testCancelQueryWillReturnRejectedPromiseWhenPrimaryExecutorRejec { $query = new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN); - $primary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $primary->expects($this->once())->method('query')->with($query)->willReturn(\React\Promise\reject(new \RuntimeException())); + $primary = $this->createMock(ExecutorInterface::class); + $primary->expects($this->once())->method('query')->with($query)->willReturn(reject(new \RuntimeException())); - $secondary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $secondary = $this->createMock(ExecutorInterface::class); $secondary->expects($this->once())->method('query')->with($query)->willReturn(new Promise(function () { }, function () { throw new \RuntimeException(); })); $executor = new FallbackExecutor($primary, $secondary); @@ -166,7 +170,7 @@ public function testCancelQueryWillReturnRejectedPromiseWhenPrimaryExecutorRejec $promise = $executor->query($query); $promise->cancel(); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $promise->then($this->expectCallableNever(), $this->expectCallableOnce()); } @@ -176,10 +180,10 @@ public function testCancelQueryShouldNotCauseGarbageReferencesWhenCancellingPrim $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $primary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $primary = $this->createMock(ExecutorInterface::class); $primary->expects($this->once())->method('query')->willReturn(new Promise(function () { }, function () { throw new \RuntimeException(); })); - $secondary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $secondary = $this->createMock(ExecutorInterface::class); $secondary->expects($this->never())->method('query'); $executor = new FallbackExecutor($primary, $secondary); @@ -203,10 +207,10 @@ public function testCancelQueryShouldNotCauseGarbageReferencesWhenCancellingSeco $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $primary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $primary->expects($this->once())->method('query')->willReturn(\React\Promise\reject(new \RuntimeException())); + $primary = $this->createMock(ExecutorInterface::class); + $primary->expects($this->once())->method('query')->willReturn(reject(new \RuntimeException())); - $secondary = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $secondary = $this->createMock(ExecutorInterface::class); $secondary->expects($this->once())->method('query')->willReturn(new Promise(function () { }, function () { throw new \RuntimeException(); })); $executor = new FallbackExecutor($primary, $secondary); diff --git a/tests/Query/HostsFileExecutorTest.php b/tests/Query/HostsFileExecutorTest.php index 2a1d818e..5bf8f0f5 100644 --- a/tests/Query/HostsFileExecutorTest.php +++ b/tests/Query/HostsFileExecutorTest.php @@ -2,10 +2,12 @@ namespace React\Tests\Dns\Query; -use React\Tests\Dns\TestCase; +use React\Dns\Config\HostsFile; +use React\Dns\Model\Message; +use React\Dns\Query\ExecutorInterface; use React\Dns\Query\HostsFileExecutor; use React\Dns\Query\Query; -use React\Dns\Model\Message; +use React\Tests\Dns\TestCase; class HostsFileExecutorTest extends TestCase { @@ -18,8 +20,8 @@ class HostsFileExecutorTest extends TestCase */ public function setUpMocks() { - $this->hosts = $this->getMockBuilder('React\Dns\Config\HostsFile')->disableOriginalConstructor()->getMock(); - $this->fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $this->hosts = $this->createMock(HostsFile::class); + $this->fallback = $this->createMock(ExecutorInterface::class); $this->executor = new HostsFileExecutor($this->hosts, $this->fallback); } @@ -33,7 +35,7 @@ public function testDoesNotTryToGetIpsForMxQuery() public function testFallsBackIfNoIpsWereFound() { - $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(array()); + $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn([]); $this->fallback->expects($this->once())->method('query'); $this->executor->query(new Query('google.com', Message::TYPE_A, Message::CLASS_IN)); @@ -41,7 +43,7 @@ public function testFallsBackIfNoIpsWereFound() public function testReturnsResponseMessageIfIpsWereFound() { - $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(array('127.0.0.1')); + $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(['127.0.0.1']); $this->fallback->expects($this->never())->method('query'); $ret = $this->executor->query(new Query('google.com', Message::TYPE_A, Message::CLASS_IN)); @@ -49,7 +51,7 @@ public function testReturnsResponseMessageIfIpsWereFound() public function testFallsBackIfNoIpv4Matches() { - $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(array('::1')); + $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(['::1']); $this->fallback->expects($this->once())->method('query'); $ret = $this->executor->query(new Query('google.com', Message::TYPE_A, Message::CLASS_IN)); @@ -57,7 +59,7 @@ public function testFallsBackIfNoIpv4Matches() public function testReturnsResponseMessageIfIpv6AddressesWereFound() { - $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(array('::1')); + $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(['::1']); $this->fallback->expects($this->never())->method('query'); $ret = $this->executor->query(new Query('google.com', Message::TYPE_AAAA, Message::CLASS_IN)); @@ -65,7 +67,7 @@ public function testReturnsResponseMessageIfIpv6AddressesWereFound() public function testFallsBackIfNoIpv6Matches() { - $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(array('127.0.0.1')); + $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(['127.0.0.1']); $this->fallback->expects($this->once())->method('query'); $ret = $this->executor->query(new Query('google.com', Message::TYPE_AAAA, Message::CLASS_IN)); @@ -73,7 +75,7 @@ public function testFallsBackIfNoIpv6Matches() public function testDoesReturnReverseIpv4Lookup() { - $this->hosts->expects($this->once())->method('getHostsForIp')->with('127.0.0.1')->willReturn(array('localhost')); + $this->hosts->expects($this->once())->method('getHostsForIp')->with('127.0.0.1')->willReturn(['localhost']); $this->fallback->expects($this->never())->method('query'); $this->executor->query(new Query('1.0.0.127.in-addr.arpa', Message::TYPE_PTR, Message::CLASS_IN)); @@ -81,7 +83,7 @@ public function testDoesReturnReverseIpv4Lookup() public function testFallsBackIfNoReverseIpv4Matches() { - $this->hosts->expects($this->once())->method('getHostsForIp')->with('127.0.0.1')->willReturn(array()); + $this->hosts->expects($this->once())->method('getHostsForIp')->with('127.0.0.1')->willReturn([]); $this->fallback->expects($this->once())->method('query'); $this->executor->query(new Query('1.0.0.127.in-addr.arpa', Message::TYPE_PTR, Message::CLASS_IN)); @@ -89,7 +91,7 @@ public function testFallsBackIfNoReverseIpv4Matches() public function testDoesReturnReverseIpv6Lookup() { - $this->hosts->expects($this->once())->method('getHostsForIp')->with('2a02:2e0:3fe:100::6')->willReturn(array('ip6-localhost')); + $this->hosts->expects($this->once())->method('getHostsForIp')->with('2a02:2e0:3fe:100::6')->willReturn(['ip6-localhost']); $this->fallback->expects($this->never())->method('query'); $this->executor->query(new Query('6.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.e.f.3.0.0.e.2.0.2.0.a.2.ip6.arpa', Message::TYPE_PTR, Message::CLASS_IN)); diff --git a/tests/Query/RetryExecutorTest.php b/tests/Query/RetryExecutorTest.php index 93b46d50..c7695c76 100644 --- a/tests/Query/RetryExecutorTest.php +++ b/tests/Query/RetryExecutorTest.php @@ -2,15 +2,18 @@ namespace React\Tests\Dns\Query; -use React\Tests\Dns\TestCase; -use React\Dns\Query\RetryExecutor; -use React\Dns\Query\Query; use React\Dns\Model\Message; -use React\Dns\Query\TimeoutException; use React\Dns\Model\Record; -use React\Promise; -use React\Promise\Deferred; use React\Dns\Query\CancellationException; +use React\Dns\Query\ExecutorInterface; +use React\Dns\Query\Query; +use React\Dns\Query\RetryExecutor; +use React\Dns\Query\TimeoutException; +use React\Promise\Deferred; +use React\Promise\PromiseInterface; +use React\Tests\Dns\TestCase; +use function React\Promise\reject; +use function React\Promise\resolve; class RetryExecutorTest extends TestCase { @@ -24,7 +27,7 @@ public function queryShouldDelegateToDecoratedExecutor() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnValue($this->expectPromiseOnce())); $retryExecutor = new RetryExecutor($executor, 2); @@ -45,13 +48,13 @@ public function queryShouldRetryQueryOnTimeout() $executor ->expects($this->exactly(2)) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->onConsecutiveCalls( $this->returnCallback(function ($query) { - return Promise\reject(new TimeoutException("timeout")); + return reject(new TimeoutException("timeout")); }), $this->returnCallback(function ($query) use ($response) { - return Promise\resolve($response); + return resolve($response); }) )); @@ -59,7 +62,7 @@ public function queryShouldRetryQueryOnTimeout() $callback ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('React\Dns\Model\Message')); + ->with($this->isInstanceOf(Message::class)); $errorback = $this->expectCallableNever(); @@ -79,9 +82,9 @@ public function queryShouldStopRetryingAfterSomeAttempts() $executor ->expects($this->exactly(3)) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) { - return Promise\reject(new TimeoutException("timeout")); + return reject(new TimeoutException("timeout")); })); $retryExecutor = new RetryExecutor($executor, 2); @@ -95,10 +98,10 @@ public function queryShouldStopRetryingAfterSomeAttempts() }); assert($exception instanceof \RuntimeException); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for igor.io (A) failed: too many retries', $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); - $this->assertInstanceOf('React\Dns\Query\TimeoutException', $exception->getPrevious()); + $this->assertInstanceOf(TimeoutException::class, $exception->getPrevious()); $this->assertNotEquals('', $exception->getTraceAsString()); } @@ -112,9 +115,9 @@ public function queryShouldForwardNonTimeoutErrors() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) { - return Promise\reject(new \Exception); + return reject(new \Exception); })); $callback = $this->expectCallableNever(); @@ -123,7 +126,7 @@ public function queryShouldForwardNonTimeoutErrors() $errorback ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Exception')); + ->with($this->isInstanceOf(\Exception::class)); $retryExecutor = new RetryExecutor($executor, 2); @@ -143,7 +146,7 @@ public function queryShouldCancelQueryOnCancel() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) use (&$cancelled) { $deferred = new Deferred(function ($resolve, $reject) use (&$cancelled) { ++$cancelled; @@ -179,7 +182,7 @@ public function queryShouldCancelSecondQueryOnCancel() $executor ->expects($this->exactly(2)) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->onConsecutiveCalls( $this->returnValue($deferred->promise()), $this->returnCallback(function ($query) use (&$cancelled) { @@ -221,8 +224,8 @@ public function queryShouldNotCauseGarbageReferencesOnSuccess() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) - ->willReturn(Promise\resolve($this->createStandardResponse())); + ->with($this->isInstanceOf(Query::class)) + ->willReturn(resolve($this->createStandardResponse())); $retryExecutor = new RetryExecutor($executor, 0); @@ -250,8 +253,8 @@ public function queryShouldNotCauseGarbageReferencesOnTimeoutErrors() $executor ->expects($this->any()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) - ->willReturn(Promise\reject(new TimeoutException("timeout"))); + ->with($this->isInstanceOf(Query::class)) + ->willReturn(reject(new TimeoutException("timeout"))); $retryExecutor = new RetryExecutor($executor, 0); @@ -285,7 +288,7 @@ public function queryShouldNotCauseGarbageReferencesOnCancellation() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->willReturn($deferred->promise()); $retryExecutor = new RetryExecutor($executor, 0); @@ -316,9 +319,9 @@ public function queryShouldNotCauseGarbageReferencesOnNonTimeoutErrors() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) { - return Promise\reject(new \Exception); + return reject(new \Exception); })); $retryExecutor = new RetryExecutor($executor, 2); @@ -341,19 +344,19 @@ protected function expectPromiseOnce($return = null) $mock ->expects($this->once()) ->method('then') - ->will($this->returnValue(Promise\resolve($return))); + ->will($this->returnValue(resolve($return))); return $mock; } protected function createExecutorMock() { - return $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + return $this->createMock(ExecutorInterface::class); } protected function createPromiseMock() { - return $this->getMockBuilder('React\Promise\PromiseInterface')->getMock(); + return $this->createMock(PromiseInterface::class); } protected function createStandardResponse() diff --git a/tests/Query/SelectiveTransportExecutorTest.php b/tests/Query/SelectiveTransportExecutorTest.php index c38dbeb2..5f439f3b 100644 --- a/tests/Query/SelectiveTransportExecutorTest.php +++ b/tests/Query/SelectiveTransportExecutorTest.php @@ -3,11 +3,14 @@ namespace React\Tests\Dns\Query; use React\Dns\Model\Message; +use React\Dns\Query\ExecutorInterface; use React\Dns\Query\Query; use React\Dns\Query\SelectiveTransportExecutor; use React\Promise\Deferred; use React\Promise\Promise; use React\Tests\Dns\TestCase; +use function React\Promise\reject; +use function React\Promise\resolve; class SelectiveTransportExecutorTest extends TestCase { @@ -20,8 +23,8 @@ class SelectiveTransportExecutorTest extends TestCase */ public function setUpMocks() { - $this->datagram = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); - $this->stream = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $this->datagram = $this->createMock(ExecutorInterface::class); + $this->stream = $this->createMock(ExecutorInterface::class); $this->executor = new SelectiveTransportExecutor($this->datagram, $this->stream); } @@ -36,7 +39,7 @@ public function testQueryResolvesWhenDatagramTransportResolvesWithoutUsingStream ->expects($this->once()) ->method('query') ->with($query) - ->willReturn(\React\Promise\resolve($response)); + ->willReturn(resolve($response)); $this->stream ->expects($this->never()) @@ -57,13 +60,13 @@ public function testQueryResolvesWhenStreamTransportResolvesAfterDatagramTranspo ->expects($this->once()) ->method('query') ->with($query) - ->willReturn(\React\Promise\reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90))); + ->willReturn(reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90))); $this->stream ->expects($this->once()) ->method('query') ->with($query) - ->willReturn(\React\Promise\resolve($response)); + ->willReturn(resolve($response)); $promise = $this->executor->query($query); @@ -78,7 +81,7 @@ public function testQueryRejectsWhenDatagramTransportRejectsWithRuntimeException ->expects($this->once()) ->method('query') ->with($query) - ->willReturn(\React\Promise\reject(new \RuntimeException())); + ->willReturn(reject(new \RuntimeException())); $this->stream ->expects($this->never()) @@ -97,13 +100,13 @@ public function testQueryRejectsWhenStreamTransportRejectsAfterDatagramTransport ->expects($this->once()) ->method('query') ->with($query) - ->willReturn(\React\Promise\reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90))); + ->willReturn(reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90))); $this->stream ->expects($this->once()) ->method('query') ->with($query) - ->willReturn(\React\Promise\reject(new \RuntimeException())); + ->willReturn(reject(new \RuntimeException())); $promise = $this->executor->query($query); @@ -216,13 +219,13 @@ public function testRejectedPromiseAfterTruncatedResponseShouldNotCreateAnyGarba ->expects($this->once()) ->method('query') ->with($query) - ->willReturn(\React\Promise\reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90))); + ->willReturn(reject(new \RuntimeException('', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90))); $this->stream ->expects($this->once()) ->method('query') ->with($query) - ->willReturn(\React\Promise\reject(new \RuntimeException())); + ->willReturn(reject(new \RuntimeException())); while (gc_collect_cycles()) { // collect all garbage cycles diff --git a/tests/Query/TcpTransportExecutorTest.php b/tests/Query/TcpTransportExecutorTest.php index 33dddacd..e65e347d 100644 --- a/tests/Query/TcpTransportExecutorTest.php +++ b/tests/Query/TcpTransportExecutorTest.php @@ -5,10 +5,17 @@ use React\Dns\Model\Message; use React\Dns\Protocol\BinaryDumper; use React\Dns\Protocol\Parser; +use React\Dns\Query\CancellationException; use React\Dns\Query\Query; use React\Dns\Query\TcpTransportExecutor; use React\EventLoop\Loop; +use React\EventLoop\LoopInterface; +use React\EventLoop\TimerInterface; +use React\Promise\PromiseInterface; use React\Tests\Dns\TestCase; +use function React\Async\await; +use function React\Promise\Timer\sleep; +use function React\Promise\Timer\timeout; class TcpTransportExecutorTest extends TestCase { @@ -19,7 +26,7 @@ class TcpTransportExecutorTest extends TestCase */ public function testCtorShouldAcceptNameserverAddresses($input, $expected) { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $executor = new TcpTransportExecutor($input, $loop); @@ -32,32 +39,30 @@ public function testCtorShouldAcceptNameserverAddresses($input, $expected) public static function provideDefaultPortProvider() { - return array( - array( - '8.8.8.8', - 'tcp://8.8.8.8:53' - ), - array( - '1.2.3.4:5', - 'tcp://1.2.3.4:5' - ), - array( - 'tcp://1.2.3.4', - 'tcp://1.2.3.4:53' - ), - array( - 'tcp://1.2.3.4:53', - 'tcp://1.2.3.4:53' - ), - array( - '::1', - 'tcp://[::1]:53' - ), - array( - '[::1]:53', - 'tcp://[::1]:53' - ) - ); + yield [ + '8.8.8.8', + 'tcp://8.8.8.8:53' + ]; + yield [ + '1.2.3.4:5', + 'tcp://1.2.3.4:5' + ]; + yield [ + 'tcp://1.2.3.4', + 'tcp://1.2.3.4:53' + ]; + yield [ + 'tcp://1.2.3.4:53', + 'tcp://1.2.3.4:53' + ]; + yield [ + '::1', + 'tcp://[::1]:53' + ]; + yield [ + '[::1]:53', + 'tcp://[::1]:53' + ]; } public function testCtorWithoutLoopShouldAssignDefaultLoop() @@ -68,36 +73,36 @@ public function testCtorWithoutLoopShouldAssignDefaultLoop() $ref->setAccessible(true); $loop = $ref->getValue($executor); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testCtorShouldThrowWhenNameserverAddressIsInvalid() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); new TcpTransportExecutor('///', $loop); } public function testCtorShouldThrowWhenNameserverAddressContainsHostname() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); new TcpTransportExecutor('localhost', $loop); } public function testCtorShouldThrowWhenNameserverSchemeIsInvalid() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); new TcpTransportExecutor('udp://1.2.3.4', $loop); } public function testQueryRejectsIfMessageExceedsMaximumMessageSize() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addWriteStream'); $executor = new TcpTransportExecutor('8.8.8.8:53', $loop); @@ -111,17 +116,13 @@ public function testQueryRejectsIfMessageExceedsMaximumMessageSize() }); /** @var \RuntimeException $exception */ - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for '. $query->name . ' (A) failed: Query too large for TCP transport', $exception->getMessage()); } public function testQueryRejectsIfServerConnectionFails() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('HHVM reports different error message for invalid addresses'); - } - - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addWriteStream'); $executor = new TcpTransportExecutor('::1', $loop); @@ -139,19 +140,19 @@ public function testQueryRejectsIfServerConnectionFails() }); /** @var \RuntimeException $exception */ - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for google.com (A) failed: Unable to connect to DNS server /// (Failed to parse address "///")', $exception->getMessage()); } public function testQueryRejectsOnCancellationWithoutClosingSocketButStartsIdleTimer() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->never())->method('removeWriteStream'); $loop->expects($this->never())->method('addReadStream'); $loop->expects($this->never())->method('removeReadStream'); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.001, $this->anything())->willReturn($timer); $loop->expects($this->never())->method('cancelTimer'); @@ -170,19 +171,19 @@ public function testQueryRejectsOnCancellationWithoutClosingSocketButStartsIdleT }); /** @var \React\Dns\Query\CancellationException $exception */ - $this->assertInstanceOf('React\Dns\Query\CancellationException', $exception); + $this->assertInstanceOf(CancellationException::class, $exception); $this->assertEquals('DNS query for google.com (A) has been cancelled', $exception->getMessage()); } public function testTriggerIdleTimerAfterQueryRejectedOnCancellationWillCloseSocket() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->once())->method('removeWriteStream'); $loop->expects($this->never())->method('addReadStream'); $loop->expects($this->never())->method('removeReadStream'); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); $timerCallback = null; $loop->expects($this->once())->method('addTimer')->with(0.001, $this->callback(function ($cb) use (&$timerCallback) { $timerCallback = $cb; @@ -199,7 +200,7 @@ public function testTriggerIdleTimerAfterQueryRejectedOnCancellationWillCloseSoc $promise = $executor->query($query); $promise->cancel(); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $promise->then(null, $this->expectCallableOnce()); // trigger idle timer @@ -209,7 +210,7 @@ public function testTriggerIdleTimerAfterQueryRejectedOnCancellationWillCloseSoc public function testQueryRejectsOnCancellationWithoutClosingSocketAndWithoutStartingIdleTimerWhenOtherQueryIsStillPending() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->never())->method('removeWriteStream'); $loop->expects($this->never())->method('addReadStream'); @@ -234,7 +235,7 @@ public function testQueryRejectsOnCancellationWithoutClosingSocketAndWithoutStar public function testQueryAgainAfterPreviousWasCancelledReusesExistingSocket() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->never())->method('removeWriteStream'); $loop->expects($this->never())->method('addReadStream'); @@ -266,20 +267,20 @@ function ($e) use (&$exception) { } ); - \React\Async\await(\React\Promise\Timer\sleep(0.01)); + await(sleep(0.01)); if ($exception === null) { - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); } /** @var \RuntimeException $exception */ - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for google.com (A) failed: Unable to connect to DNS server tcp://127.0.0.1:1 (Connection refused)', $exception->getMessage()); $this->assertEquals(defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111, $exception->getCode()); } public function testQueryStaysPendingWhenClientCanNotSendExcessiveMessageInOneChunk() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->once())->method('addReadStream'); $loop->expects($this->never())->method('removeWriteStream'); @@ -322,7 +323,7 @@ public function testQueryStaysPendingWhenClientCanNotSendExcessiveMessageInOneCh $this->markTestSkipped('Skipped on macOS due to possible race condition'); } - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->once())->method('addReadStream'); $loop->expects($this->never())->method('removeWriteStream'); @@ -356,7 +357,7 @@ public function testQueryStaysPendingWhenClientCanNotSendExcessiveMessageInOneCh public function testQueryRejectsWhenClientKeepsSendingWhenServerClosesSocketWithoutCallingCustomErrorHandler() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->once())->method('addReadStream'); $loop->expects($this->once())->method('removeWriteStream'); @@ -403,11 +404,11 @@ public function testQueryRejectsWhenClientKeepsSendingWhenServerClosesSocketWith restore_error_handler(); $this->assertNull($error); - // expect EPIPE (Broken pipe), except for macOS kernel race condition or legacy HHVM - $this->setExpectedException( - 'RuntimeException', + // expect EPIPE (Broken pipe), except for macOS kernel race condition + $this->expectException( + \RuntimeException::class, 'Unable to send query to DNS server tcp://' . $address . ' (', - defined('SOCKET_EPIPE') && !defined('HHVM_VERSION') ? (PHP_OS !== 'Darwin' || $writePending ? SOCKET_EPIPE : SOCKET_EPROTOTYPE) : null + defined('SOCKET_EPIPE') ? (PHP_OS !== 'Darwin' || $writePending ? SOCKET_EPIPE : SOCKET_EPROTOTYPE) : null ); throw $exception; } @@ -436,13 +437,13 @@ function ($e) use (&$exception) { } ); - \React\Async\await(\React\Promise\Timer\sleep(0.01)); + await(sleep(0.01)); if ($exception === null) { - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); } /** @var \RuntimeException $exception */ - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for google.com (A) failed: Connection to DNS server tcp://' . $address . ' lost', $exception->getMessage()); } @@ -474,7 +475,7 @@ function ($e) use (&$wait) { } ); - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); $this->assertTrue($wait); $this->assertNotNull($client); @@ -510,7 +511,7 @@ function ($e) use (&$wait) { } ); - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); $this->assertTrue($wait); $this->assertNotNull($client); @@ -545,13 +546,13 @@ function ($e) use (&$exception) { } ); - \React\Async\await(\React\Promise\Timer\sleep(0.01)); + await(sleep(0.01)); if ($exception === null) { - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); } /** @var \RuntimeException $exception */ - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for google.com (A) failed: Invalid message received from DNS server tcp://' . $address, $exception->getMessage()); } @@ -597,13 +598,13 @@ function ($e) use (&$exception) { } ); - \React\Async\await(\React\Promise\Timer\sleep(0.01)); + await(sleep(0.01)); if ($exception === null) { - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); } /** @var \RuntimeException $exception */ - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for google.com (A) failed: Invalid response message received from DNS server tcp://' . $address, $exception->getMessage()); } @@ -649,13 +650,13 @@ function ($e) use (&$exception) { } ); - \React\Async\await(\React\Promise\Timer\sleep(0.01)); + await(sleep(0.01)); if ($exception === null) { - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); } /** @var \RuntimeException $exception */ - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('DNS query for google.com (A) failed: Invalid response message received from DNS server tcp://' . $address, $exception->getMessage()); } @@ -684,14 +685,14 @@ public function testQueryResolvesIfServerSendsValidResponse() $query = new Query('google.com', Message::TYPE_A, Message::CLASS_IN); $promise = $executor->query($query); - $response = \React\Async\await(\React\Promise\Timer\timeout($promise, 0.2)); + $response = await(timeout($promise, 0.2)); - $this->assertInstanceOf('React\Dns\Model\Message', $response); + $this->assertInstanceOf(Message::class, $response); } public function testQueryRejectsIfSocketIsClosedAfterPreviousQueryThatWasStillPending() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->exactly(2))->method('addWriteStream'); $loop->expects($this->exactly(2))->method('removeWriteStream'); $loop->expects($this->once())->method('addReadStream'); @@ -725,7 +726,7 @@ public function testQueryRejectsIfSocketIsClosedAfterPreviousQueryThatWasStillPe public function testQueryResolvesIfServerSendsBackResponseMessageAndWillStartIdleTimer() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->once())->method('removeWriteStream'); $loop->expects($this->once())->method('addReadStream'); @@ -758,13 +759,13 @@ public function testQueryResolvesIfServerSendsBackResponseMessageAndWillStartIdl public function testQueryResolvesIfServerSendsBackResponseMessageAfterCancellingQueryAndWillStartIdleTimer() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->once())->method('removeWriteStream'); $loop->expects($this->once())->method('addReadStream'); $loop->expects($this->never())->method('removeReadStream'); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.001, $this->anything())->willReturn($timer); $loop->expects($this->never())->method('cancelTimer'); @@ -793,7 +794,7 @@ public function testQueryResolvesIfServerSendsBackResponseMessageAfterCancelling public function testQueryResolvesIfServerSendsBackResponseMessageAfterCancellingOtherQueryAndWillStartIdleTimer() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->once())->method('removeWriteStream'); $loop->expects($this->once())->method('addReadStream'); @@ -829,13 +830,13 @@ public function testQueryResolvesIfServerSendsBackResponseMessageAfterCancelling public function testTriggerIdleTimerAfterPreviousQueryResolvedWillCloseIdleSocketConnection() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->once())->method('removeWriteStream'); $loop->expects($this->once())->method('addReadStream'); $loop->expects($this->once())->method('removeReadStream'); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); $timerCallback = null; $loop->expects($this->once())->method('addTimer')->with(0.001, $this->callback(function ($cb) use (&$timerCallback) { $timerCallback = $cb; @@ -871,13 +872,13 @@ public function testTriggerIdleTimerAfterPreviousQueryResolvedWillCloseIdleSocke public function testClosingConnectionAfterPreviousQueryResolvedWillCancelIdleTimer() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream'); $loop->expects($this->once())->method('removeWriteStream'); $loop->expects($this->once())->method('addReadStream'); $loop->expects($this->once())->method('removeReadStream'); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.001, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); @@ -909,13 +910,13 @@ public function testClosingConnectionAfterPreviousQueryResolvedWillCancelIdleTim public function testQueryAgainAfterPreviousQueryResolvedWillReuseSocketAndCancelIdleTimer() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->exactly(2))->method('addWriteStream'); $loop->expects($this->once())->method('removeWriteStream'); $loop->expects($this->once())->method('addReadStream'); $loop->expects($this->never())->method('removeReadStream'); - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.001, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); diff --git a/tests/Query/TimeoutExecutorTest.php b/tests/Query/TimeoutExecutorTest.php index b7857783..96b355ce 100644 --- a/tests/Query/TimeoutExecutorTest.php +++ b/tests/Query/TimeoutExecutorTest.php @@ -4,12 +4,16 @@ use React\Dns\Model\Message; use React\Dns\Query\CancellationException; +use React\Dns\Query\ExecutorInterface; use React\Dns\Query\Query; use React\Dns\Query\TimeoutException; use React\Dns\Query\TimeoutExecutor; -use React\Promise; +use React\EventLoop\LoopInterface; +use React\EventLoop\TimerInterface; use React\Promise\Deferred; use React\Tests\Dns\TestCase; +use function React\Promise\reject; +use function React\Promise\resolve; class TimeoutExecutorTest extends TestCase { @@ -22,9 +26,9 @@ class TimeoutExecutorTest extends TestCase */ public function setUpExecutor() { - $this->wrapped = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + $this->wrapped = $this->createMock(ExecutorInterface::class); - $this->loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $this->loop = $this->createMock(LoopInterface::class); $this->executor = new TimeoutExecutor($this->wrapped, 5.0, $this->loop); } @@ -37,12 +41,12 @@ public function testCtorWithoutLoopShouldAssignDefaultLoop() $ref->setAccessible(true); $loop = $ref->getValue($executor); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testCancellingPromiseWillCancelWrapped() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); $this->loop->expects($this->once())->method('addTimer')->with(5.0, $this->anything())->willReturn($timer); $this->loop->expects($this->once())->method('cancelTimer')->with($timer); @@ -78,7 +82,7 @@ public function testResolvesPromiseWithoutStartingTimerWhenWrappedReturnsResolve $this->wrapped ->expects($this->once()) ->method('query') - ->willReturn(Promise\resolve('0.0.0.0')); + ->willReturn(resolve('0.0.0.0')); $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN); $promise = $this->executor->query($query); @@ -88,7 +92,7 @@ public function testResolvesPromiseWithoutStartingTimerWhenWrappedReturnsResolve public function testResolvesPromiseAfterCancellingTimerWhenWrappedReturnsPendingPromiseThatResolves() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); $this->loop->expects($this->once())->method('addTimer')->with(5.0, $this->anything())->willReturn($timer); $this->loop->expects($this->once())->method('cancelTimer')->with($timer); @@ -114,7 +118,7 @@ public function testRejectsPromiseWithoutStartingTimerWhenWrappedReturnsRejected $this->wrapped ->expects($this->once()) ->method('query') - ->willReturn(Promise\reject(new \RuntimeException())); + ->willReturn(reject(new \RuntimeException())); $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN); $promise = $this->executor->query($query); @@ -124,7 +128,7 @@ public function testRejectsPromiseWithoutStartingTimerWhenWrappedReturnsRejected public function testRejectsPromiseAfterCancellingTimerWhenWrappedReturnsPendingPromiseThatRejects() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); $this->loop->expects($this->once())->method('addTimer')->with(5.0, $this->anything())->willReturn($timer); $this->loop->expects($this->once())->method('cancelTimer')->with($timer); @@ -145,7 +149,7 @@ public function testRejectsPromiseAfterCancellingTimerWhenWrappedReturnsPendingP public function testRejectsPromiseAndCancelsPendingQueryWhenTimeoutTriggers() { $timerCallback = null; - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); $this->loop->expects($this->once())->method('addTimer')->with(5.0, $this->callback(function ($callback) use (&$timerCallback) { $timerCallback = $callback; return true; @@ -182,7 +186,7 @@ public function testRejectsPromiseAndCancelsPendingQueryWhenTimeoutTriggers() }); assert($exception instanceof TimeoutException); - $this->assertInstanceOf('React\Dns\Query\TimeoutException', $exception); + $this->assertInstanceOf(TimeoutException::class, $exception); $this->assertEquals('DNS query for igor.io (A) timed out' , $exception->getMessage()); } } diff --git a/tests/Query/UdpTransportExecutorTest.php b/tests/Query/UdpTransportExecutorTest.php index 3f04d9ad..41b27a9a 100644 --- a/tests/Query/UdpTransportExecutorTest.php +++ b/tests/Query/UdpTransportExecutorTest.php @@ -5,10 +5,16 @@ use React\Dns\Model\Message; use React\Dns\Protocol\BinaryDumper; use React\Dns\Protocol\Parser; +use React\Dns\Query\CancellationException; use React\Dns\Query\Query; use React\Dns\Query\UdpTransportExecutor; use React\EventLoop\Loop; +use React\EventLoop\LoopInterface; +use React\Promise\PromiseInterface; use React\Tests\Dns\TestCase; +use function React\Async\await; +use function React\Promise\Timer\sleep; +use function React\Promise\Timer\timeout; class UdpTransportExecutorTest extends TestCase { @@ -19,7 +25,7 @@ class UdpTransportExecutorTest extends TestCase */ public function testCtorShouldAcceptNameserverAddresses($input, $expected) { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $executor = new UdpTransportExecutor($input, $loop); @@ -32,32 +38,30 @@ public function testCtorShouldAcceptNameserverAddresses($input, $expected) public static function provideDefaultPortProvider() { - return array( - array( - '8.8.8.8', - 'udp://8.8.8.8:53' - ), - array( - '1.2.3.4:5', - 'udp://1.2.3.4:5' - ), - array( - 'udp://1.2.3.4', - 'udp://1.2.3.4:53' - ), - array( - 'udp://1.2.3.4:53', - 'udp://1.2.3.4:53' - ), - array( - '::1', - 'udp://[::1]:53' - ), - array( - '[::1]:53', - 'udp://[::1]:53' - ) - ); + yield [ + '8.8.8.8', + 'udp://8.8.8.8:53' + ]; + yield [ + '1.2.3.4:5', + 'udp://1.2.3.4:5' + ]; + yield [ + 'udp://1.2.3.4', + 'udp://1.2.3.4:53' + ]; + yield [ + 'udp://1.2.3.4:53', + 'udp://1.2.3.4:53' + ]; + yield [ + '::1', + 'udp://[::1]:53' + ]; + yield [ + '[::1]:53', + 'udp://[::1]:53' + ]; } public function testCtorWithoutLoopShouldAssignDefaultLoop() @@ -68,36 +72,36 @@ public function testCtorWithoutLoopShouldAssignDefaultLoop() $ref->setAccessible(true); $loop = $ref->getValue($executor); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testCtorShouldThrowWhenNameserverAddressIsInvalid() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); new UdpTransportExecutor('///', $loop); } public function testCtorShouldThrowWhenNameserverAddressContainsHostname() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); new UdpTransportExecutor('localhost', $loop); } public function testCtorShouldThrowWhenNameserverSchemeIsInvalid() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); new UdpTransportExecutor('tcp://1.2.3.4', $loop); } public function testQueryRejectsIfMessageExceedsUdpSize() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addReadStream'); $executor = new UdpTransportExecutor('8.8.8.8:53', $loop); @@ -105,15 +109,15 @@ public function testQueryRejectsIfMessageExceedsUdpSize() $query = new Query('google.' . str_repeat('.com', 200), Message::TYPE_A, Message::CLASS_IN); $promise = $executor->query($query); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $exception = null; $promise->then(null, function ($reason) use (&$exception) { $exception = $reason; }); - $this->setExpectedException( - 'RuntimeException', + $this->expectException( + \RuntimeException::class, 'DNS query for ' . $query->name . ' (A) failed: Query too large for UDP transport', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90 ); @@ -122,11 +126,7 @@ public function testQueryRejectsIfMessageExceedsUdpSize() public function testQueryRejectsIfServerConnectionFails() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('HHVM reports different error message for invalid addresses'); - } - - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addReadStream'); $executor = new UdpTransportExecutor('::1', $loop); @@ -138,15 +138,15 @@ public function testQueryRejectsIfServerConnectionFails() $query = new Query('google.com', Message::TYPE_A, Message::CLASS_IN); $promise = $executor->query($query); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $exception = null; $promise->then(null, function ($reason) use (&$exception) { $exception = $reason; }); - $this->setExpectedException( - 'RuntimeException', + $this->expectException( + \RuntimeException::class, 'DNS query for google.com (A) failed: Unable to connect to DNS server /// (Failed to parse address "///")' ); throw $exception; @@ -154,7 +154,7 @@ public function testQueryRejectsIfServerConnectionFails() public function testQueryRejectsIfSendToServerFailsAfterConnectionWithoutCallingCustomErrorHandler() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addReadStream'); $executor = new UdpTransportExecutor('0.0.0.0', $loop); @@ -175,7 +175,7 @@ public function testQueryRejectsIfSendToServerFailsAfterConnectionWithoutCalling restore_error_handler(); $this->assertNull($error); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $exception = null; $promise->then(null, function ($reason) use (&$exception) { @@ -183,8 +183,8 @@ public function testQueryRejectsIfSendToServerFailsAfterConnectionWithoutCalling }); // ECONNREFUSED (Connection refused) on Linux, EMSGSIZE (Message too long) on macOS - $this->setExpectedException( - 'RuntimeException', + $this->expectException( + \RuntimeException::class, 'DNS query for ' . $query->name . ' (A) failed: Unable to send query to DNS server udp://0.0.0.0:53 (' ); throw $exception; @@ -194,7 +194,7 @@ public function testQueryKeepsPendingIfReadFailsBecauseServerRefusesConnection() { $socket = null; $callback = null; - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream')->with($this->callback(function ($ref) use (&$socket) { $socket = $ref; return true; @@ -211,7 +211,7 @@ public function testQueryKeepsPendingIfReadFailsBecauseServerRefusesConnection() $this->assertNotNull($socket); $callback($socket); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); $pending = true; $promise->then(function () use (&$pending) { @@ -228,7 +228,7 @@ public function testQueryKeepsPendingIfReadFailsBecauseServerRefusesConnection() */ public function testQueryRejectsOnCancellation() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream'); $loop->expects($this->once())->method('removeReadStream'); @@ -244,7 +244,7 @@ public function testQueryRejectsOnCancellation() }); /** @var \React\Dns\Query\CancellationException $exception */ - $this->assertInstanceOf('React\Dns\Query\CancellationException', $exception); + $this->assertInstanceOf(CancellationException::class, $exception); $this->assertEquals('DNS query for google.com (A) has been cancelled', $exception->getMessage()); } @@ -272,7 +272,7 @@ function ($e) use (&$wait) { } ); - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); $this->assertTrue($wait); $promise->cancel(); @@ -309,7 +309,7 @@ function ($e) use (&$wait) { } ); - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); $this->assertTrue($wait); $promise->cancel(); @@ -340,12 +340,12 @@ public function testQueryRejectsIfServerSendsTruncatedResponse() $promise = $executor->query($query); - $this->setExpectedException( - 'RuntimeException', + $this->expectException( + \RuntimeException::class, 'DNS query for google.com (A) failed: The DNS server udp://' . $address . ' returned a truncated result for a UDP query', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90 ); - \React\Async\await(\React\Promise\Timer\timeout($promise, 0.1)); + await(timeout($promise, 0.1)); } public function testQueryResolvesIfServerSendsValidResponse() @@ -371,8 +371,8 @@ public function testQueryResolvesIfServerSendsValidResponse() $query = new Query('google.com', Message::TYPE_A, Message::CLASS_IN); $promise = $executor->query($query); - $response = \React\Async\await(\React\Promise\Timer\timeout($promise, 0.2)); + $response = await(timeout($promise, 0.2)); - $this->assertInstanceOf('React\Dns\Model\Message', $response); + $this->assertInstanceOf(Message::class, $response); } } diff --git a/tests/Resolver/FactoryTest.php b/tests/Resolver/FactoryTest.php index af758b51..c50f80f3 100644 --- a/tests/Resolver/FactoryTest.php +++ b/tests/Resolver/FactoryTest.php @@ -2,9 +2,21 @@ namespace React\Tests\Dns\Resolver; +use React\Cache\ArrayCache; +use React\Cache\CacheInterface; use React\Dns\Config\Config; +use React\Dns\Query\CachingExecutor; +use React\Dns\Query\CoopExecutor; use React\Dns\Query\HostsFileExecutor; +use React\Dns\Query\FallbackExecutor; +use React\Dns\Query\RetryExecutor; +use React\Dns\Query\SelectiveTransportExecutor; +use React\Dns\Query\TcpTransportExecutor; +use React\Dns\Query\TimeoutExecutor; +use React\Dns\Query\UdpTransportExecutor; use React\Dns\Resolver\Factory; +use React\Dns\Resolver\Resolver; +use React\EventLoop\LoopInterface; use React\Tests\Dns\TestCase; class FactoryTest extends TestCase @@ -15,34 +27,34 @@ public function createShouldCreateResolver() $factory = new Factory(); $resolver = $factory->create('8.8.8.8:53'); - $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver); + $this->assertInstanceOf(Resolver::class, $resolver); } /** @test */ public function createWithoutSchemeShouldCreateResolverWithSelectiveUdpAndTcpExecutorStack() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $factory = new Factory(); $resolver = $factory->create('8.8.8.8:53', $loop); - $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver); + $this->assertInstanceOf(Resolver::class, $resolver); $coopExecutor = $this->getResolverPrivateExecutor($resolver); - $this->assertInstanceOf('React\Dns\Query\CoopExecutor', $coopExecutor); + $this->assertInstanceOf(CoopExecutor::class, $coopExecutor); $ref = new \ReflectionProperty($coopExecutor, 'executor'); $ref->setAccessible(true); $retryExecutor = $ref->getValue($coopExecutor); - $this->assertInstanceOf('React\Dns\Query\RetryExecutor', $retryExecutor); + $this->assertInstanceOf(RetryExecutor::class, $retryExecutor); $ref = new \ReflectionProperty($retryExecutor, 'executor'); $ref->setAccessible(true); $selectiveExecutor = $ref->getValue($retryExecutor); - $this->assertInstanceOf('React\Dns\Query\SelectiveTransportExecutor', $selectiveExecutor); + $this->assertInstanceOf(SelectiveTransportExecutor::class, $selectiveExecutor); // udp below: @@ -50,13 +62,13 @@ public function createWithoutSchemeShouldCreateResolverWithSelectiveUdpAndTcpExe $ref->setAccessible(true); $timeoutExecutor = $ref->getValue($selectiveExecutor); - $this->assertInstanceOf('React\Dns\Query\TimeoutExecutor', $timeoutExecutor); + $this->assertInstanceOf(TimeoutExecutor::class, $timeoutExecutor); $ref = new \ReflectionProperty($timeoutExecutor, 'executor'); $ref->setAccessible(true); $udpExecutor = $ref->getValue($timeoutExecutor); - $this->assertInstanceOf('React\Dns\Query\UdpTransportExecutor', $udpExecutor); + $this->assertInstanceOf(UdpTransportExecutor::class, $udpExecutor); // tcp below: @@ -64,85 +76,85 @@ public function createWithoutSchemeShouldCreateResolverWithSelectiveUdpAndTcpExe $ref->setAccessible(true); $timeoutExecutor = $ref->getValue($selectiveExecutor); - $this->assertInstanceOf('React\Dns\Query\TimeoutExecutor', $timeoutExecutor); + $this->assertInstanceOf(TimeoutExecutor::class, $timeoutExecutor); $ref = new \ReflectionProperty($timeoutExecutor, 'executor'); $ref->setAccessible(true); $tcpExecutor = $ref->getValue($timeoutExecutor); - $this->assertInstanceOf('React\Dns\Query\TcpTransportExecutor', $tcpExecutor); + $this->assertInstanceOf(TcpTransportExecutor::class, $tcpExecutor); } /** @test */ public function createWithUdpSchemeShouldCreateResolverWithUdpExecutorStack() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $factory = new Factory(); $resolver = $factory->create('udp://8.8.8.8:53', $loop); - $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver); + $this->assertInstanceOf(Resolver::class, $resolver); $coopExecutor = $this->getResolverPrivateExecutor($resolver); - $this->assertInstanceOf('React\Dns\Query\CoopExecutor', $coopExecutor); + $this->assertInstanceOf(CoopExecutor::class, $coopExecutor); $ref = new \ReflectionProperty($coopExecutor, 'executor'); $ref->setAccessible(true); $retryExecutor = $ref->getValue($coopExecutor); - $this->assertInstanceOf('React\Dns\Query\RetryExecutor', $retryExecutor); + $this->assertInstanceOf(RetryExecutor::class, $retryExecutor); $ref = new \ReflectionProperty($retryExecutor, 'executor'); $ref->setAccessible(true); $timeoutExecutor = $ref->getValue($retryExecutor); - $this->assertInstanceOf('React\Dns\Query\TimeoutExecutor', $timeoutExecutor); + $this->assertInstanceOf(TimeoutExecutor::class, $timeoutExecutor); $ref = new \ReflectionProperty($timeoutExecutor, 'executor'); $ref->setAccessible(true); $udpExecutor = $ref->getValue($timeoutExecutor); - $this->assertInstanceOf('React\Dns\Query\UdpTransportExecutor', $udpExecutor); + $this->assertInstanceOf(UdpTransportExecutor::class, $udpExecutor); } /** @test */ public function createWithTcpSchemeShouldCreateResolverWithTcpExecutorStack() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $factory = new Factory(); $resolver = $factory->create('tcp://8.8.8.8:53', $loop); - $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver); + $this->assertInstanceOf(Resolver::class, $resolver); $coopExecutor = $this->getResolverPrivateExecutor($resolver); - $this->assertInstanceOf('React\Dns\Query\CoopExecutor', $coopExecutor); + $this->assertInstanceOf(CoopExecutor::class, $coopExecutor); $ref = new \ReflectionProperty($coopExecutor, 'executor'); $ref->setAccessible(true); $retryExecutor = $ref->getValue($coopExecutor); - $this->assertInstanceOf('React\Dns\Query\RetryExecutor', $retryExecutor); + $this->assertInstanceOf(RetryExecutor::class, $retryExecutor); $ref = new \ReflectionProperty($retryExecutor, 'executor'); $ref->setAccessible(true); $timeoutExecutor = $ref->getValue($retryExecutor); - $this->assertInstanceOf('React\Dns\Query\TimeoutExecutor', $timeoutExecutor); + $this->assertInstanceOf(TimeoutExecutor::class, $timeoutExecutor); $ref = new \ReflectionProperty($timeoutExecutor, 'executor'); $ref->setAccessible(true); $tcpExecutor = $ref->getValue($timeoutExecutor); - $this->assertInstanceOf('React\Dns\Query\TcpTransportExecutor', $tcpExecutor); + $this->assertInstanceOf(TcpTransportExecutor::class, $tcpExecutor); } /** @test */ public function createWithConfigWithTcpNameserverSchemeShouldCreateResolverWithTcpExecutorStack() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $config = new Config(); $config->nameservers[] = 'tcp://8.8.8.8:53'; @@ -150,35 +162,35 @@ public function createWithConfigWithTcpNameserverSchemeShouldCreateResolverWithT $factory = new Factory(); $resolver = $factory->create($config, $loop); - $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver); + $this->assertInstanceOf(Resolver::class, $resolver); $coopExecutor = $this->getResolverPrivateExecutor($resolver); - $this->assertInstanceOf('React\Dns\Query\CoopExecutor', $coopExecutor); + $this->assertInstanceOf(CoopExecutor::class, $coopExecutor); $ref = new \ReflectionProperty($coopExecutor, 'executor'); $ref->setAccessible(true); $retryExecutor = $ref->getValue($coopExecutor); - $this->assertInstanceOf('React\Dns\Query\RetryExecutor', $retryExecutor); + $this->assertInstanceOf(RetryExecutor::class, $retryExecutor); $ref = new \ReflectionProperty($retryExecutor, 'executor'); $ref->setAccessible(true); $timeoutExecutor = $ref->getValue($retryExecutor); - $this->assertInstanceOf('React\Dns\Query\TimeoutExecutor', $timeoutExecutor); + $this->assertInstanceOf(TimeoutExecutor::class, $timeoutExecutor); $ref = new \ReflectionProperty($timeoutExecutor, 'executor'); $ref->setAccessible(true); $tcpExecutor = $ref->getValue($timeoutExecutor); - $this->assertInstanceOf('React\Dns\Query\TcpTransportExecutor', $tcpExecutor); + $this->assertInstanceOf(TcpTransportExecutor::class, $tcpExecutor); } /** @test */ public function createWithConfigWithTwoNameserversWithTcpSchemeShouldCreateResolverWithFallbackExecutorStack() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $config = new Config(); $config->nameservers[] = 'tcp://8.8.8.8:53'; @@ -187,35 +199,35 @@ public function createWithConfigWithTwoNameserversWithTcpSchemeShouldCreateResol $factory = new Factory(); $resolver = $factory->create($config, $loop); - $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver); + $this->assertInstanceOf(Resolver::class, $resolver); $coopExecutor = $this->getResolverPrivateExecutor($resolver); - $this->assertInstanceOf('React\Dns\Query\CoopExecutor', $coopExecutor); + $this->assertInstanceOf(CoopExecutor::class, $coopExecutor); $ref = new \ReflectionProperty($coopExecutor, 'executor'); $ref->setAccessible(true); $retryExecutor = $ref->getValue($coopExecutor); - $this->assertInstanceOf('React\Dns\Query\RetryExecutor', $retryExecutor); + $this->assertInstanceOf(RetryExecutor::class, $retryExecutor); $ref = new \ReflectionProperty($retryExecutor, 'executor'); $ref->setAccessible(true); $fallbackExecutor = $ref->getValue($retryExecutor); - $this->assertInstanceOf('React\Dns\Query\FallbackExecutor', $fallbackExecutor); + $this->assertInstanceOf(FallbackExecutor::class, $fallbackExecutor); $ref = new \ReflectionProperty($fallbackExecutor, 'executor'); $ref->setAccessible(true); $timeoutExecutor = $ref->getValue($fallbackExecutor); - $this->assertInstanceOf('React\Dns\Query\TimeoutExecutor', $timeoutExecutor); + $this->assertInstanceOf(TimeoutExecutor::class, $timeoutExecutor); $ref = new \ReflectionProperty($timeoutExecutor, 'executor'); $ref->setAccessible(true); $tcpExecutor = $ref->getValue($timeoutExecutor); - $this->assertInstanceOf('React\Dns\Query\TcpTransportExecutor', $tcpExecutor); + $this->assertInstanceOf(TcpTransportExecutor::class, $tcpExecutor); $ref = new \ReflectionProperty($tcpExecutor, 'nameserver'); $ref->setAccessible(true); @@ -227,13 +239,13 @@ public function createWithConfigWithTwoNameserversWithTcpSchemeShouldCreateResol $ref->setAccessible(true); $timeoutExecutor = $ref->getValue($fallbackExecutor); - $this->assertInstanceOf('React\Dns\Query\TimeoutExecutor', $timeoutExecutor); + $this->assertInstanceOf(TimeoutExecutor::class, $timeoutExecutor); $ref = new \ReflectionProperty($timeoutExecutor, 'executor'); $ref->setAccessible(true); $tcpExecutor = $ref->getValue($timeoutExecutor); - $this->assertInstanceOf('React\Dns\Query\TcpTransportExecutor', $tcpExecutor); + $this->assertInstanceOf(TcpTransportExecutor::class, $tcpExecutor); $ref = new \ReflectionProperty($tcpExecutor, 'nameserver'); $ref->setAccessible(true); @@ -245,7 +257,7 @@ public function createWithConfigWithTwoNameserversWithTcpSchemeShouldCreateResol /** @test */ public function createWithConfigWithThreeNameserversWithTcpSchemeShouldCreateResolverWithNestedFallbackExecutorStack() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $config = new Config(); $config->nameservers[] = 'tcp://8.8.8.8:53'; @@ -255,35 +267,35 @@ public function createWithConfigWithThreeNameserversWithTcpSchemeShouldCreateRes $factory = new Factory(); $resolver = $factory->create($config, $loop); - $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver); + $this->assertInstanceOf(Resolver::class, $resolver); $coopExecutor = $this->getResolverPrivateExecutor($resolver); - $this->assertInstanceOf('React\Dns\Query\CoopExecutor', $coopExecutor); + $this->assertInstanceOf(CoopExecutor::class, $coopExecutor); $ref = new \ReflectionProperty($coopExecutor, 'executor'); $ref->setAccessible(true); $retryExecutor = $ref->getValue($coopExecutor); - $this->assertInstanceOf('React\Dns\Query\RetryExecutor', $retryExecutor); + $this->assertInstanceOf(RetryExecutor::class, $retryExecutor); $ref = new \ReflectionProperty($retryExecutor, 'executor'); $ref->setAccessible(true); $fallbackExecutor = $ref->getValue($retryExecutor); - $this->assertInstanceOf('React\Dns\Query\FallbackExecutor', $fallbackExecutor); + $this->assertInstanceOf(FallbackExecutor::class, $fallbackExecutor); $ref = new \ReflectionProperty($fallbackExecutor, 'executor'); $ref->setAccessible(true); $timeoutExecutor = $ref->getValue($fallbackExecutor); - $this->assertInstanceOf('React\Dns\Query\TimeoutExecutor', $timeoutExecutor); + $this->assertInstanceOf(TimeoutExecutor::class, $timeoutExecutor); $ref = new \ReflectionProperty($timeoutExecutor, 'executor'); $ref->setAccessible(true); $tcpExecutor = $ref->getValue($timeoutExecutor); - $this->assertInstanceOf('React\Dns\Query\TcpTransportExecutor', $tcpExecutor); + $this->assertInstanceOf(TcpTransportExecutor::class, $tcpExecutor); $ref = new \ReflectionProperty($tcpExecutor, 'nameserver'); $ref->setAccessible(true); @@ -295,19 +307,19 @@ public function createWithConfigWithThreeNameserversWithTcpSchemeShouldCreateRes $ref->setAccessible(true); $fallbackExecutor = $ref->getValue($fallbackExecutor); - $this->assertInstanceOf('React\Dns\Query\FallbackExecutor', $fallbackExecutor); + $this->assertInstanceOf(FallbackExecutor::class, $fallbackExecutor); $ref = new \ReflectionProperty($fallbackExecutor, 'executor'); $ref->setAccessible(true); $timeoutExecutor = $ref->getValue($fallbackExecutor); - $this->assertInstanceOf('React\Dns\Query\TimeoutExecutor', $timeoutExecutor); + $this->assertInstanceOf(TimeoutExecutor::class, $timeoutExecutor); $ref = new \ReflectionProperty($timeoutExecutor, 'executor'); $ref->setAccessible(true); $tcpExecutor = $ref->getValue($timeoutExecutor); - $this->assertInstanceOf('React\Dns\Query\TcpTransportExecutor', $tcpExecutor); + $this->assertInstanceOf(TcpTransportExecutor::class, $tcpExecutor); $ref = new \ReflectionProperty($tcpExecutor, 'nameserver'); $ref->setAccessible(true); @@ -319,13 +331,13 @@ public function createWithConfigWithThreeNameserversWithTcpSchemeShouldCreateRes $ref->setAccessible(true); $timeoutExecutor = $ref->getValue($fallbackExecutor); - $this->assertInstanceOf('React\Dns\Query\TimeoutExecutor', $timeoutExecutor); + $this->assertInstanceOf(TimeoutExecutor::class, $timeoutExecutor); $ref = new \ReflectionProperty($timeoutExecutor, 'executor'); $ref->setAccessible(true); $tcpExecutor = $ref->getValue($timeoutExecutor); - $this->assertInstanceOf('React\Dns\Query\TcpTransportExecutor', $tcpExecutor); + $this->assertInstanceOf(TcpTransportExecutor::class, $tcpExecutor); $ref = new \ReflectionProperty($tcpExecutor, 'nameserver'); $ref->setAccessible(true); @@ -337,36 +349,36 @@ public function createWithConfigWithThreeNameserversWithTcpSchemeShouldCreateRes /** @test */ public function createShouldThrowWhenNameserverIsInvalid() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $factory = new Factory(); - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $factory->create('///', $loop); } /** @test */ public function createShouldThrowWhenConfigHasNoNameservers() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $factory = new Factory(); - $this->setExpectedException('UnderflowException'); + $this->expectException(\UnderflowException::class); $factory->create(new Config(), $loop); } /** @test */ public function createShouldThrowWhenConfigHasInvalidNameserver() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $factory = new Factory(); $config = new Config(); $config->nameservers[] = '///'; - $this->setExpectedException('InvalidArgumentException'); + $this->expectException(\InvalidArgumentException::class); $factory->create($config, $loop); } @@ -376,25 +388,25 @@ public function createCachedShouldCreateResolverWithCachingExecutor() $factory = new Factory(); $resolver = $factory->createCached('8.8.8.8:53'); - $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver); + $this->assertInstanceOf(Resolver::class, $resolver); $executor = $this->getResolverPrivateExecutor($resolver); - $this->assertInstanceOf('React\Dns\Query\CachingExecutor', $executor); + $this->assertInstanceOf(CachingExecutor::class, $executor); $cache = $this->getCachingExecutorPrivateMemberValue($executor, 'cache'); - $this->assertInstanceOf('React\Cache\ArrayCache', $cache); + $this->assertInstanceOf(ArrayCache::class, $cache); } /** @test */ public function createCachedShouldCreateResolverWithCachingExecutorWithCustomCache() { - $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $cache = $this->createMock(CacheInterface::class); + $loop = $this->createMock(LoopInterface::class); $factory = new Factory(); $resolver = $factory->createCached('8.8.8.8:53', $loop, $cache); - $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver); + $this->assertInstanceOf(Resolver::class, $resolver); $executor = $this->getResolverPrivateExecutor($resolver); - $this->assertInstanceOf('React\Dns\Query\CachingExecutor', $executor); + $this->assertInstanceOf(CachingExecutor::class, $executor); $cacheProperty = $this->getCachingExecutorPrivateMemberValue($executor, 'cache'); $this->assertSame($cache, $cacheProperty); } @@ -405,7 +417,7 @@ private function getResolverPrivateExecutor($resolver) // extract underlying executor that may be wrapped in multiple layers of hosts file executors while ($executor instanceof HostsFileExecutor) { - $reflector = new \ReflectionProperty('React\Dns\Query\HostsFileExecutor', 'fallback'); + $reflector = new \ReflectionProperty(HostsFileExecutor::class, 'fallback'); $reflector->setAccessible(true); $executor = $reflector->getValue($executor); @@ -416,14 +428,14 @@ private function getResolverPrivateExecutor($resolver) private function getResolverPrivateMemberValue($resolver, $field) { - $reflector = new \ReflectionProperty('React\Dns\Resolver\Resolver', $field); + $reflector = new \ReflectionProperty(Resolver::class, $field); $reflector->setAccessible(true); return $reflector->getValue($resolver); } private function getCachingExecutorPrivateMemberValue($resolver, $field) { - $reflector = new \ReflectionProperty('React\Dns\Query\CachingExecutor', $field); + $reflector = new \ReflectionProperty(CachingExecutor::class, $field); $reflector->setAccessible(true); return $reflector->getValue($resolver); } diff --git a/tests/Resolver/ResolveAliasesTest.php b/tests/Resolver/ResolveAliasesTest.php index 98901be9..013aa048 100644 --- a/tests/Resolver/ResolveAliasesTest.php +++ b/tests/Resolver/ResolveAliasesTest.php @@ -2,10 +2,12 @@ namespace React\Tests\Dns\Resolver; -use React\Tests\Dns\TestCase; -use React\Dns\Resolver\Resolver; use React\Dns\Model\Message; use React\Dns\Model\Record; +use React\Dns\Query\ExecutorInterface; +use React\Dns\Resolver\Resolver; +use React\Tests\Dns\TestCase; +use function React\Promise\resolve; class ResolveAliasesTest extends TestCase { @@ -20,7 +22,7 @@ public function testResolveAliases(array $expectedAnswers, array $answers, $name } $executor = $this->createExecutorMock(); - $executor->expects($this->once())->method('query')->willReturn(\React\Promise\resolve($message)); + $executor->expects($this->once())->method('query')->willReturn(resolve($message)); $resolver = new Resolver($executor); @@ -31,67 +33,65 @@ public function testResolveAliases(array $expectedAnswers, array $answers, $name public function provideAliasedAnswers() { - return array( - array( - array('178.79.169.131'), - array( - new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), - ), - 'igor.io', - ), - array( - array('178.79.169.131', '178.79.169.132', '178.79.169.133'), - array( - new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), - new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.132'), - new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.133'), - ), - 'igor.io', - ), - array( - array('178.79.169.131'), - array( - new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), - new Record('foo.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), - new Record('bar.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), - ), - 'igor.io', - ), - array( - array('178.79.169.131'), - array( - new Record('igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'foo.igor.io'), - new Record('foo.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), - ), - 'igor.io', - ), - array( - array('178.79.169.131'), - array( - new Record('igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'foo.igor.io'), - new Record('foo.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'bar.igor.io'), - new Record('bar.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), - ), - 'igor.io', - ), - array( - array('178.79.169.131', '178.79.169.132', '178.79.169.133'), - array( - new Record('igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'foo.igor.io'), - new Record('foo.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'bar.igor.io'), - new Record('bar.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'baz.igor.io'), - new Record('bar.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'qux.igor.io'), - new Record('baz.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), - new Record('baz.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.132'), - new Record('qux.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.133'), - ), - 'igor.io', - ), - ); + yield [ + ['178.79.169.131'], + [ + new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), + ], + 'igor.io', + ]; + yield [ + ['178.79.169.131', '178.79.169.132', '178.79.169.133'], + [ + new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), + new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.132'), + new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.133'), + ], + 'igor.io', + ]; + yield [ + ['178.79.169.131'], + [ + new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), + new Record('foo.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), + new Record('bar.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), + ], + 'igor.io', + ]; + yield [ + ['178.79.169.131'], + [ + new Record('igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'foo.igor.io'), + new Record('foo.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), + ], + 'igor.io', + ]; + yield [ + ['178.79.169.131'], + [ + new Record('igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'foo.igor.io'), + new Record('foo.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'bar.igor.io'), + new Record('bar.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), + ], + 'igor.io', + ]; + yield [ + ['178.79.169.131', '178.79.169.132', '178.79.169.133'], + [ + new Record('igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'foo.igor.io'), + new Record('foo.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'bar.igor.io'), + new Record('bar.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'baz.igor.io'), + new Record('bar.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'qux.igor.io'), + new Record('baz.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'), + new Record('baz.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.132'), + new Record('qux.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.133'), + ], + 'igor.io', + ]; } private function createExecutorMock() { - return $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + return $this->createMock(ExecutorInterface::class); } } diff --git a/tests/Resolver/ResolverTest.php b/tests/Resolver/ResolverTest.php index 292d80d2..f1df1850 100644 --- a/tests/Resolver/ResolverTest.php +++ b/tests/Resolver/ResolverTest.php @@ -2,13 +2,14 @@ namespace React\Tests\Dns\Resolver; -use React\Dns\Resolver\Resolver; -use React\Dns\Query\Query; use React\Dns\Model\Message; use React\Dns\Model\Record; -use React\Promise; -use React\Tests\Dns\TestCase; +use React\Dns\Query\ExecutorInterface; +use React\Dns\Query\Query; use React\Dns\RecordNotFoundException; +use React\Dns\Resolver\Resolver; +use React\Tests\Dns\TestCase; +use function React\Promise\resolve; class ResolverTest extends TestCase { @@ -19,14 +20,14 @@ public function resolveShouldQueryARecords() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) { $response = new Message(); $response->qr = true; $response->questions[] = new Query($query->name, $query->type, $query->class); $response->answers[] = new Record($query->name, $query->type, $query->class, 3600, '178.79.169.131'); - return Promise\resolve($response); + return resolve($response); })); $resolver = new Resolver($executor); @@ -40,18 +41,18 @@ public function resolveAllShouldQueryGivenRecords() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) { $response = new Message(); $response->qr = true; $response->questions[] = new Query($query->name, $query->type, $query->class); $response->answers[] = new Record($query->name, $query->type, $query->class, 3600, '::1'); - return Promise\resolve($response); + return resolve($response); })); $resolver = new Resolver($executor); - $resolver->resolveAll('reactphp.org', Message::TYPE_AAAA)->then($this->expectCallableOnceWith(array('::1'))); + $resolver->resolveAll('reactphp.org', Message::TYPE_AAAA)->then($this->expectCallableOnceWith(['::1'])); } /** @test */ @@ -61,19 +62,19 @@ public function resolveAllShouldIgnoreRecordsWithOtherTypes() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) { $response = new Message(); $response->qr = true; $response->questions[] = new Query($query->name, $query->type, $query->class); - $response->answers[] = new Record($query->name, Message::TYPE_TXT, $query->class, 3600, array('ignored')); + $response->answers[] = new Record($query->name, Message::TYPE_TXT, $query->class, 3600, ['ignored']); $response->answers[] = new Record($query->name, $query->type, $query->class, 3600, '::1'); - return Promise\resolve($response); + return resolve($response); })); $resolver = new Resolver($executor); - $resolver->resolveAll('reactphp.org', Message::TYPE_AAAA)->then($this->expectCallableOnceWith(array('::1'))); + $resolver->resolveAll('reactphp.org', Message::TYPE_AAAA)->then($this->expectCallableOnceWith(['::1'])); } /** @test */ @@ -83,7 +84,7 @@ public function resolveAllShouldReturnMultipleValuesForAlias() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) { $response = new Message(); $response->qr = true; @@ -92,12 +93,12 @@ public function resolveAllShouldReturnMultipleValuesForAlias() $response->answers[] = new Record('example.com', $query->type, $query->class, 3600, '::1'); $response->answers[] = new Record('example.com', $query->type, $query->class, 3600, '::2'); - return Promise\resolve($response); + return resolve($response); })); $resolver = new Resolver($executor); $resolver->resolveAll('reactphp.org', Message::TYPE_AAAA)->then( - $this->expectCallableOnceWith($this->equalTo(array('::1', '::2'))) + $this->expectCallableOnceWith($this->equalTo(['::1', '::2'])) ); } @@ -108,14 +109,14 @@ public function resolveShouldQueryARecordsAndIgnoreCase() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) { $response = new Message(); $response->qr = true; $response->questions[] = new Query('Blog.wyrihaximus.net', $query->type, $query->class); $response->answers[] = new Record('Blog.wyrihaximus.net', $query->type, $query->class, 3600, '178.79.169.131'); - return Promise\resolve($response); + return resolve($response); })); $resolver = new Resolver($executor); @@ -129,17 +130,17 @@ public function resolveShouldFilterByName() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) { $response = new Message(); $response->qr = true; $response->questions[] = new Query($query->name, $query->type, $query->class); $response->answers[] = new Record('foo.bar', $query->type, $query->class, 3600, '178.79.169.131'); - return Promise\resolve($response); + return resolve($response); })); - $errback = $this->expectCallableOnceWith($this->isInstanceOf('React\Dns\RecordNotFoundException')); + $errback = $this->expectCallableOnceWith($this->isInstanceOf(RecordNotFoundException::class)); $resolver = new Resolver($executor); $resolver->resolve('igor.io')->then($this->expectCallableNever(), $errback); @@ -154,13 +155,13 @@ public function resolveWithNoAnswersShouldCallErrbackIfGiven() $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) { $response = new Message(); $response->qr = true; $response->questions[] = new Query($query->name, $query->type, $query->class); - return Promise\resolve($response); + return resolve($response); })); $errback = $this->expectCallableOnceWith($this->callback(function ($param) { @@ -173,32 +174,30 @@ public function resolveWithNoAnswersShouldCallErrbackIfGiven() public function provideRcodeErrors() { - return array( - array( - Message::RCODE_FORMAT_ERROR, - 'DNS query for example.com (A) returned an error response (Format Error)', - ), - array( - Message::RCODE_SERVER_FAILURE, - 'DNS query for example.com (A) returned an error response (Server Failure)', - ), - array( - Message::RCODE_NAME_ERROR, - 'DNS query for example.com (A) returned an error response (Non-Existent Domain / NXDOMAIN)' - ), - array( - Message::RCODE_NOT_IMPLEMENTED, - 'DNS query for example.com (A) returned an error response (Not Implemented)' - ), - array( - Message::RCODE_REFUSED, - 'DNS query for example.com (A) returned an error response (Refused)' - ), - array( - 99, - 'DNS query for example.com (A) returned an error response (Unknown error response code 99)' - ) - ); + yield [ + Message::RCODE_FORMAT_ERROR, + 'DNS query for example.com (A) returned an error response (Format Error)', + ]; + yield [ + Message::RCODE_SERVER_FAILURE, + 'DNS query for example.com (A) returned an error response (Server Failure)', + ]; + yield [ + Message::RCODE_NAME_ERROR, + 'DNS query for example.com (A) returned an error response (Non-Existent Domain / NXDOMAIN)' + ]; + yield [ + Message::RCODE_NOT_IMPLEMENTED, + 'DNS query for example.com (A) returned an error response (Not Implemented)' + ]; + yield [ + Message::RCODE_REFUSED, + 'DNS query for example.com (A) returned an error response (Refused)' + ]; + yield [ + 99, + 'DNS query for example.com (A) returned an error response (Unknown error response code 99)' + ]; } /** @@ -211,14 +210,14 @@ public function resolveWithRcodeErrorShouldCallErrbackIfGiven($code, $expectedMe $executor ->expects($this->once()) ->method('query') - ->with($this->isInstanceOf('React\Dns\Query\Query')) + ->with($this->isInstanceOf(Query::class)) ->will($this->returnCallback(function ($query) use ($code) { $response = new Message(); $response->qr = true; $response->rcode = $code; $response->questions[] = new Query($query->name, $query->type, $query->class); - return Promise\resolve($response); + return resolve($response); })); $errback = $this->expectCallableOnceWith($this->callback(function ($param) use ($code, $expectedMessage) { @@ -231,6 +230,6 @@ public function resolveWithRcodeErrorShouldCallErrbackIfGiven($code, $expectedMe private function createExecutorMock() { - return $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock(); + return $this->createMock(ExecutorInterface::class); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 6ea467e6..23bd860e 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -39,29 +39,13 @@ protected function expectCallableNever() protected function createCallableMock() { - if (method_exists('PHPUnit\Framework\MockObject\MockBuilder', 'addMethods')) { + $builder = $this->getMockBuilder(\stdClass::class); + if (method_exists($builder, 'addMethods')) { // PHPUnit 9+ - return $this->getMockBuilder('stdClass')->addMethods(array('__invoke'))->getMock(); + return $builder->addMethods(['__invoke'])->getMock(); } else { - // legacy PHPUnit 4 - PHPUnit 9 - return $this->getMockBuilder('stdClass')->setMethods(array('__invoke'))->getMock(); + // legacy PHPUnit + return $builder->setMethods(['__invoke'])->getMock(); } } - - public function setExpectedException($exception, $exceptionMessage = '', $exceptionCode = null) - { - if (method_exists($this, 'expectException')) { - // PHPUnit 5 - $this->expectException($exception); - if ($exceptionMessage !== '') { - $this->expectExceptionMessage($exceptionMessage); - } - if ($exceptionCode !== null) { - $this->expectExceptionCode($exceptionCode); - } - } else { - // legacy PHPUnit 4 - parent::setExpectedException($exception, $exceptionMessage, $exceptionCode); - } - } }