Skip to content

Commit 371f352

Browse files
authored
MQE-1043: MFTF force flag should ignore the magento base url even when valid
- ModuleResolver now completely ignores trying to get enabledModules if --force is set - Shuffled around exception throwing for faster failure - Fix for MQE-1017 included, exceptions are now more verbose and precise as to when they are thrown.
1 parent 37de3a1 commit 371f352

File tree

3 files changed

+147
-34
lines changed

3 files changed

+147
-34
lines changed

dev/tests/unit/Magento/FunctionalTestFramework/Util/ModuleResolverTest.php

Lines changed: 100 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use AspectMock\Proxy\Verifier;
1010
use AspectMock\Test as AspectMock;
1111

12+
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
13+
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
1214
use Magento\FunctionalTestingFramework\ObjectManager;
1315
use Magento\FunctionalTestingFramework\ObjectManagerFactory;
1416
use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil;
@@ -54,9 +56,10 @@ public function testGetModulePathsAlreadySet()
5456
*/
5557
public function testGetModulePathsAggregate()
5658
{
57-
$this->setMockResolverClass(false, null, null, null, ["example" . DIRECTORY_SEPARATOR . "paths"]);
59+
$this->mockForceGenerate(false);
60+
$this->setMockResolverClass(false, null, null, null, ["example" => "example" . DIRECTORY_SEPARATOR . "paths"]);
5861
$resolver = ModuleResolver::getInstance();
59-
$this->setMockResolverProperties($resolver, null, null);
62+
$this->setMockResolverProperties($resolver, null, [0 => "Magento_example"]);
6063
$this->assertEquals(
6164
[
6265
"example" . DIRECTORY_SEPARATOR . "paths",
@@ -73,12 +76,13 @@ public function testGetModulePathsAggregate()
7376
*/
7477
public function testGetModulePathsLocations()
7578
{
79+
$this->mockForceGenerate(false);
7680
$mockResolver = $this->setMockResolverClass(
77-
false,
78-
null,
81+
true,
82+
[0 => "magento_example"],
7983
null,
8084
null,
81-
["example" . DIRECTORY_SEPARATOR . "paths"]
85+
["example" => "example" . DIRECTORY_SEPARATOR . "paths"]
8286
);
8387
$resolver = ModuleResolver::getInstance();
8488
$this->setMockResolverProperties($resolver, null, null);
@@ -166,15 +170,78 @@ function ($arg1, $arg2) {
166170
}
167171

168172
/**
169-
* Validate that getEnabledModules returns correctly with no admin token
173+
* Validate that getEnabledModules errors out when no Admin Token is returned and --force is false
170174
* @throws \Exception
171175
*/
172176
public function testGetModulePathsNoAdminToken()
173177
{
178+
// Set --force to false
179+
$this->mockForceGenerate(false);
180+
181+
// Mock ModuleResolver and $enabledModulesPath
174182
$this->setMockResolverClass(false, null, ["example" . DIRECTORY_SEPARATOR . "paths"], []);
175183
$resolver = ModuleResolver::getInstance();
176184
$this->setMockResolverProperties($resolver, null, null);
177-
$this->assertEquals(["example" . DIRECTORY_SEPARATOR . "paths"], $resolver->getModulesPath());
185+
186+
// Cannot Generate if no --force was passed in and no Admin Token is returned succesfully
187+
$this->expectException(TestFrameworkException::class);
188+
$resolver->getModulesPath();
189+
}
190+
191+
/**
192+
* Validates that getAdminToken is not called when --force is enabled
193+
*/
194+
public function testGetAdminTokenNotCalledWhenForce()
195+
{
196+
// Set --force to true
197+
$this->mockForceGenerate(true);
198+
199+
// Mock ModuleResolver and applyCustomModuleMethods()
200+
$mockResolver = $this->setMockResolverClass();
201+
$resolver = ModuleResolver::getInstance();
202+
$this->setMockResolverProperties($resolver, null, null);
203+
$resolver->getModulesPath();
204+
$mockResolver->verifyNeverInvoked("getAdminToken");
205+
206+
// verifyNeverInvoked does not add to assertion count
207+
$this->addToAssertionCount(1);
208+
}
209+
210+
/**
211+
* Verify the getAdminToken method returns throws an exception if ENV is not fully loaded.
212+
*/
213+
public function testGetAdminTokenWithMissingEnv()
214+
{
215+
// Set --force to true
216+
$this->mockForceGenerate(false);
217+
218+
// Unset env
219+
unset($_ENV['MAGENTO_ADMIN_USERNAME']);
220+
221+
// Mock ModuleResolver and applyCustomModuleMethods()
222+
$mockResolver = $this->setMockResolverClass();
223+
$resolver = ModuleResolver::getInstance();
224+
225+
// Expect exception
226+
$this->expectException(TestFrameworkException::class);
227+
$resolver->getModulesPath();
228+
}
229+
230+
/**
231+
* Verify the getAdminToken method returns throws an exception if Token was bad.
232+
*/
233+
public function testGetAdminTokenWithBadResponse()
234+
{
235+
// Set --force to true
236+
$this->mockForceGenerate(false);
237+
238+
// Mock ModuleResolver and applyCustomModuleMethods()
239+
$mockResolver = $this->setMockResolverClass();
240+
$resolver = ModuleResolver::getInstance();
241+
242+
// Expect exception
243+
$this->expectException(TestFrameworkException::class);
244+
$resolver->getModulesPath();
178245
}
179246

180247
/**
@@ -205,7 +272,7 @@ private function setMockResolverClass(
205272
if (isset($mockToken)) {
206273
$mockMethods['getAdminToken'] = $mockToken;
207274
}
208-
if (isset($mockModules)) {
275+
if (isset($mockGetModules)) {
209276
$mockMethods['getEnabledModules'] = $mockGetModules;
210277
}
211278
if (isset($mockCustomMethods)) {
@@ -220,7 +287,7 @@ private function setMockResolverClass(
220287
if (isset($mockCustomModules)) {
221288
$mockMethods['getCustomModulePaths'] = $mockCustomModules;
222289
}
223-
$mockMethods['printMagentoVersionInfo'] = null;
290+
// $mockMethods['printMagentoVersionInfo'] = null;
224291

225292
$mockResolver = AspectMock::double(
226293
ModuleResolver::class,
@@ -260,12 +327,36 @@ private function setMockResolverProperties($instance, $mockPaths = null, $mockMo
260327
$property->setValue($instance, $mockBlacklist);
261328
}
262329

330+
/**
331+
* Mocks MftfApplicationConfig->forceGenerateEnabled()
332+
* @param $forceGenerate
333+
* @throws \Exception
334+
* @return void
335+
*/
336+
private function mockForceGenerate($forceGenerate)
337+
{
338+
$mockConfig = AspectMock::double(
339+
MftfApplicationConfig::class,
340+
['forceGenerateEnabled' => $forceGenerate]
341+
);
342+
$instance = AspectMock::double(
343+
ObjectManager::class,
344+
['create' => $mockConfig->make(), 'get' => null]
345+
)->make();
346+
AspectMock::double(ObjectManagerFactory::class, ['getObjectManager' => $instance]);
347+
}
348+
263349
/**
264350
* After method functionality
265351
* @return void
266352
*/
267353
protected function tearDown()
268354
{
355+
// re set env
356+
if (!isset($_ENV['MAGENTO_ADMIN_USERNAME'])) {
357+
$_ENV['MAGENTO_ADMIN_USERNAME'] = "admin";
358+
}
359+
269360
AspectMock::clean();
270361
}
271362
}

src/Magento/FunctionalTestingFramework/Exceptions/TestFrameworkException.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace Magento\FunctionalTestingFramework\Exceptions;
88

9+
use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil;
10+
911
/**
1012
* Class TestFrameworkException
1113
*/
@@ -14,9 +16,17 @@ class TestFrameworkException extends \Exception
1416
/**
1517
* TestFrameworkException constructor.
1618
* @param string $message
19+
* @param array $context
20+
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
1721
*/
18-
public function __construct($message)
22+
public function __construct($message, $context = [])
1923
{
24+
list($childClass, $callingClass) = debug_backtrace(false, 2);
25+
LoggingUtil::getInstance()->getLogger($callingClass['class'])->error(
26+
$message,
27+
$context
28+
);
29+
2030
parent::__construct($message);
2131
}
2232
}

src/Magento/FunctionalTestingFramework/Util/ModuleResolver.php

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace Magento\FunctionalTestingFramework\Util;
88

99
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
10+
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
1011
use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil;
1112

1213
/**
@@ -138,10 +139,6 @@ public function getEnabledModules()
138139
}
139140

140141
$token = $this->getAdminToken();
141-
if (!$token || !is_string($token)) {
142-
$this->enabledModules = [];
143-
return $this->enabledModules;
144-
}
145142

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

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

159156
if (!$response) {
160-
$this->enabledModules = [];
161-
} else {
162-
$this->enabledModules = json_decode($response);
157+
$message = "Could not retrieve Modules from Magento Instance.";
158+
$context = [
159+
"Admin Module List Url" => $url,
160+
"MAGENTO_ADMIN_USERNAME" => getenv("MAGENTO_ADMIN_USERNAME"),
161+
"MAGENTO_ADMIN_PASSWORD" => getenv("MAGENTO_ADMIN_PASSWORD"),
162+
];
163+
throw new TestFrameworkException($message, $context);
163164
}
165+
166+
$this->enabledModules = json_decode($response);
167+
164168
return $this->enabledModules;
165169
}
166170

@@ -190,25 +194,14 @@ public function getModulesPath()
190194
return $this->enabledModulePaths;
191195
}
192196

193-
$enabledModules = $this->getEnabledModules();
194-
if (empty($enabledModules) && !MftfApplicationConfig::getConfig()->forceGenerateEnabled()) {
195-
$errorMsg = 'Could not retrieve enabled modules from provided MAGENTO_BASE_URL ' .
196-
'please make sure Magento is available at this url';
197-
LoggingUtil::getInstance()->getLogger(ModuleResolver::class)->error(
198-
$errorMsg,
199-
['MAGENTO_BASE_URL' => getenv('MAGENTO_BASE_URL')]
200-
);
201-
trigger_error($errorMsg, E_USER_ERROR);
202-
}
203-
204197
$allModulePaths = $this->aggregateTestModulePaths();
205198

206-
if (empty($enabledModules)) {
199+
if (MftfApplicationConfig::getConfig()->forceGenerateEnabled()) {
207200
$this->enabledModulePaths = $this->applyCustomModuleMethods($allModulePaths);
208201
return $this->enabledModulePaths;
209202
}
210203

211-
$enabledModules = array_merge($enabledModules, $this->getModuleWhitelist());
204+
$enabledModules = array_merge($this->getEnabledModules(), $this->getModuleWhitelist());
212205
$enabledDirectoryPaths = $this->getEnabledDirectoryPaths($enabledModules, $allModulePaths);
213206

214207
$this->enabledModulePaths = $this->applyCustomModuleMethods($enabledDirectoryPaths);
@@ -325,9 +318,15 @@ private function getEnabledDirectoryPaths($enabledModules, $allModulePaths)
325318
{
326319
$enabledDirectoryPaths = [];
327320
foreach ($enabledModules as $magentoModuleName) {
328-
$moduleShortName = explode('_', $magentoModuleName)[1];
321+
// Magento_Backend -> Backend or DevDocs -> DevDocs (if whitelisted has no underscore)
322+
$moduleShortName = explode('_', $magentoModuleName)[1] ?? $magentoModuleName;
329323
if (!isset($this->knownDirectories[$moduleShortName]) && !isset($allModulePaths[$moduleShortName])) {
330324
continue;
325+
} elseif (isset($this->knownDirectories[$moduleShortName]) && !isset($allModulePaths[$moduleShortName])) {
326+
LoggingUtil::getInstance()->getLogger(ModuleResolver::class)->warn(
327+
"Known directory could not match to an existing path.",
328+
['knownDirectory' => $moduleShortName]
329+
);
331330
} else {
332331
$enabledDirectoryPaths[$moduleShortName] = $allModulePaths[$moduleShortName];
333332
}
@@ -342,7 +341,6 @@ private function getEnabledDirectoryPaths($enabledModules, $allModulePaths)
342341
*/
343342
private function printMagentoVersionInfo()
344343
{
345-
346344
if (MftfApplicationConfig::getConfig()->forceGenerateEnabled()) {
347345
return;
348346
}
@@ -377,7 +375,13 @@ protected function getAdminToken()
377375
$login = $_ENV['MAGENTO_ADMIN_USERNAME'] ?? null;
378376
$password = $_ENV['MAGENTO_ADMIN_PASSWORD'] ?? null;
379377
if (!$login || !$password || !isset($_ENV['MAGENTO_BASE_URL'])) {
380-
return false;
378+
$message = "Cannot retrieve API token without credentials and base url, please fill out .env.";
379+
$context = [
380+
"MAGENTO_BASE_URL" => getenv("MAGENTO_BASE_URL"),
381+
"MAGENTO_ADMIN_USERNAME" => getenv("MAGENTO_ADMIN_USERNAME"),
382+
"MAGENTO_ADMIN_PASSWORD" => getenv("MAGENTO_ADMIN_PASSWORD"),
383+
];
384+
throw new TestFrameworkException($message, $context);
381385
}
382386

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

400404
$response = curl_exec($ch);
405+
401406
if (!$response) {
402-
return $response;
407+
$message = "Could not retrieve API token from Magento Instance.";
408+
$context = [
409+
"Admin Integration Token Url" => $url,
410+
"MAGENTO_ADMIN_USERNAME" => getenv("MAGENTO_ADMIN_USERNAME"),
411+
"MAGENTO_ADMIN_PASSWORD" => getenv("MAGENTO_ADMIN_PASSWORD"),
412+
];
413+
throw new TestFrameworkException($message, $context);
403414
}
415+
404416
return json_decode($response);
405417
}
406418

0 commit comments

Comments
 (0)