Skip to content

MQE-1043: MFTF force flag should ignore the magento base url even when valid #143

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 4 commits into from
Jun 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use AspectMock\Proxy\Verifier;
use AspectMock\Test as AspectMock;

use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
use Magento\FunctionalTestingFramework\ObjectManager;
use Magento\FunctionalTestingFramework\ObjectManagerFactory;
use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil;
Expand Down Expand Up @@ -54,9 +56,10 @@ public function testGetModulePathsAlreadySet()
*/
public function testGetModulePathsAggregate()
{
$this->setMockResolverClass(false, null, null, null, ["example" . DIRECTORY_SEPARATOR . "paths"]);
$this->mockForceGenerate(false);
$this->setMockResolverClass(false, null, null, null, ["example" => "example" . DIRECTORY_SEPARATOR . "paths"]);
$resolver = ModuleResolver::getInstance();
$this->setMockResolverProperties($resolver, null, null);
$this->setMockResolverProperties($resolver, null, [0 => "Magento_example"]);
$this->assertEquals(
[
"example" . DIRECTORY_SEPARATOR . "paths",
Expand All @@ -73,12 +76,13 @@ public function testGetModulePathsAggregate()
*/
public function testGetModulePathsLocations()
{
$this->mockForceGenerate(false);
$mockResolver = $this->setMockResolverClass(
false,
null,
true,
[0 => "magento_example"],
null,
null,
["example" . DIRECTORY_SEPARATOR . "paths"]
["example" => "example" . DIRECTORY_SEPARATOR . "paths"]
);
$resolver = ModuleResolver::getInstance();
$this->setMockResolverProperties($resolver, null, null);
Expand Down Expand Up @@ -166,15 +170,78 @@ function ($arg1, $arg2) {
}

/**
* Validate that getEnabledModules returns correctly with no admin token
* Validate that getEnabledModules errors out when no Admin Token is returned and --force is false
* @throws \Exception
*/
public function testGetModulePathsNoAdminToken()
{
// Set --force to false
$this->mockForceGenerate(false);

// Mock ModuleResolver and $enabledModulesPath
$this->setMockResolverClass(false, null, ["example" . DIRECTORY_SEPARATOR . "paths"], []);
$resolver = ModuleResolver::getInstance();
$this->setMockResolverProperties($resolver, null, null);
$this->assertEquals(["example" . DIRECTORY_SEPARATOR . "paths"], $resolver->getModulesPath());

// Cannot Generate if no --force was passed in and no Admin Token is returned succesfully
$this->expectException(TestFrameworkException::class);
$resolver->getModulesPath();
}

/**
* Validates that getAdminToken is not called when --force is enabled
*/
public function testGetAdminTokenNotCalledWhenForce()
{
// Set --force to true
$this->mockForceGenerate(true);

// Mock ModuleResolver and applyCustomModuleMethods()
$mockResolver = $this->setMockResolverClass();
$resolver = ModuleResolver::getInstance();
$this->setMockResolverProperties($resolver, null, null);
$resolver->getModulesPath();
$mockResolver->verifyNeverInvoked("getAdminToken");

// verifyNeverInvoked does not add to assertion count
$this->addToAssertionCount(1);
}

/**
* Verify the getAdminToken method returns throws an exception if ENV is not fully loaded.
*/
public function testGetAdminTokenWithMissingEnv()
{
// Set --force to true
$this->mockForceGenerate(false);

// Unset env
unset($_ENV['MAGENTO_ADMIN_USERNAME']);

// Mock ModuleResolver and applyCustomModuleMethods()
$mockResolver = $this->setMockResolverClass();
$resolver = ModuleResolver::getInstance();

// Expect exception
$this->expectException(TestFrameworkException::class);
$resolver->getModulesPath();
}

/**
* Verify the getAdminToken method returns throws an exception if Token was bad.
*/
public function testGetAdminTokenWithBadResponse()
{
// Set --force to true
$this->mockForceGenerate(false);

// Mock ModuleResolver and applyCustomModuleMethods()
$mockResolver = $this->setMockResolverClass();
$resolver = ModuleResolver::getInstance();

// Expect exception
$this->expectException(TestFrameworkException::class);
$resolver->getModulesPath();
}

/**
Expand Down Expand Up @@ -205,7 +272,7 @@ private function setMockResolverClass(
if (isset($mockToken)) {
$mockMethods['getAdminToken'] = $mockToken;
}
if (isset($mockModules)) {
if (isset($mockGetModules)) {
$mockMethods['getEnabledModules'] = $mockGetModules;
}
if (isset($mockCustomMethods)) {
Expand All @@ -220,7 +287,7 @@ private function setMockResolverClass(
if (isset($mockCustomModules)) {
$mockMethods['getCustomModulePaths'] = $mockCustomModules;
}
$mockMethods['printMagentoVersionInfo'] = null;
// $mockMethods['printMagentoVersionInfo'] = null;

$mockResolver = AspectMock::double(
ModuleResolver::class,
Expand Down Expand Up @@ -260,12 +327,36 @@ private function setMockResolverProperties($instance, $mockPaths = null, $mockMo
$property->setValue($instance, $mockBlacklist);
}

/**
* Mocks MftfApplicationConfig->forceGenerateEnabled()
* @param $forceGenerate
* @throws \Exception
* @return void
*/
private function mockForceGenerate($forceGenerate)
{
$mockConfig = AspectMock::double(
MftfApplicationConfig::class,
['forceGenerateEnabled' => $forceGenerate]
);
$instance = AspectMock::double(
ObjectManager::class,
['create' => $mockConfig->make(), 'get' => null]
)->make();
AspectMock::double(ObjectManagerFactory::class, ['getObjectManager' => $instance]);
}

/**
* After method functionality
* @return void
*/
protected function tearDown()
{
// re set env
if (!isset($_ENV['MAGENTO_ADMIN_USERNAME'])) {
$_ENV['MAGENTO_ADMIN_USERNAME'] = "admin";
}

AspectMock::clean();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

namespace Magento\FunctionalTestingFramework\Exceptions;

use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil;

/**
* Class TestFrameworkException
*/
Expand All @@ -14,9 +16,17 @@ class TestFrameworkException extends \Exception
/**
* TestFrameworkException constructor.
* @param string $message
* @param array $context
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
public function __construct($message)
public function __construct($message, $context = [])
{
list($childClass, $callingClass) = debug_backtrace(false, 2);
LoggingUtil::getInstance()->getLogger($callingClass['class'])->error(
$message,
$context
);

parent::__construct($message);
}
}
60 changes: 36 additions & 24 deletions src/Magento/FunctionalTestingFramework/Util/ModuleResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace Magento\FunctionalTestingFramework\Util;

use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil;

/**
Expand Down Expand Up @@ -138,10 +139,6 @@ public function getEnabledModules()
}

$token = $this->getAdminToken();
if (!$token || !is_string($token)) {
$this->enabledModules = [];
return $this->enabledModules;
}

$url = ConfigSanitizerUtil::sanitizeUrl(getenv('MAGENTO_BASE_URL')) . $this->moduleUrl;

Expand All @@ -157,10 +154,17 @@ public function getEnabledModules()
$response = curl_exec($ch);

if (!$response) {
$this->enabledModules = [];
} else {
$this->enabledModules = json_decode($response);
$message = "Could not retrieve Modules from Magento Instance.";
$context = [
"Admin Module List Url" => $url,
"MAGENTO_ADMIN_USERNAME" => getenv("MAGENTO_ADMIN_USERNAME"),
"MAGENTO_ADMIN_PASSWORD" => getenv("MAGENTO_ADMIN_PASSWORD"),
];
throw new TestFrameworkException($message, $context);
}

$this->enabledModules = json_decode($response);

return $this->enabledModules;
}

Expand Down Expand Up @@ -190,25 +194,14 @@ public function getModulesPath()
return $this->enabledModulePaths;
}

$enabledModules = $this->getEnabledModules();
if (empty($enabledModules) && !MftfApplicationConfig::getConfig()->forceGenerateEnabled()) {
$errorMsg = 'Could not retrieve enabled modules from provided MAGENTO_BASE_URL ' .
'please make sure Magento is available at this url';
LoggingUtil::getInstance()->getLogger(ModuleResolver::class)->error(
$errorMsg,
['MAGENTO_BASE_URL' => getenv('MAGENTO_BASE_URL')]
);
trigger_error($errorMsg, E_USER_ERROR);
}

$allModulePaths = $this->aggregateTestModulePaths();

if (empty($enabledModules)) {
if (MftfApplicationConfig::getConfig()->forceGenerateEnabled()) {
$this->enabledModulePaths = $this->applyCustomModuleMethods($allModulePaths);
return $this->enabledModulePaths;
}

$enabledModules = array_merge($enabledModules, $this->getModuleWhitelist());
$enabledModules = array_merge($this->getEnabledModules(), $this->getModuleWhitelist());
$enabledDirectoryPaths = $this->getEnabledDirectoryPaths($enabledModules, $allModulePaths);

$this->enabledModulePaths = $this->applyCustomModuleMethods($enabledDirectoryPaths);
Expand Down Expand Up @@ -325,9 +318,15 @@ private function getEnabledDirectoryPaths($enabledModules, $allModulePaths)
{
$enabledDirectoryPaths = [];
foreach ($enabledModules as $magentoModuleName) {
$moduleShortName = explode('_', $magentoModuleName)[1];
// Magento_Backend -> Backend or DevDocs -> DevDocs (if whitelisted has no underscore)
$moduleShortName = explode('_', $magentoModuleName)[1] ?? $magentoModuleName;
if (!isset($this->knownDirectories[$moduleShortName]) && !isset($allModulePaths[$moduleShortName])) {
continue;
} elseif (isset($this->knownDirectories[$moduleShortName]) && !isset($allModulePaths[$moduleShortName])) {
LoggingUtil::getInstance()->getLogger(ModuleResolver::class)->warn(
"Known directory could not match to an existing path.",
['knownDirectory' => $moduleShortName]
);
} else {
$enabledDirectoryPaths[$moduleShortName] = $allModulePaths[$moduleShortName];
}
Expand All @@ -342,7 +341,6 @@ private function getEnabledDirectoryPaths($enabledModules, $allModulePaths)
*/
private function printMagentoVersionInfo()
{

if (MftfApplicationConfig::getConfig()->forceGenerateEnabled()) {
return;
}
Expand Down Expand Up @@ -377,7 +375,13 @@ protected function getAdminToken()
$login = $_ENV['MAGENTO_ADMIN_USERNAME'] ?? null;
$password = $_ENV['MAGENTO_ADMIN_PASSWORD'] ?? null;
if (!$login || !$password || !isset($_ENV['MAGENTO_BASE_URL'])) {
return false;
$message = "Cannot retrieve API token without credentials and base url, please fill out .env.";
$context = [
"MAGENTO_BASE_URL" => getenv("MAGENTO_BASE_URL"),
"MAGENTO_ADMIN_USERNAME" => getenv("MAGENTO_ADMIN_USERNAME"),
"MAGENTO_ADMIN_PASSWORD" => getenv("MAGENTO_ADMIN_PASSWORD"),
];
throw new TestFrameworkException($message, $context);
}

$url = ConfigSanitizerUtil::sanitizeUrl($_ENV['MAGENTO_BASE_URL']) . $this->adminTokenUrl;
Expand All @@ -398,9 +402,17 @@ protected function getAdminToken()
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$response = curl_exec($ch);

if (!$response) {
return $response;
$message = "Could not retrieve API token from Magento Instance.";
$context = [
"Admin Integration Token Url" => $url,
"MAGENTO_ADMIN_USERNAME" => getenv("MAGENTO_ADMIN_USERNAME"),
"MAGENTO_ADMIN_PASSWORD" => getenv("MAGENTO_ADMIN_PASSWORD"),
];
throw new TestFrameworkException($message, $context);
}

return json_decode($response);
}

Expand Down