/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.modules.session.internal.filter;
import static org.junit.Assert.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import org.apache.geode.modules.session.filter.SessionCachingFilter;
import com.mockrunner.mock.web.MockHttpServletRequest;
import com.mockrunner.mock.web.MockHttpServletResponse;
import com.mockrunner.mock.web.MockHttpSession;
import com.mockrunner.servlet.BasicServletTestCaseAdapter;
import org.junit.Ignore;
import org.junit.Test;
/**
* This servlet tests the effects of the downstream SessionCachingFilter filter. When these tests
* are performed, the filter would already have taken effect.
*/
public abstract class CommonTests extends BasicServletTestCaseAdapter {
protected static final String CONTEXT_PATH = "/test";
@Test
public void testGetSession1() throws Exception {
doFilter();
HttpSession session1 = ((HttpServletRequest) getFilteredRequest()).getSession();
HttpSession session2 = ((HttpServletRequest) getFilteredRequest()).getSession();
assertSame("Session should be the same", session1, session2);
}
@Test
public void testGetSession2() throws Exception {
doFilter();
HttpSession session1 = ((HttpServletRequest) getFilteredRequest()).getSession();
MockHttpServletResponse response = getWebMockObjectFactory().getMockResponse();
Cookie cookie = (Cookie) response.getCookies().get(0);
getWebMockObjectFactory().getMockRequest().addCookie(cookie);
doFilter();
HttpSession session2 = ((HttpServletRequest) getFilteredRequest()).getSession();
assertEquals("Session objects across requests should be the same", session1, session2);
}
@Test
public void testGetAttributeRequest1() throws Exception {
doFilter();
getFilteredRequest().setAttribute("foo", "bar");
assertEquals("bar", getFilteredRequest().getAttribute("foo"));
assertNull("Unknown attribute should be null", getFilteredRequest().getAttribute("baz"));
}
@Test
public void testGetAttributeRequest2() throws Exception {
// Setup
CallbackServlet s = (CallbackServlet) getServlet();
s.setCallback(new Callback() {
@Override
public void call(HttpServletRequest request, HttpServletResponse response) {
request.setAttribute("foo", "bar");
}
});
doFilter();
assertEquals("bar", getFilteredRequest().getAttribute("foo"));
assertNull("Unknown attribute should be null", getFilteredRequest().getAttribute("baz"));
}
@Test
public void testGetAttributeSession1() throws Exception {
doFilter();
((HttpServletRequest) getFilteredRequest()).getSession().setAttribute("foo", "bar");
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
assertEquals("bar", request.getSession().getAttribute("foo"));
}
/**
* Are attributes preserved across client requests?
*/
@Test
public void testGetAttributeSession2() throws Exception {
doFilter();
((HttpServletRequest) getFilteredRequest()).getSession().setAttribute("foo", "bar");
MockHttpServletResponse response = getWebMockObjectFactory().getMockResponse();
Cookie cookie = (Cookie) response.getCookies().get(0);
getWebMockObjectFactory().getMockRequest().addCookie(cookie);
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
assertEquals("bar", request.getSession().getAttribute("foo"));
}
/**
* Setting a session attribute to null should remove it
*/
@Test
public void testSetAttributeNullSession1() throws Exception {
// Setup
CallbackServlet s = (CallbackServlet) getServlet();
s.setCallback(new Callback() {
private boolean called = false;
@Override
public void call(HttpServletRequest request, HttpServletResponse response) {
if (called) {
request.getSession().setAttribute("foo", null);
} else {
request.getSession().setAttribute("foo", "bar");
called = true;
}
}
});
doFilter();
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
String attr = (String) session.getAttribute("foo");
assertNull("Attribute should be null but is " + attr, attr);
}
/**
* Test that various methods throw the appropriate exception when the session is invalid.
*/
@Test
public void testInvalidate1() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.getAttribute("foo");
fail("Session should be invalid and an exception should be thrown");
} catch (IllegalStateException iex) {
// Pass
}
}
@Test
public void testInvalidate2() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.getAttributeNames();
fail("Session should be invalid and an exception should be thrown");
} catch (IllegalStateException iex) {
// Pass
}
}
@Ignore(value = "until mockrunner 1.0.9 - see pull request #23")
public void testInvalidate3() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.getCreationTime();
fail("Session should be invalid and an exception should be thrown");
} catch (IllegalStateException iex) {
// Pass
}
}
@Test
public void testInvalidate4() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.getId();
} catch (Exception iex) {
fail("Exception should not be thrown");
}
}
@Test
public void testInvalidate5() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.getLastAccessedTime();
fail("Session should be invalid and an exception should be thrown");
} catch (IllegalStateException iex) {
// Pass
}
}
@Test
public void testInvalidate6() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.getMaxInactiveInterval();
} catch (Exception ex) {
fail("Exception should not be thrown");
}
}
@Test
public void testInvalidate7() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.getServletContext();
} catch (Exception ex) {
fail("Exception should not be thrown");
}
}
@Test
public void testInvalidate8() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.isNew();
fail("Session should be invalid and an exception should be thrown");
} catch (IllegalStateException iex) {
// Pass
}
}
@Test
public void testInvalidate9() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.removeAttribute("foo");
fail("Session should be invalid and an exception should be thrown");
} catch (IllegalStateException iex) {
// Pass
}
}
@Test
public void testInvalidate10() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.setAttribute("foo", "bar");
fail("Session should be invalid and an exception should be thrown");
} catch (IllegalStateException iex) {
// Pass
}
}
@Test
public void testInvalidate11() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
session.invalidate();
try {
session.setMaxInactiveInterval(1);
} catch (Exception ex) {
fail("Exception should not be thrown");
}
}
/**
* Test that Session Attribute events get triggered
*/
@Test
public void testSessionAttributeListener1() throws Exception {
AbstractListener listener = new HttpSessionAttributeListenerImpl();
RendezvousManager.registerListener(listener);
listener.setLatch(3);
doFilter();
// Ugh
MockHttpSession session =
(MockHttpSession) ((GemfireHttpSession) ((HttpServletRequest) getFilteredRequest())
.getSession()).getNativeSession();
session.addAttributeListener((HttpSessionAttributeListener) listener);
session.setAttribute("foo", "bar");
session.setAttribute("foo", "baz");
session.setAttribute("foo", null);
assertTrue("Event timeout", listener.await(1, TimeUnit.SECONDS));
assertEquals(ListenerEventType.SESSION_ATTRIBUTE_ADDED, listener.getEvents().get(0));
assertEquals(ListenerEventType.SESSION_ATTRIBUTE_REPLACED, listener.getEvents().get(1));
assertEquals(ListenerEventType.SESSION_ATTRIBUTE_REMOVED, listener.getEvents().get(2));
}
/**
* Test that both replace and remove events get triggered
*/
@Test
public void testHttpSessionBindingListener1() throws Exception {
doFilter();
HttpSession session = ((HttpServletRequest) getFilteredRequest()).getSession();
HttpSessionBindingListenerImpl listener1 = new HttpSessionBindingListenerImpl(2);
HttpSessionBindingListenerImpl listener2 = new HttpSessionBindingListenerImpl(2);
session.setAttribute("foo", listener1);
session.setAttribute("foo", listener2);
session.setAttribute("foo", null);
assertTrue("Event timeout", listener1.await(1, TimeUnit.SECONDS));
assertTrue("Event timeout", listener2.await(1, TimeUnit.SECONDS));
assertEquals("Event list size incorrect", 2, listener1.getEvents().size());
assertEquals("Event list size incorrect", 2, listener2.getEvents().size());
assertEquals(ListenerEventType.SESSION_VALUE_BOUND, listener1.getEvents().get(0));
assertEquals(ListenerEventType.SESSION_VALUE_UNBOUND, listener1.getEvents().get(1));
assertEquals(ListenerEventType.SESSION_VALUE_BOUND, listener2.getEvents().get(0));
assertEquals(ListenerEventType.SESSION_VALUE_UNBOUND, listener2.getEvents().get(1));
}
@Test
public void testGetId1() throws Exception {
doFilter();
assertNotNull("Session Id should not be null",
((HttpServletRequest) getFilteredRequest()).getSession().getId());
}
/**
* Test that multiple calls from the same client return the same session id
*/
@Test
public void testGetId2() throws Exception {
doFilter();
String sessionId = ((HttpServletRequest) getFilteredRequest()).getSession().getId();
MockHttpServletResponse response = getWebMockObjectFactory().getMockResponse();
Cookie cookie = (Cookie) response.getCookies().get(0);
getWebMockObjectFactory().getMockRequest().addCookie(cookie);
doFilter();
assertEquals("Session Ids should be the same", sessionId,
((HttpServletRequest) getFilteredRequest()).getSession().getId());
}
@Test
public void testGetCreationTime1() throws Exception {
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
assertTrue("Session should have a non-zero creation time",
request.getSession().getCreationTime() > 0);
}
/**
* Test that multiple calls from the same client don't change the creation time.
*/
@Test
public void testGetCreationTime2() throws Exception {
doFilter();
long creationTime = ((HttpServletRequest) getFilteredRequest()).getSession().getCreationTime();
MockHttpServletResponse response = getWebMockObjectFactory().getMockResponse();
Cookie cookie = (Cookie) response.getCookies().get(0);
getWebMockObjectFactory().getMockRequest().addCookie(cookie);
doFilter();
assertEquals("Session creation time should be the same", creationTime,
((HttpServletRequest) getFilteredRequest()).getSession().getCreationTime());
}
@Test
public void testResponseContainsRequestedSessionId1() throws Exception {
Cookie cookie = new Cookie("JSESSIONID", "999-GF");
getWebMockObjectFactory().getMockRequest().addCookie(cookie);
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
assertEquals("Request does not contain requested session ID", "999-GF",
request.getRequestedSessionId());
}
@Test
public void testGetLastAccessedTime1() throws Exception {
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
assertTrue("Session should have a non-zero last access time",
request.getSession().getLastAccessedTime() > 0);
}
/**
* Test that repeated accesses update the last accessed time
*/
@Test
public void testGetLastAccessedTime2() throws Exception {
// Setup
CallbackServlet s = (CallbackServlet) getServlet();
s.setCallback(new Callback() {
@Override
public void call(HttpServletRequest request, HttpServletResponse response) {
request.getSession();
}
});
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
long lastAccess = request.getSession().getLastAccessedTime();
assertTrue("Session should have a non-zero last access time", lastAccess > 0);
MockHttpServletResponse response = getWebMockObjectFactory().getMockResponse();
Cookie cookie = (Cookie) response.getCookies().get(0);
MockHttpServletRequest mRequest = getWebMockObjectFactory().createMockRequest();
mRequest.setRequestURL("/test/foo/bar");
mRequest.setContextPath(CONTEXT_PATH);
mRequest.addCookie(cookie);
getWebMockObjectFactory().addRequestWrapper(mRequest);
Thread.sleep(50);
doFilter();
assertTrue("Last access time should be changing",
request.getSession().getLastAccessedTime() > lastAccess);
}
@Test
public void testGetSetMaxInactiveInterval() throws Exception {
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
request.getSession().setMaxInactiveInterval(50);
assertEquals(50, request.getSession().getMaxInactiveInterval());
}
@Test
public void testIsNew1() throws Exception {
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
assertTrue("Session should be new", request.getSession().isNew());
}
/**
* Subsequent calls should not return true
*/
@Test
public void testIsNew2() throws Exception {
// Setup
CallbackServlet s = (CallbackServlet) getServlet();
s.setCallback(new Callback() {
@Override
public void call(HttpServletRequest request, HttpServletResponse response) {
request.getSession();
}
});
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
request.getSession();
MockHttpServletResponse response = getWebMockObjectFactory().getMockResponse();
Cookie cookie = (Cookie) response.getCookies().get(0);
MockHttpServletRequest mRequest = getWebMockObjectFactory().createMockRequest();
mRequest.setRequestURL("/test/foo/bar");
mRequest.setContextPath(CONTEXT_PATH);
mRequest.addCookie(cookie);
getWebMockObjectFactory().addRequestWrapper(mRequest);
doFilter();
request = (HttpServletRequest) getFilteredRequest();
HttpSession s1 = request.getSession();
assertFalse("Subsequent isNew() calls should be false", request.getSession().isNew());
}
@Test
public void testIsRequestedSessionIdFromCookie() {
MockHttpServletRequest mRequest = getWebMockObjectFactory().getMockRequest();
Cookie c = new Cookie("JSESSIONID", "1-GF");
mRequest.addCookie(c);
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
request.getSession();
assertTrue(request.isRequestedSessionIdFromCookie());
}
@Test
public void testIsRequestedSessionIdFromURL() {
MockHttpServletRequest mRequest = getWebMockObjectFactory().getMockRequest();
mRequest.setRequestURL("/foo/bar;jsessionid=1");
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
request.getSession();
assertFalse("Session ID should not be from cookie", request.isRequestedSessionIdFromCookie());
assertTrue("Session ID should be from URL", request.isRequestedSessionIdFromURL());
}
@Test
public void testOnlyOneSessionWhenSecondFilterWrapsRequest() throws Exception {
createFilter(RequestWrappingFilter.class);
createFilter(SessionCachingFilter.class);
doFilter();
HttpServletRequest request = (HttpServletRequest) getFilteredRequest();
HttpSession originalSession = (HttpSession) request.getAttribute("original_session");
assertEquals(originalSession, request.getSession());
}
public static class RequestWrappingFilter implements Filter {
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
final HttpServletRequest httpRequest = (HttpServletRequest) request;
httpRequest.getSession();
httpRequest.setAttribute("original_session", httpRequest.getSession());
request = new HttpServletRequestWrapper(httpRequest);
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
}