Jetty 9.4.x 3337 session serialization tests (#3409)
* Issue #3337 Session serialization tests Signed-off-by: Jan Bartel <janb@webtide.com>
This commit is contained in:
parent
c23303c05a
commit
11755539e8
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.server.session;
|
|||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* FileSessionDataStoreTest
|
||||
|
@ -68,7 +69,17 @@ public class FileSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
@Override
|
||||
public boolean checkSessionExists(SessionData data) throws Exception
|
||||
{
|
||||
return (FileTestHelper.getFile(data.getId()) != null);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader (_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return (FileTestHelper.getFile(data.getId()) != null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,7 +88,29 @@ public class FileSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
@Override
|
||||
public boolean checkSessionPersisted(SessionData data) throws Exception
|
||||
{
|
||||
return FileTestHelper.checkSessionPersisted(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader (_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return FileTestHelper.checkSessionPersisted(data);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void testStoreSession() throws Exception
|
||||
{
|
||||
super.testStoreSession();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -96,7 +96,16 @@ public class GCloudSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
@Override
|
||||
public boolean checkSessionPersisted(SessionData data) throws Exception
|
||||
{
|
||||
return __testSupport.checkSessionPersisted(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader (_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return __testSupport.checkSessionPersisted(data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -152,6 +152,15 @@ public class HazelcastSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
@Override
|
||||
public boolean checkSessionPersisted(SessionData data) throws Exception
|
||||
{
|
||||
return _testHelper.checkSessionPersisted(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader (_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return _testHelper.checkSessionPersisted(data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,7 +152,16 @@ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
@Override
|
||||
public boolean checkSessionPersisted(SessionData data) throws Exception
|
||||
{
|
||||
return __testSupport.checkSessionPersisted(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader (_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return __testSupport.checkSessionPersisted(data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -96,7 +96,16 @@ public class RemoteInfinispanSessionDataStoreTest extends AbstractSessionDataSto
|
|||
@Override
|
||||
public boolean checkSessionPersisted(SessionData data) throws Exception
|
||||
{
|
||||
return __testSupport.checkSessionPersisted(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader (_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return __testSupport.checkSessionPersisted(data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -89,7 +89,17 @@ public class JDBCSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
@Override
|
||||
public boolean checkSessionPersisted(SessionData data) throws Exception
|
||||
{
|
||||
return JdbcTestHelper.checkSessionPersisted(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader (_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return JdbcTestHelper.checkSessionPersisted(data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -92,7 +92,16 @@ public class MongoSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
@Override
|
||||
public boolean checkSessionPersisted(SessionData data) throws Exception
|
||||
{
|
||||
return MongoTestHelper.checkSessionPersisted(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader (_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return MongoTestHelper.checkSessionPersisted(data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ public class MongoTestHelper
|
|||
try
|
||||
{
|
||||
_mongoClient =
|
||||
new MongoClient( System.getProperty( "embedmongo.host" ), Integer.getInteger( "embedmongoPort" ) );
|
||||
new MongoClient( System.getProperty( "embedmongo.host" ), Integer.getInteger( "embedmongoPort" ) );
|
||||
}
|
||||
catch ( UnknownHostException e )
|
||||
{
|
||||
|
|
|
@ -28,13 +28,20 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
|||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
|
@ -54,6 +61,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
public static final long ANCIENT_TIMESTAMP = 100L;
|
||||
public static final long RECENT_TIMESTAMP = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(3*GRACE_PERIOD_SEC);
|
||||
|
||||
protected URLClassLoader _contextClassLoader;
|
||||
|
||||
|
||||
|
||||
|
@ -70,31 +78,86 @@ public abstract class AbstractSessionDataStoreTest
|
|||
|
||||
|
||||
/**
|
||||
* Test that the store can persist a session.
|
||||
* Test that the store can persist a session. The session uses an attribute
|
||||
* class that is only known to the webapp classloader. This tests that
|
||||
* we use the webapp loader when we serialize the session data (ie save the session).
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testStoreSession() throws Exception
|
||||
{
|
||||
//Use a class that would only be known to the webapp classloader
|
||||
InputStream foostream = Thread.currentThread().getContextClassLoader().getResourceAsStream("Foo.clazz");
|
||||
File foodir = new File (MavenTestingUtils.getTargetDir(), "foo");
|
||||
foodir.mkdirs();
|
||||
File fooclass = new File (foodir, "Foo.class");
|
||||
IO.copy(foostream, new FileOutputStream(fooclass));
|
||||
|
||||
assertTrue(fooclass.exists());
|
||||
assertTrue(fooclass.length() != 0);
|
||||
|
||||
URL[] foodirUrls = new URL[]{foodir.toURI().toURL()};
|
||||
_contextClassLoader = new URLClassLoader(foodirUrls, Thread.currentThread().getContextClassLoader());
|
||||
|
||||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setContextPath("/test");
|
||||
//use the classloader with the special class in it
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
|
||||
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();
|
||||
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
SessionData data = null;
|
||||
try
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(_contextClassLoader);
|
||||
Class fooclazz = Class.forName("Foo", true, _contextClassLoader);
|
||||
//create a session
|
||||
long now = System.currentTimeMillis();
|
||||
data = store.newSessionData("1234", 100, now, now-1, -1);//never expires
|
||||
data.setLastNode(sessionContext.getWorkerName());
|
||||
|
||||
//Make an attribute that uses the class only known to the webapp classloader
|
||||
data.setAttribute("a", fooclazz.getConstructor(null).newInstance());
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
|
||||
//store the session, using a different thread to ensure
|
||||
//that the thread is adorned with the webapp classloader
|
||||
//before serialization
|
||||
final SessionData finalData = data;
|
||||
|
||||
//create a session
|
||||
long now = System.currentTimeMillis();
|
||||
SessionData data = store.newSessionData("1234", 100, now, now-1, -1);//never expires
|
||||
data.setAttribute("a", "b");
|
||||
data.setLastNode(sessionContext.getWorkerName());
|
||||
|
||||
store.store("1234", data);
|
||||
Runnable r = new Runnable()
|
||||
{
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
store.store("1234", finalData);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
fail(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread t = new Thread(r, "saver");
|
||||
t.start();
|
||||
t.join(TimeUnit.SECONDS.toMillis(10));
|
||||
|
||||
//check that the store contains all of the session data
|
||||
assertTrue(checkSessionPersisted(data));
|
||||
|
@ -148,33 +211,31 @@ public abstract class AbstractSessionDataStoreTest
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testStoreObjectAttributes() 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();
|
||||
|
||||
//create a session
|
||||
SessionData data = store.newSessionData("1234", 100, 200, 199, -1);//never expires
|
||||
TestFoo testFoo = new TestFoo();
|
||||
testFoo.setInt(33);
|
||||
FooInvocationHandler handler = new FooInvocationHandler(testFoo);
|
||||
Foo foo = (Foo)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {Foo.class}, handler);
|
||||
data.setAttribute("foo", foo);
|
||||
data.setLastNode(sessionContext.getWorkerName());
|
||||
|
||||
//test that it can be persisted
|
||||
store.store("1234", data);
|
||||
checkSessionPersisted(data);
|
||||
}
|
||||
/*
|
||||
* @Test public void testStoreObjectAttributes() 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();
|
||||
*
|
||||
* //create a session SessionData data = store.newSessionData("1234", 100,
|
||||
* 200, 199, -1);//never expires TestFoo testFoo = new TestFoo();
|
||||
* testFoo.setInt(33); FooInvocationHandler handler = new
|
||||
* FooInvocationHandler(testFoo); Foo foo =
|
||||
* (Foo)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(
|
||||
* ), new Class[] {Foo.class}, handler); data.setAttribute("foo", foo);
|
||||
* data.setLastNode(sessionContext.getWorkerName());
|
||||
*
|
||||
* //test that it can be persisted store.store("1234", data);
|
||||
* checkSessionPersisted(data); }
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test that we can load a persisted session.
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
public class Foo implements java.io.Serializable
|
||||
{
|
||||
int myI = 0;
|
||||
|
||||
public Foo()
|
||||
{
|
||||
}
|
||||
|
||||
public void setI(int i)
|
||||
{
|
||||
myI = i;
|
||||
}
|
||||
|
||||
public int getI()
|
||||
{
|
||||
return myI;
|
||||
}
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return ((Foo)o).getI() == myI;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue