Skip to content

Commit fb20921

Browse files
committed
Merge branch 'MAGETWO-51544-dir-file-path-updater' into PR_Branch
2 parents e71451d + 8c74a4d commit fb20921

File tree

4 files changed

+249
-11
lines changed

4 files changed

+249
-11
lines changed

setup/src/Magento/Setup/Model/Cron/ReadinessCheck.php

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
use Magento\Framework\App\Filesystem\DirectoryList;
1010
use Magento\Framework\Config\ConfigOptionsListConstants;
1111
use Magento\Framework\Filesystem;
12+
use Magento\Framework\View\Design\Theme\Customization\Path;
1213
use Magento\Setup\Model\PhpReadinessCheck;
1314
use Magento\Setup\Validator\DbValidator;
15+
use Magento\Setup\Model\PathBuilder;
1416

1517
/**
1618
* This class is used by setup:cron:run command to check if this command can be run properly. It also checks if PHP
@@ -32,7 +34,9 @@ class ReadinessCheck
3234
const KEY_PHP_VERSION_VERIFIED = 'php_version_verified';
3335
const KEY_PHP_SETTINGS_VERIFIED = 'php_settings_verified';
3436
const KEY_PHP_EXTENSIONS_VERIFIED = 'php_extensions_verified';
37+
const KEY_FILE_PATHS = 'file_paths';
3538
const KEY_ERROR = 'error';
39+
const KEY_LIST = 'list';
3640
const KEY_CURRENT_TIMESTAMP = 'current_timestamp';
3741
const KEY_LAST_TIMESTAMP = 'last_timestamp';
3842
/**#@-*/
@@ -57,24 +61,32 @@ class ReadinessCheck
5761
*/
5862
private $phpReadinessCheck;
5963

64+
/**
65+
* @var PathBuilder
66+
*/
67+
private $pathBuilder;
68+
6069
/**
6170
* Constructor
6271
*
6372
* @param DbValidator $dbValidator
6473
* @param DeploymentConfig $deploymentConfig
6574
* @param Filesystem $filesystem
6675
* @param PhpReadinessCheck $phpReadinessCheck
76+
* @param PathBuilder $pathBuilder
6777
*/
6878
public function __construct(
6979
DbValidator $dbValidator,
7080
DeploymentConfig $deploymentConfig,
7181
Filesystem $filesystem,
72-
PhpReadinessCheck $phpReadinessCheck
82+
PhpReadinessCheck $phpReadinessCheck,
83+
PathBuilder $pathBuilder
7384
) {
7485
$this->dbValidator = $dbValidator;
7586
$this->deploymentConfig = $deploymentConfig;
7687
$this->filesystem = $filesystem;
7788
$this->phpReadinessCheck = $phpReadinessCheck;
89+
$this->pathBuilder = $pathBuilder;
7890
}
7991

8092
/**
@@ -84,6 +96,7 @@ public function __construct(
8496
*/
8597
public function runReadinessCheck()
8698
{
99+
$returnValue = true;
87100
$resultJsonRawData = [self::KEY_READINESS_CHECKS => []];
88101
// checks PHP
89102
$phpVersionCheckResult = $this->phpReadinessCheck->checkPhpVersion();
@@ -92,8 +105,6 @@ public function runReadinessCheck()
92105
$resultJsonRawData[self::KEY_PHP_CHECKS][self::KEY_PHP_VERSION_VERIFIED] = $phpVersionCheckResult;
93106
$resultJsonRawData[self::KEY_PHP_CHECKS][self::KEY_PHP_EXTENSIONS_VERIFIED] = $phpExtensionsCheckResult;
94107
$resultJsonRawData[self::KEY_PHP_CHECKS][self::KEY_PHP_SETTINGS_VERIFIED] = $phpSettingsCheckResult;
95-
// checks Database privileges
96-
$success = true;
97108
$errorMsg = '';
98109
$write = $this->filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
99110
$dbInfo = $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT);
@@ -104,16 +115,27 @@ public function runReadinessCheck()
104115
$dbInfo[ConfigOptionsListConstants::KEY_USER],
105116
$dbInfo[ConfigOptionsListConstants::KEY_PASSWORD]
106117
);
107-
} catch (\Exception $e) {
108-
$success = false;
109-
$errorMsg .= $e->getMessage();
110-
}
111-
if ($success) {
112118
$resultJsonRawData[self::KEY_READINESS_CHECKS][self::KEY_DB_WRITE_PERMISSION_VERIFIED] = true;
113-
} else {
119+
} catch (\Exception $e) {
120+
$errorMsg = $e->getMessage();
114121
$resultJsonRawData[self::KEY_READINESS_CHECKS][self::KEY_DB_WRITE_PERMISSION_VERIFIED] = false;
115122
$resultJsonRawData[self::KEY_READINESS_CHECKS][self::KEY_ERROR] = $errorMsg;
123+
$returnValue = false;
116124
}
125+
126+
$errorMsg = '';
127+
// Prepare list of magento specific files and directory paths for updater application to check write
128+
// permissions
129+
try {
130+
$filePaths = $this->pathBuilder->build();
131+
$resultJsonRawData[self::KEY_FILE_PATHS][self::KEY_LIST] = $filePaths;
132+
} catch (\Exception $e) {
133+
$errorMsg = $e->getMessage();
134+
$resultJsonRawData[self::KEY_FILE_PATHS][self::KEY_LIST] = [];
135+
$returnValue = false;
136+
}
137+
$resultJsonRawData[self::KEY_FILE_PATHS][self::KEY_ERROR] = $errorMsg;
138+
117139
// updates timestamp
118140
if ($write->isExist(self::SETUP_CRON_JOB_STATUS_FILE)) {
119141
$jsonData = json_decode($write->readFile(self::SETUP_CRON_JOB_STATUS_FILE), true);
@@ -125,6 +147,6 @@ public function runReadinessCheck()
125147

126148
$resultJson = json_encode($resultJsonRawData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
127149
$write->writeFile(self::SETUP_CRON_JOB_STATUS_FILE, $resultJson);
128-
return $success;
150+
return $returnValue;
129151
}
130152
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Setup\Model;
7+
8+
use Magento\Framework\FileSystem\Directory\ReadFactory;
9+
10+
/**
11+
* Prepares list of magento specific files and directory paths that updater will need access to perform the upgrade
12+
*/
13+
class PathBuilder
14+
{
15+
const MAGENTO_BASE_PACKAGE_COMPOSER_JSON_FILE = 'magento/magento2-base/composer.json';
16+
17+
const COMPOSER_KEY_EXTRA = 'extra';
18+
19+
const COMPOSER_KEY_MAP = 'map';
20+
21+
/**
22+
* @var \Magento\Framework\Filesystem\Directory\ReadInterface $reader
23+
*/
24+
private $reader;
25+
26+
/**
27+
* Constructor
28+
*
29+
* @param ReadFactory $readFactory
30+
*/
31+
public function __construct(ReadFactory $readFactory)
32+
{
33+
$this->reader = $readFactory->create(BP);
34+
}
35+
36+
/**
37+
* Builds list of important files and directory paths that used by magento that updater application will need
38+
* access to perform upgrade operation
39+
*
40+
* @return string []
41+
* @throws \Magento\Setup\Exception
42+
*/
43+
public function build()
44+
{
45+
// Locate composer.json for magento2-base module and read the extra map section for the list of
46+
// magento specific files and directories that updater will need access to perform the upgrade
47+
48+
$filesPathList = [];
49+
$vendorDir = require VENDOR_PATH;
50+
$basePackageComposerFilePath = $vendorDir . '/' . self::MAGENTO_BASE_PACKAGE_COMPOSER_JSON_FILE;
51+
if (!$this->reader->isExist($basePackageComposerFilePath)) {
52+
throw new \Magento\Setup\Exception(
53+
'Could not locate ' . self::MAGENTO_BASE_PACKAGE_COMPOSER_JSON_FILE . ' file.'
54+
);
55+
}
56+
if (!$this->reader->isReadable($basePackageComposerFilePath)) {
57+
throw new \Magento\Setup\Exception(
58+
'Could not read ' . self::MAGENTO_BASE_PACKAGE_COMPOSER_JSON_FILE . ' file.'
59+
);
60+
}
61+
$composerJsonFileData = json_decode($this->reader->readFile($basePackageComposerFilePath), true);
62+
if (!isset($composerJsonFileData[self::COMPOSER_KEY_EXTRA][self::COMPOSER_KEY_MAP])) {
63+
return $filesPathList;
64+
}
65+
$extraMappings = $composerJsonFileData[self::COMPOSER_KEY_EXTRA][self::COMPOSER_KEY_MAP];
66+
foreach ($extraMappings as $map) {
67+
$filesPathList[] = $map[1];
68+
}
69+
return $filesPathList;
70+
}
71+
}

setup/src/Magento/Setup/Test/Unit/Model/Cron/ReadinessCheckTest.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ class ReadinessCheckTest extends \PHPUnit_Framework_TestCase
4040
*/
4141
private $readinessCheck;
4242

43+
/**
44+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Model\PathBuilder
45+
*/
46+
private $pathBuilder;
47+
4348
/**
4449
* @var array
4550
*/
@@ -63,11 +68,14 @@ public function setUp()
6368
$this->write = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false);
6469
$this->filesystem->expects($this->once())->method('getDirectoryWrite')->willReturn($this->write);
6570
$this->phpReadinessCheck = $this->getMock('Magento\Setup\Model\PhpReadinessCheck', [], [], '', false);
71+
$this->pathBuilder = $this->getMock('Magento\Setup\Model\PathBuilder', [], [], '', false);
72+
$this->pathBuilder->expects($this->once())->method('build')->willReturn([__FILE__]);
6673
$this->readinessCheck = new ReadinessCheck(
6774
$this->dbValidator,
6875
$this->deploymentConfig,
6976
$this->filesystem,
70-
$this->phpReadinessCheck
77+
$this->phpReadinessCheck,
78+
$this->pathBuilder
7179
);
7280
$this->phpReadinessCheck->expects($this->once())->method('checkPhpVersion')->willReturn(['success' => true]);
7381
$this->phpReadinessCheck->expects($this->once())->method('checkPhpExtensions')->willReturn(['success' => true]);
@@ -95,6 +103,10 @@ public function testRunReadinessCheckNoDbAccess()
95103
'error' => 'Connection failure'
96104
],
97105
ReadinessCheck::KEY_PHP_CHECKS => $this->expected,
106+
ReadinessCheck::KEY_FILE_PATHS => [
107+
ReadinessCheck::KEY_LIST => [__FILE__],
108+
ReadinessCheck::KEY_ERROR => ""
109+
],
98110
ReadinessCheck::KEY_CURRENT_TIMESTAMP => 100
99111
];
100112
$expectedJson = json_encode($expected, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
@@ -117,6 +129,10 @@ public function testRunReadinessCheckNoDbWriteAccess()
117129
'error' => 'Database user username does not have write access.'
118130
],
119131
ReadinessCheck::KEY_PHP_CHECKS => $this->expected,
132+
ReadinessCheck::KEY_FILE_PATHS => [
133+
ReadinessCheck::KEY_LIST => [__FILE__],
134+
ReadinessCheck::KEY_ERROR => ""
135+
],
120136
ReadinessCheck::KEY_CURRENT_TIMESTAMP => 100
121137
];
122138
$expectedJson = json_encode($expected, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
@@ -134,6 +150,10 @@ public function testRunReadinessCheck()
134150
$expected = [
135151
ReadinessCheck::KEY_READINESS_CHECKS => [ReadinessCheck::KEY_DB_WRITE_PERMISSION_VERIFIED => true],
136152
ReadinessCheck::KEY_PHP_CHECKS => $this->expected,
153+
ReadinessCheck::KEY_FILE_PATHS => [
154+
ReadinessCheck::KEY_LIST => [__FILE__],
155+
ReadinessCheck::KEY_ERROR => ""
156+
],
137157
ReadinessCheck::KEY_CURRENT_TIMESTAMP => 100
138158
];
139159
$expectedJson = json_encode($expected, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
@@ -151,6 +171,10 @@ public function testRunReadinessCheckLastTimestamp()
151171
$expected = [
152172
ReadinessCheck::KEY_READINESS_CHECKS => [ReadinessCheck::KEY_DB_WRITE_PERMISSION_VERIFIED => true],
153173
ReadinessCheck::KEY_PHP_CHECKS => $this->expected,
174+
ReadinessCheck::KEY_FILE_PATHS => [
175+
ReadinessCheck::KEY_LIST => [__FILE__],
176+
ReadinessCheck::KEY_ERROR => ""
177+
],
154178
ReadinessCheck::KEY_LAST_TIMESTAMP => 50,
155179
ReadinessCheck::KEY_CURRENT_TIMESTAMP => 100,
156180
];
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Setup\Test\Unit\Model;
8+
9+
use \Magento\Setup\Model\PathBuilder;
10+
11+
class PathBuilderTest extends \PHPUnit_Framework_TestCase
12+
{
13+
/**
14+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\FileSystem\Directory\ReadFactory
15+
*/
16+
private $readFactoryMock;
17+
18+
/**
19+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\FileSystem\Directory\ReadInterface
20+
*/
21+
private $readerMock;
22+
23+
/**
24+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Model\PathBuilder
25+
*/
26+
private $pathBuilder;
27+
28+
public function setup()
29+
{
30+
$this->readFactoryMock = $this->getMock(
31+
'Magento\Framework\Filesystem\Directory\ReadFactory',
32+
[],
33+
[],
34+
'',
35+
false
36+
);
37+
$this->readerMock = $this->getMockForAbstractClass(
38+
'Magento\Framework\Filesystem\Directory\ReadInterface',
39+
[],
40+
'',
41+
false
42+
);
43+
$this->readFactoryMock->expects($this->once())->method('create')->willReturn($this->readerMock);
44+
$this->pathBuilder = new PathBuilder($this->readFactoryMock);
45+
}
46+
47+
// Error scenario: magento/magento2-base/composer.json not found
48+
public function testBuildComposerJsonFileNotFound()
49+
{
50+
$this->readerMock->expects($this->once())->method('isExist')->willReturn(false);
51+
$this->readerMock->expects($this->never())->method('isReadable');
52+
$this->readerMock->expects($this->never())->method('readFile');
53+
$this->setExpectedException(
54+
'Magento\Setup\Exception',
55+
sprintf('Could not locate %s file.', PathBuilder::MAGENTO_BASE_PACKAGE_COMPOSER_JSON_FILE)
56+
);
57+
$this->pathBuilder->build();
58+
}
59+
60+
// Error scenario: magento/magento2-base/composer.json file could not be read
61+
public function testBuildComposerJsonFileNotReadable()
62+
{
63+
$this->readerMock->expects($this->once())->method('isExist')->willReturn(true);
64+
$this->readerMock->expects($this->once())->method('isReadable')->willReturn(false);
65+
$this->readerMock->expects($this->never())->method('readFile');
66+
$this->setExpectedException(
67+
'Magento\Setup\Exception',
68+
sprintf('Could not read %s file.', PathBuilder::MAGENTO_BASE_PACKAGE_COMPOSER_JSON_FILE)
69+
);
70+
$this->pathBuilder->build();
71+
}
72+
73+
// Scenario: ["extra"]["map"] is absent within magento/magento2-base/composer.json file
74+
public function testBuildNoExtraMapSectionInComposerJsonFile()
75+
{
76+
$this->readerMock->expects($this->once())->method('isExist')->willReturn(true);
77+
$this->readerMock->expects($this->once())->method('isReadable')->willReturn(true);
78+
$jsonData = json_encode(
79+
[
80+
PathBuilder::COMPOSER_KEY_EXTRA =>
81+
[
82+
__FILE__,
83+
__FILE__
84+
]
85+
]
86+
);
87+
$this->readerMock->expects($this->once())->method('readFile')->willReturn($jsonData);
88+
$expectedList = [];
89+
$actualList = $this->pathBuilder->build();
90+
$this->assertEquals($expectedList, $actualList);
91+
}
92+
93+
// Success scenario
94+
public function testBuild()
95+
{
96+
$this->readerMock->expects($this->once())->method('isExist')->willReturn(true);
97+
$this->readerMock->expects($this->once())->method('isReadable')->willReturn(true);
98+
$jsonData = json_encode(
99+
[
100+
PathBuilder::COMPOSER_KEY_EXTRA =>
101+
[
102+
PathBuilder::COMPOSER_KEY_MAP =>
103+
[
104+
[
105+
__FILE__,
106+
__FILE__
107+
],
108+
[
109+
__DIR__,
110+
__DIR__
111+
]
112+
]
113+
]
114+
]
115+
);
116+
$this->readerMock->expects($this->once())->method('readFile')->willReturn($jsonData);
117+
$expectedList = [__FILE__, __DIR__];
118+
$actualList = $this->pathBuilder->build();
119+
$this->assertEquals($expectedList, $actualList);
120+
}
121+
}

0 commit comments

Comments
 (0)