22
22
use Yandex \Allure \Adapter \AllureException ;
23
23
use Magento \FunctionalTestingFramework \Util \Protocol \CurlTransport ;
24
24
use Symfony \Component \Process \Process ;
25
+ use Symfony \Component \Process \Exception \ProcessTimedOutException ;
25
26
use Yandex \Allure \Adapter \Support \AttachmentSupport ;
26
27
use Magento \FunctionalTestingFramework \Exceptions \TestFrameworkException ;
27
28
use Magento \FunctionalTestingFramework \Config \MftfApplicationConfig ;
@@ -52,6 +53,8 @@ class MagentoWebDriver extends WebDriver
52
53
{
53
54
use AttachmentSupport;
54
55
56
+ const COMMAND_CRON_RUN = 'cron:run ' ;
57
+
55
58
/**
56
59
* List of known magento loading masks by selector
57
60
*
@@ -520,13 +523,14 @@ public function scrollToTopOfPage()
520
523
*/
521
524
public function magentoCLI ($ command , $ timeout = null , $ arguments = null )
522
525
{
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
+ }
530
534
}
531
535
532
536
/**
@@ -838,6 +842,7 @@ public function makeScreenshot($name = null)
838
842
/**
839
843
* Takes given $command and executes it against bin/magento executable. Returns stdout output from the command.
840
844
*
845
+ * @param string $magentoBinary
841
846
* @param string $command
842
847
* @param integer $timeout
843
848
* @param string $arguments
@@ -846,20 +851,41 @@ public function makeScreenshot($name = null)
846
851
* @return string
847
852
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
848
853
*/
849
- private function shellExecMagentoCLI ($ command , $ timeout , $ arguments ): string
854
+ private function shellExecMagentoCLI ($ magentoBinary , $ command , $ timeout , $ arguments ): string
850
855
{
851
856
$ 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 );
855
859
$ process ->setIdleTimeout ($ timeout );
856
860
$ 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
+
858
885
if ($ exitCode !== 0 ) {
859
886
throw new \RuntimeException ($ process ->getErrorOutput ());
860
887
}
861
-
862
- return $ process ->getOutput ();
888
+ return $ output ;
863
889
}
864
890
865
891
/**
@@ -904,4 +930,40 @@ private function curlExecMagentoCLI($command, $timeout, $arguments): string
904
930
905
931
return $ response ;
906
932
}
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
+
907
968
}
969
+
0 commit comments