Skip to content

MQE-1124: [Github Issue] Allow running tests for modules installed in… #228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Sep 25, 2018
Original file line number Diff line number Diff line change
Expand Up @@ -96,27 +96,22 @@ public function testGetModulePathsLocations()
);

// Define the Module paths from app/code
$appCodePath = MAGENTO_BP
. DIRECTORY_SEPARATOR
. 'app' . DIRECTORY_SEPARATOR
. 'code' . DIRECTORY_SEPARATOR;
$magentoBaseCodePath = MAGENTO_BP;

// Define the Module paths from default TESTS_MODULE_PATH
$modulePath = defined('TESTS_MODULE_PATH') ? TESTS_MODULE_PATH : TESTS_BP;

// Define the Module paths from vendor modules
$vendorCodePath = PROJECT_ROOT
. DIRECTORY_SEPARATOR
. 'vendor' . DIRECTORY_SEPARATOR;
$projectRootCodePath = PROJECT_ROOT;

$mockResolver->verifyInvoked('globRelevantPaths', [$modulePath, '']);
$mockResolver->verifyInvoked(
'globRelevantPaths',
[$appCodePath, DIRECTORY_SEPARATOR . 'Test' . DIRECTORY_SEPARATOR .'Mftf']
[$magentoBaseCodePath, 'Test' . DIRECTORY_SEPARATOR .'Mftf']
);
$mockResolver->verifyInvoked(
'globRelevantPaths',
[$vendorCodePath, DIRECTORY_SEPARATOR . 'Test' . DIRECTORY_SEPARATOR .'Mftf']
[$projectRootCodePath, 'Test' . DIRECTORY_SEPARATOR .'Mftf']
);
}

Expand Down Expand Up @@ -151,8 +146,6 @@ public function testGetModulePathsBlacklist()
function ($arg1, $arg2) {
if ($arg2 === "") {
$mockValue = ["somePath" => "somePath"];
} elseif (strpos($arg1, "app")) {
$mockValue = ["otherPath" => "otherPath"];
} else {
$mockValue = ["lastPath" => "lastPath"];
}
Expand All @@ -161,7 +154,7 @@ function ($arg1, $arg2) {
);
$resolver = ModuleResolver::getInstance();
$this->setMockResolverProperties($resolver, null, null, ["somePath"]);
$this->assertEquals(["otherPath", "lastPath"], $resolver->getModulesPath());
$this->assertEquals(["lastPath", "lastPath"], $resolver->getModulesPath());
TestLoggingUtil::getInstance()->validateMockLogStatement(
'info',
'excluding module',
Expand Down
85 changes: 72 additions & 13 deletions src/Magento/FunctionalTestingFramework/Util/ModuleResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ class ModuleResolver
*/
const CUSTOM_MODULE_PATHS = 'CUSTOM_MODULE_PATHS';

/**
* List of path types present in Magento Component Registrar
*/
const PATHS = ['module', 'library', 'theme', 'language'];

/**
* Magento Registrar Class
*/
const REGISTRAR_CLASS = "\Magento\Framework\Component\ComponentRegistrar";

/**
* Magento Directory Structure Name Prefix
*/
const MAGENTO_PREFIX = "Magento_";

/**
* Enabled modules.
*
Expand Down Expand Up @@ -218,25 +233,20 @@ private function aggregateTestModulePaths()
{
$allModulePaths = [];

// Define the Module paths from app/code
$appCodePath = MAGENTO_BP
. DIRECTORY_SEPARATOR
. 'app' . DIRECTORY_SEPARATOR
. 'code' . DIRECTORY_SEPARATOR;
// Define the Module paths from magento bp
$magentoBaseCodePath = MAGENTO_BP;

// Define the Module paths from default TESTS_MODULE_PATH
$modulePath = defined('TESTS_MODULE_PATH') ? TESTS_MODULE_PATH : TESTS_BP;
$modulePath = rtrim($modulePath, DIRECTORY_SEPARATOR);

// Define the Module paths from vendor modules
$vendorCodePath = PROJECT_ROOT
. DIRECTORY_SEPARATOR
. 'vendor' . DIRECTORY_SEPARATOR;
// Define the Module paths from project root
$projectRootCodePath = PROJECT_ROOT;

$codePathsToPattern = [
$modulePath => '',
$appCodePath => DIRECTORY_SEPARATOR . 'Test' . DIRECTORY_SEPARATOR . 'Mftf',
$vendorCodePath => DIRECTORY_SEPARATOR . 'Test' . DIRECTORY_SEPARATOR . 'Mftf'
$magentoBaseCodePath => 'Test' . DIRECTORY_SEPARATOR . 'Mftf',
$projectRootCodePath => 'Test' . DIRECTORY_SEPARATOR . 'Mftf'
];

foreach ($codePathsToPattern as $codePath => $pattern) {
Expand Down Expand Up @@ -264,8 +274,11 @@ private function globRelevantPaths($testPath, $pattern)
$relevantPaths = $this->globRelevantWrapper($testPath, $pattern);
}

$allComponents = $this->getRegisteredModuleList();

foreach ($relevantPaths as $codePath) {
$mainModName = basename(str_replace($pattern, '', $codePath));
$mainModName = array_search($codePath, $allComponents) ?: basename(str_replace($pattern, '', $codePath));
$mainModName = str_replace(self::MAGENTO_PREFIX, "", $mainModName);
$modulePaths[$mainModName][] = $codePath;

if (MftfApplicationConfig::getConfig()->verboseEnabled()) {
Expand All @@ -288,7 +301,15 @@ private function globRelevantPaths($testPath, $pattern)
*/
private static function globRelevantWrapper($testPath, $pattern)
{
return glob($testPath . '*' . DIRECTORY_SEPARATOR . '*' . $pattern);
if ($pattern == "") {
return glob($testPath . '*' . DIRECTORY_SEPARATOR . '*' . $pattern);
}
$subDirectory = "*" . DIRECTORY_SEPARATOR;
$directories = glob($testPath . $subDirectory . $pattern, GLOB_ONLYDIR);
foreach (glob($testPath . $subDirectory, GLOB_ONLYDIR) as $dir) {
$directories = array_merge_recursive($directories, self::globRelevantWrapper($dir, $pattern));
}
return $directories;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These directory changes seem to pick up modules under vendor just fine, but consider the following:
I have pulled CE 2.2.6 and attempted to generate tests, the following path is directory is found by this glob:
/Users/kkozan/Documents/TestPull/magento2ce/vendor/magento/module-catalog/Test/Mftf
The function GlobRelevantPaths assigns the above path to an index based on the module it found (which is found via the pattern given, leaving the path under module-catalog.

This is going to fail to map to the module returned by our ping to Magento, Magento_Catalog.
We need to find a way to map module-* to Magento_* manually or hopefully from the magento instance itself.

}

/**
Expand Down Expand Up @@ -504,4 +525,42 @@ private function getModuleBlacklist()
{
return $this->moduleBlacklist;
}

/**
* Calls Magento method for determining registered modules.
*
* @return string[]
*/
private function getRegisteredModuleList()
{
if (array_key_exists('MAGENTO_BP', $_ENV)) {
$autoloadPath = realpath(MAGENTO_BP . "/app/autoload.php");
if ($autoloadPath) {
require_once($autoloadPath);
} else {
throw new TestFrameworkException("Magento app/autoload.php not found with given MAGENTO_BP:"
. MAGENTO_BP);
}
}

try {
$allComponents = [];
if (!class_exists(self::REGISTRAR_CLASS)) {
throw new TestFrameworkException("Magento Installation not found when loading registered modules.\n");
}
$components = new \Magento\Framework\Component\ComponentRegistrar();
foreach (self::PATHS as $componentType) {
$allComponents = array_merge($allComponents, $components->getPaths($componentType));
}
array_walk($allComponents, function (&$value) {
$value .= DIRECTORY_SEPARATOR . 'Test' . DIRECTORY_SEPARATOR . 'Mftf';
});
return $allComponents;
} catch (TestFrameworkException $e) {
LoggingUtil::getInstance()->getLogger(ModuleResolver::class)->warning(
"$e"
);
}
return [];
}
}