33 * Copyright © Magento, Inc. All rights reserved.
44 * See COPYING.txt for license details.
55 */
6+ declare (strict_types=1 );
67
78use Magento \Framework \Component \ComponentRegistrar ;
89
1415 'USAGE ' ,
1516 <<<USAGE
1617Usage:
17- php -f $ scriptName path_to_phpunit.xml(.dist)
18+ php -f $ scriptName path_to_phpunit.xml(.dist) rest|soap|graphql|integration
1819USAGE
1920);
2021
21- assertUsage (empty ($ argv [1 ]) || !file_exists ($ argv [1 ]), 'missing or invalid phpunit.xml(.dist) file ' );
22- $ xmlDom = new DOMDocument ();
23- $ xmlDom ->preserveWhiteSpace = true ;
24- $ xmlDom ->formatOutput = true ;
25- assertUsage ($ xmlDom ->load ($ argv [1 ]) == false , 'missing or invalid phpunit.xml(.dist) file ' );
26- $ testType = getTestType ($ xmlDom );
27- // Update testsuite based on magento installation
28- $ xmlDom = updateTestSuite ($ xmlDom , $ testType );
29- $ xmlDom ->save ($ argv [1 ]);
30- echo "{$ testType } " . basename ($ argv [1 ]) . " is updated. " ;
22+ try {
23+ assertUsage (empty ($ argv [1 ]) || !file_exists ($ argv [1 ]), 'Invalid $argv[1]: must be a phpunit.xml(.dist) file ' );
24+ $ xmlDom = new DOMDocument ();
25+ $ xmlDom ->preserveWhiteSpace = true ;
26+ $ xmlDom ->formatOutput = true ;
27+ assertUsage ($ xmlDom ->load ($ argv [1 ]) == false , 'Invalid $argv[1]: must be a phpunit.xml(.dist) file ' );
28+ $ testType = !empty ($ argv [2 ]) ? getTestType ($ argv [2 ]) : null ;
29+ assertUsage (empty ($ testType ), 'Invalid $argv[2]: must be a value from "rest", "soap", "graphql" or "integration" ' );
30+
31+ // This flag allows the user to skip generating default test suite directory in result <testsuite> node.
32+ // This is desired for internal api-functional builds.
33+ $ skipDefaultDir = !empty ($ argv [3 ]);
34+
35+ // Update testsuite based on magento installation
36+ $ xmlDom = updateTestSuite ($ xmlDom , $ testType );
37+ $ xmlDom ->save ($ argv [1 ]);
38+ //phpcs:ignore Magento2.Security.LanguageConstruct
39+ print ("{$ testType } " . basename ($ argv [1 ]) . " is updated. " );
40+ //phpcs:ignore Magento2.Security.LanguageConstruct
41+ } catch (Exception $ e ) {
42+ //phpcs:ignore Magento2.Security.LanguageConstruct
43+ print ($ e ->getMessage ());
44+ //phpcs:ignore Magento2.Security.LanguageConstruct
45+ exit (1 );
46+ }
3147
3248/**
33- * Read DOMDocument to get test type.
49+ * Parse input string to get test type.
3450 *
35- * @param DOMDocument $dom
51+ * @param String $arg
3652 * @return string
3753 */
38- function getTestType (DOMDocument $ dom ): string
54+ function getTestType (String $ arg ): string
3955{
4056 $ testType = null ;
41- /** @var DOMElement $testsuite */
42- foreach ($ dom ->getElementsByTagName ('testsuite ' ) as $ testsuite ) {
43- if (stripos ($ testsuite ->getAttribute ('name ' ), 'real suite ' ) === false ) {
44- continue ;
45- }
46- if (stripos ($ testsuite ->getAttribute ('name ' ), 'rest ' ) !== false ) {
57+ switch (strtolower (trim ($ arg ))) {
58+ case 'rest ' :
4759 $ testType = 'REST ' ;
48- }
49- if ( stripos ( $ testsuite -> getAttribute ( ' name ' ), ' soap ') !== false ) {
60+ break ;
61+ case ' soap ':
5062 $ testType = 'SOAP ' ;
51- }
52- if ( stripos ( $ testsuite -> getAttribute ( ' name ' ), ' graphql ') !== false ) {
63+ break ;
64+ case ' graphql ':
5365 $ testType = 'GraphQl ' ;
54- }
55- if ( stripos ( $ testsuite -> getAttribute ( ' name ' ), ' integration ') !== false ) {
66+ break ;
67+ case ' integration ':
5668 $ testType = 'Integration ' ;
57- }
58- if ($ testType ) {
5969 break ;
60- }
70+ default :
71+ break ;
6172 }
6273 return $ testType ;
6374}
@@ -66,7 +77,7 @@ function getTestType(DOMDocument $dom): string
6677 * Find magento modules directories patterns through magento ComponentRegistrar.
6778 *
6879 * @param string $testType
69- * @return string []
80+ * @return array
7081 */
7182function findMagentoModuleDirs (string $ testType ): array
7283{
@@ -80,51 +91,64 @@ function findMagentoModuleDirs(string $testType): array
8091 $ magentoBaseDirPattern = preg_quote ($ magentoBaseDir , '/ ' );
8192 $ componentRegistrar = new ComponentRegistrar ();
8293 $ modulePaths = $ componentRegistrar ->getPaths (ComponentRegistrar::MODULE );
83- $ testPathPatterns = [];
94+ $ directoryPatterns = [];
95+ $ excludePatterns = [];
8496 foreach ($ modulePaths as $ modulePath ) {
8597 preg_match ('~ ' . $ magentoBaseDirPattern . '(.+)\/[^\/]+~ ' , $ modulePath , $ match );
8698 if (isset ($ match [1 ]) && isset ($ patterns [$ testType ])) {
87- $ testPathPatterns [] = '../../../ ' . $ match [1 ] . '/*/Test/ ' . $ patterns [$ testType ];
99+ $ directoryPatterns [] = '../../../ ' . $ match [1 ] . '/*/Test/ ' . $ patterns [$ testType ];
88100 if ($ testType == 'GraphQl ' ) {
89- $ testPathPatterns [] = '../../../ ' . $ match [1 ] . '/*GraphQl/Test/Api ' ;
90- $ testPathPatterns [] = '../../../ ' . $ match [1 ] . '/*graph-ql/Test/Api ' ;
101+ $ directoryPatterns [] = '../../../ ' . $ match [1 ] . '/*GraphQl/Test/Api ' ;
102+ $ directoryPatterns [] = '../../../ ' . $ match [1 ] . '/*graph-ql/Test/Api ' ;
103+ } elseif ($ testType == 'REST ' || $ testType == 'SOAP ' ) {
104+ $ excludePatterns [] = '../../../ ' . $ match [1 ] . '/*/Test/ ' . $ patterns ['GraphQl ' ];
105+ $ excludePatterns [] = '../../../ ' . $ match [1 ] . '/*GraphQl/Test/Api ' ;
106+ $ excludePatterns [] = '../../../ ' . $ match [1 ] . '/*graph-ql/Test/Api ' ;
91107 }
92108 }
93109 }
94110
95- return array_unique ($ testPathPatterns );
111+ return [
112+ 'directory ' => array_unique ($ directoryPatterns ),
113+ 'exclude ' => array_unique ($ excludePatterns )
114+ ];
96115}
97116
98117/**
99118 * Create a new testsuite DOMDocument based on installed magento module directories.
100119 *
101120 * @param string $testType
121+ * @param string $attribute
122+ * @param array $excludes
102123 * @return DOMDocument
103124 * @throws DOMException
104125 */
105- function createNewDomElement (string $ testType ): DOMDocument
126+ function createNewDomElement (string $ testType, string $ attribute , array $ excludes ): DOMDocument
106127{
107128 $ defTestSuite = getDefaultSuites ($ testType );
108129
109130 // Create the new element
110131 $ newTestSuite = new DomDocument ();
111132 $ newTestSuite ->formatOutput = true ;
112133 $ newTestSuiteElement = $ newTestSuite ->createElement ('testsuite ' );
113- if ($ testType == 'Integration ' ) {
114- $ newTestSuiteElement ->setAttribute ('name ' , 'Magento ' . $ testType . ' Tests Real Suite ' );
115- } else {
116- $ newTestSuiteElement ->setAttribute ('name ' , 'Magento ' . $ testType . ' Web API Functional Tests Real Suite ' );
117- }
134+ $ newTestSuiteElement ->setAttribute ('name ' , $ attribute );
118135 foreach ($ defTestSuite ['directory ' ] as $ directory ) {
119136 $ newTestSuiteElement ->appendChild ($ newTestSuite ->createElement ('directory ' , $ directory ));
120137 }
121- foreach (findMagentoModuleDirs ($ testType ) as $ directory ) {
138+
139+ $ moduleDirs = findMagentoModuleDirs ($ testType );
140+ foreach ($ moduleDirs ['directory ' ] as $ directory ) {
122141 $ newTestSuiteElement ->appendChild ($ newTestSuite ->createElement ('directory ' , $ directory ));
123142 }
124- foreach ($ defTestSuite ['exclude ' ] as $ exclude ) {
143+ foreach ($ defTestSuite ['exclude ' ] as $ defExclude ) {
144+ $ newTestSuiteElement ->appendChild ($ newTestSuite ->createElement ('exclude ' , $ defExclude ));
145+ }
146+ foreach ($ moduleDirs ['exclude ' ] as $ modExclude ) {
147+ $ newTestSuiteElement ->appendChild ($ newTestSuite ->createElement ('exclude ' , $ modExclude ));
148+ }
149+ foreach ($ excludes as $ exclude ) {
125150 $ newTestSuiteElement ->appendChild ($ newTestSuite ->createElement ('exclude ' , $ exclude ));
126151 }
127-
128152 $ newTestSuite ->appendChild ($ newTestSuiteElement );
129153 return $ newTestSuite ;
130154}
@@ -142,13 +166,23 @@ function updateTestSuite(DOMDocument $dom, string $testType): DOMDocument
142166 // Locate the old node
143167 $ xpath = new DOMXpath ($ dom );
144168 $ nodelist = $ xpath ->query ('/phpunit/testsuites/testsuite ' );
145- for ($ index = 0 ; $ index < $ nodelist ->count (); $ index ++) {
146- $ oldNode = $ nodelist ->item ($ index );
147- if (stripos ($ oldNode ->getAttribute ('name ' ), 'real suite ' ) !== false ) {
169+ /** @var DOMNode $node */
170+ foreach ($ nodelist as $ node ) {
171+ $ attribute = $ node ->getAttribute ('name ' );
172+ if (stripos ($ attribute , 'real ' ) !== false ) {
173+ $ excludes = [];
174+ $ excludeList = $ node ->getElementsByTagName ('exclude ' );
175+ /** @var DOMNode $excludeNode */
176+ foreach ($ excludeList as $ excludeNode ) {
177+ $ excludes [] = $ excludeNode ->textContent ;
178+ }
148179 // Load the $parent document fragment into the current document
149- $ newNode = $ dom ->importNode (createNewDomElement ($ testType )->documentElement , true );
180+ $ newNode = $ dom ->importNode (
181+ createNewDomElement ($ testType , $ attribute , $ excludes )->documentElement ,
182+ true
183+ );
150184 // Replace
151- $ oldNode ->parentNode ->replaceChild ($ newNode , $ oldNode );
185+ $ node ->parentNode ->replaceChild ($ newNode , $ node );
152186 }
153187 }
154188 return $ dom ;
@@ -177,6 +211,8 @@ function assertUsage(bool $condition, string $error): void
177211 */
178212function getDefaultSuites (string $ testType ): array
179213{
214+ global $ skipDefaultDir ;
215+
180216 $ suites = [];
181217 switch ($ testType ) {
182218 case 'Integration ' :
@@ -191,29 +227,17 @@ function getDefaultSuites(string $testType): array
191227 ];
192228 break ;
193229 case 'REST ' :
194- $ suites = [
195- 'directory ' => [
196- 'testsuite '
197- ],
198- 'exclude ' => [
199- 'testsuite/Magento/GraphQl '
200- ]
201- ];
202- break ;
203230 case 'SOAP ' :
204231 $ suites = [
205- 'directory ' => [
206- 'testsuite '
207- ],
232+ 'directory ' => $ skipDefaultDir ? [] : ['testsuite ' ],
208233 'exclude ' => [
234+ 'testsuite/Magento/GraphQl '
209235 ]
210236 ];
211237 break ;
212238 case 'GraphQl ' :
213239 $ suites = [
214- 'directory ' => [
215- 'testsuite/Magento/GraphQl '
216- ],
240+ 'directory ' => $ skipDefaultDir ? [] : ['testsuite/Magento/GraphQl ' ],
217241 'exclude ' => [
218242 ]
219243 ];
0 commit comments