mirror of
https://github.com/moodle/moodle.git
synced 2025-08-09 10:56:56 +02:00
MDL-66151 Performance: Session Manager modularisation
Storage of session metadata has moved into the session handler class. This allows for other classes to fully control session handling and removes the dependancy on the core sessions database table. Previously, the standard method of interaction with the session metadata was direct DB calls; this may break other plugins as there are now proper APIs available through the session manager. Co-authored-by: Darren Cocco <moodle@darren.cocco.id.au> Co-authored-by: Trisha Milan <trishamilan@catalyst-au.net> Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
This commit is contained in:
parent
072fb90384
commit
e52fbd2f84
30 changed files with 1408 additions and 700 deletions
86
lib/tests/classes/session/mock_handler.php
Normal file
86
lib/tests/classes/session/mock_handler.php
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core\tests\session;
|
||||
|
||||
use core\clock;
|
||||
use core\di;
|
||||
use core\session\database;
|
||||
|
||||
/**
|
||||
* Mock handler methods class.
|
||||
*
|
||||
* @package core
|
||||
* @author Darren Cocco <moodle@darren.cocco.id.au>
|
||||
* @author Trisha Milan <trishamilan@catalyst-au.net>
|
||||
* @copyright 2022 Monash University (http://www.monash.edu)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mock_handler extends database {
|
||||
#[\Override]
|
||||
public function init(): bool {
|
||||
// Nothing special to do in the mock.
|
||||
return true;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function session_exists($sid): bool {
|
||||
global $DB;
|
||||
|
||||
return $DB->record_exists('sessions', ['sid' => $sid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new session record to be used in unit tests.
|
||||
*
|
||||
* @param \stdClass $record
|
||||
* @return int Inserted record id.
|
||||
*/
|
||||
public function add_test_session(\stdClass $record): int {
|
||||
global $DB, $USER;
|
||||
|
||||
$data = new \stdClass();
|
||||
$data->state = $record->state ?? 0;
|
||||
$data->sid = $record->sid ?? session_id();
|
||||
$data->sessdata = $record->sessdata ?? null;
|
||||
$data->userid = $record->userid ?? $USER->id;
|
||||
$data->timecreated = $record->timecreated ?? di::get(clock::class)->time();
|
||||
$data->timemodified = $record->timemodified ?? di::get(clock::class)->time();
|
||||
$data->firstip = $record->firstip ?? getremoteaddr();
|
||||
$data->lastip = $record->lastip ?? getremoteaddr();
|
||||
|
||||
return $DB->insert_record('sessions', $data);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function get_all_sessions(): \Iterator {
|
||||
global $DB;
|
||||
|
||||
$records = $DB->get_records('sessions');
|
||||
return new \ArrayIterator($records);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of all sessions stored.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count_sessions(): int {
|
||||
global $DB;
|
||||
|
||||
return $DB->count_records('sessions');
|
||||
}
|
||||
}
|
|
@ -14,7 +14,9 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core;
|
||||
namespace core\session;
|
||||
|
||||
use core\tests\session\mock_handler;
|
||||
|
||||
/**
|
||||
* Unit tests for session manager class.
|
||||
|
@ -23,8 +25,18 @@ namespace core;
|
|||
* @category test
|
||||
* @copyright 2013 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \core\session\manager
|
||||
*/
|
||||
class session_manager_test extends \advanced_testcase {
|
||||
final class manager_test extends \advanced_testcase {
|
||||
|
||||
/** @var mock_handler $mockhandler Dedicated testing handler. */
|
||||
protected mock_handler $mockhandler;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->mockhandler = new mock_handler();
|
||||
}
|
||||
|
||||
public function test_start(): void {
|
||||
$this->resetAfterTest();
|
||||
// Session must be started only once...
|
||||
|
@ -185,23 +197,23 @@ class session_manager_test extends \advanced_testcase {
|
|||
$record->sid = $sid;
|
||||
$record->timecreated = time();
|
||||
$record->timemodified = $record->timecreated;
|
||||
$record->id = $DB->insert_record('sessions', $record);
|
||||
$record->id = $this->mockhandler->add_test_session($record);
|
||||
|
||||
$this->assertTrue(\core\session\manager::session_exists($sid));
|
||||
|
||||
$record->timecreated = time() - $CFG->sessiontimeout - 100;
|
||||
$record->timemodified = $record->timecreated + 10;
|
||||
$DB->update_record('sessions', $record);
|
||||
\core\session\manager::update_session($record);
|
||||
|
||||
$this->assertTrue(\core\session\manager::session_exists($sid));
|
||||
|
||||
$record->userid = $guest->id;
|
||||
$DB->update_record('sessions', $record);
|
||||
\core\session\manager::update_session($record);
|
||||
|
||||
$this->assertTrue(\core\session\manager::session_exists($sid));
|
||||
|
||||
$record->userid = $user->id;
|
||||
$DB->update_record('sessions', $record);
|
||||
\core\session\manager::update_session($record);
|
||||
|
||||
$this->assertFalse(\core\session\manager::session_exists($sid));
|
||||
|
||||
|
@ -211,7 +223,6 @@ class session_manager_test extends \advanced_testcase {
|
|||
}
|
||||
|
||||
public function test_touch_session(): void {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
$sid = md5('hokus');
|
||||
|
@ -223,17 +234,23 @@ class session_manager_test extends \advanced_testcase {
|
|||
$record->timecreated = time() - 60*60;
|
||||
$record->timemodified = time() - 30;
|
||||
$record->firstip = $record->lastip = '10.0.0.1';
|
||||
$record->id = $DB->insert_record('sessions', $record);
|
||||
$record->id = $this->mockhandler->add_test_session($record);
|
||||
|
||||
$now = time();
|
||||
\core\session\manager::touch_session($sid);
|
||||
$updated = $DB->get_field('sessions', 'timemodified', array('id'=>$record->id));
|
||||
$session = \core\session\manager::get_session_by_sid($sid);
|
||||
|
||||
$this->assertGreaterThanOrEqual($now, $updated);
|
||||
$this->assertLessThanOrEqual(time(), $updated);
|
||||
$this->assertGreaterThanOrEqual($now, $session->timemodified);
|
||||
$this->assertLessThanOrEqual(time(), $session->timemodified);
|
||||
}
|
||||
|
||||
public function test_kill_session(): void {
|
||||
/**
|
||||
* Test destroy method.
|
||||
*
|
||||
* @return void
|
||||
* @throws \dml_exception
|
||||
*/
|
||||
public function test_destroy(): void {
|
||||
global $DB, $USER;
|
||||
$this->resetAfterTest();
|
||||
|
||||
|
@ -249,23 +266,23 @@ class session_manager_test extends \advanced_testcase {
|
|||
$record->timecreated = time() - 60*60;
|
||||
$record->timemodified = time() - 30;
|
||||
$record->firstip = $record->lastip = '10.0.0.1';
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->userid = 0;
|
||||
$record->sid = md5('pokus');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$this->assertEquals(2, $DB->count_records('sessions'));
|
||||
$this->assertEquals(2, $this->mockhandler->count_sessions());
|
||||
|
||||
\core\session\manager::kill_session($sid);
|
||||
|
||||
$this->assertEquals(1, $DB->count_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('sid'=>$sid)));
|
||||
\core\session\manager::destroy($sid);
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertEquals(1, count($sessions));
|
||||
$this->assertFalse($this->contains_session(['sid' => $sid], $sessions));
|
||||
|
||||
$this->assertSame($userid, $USER->id);
|
||||
}
|
||||
|
||||
public function test_kill_user_sessions(): void {
|
||||
public function test_destroy_user_sessions(): void {
|
||||
global $DB, $USER;
|
||||
$this->resetAfterTest();
|
||||
|
||||
|
@ -281,40 +298,44 @@ class session_manager_test extends \advanced_testcase {
|
|||
$record->timecreated = time() - 60*60;
|
||||
$record->timemodified = time() - 30;
|
||||
$record->firstip = $record->lastip = '10.0.0.1';
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->sid = md5('hokus2');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->userid = 0;
|
||||
$record->sid = md5('pokus');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$this->assertEquals(3, $DB->count_records('sessions'));
|
||||
|
||||
\core\session\manager::kill_user_sessions($userid);
|
||||
\core\session\manager::destroy_user_sessions($userid);
|
||||
|
||||
$this->assertEquals(1, $DB->count_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $userid)));
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertEquals(1, count($sessions));
|
||||
$this->assertFalse($this->contains_session(['userid' => $userid], $sessions));
|
||||
|
||||
$record->userid = $userid;
|
||||
$record->sid = md5('pokus3');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->userid = $userid;
|
||||
$record->sid = md5('pokus4');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->userid = $userid;
|
||||
$record->sid = md5('pokus5');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$this->assertEquals(3, $DB->count_records('sessions', array('userid' => $userid)));
|
||||
$sessions = \core\session\manager::get_sessions_by_userid($userid);
|
||||
$this->assertCount(3, $sessions);
|
||||
|
||||
\core\session\manager::kill_user_sessions($userid, md5('pokus5'));
|
||||
\core\session\manager::destroy_user_sessions($userid, md5('pokus5'));
|
||||
|
||||
$this->assertEquals(1, $DB->count_records('sessions', array('userid' => $userid)));
|
||||
$this->assertEquals(1, $DB->count_records('sessions', array('userid' => $userid, 'sid' => md5('pokus5'))));
|
||||
$sessions = \core\session\manager::get_sessions_by_userid($userid);
|
||||
$session = reset($sessions);
|
||||
$this->assertCount(1, $sessions);
|
||||
$this->assertEquals(md5('pokus5'), $session->sid);
|
||||
}
|
||||
|
||||
public function test_apply_concurrent_login_limit(): void {
|
||||
|
@ -334,41 +355,41 @@ class session_manager_test extends \advanced_testcase {
|
|||
|
||||
$record->sid = md5('hokus1');
|
||||
$record->timecreated = 20;
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
$record->sid = md5('hokus2');
|
||||
$record->timecreated = 10;
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
$record->sid = md5('hokus3');
|
||||
$record->timecreated = 30;
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->userid = $user2->id;
|
||||
$record->sid = md5('pokus1');
|
||||
$record->timecreated = 20;
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
$record->sid = md5('pokus2');
|
||||
$record->timecreated = 10;
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
$record->sid = md5('pokus3');
|
||||
$record->timecreated = 30;
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->timecreated = 10;
|
||||
$record->userid = $guest->id;
|
||||
$record->sid = md5('g1');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
$record->sid = md5('g2');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
$record->sid = md5('g3');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->userid = 0;
|
||||
$record->sid = md5('nl1');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
$record->sid = md5('nl2');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
$record->sid = md5('nl3');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
set_config('limitconcurrentlogins', 0);
|
||||
$this->assertCount(12, $DB->get_records('sessions'));
|
||||
|
@ -390,57 +411,103 @@ class session_manager_test extends \advanced_testcase {
|
|||
set_config('limitconcurrentlogins', 2);
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user1->id);
|
||||
$this->assertCount(11, $DB->get_records('sessions'));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 20)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 30)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 10)));
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertCount(11, $sessions);
|
||||
$this->assertTrue($this->contains_session(['userid' => $user1->id, 'timecreated' => 20], $sessions));
|
||||
$this->assertTrue($this->contains_session(['userid' => $user1->id, 'timecreated' => 30], $sessions));
|
||||
$this->assertFalse($this->contains_session(['userid' => $user1->id, 'timecreated' => 10], $sessions));
|
||||
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10)));
|
||||
$this->assertTrue($this->contains_session(['userid' => $user2->id, 'timecreated' => 20], $sessions));
|
||||
$this->assertTrue($this->contains_session(['userid' => $user2->id, 'timecreated' => 30], $sessions));
|
||||
$this->assertTrue($this->contains_session(['userid' => $user2->id, 'timecreated' => 10], $sessions));
|
||||
set_config('limitconcurrentlogins', 2);
|
||||
\core\session\manager::apply_concurrent_login_limit($user2->id, md5('pokus2'));
|
||||
$this->assertCount(10, $DB->get_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10)));
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertCount(10, $sessions);
|
||||
$this->assertFalse($this->contains_session(['userid' => $user2->id, 'timecreated' => 20], $sessions));
|
||||
$this->assertTrue($this->contains_session(['userid' => $user2->id, 'timecreated' => 30], $sessions));
|
||||
$this->assertTrue($this->contains_session(['userid' => $user2->id, 'timecreated' => 10], $sessions));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($guest->id);
|
||||
\core\session\manager::apply_concurrent_login_limit(0);
|
||||
$this->assertCount(10, $DB->get_records('sessions'));
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertCount(10, $sessions);
|
||||
|
||||
set_config('limitconcurrentlogins', 1);
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user1->id, md5('grrr'));
|
||||
$this->assertCount(9, $DB->get_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 20)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 30)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 10)));
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertCount(9, $sessions);
|
||||
$this->assertFalse($this->contains_session(['userid' => $user1->id, 'timecreated' => 20], $sessions));
|
||||
$this->assertTrue($this->contains_session(['userid' => $user1->id, 'timecreated' => 30], $sessions));
|
||||
$this->assertFalse($this->contains_session(['userid' => $user1->id, 'timecreated' => 10], $sessions));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user1->id);
|
||||
$this->assertCount(9, $DB->get_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 20)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 30)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 10)));
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertCount(9, $sessions);
|
||||
$this->assertFalse($this->contains_session(['userid' => $user1->id, 'timecreated' => 20], $sessions));
|
||||
$this->assertTrue($this->contains_session(['userid' => $user1->id, 'timecreated' => 30], $sessions));
|
||||
$this->assertFalse($this->contains_session(['userid' => $user1->id, 'timecreated' => 10], $sessions));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user2->id, md5('pokus2'));
|
||||
$this->assertCount(8, $DB->get_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10)));
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertCount(8, $sessions);
|
||||
$this->assertFalse($this->contains_session(['userid' => $user2->id, 'timecreated' => 20], $sessions));
|
||||
$this->assertFalse($this->contains_session(['userid' => $user2->id, 'timecreated' => 30], $sessions));
|
||||
$this->assertTrue($this->contains_session(['userid' => $user2->id, 'timecreated' => 10], $sessions));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user2->id);
|
||||
$this->assertCount(8, $DB->get_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10)));
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertCount(8, $sessions);
|
||||
$this->assertFalse($this->contains_session(['userid' => $user2->id, 'timecreated' => 20], $sessions));
|
||||
$this->assertFalse($this->contains_session(['userid' => $user2->id, 'timecreated' => 30], $sessions));
|
||||
$this->assertTrue($this->contains_session(['userid' => $user2->id, 'timecreated' => 10], $sessions));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($guest->id);
|
||||
\core\session\manager::apply_concurrent_login_limit(0);
|
||||
$this->assertCount(8, $DB->get_records('sessions'));
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertCount(8, $sessions);
|
||||
}
|
||||
|
||||
public function test_kill_all_sessions(): void {
|
||||
/**
|
||||
* Helper method to check if the sessions array contains a session with the given conditions.
|
||||
*
|
||||
* @param array $conditions Conditions to match.
|
||||
* @param null|\Iterator $sessions Sessions to check.
|
||||
* @return bool
|
||||
*/
|
||||
protected function contains_session(array $conditions, ?\Iterator $sessions = null): bool {
|
||||
foreach ($sessions as $session) {
|
||||
if ($this->matches_session($conditions, $session)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to check if the session matches the given conditions.
|
||||
*
|
||||
* @param array $conditions Conditions to match.
|
||||
* @param \stdClass $session Session to check.
|
||||
* @return bool
|
||||
*/
|
||||
protected function matches_session(array $conditions, \stdClass $session): bool {
|
||||
foreach ($conditions as $key => $value) {
|
||||
if ($session->$key != $value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test destroy_all method.
|
||||
*
|
||||
* @return void
|
||||
* @throws \dml_exception
|
||||
*/
|
||||
public function test_destroy_all(): void {
|
||||
global $DB, $USER;
|
||||
$this->resetAfterTest();
|
||||
|
||||
|
@ -456,25 +523,25 @@ class session_manager_test extends \advanced_testcase {
|
|||
$record->timecreated = time() - 60*60;
|
||||
$record->timemodified = time() - 30;
|
||||
$record->firstip = $record->lastip = '10.0.0.1';
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->sid = md5('hokus2');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->userid = 0;
|
||||
$record->sid = md5('pokus');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$this->assertEquals(3, $DB->count_records('sessions'));
|
||||
|
||||
\core\session\manager::kill_all_sessions();
|
||||
\core\session\manager::destroy_all();
|
||||
|
||||
$this->assertEquals(0, $DB->count_records('sessions'));
|
||||
$this->assertSame(0, $USER->id);
|
||||
}
|
||||
|
||||
public function test_gc(): void {
|
||||
global $CFG, $DB, $USER;
|
||||
global $CFG, $USER;
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->setAdminUser();
|
||||
|
@ -483,6 +550,8 @@ class session_manager_test extends \advanced_testcase {
|
|||
$guestid = $USER->id;
|
||||
$this->setUser(0);
|
||||
|
||||
// Set sessions timeout to 600 (10 minutes) seconds.
|
||||
// We will test if sessions not modified for 600 seconds are removed.
|
||||
$CFG->sessiontimeout = 60*10;
|
||||
|
||||
$record = new \stdClass();
|
||||
|
@ -493,53 +562,53 @@ class session_manager_test extends \advanced_testcase {
|
|||
$record->timecreated = time() - 60*60;
|
||||
$record->timemodified = time() - 30;
|
||||
$record->firstip = $record->lastip = '10.0.0.1';
|
||||
$r1 = $DB->insert_record('sessions', $record);
|
||||
$r1 = $this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->sid = md5('hokus2');
|
||||
$record->userid = $adminid;
|
||||
$record->timecreated = time() - 60*60;
|
||||
$record->timemodified = time() - 60*20;
|
||||
$r2 = $DB->insert_record('sessions', $record);
|
||||
$r2 = $this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->sid = md5('hokus3');
|
||||
$record->userid = $guestid;
|
||||
$record->timecreated = time() - 60*60*60;
|
||||
$record->timemodified = time() - 60*20;
|
||||
$r3 = $DB->insert_record('sessions', $record);
|
||||
$r3 = $this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->sid = md5('hokus4');
|
||||
$record->userid = $guestid;
|
||||
$record->timecreated = time() - 60*60*60;
|
||||
$record->timemodified = time() - 60*10*5 - 60;
|
||||
$r4 = $DB->insert_record('sessions', $record);
|
||||
$r4 = $this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->sid = md5('hokus5');
|
||||
$record->userid = 0;
|
||||
$record->timecreated = time() - 60*5;
|
||||
$record->timemodified = time() - 60*5;
|
||||
$r5 = $DB->insert_record('sessions', $record);
|
||||
$r5 = $this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->sid = md5('hokus6');
|
||||
$record->userid = 0;
|
||||
$record->timecreated = time() - 60*60;
|
||||
$record->timemodified = time() - 60*10 -10;
|
||||
$r6 = $DB->insert_record('sessions', $record);
|
||||
$r6 = $this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->sid = md5('hokus7');
|
||||
$record->userid = 0;
|
||||
$record->timecreated = time() - 60*60;
|
||||
$record->timemodified = time() - 60*9;
|
||||
$r7 = $DB->insert_record('sessions', $record);
|
||||
$r7 = $this->mockhandler->add_test_session($record);
|
||||
|
||||
\core\session\manager::gc();
|
||||
|
||||
$this->assertTrue($DB->record_exists('sessions', array('id'=>$r1)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('id'=>$r2)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('id'=>$r3)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('id'=>$r4)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('id'=>$r5)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('id'=>$r6)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('id'=>$r7)));
|
||||
\core\session\manager::gc($CFG->sessiontimeout);
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertTrue($this->contains_session(['id' => $r1], $sessions));
|
||||
$this->assertFalse($this->contains_session(['id' => $r2], $sessions));
|
||||
$this->assertTrue($this->contains_session(['id' => $r3], $sessions));
|
||||
$this->assertFalse($this->contains_session(['id' => $r4], $sessions));
|
||||
$this->assertFalse($this->contains_session(['id' => $r5], $sessions));
|
||||
$this->assertFalse($this->contains_session(['id' => $r6], $sessions));
|
||||
$this->assertTrue($this->contains_session(['id' => $r7], $sessions));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -648,7 +717,7 @@ class session_manager_test extends \advanced_testcase {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function pages_sessionlocks() {
|
||||
public function pages_sessionlocks(): array {
|
||||
return [
|
||||
[
|
||||
'url' => '/good.php',
|
||||
|
@ -738,7 +807,7 @@ class session_manager_test extends \advanced_testcase {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sessionlock_history() {
|
||||
public function sessionlock_history(): array {
|
||||
return [
|
||||
[
|
||||
'url' => '/good.php',
|
||||
|
@ -849,7 +918,7 @@ class session_manager_test extends \advanced_testcase {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function array_session_diff_provider() {
|
||||
public static function array_session_diff_provider(): array {
|
||||
// Create an instance of this object so the comparison object's identities are the same.
|
||||
// Used in one of the tests below.
|
||||
$compareobjectb = (object) ['array' => 'b'];
|
||||
|
@ -920,4 +989,44 @@ class session_manager_test extends \advanced_testcase {
|
|||
$result = $method->invokeArgs(null, [$a, $b]);
|
||||
$this->assertSame($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test destroy by auth plugin method.
|
||||
*/
|
||||
public function test_destroy_by_auth_plugin(): void {
|
||||
$this->resetAfterTest();
|
||||
global $DB;
|
||||
|
||||
// Create test users.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user(['auth' => 'db']);
|
||||
|
||||
// Create sessions for the users.
|
||||
$user1sid = md5('hokus');
|
||||
$record = new \stdClass();
|
||||
$record->state = 0;
|
||||
$record->sid = $user1sid;
|
||||
$record->sessdata = null;
|
||||
$record->userid = $user1->id;
|
||||
$record->timecreated = time() - 60 * 60;
|
||||
$record->timemodified = time() - 30;
|
||||
$record->firstip = $record->lastip = '10.0.0.1';
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
$record->sid = md5('pokus');
|
||||
$record->userid = $user2->id;
|
||||
$this->mockhandler->add_test_session($record);
|
||||
|
||||
// Check sessions.
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertEquals(2, count($sessions));
|
||||
|
||||
// Destroy the session for the user with manual auth plugin.
|
||||
\core\session\manager::destroy_by_auth_plugin('manual');
|
||||
|
||||
// Check that the session for the user with manual auth plugin is destroyed.
|
||||
$sessions = $this->mockhandler->get_all_sessions();
|
||||
$this->assertEquals(1, count($sessions));
|
||||
$this->assertFalse($this->contains_session(['sid' => $user1sid], $sessions));
|
||||
}
|
||||
}
|
|
@ -14,8 +14,9 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core;
|
||||
namespace core\session;
|
||||
|
||||
use core\tests\session\mock_handler;
|
||||
use Redis;
|
||||
use RedisException;
|
||||
|
||||
|
@ -34,21 +35,21 @@ use RedisException;
|
|||
* @copyright 2016 Russell Smith
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @runClassInSeparateProcess
|
||||
* @covers \core\session\redis
|
||||
*/
|
||||
class session_redis_test extends \advanced_testcase {
|
||||
|
||||
/** @var $keyprefix This key prefix used when testing Redis */
|
||||
protected $keyprefix = null;
|
||||
/** @var $redis The current testing redis connection */
|
||||
protected $redis = null;
|
||||
final class redis_test extends \advanced_testcase {
|
||||
/** @var string $keyprefix This key prefix used when testing Redis */
|
||||
protected string $keyprefix = '';
|
||||
/** @var ?Redis $redis The current testing redis connection */
|
||||
protected ?Redis $redis = null;
|
||||
/** @var bool $encrypted Is the current testing redis connection encrypted*/
|
||||
protected $encrypted = false;
|
||||
protected bool $encrypted = false;
|
||||
/** @var int $acquiretimeout how long we wait for session lock in seconds when testing Redis */
|
||||
protected $acquiretimeout = 1;
|
||||
protected int $acquiretimeout = 1;
|
||||
/** @var int $lockexpire how long to wait in seconds before expiring the lock when testing Redis */
|
||||
protected $lockexpire = 70;
|
||||
|
||||
protected int $lockexpire = 70;
|
||||
|
||||
#[\Override]
|
||||
public function setUp(): void {
|
||||
global $CFG;
|
||||
parent::setUp();
|
||||
|
@ -62,8 +63,8 @@ class session_redis_test extends \advanced_testcase {
|
|||
$version = phpversion('Redis');
|
||||
if (!$version) {
|
||||
$this->markTestSkipped('Redis extension version missing');
|
||||
} else if (version_compare($version, \core\session\redis::REDIS_EXTENSION_MIN_VERSION) <= 0) {
|
||||
$this->markTestSkipped('Redis extension version must be at least ' . \core\session\redis::REDIS_EXTENSION_MIN_VERSION .
|
||||
} else if (version_compare($version, \core\session\redis::REDIS_MIN_EXTENSION_VERSION) <= 0) {
|
||||
$this->markTestSkipped('Redis extension version must be at least ' . \core\session\redis::REDIS_MIN_EXTENSION_VERSION .
|
||||
': now running "' . $version . '"');
|
||||
}
|
||||
|
||||
|
@ -135,7 +136,7 @@ class session_redis_test extends \advanced_testcase {
|
|||
$this->assertSame('DATA', $sess->read('sess1'));
|
||||
$this->assertTrue($sess->write('sess1', 'DATA-new'));
|
||||
$this->assertTrue($sess->close());
|
||||
$this->assertSessionNoLocks();
|
||||
$this->assert_session_no_locks();
|
||||
}
|
||||
|
||||
public function test_compression_read_and_write_works(): void {
|
||||
|
@ -187,16 +188,16 @@ class session_redis_test extends \advanced_testcase {
|
|||
$sessblocked->read('sess1');
|
||||
$this->fail('Session lock must fail to be obtained.');
|
||||
} catch (\core\session\exception $e) {
|
||||
$this->assertStringContainsString("Unable to obtain lock for session id sess1", $e->getMessage());
|
||||
$this->assertStringContainsString("Unable to obtain lock for session id session_se", $e->getMessage());
|
||||
$this->assertStringContainsString('within 1 sec.', $e->getMessage());
|
||||
$this->assertStringContainsString('session lock timeout (1 min 10 secs) ', $e->getMessage());
|
||||
$this->assertStringContainsString('Cannot obtain session lock for sid: sess1', file_get_contents($errorlog));
|
||||
$this->assertStringContainsString('Cannot obtain session lock for sid: session_sess1', file_get_contents($errorlog));
|
||||
}
|
||||
|
||||
$this->assertTrue($sessblocked->close());
|
||||
$this->assertTrue($sess->write('sess1', 'DATA-new'));
|
||||
$this->assertTrue($sess->close());
|
||||
$this->assertSessionNoLocks();
|
||||
$this->assert_session_no_locks();
|
||||
}
|
||||
|
||||
public function test_session_is_destroyed_when_it_does_not_exist(): void {
|
||||
|
@ -205,7 +206,7 @@ class session_redis_test extends \advanced_testcase {
|
|||
$sess->set_requires_write_lock(true);
|
||||
$this->assertTrue($sess->open('Not used', 'Not used'));
|
||||
$this->assertTrue($sess->destroy('sess-destroy'));
|
||||
$this->assertSessionNoLocks();
|
||||
$this->assert_session_no_locks();
|
||||
}
|
||||
|
||||
public function test_session_is_destroyed_when_we_have_it_open(): void {
|
||||
|
@ -216,7 +217,7 @@ class session_redis_test extends \advanced_testcase {
|
|||
$this->assertSame('', $sess->read('sess-destroy'));
|
||||
$this->assertTrue($sess->destroy('sess-destroy'));
|
||||
$this->assertTrue($sess->close());
|
||||
$this->assertSessionNoLocks();
|
||||
$this->assert_session_no_locks();
|
||||
}
|
||||
|
||||
public function test_multiple_sessions_do_not_interfere_with_each_other(): void {
|
||||
|
@ -260,7 +261,7 @@ class session_redis_test extends \advanced_testcase {
|
|||
$this->assertTrue($sess2->close());
|
||||
|
||||
// Read the session again to ensure locking did what it should.
|
||||
$this->assertSessionNoLocks();
|
||||
$this->assert_session_no_locks();
|
||||
}
|
||||
|
||||
public function test_multiple_sessions_work_with_a_single_instance(): void {
|
||||
|
@ -279,7 +280,7 @@ class session_redis_test extends \advanced_testcase {
|
|||
$this->assertTrue($sess->destroy('sess2'));
|
||||
|
||||
$this->assertTrue($sess->close());
|
||||
$this->assertSessionNoLocks();
|
||||
$this->assert_session_no_locks();
|
||||
|
||||
$this->assertTrue($sess->close());
|
||||
}
|
||||
|
@ -299,12 +300,14 @@ class session_redis_test extends \advanced_testcase {
|
|||
$this->assertFalse($sess->session_exists('sess1'), 'Session should be destroyed.');
|
||||
}
|
||||
|
||||
public function test_kill_sessions_removes_the_session_from_redis(): void {
|
||||
public function test_destroy_removes_the_session_from_redis(): void {
|
||||
global $DB;
|
||||
|
||||
$sess = new \core\session\redis();
|
||||
$sess->init();
|
||||
|
||||
$mockhandler = new mock_handler();
|
||||
|
||||
$this->assertTrue($sess->open('Not used', 'Not used'));
|
||||
$this->assertTrue($sess->write('sess1', 'DATA'));
|
||||
$this->assertTrue($sess->write('sess2', 'DATA'));
|
||||
|
@ -316,22 +319,27 @@ class session_redis_test extends \advanced_testcase {
|
|||
$sessiondata->timemodified = time();
|
||||
|
||||
$sessiondata->sid = 'sess1';
|
||||
$DB->insert_record('sessions', $sessiondata);
|
||||
$mockhandler->add_test_session($sessiondata);
|
||||
$sessiondata->sid = 'sess2';
|
||||
$DB->insert_record('sessions', $sessiondata);
|
||||
$mockhandler->add_test_session($sessiondata);
|
||||
$sessiondata->sid = 'sess3';
|
||||
$DB->insert_record('sessions', $sessiondata);
|
||||
$mockhandler->add_test_session($sessiondata);
|
||||
|
||||
$this->assertNotEquals('', $sess->read('sess1'));
|
||||
$sess->kill_session('sess1');
|
||||
$sess->destroy('sess1');
|
||||
$this->assertEquals('', $sess->read('sess1'));
|
||||
|
||||
$this->assertEmpty($this->redis->keys($this->keyprefix.'sess1.lock'));
|
||||
|
||||
$sess->kill_all_sessions();
|
||||
$sess->destroy_all();
|
||||
|
||||
$this->assertEquals(3, $DB->count_records('sessions'), 'Moodle handles session database, plugin must not change it.');
|
||||
$this->assertSessionNoLocks();
|
||||
$mockhandler = new mock_handler();
|
||||
$this->assertEquals(
|
||||
3,
|
||||
$mockhandler->count_sessions(),
|
||||
'Moodle handles session database, plugin must not change it.',
|
||||
);
|
||||
$this->assert_session_no_locks();
|
||||
$this->assertEmpty($this->redis->keys($this->keyprefix.'*'), 'There should be no session data left.');
|
||||
}
|
||||
|
||||
|
@ -360,7 +368,7 @@ class session_redis_test extends \advanced_testcase {
|
|||
/**
|
||||
* Assert that we don't have any session locks in Redis.
|
||||
*/
|
||||
protected function assertSessionNoLocks() {
|
||||
protected function assert_session_no_locks(): void {
|
||||
$this->assertEmpty($this->redis->keys($this->keyprefix.'*.lock'));
|
||||
}
|
||||
|
||||
|
@ -375,4 +383,208 @@ class session_redis_test extends \advanced_testcase {
|
|||
|
||||
$this->assertEquals($CFG->session_redis_encrypt, $prop->getValue($sess));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the get maxlifetime method.
|
||||
*/
|
||||
public function test_get_maxlifetime(): void {
|
||||
global $CFG;
|
||||
|
||||
// Set the timeout to something known for the test.
|
||||
set_config('sessiontimeout', 100);
|
||||
|
||||
// Generate a test user.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Create a new redis session object.
|
||||
$session = new \core\session\redis();
|
||||
$session->init();
|
||||
|
||||
// The get_maxlifetime is private, so we need to use reflection to access it.
|
||||
$method = new \ReflectionMethod(\core\session\redis::class, 'get_maxlifetime');
|
||||
|
||||
// Test guest timeout, which should be longer.
|
||||
$result = $method->invoke($session, $CFG->siteguest);
|
||||
$this->assertEquals(500, $result);
|
||||
|
||||
// Test first access timeout.
|
||||
$result = $method->invoke($session, 0, true);
|
||||
$this->assertEquals(180, $result);
|
||||
|
||||
// Test with a real user.
|
||||
$result = $method->invoke($session, $user->id);
|
||||
$this->assertEquals(180, $result);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the add session method.
|
||||
*/
|
||||
public function test_add_session(): void {
|
||||
|
||||
// Set the timeout to something known for the test.
|
||||
set_config('sessiontimeout', 100);
|
||||
|
||||
// Generate a test user.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Create a new redis session object.
|
||||
$session = new \core\session\redis();
|
||||
$session->init();
|
||||
|
||||
// Create two sessions for the user.
|
||||
session_id('id1');
|
||||
$session1data = $session->add_session($user->id);
|
||||
session_id('id2');
|
||||
$session2data = $session->add_session($user->id);
|
||||
|
||||
$session1 = $session->get_session_by_sid('id1');
|
||||
$session2 = $session->get_session_by_sid('id2');
|
||||
|
||||
// Assert that the sessions were created and have expected data.
|
||||
$this->assertEqualsCanonicalizing((array)$session1data, (array)$session1);
|
||||
$this->assertEqualsCanonicalizing((array)$session2data, (array)$session2);
|
||||
|
||||
// Check that the session hash has a ttl set.
|
||||
$this->assertGreaterThan(-1, $this->redis->ttl($this->keyprefix . 'session_id1'));
|
||||
|
||||
// Check that the session ttl is less or equal to what we set it.
|
||||
$this->assertLessThanOrEqual(180, $this->redis->ttl($this->keyprefix . 'session_id1'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test writing session data.
|
||||
*/
|
||||
public function test_write(): void {
|
||||
// Set the timeout to something known for the test.
|
||||
set_config('sessiontimeout', 100);
|
||||
|
||||
// Generate a test user.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Create a new redis session object.
|
||||
$session = new \core\session\redis();
|
||||
$session->init();
|
||||
|
||||
// Create two sessions for the user.
|
||||
session_id('id1');
|
||||
$session->add_session($user->id);
|
||||
session_id('id2');
|
||||
$session->add_session($user->id);
|
||||
|
||||
$testdata = 'some test data';
|
||||
|
||||
// Write some data to the store.
|
||||
$result = $session->write('id2', $testdata);
|
||||
|
||||
// Check that the write was successful.
|
||||
$this->assertTrue($result);
|
||||
|
||||
// Check that the data was written to the store.
|
||||
$getdata = $this->redis->hget($this->keyprefix . 'session_id2', 'sessdata');
|
||||
$this->assertStringContainsString($testdata, $getdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading session data.
|
||||
*/
|
||||
public function test_read(): void {
|
||||
// Set the timeout to something known for the test.
|
||||
set_config('sessiontimeout', 100);
|
||||
|
||||
// Generate a test user.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Create a new redis session object.
|
||||
$session = new \core\session\redis();
|
||||
$session->init();
|
||||
|
||||
// Create two sessions for the user.
|
||||
session_id('id1');
|
||||
$session->add_session($user->id);
|
||||
session_id('id2');
|
||||
$session->add_session($user->id);
|
||||
|
||||
$testdata = 'some test data';
|
||||
|
||||
// Write some session data to the store.
|
||||
$session->write('id2', $testdata);
|
||||
|
||||
// Read the session data.
|
||||
$result = $session->read('id2');
|
||||
|
||||
// Check that the read was successful.
|
||||
$this->assertEquals($result, $testdata);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test updating a session.
|
||||
*/
|
||||
public function test_update_session(): void {
|
||||
// Set the timeout to something known for the test.
|
||||
set_config('sessiontimeout', 100);
|
||||
|
||||
// Generate a test user.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Create a new redis session object.
|
||||
$session = new \core\session\redis();
|
||||
$session->init();
|
||||
|
||||
// Create two sessions for the user.
|
||||
session_id('id1');
|
||||
$session->add_session($user->id);
|
||||
session_id('id2');
|
||||
$sessiondata = $session->add_session($user->id);
|
||||
|
||||
// Update the session data.
|
||||
$sessiondata->lastip = '8.8.8.8';
|
||||
$session->update_session($sessiondata);
|
||||
|
||||
// Check the value was updated.
|
||||
$updatedsession = $session->get_session_by_sid('id2');
|
||||
$this->assertEquals('8.8.8.8', $updatedsession->lastip);
|
||||
|
||||
// Test session update when userid is not set, should not error.
|
||||
unset($sessiondata->userid);
|
||||
$session->update_session($sessiondata);
|
||||
$this->assertDebuggingNotCalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test destroying a session by auth plugin.
|
||||
*/
|
||||
public function test_destroy_by_auth_plugin(): void {
|
||||
// Create test users.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user(['auth' => 'db']);
|
||||
|
||||
// Create a new redis session object.
|
||||
$session = new \core\session\redis();
|
||||
$session->init();
|
||||
|
||||
// Create sessions for the users.
|
||||
session_id('id1');
|
||||
$session1data = $session->add_session($user1->id);
|
||||
session_id('id2');
|
||||
$session2data = $session->add_session($user2->id);
|
||||
|
||||
$session1 = $session->get_session_by_sid('id1');
|
||||
$session2 = $session->get_session_by_sid('id2');
|
||||
|
||||
// Assert that the sessions were created and have expected data.
|
||||
$this->assertEqualsCanonicalizing((array) $session1data, (array) $session1);
|
||||
$this->assertEqualsCanonicalizing((array) $session2data, (array) $session2);
|
||||
|
||||
// Destroy the session by auth plugin.
|
||||
$session->destroy_by_auth_plugin('manual');
|
||||
|
||||
// Check that the session was destroyed.
|
||||
$this->assertFalse($session->session_exists('id1'));
|
||||
|
||||
// Check the session with db auth plugin was not destroyed.
|
||||
$this->assertTrue($session->session_exists('id2'));
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue