Skip to content

Commit

Permalink
Merge pull request magento#2775 from magento-thunder/MAGETWO-92986
Browse files Browse the repository at this point in the history
[thunder] MAGETWO-92986: Write Logs for Failed Process of Generating Factories in Extensions
  • Loading branch information
viktym authored Jul 9, 2018
2 parents 0c2fa6f + 0dfe22b commit 6178786
Show file tree
Hide file tree
Showing 3 changed files with 258 additions and 160 deletions.
205 changes: 105 additions & 100 deletions dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,155 +5,151 @@
*/
namespace Magento\Framework\Code;

use Magento\Framework\Code\Generator;
use Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceFactoryGenerator;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Filesystem;
use Magento\Framework\Interception\Code\Generator as InterceptionGenerator;
use Magento\Framework\ObjectManager\Code\Generator as DIGenerator;
use Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceFactoryGenerator;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;

require_once __DIR__ . '/GeneratorTest/SourceClassWithNamespace.php';
require_once __DIR__ . '/GeneratorTest/ParentClassWithNamespace.php';
require_once __DIR__ . '/GeneratorTest/SourceClassWithNamespaceExtension.php';

/**
* @magentoAppIsolation enabled
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class GeneratorTest extends \PHPUnit\Framework\TestCase
class GeneratorTest extends TestCase
{
const CLASS_NAME_WITH_NAMESPACE = \Magento\Framework\Code\GeneratorTest\SourceClassWithNamespace::class;
const CLASS_NAME_WITH_NAMESPACE = GeneratorTest\SourceClassWithNamespace::class;

/**
* @var \Magento\Framework\Code\Generator
* @var Generator
*/
protected $_generator;

/**
* @var \Magento\Framework\Code\Generator\Io
* @var Generator/Io
*/
protected $_ioObject;

/**
* @var \Magento\Framework\Filesystem\Directory\Write
* @var Filesystem\Directory\Write
*/
private $generatedDirectory;

/**
* @var Filesystem\Directory\Read
*/
private $logDirectory;

/**
* @var string
*/
protected $varDirectory;
private $testRelativePath = './Magento/Framework/Code/GeneratorTest/';

/**
* @inheritdoc
*/
protected function setUp()
{
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
$this->varDirectory = $objectManager->get(
\Magento\Framework\Filesystem::class
)->getDirectoryWrite(
DirectoryList::VAR_DIR
);
$generationDirectory = $this->varDirectory->getAbsolutePath('generation');
$this->_ioObject = new \Magento\Framework\Code\Generator\Io(
new \Magento\Framework\Filesystem\Driver\File(),
$generationDirectory
);
$objectManager = Bootstrap::getObjectManager();
/** @var Filesystem $filesystem */
$filesystem = $objectManager->get(Filesystem::class);
$this->generatedDirectory = $filesystem->getDirectoryWrite(DirectoryList::GENERATED_CODE);
$this->logDirectory = $filesystem->getDirectoryRead(DirectoryList::LOG);
$generatedDirectoryAbsolutePath = $this->generatedDirectory->getAbsolutePath();
$this->_ioObject = new Generator\Io(new Filesystem\Driver\File(), $generatedDirectoryAbsolutePath);
$this->_generator = $objectManager->create(
\Magento\Framework\Code\Generator::class,
Generator::class,
[
'ioObject' => $this->_ioObject,
'generatedEntities' => [
ExtensionAttributesInterfaceFactoryGenerator::ENTITY_TYPE =>
ExtensionAttributesInterfaceFactoryGenerator::class,
DIGenerator\Factory::ENTITY_TYPE => \Magento\Framework\ObjectManager\Code\Generator\Factory::class,
DIGenerator\Proxy::ENTITY_TYPE => \Magento\Framework\ObjectManager\Code\Generator\Proxy::class,
InterceptionGenerator\Interceptor::ENTITY_TYPE =>
\Magento\Framework\Interception\Code\Generator\Interceptor::class,
DIGenerator\Factory::ENTITY_TYPE => DIGenerator\Factory::class,
DIGenerator\Proxy::ENTITY_TYPE => DIGenerator\Proxy::class,
InterceptionGenerator\Interceptor::ENTITY_TYPE => InterceptionGenerator\Interceptor::class,
]
]
);
$this->_generator->setObjectManager($objectManager);
}

/**
* @inheritdoc
*/
protected function tearDown()
{
$this->varDirectory->delete('generation');
$this->_generator = null;
if ($this->generatedDirectory->isExist($this->testRelativePath)) {
if (!$this->generatedDirectory->isWritable($this->testRelativePath)) {
$this->generatedDirectory->changePermissionsRecursively($this->testRelativePath, 0775, 0664);
}
$this->generatedDirectory->delete($this->testRelativePath);
}
}

protected function _clearDocBlock($classBody)
{
return preg_replace('/(\/\*[\w\W]*)\nclass/', 'class', $classBody);
}

/**
* Generates a new file with Factory class and compares with the sample from the
* SourceClassWithNamespaceFactory.php.sample file.
*/
public function testGenerateClassFactoryWithNamespace()
{
$factoryClassName = self::CLASS_NAME_WITH_NAMESPACE . 'Factory';
$result = false;
$generatorResult = $this->_generator->generateClass($factoryClassName);
if (\Magento\Framework\Code\Generator::GENERATION_ERROR !== $generatorResult) {
$result = true;
}
$this->assertTrue($result, 'Failed asserting that \'' . (string)$generatorResult . '\' equals \'success\'.');

$factory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create($factoryClassName);

$object = $factory->create();
$this->assertInstanceOf(self::CLASS_NAME_WITH_NAMESPACE, $object);

// This test is only valid if the factory created the object if Autoloader did not pick it up automatically
if (\Magento\Framework\Code\Generator::GENERATION_SUCCESS == $generatorResult) {
$content = $this->_clearDocBlock(
file_get_contents(
$this->_ioObject->generateResultFileName(self::CLASS_NAME_WITH_NAMESPACE . 'Factory')
)
);
$expectedContent = $this->_clearDocBlock(
file_get_contents(__DIR__ . '/_expected/SourceClassWithNamespaceFactory.php.sample')
);
$this->assertEquals($expectedContent, $content);
}
$this->assertEquals(Generator::GENERATION_SUCCESS, $this->_generator->generateClass($factoryClassName));
$factory = Bootstrap::getObjectManager()->create($factoryClassName);
$this->assertInstanceOf(self::CLASS_NAME_WITH_NAMESPACE, $factory->create());
$content = $this->_clearDocBlock(
file_get_contents($this->_ioObject->generateResultFileName($factoryClassName))
);
$expectedContent = $this->_clearDocBlock(
file_get_contents(__DIR__ . '/_expected/SourceClassWithNamespaceFactory.php.sample')
);
$this->assertEquals($expectedContent, $content);
}

/**
* Generates a new file with Proxy class and compares with the sample from the
* SourceClassWithNamespaceProxy.php.sample file.
*/
public function testGenerateClassProxyWithNamespace()
{
$proxyClassName = self::CLASS_NAME_WITH_NAMESPACE . '\Proxy';
$result = false;
$generatorResult = $this->_generator->generateClass($proxyClassName);
if (\Magento\Framework\Code\Generator::GENERATION_ERROR !== $generatorResult) {
$result = true;
}
$this->assertTrue($result, 'Failed asserting that \'' . (string)$generatorResult . '\' equals \'success\'.');

$proxy = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create($proxyClassName);
$this->assertEquals(Generator::GENERATION_SUCCESS, $this->_generator->generateClass($proxyClassName));
$proxy = Bootstrap::getObjectManager()->create($proxyClassName);
$this->assertInstanceOf(self::CLASS_NAME_WITH_NAMESPACE, $proxy);

// This test is only valid if the factory created the object if Autoloader did not pick it up automatically
if (\Magento\Framework\Code\Generator::GENERATION_SUCCESS == $generatorResult) {
$content = $this->_clearDocBlock(
file_get_contents($this->_ioObject->generateResultFileName(self::CLASS_NAME_WITH_NAMESPACE . '\Proxy'))
);
$expectedContent = $this->_clearDocBlock(
file_get_contents(__DIR__ . '/_expected/SourceClassWithNamespaceProxy.php.sample')
);
$this->assertEquals($expectedContent, $content);
}
$content = $this->_clearDocBlock(
file_get_contents($this->_ioObject->generateResultFileName($proxyClassName))
);
$expectedContent = $this->_clearDocBlock(
file_get_contents(__DIR__ . '/_expected/SourceClassWithNamespaceProxy.php.sample')
);
$this->assertEquals($expectedContent, $content);
}

/**
* Generates a new file with Interceptor class and compares with the sample from the
* SourceClassWithNamespaceInterceptor.php.sample file.
*/
public function testGenerateClassInterceptorWithNamespace()
{
$interceptorClassName = self::CLASS_NAME_WITH_NAMESPACE . '\Interceptor';
$result = false;
$generatorResult = $this->_generator->generateClass($interceptorClassName);
if (\Magento\Framework\Code\Generator::GENERATION_ERROR !== $generatorResult) {
$result = true;
}
$this->assertTrue($result, 'Failed asserting that \'' . (string)$generatorResult . '\' equals \'success\'.');

if (\Magento\Framework\Code\Generator::GENERATION_SUCCESS == $generatorResult) {
$content = $this->_clearDocBlock(
file_get_contents(
$this->_ioObject->generateResultFileName(self::CLASS_NAME_WITH_NAMESPACE . '\Interceptor')
)
);
$expectedContent = $this->_clearDocBlock(
file_get_contents(__DIR__ . '/_expected/SourceClassWithNamespaceInterceptor.php.sample')
);
$this->assertEquals($expectedContent, $content);
}
$this->assertEquals(Generator::GENERATION_SUCCESS, $this->_generator->generateClass($interceptorClassName));
$content = $this->_clearDocBlock(
file_get_contents($this->_ioObject->generateResultFileName($interceptorClassName))
);
$expectedContent = $this->_clearDocBlock(
file_get_contents(__DIR__ . '/_expected/SourceClassWithNamespaceInterceptor.php.sample')
);
$this->assertEquals($expectedContent, $content);
}

/**
Expand All @@ -163,26 +159,35 @@ public function testGenerateClassInterceptorWithNamespace()
public function testGenerateClassExtensionAttributesInterfaceFactoryWithNamespace()
{
$factoryClassName = self::CLASS_NAME_WITH_NAMESPACE . 'ExtensionInterfaceFactory';
$this->varDirectory->create(
$this->varDirectory->getAbsolutePath('generation') . '/Magento/Framework/Code/GeneratorTest/'
);

$generatorResult = $this->_generator->generateClass($factoryClassName);

$this->generatedDirectory->create($this->testRelativePath);
$this->assertEquals(Generator::GENERATION_SUCCESS, $this->_generator->generateClass($factoryClassName));
$factory = Bootstrap::getObjectManager()->create($factoryClassName);
$object = $factory->create();

$this->assertEquals($generatorResult, Generator::GENERATION_SUCCESS);
$this->assertInstanceOf(self::CLASS_NAME_WITH_NAMESPACE . 'Extension', $object);

$this->assertInstanceOf(self::CLASS_NAME_WITH_NAMESPACE . 'Extension', $factory->create());
$content = $this->_clearDocBlock(
file_get_contents(
$this->_ioObject->generateResultFileName(self::CLASS_NAME_WITH_NAMESPACE . 'ExtensionInterfaceFactory')
)
file_get_contents($this->_ioObject->generateResultFileName($factoryClassName))
);
$expectedContent = $this->_clearDocBlock(
file_get_contents(__DIR__ . '/_expected/SourceClassWithNamespaceExtensionInterfaceFactory.php.sample')
);
$this->assertEquals($expectedContent, $content);
}

/**
* It tries to generate a new class file when the generated directory is read-only
*/
public function testGeneratorClassWithErrorSaveClassFile()
{
$factoryClassName = self::CLASS_NAME_WITH_NAMESPACE . 'Factory';
$msgPart = 'Class ' . $factoryClassName . ' generation error: The requested class did not generate properly, '
. 'because the \'generated\' directory permission is read-only.';
$regexpMsgPart = preg_quote($msgPart);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessageRegExp("/.*$regexpMsgPart.*/");
$this->generatedDirectory->create($this->testRelativePath);
$this->generatedDirectory->changePermissionsRecursively($this->testRelativePath, 0555, 0444);
$generatorResult = $this->_generator->generateClass($factoryClassName);
$this->assertFalse($generatorResult);
$pathToSystemLog = $this->logDirectory->getAbsolutePath('system.log');
$this->assertContains($msgPart, file_get_contents($pathToSystemLog));
}
}
Loading

0 comments on commit 6178786

Please sign in to comment.