From 3becb62e67c8200074144beffcd054b7f96ee717 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan Date: Tue, 3 Dec 2019 08:50:42 -0600 Subject: [PATCH 1/9] 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. --- .../Module/MagentoWebDriver.php | 90 ++++++++++++++++--- 1 file changed, 76 insertions(+), 14 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php index cbde1ddfc..37c39b0ec 100644 --- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php +++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php @@ -22,6 +22,7 @@ use Yandex\Allure\Adapter\AllureException; use Magento\FunctionalTestingFramework\Util\Protocol\CurlTransport; use Symfony\Component\Process\Process; +use Symfony\Component\Process\Exception\ProcessTimedOutException; use Yandex\Allure\Adapter\Support\AttachmentSupport; use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException; use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig; @@ -52,6 +53,8 @@ class MagentoWebDriver extends WebDriver { use AttachmentSupport; + const COMMAND_CRON_RUN = 'cron:run'; + /** * List of known magento loading masks by selector * @@ -520,13 +523,14 @@ public function scrollToTopOfPage() */ public function magentoCLI($command, $timeout = null, $arguments = null) { - return $this->curlExecMagentoCLI($command, $timeout, $arguments); - //TODO: calling bin/magento from pipeline is timing out, needs investigation (ref: MQE-1774) -// try { -// return $this->shellExecMagentoCLI($command, $arguments); -// } catch (\Exception $exception) { -// return $this->curlExecMagentoCLI($command, $arguments); -// } + $magentoBinary = realpath(MAGENTO_BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento'); + $valid = $this->validateCommand($magentoBinary, $command); + // execute from shell when running tests from web root -- excludes cron jobs. + if ($valid && strpos($command, self::COMMAND_CRON_RUN) === false) { + return $this->shellExecMagentoCLI($magentoBinary, $command, $timeout, $arguments); + } else { + return $this->curlExecMagentoCLI($command, $timeout, $arguments); + } } /** @@ -838,6 +842,7 @@ public function makeScreenshot($name = null) /** * Takes given $command and executes it against bin/magento executable. Returns stdout output from the command. * + * @param string $magentoBinary * @param string $command * @param integer $timeout * @param string $arguments @@ -846,20 +851,41 @@ public function makeScreenshot($name = null) * @return string * @SuppressWarnings(PHPMD.UnusedPrivateMethod) */ - private function shellExecMagentoCLI($command, $timeout, $arguments): string + private function shellExecMagentoCLI($magentoBinary, $command, $timeout, $arguments): string { $php = PHP_BINDIR ? PHP_BINDIR . DIRECTORY_SEPARATOR. 'php' : 'php'; - $binMagento = realpath(MAGENTO_BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento'); - $command = $php . ' -f ' . $binMagento . ' ' . $command . ' ' . $arguments; - $process = new Process(escapeshellcmd($command), MAGENTO_BP); + $fullCommand = $php . ' -f ' . $magentoBinary . ' ' . $command . ' ' . $arguments; + $process = new Process(escapeshellcmd($fullCommand), MAGENTO_BP); $process->setIdleTimeout($timeout); $process->setTimeout(0); - $exitCode = $process->run(); + try { + $process->run(); + $output = $process->getOutput(); + if (!$process->isSuccessful()) { + $failureOutput = $process->getErrorOutput(); + if (!empty($failureOutput)) { + $output = $failureOutput; + } + } + if (empty($output)) { + $output = "CLI did not return output."; + } + + } catch (ProcessTimedOutException $exception) { + $output = "CLI command timed out, no output available."; + + } + + if ($this->checkForFilePath($output)) { + $output = "CLI output suppressed, filepath detected in output."; + } + + $exitCode = $process->getExitCode(); + if ($exitCode !== 0) { throw new \RuntimeException($process->getErrorOutput()); } - - return $process->getOutput(); + return $output; } /** @@ -904,4 +930,40 @@ private function curlExecMagentoCLI($command, $timeout, $arguments): string return $response; } + + /** + * Checks magento list of CLI commands for given $command. Does not check command parameters, just base command. + * @param string $magentoBinary + * @param string $command + * @return bool + */ + private function validateCommand($magentoBinary, $command) + { + exec($magentoBinary . ' list', $commandList); + // Trim list of commands after first whitespace + $commandList = array_map(array($this, 'trimAfterWhitespace'), $commandList); + return in_array($this->trimAfterWhitespace($command), $commandList); + } + + /** + * Returns given string trimmed of everything after the first found whitespace. + * @param string $string + * @return string + */ + private function trimAfterWhitespace($string) + { + return strtok($string, ' '); + } + + /** + * Detects file path in string. + * @param string $string + * @return boolean + */ + private function checkForFilePath($string) + { + return preg_match('/\/[\S]+\//', $string); + } + } + From 41afe3d9594f26ea1f700015a536ab0a807c4de2 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan Date: Tue, 3 Dec 2019 09:17:27 -0600 Subject: [PATCH 2/9] MQE-1902: Running bin/magento from MagentoWebDriver causing timeout issues on pipeline fixed phpunit checks --- .../Module/MagentoWebDriver.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php index 37c39b0ec..fa5bf2110 100644 --- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php +++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php @@ -849,7 +849,6 @@ public function makeScreenshot($name = null) * * @throws \RuntimeException * @return string - * @SuppressWarnings(PHPMD.UnusedPrivateMethod) */ private function shellExecMagentoCLI($magentoBinary, $command, $timeout, $arguments): string { @@ -870,10 +869,8 @@ private function shellExecMagentoCLI($magentoBinary, $command, $timeout, $argume if (empty($output)) { $output = "CLI did not return output."; } - } catch (ProcessTimedOutException $exception) { $output = "CLI command timed out, no output available."; - } if ($this->checkForFilePath($output)) { @@ -933,21 +930,25 @@ private function curlExecMagentoCLI($command, $timeout, $arguments): string /** * Checks magento list of CLI commands for given $command. Does not check command parameters, just base command. + * * @param string $magentoBinary * @param string $command - * @return bool + * + * @return boolean */ private function validateCommand($magentoBinary, $command) { exec($magentoBinary . ' list', $commandList); // Trim list of commands after first whitespace - $commandList = array_map(array($this, 'trimAfterWhitespace'), $commandList); + $commandList = array_map([$this, 'trimAfterWhitespace'], $commandList); return in_array($this->trimAfterWhitespace($command), $commandList); } /** * Returns given string trimmed of everything after the first found whitespace. + * * @param string $string + * * @return string */ private function trimAfterWhitespace($string) @@ -957,13 +958,13 @@ private function trimAfterWhitespace($string) /** * Detects file path in string. + * * @param string $string + * * @return boolean */ private function checkForFilePath($string) { return preg_match('/\/[\S]+\//', $string); } - -} - +} \ No newline at end of file From dea0c05b621710d159fa88504ff2f777486a3303 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan Date: Tue, 3 Dec 2019 10:42:34 -0600 Subject: [PATCH 3/9] MQE-1902: Running bin/magento from MagentoWebDriver causing timeout issues on pipeline Not fetching output from cron. --- .../Module/MagentoWebDriver.php | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php index fa5bf2110..ae12ad754 100644 --- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php +++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php @@ -525,8 +525,8 @@ public function magentoCLI($command, $timeout = null, $arguments = null) { $magentoBinary = realpath(MAGENTO_BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento'); $valid = $this->validateCommand($magentoBinary, $command); - // execute from shell when running tests from web root -- excludes cron jobs. - if ($valid && strpos($command, self::COMMAND_CRON_RUN) === false) { + // execute from shell when running tests from web root. + if ($valid) { return $this->shellExecMagentoCLI($magentoBinary, $command, $timeout, $arguments); } else { return $this->curlExecMagentoCLI($command, $timeout, $arguments); @@ -854,16 +854,18 @@ private function shellExecMagentoCLI($magentoBinary, $command, $timeout, $argume { $php = PHP_BINDIR ? PHP_BINDIR . DIRECTORY_SEPARATOR. 'php' : 'php'; $fullCommand = $php . ' -f ' . $magentoBinary . ' ' . $command . ' ' . $arguments; - $process = new Process(escapeshellcmd($fullCommand), MAGENTO_BP); + $process = Process::fromShellCommandline(escapeshellcmd($fullCommand), MAGENTO_BP); $process->setIdleTimeout($timeout); $process->setTimeout(0); try { $process->run(); - $output = $process->getOutput(); - if (!$process->isSuccessful()) { - $failureOutput = $process->getErrorOutput(); - if (!empty($failureOutput)) { - $output = $failureOutput; + if (strpos($command, self::COMMAND_CRON_RUN) === false) { + $output = $process->getOutput(); + if (!$process->isSuccessful()) { + $failureOutput = $process->getErrorOutput(); + if (!empty($failureOutput)) { + $output = $failureOutput; + } } } if (empty($output)) { @@ -967,4 +969,5 @@ private function checkForFilePath($string) { return preg_match('/\/[\S]+\//', $string); } -} \ No newline at end of file +} + From 50d9cd27a4edb4b0801abc821469d45f5196d26b Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan Date: Tue, 3 Dec 2019 14:24:27 -0600 Subject: [PATCH 4/9] MQE-1902: Running bin/magento from MagentoWebDriver causing timeout issues on pipeline Reverted changes, build still hangs with starting cron process from shell. --- .../Module/MagentoWebDriver.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php index ae12ad754..6bdfbcd12 100644 --- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php +++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php @@ -525,8 +525,9 @@ public function magentoCLI($command, $timeout = null, $arguments = null) { $magentoBinary = realpath(MAGENTO_BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento'); $valid = $this->validateCommand($magentoBinary, $command); - // execute from shell when running tests from web root. - if ($valid) { + // execute from shell when running tests from web root -- excluding cron + //TODO: investigate why cron:run hangs with shell execution on pipeline + if ($valid && ($command !== self::COMMAND_CRON_RUN)) { return $this->shellExecMagentoCLI($magentoBinary, $command, $timeout, $arguments); } else { return $this->curlExecMagentoCLI($command, $timeout, $arguments); @@ -859,13 +860,11 @@ private function shellExecMagentoCLI($magentoBinary, $command, $timeout, $argume $process->setTimeout(0); try { $process->run(); - if (strpos($command, self::COMMAND_CRON_RUN) === false) { - $output = $process->getOutput(); - if (!$process->isSuccessful()) { - $failureOutput = $process->getErrorOutput(); - if (!empty($failureOutput)) { - $output = $failureOutput; - } + $output = $process->getOutput(); + if (!$process->isSuccessful()) { + $failureOutput = $process->getErrorOutput(); + if (!empty($failureOutput)) { + $output = $failureOutput; } } if (empty($output)) { From 5946652fcd956441c9fabf36f948f657e12013a7 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan Date: Tue, 3 Dec 2019 14:27:23 -0600 Subject: [PATCH 5/9] MQE-1902: Running bin/magento from MagentoWebDriver causing timeout issues on pipeline Reverted changes, build still hangs with starting cron process from shell. --- .../FunctionalTestingFramework/Module/MagentoWebDriver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php index 6bdfbcd12..43437d116 100644 --- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php +++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php @@ -527,7 +527,7 @@ public function magentoCLI($command, $timeout = null, $arguments = null) $valid = $this->validateCommand($magentoBinary, $command); // execute from shell when running tests from web root -- excluding cron //TODO: investigate why cron:run hangs with shell execution on pipeline - if ($valid && ($command !== self::COMMAND_CRON_RUN)) { + if ($valid && strpos($command, self::COMMAND_CRON_RUN) === false) { return $this->shellExecMagentoCLI($magentoBinary, $command, $timeout, $arguments); } else { return $this->curlExecMagentoCLI($command, $timeout, $arguments); From 84b9f87123d00bd3b36cc2bad4358666ca48c756 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan Date: Tue, 3 Dec 2019 15:03:40 -0600 Subject: [PATCH 6/9] MQE-1902: Running bin/magento from MagentoWebDriver causing timeout issues on pipeline fixed phpunit checks --- .../FunctionalTestingFramework/Module/MagentoWebDriver.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php index 43437d116..710ea993e 100644 --- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php +++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php @@ -969,4 +969,3 @@ private function checkForFilePath($string) return preg_match('/\/[\S]+\//', $string); } } - From e207c475faae37be3c1be9066572c5d25f135c16 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan Date: Wed, 4 Dec 2019 11:28:53 -0600 Subject: [PATCH 7/9] MQE-1902: Running bin/magento from MagentoWebDriver causing timeout issues on pipeline reverting changes of community PR#343 --- .../Module/MagentoWebDriver.php | 167 +++--------------- 1 file changed, 29 insertions(+), 138 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php index 710ea993e..dacfbb2d4 100644 --- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php +++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php @@ -523,15 +523,35 @@ public function scrollToTopOfPage() */ public function magentoCLI($command, $timeout = null, $arguments = null) { - $magentoBinary = realpath(MAGENTO_BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento'); - $valid = $this->validateCommand($magentoBinary, $command); - // execute from shell when running tests from web root -- excluding cron - //TODO: investigate why cron:run hangs with shell execution on pipeline - if ($valid && strpos($command, self::COMMAND_CRON_RUN) === false) { - return $this->shellExecMagentoCLI($magentoBinary, $command, $timeout, $arguments); - } else { - return $this->curlExecMagentoCLI($command, $timeout, $arguments); - } + // Remove index.php if it's present in url + $baseUrl = rtrim( + str_replace('index.php', '', rtrim($this->config['url'], '/')), + '/' + ); + + $apiURL = UrlFormatter::format( + $baseUrl . '/' . ltrim(getenv('MAGENTO_CLI_COMMAND_PATH'), '/'), + false + ); + + $restExecutor = new WebapiExecutor(); + $executor = new CurlTransport(); + $executor->write( + $apiURL, + [ + 'token' => $restExecutor->getAuthToken(), + getenv('MAGENTO_CLI_COMMAND_PARAMETER') => $command, + 'arguments' => $arguments, + 'timeout' => $timeout, + ], + CurlInterface::POST, + [] + ); + $response = $executor->read(); + $restExecutor->close(); + $executor->close(); + + return $response; } /** @@ -839,133 +859,4 @@ public function makeScreenshot($name = null) $this->debug("Screenshot saved to $screenName"); AllureHelper::addAttachmentToCurrentStep($screenName, 'Screenshot'); } - - /** - * Takes given $command and executes it against bin/magento executable. Returns stdout output from the command. - * - * @param string $magentoBinary - * @param string $command - * @param integer $timeout - * @param string $arguments - * - * @throws \RuntimeException - * @return string - */ - private function shellExecMagentoCLI($magentoBinary, $command, $timeout, $arguments): string - { - $php = PHP_BINDIR ? PHP_BINDIR . DIRECTORY_SEPARATOR. 'php' : 'php'; - $fullCommand = $php . ' -f ' . $magentoBinary . ' ' . $command . ' ' . $arguments; - $process = Process::fromShellCommandline(escapeshellcmd($fullCommand), MAGENTO_BP); - $process->setIdleTimeout($timeout); - $process->setTimeout(0); - try { - $process->run(); - $output = $process->getOutput(); - if (!$process->isSuccessful()) { - $failureOutput = $process->getErrorOutput(); - if (!empty($failureOutput)) { - $output = $failureOutput; - } - } - if (empty($output)) { - $output = "CLI did not return output."; - } - } catch (ProcessTimedOutException $exception) { - $output = "CLI command timed out, no output available."; - } - - if ($this->checkForFilePath($output)) { - $output = "CLI output suppressed, filepath detected in output."; - } - - $exitCode = $process->getExitCode(); - - if ($exitCode !== 0) { - throw new \RuntimeException($process->getErrorOutput()); - } - return $output; - } - - /** - * Takes given $command and executes it against exposed MTF CLI entry point. Returns response from server. - * - * @param string $command - * @param integer $timeout - * @param string $arguments - * - * @return string - * @throws TestFrameworkException - */ - private function curlExecMagentoCLI($command, $timeout, $arguments): string - { - // Remove index.php if it's present in url - $baseUrl = rtrim( - str_replace('index.php', '', rtrim($this->config['url'], '/')), - '/' - ); - - $apiURL = UrlFormatter::format( - $baseUrl . '/' . ltrim(getenv('MAGENTO_CLI_COMMAND_PATH'), '/'), - false - ); - - $restExecutor = new WebapiExecutor(); - $executor = new CurlTransport(); - $executor->write( - $apiURL, - [ - 'token' => $restExecutor->getAuthToken(), - getenv('MAGENTO_CLI_COMMAND_PARAMETER') => $command, - 'arguments' => $arguments, - 'timeout' => $timeout, - ], - CurlInterface::POST, - [] - ); - $response = $executor->read(); - $restExecutor->close(); - $executor->close(); - - return $response; - } - - /** - * Checks magento list of CLI commands for given $command. Does not check command parameters, just base command. - * - * @param string $magentoBinary - * @param string $command - * - * @return boolean - */ - private function validateCommand($magentoBinary, $command) - { - exec($magentoBinary . ' list', $commandList); - // Trim list of commands after first whitespace - $commandList = array_map([$this, 'trimAfterWhitespace'], $commandList); - return in_array($this->trimAfterWhitespace($command), $commandList); - } - - /** - * Returns given string trimmed of everything after the first found whitespace. - * - * @param string $string - * - * @return string - */ - private function trimAfterWhitespace($string) - { - return strtok($string, ' '); - } - - /** - * Detects file path in string. - * - * @param string $string - * - * @return boolean - */ - private function checkForFilePath($string) - { - return preg_match('/\/[\S]+\//', $string); - } } From 712cc518039c2f87ee93e163d3e638019147ab63 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan Date: Wed, 4 Dec 2019 11:30:51 -0600 Subject: [PATCH 8/9] MQE-1902: Running bin/magento from MagentoWebDriver causing timeout issues on pipeline reverting changes of community PR#343 --- .../FunctionalTestingFramework/Module/MagentoWebDriver.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php index dacfbb2d4..5c86e0346 100644 --- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php +++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php @@ -53,8 +53,6 @@ class MagentoWebDriver extends WebDriver { use AttachmentSupport; - const COMMAND_CRON_RUN = 'cron:run'; - /** * List of known magento loading masks by selector * From fa8e51bab2821daddc4408a5c7516cd3174e5b7a Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan Date: Wed, 4 Dec 2019 13:06:18 -0600 Subject: [PATCH 9/9] MQE-1902: Running bin/magento from MagentoWebDriver causing timeout issues on pipeline removing unused references --- .../FunctionalTestingFramework/Module/MagentoWebDriver.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php index 5c86e0346..ff0c621dd 100644 --- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php +++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php @@ -21,8 +21,6 @@ use Magento\FunctionalTestingFramework\Util\ConfigSanitizerUtil; use Yandex\Allure\Adapter\AllureException; use Magento\FunctionalTestingFramework\Util\Protocol\CurlTransport; -use Symfony\Component\Process\Process; -use Symfony\Component\Process\Exception\ProcessTimedOutException; use Yandex\Allure\Adapter\Support\AttachmentSupport; use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException; use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;