Skip to content

Commit 3becb62

Browse files
committed
MQE-1902: Running bin/magento from MagentoWebDriver causing timeout issues on pipeline
Updated shellExecMagentoCLI to mimic command.php Excluding cron from shell execution to prevent timeouts in pipeline.
1 parent 94737d1 commit 3becb62

File tree

1 file changed

+76
-14
lines changed

1 file changed

+76
-14
lines changed

src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php

+76-14
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Yandex\Allure\Adapter\AllureException;
2323
use Magento\FunctionalTestingFramework\Util\Protocol\CurlTransport;
2424
use Symfony\Component\Process\Process;
25+
use Symfony\Component\Process\Exception\ProcessTimedOutException;
2526
use Yandex\Allure\Adapter\Support\AttachmentSupport;
2627
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
2728
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
@@ -52,6 +53,8 @@ class MagentoWebDriver extends WebDriver
5253
{
5354
use AttachmentSupport;
5455

56+
const COMMAND_CRON_RUN = 'cron:run';
57+
5558
/**
5659
* List of known magento loading masks by selector
5760
*
@@ -520,13 +523,14 @@ public function scrollToTopOfPage()
520523
*/
521524
public function magentoCLI($command, $timeout = null, $arguments = null)
522525
{
523-
return $this->curlExecMagentoCLI($command, $timeout, $arguments);
524-
//TODO: calling bin/magento from pipeline is timing out, needs investigation (ref: MQE-1774)
525-
// try {
526-
// return $this->shellExecMagentoCLI($command, $arguments);
527-
// } catch (\Exception $exception) {
528-
// return $this->curlExecMagentoCLI($command, $arguments);
529-
// }
526+
$magentoBinary = realpath(MAGENTO_BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento');
527+
$valid = $this->validateCommand($magentoBinary, $command);
528+
// execute from shell when running tests from web root -- excludes cron jobs.
529+
if ($valid && strpos($command, self::COMMAND_CRON_RUN) === false) {
530+
return $this->shellExecMagentoCLI($magentoBinary, $command, $timeout, $arguments);
531+
} else {
532+
return $this->curlExecMagentoCLI($command, $timeout, $arguments);
533+
}
530534
}
531535

532536
/**
@@ -838,6 +842,7 @@ public function makeScreenshot($name = null)
838842
/**
839843
* Takes given $command and executes it against bin/magento executable. Returns stdout output from the command.
840844
*
845+
* @param string $magentoBinary
841846
* @param string $command
842847
* @param integer $timeout
843848
* @param string $arguments
@@ -846,20 +851,41 @@ public function makeScreenshot($name = null)
846851
* @return string
847852
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
848853
*/
849-
private function shellExecMagentoCLI($command, $timeout, $arguments): string
854+
private function shellExecMagentoCLI($magentoBinary, $command, $timeout, $arguments): string
850855
{
851856
$php = PHP_BINDIR ? PHP_BINDIR . DIRECTORY_SEPARATOR. 'php' : 'php';
852-
$binMagento = realpath(MAGENTO_BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento');
853-
$command = $php . ' -f ' . $binMagento . ' ' . $command . ' ' . $arguments;
854-
$process = new Process(escapeshellcmd($command), MAGENTO_BP);
857+
$fullCommand = $php . ' -f ' . $magentoBinary . ' ' . $command . ' ' . $arguments;
858+
$process = new Process(escapeshellcmd($fullCommand), MAGENTO_BP);
855859
$process->setIdleTimeout($timeout);
856860
$process->setTimeout(0);
857-
$exitCode = $process->run();
861+
try {
862+
$process->run();
863+
$output = $process->getOutput();
864+
if (!$process->isSuccessful()) {
865+
$failureOutput = $process->getErrorOutput();
866+
if (!empty($failureOutput)) {
867+
$output = $failureOutput;
868+
}
869+
}
870+
if (empty($output)) {
871+
$output = "CLI did not return output.";
872+
}
873+
874+
} catch (ProcessTimedOutException $exception) {
875+
$output = "CLI command timed out, no output available.";
876+
877+
}
878+
879+
if ($this->checkForFilePath($output)) {
880+
$output = "CLI output suppressed, filepath detected in output.";
881+
}
882+
883+
$exitCode = $process->getExitCode();
884+
858885
if ($exitCode !== 0) {
859886
throw new \RuntimeException($process->getErrorOutput());
860887
}
861-
862-
return $process->getOutput();
888+
return $output;
863889
}
864890

865891
/**
@@ -904,4 +930,40 @@ private function curlExecMagentoCLI($command, $timeout, $arguments): string
904930

905931
return $response;
906932
}
933+
934+
/**
935+
* Checks magento list of CLI commands for given $command. Does not check command parameters, just base command.
936+
* @param string $magentoBinary
937+
* @param string $command
938+
* @return bool
939+
*/
940+
private function validateCommand($magentoBinary, $command)
941+
{
942+
exec($magentoBinary . ' list', $commandList);
943+
// Trim list of commands after first whitespace
944+
$commandList = array_map(array($this, 'trimAfterWhitespace'), $commandList);
945+
return in_array($this->trimAfterWhitespace($command), $commandList);
946+
}
947+
948+
/**
949+
* Returns given string trimmed of everything after the first found whitespace.
950+
* @param string $string
951+
* @return string
952+
*/
953+
private function trimAfterWhitespace($string)
954+
{
955+
return strtok($string, ' ');
956+
}
957+
958+
/**
959+
* Detects file path in string.
960+
* @param string $string
961+
* @return boolean
962+
*/
963+
private function checkForFilePath($string)
964+
{
965+
return preg_match('/\/[\S]+\//', $string);
966+
}
967+
907968
}
969+

0 commit comments

Comments
 (0)