init
This commit is contained in:
47
vendor/react/socket/tests/ConnectionTest.php
vendored
Executable file
47
vendor/react/socket/tests/ConnectionTest.php
vendored
Executable file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\Socket\Connection;
|
||||
|
||||
class ConnectionTest extends TestCase
|
||||
{
|
||||
public function testCloseConnectionWillCloseSocketResource()
|
||||
{
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$this->markTestSkipped('HHVM does not support socket operation on test memory stream');
|
||||
}
|
||||
|
||||
$resource = fopen('php://memory', 'r+');
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$connection = new Connection($resource, $loop);
|
||||
$connection->close();
|
||||
|
||||
$this->assertFalse(is_resource($resource));
|
||||
}
|
||||
|
||||
public function testCloseConnectionWillRemoveResourceFromLoopBeforeClosingResource()
|
||||
{
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$this->markTestSkipped('HHVM does not support socket operation on test memory stream');
|
||||
}
|
||||
|
||||
$resource = fopen('php://memory', 'r+');
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('addWriteStream')->with($resource);
|
||||
|
||||
$onRemove = null;
|
||||
$loop->expects($this->once())->method('removeWriteStream')->with($this->callback(function ($param) use (&$onRemove) {
|
||||
$onRemove = is_resource($param);
|
||||
return true;
|
||||
}));
|
||||
|
||||
$connection = new Connection($resource, $loop);
|
||||
$connection->write('test');
|
||||
$connection->close();
|
||||
|
||||
$this->assertTrue($onRemove);
|
||||
$this->assertFalse(is_resource($resource));
|
||||
}
|
||||
}
|
||||
128
vendor/react/socket/tests/ConnectorTest.php
vendored
Executable file
128
vendor/react/socket/tests/ConnectorTest.php
vendored
Executable file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\Socket\Connector;
|
||||
use React\Promise\Promise;
|
||||
|
||||
class ConnectorTest extends TestCase
|
||||
{
|
||||
public function testConnectorUsesTcpAsDefaultScheme()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$promise = new Promise(function () { });
|
||||
$tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('connect')->with('127.0.0.1:80')->willReturn($promise);
|
||||
|
||||
$connector = new Connector($loop, array(
|
||||
'tcp' => $tcp
|
||||
));
|
||||
|
||||
$connector->connect('127.0.0.1:80');
|
||||
}
|
||||
|
||||
public function testConnectorPassedThroughHostnameIfDnsIsDisabled()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$promise = new Promise(function () { });
|
||||
$tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('connect')->with('tcp://google.com:80')->willReturn($promise);
|
||||
|
||||
$connector = new Connector($loop, array(
|
||||
'tcp' => $tcp,
|
||||
'dns' => false
|
||||
));
|
||||
|
||||
$connector->connect('tcp://google.com:80');
|
||||
}
|
||||
|
||||
public function testConnectorWithUnknownSchemeAlwaysFails()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$connector = new Connector($loop);
|
||||
|
||||
$promise = $connector->connect('unknown://google.com:80');
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testConnectorWithDisabledTcpDefaultSchemeAlwaysFails()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$connector = new Connector($loop, array(
|
||||
'tcp' => false
|
||||
));
|
||||
|
||||
$promise = $connector->connect('google.com:80');
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testConnectorWithDisabledTcpSchemeAlwaysFails()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$connector = new Connector($loop, array(
|
||||
'tcp' => false
|
||||
));
|
||||
|
||||
$promise = $connector->connect('tcp://google.com:80');
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testConnectorWithDisabledTlsSchemeAlwaysFails()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$connector = new Connector($loop, array(
|
||||
'tls' => false
|
||||
));
|
||||
|
||||
$promise = $connector->connect('tls://google.com:443');
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testConnectorWithDisabledUnixSchemeAlwaysFails()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$connector = new Connector($loop, array(
|
||||
'unix' => false
|
||||
));
|
||||
|
||||
$promise = $connector->connect('unix://demo.sock');
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testConnectorUsesGivenResolverInstance()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$promise = new Promise(function () { });
|
||||
$resolver = $this->getMockBuilder('React\Dns\Resolver\Resolver')->disableOriginalConstructor()->getMock();
|
||||
$resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn($promise);
|
||||
|
||||
$connector = new Connector($loop, array(
|
||||
'dns' => $resolver
|
||||
));
|
||||
|
||||
$connector->connect('google.com:80');
|
||||
}
|
||||
|
||||
public function testConnectorUsesResolvedHostnameIfDnsIsUsed()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$promise = new Promise(function ($resolve) { $resolve('127.0.0.1'); });
|
||||
$resolver = $this->getMockBuilder('React\Dns\Resolver\Resolver')->disableOriginalConstructor()->getMock();
|
||||
$resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn($promise);
|
||||
|
||||
$promise = new Promise(function () { });
|
||||
$tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('connect')->with('tcp://127.0.0.1:80?hostname=google.com')->willReturn($promise);
|
||||
|
||||
$connector = new Connector($loop, array(
|
||||
'tcp' => $tcp,
|
||||
'dns' => $resolver
|
||||
));
|
||||
|
||||
$connector->connect('tcp://google.com:80');
|
||||
}
|
||||
}
|
||||
111
vendor/react/socket/tests/DnsConnectorTest.php
vendored
Executable file
111
vendor/react/socket/tests/DnsConnectorTest.php
vendored
Executable file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\Socket\DnsConnector;
|
||||
use React\Promise;
|
||||
|
||||
class DnsConnectorTest extends TestCase
|
||||
{
|
||||
private $tcp;
|
||||
private $resolver;
|
||||
private $connector;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$this->resolver = $this->getMockBuilder('React\Dns\Resolver\Resolver')->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->connector = new DnsConnector($this->tcp, $this->resolver);
|
||||
}
|
||||
|
||||
public function testPassByResolverIfGivenIp()
|
||||
{
|
||||
$this->resolver->expects($this->never())->method('resolve');
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('127.0.0.1:80'))->will($this->returnValue(Promise\reject()));
|
||||
|
||||
$this->connector->connect('127.0.0.1:80');
|
||||
}
|
||||
|
||||
public function testPassThroughResolverIfGivenHost()
|
||||
{
|
||||
$this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('1.2.3.4')));
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=google.com'))->will($this->returnValue(Promise\reject()));
|
||||
|
||||
$this->connector->connect('google.com:80');
|
||||
}
|
||||
|
||||
public function testPassThroughResolverIfGivenHostWhichResolvesToIpv6()
|
||||
{
|
||||
$this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('::1')));
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('[::1]:80?hostname=google.com'))->will($this->returnValue(Promise\reject()));
|
||||
|
||||
$this->connector->connect('google.com:80');
|
||||
}
|
||||
|
||||
public function testPassByResolverIfGivenCompleteUri()
|
||||
{
|
||||
$this->resolver->expects($this->never())->method('resolve');
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://127.0.0.1:80/path?query#fragment'))->will($this->returnValue(Promise\reject()));
|
||||
|
||||
$this->connector->connect('scheme://127.0.0.1:80/path?query#fragment');
|
||||
}
|
||||
|
||||
public function testPassThroughResolverIfGivenCompleteUri()
|
||||
{
|
||||
$this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('1.2.3.4')));
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/path?query&hostname=google.com#fragment'))->will($this->returnValue(Promise\reject()));
|
||||
|
||||
$this->connector->connect('scheme://google.com:80/path?query#fragment');
|
||||
}
|
||||
|
||||
public function testPassThroughResolverIfGivenExplicitHost()
|
||||
{
|
||||
$this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('1.2.3.4')));
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/?hostname=google.de'))->will($this->returnValue(Promise\reject()));
|
||||
|
||||
$this->connector->connect('scheme://google.com:80/?hostname=google.de');
|
||||
}
|
||||
|
||||
public function testRejectsImmediatelyIfUriIsInvalid()
|
||||
{
|
||||
$this->resolver->expects($this->never())->method('resolve');
|
||||
$this->tcp->expects($this->never())->method('connect');
|
||||
|
||||
$promise = $this->connector->connect('////');
|
||||
|
||||
$promise->then($this->expectCallableNever(), $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testSkipConnectionIfDnsFails()
|
||||
{
|
||||
$this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.invalid'))->will($this->returnValue(Promise\reject()));
|
||||
$this->tcp->expects($this->never())->method('connect');
|
||||
|
||||
$this->connector->connect('example.invalid:80');
|
||||
}
|
||||
|
||||
public function testCancelDuringDnsCancelsDnsAndDoesNotStartTcpConnection()
|
||||
{
|
||||
$pending = new Promise\Promise(function () { }, $this->expectCallableOnce());
|
||||
$this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->will($this->returnValue($pending));
|
||||
$this->tcp->expects($this->never())->method('connect');
|
||||
|
||||
$promise = $this->connector->connect('example.com:80');
|
||||
$promise->cancel();
|
||||
|
||||
$promise->then($this->expectCallableNever(), $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testCancelDuringTcpConnectionCancelsTcpConnection()
|
||||
{
|
||||
$pending = new Promise\Promise(function () { }, function () { throw new \Exception(); });
|
||||
$this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->will($this->returnValue(Promise\resolve('1.2.3.4')));
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->will($this->returnValue($pending));
|
||||
|
||||
$promise = $this->connector->connect('example.com:80');
|
||||
$promise->cancel();
|
||||
|
||||
$promise->then($this->expectCallableNever(), $this->expectCallableOnce());
|
||||
}
|
||||
}
|
||||
19
vendor/react/socket/tests/FixedUriConnectorTest.php
vendored
Executable file
19
vendor/react/socket/tests/FixedUriConnectorTest.php
vendored
Executable file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\Socket\FixedUriConnector;
|
||||
use React\Tests\Socket\TestCase;
|
||||
|
||||
class FixedUriConnectorTest extends TestCase
|
||||
{
|
||||
public function testWillInvokeGivenConnector()
|
||||
{
|
||||
$base = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$base->expects($this->once())->method('connect')->with('test')->willReturn('ret');
|
||||
|
||||
$connector = new FixedUriConnector('test', $base);
|
||||
|
||||
$this->assertEquals('ret', $connector->connect('ignored'));
|
||||
}
|
||||
}
|
||||
32
vendor/react/socket/tests/FunctionalConnectorTest.php
vendored
Executable file
32
vendor/react/socket/tests/FunctionalConnectorTest.php
vendored
Executable file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use Clue\React\Block;
|
||||
use React\EventLoop\Factory;
|
||||
use React\Socket\Connector;
|
||||
use React\Socket\TcpServer;
|
||||
|
||||
class FunctionalConnectorTest extends TestCase
|
||||
{
|
||||
const TIMEOUT = 1.0;
|
||||
|
||||
/** @test */
|
||||
public function connectionToTcpServerShouldSucceedWithLocalhost()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(9998, $loop);
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
$server->on('connection', array($server, 'close'));
|
||||
|
||||
$connector = new Connector($loop);
|
||||
|
||||
$connection = Block\await($connector->connect('localhost:9998'), $loop, self::TIMEOUT);
|
||||
|
||||
$this->assertInstanceOf('React\Socket\ConnectionInterface', $connection);
|
||||
|
||||
$connection->close();
|
||||
$server->close();
|
||||
}
|
||||
}
|
||||
438
vendor/react/socket/tests/FunctionalSecureServerTest.php
vendored
Executable file
438
vendor/react/socket/tests/FunctionalSecureServerTest.php
vendored
Executable file
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\EventLoop\Factory;
|
||||
use React\Socket\SecureServer;
|
||||
use React\Socket\ConnectionInterface;
|
||||
use React\Socket\TcpServer;
|
||||
use React\Socket\TcpConnector;
|
||||
use React\Socket\SecureConnector;
|
||||
use Clue\React\Block;
|
||||
|
||||
class FunctionalSecureServerTest extends TestCase
|
||||
{
|
||||
const TIMEOUT = 0.5;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
if (!function_exists('stream_socket_enable_crypto')) {
|
||||
$this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
|
||||
}
|
||||
}
|
||||
|
||||
public function testEmitsConnectionForNewConnection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
Block\await($promise, $loop, self::TIMEOUT);
|
||||
}
|
||||
|
||||
public function testWritesDataToConnection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$server->on('connection', function (ConnectionInterface $conn) {
|
||||
$conn->write('foo');
|
||||
});
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$local = Block\await($promise, $loop, self::TIMEOUT);
|
||||
/* @var $local ConnectionInterface */
|
||||
|
||||
$local->on('data', $this->expectCallableOnceWith('foo'));
|
||||
|
||||
Block\sleep(self::TIMEOUT, $loop);
|
||||
}
|
||||
|
||||
public function testWritesDataInMultipleChunksToConnection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$server->on('connection', function (ConnectionInterface $conn) {
|
||||
$conn->write(str_repeat('*', 400000));
|
||||
});
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$local = Block\await($promise, $loop, self::TIMEOUT);
|
||||
/* @var $local React\Stream\Stream */
|
||||
|
||||
$received = 0;
|
||||
$local->on('data', function ($chunk) use (&$received) {
|
||||
$received += strlen($chunk);
|
||||
});
|
||||
|
||||
Block\sleep(self::TIMEOUT, $loop);
|
||||
|
||||
$this->assertEquals(400000, $received);
|
||||
}
|
||||
|
||||
public function testWritesMoreDataInMultipleChunksToConnection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$server->on('connection', function (ConnectionInterface $conn) {
|
||||
$conn->write(str_repeat('*', 2000000));
|
||||
});
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$local = Block\await($promise, $loop, self::TIMEOUT);
|
||||
/* @var $local React\Stream\Stream */
|
||||
|
||||
$received = 0;
|
||||
$local->on('data', function ($chunk) use (&$received) {
|
||||
$received += strlen($chunk);
|
||||
});
|
||||
|
||||
Block\sleep(self::TIMEOUT, $loop);
|
||||
|
||||
$this->assertEquals(2000000, $received);
|
||||
}
|
||||
|
||||
public function testEmitsDataFromConnection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$once = $this->expectCallableOnceWith('foo');
|
||||
$server->on('connection', function (ConnectionInterface $conn) use ($once) {
|
||||
$conn->on('data', $once);
|
||||
});
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$local = Block\await($promise, $loop, self::TIMEOUT);
|
||||
/* @var $local React\Stream\Stream */
|
||||
|
||||
$local->write("foo");
|
||||
|
||||
Block\sleep(self::TIMEOUT, $loop);
|
||||
}
|
||||
|
||||
public function testEmitsDataInMultipleChunksFromConnection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$received = 0;
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$received) {
|
||||
$conn->on('data', function ($chunk) use (&$received) {
|
||||
$received += strlen($chunk);
|
||||
});
|
||||
});
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$local = Block\await($promise, $loop, self::TIMEOUT);
|
||||
/* @var $local React\Stream\Stream */
|
||||
|
||||
$local->write(str_repeat('*', 400000));
|
||||
|
||||
Block\sleep(self::TIMEOUT, $loop);
|
||||
|
||||
$this->assertEquals(400000, $received);
|
||||
}
|
||||
|
||||
public function testPipesDataBackInMultipleChunksFromConnection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$received) {
|
||||
$conn->pipe($conn);
|
||||
});
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$local = Block\await($promise, $loop, self::TIMEOUT);
|
||||
/* @var $local React\Stream\Stream */
|
||||
|
||||
$received = 0;
|
||||
$local->on('data', function ($chunk) use (&$received) {
|
||||
$received += strlen($chunk);
|
||||
});
|
||||
|
||||
$local->write(str_repeat('*', 400000));
|
||||
|
||||
Block\sleep(self::TIMEOUT, $loop);
|
||||
|
||||
$this->assertEquals(400000, $received);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 5.6
|
||||
*/
|
||||
public function testEmitsConnectionForNewTlsv11Connection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem',
|
||||
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER
|
||||
));
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false,
|
||||
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
Block\await($promise, $loop, self::TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 5.6
|
||||
*/
|
||||
public function testEmitsErrorForClientWithTlsVersionMismatch()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem',
|
||||
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER|STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
|
||||
));
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false,
|
||||
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$this->setExpectedException('RuntimeException', 'handshake');
|
||||
Block\await($promise, $loop, self::TIMEOUT);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionForNewConnectionWithEncryptedCertificate()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem',
|
||||
'passphrase' => 'swordfish'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
Block\await($promise, $loop, self::TIMEOUT);
|
||||
}
|
||||
|
||||
public function testEmitsErrorForServerWithInvalidCertificate()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => 'invalid.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$this->setExpectedException('RuntimeException', 'handshake');
|
||||
Block\await($promise, $loop, self::TIMEOUT);
|
||||
}
|
||||
|
||||
public function testEmitsErrorForServerWithEncryptedCertificateMissingPassphrase()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$this->setExpectedException('RuntimeException', 'handshake');
|
||||
Block\await($promise, $loop, self::TIMEOUT);
|
||||
}
|
||||
|
||||
public function testEmitsErrorForServerWithEncryptedCertificateWithInvalidPassphrase()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem',
|
||||
'passphrase' => 'nope'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$this->setExpectedException('RuntimeException', 'handshake');
|
||||
Block\await($promise, $loop, self::TIMEOUT);
|
||||
}
|
||||
|
||||
public function testEmitsErrorForConnectionWithPeerVerification()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => true
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
Block\sleep(self::TIMEOUT, $loop);
|
||||
}
|
||||
|
||||
public function testEmitsErrorIfConnectionIsCancelled()
|
||||
{
|
||||
if (PHP_OS !== 'Linux') {
|
||||
$this->markTestSkipped('Linux only (OS is ' . PHP_OS . ')');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
|
||||
'verify_peer' => false
|
||||
));
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
$promise->cancel();
|
||||
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
Block\sleep(self::TIMEOUT, $loop);
|
||||
}
|
||||
|
||||
public function testEmitsNothingIfConnectionIsIdle()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
$server->on('error', $this->expectCallableNever());
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect(str_replace('tls://', '', $server->getAddress()));
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
Block\sleep(self::TIMEOUT, $loop);
|
||||
}
|
||||
|
||||
public function testEmitsErrorIfConnectionIsNotSecureHandshake()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new SecureServer($server, $loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect(str_replace('tls://', '', $server->getAddress()));
|
||||
|
||||
$promise->then(function (ConnectionInterface $stream) {
|
||||
$stream->write("GET / HTTP/1.0\r\n\r\n");
|
||||
});
|
||||
|
||||
Block\sleep(self::TIMEOUT, $loop);
|
||||
}
|
||||
}
|
||||
324
vendor/react/socket/tests/FunctionalTcpServerTest.php
vendored
Executable file
324
vendor/react/socket/tests/FunctionalTcpServerTest.php
vendored
Executable file
@@ -0,0 +1,324 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\EventLoop\Factory;
|
||||
use React\Socket\TcpServer;
|
||||
use React\Socket\ConnectionInterface;
|
||||
use React\Socket\TcpConnector;
|
||||
use Clue\React\Block;
|
||||
|
||||
class FunctionalTcpServerTest extends TestCase
|
||||
{
|
||||
public function testEmitsConnectionForNewConnection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
}
|
||||
|
||||
public function testEmitsNoConnectionForNewConnectionWhenPaused()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
$server->pause();
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionForNewConnectionWhenResumedAfterPause()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
$server->pause();
|
||||
$server->resume();
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionWithRemoteIp()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$peer = null;
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$peer) {
|
||||
$peer = $conn->getRemoteAddress();
|
||||
});
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertContains('127.0.0.1:', $peer);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionWithLocalIp()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$local = null;
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$local) {
|
||||
$local = $conn->getLocalAddress();
|
||||
});
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertContains('127.0.0.1:', $local);
|
||||
$this->assertEquals($server->getAddress(), $local);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionWithLocalIpDespiteListeningOnAll()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer('0.0.0.0:0', $loop);
|
||||
$local = null;
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$local) {
|
||||
$local = $conn->getLocalAddress();
|
||||
});
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertContains('127.0.0.1:', $local);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionWithRemoteIpAfterConnectionIsClosedByPeer()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$peer = null;
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$peer) {
|
||||
$conn->on('close', function () use ($conn, &$peer) {
|
||||
$peer = $conn->getRemoteAddress();
|
||||
});
|
||||
});
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$client = Block\await($promise, $loop, 0.1);
|
||||
$client->end();
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertContains('127.0.0.1:', $peer);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionWithRemoteNullAddressAfterConnectionIsClosedLocally()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$peer = null;
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$peer) {
|
||||
$conn->close();
|
||||
$peer = $conn->getRemoteAddress();
|
||||
});
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertNull($peer);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionEvenIfConnectionIsCancelled()
|
||||
{
|
||||
if (PHP_OS !== 'Linux') {
|
||||
$this->markTestSkipped('Linux only (OS is ' . PHP_OS . ')');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
$promise->cancel();
|
||||
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionForNewIpv6Connection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
try {
|
||||
$server = new TcpServer('[::1]:0', $loop);
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->markTestSkipped('Unable to start IPv6 server socket (not available on your platform?)');
|
||||
}
|
||||
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionWithRemoteIpv6()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
try {
|
||||
$server = new TcpServer('[::1]:0', $loop);
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->markTestSkipped('Unable to start IPv6 server socket (not available on your platform?)');
|
||||
}
|
||||
|
||||
$peer = null;
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$peer) {
|
||||
$peer = $conn->getRemoteAddress();
|
||||
});
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertContains('[::1]:', $peer);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionWithLocalIpv6()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
try {
|
||||
$server = new TcpServer('[::1]:0', $loop);
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->markTestSkipped('Unable to start IPv6 server socket (not available on your platform?)');
|
||||
}
|
||||
|
||||
$local = null;
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$local) {
|
||||
$local = $conn->getLocalAddress();
|
||||
});
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertContains('[::1]:', $local);
|
||||
$this->assertEquals($server->getAddress(), $local);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionWithInheritedContextOptions()
|
||||
{
|
||||
if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.13', '<')) {
|
||||
// https://3v4l.org/hB4Tc
|
||||
$this->markTestSkipped('Not supported on legacy HHVM < 3.13');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop, array(
|
||||
'backlog' => 4
|
||||
));
|
||||
|
||||
$all = null;
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$all) {
|
||||
$all = stream_context_get_options($conn->stream);
|
||||
});
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertEquals(array('socket' => array('backlog' => 4)), $all);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testFailsToListenOnInvalidUri()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
new TcpServer('///', $loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testFailsToListenOnUriWithoutPort()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
new TcpServer('127.0.0.1', $loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testFailsToListenOnUriWithWrongScheme()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
new TcpServer('udp://127.0.0.1:0', $loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testFailsToListenOnUriWIthHostname()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
new TcpServer('localhost:8080', $loop);
|
||||
}
|
||||
}
|
||||
328
vendor/react/socket/tests/IntegrationTest.php
vendored
Executable file
328
vendor/react/socket/tests/IntegrationTest.php
vendored
Executable file
@@ -0,0 +1,328 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use Clue\React\Block;
|
||||
use React\Dns\Resolver\Factory as ResolverFactory;
|
||||
use React\EventLoop\Factory;
|
||||
use React\Socket\Connector;
|
||||
use React\Socket\DnsConnector;
|
||||
use React\Socket\SecureConnector;
|
||||
use React\Socket\TcpConnector;
|
||||
|
||||
/** @group internet */
|
||||
class IntegrationTest extends TestCase
|
||||
{
|
||||
const TIMEOUT = 5.0;
|
||||
|
||||
/** @test */
|
||||
public function gettingStuffFromGoogleShouldWork()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
$connector = new Connector($loop);
|
||||
|
||||
$conn = Block\await($connector->connect('google.com:80'), $loop);
|
||||
|
||||
$this->assertContains(':80', $conn->getRemoteAddress());
|
||||
$this->assertNotEquals('google.com:80', $conn->getRemoteAddress());
|
||||
|
||||
$conn->write("GET / HTTP/1.0\r\n\r\n");
|
||||
|
||||
$response = $this->buffer($conn, $loop, self::TIMEOUT);
|
||||
|
||||
$this->assertRegExp('#^HTTP/1\.0#', $response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gettingEncryptedStuffFromGoogleShouldWork()
|
||||
{
|
||||
if (!function_exists('stream_socket_enable_crypto')) {
|
||||
$this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
$secureConnector = new Connector($loop);
|
||||
|
||||
$conn = Block\await($secureConnector->connect('tls://google.com:443'), $loop);
|
||||
|
||||
$conn->write("GET / HTTP/1.0\r\n\r\n");
|
||||
|
||||
$response = $this->buffer($conn, $loop, self::TIMEOUT);
|
||||
|
||||
$this->assertRegExp('#^HTTP/1\.0#', $response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gettingEncryptedStuffFromGoogleShouldWorkIfHostIsResolvedFirst()
|
||||
{
|
||||
if (!function_exists('stream_socket_enable_crypto')) {
|
||||
$this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$factory = new ResolverFactory();
|
||||
$dns = $factory->create('8.8.8.8', $loop);
|
||||
|
||||
$connector = new DnsConnector(
|
||||
new SecureConnector(
|
||||
new TcpConnector($loop),
|
||||
$loop
|
||||
),
|
||||
$dns
|
||||
);
|
||||
|
||||
$conn = Block\await($connector->connect('google.com:443'), $loop);
|
||||
|
||||
$conn->write("GET / HTTP/1.0\r\n\r\n");
|
||||
|
||||
$response = $this->buffer($conn, $loop, self::TIMEOUT);
|
||||
|
||||
$this->assertRegExp('#^HTTP/1\.0#', $response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gettingPlaintextStuffFromEncryptedGoogleShouldNotWork()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
$connector = new Connector($loop);
|
||||
|
||||
$conn = Block\await($connector->connect('google.com:443'), $loop);
|
||||
|
||||
$this->assertContains(':443', $conn->getRemoteAddress());
|
||||
$this->assertNotEquals('google.com:443', $conn->getRemoteAddress());
|
||||
|
||||
$conn->write("GET / HTTP/1.0\r\n\r\n");
|
||||
|
||||
$response = $this->buffer($conn, $loop, self::TIMEOUT);
|
||||
|
||||
$this->assertNotRegExp('#^HTTP/1\.0#', $response);
|
||||
}
|
||||
|
||||
public function testConnectingFailsIfDnsUsesInvalidResolver()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$factory = new ResolverFactory();
|
||||
$dns = $factory->create('demo.invalid', $loop);
|
||||
|
||||
$connector = new Connector($loop, array(
|
||||
'dns' => $dns
|
||||
));
|
||||
|
||||
$this->setExpectedException('RuntimeException');
|
||||
Block\await($connector->connect('google.com:80'), $loop, self::TIMEOUT);
|
||||
}
|
||||
|
||||
public function testCancellingPendingConnectionWithoutTimeoutShouldNotCreateAnyGarbageReferences()
|
||||
{
|
||||
if (class_exists('React\Promise\When')) {
|
||||
$this->markTestSkipped('Not supported on legacy Promise v1 API');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
$connector = new Connector($loop, array('timeout' => false));
|
||||
|
||||
gc_collect_cycles();
|
||||
$promise = $connector->connect('8.8.8.8:80');
|
||||
$promise->cancel();
|
||||
unset($promise);
|
||||
|
||||
$this->assertEquals(0, gc_collect_cycles());
|
||||
}
|
||||
|
||||
public function testCancellingPendingConnectionShouldNotCreateAnyGarbageReferences()
|
||||
{
|
||||
if (class_exists('React\Promise\When')) {
|
||||
$this->markTestSkipped('Not supported on legacy Promise v1 API');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
$connector = new Connector($loop);
|
||||
|
||||
gc_collect_cycles();
|
||||
$promise = $connector->connect('8.8.8.8:80');
|
||||
$promise->cancel();
|
||||
unset($promise);
|
||||
|
||||
$this->assertEquals(0, gc_collect_cycles());
|
||||
}
|
||||
|
||||
public function testWaitingForRejectedConnectionShouldNotCreateAnyGarbageReferences()
|
||||
{
|
||||
if (class_exists('React\Promise\When')) {
|
||||
$this->markTestSkipped('Not supported on legacy Promise v1 API');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
$connector = new Connector($loop, array('timeout' => false));
|
||||
|
||||
gc_collect_cycles();
|
||||
|
||||
$wait = true;
|
||||
$promise = $connector->connect('127.0.0.1:1')->then(
|
||||
null,
|
||||
function ($e) use (&$wait) {
|
||||
$wait = false;
|
||||
throw $e;
|
||||
}
|
||||
);
|
||||
|
||||
// run loop for short period to ensure we detect connection refused error
|
||||
Block\sleep(0.01, $loop);
|
||||
if ($wait) {
|
||||
Block\sleep(0.2, $loop);
|
||||
if ($wait) {
|
||||
$this->fail('Connection attempt did not fail');
|
||||
}
|
||||
}
|
||||
unset($promise);
|
||||
|
||||
$this->assertEquals(0, gc_collect_cycles());
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7
|
||||
*/
|
||||
public function testWaitingForConnectionTimeoutShouldNotCreateAnyGarbageReferences()
|
||||
{
|
||||
if (class_exists('React\Promise\When')) {
|
||||
$this->markTestSkipped('Not supported on legacy Promise v1 API');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
$connector = new Connector($loop, array('timeout' => 0.001));
|
||||
|
||||
gc_collect_cycles();
|
||||
|
||||
$wait = true;
|
||||
$promise = $connector->connect('google.com:80')->then(
|
||||
null,
|
||||
function ($e) use (&$wait) {
|
||||
$wait = false;
|
||||
throw $e;
|
||||
}
|
||||
);
|
||||
|
||||
// run loop for short period to ensure we detect connection timeout error
|
||||
Block\sleep(0.01, $loop);
|
||||
if ($wait) {
|
||||
Block\sleep(0.2, $loop);
|
||||
if ($wait) {
|
||||
$this->fail('Connection attempt did not fail');
|
||||
}
|
||||
}
|
||||
unset($promise);
|
||||
|
||||
$this->assertEquals(0, gc_collect_cycles());
|
||||
}
|
||||
|
||||
public function testWaitingForInvalidDnsConnectionShouldNotCreateAnyGarbageReferences()
|
||||
{
|
||||
if (class_exists('React\Promise\When')) {
|
||||
$this->markTestSkipped('Not supported on legacy Promise v1 API');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
$connector = new Connector($loop, array('timeout' => false));
|
||||
|
||||
gc_collect_cycles();
|
||||
|
||||
$wait = true;
|
||||
$promise = $connector->connect('example.invalid:80')->then(
|
||||
null,
|
||||
function ($e) use (&$wait) {
|
||||
$wait = false;
|
||||
throw $e;
|
||||
}
|
||||
);
|
||||
|
||||
// run loop for short period to ensure we detect DNS error
|
||||
Block\sleep(0.01, $loop);
|
||||
if ($wait) {
|
||||
Block\sleep(0.2, $loop);
|
||||
if ($wait) {
|
||||
$this->fail('Connection attempt did not fail');
|
||||
}
|
||||
}
|
||||
unset($promise);
|
||||
|
||||
$this->assertEquals(0, gc_collect_cycles());
|
||||
}
|
||||
|
||||
public function testWaitingForSuccessfullyClosedConnectionShouldNotCreateAnyGarbageReferences()
|
||||
{
|
||||
if (class_exists('React\Promise\When')) {
|
||||
$this->markTestSkipped('Not supported on legacy Promise v1 API');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
$connector = new Connector($loop, array('timeout' => false));
|
||||
|
||||
gc_collect_cycles();
|
||||
$promise = $connector->connect('google.com:80')->then(
|
||||
function ($conn) {
|
||||
$conn->close();
|
||||
}
|
||||
);
|
||||
Block\await($promise, $loop, self::TIMEOUT);
|
||||
unset($promise);
|
||||
|
||||
$this->assertEquals(0, gc_collect_cycles());
|
||||
}
|
||||
|
||||
public function testConnectingFailsIfTimeoutIsTooSmall()
|
||||
{
|
||||
if (!function_exists('stream_socket_enable_crypto')) {
|
||||
$this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$connector = new Connector($loop, array(
|
||||
'timeout' => 0.001
|
||||
));
|
||||
|
||||
$this->setExpectedException('RuntimeException');
|
||||
Block\await($connector->connect('google.com:80'), $loop, self::TIMEOUT);
|
||||
}
|
||||
|
||||
public function testSelfSignedRejectsIfVerificationIsEnabled()
|
||||
{
|
||||
if (!function_exists('stream_socket_enable_crypto')) {
|
||||
$this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$connector = new Connector($loop, array(
|
||||
'tls' => array(
|
||||
'verify_peer' => true
|
||||
)
|
||||
));
|
||||
|
||||
$this->setExpectedException('RuntimeException');
|
||||
Block\await($connector->connect('tls://self-signed.badssl.com:443'), $loop, self::TIMEOUT);
|
||||
}
|
||||
|
||||
public function testSelfSignedResolvesIfVerificationIsDisabled()
|
||||
{
|
||||
if (!function_exists('stream_socket_enable_crypto')) {
|
||||
$this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$connector = new Connector($loop, array(
|
||||
'tls' => array(
|
||||
'verify_peer' => false
|
||||
)
|
||||
));
|
||||
|
||||
$conn = Block\await($connector->connect('tls://self-signed.badssl.com:443'), $loop, self::TIMEOUT);
|
||||
$conn->close();
|
||||
|
||||
// if we reach this, then everything is good
|
||||
$this->assertNull(null);
|
||||
}
|
||||
}
|
||||
195
vendor/react/socket/tests/LimitingServerTest.php
vendored
Executable file
195
vendor/react/socket/tests/LimitingServerTest.php
vendored
Executable file
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\Socket\LimitingServer;
|
||||
use React\Socket\TcpServer;
|
||||
use React\EventLoop\Factory;
|
||||
use Clue\React\Block;
|
||||
|
||||
class LimitingServerTest extends TestCase
|
||||
{
|
||||
public function testGetAddressWillBePassedThroughToTcpServer()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('getAddress')->willReturn('127.0.0.1:1234');
|
||||
|
||||
$server = new LimitingServer($tcp, 100);
|
||||
|
||||
$this->assertEquals('127.0.0.1:1234', $server->getAddress());
|
||||
}
|
||||
|
||||
public function testPauseWillBePassedThroughToTcpServer()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('pause');
|
||||
|
||||
$server = new LimitingServer($tcp, 100);
|
||||
|
||||
$server->pause();
|
||||
}
|
||||
|
||||
public function testPauseTwiceWillBePassedThroughToTcpServerOnce()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('pause');
|
||||
|
||||
$server = new LimitingServer($tcp, 100);
|
||||
|
||||
$server->pause();
|
||||
$server->pause();
|
||||
}
|
||||
|
||||
public function testResumeWillBePassedThroughToTcpServer()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('resume');
|
||||
|
||||
$server = new LimitingServer($tcp, 100);
|
||||
|
||||
$server->pause();
|
||||
$server->resume();
|
||||
}
|
||||
|
||||
public function testResumeTwiceWillBePassedThroughToTcpServerOnce()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('resume');
|
||||
|
||||
$server = new LimitingServer($tcp, 100);
|
||||
|
||||
$server->pause();
|
||||
$server->resume();
|
||||
$server->resume();
|
||||
}
|
||||
|
||||
public function testCloseWillBePassedThroughToTcpServer()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('close');
|
||||
|
||||
$server = new LimitingServer($tcp, 100);
|
||||
|
||||
$server->close();
|
||||
}
|
||||
|
||||
public function testSocketErrorWillBeForwarded()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$tcp = new TcpServer(0, $loop);
|
||||
|
||||
$server = new LimitingServer($tcp, 100);
|
||||
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$tcp->emit('error', array(new \RuntimeException('test')));
|
||||
}
|
||||
|
||||
public function testSocketConnectionWillBeForwarded()
|
||||
{
|
||||
$connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
|
||||
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$tcp = new TcpServer(0, $loop);
|
||||
|
||||
$server = new LimitingServer($tcp, 100);
|
||||
$server->on('connection', $this->expectCallableOnceWith($connection));
|
||||
$server->on('error', $this->expectCallableNever());
|
||||
|
||||
$tcp->emit('connection', array($connection));
|
||||
|
||||
$this->assertEquals(array($connection), $server->getConnections());
|
||||
}
|
||||
|
||||
public function testSocketConnectionWillBeClosedOnceLimitIsReached()
|
||||
{
|
||||
$first = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
|
||||
$first->expects($this->never())->method('close');
|
||||
$second = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
|
||||
$second->expects($this->once())->method('close');
|
||||
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$tcp = new TcpServer(0, $loop);
|
||||
|
||||
$server = new LimitingServer($tcp, 1);
|
||||
$server->on('connection', $this->expectCallableOnceWith($first));
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$tcp->emit('connection', array($first));
|
||||
$tcp->emit('connection', array($second));
|
||||
}
|
||||
|
||||
public function testPausingServerWillBePausedOnceLimitIsReached()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('addReadStream');
|
||||
$loop->expects($this->once())->method('removeReadStream');
|
||||
|
||||
$tcp = new TcpServer(0, $loop);
|
||||
|
||||
$connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
|
||||
|
||||
$server = new LimitingServer($tcp, 1, true);
|
||||
|
||||
$tcp->emit('connection', array($connection));
|
||||
}
|
||||
|
||||
public function testSocketDisconnectionWillRemoveFromList()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$tcp = new TcpServer(0, $loop);
|
||||
|
||||
$socket = stream_socket_client($tcp->getAddress());
|
||||
fclose($socket);
|
||||
|
||||
$server = new LimitingServer($tcp, 100);
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
$server->on('error', $this->expectCallableNever());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertEquals(array(), $server->getConnections());
|
||||
}
|
||||
|
||||
public function testPausingServerWillEmitOnlyOneButAcceptTwoConnectionsDueToOperatingSystem()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new LimitingServer($server, 1, true);
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
$server->on('error', $this->expectCallableNever());
|
||||
|
||||
$first = stream_socket_client($server->getAddress());
|
||||
$second = stream_socket_client($server->getAddress());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
fclose($first);
|
||||
fclose($second);
|
||||
}
|
||||
|
||||
public function testPausingServerWillEmitTwoConnectionsFromBacklog()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$twice = $this->createCallableMock();
|
||||
$twice->expects($this->exactly(2))->method('__invoke');
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server = new LimitingServer($server, 1, true);
|
||||
$server->on('connection', $twice);
|
||||
$server->on('error', $this->expectCallableNever());
|
||||
|
||||
$first = stream_socket_client($server->getAddress());
|
||||
fclose($first);
|
||||
$second = stream_socket_client($server->getAddress());
|
||||
fclose($second);
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
}
|
||||
}
|
||||
74
vendor/react/socket/tests/SecureConnectorTest.php
vendored
Executable file
74
vendor/react/socket/tests/SecureConnectorTest.php
vendored
Executable file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\Promise;
|
||||
use React\Socket\SecureConnector;
|
||||
|
||||
class SecureConnectorTest extends TestCase
|
||||
{
|
||||
private $loop;
|
||||
private $tcp;
|
||||
private $connector;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
if (!function_exists('stream_socket_enable_crypto')) {
|
||||
$this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
|
||||
}
|
||||
|
||||
$this->loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$this->tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$this->connector = new SecureConnector($this->tcp, $this->loop);
|
||||
}
|
||||
|
||||
public function testConnectionWillWaitForTcpConnection()
|
||||
{
|
||||
$pending = new Promise\Promise(function () { });
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->will($this->returnValue($pending));
|
||||
|
||||
$promise = $this->connector->connect('example.com:80');
|
||||
|
||||
$this->assertInstanceOf('React\Promise\PromiseInterface', $promise);
|
||||
}
|
||||
|
||||
public function testConnectionWithCompleteUriWillBePassedThroughExpectForScheme()
|
||||
{
|
||||
$pending = new Promise\Promise(function () { });
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80/path?query#fragment'))->will($this->returnValue($pending));
|
||||
|
||||
$this->connector->connect('tls://example.com:80/path?query#fragment');
|
||||
}
|
||||
|
||||
public function testConnectionToInvalidSchemeWillReject()
|
||||
{
|
||||
$this->tcp->expects($this->never())->method('connect');
|
||||
|
||||
$promise = $this->connector->connect('tcp://example.com:80');
|
||||
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testCancelDuringTcpConnectionCancelsTcpConnection()
|
||||
{
|
||||
$pending = new Promise\Promise(function () { }, function () { throw new \Exception(); });
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->will($this->returnValue($pending));
|
||||
|
||||
$promise = $this->connector->connect('example.com:80');
|
||||
$promise->cancel();
|
||||
|
||||
$promise->then($this->expectCallableNever(), $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testConnectionWillBeClosedAndRejectedIfConnectioIsNoStream()
|
||||
{
|
||||
$connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
|
||||
$connection->expects($this->once())->method('close');
|
||||
|
||||
$this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(Promise\resolve($connection));
|
||||
|
||||
$promise = $this->connector->connect('example.com:80');
|
||||
|
||||
$promise->then($this->expectCallableNever(), $this->expectCallableOnce());
|
||||
}
|
||||
}
|
||||
204
vendor/react/socket/tests/SecureIntegrationTest.php
vendored
Executable file
204
vendor/react/socket/tests/SecureIntegrationTest.php
vendored
Executable file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\EventLoop\Factory as LoopFactory;
|
||||
use React\Socket\TcpServer;
|
||||
use React\Socket\SecureServer;
|
||||
use React\Socket\TcpConnector;
|
||||
use React\Socket\SecureConnector;
|
||||
use Clue\React\Block;
|
||||
use React\Promise\Promise;
|
||||
use Evenement\EventEmitterInterface;
|
||||
use React\Promise\Deferred;
|
||||
use React\Socket\ConnectionInterface;
|
||||
|
||||
class SecureIntegrationTest extends TestCase
|
||||
{
|
||||
const TIMEOUT = 0.5;
|
||||
|
||||
private $loop;
|
||||
private $server;
|
||||
private $connector;
|
||||
private $address;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
if (!function_exists('stream_socket_enable_crypto')) {
|
||||
$this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
|
||||
}
|
||||
|
||||
$this->loop = LoopFactory::create();
|
||||
$this->server = new TcpServer(0, $this->loop);
|
||||
$this->server = new SecureServer($this->server, $this->loop, array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
));
|
||||
$this->address = $this->server->getAddress();
|
||||
$this->connector = new SecureConnector(new TcpConnector($this->loop), $this->loop, array('verify_peer' => false));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
if ($this->server !== null) {
|
||||
$this->server->close();
|
||||
$this->server = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function testConnectToServer()
|
||||
{
|
||||
$client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
|
||||
/* @var $client ConnectionInterface */
|
||||
|
||||
$client->close();
|
||||
|
||||
// if we reach this, then everything is good
|
||||
$this->assertNull(null);
|
||||
}
|
||||
|
||||
public function testConnectToServerEmitsConnection()
|
||||
{
|
||||
$promiseServer = $this->createPromiseForEvent($this->server, 'connection', $this->expectCallableOnce());
|
||||
|
||||
$promiseClient = $this->connector->connect($this->address);
|
||||
|
||||
list($_, $client) = Block\awaitAll(array($promiseServer, $promiseClient), $this->loop, self::TIMEOUT);
|
||||
/* @var $client ConnectionInterface */
|
||||
|
||||
$client->close();
|
||||
}
|
||||
|
||||
public function testSendSmallDataToServerReceivesOneChunk()
|
||||
{
|
||||
// server expects one connection which emits one data event
|
||||
$received = new Deferred();
|
||||
$this->server->on('connection', function (ConnectionInterface $peer) use ($received) {
|
||||
$peer->on('data', function ($chunk) use ($received) {
|
||||
$received->resolve($chunk);
|
||||
});
|
||||
});
|
||||
|
||||
$client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
|
||||
/* @var $client ConnectionInterface */
|
||||
|
||||
$client->write('hello');
|
||||
|
||||
// await server to report one "data" event
|
||||
$data = Block\await($received->promise(), $this->loop, self::TIMEOUT);
|
||||
|
||||
$client->close();
|
||||
|
||||
$this->assertEquals('hello', $data);
|
||||
}
|
||||
|
||||
public function testSendDataWithEndToServerReceivesAllData()
|
||||
{
|
||||
$disconnected = new Deferred();
|
||||
$this->server->on('connection', function (ConnectionInterface $peer) use ($disconnected) {
|
||||
$received = '';
|
||||
$peer->on('data', function ($chunk) use (&$received) {
|
||||
$received .= $chunk;
|
||||
});
|
||||
$peer->on('close', function () use (&$received, $disconnected) {
|
||||
$disconnected->resolve($received);
|
||||
});
|
||||
});
|
||||
|
||||
$client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
|
||||
/* @var $client ConnectionInterface */
|
||||
|
||||
$data = str_repeat('a', 200000);
|
||||
$client->end($data);
|
||||
|
||||
// await server to report connection "close" event
|
||||
$received = Block\await($disconnected->promise(), $this->loop, self::TIMEOUT);
|
||||
|
||||
$this->assertEquals($data, $received);
|
||||
}
|
||||
|
||||
public function testSendDataWithoutEndingToServerReceivesAllData()
|
||||
{
|
||||
$received = '';
|
||||
$this->server->on('connection', function (ConnectionInterface $peer) use (&$received) {
|
||||
$peer->on('data', function ($chunk) use (&$received) {
|
||||
$received .= $chunk;
|
||||
});
|
||||
});
|
||||
|
||||
$client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
|
||||
/* @var $client ConnectionInterface */
|
||||
|
||||
$data = str_repeat('d', 200000);
|
||||
$client->write($data);
|
||||
|
||||
// buffer incoming data for 0.1s (should be plenty of time)
|
||||
Block\sleep(0.1, $this->loop);
|
||||
|
||||
$client->close();
|
||||
|
||||
$this->assertEquals($data, $received);
|
||||
}
|
||||
|
||||
public function testConnectToServerWhichSendsSmallDataReceivesOneChunk()
|
||||
{
|
||||
$this->server->on('connection', function (ConnectionInterface $peer) {
|
||||
$peer->write('hello');
|
||||
});
|
||||
|
||||
$client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
|
||||
/* @var $client ConnectionInterface */
|
||||
|
||||
// await client to report one "data" event
|
||||
$receive = $this->createPromiseForEvent($client, 'data', $this->expectCallableOnceWith('hello'));
|
||||
Block\await($receive, $this->loop, self::TIMEOUT);
|
||||
|
||||
$client->close();
|
||||
}
|
||||
|
||||
public function testConnectToServerWhichSendsDataWithEndReceivesAllData()
|
||||
{
|
||||
$data = str_repeat('b', 100000);
|
||||
$this->server->on('connection', function (ConnectionInterface $peer) use ($data) {
|
||||
$peer->end($data);
|
||||
});
|
||||
|
||||
$client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
|
||||
/* @var $client ConnectionInterface */
|
||||
|
||||
// await data from client until it closes
|
||||
$received = $this->buffer($client, $this->loop, self::TIMEOUT);
|
||||
|
||||
$this->assertEquals($data, $received);
|
||||
}
|
||||
|
||||
public function testConnectToServerWhichSendsDataWithoutEndingReceivesAllData()
|
||||
{
|
||||
$data = str_repeat('c', 100000);
|
||||
$this->server->on('connection', function (ConnectionInterface $peer) use ($data) {
|
||||
$peer->write($data);
|
||||
});
|
||||
|
||||
$client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
|
||||
/* @var $client ConnectionInterface */
|
||||
|
||||
// buffer incoming data for 0.1s (should be plenty of time)
|
||||
$received = '';
|
||||
$client->on('data', function ($chunk) use (&$received) {
|
||||
$received .= $chunk;
|
||||
});
|
||||
Block\sleep(0.1, $this->loop);
|
||||
|
||||
$client->close();
|
||||
|
||||
$this->assertEquals($data, $received);
|
||||
}
|
||||
|
||||
private function createPromiseForEvent(EventEmitterInterface $emitter, $event, $fn)
|
||||
{
|
||||
return new Promise(function ($resolve) use ($emitter, $event, $fn) {
|
||||
$emitter->on($event, function () use ($resolve, $fn) {
|
||||
$resolve(call_user_func_array($fn, func_get_args()));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
105
vendor/react/socket/tests/SecureServerTest.php
vendored
Executable file
105
vendor/react/socket/tests/SecureServerTest.php
vendored
Executable file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\Socket\SecureServer;
|
||||
use React\Socket\TcpServer;
|
||||
|
||||
class SecureServerTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
if (!function_exists('stream_socket_enable_crypto')) {
|
||||
$this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetAddressWillBePassedThroughToTcpServer()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('getAddress')->willReturn('tcp://127.0.0.1:1234');
|
||||
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$server = new SecureServer($tcp, $loop, array());
|
||||
|
||||
$this->assertEquals('tls://127.0.0.1:1234', $server->getAddress());
|
||||
}
|
||||
|
||||
public function testGetAddressWillReturnNullIfTcpServerReturnsNull()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('getAddress')->willReturn(null);
|
||||
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$server = new SecureServer($tcp, $loop, array());
|
||||
|
||||
$this->assertNull($server->getAddress());
|
||||
}
|
||||
|
||||
public function testPauseWillBePassedThroughToTcpServer()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('pause');
|
||||
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$server = new SecureServer($tcp, $loop, array());
|
||||
|
||||
$server->pause();
|
||||
}
|
||||
|
||||
public function testResumeWillBePassedThroughToTcpServer()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('resume');
|
||||
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$server = new SecureServer($tcp, $loop, array());
|
||||
|
||||
$server->resume();
|
||||
}
|
||||
|
||||
public function testCloseWillBePassedThroughToTcpServer()
|
||||
{
|
||||
$tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
|
||||
$tcp->expects($this->once())->method('close');
|
||||
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$server = new SecureServer($tcp, $loop, array());
|
||||
|
||||
$server->close();
|
||||
}
|
||||
|
||||
public function testConnectionWillBeEndedWithErrorIfItIsNotAStream()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$tcp = new TcpServer(0, $loop);
|
||||
|
||||
$connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
|
||||
$connection->expects($this->once())->method('end');
|
||||
|
||||
$server = new SecureServer($tcp, $loop, array());
|
||||
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$tcp->emit('connection', array($connection));
|
||||
}
|
||||
|
||||
public function testSocketErrorWillBeForwarded()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$tcp = new TcpServer(0, $loop);
|
||||
|
||||
$server = new SecureServer($tcp, $loop, array());
|
||||
|
||||
$server->on('error', $this->expectCallableOnce());
|
||||
|
||||
$tcp->emit('error', array(new \RuntimeException('test')));
|
||||
}
|
||||
}
|
||||
173
vendor/react/socket/tests/ServerTest.php
vendored
Executable file
173
vendor/react/socket/tests/ServerTest.php
vendored
Executable file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\EventLoop\Factory;
|
||||
use React\Socket\Server;
|
||||
use React\Socket\TcpConnector;
|
||||
use React\Socket\UnixConnector;
|
||||
use Clue\React\Block;
|
||||
use React\Socket\ConnectionInterface;
|
||||
|
||||
class ServerTest extends TestCase
|
||||
{
|
||||
const TIMEOUT = 0.1;
|
||||
|
||||
public function testCreateServerWithZeroPortAssignsRandomPort()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new Server(0, $loop);
|
||||
$this->assertNotEquals(0, $server->getAddress());
|
||||
$server->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testConstructorThrowsForInvalidUri()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$server = new Server('invalid URI', $loop);
|
||||
}
|
||||
|
||||
public function testConstructorCreatesExpectedTcpServer()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new Server(0, $loop);
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$connector->connect($server->getAddress())
|
||||
->then($this->expectCallableOnce(), $this->expectCallableNever());
|
||||
|
||||
$connection = Block\await($connector->connect($server->getAddress()), $loop, self::TIMEOUT);
|
||||
|
||||
$connection->close();
|
||||
$server->close();
|
||||
}
|
||||
|
||||
public function testConstructorCreatesExpectedUnixServer()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new Server($this->getRandomSocketUri(), $loop);
|
||||
|
||||
$connector = new UnixConnector($loop);
|
||||
$connector->connect($server->getAddress())
|
||||
->then($this->expectCallableOnce(), $this->expectCallableNever());
|
||||
|
||||
$connection = Block\await($connector->connect($server->getAddress()), $loop, self::TIMEOUT);
|
||||
|
||||
$connection->close();
|
||||
$server->close();
|
||||
}
|
||||
|
||||
public function testEmitsConnectionForNewConnection()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new Server(0, $loop);
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$client = stream_socket_client($server->getAddress());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
}
|
||||
|
||||
public function testDoesNotEmitConnectionForNewConnectionToPausedServer()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new Server(0, $loop);
|
||||
$server->pause();
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
|
||||
$client = stream_socket_client($server->getAddress());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
}
|
||||
|
||||
public function testDoesEmitConnectionForNewConnectionToResumedServer()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new Server(0, $loop);
|
||||
$server->pause();
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$client = stream_socket_client($server->getAddress());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$server->resume();
|
||||
Block\sleep(0.1, $loop);
|
||||
}
|
||||
|
||||
public function testDoesNotAllowConnectionToClosedServer()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new Server(0, $loop);
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
$address = $server->getAddress();
|
||||
$server->close();
|
||||
|
||||
$client = @stream_socket_client($address);
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertFalse($client);
|
||||
}
|
||||
|
||||
public function testEmitsConnectionWithInheritedContextOptions()
|
||||
{
|
||||
if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.13', '<')) {
|
||||
// https://3v4l.org/hB4Tc
|
||||
$this->markTestSkipped('Not supported on legacy HHVM < 3.13');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new Server(0, $loop, array(
|
||||
'backlog' => 4
|
||||
));
|
||||
|
||||
$all = null;
|
||||
$server->on('connection', function (ConnectionInterface $conn) use (&$all) {
|
||||
$all = stream_context_get_options($conn->stream);
|
||||
});
|
||||
|
||||
$client = stream_socket_client($server->getAddress());
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
|
||||
$this->assertEquals(array('socket' => array('backlog' => 4)), $all);
|
||||
}
|
||||
|
||||
public function testDoesNotEmitSecureConnectionForNewPlainConnection()
|
||||
{
|
||||
if (!function_exists('stream_socket_enable_crypto')) {
|
||||
$this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
|
||||
}
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new Server('tls://127.0.0.1:0', $loop, array(
|
||||
'tls' => array(
|
||||
'local_cert' => __DIR__ . '/../examples/localhost.pem'
|
||||
)
|
||||
));
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
|
||||
$client = stream_socket_client(str_replace('tls://', '', $server->getAddress()));
|
||||
|
||||
Block\sleep(0.1, $loop);
|
||||
}
|
||||
|
||||
private function getRandomSocketUri()
|
||||
{
|
||||
return "unix://" . sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid(rand(), true) . '.sock';
|
||||
}
|
||||
}
|
||||
10
vendor/react/socket/tests/Stub/CallableStub.php
vendored
Executable file
10
vendor/react/socket/tests/Stub/CallableStub.php
vendored
Executable file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket\Stub;
|
||||
|
||||
class CallableStub
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
}
|
||||
}
|
||||
63
vendor/react/socket/tests/Stub/ConnectionStub.php
vendored
Executable file
63
vendor/react/socket/tests/Stub/ConnectionStub.php
vendored
Executable file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket\Stub;
|
||||
|
||||
use Evenement\EventEmitter;
|
||||
use React\Socket\ConnectionInterface;
|
||||
use React\Stream\WritableStreamInterface;
|
||||
use React\Stream\Util;
|
||||
|
||||
class ConnectionStub extends EventEmitter implements ConnectionInterface
|
||||
{
|
||||
private $data = '';
|
||||
|
||||
public function isReadable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isWritable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function pause()
|
||||
{
|
||||
}
|
||||
|
||||
public function resume()
|
||||
{
|
||||
}
|
||||
|
||||
public function pipe(WritableStreamInterface $dest, array $options = array())
|
||||
{
|
||||
Util::pipe($this, $dest, $options);
|
||||
|
||||
return $dest;
|
||||
}
|
||||
|
||||
public function write($data)
|
||||
{
|
||||
$this->data .= $data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function end($data = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function getRemoteAddress()
|
||||
{
|
||||
return '127.0.0.1';
|
||||
}
|
||||
}
|
||||
18
vendor/react/socket/tests/Stub/ServerStub.php
vendored
Executable file
18
vendor/react/socket/tests/Stub/ServerStub.php
vendored
Executable file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket\Stub;
|
||||
|
||||
use Evenement\EventEmitter;
|
||||
use React\Socket\ServerInterface;
|
||||
|
||||
class ServerStub extends EventEmitter implements ServerInterface
|
||||
{
|
||||
public function getAddress()
|
||||
{
|
||||
return '127.0.0.1:80';
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
}
|
||||
260
vendor/react/socket/tests/TcpConnectorTest.php
vendored
Executable file
260
vendor/react/socket/tests/TcpConnectorTest.php
vendored
Executable file
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use Clue\React\Block;
|
||||
use React\EventLoop\Factory;
|
||||
use React\Socket\ConnectionInterface;
|
||||
use React\Socket\TcpConnector;
|
||||
use React\Socket\TcpServer;
|
||||
|
||||
class TcpConnectorTest extends TestCase
|
||||
{
|
||||
const TIMEOUT = 0.1;
|
||||
|
||||
/** @test */
|
||||
public function connectionToEmptyPortShouldFail()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$connector->connect('127.0.0.1:9999')
|
||||
->then($this->expectCallableNever(), $this->expectCallableOnce());
|
||||
|
||||
$loop->run();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToTcpServerShouldAddResourceToLoop()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$connector = new TcpConnector($loop);
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
|
||||
$valid = false;
|
||||
$loop->expects($this->once())->method('addWriteStream')->with($this->callback(function ($arg) use (&$valid) {
|
||||
$valid = is_resource($arg);
|
||||
return true;
|
||||
}));
|
||||
$connector->connect($server->getAddress());
|
||||
|
||||
$this->assertTrue($valid);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToTcpServerShouldSucceed()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(9999, $loop);
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
$server->on('connection', array($server, 'close'));
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
|
||||
$connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT);
|
||||
|
||||
$this->assertInstanceOf('React\Socket\ConnectionInterface', $connection);
|
||||
|
||||
$connection->close();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToTcpServerShouldSucceedWithRemoteAdressSameAsTarget()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(9999, $loop);
|
||||
$server->on('connection', array($server, 'close'));
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
|
||||
$connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT);
|
||||
/* @var $connection ConnectionInterface */
|
||||
|
||||
$this->assertEquals('tcp://127.0.0.1:9999', $connection->getRemoteAddress());
|
||||
|
||||
$connection->close();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToTcpServerShouldSucceedWithLocalAdressOnLocalhost()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(9999, $loop);
|
||||
$server->on('connection', array($server, 'close'));
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
|
||||
$connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT);
|
||||
/* @var $connection ConnectionInterface */
|
||||
|
||||
$this->assertContains('tcp://127.0.0.1:', $connection->getLocalAddress());
|
||||
$this->assertNotEquals('tcp://127.0.0.1:9999', $connection->getLocalAddress());
|
||||
|
||||
$connection->close();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToTcpServerShouldSucceedWithNullAddressesAfterConnectionClosed()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$server = new TcpServer(9999, $loop);
|
||||
$server->on('connection', array($server, 'close'));
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
|
||||
$connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT);
|
||||
/* @var $connection ConnectionInterface */
|
||||
|
||||
$connection->close();
|
||||
|
||||
$this->assertNull($connection->getRemoteAddress());
|
||||
$this->assertNull($connection->getLocalAddress());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToTcpServerWillCloseWhenOtherSideCloses()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
// immediately close connection and server once connection is in
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server->on('connection', function (ConnectionInterface $conn) use ($server) {
|
||||
$conn->close();
|
||||
$server->close();
|
||||
});
|
||||
|
||||
$once = $this->expectCallableOnce();
|
||||
$connector = new TcpConnector($loop);
|
||||
$connector->connect($server->getAddress())->then(function (ConnectionInterface $conn) use ($once) {
|
||||
$conn->write('hello');
|
||||
$conn->on('close', $once);
|
||||
});
|
||||
|
||||
$loop->run();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToEmptyIp6PortShouldFail()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$connector
|
||||
->connect('[::1]:9999')
|
||||
->then($this->expectCallableNever(), $this->expectCallableOnce());
|
||||
|
||||
$loop->run();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToIp6TcpServerShouldSucceed()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
|
||||
try {
|
||||
$server = new TcpServer('[::1]:9999', $loop);
|
||||
} catch (\Exception $e) {
|
||||
$this->markTestSkipped('Unable to start IPv6 server socket (IPv6 not supported on this system?)');
|
||||
}
|
||||
|
||||
$server->on('connection', $this->expectCallableOnce());
|
||||
$server->on('connection', array($server, 'close'));
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
|
||||
$connection = Block\await($connector->connect('[::1]:9999'), $loop, self::TIMEOUT);
|
||||
/* @var $connection ConnectionInterface */
|
||||
|
||||
$this->assertEquals('tcp://[::1]:9999', $connection->getRemoteAddress());
|
||||
|
||||
$this->assertContains('tcp://[::1]:', $connection->getLocalAddress());
|
||||
$this->assertNotEquals('tcp://[::1]:9999', $connection->getLocalAddress());
|
||||
|
||||
$connection->close();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToHostnameShouldFailImmediately()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$connector->connect('www.google.com:80')->then(
|
||||
$this->expectCallableNever(),
|
||||
$this->expectCallableOnce()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToInvalidPortShouldFailImmediately()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$connector->connect('255.255.255.255:12345678')->then(
|
||||
$this->expectCallableNever(),
|
||||
$this->expectCallableOnce()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function connectionToInvalidSchemeShouldFailImmediately()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
|
||||
$connector = new TcpConnector($loop);
|
||||
$connector->connect('tls://google.com:443')->then(
|
||||
$this->expectCallableNever(),
|
||||
$this->expectCallableOnce()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function cancellingConnectionShouldRemoveResourceFromLoopAndCloseResource()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$connector = new TcpConnector($loop);
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server->on('connection', $this->expectCallableNever());
|
||||
|
||||
$loop->expects($this->once())->method('addWriteStream');
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
|
||||
$resource = null;
|
||||
$valid = false;
|
||||
$loop->expects($this->once())->method('removeWriteStream')->with($this->callback(function ($arg) use (&$resource, &$valid) {
|
||||
$resource = $arg;
|
||||
$valid = is_resource($arg);
|
||||
return true;
|
||||
}));
|
||||
$promise->cancel();
|
||||
|
||||
// ensure that this was a valid resource during the removeWriteStream() call
|
||||
$this->assertTrue($valid);
|
||||
|
||||
// ensure that this resource should now be closed after the cancel() call
|
||||
$this->assertInternalType('resource', $resource);
|
||||
$this->assertFalse(is_resource($resource));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function cancellingConnectionShouldRejectPromise()
|
||||
{
|
||||
$loop = Factory::create();
|
||||
$connector = new TcpConnector($loop);
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
|
||||
$promise = $connector->connect($server->getAddress());
|
||||
$promise->cancel();
|
||||
|
||||
$this->setExpectedException('RuntimeException', 'Cancelled');
|
||||
Block\await($promise, $loop);
|
||||
}
|
||||
}
|
||||
285
vendor/react/socket/tests/TcpServerTest.php
vendored
Executable file
285
vendor/react/socket/tests/TcpServerTest.php
vendored
Executable file
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use Clue\React\Block;
|
||||
use React\EventLoop\Factory;
|
||||
use React\Socket\TcpServer;
|
||||
use React\Stream\DuplexResourceStream;
|
||||
|
||||
class TcpServerTest extends TestCase
|
||||
{
|
||||
private $loop;
|
||||
private $server;
|
||||
private $port;
|
||||
|
||||
private function createLoop()
|
||||
{
|
||||
return Factory::create();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers React\Socket\TcpServer::__construct
|
||||
* @covers React\Socket\TcpServer::getAddress
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$this->loop = $this->createLoop();
|
||||
$this->server = new TcpServer(0, $this->loop);
|
||||
|
||||
$this->port = parse_url($this->server->getAddress(), PHP_URL_PORT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers React\Socket\TcpServer::handleConnection
|
||||
*/
|
||||
public function testConnection()
|
||||
{
|
||||
$client = stream_socket_client('tcp://localhost:'.$this->port);
|
||||
|
||||
$this->server->on('connection', $this->expectCallableOnce());
|
||||
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers React\Socket\TcpServer::handleConnection
|
||||
*/
|
||||
public function testConnectionWithManyClients()
|
||||
{
|
||||
$client1 = stream_socket_client('tcp://localhost:'.$this->port);
|
||||
$client2 = stream_socket_client('tcp://localhost:'.$this->port);
|
||||
$client3 = stream_socket_client('tcp://localhost:'.$this->port);
|
||||
|
||||
$this->server->on('connection', $this->expectCallableExactly(3));
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
public function testDataEventWillNotBeEmittedWhenClientSendsNoData()
|
||||
{
|
||||
$client = stream_socket_client('tcp://localhost:'.$this->port);
|
||||
|
||||
$mock = $this->expectCallableNever();
|
||||
|
||||
$this->server->on('connection', function ($conn) use ($mock) {
|
||||
$conn->on('data', $mock);
|
||||
});
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
public function testDataWillBeEmittedWithDataClientSends()
|
||||
{
|
||||
$client = stream_socket_client('tcp://localhost:'.$this->port);
|
||||
|
||||
fwrite($client, "foo\n");
|
||||
|
||||
$mock = $this->expectCallableOnceWith("foo\n");
|
||||
|
||||
$this->server->on('connection', function ($conn) use ($mock) {
|
||||
$conn->on('data', $mock);
|
||||
});
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
public function testDataWillBeEmittedEvenWhenClientShutsDownAfterSending()
|
||||
{
|
||||
$client = stream_socket_client('tcp://localhost:' . $this->port);
|
||||
fwrite($client, "foo\n");
|
||||
stream_socket_shutdown($client, STREAM_SHUT_WR);
|
||||
|
||||
$mock = $this->expectCallableOnceWith("foo\n");
|
||||
|
||||
$this->server->on('connection', function ($conn) use ($mock) {
|
||||
$conn->on('data', $mock);
|
||||
});
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
public function testLoopWillEndWhenServerIsClosed()
|
||||
{
|
||||
// explicitly unset server because we already call close()
|
||||
$this->server->close();
|
||||
$this->server = null;
|
||||
|
||||
$this->loop->run();
|
||||
|
||||
// if we reach this, then everything is good
|
||||
$this->assertNull(null);
|
||||
}
|
||||
|
||||
public function testCloseTwiceIsNoOp()
|
||||
{
|
||||
$this->server->close();
|
||||
$this->server->close();
|
||||
|
||||
// if we reach this, then everything is good
|
||||
$this->assertNull(null);
|
||||
}
|
||||
|
||||
public function testGetAddressAfterCloseReturnsNull()
|
||||
{
|
||||
$this->server->close();
|
||||
$this->assertNull($this->server->getAddress());
|
||||
}
|
||||
|
||||
public function testLoopWillEndWhenServerIsClosedAfterSingleConnection()
|
||||
{
|
||||
$client = stream_socket_client('tcp://localhost:' . $this->port);
|
||||
|
||||
// explicitly unset server because we only accept a single connection
|
||||
// and then already call close()
|
||||
$server = $this->server;
|
||||
$this->server = null;
|
||||
|
||||
$server->on('connection', function ($conn) use ($server) {
|
||||
$conn->close();
|
||||
$server->close();
|
||||
});
|
||||
|
||||
$this->loop->run();
|
||||
|
||||
// if we reach this, then everything is good
|
||||
$this->assertNull(null);
|
||||
}
|
||||
|
||||
public function testDataWillBeEmittedInMultipleChunksWhenClientSendsExcessiveAmounts()
|
||||
{
|
||||
$client = stream_socket_client('tcp://localhost:' . $this->port);
|
||||
$stream = new DuplexResourceStream($client, $this->loop);
|
||||
|
||||
$bytes = 1024 * 1024;
|
||||
$stream->end(str_repeat('*', $bytes));
|
||||
|
||||
$mock = $this->expectCallableOnce();
|
||||
|
||||
// explicitly unset server because we only accept a single connection
|
||||
// and then already call close()
|
||||
$server = $this->server;
|
||||
$this->server = null;
|
||||
|
||||
$received = 0;
|
||||
$server->on('connection', function ($conn) use ($mock, &$received, $server) {
|
||||
// count number of bytes received
|
||||
$conn->on('data', function ($data) use (&$received) {
|
||||
$received += strlen($data);
|
||||
});
|
||||
|
||||
$conn->on('end', $mock);
|
||||
|
||||
// do not await any further connections in order to let the loop terminate
|
||||
$server->close();
|
||||
});
|
||||
|
||||
$this->loop->run();
|
||||
|
||||
$this->assertEquals($bytes, $received);
|
||||
}
|
||||
|
||||
public function testConnectionDoesNotEndWhenClientDoesNotClose()
|
||||
{
|
||||
$client = stream_socket_client('tcp://localhost:'.$this->port);
|
||||
|
||||
$mock = $this->expectCallableNever();
|
||||
|
||||
$this->server->on('connection', function ($conn) use ($mock) {
|
||||
$conn->on('end', $mock);
|
||||
});
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers React\Socket\Connection::end
|
||||
*/
|
||||
public function testConnectionDoesEndWhenClientCloses()
|
||||
{
|
||||
$client = stream_socket_client('tcp://localhost:'.$this->port);
|
||||
|
||||
fclose($client);
|
||||
|
||||
$mock = $this->expectCallableOnce();
|
||||
|
||||
$this->server->on('connection', function ($conn) use ($mock) {
|
||||
$conn->on('end', $mock);
|
||||
});
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
public function testCtorAddsResourceToLoop()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('addReadStream');
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
}
|
||||
|
||||
public function testResumeWithoutPauseIsNoOp()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('addReadStream');
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server->resume();
|
||||
}
|
||||
|
||||
public function testPauseRemovesResourceFromLoop()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('removeReadStream');
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server->pause();
|
||||
}
|
||||
|
||||
public function testPauseAfterPauseIsNoOp()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('removeReadStream');
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server->pause();
|
||||
$server->pause();
|
||||
}
|
||||
|
||||
public function testCloseRemovesResourceFromLoop()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('removeReadStream');
|
||||
|
||||
$server = new TcpServer(0, $loop);
|
||||
$server->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testListenOnBusyPortThrows()
|
||||
{
|
||||
if (DIRECTORY_SEPARATOR === '\\') {
|
||||
$this->markTestSkipped('Windows supports listening on same port multiple times');
|
||||
}
|
||||
|
||||
$another = new TcpServer($this->port, $this->loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers React\Socket\TcpServer::close
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
if ($this->server) {
|
||||
$this->server->close();
|
||||
}
|
||||
}
|
||||
|
||||
private function tick()
|
||||
{
|
||||
Block\sleep(0, $this->loop);
|
||||
}
|
||||
}
|
||||
101
vendor/react/socket/tests/TestCase.php
vendored
Executable file
101
vendor/react/socket/tests/TestCase.php
vendored
Executable file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\Stream\ReadableStreamInterface;
|
||||
use React\EventLoop\LoopInterface;
|
||||
use Clue\React\Block;
|
||||
use React\Promise\Promise;
|
||||
use PHPUnit\Framework\TestCase as BaseTestCase;
|
||||
|
||||
class TestCase extends BaseTestCase
|
||||
{
|
||||
protected function expectCallableExactly($amount)
|
||||
{
|
||||
$mock = $this->createCallableMock();
|
||||
$mock
|
||||
->expects($this->exactly($amount))
|
||||
->method('__invoke');
|
||||
|
||||
return $mock;
|
||||
}
|
||||
|
||||
protected function expectCallableOnce()
|
||||
{
|
||||
$mock = $this->createCallableMock();
|
||||
$mock
|
||||
->expects($this->once())
|
||||
->method('__invoke');
|
||||
|
||||
return $mock;
|
||||
}
|
||||
|
||||
protected function expectCallableOnceWith($value)
|
||||
{
|
||||
$mock = $this->createCallableMock();
|
||||
$mock
|
||||
->expects($this->once())
|
||||
->method('__invoke')
|
||||
->with($value);
|
||||
|
||||
return $mock;
|
||||
}
|
||||
|
||||
protected function expectCallableNever()
|
||||
{
|
||||
$mock = $this->createCallableMock();
|
||||
$mock
|
||||
->expects($this->never())
|
||||
->method('__invoke');
|
||||
|
||||
return $mock;
|
||||
}
|
||||
|
||||
protected function createCallableMock()
|
||||
{
|
||||
return $this->getMockBuilder('React\Tests\Socket\Stub\CallableStub')->getMock();
|
||||
}
|
||||
|
||||
protected function buffer(ReadableStreamInterface $stream, LoopInterface $loop, $timeout)
|
||||
{
|
||||
if (!$stream->isReadable()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return Block\await(new Promise(
|
||||
function ($resolve, $reject) use ($stream) {
|
||||
$buffer = '';
|
||||
$stream->on('data', function ($chunk) use (&$buffer) {
|
||||
$buffer .= $chunk;
|
||||
});
|
||||
|
||||
$stream->on('error', $reject);
|
||||
|
||||
$stream->on('close', function () use (&$buffer, $resolve) {
|
||||
$resolve($buffer);
|
||||
});
|
||||
},
|
||||
function () use ($stream) {
|
||||
$stream->close();
|
||||
throw new \RuntimeException();
|
||||
}
|
||||
), $loop, $timeout);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
103
vendor/react/socket/tests/TimeoutConnectorTest.php
vendored
Executable file
103
vendor/react/socket/tests/TimeoutConnectorTest.php
vendored
Executable file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\Socket\TimeoutConnector;
|
||||
use React\Promise;
|
||||
use React\EventLoop\Factory;
|
||||
|
||||
class TimeoutConnectorTest extends TestCase
|
||||
{
|
||||
public function testRejectsOnTimeout()
|
||||
{
|
||||
$promise = new Promise\Promise(function () { });
|
||||
|
||||
$connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise));
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$timeout = new TimeoutConnector($connector, 0.01, $loop);
|
||||
|
||||
$timeout->connect('google.com:80')->then(
|
||||
$this->expectCallableNever(),
|
||||
$this->expectCallableOnce()
|
||||
);
|
||||
|
||||
$loop->run();
|
||||
}
|
||||
|
||||
public function testRejectsWhenConnectorRejects()
|
||||
{
|
||||
$promise = Promise\reject(new \RuntimeException());
|
||||
|
||||
$connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise));
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$timeout = new TimeoutConnector($connector, 5.0, $loop);
|
||||
|
||||
$timeout->connect('google.com:80')->then(
|
||||
$this->expectCallableNever(),
|
||||
$this->expectCallableOnce()
|
||||
);
|
||||
|
||||
$loop->run();
|
||||
}
|
||||
|
||||
public function testResolvesWhenConnectorResolves()
|
||||
{
|
||||
$promise = Promise\resolve();
|
||||
|
||||
$connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise));
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$timeout = new TimeoutConnector($connector, 5.0, $loop);
|
||||
|
||||
$timeout->connect('google.com:80')->then(
|
||||
$this->expectCallableOnce(),
|
||||
$this->expectCallableNever()
|
||||
);
|
||||
|
||||
$loop->run();
|
||||
}
|
||||
|
||||
public function testRejectsAndCancelsPendingPromiseOnTimeout()
|
||||
{
|
||||
$promise = new Promise\Promise(function () { }, $this->expectCallableOnce());
|
||||
|
||||
$connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise));
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$timeout = new TimeoutConnector($connector, 0.01, $loop);
|
||||
|
||||
$timeout->connect('google.com:80')->then(
|
||||
$this->expectCallableNever(),
|
||||
$this->expectCallableOnce()
|
||||
);
|
||||
|
||||
$loop->run();
|
||||
}
|
||||
|
||||
public function testCancelsPendingPromiseOnCancel()
|
||||
{
|
||||
$promise = new Promise\Promise(function () { }, function () { throw new \Exception(); });
|
||||
|
||||
$connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
|
||||
$connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise));
|
||||
|
||||
$loop = Factory::create();
|
||||
|
||||
$timeout = new TimeoutConnector($connector, 0.01, $loop);
|
||||
|
||||
$out = $timeout->connect('google.com:80');
|
||||
$out->cancel();
|
||||
|
||||
$out->then($this->expectCallableNever(), $this->expectCallableOnce());
|
||||
}
|
||||
}
|
||||
64
vendor/react/socket/tests/UnixConnectorTest.php
vendored
Executable file
64
vendor/react/socket/tests/UnixConnectorTest.php
vendored
Executable file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use React\Socket\ConnectionInterface;
|
||||
use React\Socket\UnixConnector;
|
||||
|
||||
class UnixConnectorTest extends TestCase
|
||||
{
|
||||
private $loop;
|
||||
private $connector;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$this->connector = new UnixConnector($this->loop);
|
||||
}
|
||||
|
||||
public function testInvalid()
|
||||
{
|
||||
$promise = $this->connector->connect('google.com:80');
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testInvalidScheme()
|
||||
{
|
||||
$promise = $this->connector->connect('tcp://google.com:80');
|
||||
$promise->then(null, $this->expectCallableOnce());
|
||||
}
|
||||
|
||||
public function testValid()
|
||||
{
|
||||
// random unix domain socket path
|
||||
$path = sys_get_temp_dir() . '/test' . uniqid() . '.sock';
|
||||
|
||||
// temporarily create unix domain socket server to connect to
|
||||
$server = stream_socket_server('unix://' . $path, $errno, $errstr);
|
||||
|
||||
// skip test if we can not create a test server (Windows etc.)
|
||||
if (!$server) {
|
||||
$this->markTestSkipped('Unable to create socket "' . $path . '": ' . $errstr . '(' . $errno .')');
|
||||
return;
|
||||
}
|
||||
|
||||
// tests succeeds if we get notified of successful connection
|
||||
$promise = $this->connector->connect($path);
|
||||
$promise->then($this->expectCallableOnce());
|
||||
|
||||
// remember remote and local address of this connection and close again
|
||||
$remote = $local = false;
|
||||
$promise->then(function(ConnectionInterface $conn) use (&$remote, &$local) {
|
||||
$remote = $conn->getRemoteAddress();
|
||||
$local = $conn->getLocalAddress();
|
||||
$conn->close();
|
||||
});
|
||||
|
||||
// clean up server
|
||||
fclose($server);
|
||||
unlink($path);
|
||||
|
||||
$this->assertNull($local);
|
||||
$this->assertEquals('unix://' . $path, $remote);
|
||||
}
|
||||
}
|
||||
283
vendor/react/socket/tests/UnixServerTest.php
vendored
Executable file
283
vendor/react/socket/tests/UnixServerTest.php
vendored
Executable file
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
|
||||
namespace React\Tests\Socket;
|
||||
|
||||
use Clue\React\Block;
|
||||
use React\EventLoop\Factory;
|
||||
use React\Socket\UnixServer;
|
||||
use React\Stream\DuplexResourceStream;
|
||||
|
||||
class UnixServerTest extends TestCase
|
||||
{
|
||||
private $loop;
|
||||
private $server;
|
||||
private $uds;
|
||||
|
||||
/**
|
||||
* @covers React\Socket\UnixServer::__construct
|
||||
* @covers React\Socket\UnixServer::getAddress
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$this->loop = Factory::create();
|
||||
$this->uds = $this->getRandomSocketUri();
|
||||
$this->server = new UnixServer($this->uds, $this->loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers React\Socket\UnixServer::handleConnection
|
||||
*/
|
||||
public function testConnection()
|
||||
{
|
||||
$client = stream_socket_client($this->uds);
|
||||
|
||||
$this->server->on('connection', $this->expectCallableOnce());
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers React\Socket\UnixServer::handleConnection
|
||||
*/
|
||||
public function testConnectionWithManyClients()
|
||||
{
|
||||
$client1 = stream_socket_client($this->uds);
|
||||
$client2 = stream_socket_client($this->uds);
|
||||
$client3 = stream_socket_client($this->uds);
|
||||
|
||||
$this->server->on('connection', $this->expectCallableExactly(3));
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
public function testDataEventWillNotBeEmittedWhenClientSendsNoData()
|
||||
{
|
||||
$client = stream_socket_client($this->uds);
|
||||
|
||||
$mock = $this->expectCallableNever();
|
||||
|
||||
$this->server->on('connection', function ($conn) use ($mock) {
|
||||
$conn->on('data', $mock);
|
||||
});
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
public function testDataWillBeEmittedWithDataClientSends()
|
||||
{
|
||||
$client = stream_socket_client($this->uds);
|
||||
|
||||
fwrite($client, "foo\n");
|
||||
|
||||
$mock = $this->expectCallableOnceWith("foo\n");
|
||||
|
||||
$this->server->on('connection', function ($conn) use ($mock) {
|
||||
$conn->on('data', $mock);
|
||||
});
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
public function testDataWillBeEmittedEvenWhenClientShutsDownAfterSending()
|
||||
{
|
||||
$client = stream_socket_client($this->uds);
|
||||
fwrite($client, "foo\n");
|
||||
stream_socket_shutdown($client, STREAM_SHUT_WR);
|
||||
|
||||
$mock = $this->expectCallableOnceWith("foo\n");
|
||||
|
||||
$this->server->on('connection', function ($conn) use ($mock) {
|
||||
$conn->on('data', $mock);
|
||||
});
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
public function testLoopWillEndWhenServerIsClosed()
|
||||
{
|
||||
// explicitly unset server because we already call close()
|
||||
$this->server->close();
|
||||
$this->server = null;
|
||||
|
||||
$this->loop->run();
|
||||
|
||||
// if we reach this, then everything is good
|
||||
$this->assertNull(null);
|
||||
}
|
||||
|
||||
public function testCloseTwiceIsNoOp()
|
||||
{
|
||||
$this->server->close();
|
||||
$this->server->close();
|
||||
|
||||
// if we reach this, then everything is good
|
||||
$this->assertNull(null);
|
||||
}
|
||||
|
||||
public function testGetAddressAfterCloseReturnsNull()
|
||||
{
|
||||
$this->server->close();
|
||||
$this->assertNull($this->server->getAddress());
|
||||
}
|
||||
|
||||
public function testLoopWillEndWhenServerIsClosedAfterSingleConnection()
|
||||
{
|
||||
$client = stream_socket_client($this->uds);
|
||||
|
||||
// explicitly unset server because we only accept a single connection
|
||||
// and then already call close()
|
||||
$server = $this->server;
|
||||
$this->server = null;
|
||||
|
||||
$server->on('connection', function ($conn) use ($server) {
|
||||
$conn->close();
|
||||
$server->close();
|
||||
});
|
||||
|
||||
$this->loop->run();
|
||||
|
||||
// if we reach this, then everything is good
|
||||
$this->assertNull(null);
|
||||
}
|
||||
|
||||
public function testDataWillBeEmittedInMultipleChunksWhenClientSendsExcessiveAmounts()
|
||||
{
|
||||
$client = stream_socket_client($this->uds);
|
||||
$stream = new DuplexResourceStream($client, $this->loop);
|
||||
|
||||
$bytes = 1024 * 1024;
|
||||
$stream->end(str_repeat('*', $bytes));
|
||||
|
||||
$mock = $this->expectCallableOnce();
|
||||
|
||||
// explicitly unset server because we only accept a single connection
|
||||
// and then already call close()
|
||||
$server = $this->server;
|
||||
$this->server = null;
|
||||
|
||||
$received = 0;
|
||||
$server->on('connection', function ($conn) use ($mock, &$received, $server) {
|
||||
// count number of bytes received
|
||||
$conn->on('data', function ($data) use (&$received) {
|
||||
$received += strlen($data);
|
||||
});
|
||||
|
||||
$conn->on('end', $mock);
|
||||
|
||||
// do not await any further connections in order to let the loop terminate
|
||||
$server->close();
|
||||
});
|
||||
|
||||
$this->loop->run();
|
||||
|
||||
$this->assertEquals($bytes, $received);
|
||||
}
|
||||
|
||||
public function testConnectionDoesNotEndWhenClientDoesNotClose()
|
||||
{
|
||||
$client = stream_socket_client($this->uds);
|
||||
|
||||
$mock = $this->expectCallableNever();
|
||||
|
||||
$this->server->on('connection', function ($conn) use ($mock) {
|
||||
$conn->on('end', $mock);
|
||||
});
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers React\Socket\Connection::end
|
||||
*/
|
||||
public function testConnectionDoesEndWhenClientCloses()
|
||||
{
|
||||
$client = stream_socket_client($this->uds);
|
||||
|
||||
fclose($client);
|
||||
|
||||
$mock = $this->expectCallableOnce();
|
||||
|
||||
$this->server->on('connection', function ($conn) use ($mock) {
|
||||
$conn->on('end', $mock);
|
||||
});
|
||||
$this->tick();
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
public function testCtorAddsResourceToLoop()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('addReadStream');
|
||||
|
||||
$server = new UnixServer($this->getRandomSocketUri(), $loop);
|
||||
}
|
||||
|
||||
public function testResumeWithoutPauseIsNoOp()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('addReadStream');
|
||||
|
||||
$server = new UnixServer($this->getRandomSocketUri(), $loop);
|
||||
$server->resume();
|
||||
}
|
||||
|
||||
public function testPauseRemovesResourceFromLoop()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('removeReadStream');
|
||||
|
||||
$server = new UnixServer($this->getRandomSocketUri(), $loop);
|
||||
$server->pause();
|
||||
}
|
||||
|
||||
public function testPauseAfterPauseIsNoOp()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('removeReadStream');
|
||||
|
||||
$server = new UnixServer($this->getRandomSocketUri(), $loop);
|
||||
$server->pause();
|
||||
$server->pause();
|
||||
}
|
||||
|
||||
public function testCloseRemovesResourceFromLoop()
|
||||
{
|
||||
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
|
||||
$loop->expects($this->once())->method('removeReadStream');
|
||||
|
||||
$server = new UnixServer($this->getRandomSocketUri(), $loop);
|
||||
$server->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testListenOnBusyPortThrows()
|
||||
{
|
||||
if (DIRECTORY_SEPARATOR === '\\') {
|
||||
$this->markTestSkipped('Windows supports listening on same port multiple times');
|
||||
}
|
||||
|
||||
$another = new UnixServer($this->uds, $this->loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers React\Socket\UnixServer::close
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
if ($this->server) {
|
||||
$this->server->close();
|
||||
}
|
||||
}
|
||||
|
||||
private function getRandomSocketUri()
|
||||
{
|
||||
return "unix://" . sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid(rand(), true) . '.sock';
|
||||
}
|
||||
|
||||
private function tick()
|
||||
{
|
||||
Block\sleep(0, $this->loop);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user