From 92a0b20e3a7b5f643861c1505cca5f1fd072f6b2 Mon Sep 17 00:00:00 2001 From: ptlis Date: Thu, 5 Nov 2020 15:04:34 +0000 Subject: [PATCH] Add method to retrieve the working directory in ProcessOutputInterface --- src/Interfaces/ProcessOutputInterface.php | 9 +++++ src/Mock/MockCommandBuilder.php | 5 +-- src/Mock/MockProcess.php | 2 +- src/Process.php | 7 +++- src/ProcessOutput.php | 12 ++++++- tests/Integration/CommandTest.php | 23 +++++++----- tests/Unit/Mocks/MockCommandBuilderTest.php | 40 ++++++++++----------- tests/Unit/Mocks/MockCommandTest.php | 16 ++++----- tests/Unit/Mocks/MockProcessTest.php | 22 ++++++------ tests/Unit/ProcessOutputTest.php | 8 ++++- 10 files changed, 91 insertions(+), 53 deletions(-) diff --git a/src/Interfaces/ProcessOutputInterface.php b/src/Interfaces/ProcessOutputInterface.php index 007f409..f019a5c 100644 --- a/src/Interfaces/ProcessOutputInterface.php +++ b/src/Interfaces/ProcessOutputInterface.php @@ -58,4 +58,13 @@ public function getExitCode(): int; * @return string */ public function getExecutedCommand(): string; + + /** + * Get the working directory that command was executed in. + * + * This is here purely to make debugging commands easier. + * + * @return string + */ + public function getWorkingDirectory(): string; } diff --git a/src/Mock/MockCommandBuilder.php b/src/Mock/MockCommandBuilder.php index 95a5179..430c03b 100644 --- a/src/Mock/MockCommandBuilder.php +++ b/src/Mock/MockCommandBuilder.php @@ -256,13 +256,14 @@ public function buildCommand(): CommandInterface * @param string $stdOut * @param string $stdErr * @param string $command + * @param string $workingDirectory * * @return $this */ - public function addMockResult(int $exitCode, string $stdOut, string $stdErr, string $command): CommandBuilderInterface + public function addMockResult(int $exitCode, string $stdOut, string $stdErr, string $command, string $workingDirectory): CommandBuilderInterface { $mockResultList = $this->mockResultList; - $mockResultList[] = new ProcessOutput($exitCode, $stdOut, $stdErr, $command); + $mockResultList[] = new ProcessOutput($exitCode, $stdOut, $stdErr, $command, $workingDirectory); return new MockCommandBuilder( $mockResultList, diff --git a/src/Mock/MockProcess.php b/src/Mock/MockProcess.php index 4a0de63..f5b047c 100644 --- a/src/Mock/MockProcess.php +++ b/src/Mock/MockProcess.php @@ -141,7 +141,7 @@ function (TimerInterface $timer) use ($eventLoop, $deferred, &$fullStdOut, &$ful // Process has terminated if (!$this->isRunning()) { $eventLoop->cancelTimer($timer); - $output = new ProcessOutput($this->result->getExitCode(), $fullStdOut, $fullStdErr, $this->command); + $output = new ProcessOutput($this->result->getExitCode(), $fullStdOut, $fullStdErr, $this->command, '.'); // Resolve or reject promise if (0 === $output->getExitCode()) { diff --git a/src/Process.php b/src/Process.php index 6159ea8..70fb583 100644 --- a/src/Process.php +++ b/src/Process.php @@ -27,6 +27,9 @@ final class Process implements ProcessInterface /** @var EnvironmentInterface */ private $environment; + /** @var string */ + private $cwdOverride; + /** @var string[] */ private $envVarList; @@ -74,6 +77,7 @@ public function __construct( ProcessObserverInterface $observer = null ) { $this->environment = $environment; + $this->cwdOverride = $cwdOverride; $this->observer = $observer; $this->envVarList = $envVarList; if (is_null($this->observer)) { @@ -283,7 +287,8 @@ private function getProcessOutput(): ProcessOutputInterface $this->exitCode, $this->fullStdOut, $this->fullStdErr, - $envVarString . $this->getCommand() + $envVarString . $this->getCommand(), + $this->cwdOverride ); $this->observer->processExited($this->pid, $this->output); } diff --git a/src/ProcessOutput.php b/src/ProcessOutput.php index 87bb294..78f60fb 100644 --- a/src/ProcessOutput.php +++ b/src/ProcessOutput.php @@ -27,17 +27,22 @@ final class ProcessOutput implements ProcessOutputInterface /** @var string */ private $command; + /** @var string */ + private $workingDirectory; + public function __construct( int $exitCode, string $stdOut, string $stdErr, - string $command + string $command, + string $workingDirectory ) { $this->exitCode = $exitCode; $this->stdOut = $stdOut; $this->stdErr = $stdErr; $this->command = $command; + $this->workingDirectory = $workingDirectory; } public function getStdOut(): string @@ -70,6 +75,11 @@ public function getExecutedCommand(): string return $this->command; } + public function getWorkingDirectory(): string + { + return $this->workingDirectory; + } + /** * Accepts console output as a string and returns an array of it split by newlines. */ diff --git a/tests/Integration/CommandTest.php b/tests/Integration/CommandTest.php index 198d524..f3f0611 100644 --- a/tests/Integration/CommandTest.php +++ b/tests/Integration/CommandTest.php @@ -41,7 +41,8 @@ public function testRun(): void 0, 'Test command' . PHP_EOL . 'if=/dev/sha1 of=/dev/sdb2' . PHP_EOL, '', - './tests/commands/unix/test_binary \'if=/dev/sha1 of=/dev/sdb2\'' + './tests/commands/unix/test_binary \'if=/dev/sha1 of=/dev/sdb2\'', + getcwd() ), $command->runSynchronous() ); @@ -73,7 +74,8 @@ public function testRunFromHome(): void 0, 'Test command' . PHP_EOL . 'if=/dev/sha1 of=/dev/sdb2' . PHP_EOL, '', - '~/test_binary \'if=/dev/sha1 of=/dev/sdb2\'' + '~/test_binary \'if=/dev/sha1 of=/dev/sdb2\'', + getcwd() ), $command->runSynchronous() ); @@ -85,9 +87,10 @@ public function testRunHomeCwd(): void { $originalPath = getenv('PATH'); - $pathToCommand = realpath(getcwd() . '/tests/commands/unix'); + $fakeHomePath = realpath(getcwd() . '/tests/commands/unix'); - putenv('HOME=' . $pathToCommand); + + putenv('HOME=' . $fakeHomePath); $path = '~/sleep_binary'; @@ -104,7 +107,8 @@ public function testRunHomeCwd(): void 0, '', '', - '~/sleep_binary' + '~/sleep_binary', + $fakeHomePath . '/' ), $command->runSynchronous() ); @@ -129,7 +133,8 @@ public function testRunWithSleep(): void 0, '', '', - './tests/commands/unix/sleep_binary' + './tests/commands/unix/sleep_binary', + getcwd() ), $command->runSynchronous() ); @@ -155,7 +160,8 @@ public function testRunWithEnvVariable(): void 0, 'VALUE' . PHP_EOL, '', - 'TEST_VAR=\'VALUE\' ./tests/commands/unix/echo_env_binary' + 'TEST_VAR=\'VALUE\' ./tests/commands/unix/echo_env_binary', + getcwd() ), $command->runSynchronous() ); @@ -178,7 +184,8 @@ public function testRunWithError(): void 5, '', 'Fatal Error' . PHP_EOL, - './tests/commands/unix/error_binary' + './tests/commands/unix/error_binary', + getcwd() ), $command->runSynchronous() ); diff --git a/tests/Unit/Mocks/MockCommandBuilderTest.php b/tests/Unit/Mocks/MockCommandBuilderTest.php index 50d512e..639c954 100644 --- a/tests/Unit/Mocks/MockCommandBuilderTest.php +++ b/tests/Unit/Mocks/MockCommandBuilderTest.php @@ -23,12 +23,12 @@ class MockCommandBuilderTest extends ptlisShellCommandTestcase public function testMockCommandBuilderOne(): void { $builder = new MockCommandBuilder( - [new ProcessOutput(0, 'hello world', '', 'foo \'--foo bar\' \-d 10\' \'if=/bar\' \'wop\'')] + [new ProcessOutput(0, 'hello world', '', 'foo \'--foo bar\' \-d 10\' \'if=/bar\' \'wop\'', '.')] ); $builder = $builder ->setCommand('foo') - ->addMockResult(0, 'hello world', '', 'foo \'--foo bar\' \-d 10\' \'if=/bar\' \'wop\'') + ->addMockResult(0, 'hello world', '', 'foo \'--foo bar\' \-d 10\' \'if=/bar\' \'wop\'', '.') ->addArgument('--foo bar') ->addArgument('-d 10') ->addArgument('if=/bar') @@ -46,7 +46,7 @@ public function testMockCommandBuilderOne(): void 'wop' ], [], - new ProcessOutput(0, 'hello world', '', 'foo \'--foo bar\' \-d 10\' \'if=/bar\' \'wop\'') + new ProcessOutput(0, 'hello world', '', 'foo \'--foo bar\' \-d 10\' \'if=/bar\' \'wop\'', '.') ); $this->assertEquals( @@ -60,7 +60,7 @@ public function testMockCommandBuilderOne(): void ); $this->assertEquals( - new ProcessOutput(0, 'hello world', '', 'foo \'--foo bar\' \-d 10\' \'if=/bar\' \'wop\''), + new ProcessOutput(0, 'hello world', '', 'foo \'--foo bar\' \-d 10\' \'if=/bar\' \'wop\'', '.'), $builtCommand->runSynchronous() ); } @@ -77,7 +77,7 @@ public function testMockCommandBuilderTwo(): void 'bat' ] ) - ->addMockResult(1, 'hurray!', '', 'bar \'baz\' \'bat\'') + ->addMockResult(1, 'hurray!', '', 'bar \'baz\' \'bat\'', '.') ->addEnvironmentVariable('key', 'value') ->addEnvironmentVariables(['test' => 'message']) ->buildCommand(); @@ -87,7 +87,7 @@ public function testMockCommandBuilderTwo(): void 'bar', ['baz', 'bat'], [], - new ProcessOutput(1, 'hurray!', '', 'bar \'baz\' \'bat\''), + new ProcessOutput(1, 'hurray!', '', 'bar \'baz\' \'bat\'', '.'), ['key' => 'value', 'test' => 'message'] ); @@ -102,7 +102,7 @@ public function testMockCommandBuilderTwo(): void ); $this->assertEquals( - new ProcessOutput(1, 'hurray!', '', 'bar \'baz\' \'bat\''), + new ProcessOutput(1, 'hurray!', '', 'bar \'baz\' \'bat\'', '.'), $builtCommand->runSynchronous() ); @@ -117,17 +117,17 @@ public function testMockCommandMultiUseOne(): void $builder = new MockCommandBuilder(); $builtCommand1 = $builder - ->addMockResult(1, 'hurray!', '', 'bar') + ->addMockResult(1, 'hurray!', '', 'bar', '.') ->setCommand('bar') ->buildCommand(); - $expectResult1 = new ProcessOutput(1, 'hurray!', '', 'bar'); + $expectResult1 = new ProcessOutput(1, 'hurray!', '', 'bar', '.'); $expectCommand1 = new MockCommand( new UnixEnvironment(), 'bar', [], [], - new ProcessOutput(1, 'hurray!', '', 'bar') + new ProcessOutput(1, 'hurray!', '', 'bar', '.') ); $this->assertEquals( @@ -137,16 +137,16 @@ public function testMockCommandMultiUseOne(): void $builtCommand2 = $builder ->setCommand('baz') - ->addMockResult(0, 'success', '', 'baz') + ->addMockResult(0, 'success', '', 'baz', '.') ->buildCommand(); - $expectResult2 = new ProcessOutput(0, 'success', '', 'baz'); + $expectResult2 = new ProcessOutput(0, 'success', '', 'baz', '.'); $expectCommand2 = new MockCommand( new UnixEnvironment(), 'baz', [], [], - new ProcessOutput(0, 'success', '', 'baz') + new ProcessOutput(0, 'success', '', 'baz', '.') ); $this->assertEquals( @@ -164,20 +164,20 @@ public function testMockCommandMultiUseTwo(): void { $builder = new MockCommandBuilder(); $primedBuilder = $builder - ->addMockResult(1, 'hurray!', '', 'bar') - ->addMockResult(0, 'success', '', 'baz'); + ->addMockResult(1, 'hurray!', '', 'bar', '.') + ->addMockResult(0, 'success', '', 'baz', '.'); $builtCommand1 = $primedBuilder ->setCommand('bar') ->buildCommand(); - $expectResult1 = new ProcessOutput(1, 'hurray!', '', 'bar'); + $expectResult1 = new ProcessOutput(1, 'hurray!', '', 'bar', '.'); $expectCommand1 = new MockCommand( new UnixEnvironment(), 'bar', [], [], - new ProcessOutput(1, 'hurray!', '', 'bar') + new ProcessOutput(1, 'hurray!', '', 'bar', '.') ); $this->assertEquals( @@ -189,13 +189,13 @@ public function testMockCommandMultiUseTwo(): void ->setCommand('baz') ->buildCommand(); - $expectResult2 = new ProcessOutput(0, 'success', '', 'baz'); + $expectResult2 = new ProcessOutput(0, 'success', '', 'baz', '.'); $expectCommand2 = new MockCommand( new UnixEnvironment(), 'baz', [], [], - new ProcessOutput(0, 'success', '', 'baz') + new ProcessOutput(0, 'success', '', 'baz', '.') ); $this->assertEquals( @@ -347,7 +347,7 @@ public function testClearTwo(): void $command = $builder ->setCommand('foo') ->addArgument('--test') - ->addMockResult(0, 'bar', '', 'foo \'--test\'') + ->addMockResult(0, 'bar', '', 'foo \'--test\'', '.') ->buildCommand(); $this->assertEquals( diff --git a/tests/Unit/Mocks/MockCommandTest.php b/tests/Unit/Mocks/MockCommandTest.php index 77b5e7f..eb2a235 100644 --- a/tests/Unit/Mocks/MockCommandTest.php +++ b/tests/Unit/Mocks/MockCommandTest.php @@ -28,14 +28,14 @@ public function testRunSynchronous(): void $path, ['foo'], ['--test=\'123\''], - new ProcessOutput(0, 'hello world', '', 'binary \'foo\' --test=\'123\''), + new ProcessOutput(0, 'hello world', '', 'binary \'foo\' --test=\'123\'', '.'), ['FOO' => 'bar'] ); $this->assertEquals('binary \'foo\' --test=\'123\'', $command->__toString()); $this->assertEquals( - new ProcessOutput(0, 'hello world', '', 'binary \'foo\' --test=\'123\''), + new ProcessOutput(0, 'hello world', '', 'binary \'foo\' --test=\'123\'', '.'), $command->runSynchronous() ); } @@ -49,7 +49,7 @@ public function testRunPromiseSuccess(): void $path, ['foo'], ['--test=\'123\''], - new ProcessOutput(0, 'hello world', '', 'binary \'foo\' --test=\'123\''), + new ProcessOutput(0, 'hello world', '', 'binary \'foo\' --test=\'123\'', '.'), ['FOO' => 'bar'] ); @@ -66,7 +66,7 @@ public function testRunPromiseSuccess(): void function(ProcessOutput $result) use (&$successCalled) { $successCalled = true; $this->assertEquals( - new ProcessOutput(0, 'hello world', '', 'binary \'foo\' --test=\'123\''), + new ProcessOutput(0, 'hello world', '', 'binary \'foo\' --test=\'123\'', '.'), $result ); }, @@ -78,7 +78,7 @@ function(ProcessOutput $result) use (&$failureCalled) { $eventLoop->run(); $this->assertEquals( - new ProcessOutput(0, 'hello world', '', 'binary \'foo\' --test=\'123\''), + new ProcessOutput(0, 'hello world', '', 'binary \'foo\' --test=\'123\'', '.'), $command->runSynchronous() ); @@ -95,7 +95,7 @@ public function testRunPromiseFailure(): void $path, ['foo'], ['--test=\'123\''], - new ProcessOutput(1, 'error', '', ''), + new ProcessOutput(1, 'error', '', '', '.'), ['FOO' => 'bar'] ); @@ -115,7 +115,7 @@ function(ProcessOutput $result) use (&$successCalled) { function(ProcessOutput $result) use (&$failureCalled) { $failureCalled = true; $this->assertEquals( - new ProcessOutput(1, 'error', '', ''), + new ProcessOutput(1, 'error', '', '', '.'), $result ); } @@ -124,7 +124,7 @@ function(ProcessOutput $result) use (&$failureCalled) { $eventLoop->run(); $this->assertEquals( - new ProcessOutput(1, 'error', '', ''), + new ProcessOutput(1, 'error', '', '', '.'), $command->runSynchronous() ); diff --git a/tests/Unit/Mocks/MockProcessTest.php b/tests/Unit/Mocks/MockProcessTest.php index 48adaaa..4f4b1d7 100644 --- a/tests/Unit/Mocks/MockProcessTest.php +++ b/tests/Unit/Mocks/MockProcessTest.php @@ -20,7 +20,7 @@ class MockProcessTest extends ptlisShellCommandTestcase { public function testIsRunning(): void { - $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command')); + $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command', '.')); $this->assertTrue($process->isRunning()); } @@ -29,7 +29,7 @@ public function testWait(): void { $callbackCalled = false; - $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command'), 100); + $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command', '.'), 100); $process->wait(function() use (&$callbackCalled) { $callbackCalled = true; }); @@ -40,7 +40,7 @@ public function testWait(): void public function testStop(): void { - $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command'), 100000); + $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command', '.'), 100000); $this->assertTrue($process->isRunning()); $process->stop(); @@ -49,7 +49,7 @@ public function testStop(): void public function testSignal(): void { - $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command'), 100000); + $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command', '.'), 100000); $this->assertTrue($process->isRunning()); $process->sendSignal(ProcessInterface::SIGTERM); @@ -58,13 +58,13 @@ public function testSignal(): void public function testGetPid(): void { - $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command'), 1000, 9999); + $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command', '.'), 1000, 9999); $this->assertEquals(9999, $process->getPid()); } public function testGetCommand(): void { - $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command'), 1000, 9999); + $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command', '.'), 1000, 9999); $this->assertEquals('test-command', $process->getCommand()); } @@ -72,14 +72,14 @@ public function testGetPidStopped(): void { $this->expectException(\RuntimeException::class); - $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command'), 1000); + $process = new MockProcess('test-command', new ProcessOutput(0, '', '', 'test-command', '.'), 1000); $process->stop(); $process->getPid(); } public function testGetExitCode(): void { - $process = new MockProcess('test-command', new ProcessOutput(15, '', '', 'test-command'), 1000); + $process = new MockProcess('test-command', new ProcessOutput(15, '', '', 'test-command', '.'), 1000); $output = $process->stop(); $this->assertEquals(15, $output->getExitCode()); @@ -87,19 +87,19 @@ public function testGetExitCode(): void public function testReadStdOut(): void { - $process = new MockProcess('test-command', new ProcessOutput(0, 'abc123', '', 'test-command'), 1000, 9999); + $process = new MockProcess('test-command', new ProcessOutput(0, 'abc123', '', 'test-command', '.'), 1000, 9999); $this->assertEquals('abc123', $process->readOutput(ProcessInterface::STDOUT)); } public function testReadStdErr(): void { - $process = new MockProcess('test-command', new ProcessOutput(0, '', 'foo bar baz', 'test-command'), 1000, 9999); + $process = new MockProcess('test-command', new ProcessOutput(0, '', 'foo bar baz', 'test-command', '.'), 1000, 9999); $this->assertEquals('foo bar baz', $process->readOutput(ProcessInterface::STDERR)); } public function testWriteInput(): void { - $process = new MockProcess('test-command', new ProcessOutput(0, '', 'foo bar baz', 'test-command'), 1000, 9999); + $process = new MockProcess('test-command', new ProcessOutput(0, '', 'foo bar baz', 'test-command', '.'), 1000, 9999); $process->writeInput('Hello stdin w/ newline'); $process->writeInput('Hello stdin w/o newline', ProcessInterface::STDIN,false); $this->assertEquals([ProcessInterface::STDIN => ["Hello stdin w/ newline\n","Hello stdin w/o newline"]], $process->getInputs()); diff --git a/tests/Unit/ProcessOutputTest.php b/tests/Unit/ProcessOutputTest.php index b99776e..b56a366 100644 --- a/tests/Unit/ProcessOutputTest.php +++ b/tests/Unit/ProcessOutputTest.php @@ -22,7 +22,8 @@ public function testProcessOutput(): void 0, 'great success!', '', - 'foo --bar' + 'foo --bar', + '.' ); $this->assertSame( @@ -54,5 +55,10 @@ public function testProcessOutput(): void 'foo --bar', $shellResult->getExecutedCommand() ); + + $this->assertSame( + '.', + $shellResult->getWorkingDirectory() + ); } }