Skip to content

Commit da790b8

Browse files
committed
Test rejecting streams that do not support non-blocking mode
1 parent 05f5367 commit da790b8

5 files changed

Lines changed: 65 additions & 6 deletions

File tree

‎src/Buffer.php‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ public function __construct($stream, LoopInterface $loop)
2121
throw new \InvalidArgumentException('First parameter must be a valid stream resource');
2222
}
2323

24+
// this class relies on non-blocking I/O in order to not interrupt the event loop
25+
// e.g. pipes on Windows do not support this: https://bugs.php.net/bug.php?id=47918
26+
if (stream_set_blocking($stream, 0) !== true) {
27+
throw new \RuntimeException('Unable to set stream resource to non-blocking mode');
28+
}
29+
2430
$this->stream = $stream;
2531
$this->loop = $loop;
2632
}

‎src/Stream.php‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,13 @@ class Stream extends EventEmitter implements DuplexStreamInterface
3535

3636
public function __construct($stream, LoopInterface $loop, WritableStreamInterface $buffer = null)
3737
{
38-
$this->stream = $stream;
39-
if (!is_resource($this->stream) || get_resource_type($this->stream) !== "stream") {
38+
if (!is_resource($stream) || get_resource_type($stream) !== "stream") {
4039
throw new InvalidArgumentException('First parameter must be a valid stream resource');
4140
}
4241

4342
// this class relies on non-blocking I/O in order to not interrupt the event loop
4443
// e.g. pipes on Windows do not support this: https://bugs.php.net/bug.php?id=47918
45-
if (stream_set_blocking($this->stream, 0) !== true) {
44+
if (stream_set_blocking($stream, 0) !== true) {
4645
throw new \RuntimeException('Unable to set stream resource to non-blocking mode');
4746
}
4847

@@ -53,13 +52,14 @@ public function __construct($stream, LoopInterface $loop, WritableStreamInterfac
5352
// This does not affect the default event loop implementation (level
5453
// triggered), so we can ignore platforms not supporting this (HHVM).
5554
if (function_exists('stream_set_read_buffer')) {
56-
stream_set_read_buffer($this->stream, 0);
55+
stream_set_read_buffer($stream, 0);
5756
}
5857

5958
if ($buffer === null) {
6059
$buffer = new Buffer($stream, $loop);
6160
}
6261

62+
$this->stream = $stream;
6363
$this->loop = $loop;
6464
$this->buffer = $buffer;
6565

‎tests/BufferTest.php‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,29 @@ public function testConstructor()
2020

2121
/**
2222
* @covers React\Stream\Buffer::__construct
23-
* @expectedException InvalidArgumentException
2423
*/
2524
public function testConstructorThrowsIfNotAValidStreamResource()
2625
{
2726
$stream = null;
2827
$loop = $this->createLoopMock();
2928

29+
$this->setExpectedException('InvalidArgumentException');
30+
new Buffer($stream, $loop);
31+
}
32+
33+
/**
34+
* @covers React\Stream\Buffer::__construct
35+
*/
36+
public function testConstructorThrowsExceptionIfStreamDoesNotSupportNonBlocking()
37+
{
38+
if (!in_array('blocking', stream_get_wrappers())) {
39+
stream_wrapper_register('blocking', 'React\Tests\Stream\EnforceBlockingWrapper');
40+
}
41+
42+
$stream = fopen('blocking://test', 'r+');
43+
$loop = $this->createLoopMock();
44+
45+
$this->setExpectedException('RuntimeException');
3046
new Buffer($stream, $loop);
3147
}
3248

‎tests/EnforceBlockingWrapper.php‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace React\Tests\Stream;
4+
5+
class EnforceBlockingWrapper
6+
{
7+
public function stream_open($path, $mode, $options, &$opened_path)
8+
{
9+
return true;
10+
}
11+
12+
public function stream_set_option($option, $arg1, $arg2)
13+
{
14+
if ($option === STREAM_OPTION_BLOCKING) {
15+
return false;
16+
}
17+
18+
return true;
19+
}
20+
}

‎tests/StreamTest.php‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,26 @@ public function testConstructor()
2323
*/
2424
public function testConstructorThrowsExceptionOnInvalidStream()
2525
{
26+
$loop = $this->createLoopMock();
27+
2628
$this->setExpectedException('InvalidArgumentException');
29+
new Stream('breakme', $loop);
30+
}
31+
32+
/**
33+
* @covers React\Stream\Stream::__construct
34+
*/
35+
public function testConstructorThrowsExceptionIfStreamDoesNotSupportNonBlocking()
36+
{
37+
if (!in_array('blocking', stream_get_wrappers())) {
38+
stream_wrapper_register('blocking', 'React\Tests\Stream\EnforceBlockingWrapper');
39+
}
40+
41+
$stream = fopen('blocking://test', 'r+');
2742
$loop = $this->createLoopMock();
28-
$conn = new Stream('breakme', $loop);
43+
44+
$this->setExpectedException('RuntimeException');
45+
new Stream($stream, $loop);
2946
}
3047

3148
/**

0 commit comments

Comments
 (0)