<?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);
}
}