Skip to content

Commit a32814b

Browse files
committed
MC-28948: Doesn't work: "Files" as fallback when Magento fails to connect to "Redis"
1 parent d088b84 commit a32814b

File tree

2 files changed

+50
-100
lines changed

2 files changed

+50
-100
lines changed

dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php

Lines changed: 41 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@
99
use Magento\Framework\Exception\SessionException;
1010
use Magento\Framework\Phrase;
1111
use Magento\Framework\Session\Config\ConfigInterface;
12-
use Magento\Framework\App\ObjectManager;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
use Magento\TestFramework\ObjectManager;
1314

15+
/**
16+
* Tests \Magento\Framework\Session\SaveHandler functionality.
17+
*
18+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
19+
*/
1420
class SaveHandlerTest extends \PHPUnit\Framework\TestCase
1521
{
1622
/**
17-
* @var \Magento\TestFramework\ObjectManager
23+
* @var ObjectManager
1824
*/
1925
private $objectManager;
2026

@@ -28,115 +34,64 @@ class SaveHandlerTest extends \PHPUnit\Framework\TestCase
2834
*/
2935
private $saveHandlerFactoryMock;
3036

37+
/**
38+
* @inheritdoc
39+
*/
3140
protected function setUp()
3241
{
33-
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
42+
$this->objectManager = Bootstrap::getObjectManager();
3443
$this->deploymentConfigMock = $this->createMock(DeploymentConfig::class);
3544
$this->objectManager->addSharedInstance($this->deploymentConfigMock, DeploymentConfig::class);
3645
$this->saveHandlerFactoryMock = $this->createMock(SaveHandlerFactory::class);
3746
$this->objectManager->addSharedInstance($this->saveHandlerFactoryMock, SaveHandlerFactory::class);
3847
}
3948

49+
/**
50+
* @inheritdoc
51+
*/
4052
protected function tearDown()
4153
{
4254
$this->objectManager->removeSharedInstance(DeploymentConfig::class);
4355
$this->objectManager->removeSharedInstance(SaveHandlerFactory::class);
4456
}
4557

4658
/**
47-
* Tests that the session handler is correctly set when object is created.
48-
*
49-
* @dataProvider saveHandlerProvider
50-
* @param string $deploymentConfigHandler
59+
* @return void
5160
*/
52-
public function testConstructor($deploymentConfigHandler)
61+
public function testRedisSaveHandlerFallbackToDefaultOnSessionException(): void
5362
{
54-
$expected = $this->getExpectedSaveHandler($deploymentConfigHandler, ini_get('session.save_handler'));
55-
5663
$this->deploymentConfigMock->method('get')
57-
->willReturnCallback(function ($configPath) use ($deploymentConfigHandler) {
58-
switch ($configPath) {
59-
case Config::PARAM_SESSION_SAVE_METHOD:
60-
return $deploymentConfigHandler;
61-
case Config::PARAM_SESSION_CACHE_LIMITER:
62-
return 'private_no_expire';
63-
case Config::PARAM_SESSION_SAVE_PATH:
64-
return 'explicit_save_path';
65-
default:
66-
return null;
67-
}
68-
});
64+
->willReturnMap(
65+
[
66+
[Config::PARAM_SESSION_SAVE_METHOD, null, 'redis'],
67+
[Config::PARAM_SESSION_SAVE_PATH, null, 'explicit_save_path'],
68+
]
69+
);
6970

70-
$this->saveHandlerFactoryMock->expects($this->once())
71-
->method('create')
72-
->with($expected);
73-
$sessionConfig = $this->objectManager->create(ConfigInterface::class);
74-
$this->objectManager->create(SaveHandler::class, ['sessionConfig' => $sessionConfig]);
75-
76-
// Test expectation
77-
$this->assertEquals(
78-
$expected,
79-
$sessionConfig->getOption('session.save_handler')
80-
);
81-
}
82-
83-
public function saveHandlerProvider()
84-
{
85-
return [
86-
['db'],
87-
['redis'],
88-
['files'],
89-
[false],
90-
];
91-
}
92-
93-
/**
94-
* Retrieve expected session.save_handler
95-
*
96-
* @param string $deploymentConfigHandler
97-
* @param string $iniHandler
98-
* @return string
99-
*/
100-
private function getExpectedSaveHandler($deploymentConfigHandler, $iniHandler)
101-
{
102-
if ($deploymentConfigHandler) {
103-
return $deploymentConfigHandler;
104-
} elseif ($iniHandler) {
105-
return $iniHandler;
106-
} else {
107-
return SaveHandlerInterface::DEFAULT_HANDLER;
108-
}
109-
}
71+
$redisHandlerMock = $this->getMockBuilder(SaveHandler\Redis::class)
72+
->disableOriginalConstructor()
73+
->getMock();
74+
$redisHandlerMock->method('open')
75+
->with('explicit_save_path', 'test_session_id')
76+
->willThrowException(new SessionException(new Phrase('Session Exception')));
11077

111-
public function testConstructorWithException()
112-
{
113-
$this->deploymentConfigMock->method('get')
114-
->willReturnCallback(function ($configPath) {
115-
switch ($configPath) {
116-
case Config::PARAM_SESSION_SAVE_METHOD:
117-
return 'db';
118-
case Config::PARAM_SESSION_CACHE_LIMITER:
119-
return 'private_no_expire';
120-
case Config::PARAM_SESSION_SAVE_PATH:
121-
return 'explicit_save_path';
122-
default:
123-
return null;
124-
}
125-
});
78+
$defaultHandlerMock = $this->getMockBuilder(SaveHandler\Native::class)
79+
->disableOriginalConstructor()
80+
->getMock();
81+
$defaultHandlerMock->expects($this->once())->method('open')->with('explicit_save_path', 'test_session_id');
12682

12783
$this->saveHandlerFactoryMock->expects($this->at(0))
12884
->method('create')
129-
->willThrowException(new SessionException(new Phrase('Session Exception')));
85+
->with('redis')
86+
->willReturn($redisHandlerMock);
13087
$this->saveHandlerFactoryMock->expects($this->at(1))
13188
->method('create')
132-
->with(SaveHandlerInterface::DEFAULT_HANDLER);
133-
$sessionConfig = $this->objectManager->create(ConfigInterface::class);
134-
$this->objectManager->create(SaveHandler::class, ['sessionConfig' => $sessionConfig]);
89+
->with(SaveHandlerInterface::DEFAULT_HANDLER)
90+
->willReturn($defaultHandlerMock);
13591

136-
// Test expectation
137-
$this->assertEquals(
138-
'db',
139-
$sessionConfig->getOption('session.save_handler')
140-
);
92+
$sessionConfig = $this->objectManager->create(ConfigInterface::class);
93+
/** @var SaveHandler $saveHandler */
94+
$saveHandler = $this->objectManager->create(SaveHandler::class, ['sessionConfig' => $sessionConfig]);
95+
$saveHandler->open('explicit_save_path', 'test_session_id');
14196
}
14297
}

lib/internal/Magento/Framework/Session/SaveHandler.php

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ class SaveHandler implements SaveHandlerInterface
3535
*/
3636
private $defaultHandler;
3737

38+
/**
39+
* @var string
40+
*/
41+
private $saveHandler;
42+
3843
/**
3944
* @param SaveHandlerFactory $saveHandlerFactory
4045
* @param ConfigInterface $sessionConfig
@@ -48,20 +53,7 @@ public function __construct(
4853
$this->saveHandlerFactory = $saveHandlerFactory;
4954
$this->sessionConfig = $sessionConfig;
5055
$this->defaultHandler = $default;
51-
52-
/**
53-
* Session handler
54-
*
55-
* Save handler may be set to custom value in deployment config, which will override everything else.
56-
* Otherwise, try to read PHP settings for session.save_handler value. Otherwise, use 'files' as default.
57-
*/
58-
$saveMethod = $this->sessionConfig->getOption('session.save_handler') ?: $this->defaultHandler;
59-
60-
try {
61-
$this->saveHandlerAdapter = $this->saveHandlerFactory->create($saveMethod);
62-
} catch (SessionException $e) {
63-
$this->saveHandlerAdapter = $this->saveHandlerFactory->create($this->defaultHandler);
64-
}
56+
$this->saveHandler = $this->sessionConfig->getOption('session.save_handler') ?: $this->defaultHandler;
6557
}
6658

6759
/**
@@ -145,6 +137,9 @@ public function gc($maxLifetime)
145137
private function callSafely(string $method, ...$arguments)
146138
{
147139
try {
140+
if ($this->saveHandlerAdapter === null) {
141+
$this->saveHandlerAdapter = $this->saveHandlerFactory->create($this->saveHandler);
142+
}
148143
return $this->saveHandlerAdapter->{$method}(...$arguments);
149144
} catch (SessionException $exception) {
150145
$this->saveHandlerAdapter = $this->saveHandlerFactory->create($this->defaultHandler);

0 commit comments

Comments
 (0)