2017-05-16 23:27:48 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Amp\ByteStream\Test;
|
|
|
|
|
|
|
|
use Amp\ByteStream\ResourceOutputStream;
|
2018-04-03 18:20:40 +02:00
|
|
|
use Amp\ByteStream\StreamException;
|
2019-07-15 16:16:07 +02:00
|
|
|
use Amp\Loop;
|
2017-05-16 23:27:48 +02:00
|
|
|
use PHPUnit\Framework\TestCase;
|
2019-07-15 16:16:07 +02:00
|
|
|
use function Amp\ByteStream\bufferEcho;
|
2018-04-03 18:20:40 +02:00
|
|
|
use function Amp\Promise\wait;
|
2017-05-16 23:27:48 +02:00
|
|
|
|
2018-09-21 22:45:13 +02:00
|
|
|
class ResourceOutputStreamTest extends TestCase
|
|
|
|
{
|
|
|
|
public function testGetResource()
|
|
|
|
{
|
2017-05-16 23:27:48 +02:00
|
|
|
$stream = new ResourceOutputStream(\STDOUT);
|
|
|
|
|
|
|
|
$this->assertSame(\STDOUT, $stream->getResource());
|
|
|
|
}
|
|
|
|
|
2018-09-21 22:45:13 +02:00
|
|
|
public function testNonStream()
|
|
|
|
{
|
2017-05-16 23:27:48 +02:00
|
|
|
$this->expectException(\Error::class);
|
|
|
|
$this->expectExceptionMessage("Expected a valid stream");
|
|
|
|
|
|
|
|
new ResourceOutputStream(42);
|
|
|
|
}
|
|
|
|
|
2018-09-21 22:45:13 +02:00
|
|
|
public function testNotWritable()
|
|
|
|
{
|
2017-05-16 23:27:48 +02:00
|
|
|
$this->expectException(\Error::class);
|
|
|
|
$this->expectExceptionMessage("Expected a writable stream");
|
|
|
|
|
|
|
|
new ResourceOutputStream(\STDIN);
|
|
|
|
}
|
2018-04-03 18:20:40 +02:00
|
|
|
|
2018-09-21 22:45:13 +02:00
|
|
|
public function testBrokenPipe()
|
|
|
|
{
|
2018-04-03 18:20:40 +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) {
|
|
|
|
$this->fail("Failed to create socket pair.");
|
|
|
|
}
|
|
|
|
|
|
|
|
list($a, $b) = $sockets;
|
|
|
|
|
|
|
|
$stream = new ResourceOutputStream($a);
|
|
|
|
\fclose($b);
|
|
|
|
|
|
|
|
$this->expectException(StreamException::class);
|
2019-06-03 23:45:17 +02:00
|
|
|
$this->expectExceptionMessage("Failed to write to stream after multiple attempts; fwrite(): send of 6 bytes failed with errno=32 Broken pipe");
|
2018-04-03 18:20:40 +02:00
|
|
|
wait($stream->write("foobar"));
|
|
|
|
}
|
|
|
|
|
2018-09-21 22:45:13 +02:00
|
|
|
public function testClosedRemoteSocket()
|
|
|
|
{
|
2018-04-03 18:20:40 +02:00
|
|
|
$server = \stream_socket_server("tcp://127.0.0.1:0");
|
|
|
|
$address = \stream_socket_get_name($server, false);
|
|
|
|
|
|
|
|
$a = \stream_socket_client("tcp://" . $address);
|
|
|
|
$b = \stream_socket_accept($server);
|
|
|
|
|
|
|
|
$stream = new ResourceOutputStream($a);
|
|
|
|
\fclose($b);
|
|
|
|
|
|
|
|
$this->expectException(StreamException::class);
|
2019-06-03 23:45:17 +02:00
|
|
|
$this->expectExceptionMessage("Failed to write to stream after multiple attempts; fwrite(): send of 6 bytes failed with errno=32 Broken pipe");
|
2018-04-03 18:20:40 +02:00
|
|
|
|
|
|
|
// The first write still succeeds somehow...
|
|
|
|
wait($stream->write("foobar"));
|
|
|
|
wait($stream->write("foobar"));
|
|
|
|
}
|
2019-07-15 16:16:07 +02:00
|
|
|
|
|
|
|
public function testEcho()
|
|
|
|
{
|
|
|
|
Loop::run(function () {
|
|
|
|
$data = "\n".\base64_encode(\random_bytes(10))."\n";
|
|
|
|
$found = false;
|
|
|
|
\ob_start(static function ($match) use (&$found, $data) {
|
|
|
|
if ($match === $data) {
|
|
|
|
$found = true;
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
return $match;
|
|
|
|
});
|
|
|
|
yield bufferEcho($data);
|
|
|
|
\ob_end_flush();
|
|
|
|
$this->assertTrue($found, "Data wasn't sent to the output buffer");
|
|
|
|
});
|
|
|
|
}
|
2017-05-16 23:27:48 +02:00
|
|
|
}
|