SEC-1677: Create integrationTest task for Java projects and make all tests in itest module run as integration tests only.

This commit is contained in:
Luke Taylor
2011-02-14 14:57:30 +00:00
parent a225dc3776
commit 44fb3aa4ab
33 changed files with 28 additions and 24 deletions

View File

@@ -0,0 +1,157 @@
package org.springframework.security.integration;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import net.sourceforge.jwebunit.junit.WebTester;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.webapp.WebAppContext;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.DispatcherServlet;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
/**
* Base class which allows the application to be started with a particular Spring application
* context. Subclasses override the <tt>getContextConfigLocations</tt> method to return
* a list of context file names which is passed to the <tt>ContextLoaderListener</tt> when
* starting up the webapp.
*
* @author Luke Taylor
*/
public abstract class AbstractWebServerIntegrationTests {
private Server server;
private final Object SERVER_LOCK = new Object();
protected final WebTester tester = new WebTester();
/**
* Override to set the application context files that should be loaded or return null
* to use web.xml.
*/
protected abstract String getContextConfigLocations();
protected String getContextPath() {
return "/testapp";
}
@BeforeClass
public void startServer() throws Exception {
synchronized(SERVER_LOCK) {
if (server == null) {
//System.setProperty("DEBUG", "true");
//System.setProperty("VERBOSE", "true");
//System.setProperty("IGNORED", "true");
server = new Server(0);
server.addHandler(createWebContext());
server.start();
}
}
}
@SuppressWarnings("unchecked")
private WebAppContext createWebContext() {
String webappDir = System.getProperty("webapp.dir");
WebAppContext webCtx = new WebAppContext(webappDir == null ? "src/main/webapp" : webappDir, getContextPath());
if (StringUtils.hasText(getContextConfigLocations())) {
webCtx.addEventListener(new ContextLoaderListener());
webCtx.addEventListener(new HttpSessionEventPublisher());
webCtx.getInitParams().put("contextConfigLocation", getContextConfigLocations());
}
ServletHolder servlet = new ServletHolder();
servlet.setName("testapp");
servlet.setClassName(DispatcherServlet.class.getName());
webCtx.addServlet(servlet, "*.htm");
return webCtx;
}
@AfterClass
public void stopServer() throws Exception {
synchronized(SERVER_LOCK) {
if (server != null) {
server.stop();
}
server = null;
}
}
@BeforeMethod
public void initializeTester() {
tester.getTestContext().setBaseUrl(getBaseUrl());
}
@AfterMethod
public void resetWebConversation() {
tester.closeBrowser();
tester.setTestContext(null);
}
protected final String getBaseUrl() {
int port = server.getConnectors()[0].getLocalPort();
return "http://localhost:" + port + getContextPath() + "/";
}
protected final Object getBean(String beanName) {
return getAppContext().getBean(beanName);
}
protected final WebApplicationContext getAppContext() {
ServletContext servletCtx = ((WebAppContext)server.getHandler()).getServletContext();
WebApplicationContext appCtx =
WebApplicationContextUtils.getRequiredWebApplicationContext(servletCtx);
return appCtx;
}
@SuppressWarnings("unchecked")
protected Cookie getRememberMeCookie() {
List<Cookie> cookies = (List<Cookie>) tester.getTestingEngine().getCookies();
for (Cookie c : cookies) {
if (c.getName().equals("SPRING_SECURITY_REMEMBER_ME_COOKIE")) {
return c;
}
}
return null;
}
protected final void submit() {
tester.submit();
}
protected final void beginAt(String url) {
tester.beginAt(url);
}
protected final void setTextField(String name, String value) {
tester.setTextField(name, value);
}
protected final void assertFormPresent() {
tester.assertFormPresent();
}
protected final void assertTextPresent(String text) {
tester.assertTextPresent(text);
}
// Security-specific utility methods
protected void login(String username, String password) {
assertFormPresent();
setTextField("j_username", username);
setTextField("j_password", password);
submit();
}
}

View File

@@ -0,0 +1,23 @@
package org.springframework.security.integration;
import org.testng.annotations.Test;
public class BasicAuthenticationTests extends AbstractWebServerIntegrationTests {
@Override
protected String getContextConfigLocations() {
return "/WEB-INF/http-security-basic.xml /WEB-INF/in-memory-provider.xml";
}
@Test
public void basicAuthenticationIsSuccessful() throws Exception {
tester.setIgnoreFailingStatusCodes(true);
beginAt("secure/index.html");
// Ignore the 401
tester.setIgnoreFailingStatusCodes(false);
tester.assertHeaderEquals("WWW-Authenticate", "Basic realm=\"Spring Security Application\"");
tester.getTestContext().setAuthorization("johnc", "johncspassword");
beginAt("secure/index.html");
}
}

View File

@@ -0,0 +1,44 @@
package org.springframework.security.integration;
import net.sourceforge.jwebunit.junit.WebTester;
import org.testng.annotations.Test;
/**
* @author Luke Taylor
*/
public class ConcurrentSessionManagementTests extends AbstractWebServerIntegrationTests {
protected String getContextConfigLocations() {
return "/WEB-INF/http-security-concurrency.xml /WEB-INF/in-memory-provider.xml";
}
@Test
public void maxConcurrentLoginsValueIsRespected() throws Exception {
System.out.println("Client: ******* First login ******* ");
beginAt("secure/index.html");
login("jimi", "jimispassword");
// Login again
System.out.println("Client: ******* Second login ******* ");
WebTester tester2 = new WebTester();
tester2.getTestContext().setBaseUrl(getBaseUrl());
tester2.beginAt("secure/index.html");
// seems to be a bug in checking for form here (it fails)
//tester2.assertFormPresent();
tester2.setTextField("j_username", "jimi");
tester2.setTextField("j_password", "jimispassword");
// tester2.submit() also fails to detect the form
tester2.getTestingEngine().submit();
tester2.assertTextPresent("Maximum sessions of 1 for this principal exceeded");
// Now logout to kill first session
tester.gotoPage("/logout");
// Try second session again
tester2.setTextField("j_username", "jimi");
tester2.setTextField("j_password", "jimispassword");
// tester2.submit() also fails to detect the form
tester2.getTestingEngine().submit();
tester2.assertTextPresent("A Secure Page");
}
}

View File

@@ -0,0 +1,53 @@
package org.springframework.security.integration;
import net.sourceforge.jwebunit.junit.WebTester;
import org.junit.Assert;
import org.springframework.security.core.session.SessionRegistry;
import org.testng.annotations.Test;
/**
* @author Luke Taylor
*/
public class CustomConcurrentSessionManagementTests extends AbstractWebServerIntegrationTests {
protected String getContextConfigLocations() {
return "/WEB-INF/http-security-custom-concurrency.xml /WEB-INF/in-memory-provider.xml";
}
@Test
public void maxConcurrentLoginsValueIsRespected() throws Exception {
beginAt("secure/index.html");
login("jimi", "jimispassword");
// Login again
System.out.println("Client: ******* Second login ******* ");
WebTester tester2 = new WebTester();
tester2.getTestContext().setBaseUrl(getBaseUrl());
tester2.beginAt("secure/index.html");
tester2.setTextField("j_username", "jimi");
tester2.setTextField("j_password", "jimispassword");
tester2.setIgnoreFailingStatusCodes(true);
tester2.submit();
Assert.assertTrue(tester2.getServerResponse().contains("Maximum sessions of 1 for this principal exceeded"));
}
@Test
public void logoutClearsSessionRegistryAndAllowsSecondLogin() throws Exception {
beginAt("secure/index.html");
login("bessie", "bessiespassword");
SessionRegistry reg = getAppContext().getBean(SessionRegistry.class);
tester.gotoPage("/j_spring_security_logout");
// Login again
System.out.println("Client: ******* Second login ******* ");
WebTester tester2 = new WebTester();
tester2.getTestContext().setBaseUrl(getBaseUrl());
tester2.beginAt("secure/index.html");
tester2.setTextField("j_username", "bessie");
tester2.setTextField("j_password", "bessiespassword");
tester2.setIgnoreFailingStatusCodes(true);
tester2.submit();
Assert.assertTrue(tester2.getServerResponse().contains("A secure page"));
}
}

View File

@@ -0,0 +1,75 @@
package org.springframework.security.integration;
import static org.testng.Assert.*;
import javax.servlet.http.Cookie;
import net.sourceforge.jwebunit.junit.WebTester;
import org.testng.annotations.Test;
/**
* @author Luke Taylor
*/
public class InMemoryProviderWebAppTests extends AbstractWebServerIntegrationTests {
protected String getContextConfigLocations() {
return "/WEB-INF/http-security.xml /WEB-INF/in-memory-provider.xml";
}
@Test
public void loginFailsWithinvalidPassword() {
beginAt("secure/index.html");
login("jimi", "wrongPassword");
assertTextPresent("Your login attempt was not successful");
}
@Test
public void loginSucceedsWithCorrectPassword() {
beginAt("secure/index.html");
login("jimi", "jimispassword");
assertTextPresent("A Secure Page");
tester.gotoPage("/logout");
}
@Test
public void basicAuthenticationIsSuccessful() throws Exception {
tester.getTestContext().setAuthorization("johnc", "johncspassword");
beginAt("secure/index.html");
beginAt("secure/index.html");
}
/*
* Checks use of <jsp:include> with parameters in the secured page.
*/
@Test
public void savedRequestWithJspIncludeSeesCorrectParams() {
beginAt("secure/secure1.jsp?x=0");
login("jimi", "jimispassword");
// Included JSP has params ?x=1&y=2
assertTextPresent("Params: x=1, y=2");
assertTextPresent("xcount=2");
}
// SEC-1255
@Test
public void redirectToUrlWithSpecialCharsInFilenameWorksOk() throws Exception {
beginAt("secure/file%3Fwith%3Fspecial%3Fchars.htm?someArg=1");
login("jimi", "jimispassword");
assertTextPresent("I'm file?with?special?chars.htm");
}
@Test
public void persistentLoginIsSuccesful() throws Exception {
beginAt("secure/index.html");
tester.checkCheckbox("_spring_security_remember_me");
login("jimi", "jimispassword");
Cookie rememberMe = getRememberMeCookie();
assertNotNull(rememberMe);
tester.closeBrowser();
tester.getTestContext().addCookie(rememberMe);
beginAt("secure/index.html");
assertTextPresent("A Secure Page");
}
}

View File

@@ -0,0 +1,39 @@
package org.springframework.security.integration;
import static org.testng.Assert.*;
import org.testng.annotations.Test;
/**
*
* @author Luke Taylor
*/
public final class JspTaglibTests extends AbstractWebServerIntegrationTests {
@Override
protected String getContextConfigLocations() {
return "/WEB-INF/http-security.xml /WEB-INF/in-memory-provider.xml";
}
@Test
public void authenticationTagEscapingWorksCorrectly() {
beginAt("secure/authenticationTagTestPage.jsp");
login("theescapist<>&.", "theescapistspassword");
String response = tester.getServerResponse();
assertTrue(response.contains("This is the unescaped authentication name: theescapist<>&."));
assertTrue(response.contains("This is the unescaped principal.username: theescapist<>&."));
assertTrue(response.contains("This is the authentication name: theescapist&lt;&gt;&amp;&#46;"));
assertTrue(response.contains("This is the principal.username: theescapist&lt;&gt;&amp;&#46;"));
}
@Test
public void authorizationTagEvaluatesExpressionCorrectlyAndWritesValueToVariable() {
beginAt("secure/authorizationTagTestPage.jsp");
login("bessie", "bessiespassword");
String response = tester.getServerResponse();
assertTrue(response.contains("Users can see this and 'allowed' variable is true."));
assertFalse(response.contains("Role X users (nobody) can see this."));
assertTrue(response.contains("Role X expression evaluates to false"));
}
}

View File

@@ -0,0 +1,19 @@
package org.springframework.security.integration;
import org.testng.annotations.*;
/**
* @author Luke Taylor
*/
public class LdapWebAppTests extends AbstractWebServerIntegrationTests {
protected String getContextConfigLocations() {
return "/WEB-INF/http-security.xml /WEB-INF/ldap-provider.xml";
}
@Test
public void doSomething() {
}
}

View File

@@ -0,0 +1,15 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.springframework.security" level="${sec.log.level}:-WARN"/>
<logger name="org.apache.directory" level="ERROR"/>
<root level="${root.level}:-WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>