wiki.techinc.nl/tests/phpunit/includes/shell/CommandTest.php
Max Semenik 77ce3b98a0 Replace wfShellExec() with a class
This function has gotten so unwieldy that a helper was
introduced. Instead, here's this class that makes
shelling out easier and more readable.

Example usage:
  $result = Shell::command( 'shell command' )
       ->environment( [ 'ENVIRONMENT_VARIABLE' => 'VALUE' ] )
       ->limits( [ 'time' => 300 ] )
       ->execute();

  $exitCode = $result->getExitCode();
  $output = $result->getStdout();

This is a minimal change, so lots of stuff remains
unrefactored - I'd rather limit the scope of this commit.
A future improvement could be an ability to get stderr
separately from stdout.

Caveat: execution errors (proc_open is disabled/returned error) now
throw errors instead of returning a status code. wfShellExec() still
emulates this behavior though.

Competing commit: I7dccb2b67a4173a8a89b035e444fbda9102e4d0f
<legoktm> MaxSem: so you should continue working on your patch and I'll
          probably refactor on top of it later after its merged :P

Change-Id: I8ac9858b80d7908cf7e7981d7e19d0fc9c2265c0
2017-09-08 21:49:49 -07:00

94 lines
2.3 KiB
PHP

<?php
use MediaWiki\Shell\Command;
/**
* @group Shell
*/
class CommandTest extends PHPUnit_Framework_TestCase {
/**
* @expectedException PHPUnit_Framework_Error_Notice
*/
public function testDestruct() {
if ( defined( 'HHVM_VERSION' ) ) {
$this->markTestSkipped( 'destructors are unreliable in HHVM' );
}
$command = new Command();
$command->params( 'true' );
}
private function requirePosix() {
if ( wfIsWindows() ) {
$this->markTestSkipped( 'This test requires a POSIX environment.' );
}
}
/**
* @dataProvider provideExecute
*/
public function testExecute( $commandInput, $expectedExitCode, $expectedOutput ) {
$this->requirePosix();
$command = new Command();
$result = $command
->params( $commandInput )
->execute();
$this->assertSame( $expectedExitCode, $result->getExitCode() );
$this->assertSame( $expectedOutput, $result->getStdout() );
}
public function provideExecute() {
return [
'success status' => [ 'true', 0, '' ],
'failure status' => [ 'false', 1, '' ],
'output' => [ [ 'echo', '-n', 'x', '>', 'y' ], 0, 'x > y' ],
];
}
public function testEnvironment() {
$this->requirePosix();
$command = new Command();
$result = $command
->params( [ 'printenv', 'FOO' ] )
->environment( [ 'FOO' => 'bar' ] )
->execute();
$this->assertSame( "bar\n", $result->getStdout() );
}
public function testOutput() {
global $IP;
$this->requirePosix();
$command = new Command();
$result = $command
->params( [ 'ls', "$IP/index.php" ] )
->execute();
$this->assertSame( "$IP/index.php", trim( $result->getStdout() ) );
$command = new Command();
$result = $command
->params( [ 'ls', 'index.php', 'no-such-file' ] )
->includeStderr()
->execute();
$this->assertRegExp( '/^.+no-such-file.*$/m', $result->getStdout() );
}
public function testT69870() {
$commandLine = wfIsWindows()
// 333 = 331 + CRLF
? ( 'for /l %i in (1, 1, 1001) do @echo ' . str_repeat( '*', 331 ) )
: 'printf "%-333333s" "*"';
// Test several times because it involves a race condition that may randomly succeed or fail
for ( $i = 0; $i < 10; $i++ ) {
$command = new Command();
$output = $command->unsafeParams( $commandLine )
->execute()
->getStdout();
$this->assertEquals( 333333, strlen( $output ) );
}
}
}