-
-
Notifications
You must be signed in to change notification settings - Fork 49
Fixing unit tests for Windows #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4531908
f160467
6b841d4
fd658f2
a708cb8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
|
@@ -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 = '/'; | ||
| } | ||
|
|
||
| $loop = $this->createLoop(); | ||
| $process = new Process($cmd, '/'); | ||
| $process = new Process($cmd, $testCwd, null, array("bypass_shell"=>true)); | ||
|
|
||
| $output = ''; | ||
|
|
||
|
|
@@ -112,7 +125,7 @@ public function testProcessWithCwd() | |
|
|
||
| $loop->run(); | ||
|
|
||
| $this->assertSame('/' . PHP_EOL, $output); | ||
| $this->assertSame($testCwd . PHP_EOL, $output); | ||
| } | ||
|
|
||
| public function testProcessWithEnv() | ||
|
|
@@ -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 = ''; | ||
|
|
||
|
|
@@ -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(); | ||
|
|
@@ -298,6 +321,51 @@ public function testTerminateWithStopAndContinueSignalsUsingEventLoop() | |
| $this->assertFalse($process->isTerminated()); | ||
| } | ||
|
|
||
| public function outputSizeProvider() { | ||
| return [ [1000, 5], [10000, 5], [100000, 5] ]; | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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).
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this mean we expect a test failure on Windows?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
|
|
@@ -333,4 +401,9 @@ private function getPhpBinary() | |
|
|
||
| return $runtime->getBinary(); | ||
| } | ||
|
|
||
| private function getPhpCommandLine($phpCode) | ||
| { | ||
| return $this->getPhpBinary() . ' -r ' . escapeshellarg($phpCode); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
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/?There was a problem hiding this comment.
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.