ShellTest.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Test\Unit;
  7. class ShellTest extends \PHPUnit\Framework\TestCase
  8. {
  9. /**
  10. * @var \Magento\Framework\Shell\CommandRendererInterface|\PHPUnit_Framework_MockObject_MockObject
  11. */
  12. protected $commandRenderer;
  13. /**
  14. * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
  15. */
  16. protected $logger;
  17. protected function setUp()
  18. {
  19. $this->logger = $this->getMockBuilder(\Psr\Log\LoggerInterface::class)
  20. ->disableOriginalConstructor()
  21. ->getMock();
  22. $this->commandRenderer = new \Magento\Framework\Shell\CommandRenderer();
  23. }
  24. /**
  25. * Test that a command with input arguments returns an expected result
  26. *
  27. * @param \Magento\Framework\Shell $shell
  28. * @param string $command
  29. * @param array $commandArgs
  30. * @param string $expectedResult
  31. */
  32. protected function _testExecuteCommand(\Magento\Framework\Shell $shell, $command, $commandArgs, $expectedResult)
  33. {
  34. $this->expectOutputString('');
  35. // nothing is expected to be ever printed to the standard output
  36. $actualResult = $shell->execute($command, $commandArgs);
  37. $this->assertEquals($expectedResult, $actualResult);
  38. }
  39. /**
  40. * @param string $command
  41. * @param array $commandArgs
  42. * @param string $expectedResult
  43. * @dataProvider executeDataProvider
  44. */
  45. public function testExecute($command, $commandArgs, $expectedResult)
  46. {
  47. $this->_testExecuteCommand(
  48. new \Magento\Framework\Shell($this->commandRenderer, $this->logger),
  49. $command,
  50. $commandArgs,
  51. $expectedResult
  52. );
  53. }
  54. /**
  55. * @param string $command
  56. * @param array $commandArgs
  57. * @param string $expectedResult
  58. * @param array $expectedLogRecords
  59. * @dataProvider executeDataProvider
  60. */
  61. public function testExecuteLog($command, $commandArgs, $expectedResult, $expectedLogRecords)
  62. {
  63. $quoteChar = substr(escapeshellarg(' '), 0, 1);
  64. // environment-dependent quote character
  65. foreach ($expectedLogRecords as $logRecordIndex => $expectedLogMessage) {
  66. $expectedLogMessage = str_replace('`', $quoteChar, $expectedLogMessage);
  67. $this->logger->expects($this->at($logRecordIndex))
  68. ->method('info')
  69. ->with($expectedLogMessage);
  70. }
  71. $this->_testExecuteCommand(
  72. new \Magento\Framework\Shell($this->commandRenderer, $this->logger),
  73. $command,
  74. $commandArgs,
  75. $expectedResult
  76. );
  77. }
  78. /**
  79. * @return array
  80. */
  81. public function executeDataProvider()
  82. {
  83. // backtick symbol (`) has to be replaced with environment-dependent quote character
  84. return [
  85. 'STDOUT' => ['php -r %s', ['echo 27181;'], '27181', ['php -r `echo 27181;` 2>&1', '27181']],
  86. 'STDERR' => [
  87. 'php -r %s',
  88. ['fwrite(STDERR, 27182);'],
  89. '27182',
  90. ['php -r `fwrite(STDERR, 27182);` 2>&1', '27182'],
  91. ],
  92. 'piping STDERR -> STDOUT' => [
  93. // intentionally no spaces around the pipe symbol
  94. 'php -r %s|php -r %s',
  95. ['fwrite(STDERR, 27183);', 'echo fgets(STDIN);'],
  96. '27183',
  97. ['php -r `fwrite(STDERR, 27183);` 2>&1|php -r `echo fgets(STDIN);` 2>&1', '27183'],
  98. ],
  99. 'piping STDERR -> STDERR' => [
  100. 'php -r %s | php -r %s',
  101. ['fwrite(STDERR, 27184);', 'fwrite(STDERR, fgets(STDIN));'],
  102. '27184',
  103. ['php -r `fwrite(STDERR, 27184);` 2>&1 | php -r `fwrite(STDERR, fgets(STDIN));` 2>&1', '27184'],
  104. ]
  105. ];
  106. }
  107. /**
  108. * @expectedException \Magento\Framework\Exception\LocalizedException
  109. * @expectedExceptionMessage Command returned non-zero exit code:
  110. * @expectedExceptionCode 0
  111. */
  112. public function testExecuteFailure()
  113. {
  114. $shell = new \Magento\Framework\Shell($this->commandRenderer, $this->logger);
  115. $shell->execute('non_existing_command');
  116. }
  117. /**
  118. * @param string $command
  119. * @param array $commandArgs
  120. * @param string $expectedError
  121. * @dataProvider executeDataProvider
  122. */
  123. public function testExecuteFailureDetails($command, $commandArgs, $expectedError)
  124. {
  125. try {
  126. /* Force command to return non-zero exit code */
  127. $commandArgs[count($commandArgs) - 1] .= ' exit(42);';
  128. $this->testExecute($command, $commandArgs, ''); // no result is expected in a case of a command failure
  129. } catch (\Magento\Framework\Exception\LocalizedException $e) {
  130. $this->assertInstanceOf('Exception', $e->getPrevious());
  131. $this->assertEquals($expectedError, $e->getPrevious()->getMessage());
  132. $this->assertEquals(42, $e->getPrevious()->getCode());
  133. }
  134. }
  135. }