f7275e14e8c3e0d460f734f01f4ce1f15e9ee8e4
[lhc/web/wiklou.git] / tests / phpunit / includes / shell / CommandTest.php
1 <?php
2
3 use MediaWiki\Shell\Command;
4 use Wikimedia\TestingAccessWrapper;
5
6 /**
7 * @group Shell
8 */
9 class CommandTest extends PHPUnit_Framework_TestCase {
10 private function requirePosix() {
11 if ( wfIsWindows() ) {
12 $this->markTestSkipped( 'This test requires a POSIX environment.' );
13 }
14 }
15
16 /**
17 * @dataProvider provideExecute
18 */
19 public function testExecute( $commandInput, $expectedExitCode, $expectedOutput ) {
20 $this->requirePosix();
21
22 $command = new Command();
23 $result = $command
24 ->params( $commandInput )
25 ->execute();
26
27 $this->assertSame( $expectedExitCode, $result->getExitCode() );
28 $this->assertSame( $expectedOutput, $result->getStdout() );
29 }
30
31 public function provideExecute() {
32 return [
33 'success status' => [ 'true', 0, '' ],
34 'failure status' => [ 'false', 1, '' ],
35 'output' => [ [ 'echo', '-n', 'x', '>', 'y' ], 0, 'x > y' ],
36 ];
37 }
38
39 public function testEnvironment() {
40 $this->requirePosix();
41
42 $command = new Command();
43 $result = $command
44 ->params( [ 'printenv', 'FOO' ] )
45 ->environment( [ 'FOO' => 'bar' ] )
46 ->execute();
47 $this->assertSame( "bar\n", $result->getStdout() );
48 }
49
50 public function testStdout() {
51 $this->requirePosix();
52
53 $command = new Command();
54
55 $result = $command
56 ->params( 'bash', '-c', 'echo ThisIsStderr 1>&2' )
57 ->execute();
58
59 $this->assertNotContains( 'ThisIsStderr', $result->getStdout() );
60 $this->assertEquals( "ThisIsStderr\n", $result->getStderr() );
61 }
62
63 public function testStdoutRedirection() {
64 $this->requirePosix();
65
66 $command = new Command();
67
68 $result = $command
69 ->params( 'bash', '-c', 'echo ThisIsStderr 1>&2' )
70 ->includeStderr( true )
71 ->execute();
72
73 $this->assertEquals( "ThisIsStderr\n", $result->getStdout() );
74 $this->assertNull( $result->getStderr() );
75 }
76
77 public function testOutput() {
78 global $IP;
79
80 $this->requirePosix();
81 chdir( $IP );
82
83 $command = new Command();
84 $result = $command
85 ->params( [ 'ls', 'index.php' ] )
86 ->execute();
87 $this->assertRegExp( '/^index.php$/m', $result->getStdout() );
88 $this->assertSame( null, $result->getStderr() );
89
90 $command = new Command();
91 $result = $command
92 ->params( [ 'ls', 'index.php', 'no-such-file' ] )
93 ->includeStderr()
94 ->execute();
95 $this->assertRegExp( '/^index.php$/m', $result->getStdout() );
96 $this->assertRegExp( '/^.+no-such-file.*$/m', $result->getStdout() );
97 $this->assertSame( null, $result->getStderr() );
98
99 $command = new Command();
100 $result = $command
101 ->params( [ 'ls', 'index.php', 'no-such-file' ] )
102 ->execute();
103 $this->assertRegExp( '/^index.php$/m', $result->getStdout() );
104 $this->assertRegExp( '/^.+no-such-file.*$/m', $result->getStderr() );
105 }
106
107 /**
108 * Test that null values are skipped by params() and unsafeParams()
109 */
110 public function testNullsAreSkipped() {
111 $command = TestingAccessWrapper::newFromObject( new Command );
112 $command->params( 'echo', 'a', null, 'b' );
113 $command->unsafeParams( 'c', null, 'd' );
114 $this->assertEquals( "'echo' 'a' 'b' c d", $command->command );
115 }
116
117 public function testT69870() {
118 $commandLine = wfIsWindows()
119 // 333 = 331 + CRLF
120 ? ( 'for /l %i in (1, 1, 1001) do @echo ' . str_repeat( '*', 331 ) )
121 : 'printf "%-333333s" "*"';
122
123 // Test several times because it involves a race condition that may randomly succeed or fail
124 for ( $i = 0; $i < 10; $i++ ) {
125 $command = new Command();
126 $output = $command->unsafeParams( $commandLine )
127 ->execute()
128 ->getStdout();
129 $this->assertEquals( 333333, strlen( $output ) );
130 }
131 }
132
133 public function testLogStderr() {
134 $this->requirePosix();
135
136 $logger = new TestLogger( true, function ( $message, $level, $context ) {
137 return $level === Psr\Log\LogLevel::ERROR ? '1' : null;
138 }, true );
139 $command = new Command();
140 $command->setLogger( $logger );
141 $command->params( 'bash', '-c', 'echo ThisIsStderr 1>&2' );
142 $command->execute();
143 $this->assertEmpty( $logger->getBuffer() );
144
145 $command = new Command();
146 $command->setLogger( $logger );
147 $command->logStderr();
148 $command->params( 'bash', '-c', 'echo ThisIsStderr 1>&2' );
149 $command->execute();
150 $this->assertSame( 1, count( $logger->getBuffer() ) );
151 $this->assertSame( trim( $logger->getBuffer()[0][2]['error'] ), 'ThisIsStderr' );
152 }
153 }