2016-12-30 02:16:04 +01:00
|
|
|
<?php
|
2016-08-31 01:27:14 +02:00
|
|
|
|
|
|
|
namespace Amp\Parallel\Test\Sync;
|
|
|
|
|
2019-08-27 19:17:41 +02:00
|
|
|
use Amp\Parallel\Sync\ChannelException;
|
2016-08-31 01:27:14 +02:00
|
|
|
use Amp\Parallel\Sync\ChannelledSocket;
|
2019-08-27 19:17:41 +02:00
|
|
|
use Amp\Parallel\Sync\SerializationException;
|
|
|
|
use Amp\PHPUnit\AsyncTestCase;
|
2016-08-31 01:27:14 +02:00
|
|
|
|
2019-08-27 19:17:41 +02:00
|
|
|
class ChannelledSocketTest extends AsyncTestCase
|
2018-10-07 16:50:45 +02:00
|
|
|
{
|
2016-08-31 01:27:14 +02:00
|
|
|
/**
|
|
|
|
* @return resource[]
|
|
|
|
*/
|
2018-10-07 16:50:45 +02:00
|
|
|
protected function createSockets()
|
|
|
|
{
|
2016-08-31 01:27:14 +02:00
|
|
|
if (($sockets = @\stream_socket_pair(\stripos(PHP_OS, "win") === 0 ? STREAM_PF_INET : STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP)) === false) {
|
|
|
|
$message = "Failed to create socket pair";
|
|
|
|
if ($error = \error_get_last()) {
|
|
|
|
$message .= \sprintf(" Errno: %d; %s", $error["type"], $error["message"]);
|
|
|
|
}
|
|
|
|
$this->fail($message);
|
|
|
|
}
|
|
|
|
return $sockets;
|
|
|
|
}
|
2017-05-18 09:51:31 +02:00
|
|
|
|
2018-10-07 16:50:45 +02:00
|
|
|
public function testSendReceive()
|
|
|
|
{
|
2019-08-27 19:17:41 +02:00
|
|
|
list($left, $right) = $this->createSockets();
|
|
|
|
$a = new ChannelledSocket($left, $left);
|
|
|
|
$b = new ChannelledSocket($right, $right);
|
2016-08-31 01:27:14 +02:00
|
|
|
|
2019-08-27 19:17:41 +02:00
|
|
|
$message = 'hello';
|
2016-08-31 01:27:14 +02:00
|
|
|
|
2019-08-27 19:17:41 +02:00
|
|
|
yield $a->send($message);
|
|
|
|
$data = yield $b->receive();
|
|
|
|
$this->assertSame($message, $data);
|
2016-08-31 01:27:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testSendReceive
|
|
|
|
*/
|
2018-10-07 16:50:45 +02:00
|
|
|
public function testSendReceiveLongData()
|
|
|
|
{
|
2019-08-27 19:17:41 +02:00
|
|
|
list($left, $right) = $this->createSockets();
|
|
|
|
$a = new ChannelledSocket($left, $left);
|
|
|
|
$b = new ChannelledSocket($right, $right);
|
|
|
|
|
|
|
|
$length = 0xffff;
|
|
|
|
$message = '';
|
|
|
|
for ($i = 0; $i < $length; ++$i) {
|
|
|
|
$message .= \chr(\mt_rand(0, 255));
|
|
|
|
}
|
2016-08-31 01:27:14 +02:00
|
|
|
|
2019-08-27 19:17:41 +02:00
|
|
|
$a->send($message);
|
|
|
|
$data = yield $b->receive();
|
|
|
|
$this->assertSame($message, $data);
|
2016-08-31 01:27:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testSendReceive
|
|
|
|
*/
|
2018-10-07 16:50:45 +02:00
|
|
|
public function testInvalidDataReceived()
|
|
|
|
{
|
2019-08-27 19:17:41 +02:00
|
|
|
$this->expectException(ChannelException::class);
|
|
|
|
|
|
|
|
list($left, $right) = $this->createSockets();
|
|
|
|
$a = new ChannelledSocket($left, $left);
|
|
|
|
$b = new ChannelledSocket($right, $right);
|
|
|
|
|
|
|
|
\fwrite($left, \pack('L', 10) . '1234567890');
|
|
|
|
$data = yield $b->receive();
|
2016-08-31 01:27:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testSendReceive
|
|
|
|
*/
|
2018-10-07 16:50:45 +02:00
|
|
|
public function testSendUnserializableData()
|
|
|
|
{
|
2019-08-27 19:17:41 +02:00
|
|
|
$this->expectException(SerializationException::class);
|
|
|
|
|
|
|
|
list($left, $right) = $this->createSockets();
|
|
|
|
$a = new ChannelledSocket($left, $left);
|
|
|
|
$b = new ChannelledSocket($right, $right);
|
|
|
|
|
|
|
|
// Close $a. $b should close on next read...
|
|
|
|
yield $a->send(function () {});
|
|
|
|
$data = yield $b->receive();
|
2016-08-31 01:27:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testSendReceive
|
|
|
|
*/
|
2018-10-07 16:50:45 +02:00
|
|
|
public function testSendAfterClose()
|
|
|
|
{
|
2019-08-27 19:17:41 +02:00
|
|
|
$this->expectException(ChannelException::class);
|
2016-08-31 01:27:14 +02:00
|
|
|
|
2019-08-27 19:17:41 +02:00
|
|
|
list($left, $right) = $this->createSockets();
|
|
|
|
$a = new ChannelledSocket($left, $left);
|
|
|
|
$a->close();
|
|
|
|
|
|
|
|
yield $a->send('hello');
|
2016-08-31 01:27:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testSendReceive
|
|
|
|
*/
|
2018-10-07 16:50:45 +02:00
|
|
|
public function testReceiveAfterClose()
|
|
|
|
{
|
2019-08-27 19:17:41 +02:00
|
|
|
$this->expectException(ChannelException::class);
|
|
|
|
|
|
|
|
list($left, $right) = $this->createSockets();
|
|
|
|
$a = new ChannelledSocket($left, $left);
|
|
|
|
$a->close();
|
2016-08-31 01:27:14 +02:00
|
|
|
|
2019-08-27 19:17:41 +02:00
|
|
|
$data = yield $a->receive();
|
2016-08-31 01:27:14 +02:00
|
|
|
}
|
|
|
|
}
|