Merged branch 'jetty-9.4.x' into 'jetty-10.0.x'.
This commit is contained in:
commit
414a1dd396
|
@ -709,21 +709,15 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
statement.setLong(10, data.getExpiry());
|
||||
statement.setLong(11, data.getMaxInactiveMs());
|
||||
|
||||
if (!data.getAllAttributes().isEmpty())
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos))
|
||||
{
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos))
|
||||
{
|
||||
SessionData.serializeAttributes(data, oos);
|
||||
byte[] bytes = baos.toByteArray();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
statement.setBinaryStream(12, EMPTY, 0);
|
||||
SessionData.serializeAttributes(data, oos);
|
||||
byte[] bytes = baos.toByteArray();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
|
||||
}
|
||||
|
||||
statement.executeUpdate();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Inserted session " + data);
|
||||
|
@ -746,23 +740,17 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
statement.setLong(5, data.getExpiry());
|
||||
statement.setLong(6, data.getMaxInactiveMs());
|
||||
|
||||
if (!data.getAllAttributes().isEmpty())
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos))
|
||||
{
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos))
|
||||
SessionData.serializeAttributes(data, oos);
|
||||
byte[] bytes = baos.toByteArray();
|
||||
try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes))
|
||||
{
|
||||
SessionData.serializeAttributes(data, oos);
|
||||
byte[] bytes = baos.toByteArray();
|
||||
try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes))
|
||||
{
|
||||
statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob
|
||||
}
|
||||
statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
statement.setBinaryStream(7, EMPTY, 0);
|
||||
}
|
||||
|
||||
statement.executeUpdate();
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
|
|
|
@ -196,14 +196,14 @@ public class Module implements Comparable<Module>
|
|||
process(basehome);
|
||||
}
|
||||
|
||||
public static boolean isRequiredDependency(String depends)
|
||||
public static boolean isConditionalDependency(String depends)
|
||||
{
|
||||
return (depends != null) && (depends.charAt(0) != '?');
|
||||
return (depends != null) && (depends.charAt(0) == '?');
|
||||
}
|
||||
|
||||
public static String normalizeModuleName(String name)
|
||||
{
|
||||
if (!isRequiredDependency(name))
|
||||
if (isConditionalDependency(name))
|
||||
return name.substring(1);
|
||||
return name;
|
||||
}
|
||||
|
|
|
@ -136,10 +136,8 @@ public class Modules implements Iterable<Module>
|
|||
{
|
||||
parent = Module.normalizeModuleName(parent);
|
||||
System.out.printf(label, parent);
|
||||
if (!Module.isRequiredDependency(parent))
|
||||
{
|
||||
System.out.print(" [not-required]");
|
||||
}
|
||||
if (Module.isConditionalDependency(parent))
|
||||
System.out.print(" [conditional]");
|
||||
label = ", %s";
|
||||
}
|
||||
System.out.println();
|
||||
|
@ -420,7 +418,7 @@ public class Modules implements Iterable<Module>
|
|||
StartLog.debug("Enabled module [%s] depends on %s", module.getName(), module.getDepends());
|
||||
for (String dependsOnRaw : module.getDepends())
|
||||
{
|
||||
boolean isRequired = Module.isRequiredDependency(dependsOnRaw);
|
||||
boolean isConditional = Module.isConditionalDependency(dependsOnRaw);
|
||||
// Final to allow lambda's below to use name
|
||||
final String dependentModule = Module.normalizeModuleName(dependsOnRaw);
|
||||
|
||||
|
@ -436,7 +434,7 @@ public class Modules implements Iterable<Module>
|
|||
if (dependentModule.contains("/"))
|
||||
{
|
||||
Path file = _baseHome.getPath("modules/" + dependentModule + ".mod");
|
||||
if (isRequired || Files.exists(file))
|
||||
if (!isConditional || Files.exists(file))
|
||||
{
|
||||
registerModule(file).expandDependencies(_args.getProperties());
|
||||
providers = _provided.get(dependentModule);
|
||||
|
@ -447,10 +445,10 @@ public class Modules implements Iterable<Module>
|
|||
continue;
|
||||
}
|
||||
}
|
||||
// is this a non-required module
|
||||
if (!isRequired)
|
||||
// is this a conditional module
|
||||
if (isConditional)
|
||||
{
|
||||
StartLog.debug("Skipping non-required module [%s]: doesn't exist", dependentModule);
|
||||
StartLog.debug("Skipping conditional module [%s]: it does not exist", dependentModule);
|
||||
continue;
|
||||
}
|
||||
// throw an exception (not a dynamic module and a required dependency)
|
||||
|
@ -570,7 +568,7 @@ public class Modules implements Iterable<Module>
|
|||
{
|
||||
// Check dependencies
|
||||
m.getDepends().stream()
|
||||
.filter(Module::isRequiredDependency)
|
||||
.filter(depends -> !Module.isConditionalDependency(depends))
|
||||
.forEach(d ->
|
||||
{
|
||||
Set<Module> providers = getAvailableProviders(d);
|
||||
|
|
|
@ -234,6 +234,7 @@ public class ModulesTest
|
|||
|
||||
// Collect active module list
|
||||
List<Module> active = modules.getEnabled();
|
||||
modules.checkEnabledModules();
|
||||
|
||||
// Assert names are correct, and in the right order
|
||||
List<String> expectedNames = new ArrayList<>();
|
||||
|
@ -282,6 +283,7 @@ public class ModulesTest
|
|||
|
||||
// Collect active module list
|
||||
List<Module> active = modules.getEnabled();
|
||||
modules.checkEnabledModules();
|
||||
|
||||
// Assert names are correct, and in the right order
|
||||
List<String> expectedNames = new ArrayList<>();
|
||||
|
@ -331,6 +333,7 @@ public class ModulesTest
|
|||
|
||||
// Collect active module list
|
||||
List<Module> active = modules.getEnabled();
|
||||
modules.checkEnabledModules();
|
||||
|
||||
// Assert names are correct, and in the right order
|
||||
List<String> expectedNames = new ArrayList<>();
|
||||
|
|
|
@ -49,19 +49,16 @@ public class JDBCSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
public void persistSession(SessionData data)
|
||||
throws Exception
|
||||
{
|
||||
JdbcTestHelper.insertSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(),
|
||||
data.getCreated(), data.getAccessed(), data.getLastAccessed(),
|
||||
data.getMaxInactiveMs(), data.getExpiry(), data.getCookieSet(),
|
||||
data.getLastSaved(), data.getAllAttributes());
|
||||
JdbcTestHelper.insertSession(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void persistUnreadableSession(SessionData data) throws Exception
|
||||
{
|
||||
JdbcTestHelper.insertSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(),
|
||||
JdbcTestHelper.insertUnreadableSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(),
|
||||
data.getCreated(), data.getAccessed(), data.getLastAccessed(),
|
||||
data.getMaxInactiveMs(), data.getExpiry(), data.getCookieSet(),
|
||||
data.getLastSaved(), null);
|
||||
data.getLastSaved());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -29,7 +29,6 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
|
@ -132,6 +131,35 @@ public class JdbcTestHelper
|
|||
sessionTableSchema.prepareTables();
|
||||
}
|
||||
|
||||
public static void dumpRow(ResultSet row) throws SQLException
|
||||
{
|
||||
if (row != null)
|
||||
{
|
||||
String id = row.getString(ID_COL);
|
||||
long created = row.getLong(CREATE_COL);
|
||||
long accessed = row.getLong(ACCESS_COL);
|
||||
long lastAccessed = row.getLong(LAST_ACCESS_COL);
|
||||
long maxIdle = row.getLong(MAX_IDLE_COL);
|
||||
long cookieSet = row.getLong(COOKIE_COL);
|
||||
String node = row.getString(LAST_NODE_COL);
|
||||
long expires = row.getLong(EXPIRY_COL);
|
||||
long lastSaved = row.getLong(LAST_SAVE_COL);
|
||||
String context = row.getString(CONTEXT_COL);
|
||||
Blob blob = row.getBlob(MAP_COL);
|
||||
|
||||
String dump = "id=" + id +
|
||||
" ctxt=" + context +
|
||||
" node=" + node +
|
||||
" exp=" + expires +
|
||||
" acc=" + accessed +
|
||||
" lacc=" + lastAccessed +
|
||||
" ck=" + cookieSet +
|
||||
" lsv=" + lastSaved +
|
||||
" blob length=" + blob.length();
|
||||
System.err.println(dump);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean existsInSessionTable(String id, boolean verbose)
|
||||
throws Exception
|
||||
{
|
||||
|
@ -151,6 +179,7 @@ public class JdbcTestHelper
|
|||
while (result.next())
|
||||
{
|
||||
results = true;
|
||||
dumpRow(result);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
@ -234,40 +263,52 @@ public class JdbcTestHelper
|
|||
return true;
|
||||
}
|
||||
|
||||
public static void insertSession(String id, String contextPath, String vhost)
|
||||
throws Exception
|
||||
public static void insertSession(SessionData data) throws Exception
|
||||
{
|
||||
|
||||
Class.forName(DRIVER_CLASS);
|
||||
try (Connection con = DriverManager.getConnection(DEFAULT_CONNECTION_URL);)
|
||||
{
|
||||
PreparedStatement statement = con.prepareStatement("insert into " + TABLE +
|
||||
" (" + ID_COL + ", " + CONTEXT_COL + ", virtualHost, " + LAST_NODE_COL +
|
||||
", " + ACCESS_COL + ", " + LAST_ACCESS_COL + ", " + CREATE_COL + ", " + COOKIE_COL +
|
||||
", " + LAST_SAVE_COL + ", " + EXPIRY_COL + " " + ") " +
|
||||
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
", " + LAST_SAVE_COL + ", " + EXPIRY_COL + ", " + MAX_IDLE_COL + "," + MAP_COL + " ) " +
|
||||
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
statement.setString(1, id);
|
||||
statement.setString(2, contextPath);
|
||||
statement.setString(3, vhost);
|
||||
statement.setString(4, "0");
|
||||
statement.setString(1, data.getId());
|
||||
statement.setString(2, data.getContextPath());
|
||||
statement.setString(3, data.getVhost());
|
||||
statement.setString(4, data.getLastNode());
|
||||
|
||||
statement.setLong(5, System.currentTimeMillis());
|
||||
statement.setLong(6, System.currentTimeMillis());
|
||||
statement.setLong(7, System.currentTimeMillis());
|
||||
statement.setLong(8, System.currentTimeMillis());
|
||||
statement.setLong(5, data.getAccessed());
|
||||
statement.setLong(6, data.getLastAccessed());
|
||||
statement.setLong(7, data.getCreated());
|
||||
statement.setLong(8, data.getCookieSet());
|
||||
|
||||
statement.setLong(9, System.currentTimeMillis());
|
||||
statement.setLong(10, System.currentTimeMillis());
|
||||
statement.setLong(9, data.getLastSaved());
|
||||
statement.setLong(10, data.getExpiry());
|
||||
statement.setLong(11, data.getMaxInactiveMs());
|
||||
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);)
|
||||
{
|
||||
SessionData.serializeAttributes(data, oos);
|
||||
byte[] bytes = baos.toByteArray();
|
||||
|
||||
try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);)
|
||||
{
|
||||
statement.setBinaryStream(12, bais, bytes.length);
|
||||
}
|
||||
}
|
||||
statement.execute();
|
||||
assertEquals(1, statement.getUpdateCount());
|
||||
}
|
||||
}
|
||||
|
||||
public static void insertSession(String id, String contextPath, String vhost,
|
||||
public static void insertUnreadableSession(String id, String contextPath, String vhost,
|
||||
String lastNode, long created, long accessed,
|
||||
long lastAccessed, long maxIdle, long expiry,
|
||||
long cookieSet, long lastSaved, Map<String, Object> attributes)
|
||||
long cookieSet, long lastSaved)
|
||||
throws Exception
|
||||
{
|
||||
Class.forName(DRIVER_CLASS);
|
||||
|
@ -293,23 +334,7 @@ public class JdbcTestHelper
|
|||
statement.setLong(10, expiry);
|
||||
statement.setLong(11, maxIdle);
|
||||
|
||||
if (attributes != null)
|
||||
{
|
||||
SessionData tmp = new SessionData(id, contextPath, vhost, created, accessed, lastAccessed, maxIdle);
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);)
|
||||
{
|
||||
SessionData.serializeAttributes(tmp, oos);
|
||||
byte[] bytes = baos.toByteArray();
|
||||
|
||||
try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);)
|
||||
{
|
||||
statement.setBinaryStream(12, bais, bytes.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
statement.setBinaryStream(12, new ByteArrayInputStream("".getBytes()), 0);
|
||||
statement.setBinaryStream(12, new ByteArrayInputStream("".getBytes()), 0);
|
||||
|
||||
statement.execute();
|
||||
assertEquals(1, statement.getUpdateCount());
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.server.session;
|
|||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
|
@ -67,6 +68,46 @@ public class SessionTableSchemaTest
|
|||
JdbcTestHelper.shutdown(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This inserts a session into the db that does not set the session attributes MAP column. As such
|
||||
* this results in a row that is unreadable by the JDBCSessionDataStore, but is readable by using
|
||||
* only jdbc api, which is what this test does.
|
||||
*
|
||||
* @param id id of session
|
||||
* @param contextPath the context path of the session
|
||||
* @param vhost the virtual host of the session
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void insertSessionWithoutAttributes(String id, String contextPath, String vhost)
|
||||
throws Exception
|
||||
{
|
||||
Class.forName(JdbcTestHelper.DRIVER_CLASS);
|
||||
try (Connection con = DriverManager.getConnection(JdbcTestHelper.DEFAULT_CONNECTION_URL);)
|
||||
{
|
||||
PreparedStatement statement = con.prepareStatement("insert into " + JdbcTestHelper.TABLE +
|
||||
" (" + JdbcTestHelper.ID_COL + ", " + JdbcTestHelper.CONTEXT_COL + ", virtualHost, " + JdbcTestHelper.LAST_NODE_COL +
|
||||
", " + JdbcTestHelper.ACCESS_COL + ", " + JdbcTestHelper.LAST_ACCESS_COL + ", " + JdbcTestHelper.CREATE_COL + ", " + JdbcTestHelper.COOKIE_COL +
|
||||
", " + JdbcTestHelper.LAST_SAVE_COL + ", " + JdbcTestHelper.EXPIRY_COL + " " + ") " +
|
||||
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
statement.setString(1, id);
|
||||
statement.setString(2, contextPath);
|
||||
statement.setString(3, vhost);
|
||||
statement.setString(4, "0");
|
||||
|
||||
statement.setLong(5, System.currentTimeMillis());
|
||||
statement.setLong(6, System.currentTimeMillis());
|
||||
statement.setLong(7, System.currentTimeMillis());
|
||||
statement.setLong(8, System.currentTimeMillis());
|
||||
|
||||
statement.setLong(9, System.currentTimeMillis());
|
||||
statement.setLong(10, System.currentTimeMillis());
|
||||
|
||||
statement.execute();
|
||||
assertEquals(1, statement.getUpdateCount());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoad()
|
||||
throws Exception
|
||||
|
@ -76,7 +117,7 @@ public class SessionTableSchemaTest
|
|||
_tableSchema.prepareTables();
|
||||
|
||||
//insert a fake session at the root context
|
||||
JdbcTestHelper.insertSession("1234", "/", "0.0.0.0");
|
||||
insertSessionWithoutAttributes("1234", "/", "0.0.0.0");
|
||||
|
||||
//test if it can be seen
|
||||
try (Connection con = _da.getConnection())
|
||||
|
@ -101,7 +142,7 @@ public class SessionTableSchemaTest
|
|||
_tableSchema.prepareTables();
|
||||
|
||||
//insert a fake session at the root context
|
||||
JdbcTestHelper.insertSession("1234", "/", "0.0.0.0");
|
||||
insertSessionWithoutAttributes("1234", "/", "0.0.0.0");
|
||||
|
||||
//test if it can be seen
|
||||
try (Connection con = _da.getConnection())
|
||||
|
@ -125,7 +166,7 @@ public class SessionTableSchemaTest
|
|||
_tableSchema.prepareTables();
|
||||
|
||||
//insert a fake session at the root context
|
||||
JdbcTestHelper.insertSession("1234", "/", "0.0.0.0");
|
||||
insertSessionWithoutAttributes("1234", "/", "0.0.0.0");
|
||||
|
||||
//test if it can be deleted
|
||||
try (Connection con = _da.getConnection())
|
||||
|
@ -149,7 +190,7 @@ public class SessionTableSchemaTest
|
|||
_tableSchema.prepareTables();
|
||||
|
||||
//insert a fake session at the root context
|
||||
JdbcTestHelper.insertSession("1234", "/", "0.0.0.0");
|
||||
insertSessionWithoutAttributes("1234", "/", "0.0.0.0");
|
||||
|
||||
try (Connection con = _da.getConnection())
|
||||
{
|
||||
|
@ -175,7 +216,7 @@ public class SessionTableSchemaTest
|
|||
_tableSchema.prepareTables();
|
||||
|
||||
//insert a fake session at the root context
|
||||
JdbcTestHelper.insertSession("1234", "/", "0.0.0.0");
|
||||
insertSessionWithoutAttributes("1234", "/", "0.0.0.0");
|
||||
|
||||
try (Connection con = _da.getConnection())
|
||||
{
|
||||
|
@ -200,7 +241,7 @@ public class SessionTableSchemaTest
|
|||
_tableSchema.prepareTables();
|
||||
|
||||
//insert a fake session at the root context
|
||||
JdbcTestHelper.insertSession("1234", "/", "0.0.0.0");
|
||||
insertSessionWithoutAttributes("1234", "/", "0.0.0.0");
|
||||
|
||||
try (Connection con = _da.getConnection())
|
||||
{
|
||||
|
|
|
@ -428,6 +428,71 @@ public abstract class AbstractSessionDataStoreTest
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test that a session containing no attributes can be stored and re-read
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testEmptyLoadSession() throws Exception
|
||||
{
|
||||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
|
||||
store.initialize(sessionContext);
|
||||
store.start();
|
||||
|
||||
//persist a session that has no attributes
|
||||
long now = System.currentTimeMillis();
|
||||
SessionData data = store.newSessionData("222", 100, now, now - 1, -1);
|
||||
data.setLastNode(sessionContext.getWorkerName());
|
||||
//persistSession(data);
|
||||
store.store("222", data);
|
||||
|
||||
//test that we can retrieve it
|
||||
SessionData savedSession = store.load("222");
|
||||
assertEquals(0, savedSession.getAllAttributes().size());
|
||||
}
|
||||
|
||||
//Test that a session that had attributes can be modified to contain no
|
||||
//attributes, and still read
|
||||
@Test
|
||||
public void testModifyEmptyLoadSession() throws Exception
|
||||
{
|
||||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
|
||||
store.initialize(sessionContext);
|
||||
store.start();
|
||||
|
||||
//persist a session that has attributes
|
||||
long now = System.currentTimeMillis();
|
||||
SessionData data = store.newSessionData("222", 100, now, now - 1, -1);
|
||||
data.setAttribute("foo", "bar");
|
||||
data.setLastNode(sessionContext.getWorkerName());
|
||||
store.store("222", data);
|
||||
|
||||
//test that we can retrieve it
|
||||
SessionData savedSession = store.load("222");
|
||||
assertEquals("bar", savedSession.getAttribute("foo"));
|
||||
|
||||
//now modify so there are no attributes
|
||||
savedSession.setAttribute("foo", null);
|
||||
store.store("222", savedSession);
|
||||
|
||||
//check its still readable
|
||||
savedSession = store.load("222");
|
||||
assertEquals(0, savedSession.getAllAttributes().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can delete a persisted session.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue