Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit b1b604e

Browse files
author
Volodymyr Kublytskyi
committed
MAGETWO-80111: Keep maintenance mode on if it was previously enabled #11052
- revert backward incompatible changes - fix temporal coupling in \Magento\Framework\App\Console\MaintenanceModeEnabler - cover maintenance mode with unit test - revert changes in unit test to ensure code have same behavior after refactoring
1 parent 5f3068b commit b1b604e

File tree

12 files changed

+405
-194
lines changed

12 files changed

+405
-194
lines changed

app/code/Magento/Deploy/Model/Mode.php

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Magento\Framework\App\DeploymentConfig\Reader;
1313
use Magento\Framework\App\DeploymentConfig\Writer;
1414
use Magento\Framework\App\Filesystem\DirectoryList;
15+
use Magento\Framework\App\MaintenanceMode;
1516
use Magento\Framework\App\State;
1617
use Magento\Framework\Config\File\ConfigFilePool;
1718
use Symfony\Component\Console\Input\InputInterface;
@@ -49,11 +50,6 @@ class Mode
4950
*/
5051
private $reader;
5152

52-
/**
53-
* @var MaintenanceModeEnabler
54-
*/
55-
private $maintenanceMode;
56-
5753
/**
5854
* @var Filesystem
5955
*/
@@ -78,33 +74,41 @@ class Mode
7874
*/
7975
private $emulatedAreaProcessor;
8076

77+
/**
78+
* @var MaintenanceModeEnabler
79+
*/
80+
private $maintenanceModeEnabler;
81+
8182
/**
8283
* @param InputInterface $input
8384
* @param OutputInterface $output
8485
* @param Writer $writer
8586
* @param Reader $reader
86-
* @param MaintenanceModeEnabler $maintenanceMode
87+
* @param MaintenanceMode $maintenanceMode deprecated, use $maintenanceModeEnabler instead
8788
* @param Filesystem $filesystem
8889
* @param ConfigProvider $configProvider
8990
* @param ProcessorFacadeFactory $processorFacadeFactory
9091
* @param EmulatedAdminhtmlAreaProcessor $emulatedAreaProcessor
92+
* @param MaintenanceModeEnabler $maintenanceModeEnabler
93+
*
94+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
9195
*/
9296
public function __construct(
9397
InputInterface $input,
9498
OutputInterface $output,
9599
Writer $writer,
96100
Reader $reader,
97-
MaintenanceModeEnabler $maintenanceMode,
101+
MaintenanceMode $maintenanceMode,
98102
Filesystem $filesystem,
99103
ConfigProvider $configProvider = null,
100104
ProcessorFacadeFactory $processorFacadeFactory = null,
101-
EmulatedAdminhtmlAreaProcessor $emulatedAreaProcessor = null
105+
EmulatedAdminhtmlAreaProcessor $emulatedAreaProcessor = null,
106+
MaintenanceModeEnabler $maintenanceModeEnabler = null
102107
) {
103108
$this->input = $input;
104109
$this->output = $output;
105110
$this->writer = $writer;
106111
$this->reader = $reader;
107-
$this->maintenanceMode = $maintenanceMode;
108112
$this->filesystem = $filesystem;
109113

110114
$this->configProvider =
@@ -113,6 +117,8 @@ public function __construct(
113117
$processorFacadeFactory ?: ObjectManager::getInstance()->get(ProcessorFacadeFactory::class);
114118
$this->emulatedAreaProcessor =
115119
$emulatedAreaProcessor ?: ObjectManager::getInstance()->get(EmulatedAdminhtmlAreaProcessor::class);
120+
$this->maintenanceModeEnabler =
121+
$maintenanceModeEnabler ?: ObjectManager::getInstance()->get(MaintenanceModeEnabler::class);
116122
}
117123

118124
/**
@@ -123,19 +129,23 @@ public function __construct(
123129
*/
124130
public function enableProductionMode()
125131
{
126-
$this->maintenanceMode->enableMaintenanceMode($this->output);
127-
$previousMode = $this->getMode();
128-
try {
129-
// We have to turn on production mode before generation.
130-
// We need this to enable generation of the "min" files.
131-
$this->setStoreMode(State::MODE_PRODUCTION);
132-
$this->filesystem->regenerateStatic($this->output);
133-
} catch (LocalizedException $e) {
134-
// We have to return store mode to previous state in case of error.
135-
$this->setStoreMode($previousMode);
136-
throw $e;
137-
}
138-
$this->maintenanceMode->disableMaintenanceMode($this->output);
132+
$this->maintenanceModeEnabler->executeInMaintenanceMode(
133+
function () {
134+
$previousMode = $this->getMode();
135+
try {
136+
// We have to turn on production mode before generation.
137+
// We need this to enable generation of the "min" files.
138+
$this->setStoreMode(State::MODE_PRODUCTION);
139+
$this->filesystem->regenerateStatic($this->output);
140+
} catch (LocalizedException $e) {
141+
// We have to return store mode to previous state in case of error.
142+
$this->setStoreMode($previousMode);
143+
throw $e;
144+
}
145+
},
146+
$this->output,
147+
false
148+
);
139149
}
140150

141151
/**

app/code/Magento/Deploy/Test/Unit/Model/ModeTest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Magento\Framework\App\Console\MaintenanceModeEnabler;
1616
use Magento\Framework\App\DeploymentConfig\Reader;
1717
use Magento\Framework\App\DeploymentConfig\Writer;
18+
use Magento\Framework\App\MaintenanceMode;
1819
use Magento\Framework\App\State;
1920
use PHPUnit_Framework_MockObject_MockObject as Mock;
2021
use Symfony\Component\Console\Input\InputInterface;
@@ -54,7 +55,7 @@ class ModeTest extends \PHPUnit\Framework\TestCase
5455
private $writerMock;
5556

5657
/**
57-
* @var MaintenanceModeEnabler|Mock
58+
* @var MaintenanceMode|Mock
5859
*/
5960
private $maintenanceMock;
6061

@@ -95,7 +96,7 @@ protected function setUp()
9596
$this->readerMock = $this->getMockBuilder(Reader::class)
9697
->disableOriginalConstructor()
9798
->getMock();
98-
$this->maintenanceMock = $this->getMockBuilder(MaintenanceModeEnabler::class)
99+
$this->maintenanceMock = $this->getMockBuilder(MaintenanceMode::class)
99100
->disableOriginalConstructor()
100101
->getMock();
101102
$this->filesystemMock = $this->getMockBuilder(Filesystem::class)
@@ -124,7 +125,8 @@ protected function setUp()
124125
$this->filesystemMock,
125126
$this->configProvider,
126127
$this->processorFacadeFactory,
127-
$this->emulatedAreaProcessor
128+
$this->emulatedAreaProcessor,
129+
new MaintenanceModeEnabler($this->maintenanceMock)
128130
);
129131
}
130132

app/code/Magento/Theme/Console/Command/ThemeUninstallCommand.php

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66

77
namespace Magento\Theme\Console\Command;
88

9-
use Magento\Framework\App\Area;
109
use Magento\Framework\App\Cache;
10+
use Magento\Framework\App\MaintenanceMode;
1111
use Magento\Framework\App\Console\MaintenanceModeEnabler;
12+
use Magento\Framework\App\ObjectManager;
1213
use Magento\Framework\App\State\CleanupFiles;
1314
use Magento\Framework\Composer\ComposerInformation;
1415
use Magento\Framework\Composer\DependencyChecker;
@@ -39,11 +40,6 @@ class ThemeUninstallCommand extends Command
3940
const INPUT_KEY_THEMES = 'theme';
4041
const INPUT_KEY_CLEAR_STATIC_CONTENT = 'clear-static-content';
4142

42-
/**
43-
* @var MaintenanceModeEnabler
44-
*/
45-
private $maintenanceMode;
46-
4743
/**
4844
* Composer general dependency checker
4945
*
@@ -114,45 +110,55 @@ class ThemeUninstallCommand extends Command
114110
*/
115111
private $themeDependencyChecker;
116112

113+
/**
114+
* @var MaintenanceModeEnabler
115+
*/
116+
private $maintenanceModeEnabler;
117+
117118
/**
118119
* Constructor
119120
*
120121
* @param Cache $cache
121122
* @param CleanupFiles $cleanupFiles
122123
* @param ComposerInformation $composer
123-
* @param MaintenanceModeEnabler $maintenanceMode
124+
* @param MaintenanceMode $maintenanceMode deprecated, use $maintenanceModeEnabler instead
124125
* @param DependencyChecker $dependencyChecker
125126
* @param Collection $themeCollection
126127
* @param BackupRollbackFactory $backupRollbackFactory
127128
* @param ThemeValidator $themeValidator
128129
* @param ThemePackageInfo $themePackageInfo
129130
* @param ThemeUninstaller $themeUninstaller
130131
* @param ThemeDependencyChecker $themeDependencyChecker
132+
* @param MaintenanceModeEnabler $maintenanceModeEnabler
133+
*
134+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
131135
*/
132136
public function __construct(
133137
Cache $cache,
134138
CleanupFiles $cleanupFiles,
135139
ComposerInformation $composer,
136-
MaintenanceModeEnabler $maintenanceMode,
140+
MaintenanceMode $maintenanceMode,
137141
DependencyChecker $dependencyChecker,
138142
Collection $themeCollection,
139143
BackupRollbackFactory $backupRollbackFactory,
140144
ThemeValidator $themeValidator,
141145
ThemePackageInfo $themePackageInfo,
142146
ThemeUninstaller $themeUninstaller,
143-
ThemeDependencyChecker $themeDependencyChecker
147+
ThemeDependencyChecker $themeDependencyChecker,
148+
MaintenanceModeEnabler $maintenanceModeEnabler = null
144149
) {
145150
$this->cache = $cache;
146151
$this->cleanupFiles = $cleanupFiles;
147152
$this->composer = $composer;
148-
$this->maintenanceMode = $maintenanceMode;
149153
$this->dependencyChecker = $dependencyChecker;
150154
$this->themeCollection = $themeCollection;
151155
$this->backupRollbackFactory = $backupRollbackFactory;
152156
$this->themeValidator = $themeValidator;
153157
$this->themePackageInfo = $themePackageInfo;
154158
$this->themeUninstaller = $themeUninstaller;
155159
$this->themeDependencyChecker = $themeDependencyChecker;
160+
$this->maintenanceModeEnabler =
161+
$maintenanceModeEnabler ?: ObjectManager::getInstance()->get(MaintenanceModeEnabler::class);
156162
parent::__construct();
157163
}
158164

@@ -212,25 +218,32 @@ protected function execute(InputInterface $input, OutputInterface $output)
212218
return \Magento\Framework\Console\Cli::RETURN_FAILURE;
213219
}
214220

215-
try {
216-
$this->maintenanceMode->enableMaintenanceMode($output);
217-
if ($input->getOption(self::INPUT_KEY_BACKUP_CODE)) {
218-
$time = time();
219-
$codeBackup = $this->backupRollbackFactory->create($output);
220-
$codeBackup->codeBackup($time);
221-
}
222-
223-
$this->themeUninstaller->uninstallRegistry($output, $themePaths);
224-
$this->themeUninstaller->uninstallCode($output, $themePaths);
221+
$result = $this->maintenanceModeEnabler->executeInMaintenanceMode(
222+
function () use ($input, $output, $themePaths) {
223+
try {
224+
if ($input->getOption(self::INPUT_KEY_BACKUP_CODE)) {
225+
$time = time();
226+
$codeBackup = $this->backupRollbackFactory->create($output);
227+
$codeBackup->codeBackup($time);
228+
}
229+
230+
$this->themeUninstaller->uninstallRegistry($output, $themePaths);
231+
$this->themeUninstaller->uninstallCode($output, $themePaths);
232+
233+
$this->cleanup($input, $output);
234+
return \Magento\Framework\Console\Cli::RETURN_SUCCESS;
235+
} catch (\Exception $e) {
236+
$output->writeln('<error>' . $e->getMessage() . '</error>');
237+
$output->writeln('<error>Please disable maintenance mode after you resolved above issues</error>');
238+
// we must have an exit code higher than zero to indicate something was wrong
239+
return \Magento\Framework\Console\Cli::RETURN_FAILURE;
240+
}
241+
},
242+
$output,
243+
true
244+
);
225245

226-
$this->cleanup($input, $output);
227-
$this->maintenanceMode->disableMaintenanceMode($output);
228-
} catch (\Exception $e) {
229-
$output->writeln('<error>' . $e->getMessage() . '</error>');
230-
$output->writeln('<error>Please disable maintenance mode after you resolved above issues</error>');
231-
// we must have an exit code higher than zero to indicate something was wrong
232-
return \Magento\Framework\Console\Cli::RETURN_FAILURE;
233-
}
246+
return $result;
234247
}
235248

236249
/**

app/code/Magento/Theme/Test/Unit/Console/Command/ThemeUninstallCommandTest.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\Theme\Test\Unit\Console\Command;
88

9+
use Magento\Framework\App\Console\MaintenanceModeEnabler;
910
use Magento\Theme\Console\Command\ThemeUninstallCommand;
1011
use Magento\Theme\Model\Theme\themePackageInfo;
1112
use Magento\Theme\Model\Theme\ThemeUninstaller;
@@ -19,7 +20,7 @@
1920
class ThemeUninstallCommandTest extends \PHPUnit\Framework\TestCase
2021
{
2122
/**
22-
* @var \Magento\Framework\App\Console\MaintenanceModeEnabler|\PHPUnit_Framework_MockObject_MockObject
23+
* @var \Magento\Framework\App\Console\MaintenanceMode|\PHPUnit_Framework_MockObject_MockObject
2324
*/
2425
private $maintenanceMode;
2526

@@ -82,7 +83,7 @@ class ThemeUninstallCommandTest extends \PHPUnit\Framework\TestCase
8283

8384
protected function setUp()
8485
{
85-
$this->maintenanceMode = $this->createMock(\Magento\Framework\App\Console\MaintenanceModeEnabler::class);
86+
$this->maintenanceMode = $this->createMock(\Magento\Framework\App\MaintenanceMode::class);
8687
$composerInformation = $this->createMock(\Magento\Framework\Composer\ComposerInformation::class);
8788
$composerInformation->expects($this->any())
8889
->method('getRootRequiredPackages')
@@ -107,7 +108,8 @@ protected function setUp()
107108
$this->themeValidator,
108109
$this->themePackageInfo,
109110
$this->themeUninstaller,
110-
$this->themeDependencyChecker
111+
$this->themeDependencyChecker,
112+
new MaintenanceModeEnabler($this->maintenanceMode)
111113
);
112114
$this->tester = new CommandTester($this->command);
113115
}
@@ -304,9 +306,9 @@ public function testExecute()
304306
{
305307
$this->setUpExecute();
306308
$this->cleanupFiles->expects($this->never())->method('clearMaterializedViewFiles');
307-
$this->maintenanceMode->expects($this->once())->method('enableMaintenanceMode');
308-
$this->maintenanceMode->expects($this->once())->method('disableMaintenanceMode');
309309
$this->tester->execute(['theme' => ['area/vendor/test']]);
310+
$this->assertContains('Enabling maintenance mode', $this->tester->getDisplay());
311+
$this->assertContains('Disabling maintenance mode', $this->tester->getDisplay());
310312
$this->assertContains('Alert: Generated static view files were not cleared.', $this->tester->getDisplay());
311313
$this->assertNotContains('Generated static view files cleared successfully', $this->tester->getDisplay());
312314
}
@@ -315,9 +317,9 @@ public function testExecuteCleanStaticFiles()
315317
{
316318
$this->setUpExecute();
317319
$this->cleanupFiles->expects($this->once())->method('clearMaterializedViewFiles');
318-
$this->maintenanceMode->expects($this->once())->method('enableMaintenanceMode');
319-
$this->maintenanceMode->expects($this->once())->method('disableMaintenanceMode');
320320
$this->tester->execute(['theme' => ['area/vendor/test'], '-c' => true]);
321+
$this->assertContains('Enabling maintenance mode', $this->tester->getDisplay());
322+
$this->assertContains('Disabling maintenance mode', $this->tester->getDisplay());
321323
$this->assertNotContains('Alert: Generated static view files were not cleared.', $this->tester->getDisplay());
322324
$this->assertContains('Generated static view files cleared successfully', $this->tester->getDisplay());
323325
}

lib/internal/Magento/Framework/App/Console/MaintenanceModeEnabler.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function __construct(MaintenanceMode $maintenanceMode)
3838
* @param OutputInterface $output
3939
* @return void
4040
*/
41-
public function enableMaintenanceMode(OutputInterface $output)
41+
private function enableMaintenanceMode(OutputInterface $output)
4242
{
4343
if ($this->maintenanceMode->isOn()) {
4444
$this->skipDisableMaintenanceMode = true;
@@ -57,7 +57,7 @@ public function enableMaintenanceMode(OutputInterface $output)
5757
* @param OutputInterface $output
5858
* @return void
5959
*/
60-
public function disableMaintenanceMode(OutputInterface $output)
60+
private function disableMaintenanceMode(OutputInterface $output)
6161
{
6262
if ($this->skipDisableMaintenanceMode) {
6363
$output->writeln('<info>Skipped disabling maintenance mode</info>');
@@ -67,4 +67,30 @@ public function disableMaintenanceMode(OutputInterface $output)
6767
$this->maintenanceMode->set(false);
6868
$output->writeln('<info>Disabling maintenance mode</info>');
6969
}
70+
71+
/**
72+
* Run task in maintenance mode
73+
*
74+
* @param callable $task
75+
* @param OutputInterface $output
76+
* @param bool $holdMaintenanceOnFailure
77+
* @return mixed
78+
* @throws \Throwable if error occurred
79+
*/
80+
public function executeInMaintenanceMode(callable $task, OutputInterface $output, bool $holdMaintenanceOnFailure)
81+
{
82+
$this->enableMaintenanceMode($output);
83+
84+
try {
85+
$result = call_user_func($task);
86+
} catch (\Throwable $e) {
87+
if (!$holdMaintenanceOnFailure) {
88+
$this->disableMaintenanceMode($output);
89+
}
90+
throw $e;
91+
}
92+
93+
$this->disableMaintenanceMode($output);
94+
return $result;
95+
}
7096
}

0 commit comments

Comments
 (0)