[PhpUnitBridge] Mock DNS functions
This commit is contained in:
parent
f29d46f29b
commit
0b31285ee0
@ -74,7 +74,7 @@ class ClockMock
|
||||
$self = get_called_class();
|
||||
|
||||
$mockedNs = array(substr($class, 0, strrpos($class, '\\')));
|
||||
if (strpos($class, '\\Tests\\')) {
|
||||
if (0 < strpos($class, '\\Tests\\')) {
|
||||
$ns = str_replace('\\Tests\\', '\\', $class);
|
||||
$mockedNs[] = substr($ns, 0, strrpos($ns, '\\'));
|
||||
}
|
||||
|
224
src/Symfony/Bridge/PhpUnit/DnsMock.php
Normal file
224
src/Symfony/Bridge/PhpUnit/DnsMock.php
Normal file
@ -0,0 +1,224 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\PhpUnit;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class DnsMock
|
||||
{
|
||||
private static $hosts = array();
|
||||
private static $dnsTypes = array(
|
||||
'A' => DNS_A,
|
||||
'MX' => DNS_MX,
|
||||
'NS' => DNS_NS,
|
||||
'SOA' => DNS_SOA,
|
||||
'PTR' => DNS_PTR,
|
||||
'CNAME' => DNS_CNAME,
|
||||
'AAAA' => DNS_AAAA,
|
||||
'A6' => DNS_A6,
|
||||
'SRV' => DNS_SRV,
|
||||
'NAPTR' => DNS_NAPTR,
|
||||
'TXT' => DNS_TXT,
|
||||
'HINFO' => DNS_HINFO,
|
||||
);
|
||||
|
||||
/**
|
||||
* Configures the mock values for DNS queries.
|
||||
*
|
||||
* @param array $hosts Mocked hosts as keys, arrays of DNS records as returned by dns_get_record() as values.
|
||||
*/
|
||||
public static function withMockedHosts(array $hosts)
|
||||
{
|
||||
self::$hosts = $hosts;
|
||||
}
|
||||
|
||||
public static function checkdnsrr($hostname, $type = 'MX')
|
||||
{
|
||||
if (!self::$hosts) {
|
||||
return \checkdnsrr($hostname, $type);
|
||||
}
|
||||
if (isset(self::$hosts[$hostname])) {
|
||||
$type = strtoupper($type);
|
||||
|
||||
foreach (self::$hosts[$hostname] as $record) {
|
||||
if ($record['type'] === $type) {
|
||||
return true;
|
||||
}
|
||||
if ('ANY' === $type && isset(self::$dnsTypes[$record['type']]) && 'HINFO' !== $record['type']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getmxrr($hostname, &$mxhosts, &$weight = null)
|
||||
{
|
||||
if (!self::$hosts) {
|
||||
return \getmxrr($hostname, $mxhosts, $weight);
|
||||
}
|
||||
$mxhosts = $weight = array();
|
||||
|
||||
if (isset(self::$hosts[$hostname])) {
|
||||
foreach (self::$hosts[$hostname] as $record) {
|
||||
if ('MX' === $record['type']) {
|
||||
$mxhosts[] = $record['host'];
|
||||
$weight[] = $record['pri'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (bool) $mxhosts;
|
||||
}
|
||||
|
||||
public static function gethostbyaddr($ipAddress)
|
||||
{
|
||||
if (!self::$hosts) {
|
||||
return \gethostbyaddr($ipAddress);
|
||||
}
|
||||
foreach (self::$hosts as $hostname => $records) {
|
||||
foreach ($records as $record) {
|
||||
if ('A' === $record['type'] && $ipAddress === $record['ip']) {
|
||||
return $hostname;
|
||||
}
|
||||
if ('AAAA' === $record['type'] && $ipAddress === $record['ipv6']) {
|
||||
return $hostname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ipAddress;
|
||||
}
|
||||
|
||||
public static function gethostbyname($hostname)
|
||||
{
|
||||
if (!self::$hosts) {
|
||||
return \gethostbyname($hostname);
|
||||
}
|
||||
if (isset(self::$hosts[$hostname])) {
|
||||
foreach (self::$hosts[$hostname] as $record) {
|
||||
if ('A' === $record['type']) {
|
||||
return $record['ip'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $hostname;
|
||||
}
|
||||
|
||||
public static function gethostbynamel($hostname)
|
||||
{
|
||||
if (!self::$hosts) {
|
||||
return \gethostbynamel($hostname);
|
||||
}
|
||||
$ips = false;
|
||||
|
||||
if (isset(self::$hosts[$hostname])) {
|
||||
$ips = array();
|
||||
|
||||
foreach (self::$hosts[$hostname] as $record) {
|
||||
if ('A' === $record['type']) {
|
||||
$ips[] = $record['ip'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ips;
|
||||
}
|
||||
|
||||
public static function dns_get_record($hostname, $type = DNS_ANY, &$authns = null, &$addtl = null, $raw = false)
|
||||
{
|
||||
if (!self::$hosts) {
|
||||
return \dns_get_record($hostname, $type, $authns, $addtl, $raw);
|
||||
}
|
||||
|
||||
$records = false;
|
||||
|
||||
if (isset(self::$hosts[$hostname])) {
|
||||
if (DNS_ANY === $type) {
|
||||
$type = DNS_ALL;
|
||||
}
|
||||
$records = array();
|
||||
|
||||
foreach (self::$hosts[$hostname] as $record) {
|
||||
if (isset(self::$dnsTypes[$record['type']]) && (self::$dnsTypes[$record['type']] & $type)) {
|
||||
$records[] = array_merge(array('host' => $hostname, 'class' => 'IN', 'ttl' => 1, 'type' => $record['type']), $record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $records;
|
||||
}
|
||||
|
||||
public static function register($class)
|
||||
{
|
||||
$self = get_called_class();
|
||||
|
||||
$mockedNs = array(substr($class, 0, strrpos($class, '\\')));
|
||||
if (0 < strpos($class, '\\Tests\\')) {
|
||||
$ns = str_replace('\\Tests\\', '\\', $class);
|
||||
$mockedNs[] = substr($ns, 0, strrpos($ns, '\\'));
|
||||
}
|
||||
foreach ($mockedNs as $ns) {
|
||||
if (function_exists($ns.'\checkdnsrr')) {
|
||||
continue;
|
||||
}
|
||||
eval(<<<EOPHP
|
||||
namespace $ns;
|
||||
|
||||
function checkdnsrr(\$host, \$type = 'MX')
|
||||
{
|
||||
return \\$self::checkdnsrr(\$host, \$type);
|
||||
}
|
||||
|
||||
function dns_check_record(\$host, \$type = 'MX')
|
||||
{
|
||||
return \\$self::checkdnsrr(\$host, \$type);
|
||||
}
|
||||
|
||||
function getmxrr(\$hostname, &\$mxhosts, &\$weight = null)
|
||||
{
|
||||
return \\$self::getmxrr(\$hostname, \$mxhosts, \$weight);
|
||||
}
|
||||
|
||||
function dns_get_mx(\$hostname, &\$mxhosts, &\$weight = null)
|
||||
{
|
||||
return \\$self::getmxrr(\$hostname, \$mxhosts, \$weight);
|
||||
}
|
||||
|
||||
function gethostbyaddr(\$ipAddress)
|
||||
{
|
||||
return \\$self::gethostbyaddr(\$ipAddress);
|
||||
}
|
||||
|
||||
function gethostbyname(\$hostname)
|
||||
{
|
||||
return \\$self::gethostbyname(\$hostname);
|
||||
}
|
||||
|
||||
function gethostbynamel(\$hostname)
|
||||
{
|
||||
return \\$self::gethostbynamel(\$hostname);
|
||||
}
|
||||
|
||||
function dns_get_record(\$hostname, \$type = DNS_ANY, &\$authns = null, &\$addtl = null, \$raw = false)
|
||||
{
|
||||
return \\$self::dns_get_record(\$hostname, \$type, \$authns, \$addtl, \$raw);
|
||||
}
|
||||
|
||||
EOPHP
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -26,17 +26,39 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
|
||||
private $wasSkipped = array();
|
||||
private $isSkipped = array();
|
||||
|
||||
public function __construct(array $extraClockMockedNamespaces = array())
|
||||
/**
|
||||
* @param array $mockedNamespaces List of namespaces, indexed by mocked features (time-sensitive or dns-sensitive).
|
||||
*/
|
||||
public function __construct(array $mockedNamespaces = array())
|
||||
{
|
||||
if ($extraClockMockedNamespaces) {
|
||||
foreach ($extraClockMockedNamespaces as $ns) {
|
||||
ClockMock::register($ns.'\DummyClass');
|
||||
$warn = false;
|
||||
foreach ($mockedNamespaces as $type => $namespaces) {
|
||||
if (!is_array($namespaces)) {
|
||||
$namespaces = array($namespaces);
|
||||
}
|
||||
if (is_int($type)) {
|
||||
// @deprecated BC with v2.8 to v3.0
|
||||
$type = 'time-sensitive';
|
||||
$warn = true;
|
||||
}
|
||||
if ('time-sensitive' === $type) {
|
||||
foreach ($namespaces as $ns) {
|
||||
ClockMock::register($ns.'\DummyClass');
|
||||
}
|
||||
}
|
||||
if ('dns-sensitive' === $type) {
|
||||
foreach ($namespaces as $ns) {
|
||||
DnsMock::register($ns.'\DummyClass');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self::$globallyEnabled) {
|
||||
$this->state = -2;
|
||||
} else {
|
||||
self::$globallyEnabled = true;
|
||||
if ($warn) {
|
||||
echo "Clock-mocked namespaces for SymfonyTestsListener need to be nested in a \"time-sensitive\" key. This will be enforced in Symfony 4.0.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,10 +97,16 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
|
||||
for ($i = 0; isset($testSuites[$i]); ++$i) {
|
||||
foreach ($testSuites[$i]->tests() as $test) {
|
||||
if ($test instanceof \PHPUnit_Framework_TestSuite) {
|
||||
if (class_exists($test->getName(), false) && in_array('time-sensitive', \PHPUnit_Util_Test::getGroups($test->getName()), true)) {
|
||||
ClockMock::register($test->getName());
|
||||
} else {
|
||||
if (!class_exists($test->getName(), false)) {
|
||||
$testSuites[] = $test;
|
||||
continue;
|
||||
}
|
||||
$groups = \PHPUnit_Util_Test::getGroups($test->getName());
|
||||
if (in_array('time-sensitive', $groups, true)) {
|
||||
ClockMock::register($test->getName());
|
||||
}
|
||||
if (in_array('dns-sensitive', $groups, true)) {
|
||||
DnsMock::register($test->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,6 +148,9 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
|
||||
ClockMock::register(get_class($test));
|
||||
ClockMock::withClockMock(true);
|
||||
}
|
||||
if (in_array('dns-sensitive', $groups, true)) {
|
||||
DnsMock::register(get_class($test));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,6 +162,9 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
|
||||
if (in_array('time-sensitive', $groups, true)) {
|
||||
ClockMock::withClockMock(false);
|
||||
}
|
||||
if (in_array('dns-sensitive', $groups, true)) {
|
||||
DnsMock::withMockedHosts(array());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
149
src/Symfony/Bridge/PhpUnit/Tests/DnsMockTest.php
Normal file
149
src/Symfony/Bridge/PhpUnit/Tests/DnsMockTest.php
Normal file
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\PhpUnit\Tests;
|
||||
|
||||
use Symfony\Bridge\PhpUnit\DnsMock;
|
||||
|
||||
require_once __DIR__.'/../DnsMock.php';
|
||||
|
||||
class DnsMockTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected function tearDown()
|
||||
{
|
||||
DnsMock::withMockedHosts(array());
|
||||
}
|
||||
|
||||
public function testCheckdnsrr()
|
||||
{
|
||||
DnsMock::withMockedHosts(array('example.com' => array(array('type' => 'MX'))));
|
||||
$this->assertTrue(DnsMock::checkdnsrr('example.com'));
|
||||
|
||||
DnsMock::withMockedHosts(array('example.com' => array(array('type' => 'A'))));
|
||||
$this->assertFalse(DnsMock::checkdnsrr('example.com'));
|
||||
$this->assertTrue(DnsMock::checkdnsrr('example.com', 'a'));
|
||||
$this->assertTrue(DnsMock::checkdnsrr('example.com', 'any'));
|
||||
$this->assertFalse(DnsMock::checkdnsrr('foobar.com', 'ANY'));
|
||||
}
|
||||
|
||||
public function testGetmxrr()
|
||||
{
|
||||
DnsMock::withMockedHosts(array(
|
||||
'example.com' => array(array(
|
||||
'type' => 'MX',
|
||||
'host' => 'mx.example.com',
|
||||
'pri' => 10,
|
||||
)),
|
||||
));
|
||||
|
||||
$this->assertFalse(DnsMock::getmxrr('foobar.com', $mxhosts, $weight));
|
||||
$this->assertTrue(DnsMock::getmxrr('example.com', $mxhosts, $weight));
|
||||
$this->assertSame(array('mx.example.com'), $mxhosts);
|
||||
$this->assertSame(array(10), $weight);
|
||||
}
|
||||
|
||||
public function testGethostbyaddr()
|
||||
{
|
||||
DnsMock::withMockedHosts(array(
|
||||
'example.com' => array(
|
||||
array(
|
||||
'type' => 'A',
|
||||
'ip' => '1.2.3.4',
|
||||
),
|
||||
array(
|
||||
'type' => 'AAAA',
|
||||
'ipv6' => '::12',
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertSame('::21', DnsMock::gethostbyaddr('::21'));
|
||||
$this->assertSame('example.com', DnsMock::gethostbyaddr('::12'));
|
||||
$this->assertSame('example.com', DnsMock::gethostbyaddr('1.2.3.4'));
|
||||
}
|
||||
|
||||
public function testGethostbyname()
|
||||
{
|
||||
DnsMock::withMockedHosts(array(
|
||||
'example.com' => array(
|
||||
array(
|
||||
'type' => 'AAAA',
|
||||
'ipv6' => '::12',
|
||||
),
|
||||
array(
|
||||
'type' => 'A',
|
||||
'ip' => '1.2.3.4',
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertSame('foobar.com', DnsMock::gethostbyname('foobar.com'));
|
||||
$this->assertSame('1.2.3.4', DnsMock::gethostbyname('example.com'));
|
||||
}
|
||||
|
||||
public function testGethostbynamel()
|
||||
{
|
||||
DnsMock::withMockedHosts(array(
|
||||
'example.com' => array(
|
||||
array(
|
||||
'type' => 'A',
|
||||
'ip' => '1.2.3.4',
|
||||
),
|
||||
array(
|
||||
'type' => 'A',
|
||||
'ip' => '2.3.4.5',
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertFalse(DnsMock::gethostbynamel('foobar.com'));
|
||||
$this->assertSame(array('1.2.3.4', '2.3.4.5'), DnsMock::gethostbynamel('example.com'));
|
||||
}
|
||||
|
||||
public function testDnsGetRecord()
|
||||
{
|
||||
DnsMock::withMockedHosts(array(
|
||||
'example.com' => array(
|
||||
array(
|
||||
'type' => 'A',
|
||||
'ip' => '1.2.3.4',
|
||||
),
|
||||
array(
|
||||
'type' => 'PTR',
|
||||
'ip' => '2.3.4.5',
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
$records = array(
|
||||
array(
|
||||
'host' => 'example.com',
|
||||
'class' => 'IN',
|
||||
'ttl' => 1,
|
||||
'type' => 'A',
|
||||
'ip' => '1.2.3.4',
|
||||
),
|
||||
$ptr = array(
|
||||
'host' => 'example.com',
|
||||
'class' => 'IN',
|
||||
'ttl' => 1,
|
||||
'type' => 'PTR',
|
||||
'ip' => '2.3.4.5',
|
||||
),
|
||||
);
|
||||
|
||||
$this->assertFalse(DnsMock::dns_get_record('foobar.com'));
|
||||
$this->assertSame($records, DnsMock::dns_get_record('example.com'));
|
||||
$this->assertSame($records, DnsMock::dns_get_record('example.com', DNS_ALL));
|
||||
$this->assertSame($records, DnsMock::dns_get_record('example.com', DNS_A | DNS_PTR));
|
||||
$this->assertSame(array($ptr), DnsMock::dns_get_record('example.com', DNS_PTR));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user