Skip to content

Commit ffbede5

Browse files
committed
Attempt to get the session tests passing in PHP7.2
In PHP7.2 ini_set() cannot modify session configuration once headers have been 'sent'. In the CLI SAPI, headers are 'sent' as soon as STDOUT gets written to. By running most of the session tests in separate processes we can get around most of the limitations. But I had to change a few of the methods to supress errors in every other test.
1 parent 8045747 commit ffbede5

File tree

5 files changed

+36
-39
lines changed

5 files changed

+36
-39
lines changed

src/Network/Session.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ public static function create($sessionConfig = [])
108108
$sessionConfig['ini']['session.name'] = $sessionConfig['cookie'];
109109
}
110110

111-
if (!empty($sessionConfig['handler'])) {
111+
// In PHP7.1.0+ session.save_handler can't be set to user by the user.
112+
// https://github.com/php/php-src/blob/master/ext/session/session.c#L559
113+
if (!empty($sessionConfig['handler']) && version_compare(PHP_VERSION, '7.1.0', '<=')) {
112114
$sessionConfig['ini']['session.save_handler'] = 'user';
113115
}
114116

@@ -283,7 +285,7 @@ public function engine($class = null, array $options = [])
283285
*/
284286
public function options(array $options)
285287
{
286-
if (session_status() === \PHP_SESSION_ACTIVE) {
288+
if (session_status() === \PHP_SESSION_ACTIVE || headers_sent()) {
287289
return;
288290
}
289291

@@ -453,7 +455,7 @@ public function write($name, $value = null)
453455
*/
454456
public function id($id = null)
455457
{
456-
if ($id !== null) {
458+
if ($id !== null && !headers_sent()) {
457459
session_id($id);
458460
}
459461

src/Network/Session/DatabaseSession.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@ public function __construct(array $config = [])
6262
$this->_timeout = ini_get('session.gc_maxlifetime');
6363
}
6464

65+
/**
66+
* Set the timeout value for sessions.
67+
*
68+
* Primarily used in testing.
69+
*
70+
* @param int $timeout The timeout duration.
71+
* @return $this
72+
*/
73+
public function setTimeout($timeout)
74+
{
75+
$this->_timeout = $timeout;
76+
77+
return $this;
78+
}
79+
6580
/**
6681
* Method called on open of a database session.
6782
*

tests/TestCase/Network/Session/DatabaseSessionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ public function testGc()
153153
{
154154
TableRegistry::clear();
155155

156-
ini_set('session.gc_maxlifetime', '0');
157156
$storage = new DatabaseSession();
157+
$storage->setTimeout(0);
158158
$storage->write('foo', 'Some value');
159159

160160
sleep(1);

tests/TestCase/Network/SessionTest.php

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -77,39 +77,6 @@ class SessionTest extends TestCase
7777
*/
7878
public $fixtures = ['core.cake_sessions', 'core.sessions'];
7979

80-
/**
81-
* setup before class.
82-
*
83-
* @return void
84-
*/
85-
public static function setupBeforeClass()
86-
{
87-
// Make sure garbage collector will be called
88-
static::$_gcDivisor = ini_get('session.gc_divisor');
89-
ini_set('session.gc_divisor', '1');
90-
}
91-
92-
/**
93-
* teardown after class
94-
*
95-
* @return void
96-
*/
97-
public static function teardownAfterClass()
98-
{
99-
// Revert to the default setting
100-
ini_set('session.gc_divisor', static::$_gcDivisor);
101-
}
102-
103-
/**
104-
* setUp method
105-
*
106-
* @return void
107-
*/
108-
public function setUp()
109-
{
110-
parent::setUp();
111-
}
112-
11380
/**
11481
* tearDown method
11582
*
@@ -124,6 +91,7 @@ public function tearDown()
12491
/**
12592
* test setting ini properties with Session configuration.
12693
*
94+
* @runInSeparateProcess
12795
* @return void
12896
*/
12997
public function testSessionConfigIniSetting()
@@ -149,6 +117,7 @@ public function testSessionConfigIniSetting()
149117
/**
150118
* test session cookie path setting
151119
*
120+
* @runInSeparateProcess
152121
* @return void
153122
*/
154123
public function testCookiePath()
@@ -298,15 +267,16 @@ public function testConsume()
298267
/**
299268
* testId method
300269
*
270+
* @runInSeparateProcess
301271
* @return void
302272
*/
303273
public function testId()
304274
{
305275
$session = new Session();
276+
$session->start();
306277
$result = $session->id();
307-
$expected = session_id();
308278
$this->assertNotEmpty($result);
309-
$this->assertSame($expected, $result);
279+
$this->assertSame(session_id(), $result);
310280

311281
$session->id('MySessionId');
312282
$this->assertSame('MySessionId', $session->id());
@@ -489,6 +459,7 @@ public function testReadingSavedEmpty()
489459
/**
490460
* test using a handler from app/Model/Datasource/Session.
491461
*
462+
* @runInSeparateProcess
492463
* @return void
493464
*/
494465
public function testUsingAppLibsHandler()
@@ -512,6 +483,7 @@ public function testUsingAppLibsHandler()
512483
/**
513484
* test using a handler from a plugin.
514485
*
486+
* @runInSeparateProcess
515487
* @return void
516488
*/
517489
public function testUsingPluginHandler()
@@ -534,6 +506,7 @@ public function testUsingPluginHandler()
534506
/**
535507
* Tests that it is possible to pass an already made instance as the session engine
536508
*
509+
* @runInSeparateProcess
537510
* @return void
538511
*/
539512
public function testEngineWithPreMadeInstance()
@@ -564,6 +537,7 @@ public function testBadEngine()
564537
/**
565538
* Test that cookieTimeout matches timeout when unspecified.
566539
*
540+
* @runInSeparateProcess
567541
* @return void
568542
*/
569543
public function testCookieTimeoutFallback()
@@ -581,6 +555,7 @@ public function testCookieTimeoutFallback()
581555
/**
582556
* Tests that the cookie name can be changed with configuration
583557
*
558+
* @runInSeparateProcess
584559
* @return void
585560
*/
586561
public function testSessionName()
@@ -591,6 +566,8 @@ public function testSessionName()
591566

592567
/**
593568
* Test that a call of check() starts the session when cookies are disabled in php.ini
569+
*
570+
* @runInSeparateProcess
594571
*/
595572
public function testCheckStartsSessionWithCookiesDisabled()
596573
{
@@ -631,6 +608,8 @@ public function testCheckStartsSessionWithCookie()
631608

632609
/**
633610
* Test that a call of check() starts the session when the session ID is passed via URL and session.use_trans_sid is enabled
611+
*
612+
* @runInSeparateProcess
634613
*/
635614
public function testCheckStartsSessionWithSIDinURL()
636615
{

tests/bootstrap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
MutableDate::setTestNow(MutableDate::now());
132132

133133
ini_set('intl.default_locale', 'en_US');
134+
ini_set('session.gc_divisor', '1');
134135

135136
if (class_exists('PHPUnit_Runner_Version')) {
136137
class_alias('PHPUnit_Framework_TestResult', 'PHPUnit\Framework\TestResult');

0 commit comments

Comments
 (0)