Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 83 additions & 10 deletions tests/AbstractProcessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,22 +68,29 @@ public function testGetTermSignalWhenRunning($process)

public function testProcessWithDefaultCwdAndEnv()
{
$cmd = $this->getPhpBinary() . ' -r ' . escapeshellarg('echo getcwd(), PHP_EOL, count($_SERVER), PHP_EOL;');
$cmd = $this->getPhpCommandLine('echo getcwd(), PHP_EOL, count($_SERVER), PHP_EOL;');

$loop = $this->createLoop();
$process = new Process($cmd);
$process = new Process($cmd, null, null, array("bypass_shell"=>true));

$output = '';
$error = '';

$loop->addTimer(0.001, function(Timer $timer) use ($process, &$output) {
$loop->addTimer(0.001, function(Timer $timer) use ($process, &$output, &$error) {
$process->start($timer->getLoop());
$process->stdout->on('data', function () use (&$output) {
$output .= func_get_arg(0);
$process->stdout->on('data', function ($data) use (&$output) {
$output .= $data;
});
$process->stderr->on('data', function ($data) use (&$error) {
$error .= $data;
});
});

$loop->run();

$this->assertEmpty($error);
$this->assertNotEmpty($output);

list($cwd, $envCount) = explode(PHP_EOL, $output);

/* Child process should inherit the same current working directory and
Expand All @@ -96,10 +103,16 @@ public function testProcessWithDefaultCwdAndEnv()

public function testProcessWithCwd()
{
$cmd = $this->getPhpBinary() . ' -r ' . escapeshellarg('echo getcwd(), PHP_EOL;');
$cmd = $this->getPhpCommandLine('echo getcwd(), PHP_EOL;');

if (defined('PHP_WINDOWS_VERSION_BUILD')) {
$testCwd = 'C:\\';
} else {
$testCwd = '/';
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary? Does getcwd() end up returning a Windows driver letter when we assert on it later even if we pass in /?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly. on Windows , getcwd() will return "C:", even if you pass '/' as the default cwd for the command.


$loop = $this->createLoop();
$process = new Process($cmd, '/');
$process = new Process($cmd, $testCwd, null, array("bypass_shell"=>true));

$output = '';

Expand All @@ -112,7 +125,7 @@ public function testProcessWithCwd()

$loop->run();

$this->assertSame('/' . PHP_EOL, $output);
$this->assertSame($testCwd . PHP_EOL, $output);
}

public function testProcessWithEnv()
Expand All @@ -121,10 +134,16 @@ public function testProcessWithEnv()
$this->markTestSkipped('Cannot execute PHP processes with custom environments on Travis CI.');
}

$cmd = $this->getPhpBinary() . ' -r ' . escapeshellarg('echo getenv("foo"), PHP_EOL;');
$cmd = $this->getPhpCommandLine('echo getenv("foo"), PHP_EOL;');

if (defined('PHP_WINDOWS_VERSION_BUILD')) {
// Windows madness! escapeshellarg seems to completely remove double quotes in Windows!
// We need to use simple quotes in our PHP code!
$cmd = $this->getPhpCommandLine('echo getenv(\'foo\'), PHP_EOL;');
}

$loop = $this->createLoop();
$process = new Process($cmd, null, array('foo' => 'bar'));
$process = new Process($cmd, null, array('foo' => 'bar'), array("bypass_shell"=>true));

$output = '';

Expand Down Expand Up @@ -173,6 +192,10 @@ public function testStartAndAllowProcessToExitSuccessfullyUsingEventLoop()

public function testStartInvalidProcess()
{
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
$this->markTestSkipped('Windows does not have an executable flag. This test does not make sense on Windows.');
}

$cmd = tempnam(sys_get_temp_dir(), 'react');

$loop = $this->createLoop();
Expand Down Expand Up @@ -298,6 +321,51 @@ public function testTerminateWithStopAndContinueSignalsUsingEventLoop()
$this->assertFalse($process->isTerminated());
}

public function outputSizeProvider() {
return [ [1000, 5], [10000, 5], [100000, 5] ];
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These three tests would be better rewritten with the data provider pattern (using the output size as a single argument).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wooh, great idea! Will do!


/**
* @dataProvider outputSizeProvider
*/
public function testProcessOutputOfSize($size, $expectedMaxDuration = 5)
{
// Note: very strange behaviour of Windows (PHP 5.5.6):
// on a 1000 long string, Windows succeeds.
// on a 10000 long string, Windows fails to output anything.
// On a 100000 long string, it takes a lot of time but succeeds.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we expect a test failure on Windows?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, just saw your comment in the OP.

$cmd = $this->getPhpBinary() . ' -r ' . escapeshellarg('echo str_repeat(\'o\', '.$size.'), PHP_EOL;');

if (defined('PHP_WINDOWS_VERSION_BUILD')) {
// Windows madness! for some obscure reason, the whole command lines needs to be
// wrapped in quotes (?!?)
$cmd = '"'.$cmd.'"';
}

$loop = $this->createLoop();
$process = new Process($cmd);

$output = '';

$loop->addTimer(0.001, function(Timer $timer) use ($process, &$output) {
$process->start($timer->getLoop());
$process->stdout->on('data', function () use (&$output) {
$output .= func_get_arg(0);
});
});

$startTime = time();

$loop->run();

$endTime = time();

$this->assertEquals($size + strlen(PHP_EOL), strlen($output));
$this->assertSame(str_repeat('o', $size) . PHP_EOL, $output);
$this->assertLessThanOrEqual($expectedMaxDuration, $endTime - $startTime, "Process took longer than expected.");
}


/**
* Execute a callback at regular intervals until it returns successfully or
* a timeout is reached.
Expand Down Expand Up @@ -333,4 +401,9 @@ private function getPhpBinary()

return $runtime->getBinary();
}

private function getPhpCommandLine($phpCode)
{
return $this->getPhpBinary() . ' -r ' . escapeshellarg($phpCode);
}
}