From 922d5b8f98d70c873001a70f2c04abd71543b77f Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 22 Nov 2016 17:51:53 +0300 Subject: [PATCH] tests for Spring session integration #452 --- redisson/pom.xml | 37 +++ .../org/redisson/spring/session/Config.java | 21 ++ .../spring/session/ConfigTimeout.java | 21 ++ .../redisson/spring/session/Initializer.java | 13 + .../session/RedissonSessionManagerTest.java | 239 ++++++++++++++++++ .../spring/session/SessionEventsListener.java | 40 +++ .../redisson/spring/session/TestServlet.java | 96 +++++++ .../redisson/spring/session/TomcatServer.java | 61 +++++ 8 files changed, 528 insertions(+) create mode 100644 redisson/src/test/java/org/redisson/spring/session/Config.java create mode 100644 redisson/src/test/java/org/redisson/spring/session/ConfigTimeout.java create mode 100644 redisson/src/test/java/org/redisson/spring/session/Initializer.java create mode 100644 redisson/src/test/java/org/redisson/spring/session/RedissonSessionManagerTest.java create mode 100644 redisson/src/test/java/org/redisson/spring/session/SessionEventsListener.java create mode 100644 redisson/src/test/java/org/redisson/spring/session/TestServlet.java create mode 100644 redisson/src/test/java/org/redisson/spring/session/TomcatServer.java diff --git a/redisson/pom.xml b/redisson/pom.xml index 3e188f854cc..c4e6b2ade1b 100644 --- a/redisson/pom.xml +++ b/redisson/pom.xml @@ -113,6 +113,43 @@ test + + org.apache.tomcat.embed + tomcat-embed-core + 7.0.73 + test + + + org.apache.tomcat.embed + tomcat-embed-logging-juli + 7.0.73 + test + + + org.apache.tomcat.embed + tomcat-embed-jasper + 7.0.73 + test + + + org.apache.tomcat + tomcat-jasper + 7.0.73 + test + + + org.apache.httpcomponents + fluent-hc + 4.5.2 + test + + + org.springframework + spring-web + [3.1,) + test + + net.jpountz.lz4 lz4 diff --git a/redisson/src/test/java/org/redisson/spring/session/Config.java b/redisson/src/test/java/org/redisson/spring/session/Config.java new file mode 100644 index 00000000000..d8994e597b0 --- /dev/null +++ b/redisson/src/test/java/org/redisson/spring/session/Config.java @@ -0,0 +1,21 @@ +package org.redisson.spring.session; + +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.spring.session.config.EnableRedissonHttpSession; +import org.springframework.context.annotation.Bean; + +@EnableRedissonHttpSession +public class Config { + + @Bean + public RedissonClient redisson() { + return Redisson.create(); + } + + @Bean + public SessionEventsListener listener() { + return new SessionEventsListener(); + } + +} diff --git a/redisson/src/test/java/org/redisson/spring/session/ConfigTimeout.java b/redisson/src/test/java/org/redisson/spring/session/ConfigTimeout.java new file mode 100644 index 00000000000..e18e938678c --- /dev/null +++ b/redisson/src/test/java/org/redisson/spring/session/ConfigTimeout.java @@ -0,0 +1,21 @@ +package org.redisson.spring.session; + +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.spring.session.config.EnableRedissonHttpSession; +import org.springframework.context.annotation.Bean; + +@EnableRedissonHttpSession(maxInactiveIntervalInSeconds = 5) +public class ConfigTimeout { + + @Bean + public RedissonClient redisson() { + return Redisson.create(); + } + + @Bean + public SessionEventsListener listener() { + return new SessionEventsListener(); + } + +} diff --git a/redisson/src/test/java/org/redisson/spring/session/Initializer.java b/redisson/src/test/java/org/redisson/spring/session/Initializer.java new file mode 100644 index 00000000000..ec85970a90f --- /dev/null +++ b/redisson/src/test/java/org/redisson/spring/session/Initializer.java @@ -0,0 +1,13 @@ +package org.redisson.spring.session; + +import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; + +public class Initializer extends AbstractHttpSessionApplicationInitializer { + + public static Class CONFIG_CLASS = Config.class; + + public Initializer() { + super(CONFIG_CLASS); + } + +} diff --git a/redisson/src/test/java/org/redisson/spring/session/RedissonSessionManagerTest.java b/redisson/src/test/java/org/redisson/spring/session/RedissonSessionManagerTest.java new file mode 100644 index 00000000000..9f217cf2afb --- /dev/null +++ b/redisson/src/test/java/org/redisson/spring/session/RedissonSessionManagerTest.java @@ -0,0 +1,239 @@ +package org.redisson.spring.session; + +import java.io.IOException; + +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.fluent.Executor; +import org.apache.http.client.fluent.Request; +import org.apache.http.cookie.Cookie; +import org.apache.http.impl.client.BasicCookieStore; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.redisson.RedisRunner; +import org.redisson.RedisRunner.KEYSPACE_EVENTS_OPTIONS; +import org.redisson.RedissonRuntimeEnvironment; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +public class RedissonSessionManagerTest { + + private static RedisRunner.RedisProcess defaultRedisInstance; + + @AfterClass + public static void afterClass() throws IOException, InterruptedException { + if (!RedissonRuntimeEnvironment.isTravis) { + defaultRedisInstance.stop(); + } + } + + @BeforeClass + public static void beforeClass() throws IOException, InterruptedException { + if (!RedissonRuntimeEnvironment.isTravis) { + defaultRedisInstance = new RedisRunner() + .nosave() + .port(6379) + .randomDir() + .notifyKeyspaceEvents(KEYSPACE_EVENTS_OPTIONS.E, + KEYSPACE_EVENTS_OPTIONS.x, + KEYSPACE_EVENTS_OPTIONS.g) + .run(); + + } + } + + @Test + public void testSwitchServer() throws Exception { + // start the server at http://localhost:8080/myapp + TomcatServer server = new TomcatServer("myapp", 8080, "src/test/"); + server.start(); + + Executor executor = Executor.newInstance(); + BasicCookieStore cookieStore = new BasicCookieStore(); + executor.use(cookieStore); + + write(executor, "test", "1234"); + Cookie cookie = cookieStore.getCookies().get(0); + + Executor.closeIdleConnections(); + server.stop(); + + server = new TomcatServer("myapp", 8080, "src/test/"); + server.start(); + + executor = Executor.newInstance(); + cookieStore = new BasicCookieStore(); + cookieStore.addCookie(cookie); + executor.use(cookieStore); + read(executor, "test", "1234"); + remove(executor, "test", "null"); + + Executor.closeIdleConnections(); + server.stop(); + } + + + @Test + public void testWriteReadRemove() throws Exception { + // start the server at http://localhost:8080/myapp + TomcatServer server = new TomcatServer("myapp", 8080, "src/test/"); + server.start(); + + Executor executor = Executor.newInstance(); + + write(executor, "test", "1234"); + read(executor, "test", "1234"); + remove(executor, "test", "null"); + + Executor.closeIdleConnections(); + server.stop(); + } + + @Test + public void testRecreate() throws Exception { + // start the server at http://localhost:8080/myapp + TomcatServer server = new TomcatServer("myapp", 8080, "src/test/"); + server.start(); + + Executor executor = Executor.newInstance(); + + write(executor, "test", "1"); + recreate(executor, "test", "2"); + read(executor, "test", "2"); + + Executor.closeIdleConnections(); + server.stop(); + } + + @Test + public void testUpdate() throws Exception { + // start the server at http://localhost:8080/myapp + TomcatServer server = new TomcatServer("myapp", 8080, "src/test/"); + server.start(); + + Executor executor = Executor.newInstance(); + + write(executor, "test", "1"); + read(executor, "test", "1"); + write(executor, "test", "2"); + read(executor, "test", "2"); + + Executor.closeIdleConnections(); + server.stop(); + } + + @Test + public void testExpire() throws Exception { + Initializer.CONFIG_CLASS = ConfigTimeout.class; + // start the server at http://localhost:8080/myapp + TomcatServer server = new TomcatServer("myapp", 8080, "src/test/"); + server.start(); + WebApplicationContext wa = WebApplicationContextUtils.getRequiredWebApplicationContext(server.getServletContext()); + SessionEventsListener listener = wa.getBean(SessionEventsListener.class); + + Executor executor = Executor.newInstance(); + BasicCookieStore cookieStore = new BasicCookieStore(); + executor.use(cookieStore); + + write(executor, "test", "1234"); + Cookie cookie = cookieStore.getCookies().get(0); + + Assert.assertEquals(1, listener.getSessionCreatedEvents()); + Assert.assertEquals(0, listener.getSessionExpiredEvents()); + + Executor.closeIdleConnections(); + + Thread.sleep(6000); + + Assert.assertEquals(1, listener.getSessionCreatedEvents()); + Assert.assertEquals(1, listener.getSessionExpiredEvents()); + + executor = Executor.newInstance(); + cookieStore = new BasicCookieStore(); + cookieStore.addCookie(cookie); + executor.use(cookieStore); + read(executor, "test", "null"); + + Assert.assertEquals(2, listener.getSessionCreatedEvents()); + + write(executor, "test", "1234"); + Thread.sleep(3000); + read(executor, "test", "1234"); + Thread.sleep(3000); + Assert.assertEquals(1, listener.getSessionExpiredEvents()); + Thread.sleep(1000); + Assert.assertEquals(1, listener.getSessionExpiredEvents()); + Thread.sleep(3000); + Assert.assertEquals(2, listener.getSessionExpiredEvents()); + + Executor.closeIdleConnections(); + server.stop(); + } + + @Test + public void testInvalidate() throws Exception { + // start the server at http://localhost:8080/myapp + TomcatServer server = new TomcatServer("myapp", 8080, "src/test/"); + server.start(); + WebApplicationContext wa = WebApplicationContextUtils.getRequiredWebApplicationContext(server.getServletContext()); + SessionEventsListener listener = wa.getBean(SessionEventsListener.class); + + Executor executor = Executor.newInstance(); + BasicCookieStore cookieStore = new BasicCookieStore(); + executor.use(cookieStore); + + write(executor, "test", "1234"); + Cookie cookie = cookieStore.getCookies().get(0); + + Assert.assertEquals(1, listener.getSessionCreatedEvents()); + Assert.assertEquals(0, listener.getSessionDeletedEvents()); + + invalidate(executor); + + Assert.assertEquals(1, listener.getSessionCreatedEvents()); + Assert.assertEquals(1, listener.getSessionDeletedEvents()); + + Executor.closeIdleConnections(); + + executor = Executor.newInstance(); + cookieStore = new BasicCookieStore(); + cookieStore.addCookie(cookie); + executor.use(cookieStore); + read(executor, "test", "null"); + + Executor.closeIdleConnections(); + server.stop(); + } + + private void write(Executor executor, String key, String value) throws IOException, ClientProtocolException { + String url = "http://localhost:8080/myapp/write?key=" + key + "&value=" + value; + String response = executor.execute(Request.Get(url)).returnContent().asString(); + Assert.assertEquals("OK", response); + } + + private void read(Executor executor, String key, String value) throws IOException, ClientProtocolException { + String url = "http://localhost:8080/myapp/read?key=" + key; + String response = executor.execute(Request.Get(url)).returnContent().asString(); + Assert.assertEquals(value, response); + } + + private void remove(Executor executor, String key, String value) throws IOException, ClientProtocolException { + String url = "http://localhost:8080/myapp/remove?key=" + key; + String response = executor.execute(Request.Get(url)).returnContent().asString(); + Assert.assertEquals(value, response); + } + + private void invalidate(Executor executor) throws IOException, ClientProtocolException { + String url = "http://localhost:8080/myapp/invalidate"; + String response = executor.execute(Request.Get(url)).returnContent().asString(); + Assert.assertEquals("OK", response); + } + + private void recreate(Executor executor, String key, String value) throws IOException, ClientProtocolException { + String url = "http://localhost:8080/myapp/recreate?key=" + key + "&value=" + value; + String response = executor.execute(Request.Get(url)).returnContent().asString(); + Assert.assertEquals("OK", response); + } + +} diff --git a/redisson/src/test/java/org/redisson/spring/session/SessionEventsListener.java b/redisson/src/test/java/org/redisson/spring/session/SessionEventsListener.java new file mode 100644 index 00000000000..549b7b89f57 --- /dev/null +++ b/redisson/src/test/java/org/redisson/spring/session/SessionEventsListener.java @@ -0,0 +1,40 @@ +package org.redisson.spring.session; + +import org.springframework.context.ApplicationListener; +import org.springframework.session.events.AbstractSessionEvent; +import org.springframework.session.events.SessionCreatedEvent; +import org.springframework.session.events.SessionDeletedEvent; +import org.springframework.session.events.SessionExpiredEvent; + +public class SessionEventsListener implements ApplicationListener { + + private int sessionCreatedEvents; + private int sessionDeletedEvents; + private int sessionExpiredEvents; + + @Override + public void onApplicationEvent(AbstractSessionEvent event) { + if (event instanceof SessionCreatedEvent) { + sessionCreatedEvents++; + } + if (event instanceof SessionDeletedEvent) { + sessionDeletedEvents++; + } + if (event instanceof SessionExpiredEvent) { + sessionExpiredEvents++; + } + } + + public int getSessionCreatedEvents() { + return sessionCreatedEvents; + } + + public int getSessionDeletedEvents() { + return sessionDeletedEvents; + } + + public int getSessionExpiredEvents() { + return sessionExpiredEvents; + } + +} diff --git a/redisson/src/test/java/org/redisson/spring/session/TestServlet.java b/redisson/src/test/java/org/redisson/spring/session/TestServlet.java new file mode 100644 index 00000000000..a011e9f2413 --- /dev/null +++ b/redisson/src/test/java/org/redisson/spring/session/TestServlet.java @@ -0,0 +1,96 @@ +package org.redisson.spring.session; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebServlet(name = "/testServlet", urlPatterns = "/*") +public class TestServlet extends HttpServlet { + + private static final long serialVersionUID = 1243830648280853203L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + HttpSession session = req.getSession(); + + if (req.getPathInfo().equals("/write")) { + String[] params = req.getQueryString().split("&"); + String key = null; + String value = null; + for (String param : params) { + String[] paramLine = param.split("="); + String keyParam = paramLine[0]; + String valueParam = paramLine[1]; + + if ("key".equals(keyParam)) { + key = valueParam; + } + if ("value".equals(keyParam)) { + value = valueParam; + } + } + session.setAttribute(key, value); + + resp.getWriter().print("OK"); + } else if (req.getPathInfo().equals("/read")) { + String[] params = req.getQueryString().split("&"); + String key = null; + for (String param : params) { + String[] line = param.split("="); + String keyParam = line[0]; + if ("key".equals(keyParam)) { + key = line[1]; + } + } + + Object attr = session.getAttribute(key); + resp.getWriter().print(attr); + } else if (req.getPathInfo().equals("/remove")) { + String[] params = req.getQueryString().split("&"); + String key = null; + for (String param : params) { + String[] line = param.split("="); + String keyParam = line[0]; + if ("key".equals(keyParam)) { + key = line[1]; + } + } + + session.removeAttribute(key); + resp.getWriter().print(String.valueOf(session.getAttribute(key))); + } else if (req.getPathInfo().equals("/invalidate")) { + session.invalidate(); + + resp.getWriter().print("OK"); + } else if (req.getPathInfo().equals("/recreate")) { + session.invalidate(); + + session = req.getSession(); + + String[] params = req.getQueryString().split("&"); + String key = null; + String value = null; + for (String param : params) { + String[] paramLine = param.split("="); + String keyParam = paramLine[0]; + String valueParam = paramLine[1]; + + if ("key".equals(keyParam)) { + key = valueParam; + } + if ("value".equals(keyParam)) { + value = valueParam; + } + } + session.setAttribute(key, value); + + resp.getWriter().print("OK"); + } + } + +} diff --git a/redisson/src/test/java/org/redisson/spring/session/TomcatServer.java b/redisson/src/test/java/org/redisson/spring/session/TomcatServer.java new file mode 100644 index 00000000000..68c1d3a0445 --- /dev/null +++ b/redisson/src/test/java/org/redisson/spring/session/TomcatServer.java @@ -0,0 +1,61 @@ +package org.redisson.spring.session; + +import java.io.File; +import java.net.MalformedURLException; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import org.apache.catalina.LifecycleException; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.startup.Tomcat; +import org.apache.naming.resources.VirtualDirContext; + +public class TomcatServer { + + private Tomcat tomcat = new Tomcat(); + private StandardContext ctx; + + public TomcatServer(String contextPath, int port, String appBase) throws MalformedURLException, ServletException { + if(contextPath == null || appBase == null || appBase.length() == 0) { + throw new IllegalArgumentException("Context path or appbase should not be null"); + } + if(!contextPath.startsWith("/")) { + contextPath = "/" + contextPath; + } + + tomcat.setBaseDir("."); // location where temp dir is created + tomcat.setPort(port); + tomcat.getHost().setAppBase("."); + + ctx = (StandardContext) tomcat.addWebapp(contextPath, appBase); + ctx.setDelegate(true); + + File additionWebInfClasses = new File("target/test-classes"); + VirtualDirContext resources = new VirtualDirContext(); + resources.setExtraResourcePaths("/WEB-INF/classes=" + additionWebInfClasses); + ctx.setResources(resources); + } + + /** + * Start the tomcat embedded server + */ + public void start() throws LifecycleException { + tomcat.start(); + } + + /** + * Stop the tomcat embedded server + */ + public void stop() throws LifecycleException { + tomcat.stop(); + tomcat.destroy(); + tomcat.getServer().await(); + } + + public ServletContext getServletContext() { + return ctx.getServletContext(); + } + + +} \ No newline at end of file