Skip to content

Commit 046876e

Browse files
Merge branch '2.4-develop' into L3-PR-2023-09-06
2 parents 825712a + 9a58794 commit 046876e

File tree

1 file changed

+246
-0
lines changed

1 file changed

+246
-0
lines changed

dev/tests/utils/update-test-paths.php

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\Framework\Component\ComponentRegistrar;
9+
10+
require_once __DIR__ . '/../../../app/autoload.php';
11+
12+
$scriptName = basename(__FILE__);
13+
14+
define(
15+
'USAGE',
16+
<<<USAGE
17+
Usage:
18+
php -f $scriptName path_to_phpunit.xml(.dist) rest|soap|graphql|integration
19+
USAGE
20+
);
21+
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+
}
47+
48+
/**
49+
* Parse input string to get test type.
50+
*
51+
* @param String $arg
52+
* @return string
53+
*/
54+
function getTestType(String $arg): string
55+
{
56+
$testType = null;
57+
switch (strtolower(trim($arg))) {
58+
case 'rest':
59+
$testType = 'REST';
60+
break;
61+
case 'soap':
62+
$testType = 'SOAP';
63+
break;
64+
case 'graphql':
65+
$testType = 'GraphQl';
66+
break;
67+
case 'integration':
68+
$testType = 'Integration';
69+
break;
70+
default:
71+
break;
72+
}
73+
return $testType;
74+
}
75+
76+
/**
77+
* Find magento modules directories patterns through magento ComponentRegistrar.
78+
*
79+
* @param string $testType
80+
* @return array
81+
*/
82+
function findMagentoModuleDirs(string $testType): array
83+
{
84+
$patterns = [
85+
'Integration' => 'Integration',
86+
'REST' => 'Api',
87+
'SOAP' => 'Api',
88+
'GraphQl' => 'GraphQl'
89+
];
90+
$magentoBaseDir = realpath(__DIR__ . '/../../..') . DIRECTORY_SEPARATOR;
91+
$magentoBaseDirPattern = preg_quote($magentoBaseDir, '/');
92+
$componentRegistrar = new ComponentRegistrar();
93+
$modulePaths = $componentRegistrar->getPaths(ComponentRegistrar::MODULE);
94+
$directoryPatterns = [];
95+
$excludePatterns = [];
96+
foreach ($modulePaths as $modulePath) {
97+
preg_match('~' . $magentoBaseDirPattern . '(.+)\/[^\/]+~', $modulePath, $match);
98+
if (isset($match[1]) && isset($patterns[$testType])) {
99+
$directoryPatterns[] = '../../../' . $match[1] . '/*/Test/' . $patterns[$testType];
100+
if ($testType == 'GraphQl') {
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';
107+
}
108+
}
109+
}
110+
111+
return [
112+
'directory' => array_unique($directoryPatterns),
113+
'exclude' => array_unique($excludePatterns)
114+
];
115+
}
116+
117+
/**
118+
* Create a new testsuite DOMDocument based on installed magento module directories.
119+
*
120+
* @param string $testType
121+
* @param string $attribute
122+
* @param array $excludes
123+
* @return DOMDocument
124+
* @throws DOMException
125+
*/
126+
function createNewDomElement(string $testType, string $attribute, array $excludes): DOMDocument
127+
{
128+
$defTestSuite = getDefaultSuites($testType);
129+
130+
// Create the new element
131+
$newTestSuite = new DomDocument();
132+
$newTestSuite->formatOutput = true;
133+
$newTestSuiteElement = $newTestSuite->createElement('testsuite');
134+
$newTestSuiteElement->setAttribute('name', $attribute);
135+
foreach ($defTestSuite['directory'] as $directory) {
136+
$newTestSuiteElement->appendChild($newTestSuite->createElement('directory', $directory));
137+
}
138+
139+
$moduleDirs = findMagentoModuleDirs($testType);
140+
foreach ($moduleDirs['directory'] as $directory) {
141+
$newTestSuiteElement->appendChild($newTestSuite->createElement('directory', $directory));
142+
}
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) {
150+
$newTestSuiteElement->appendChild($newTestSuite->createElement('exclude', $exclude));
151+
}
152+
$newTestSuite->appendChild($newTestSuiteElement);
153+
return $newTestSuite;
154+
}
155+
156+
/**
157+
* Replace testsuite node with created new testsuite node in dom document passed in.
158+
*
159+
* @param DOMDocument $dom
160+
* @param string $testType
161+
* @return DOMDocument
162+
* @throws DOMException
163+
*/
164+
function updateTestSuite(DOMDocument $dom, string $testType): DOMDocument
165+
{
166+
// Locate the old node
167+
$xpath = new DOMXpath($dom);
168+
$nodelist = $xpath->query('/phpunit/testsuites/testsuite');
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+
}
179+
// Load the $parent document fragment into the current document
180+
$newNode = $dom->importNode(
181+
createNewDomElement($testType, $attribute, $excludes)->documentElement,
182+
true
183+
);
184+
// Replace
185+
$node->parentNode->replaceChild($newNode, $node);
186+
}
187+
}
188+
return $dom;
189+
}
190+
191+
/**
192+
* Assert usage by throwing exception on condition evaluating to true
193+
*
194+
* @param bool $condition
195+
* @param string $error
196+
* @throws Exception
197+
*/
198+
function assertUsage(bool $condition, string $error): void
199+
{
200+
if ($condition) {
201+
$error .= "\n" . USAGE;
202+
throw new Exception($error);
203+
}
204+
}
205+
206+
/**
207+
* Return suite default directories and excludes for a given test type.
208+
*
209+
* @param string $testType
210+
* @return array
211+
*/
212+
function getDefaultSuites(string $testType): array
213+
{
214+
global $skipDefaultDir;
215+
216+
$suites = [];
217+
switch ($testType) {
218+
case 'Integration':
219+
$suites = [
220+
'directory' => [
221+
'testsuite'
222+
],
223+
'exclude' => [
224+
'testsuite/Magento/MemoryUsageTest.php',
225+
'testsuite/Magento/IntegrationTest.php'
226+
]
227+
];
228+
break;
229+
case 'REST':
230+
case 'SOAP':
231+
$suites = [
232+
'directory' => $skipDefaultDir ? [] : ['testsuite'],
233+
'exclude' => [
234+
'testsuite/Magento/GraphQl'
235+
]
236+
];
237+
break;
238+
case 'GraphQl':
239+
$suites = [
240+
'directory' => $skipDefaultDir ? [] : ['testsuite/Magento/GraphQl'],
241+
'exclude' => [
242+
]
243+
];
244+
}
245+
return $suites;
246+
}

0 commit comments

Comments
 (0)