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:
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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<>&."));
|
||||
assertTrue(response.contains("This is the principal.username: theescapist<>&."));
|
||||
}
|
||||
|
||||
@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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
15
itest/web/src/integration-test/resources/logback-test.xml
Normal file
15
itest/web/src/integration-test/resources/logback-test.xml
Normal 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>
|
||||
Reference in New Issue
Block a user