From 803fde6c1db1763006db9979038a867e4b64783d Mon Sep 17 00:00:00 2001 From: mposolda Date: Tue, 29 Nov 2016 17:26:11 +0100 Subject: [PATCH] KEYCLOAK-3124 Possibility test adapter on embedded undertow --- .travis.yml | 1 + .../servers/auth-server/undertow/pom.xml | 8 + .../undertow/KeycloakOnUndertow.java | 51 +++- .../undertow/SimpleWebXmlParser.java | 254 ++++++++++++++++++ .../undertow/UndertowDeployerHelper.java | 194 +++++++++++++ .../undertow/UndertowWarClassLoader.java | 61 +++++ .../adapter/servlet/CustomerServlet.java | 18 +- .../adapter/servlet/InputServlet.java | 10 +- .../adapter/servlet/OfflineTokenServlet.java | 5 +- .../adapter/servlet/ServletTestUtils.java | 48 ++++ .../integration-arquillian/tests/base/pom.xml | 4 + .../testsuite/arquillian/ContainerInfo.java | 4 + .../DeploymentArchiveProcessor.java | 13 + .../testsuite/AbstractKeycloakTest.java | 2 +- .../AbstractDemoServletsAdapterTest.java | 11 +- .../AbstractOfflineServletsAdapterTest.java | 6 +- .../AbstractSessionServletAdapterTest.java | 6 +- .../UndertowDemoFilterServletAdapterTest.java | 28 ++ .../UndertowDemoServletsAdapterTest.java | 28 ++ .../UndertowOfflineServletsAdapterTest.java | 28 ++ .../UndertowSessionServletAdapterTest.java | 28 ++ .../keycloak/testsuite/util/URLAssert.java | 5 + travis-run-tests.sh | 7 +- 23 files changed, 782 insertions(+), 38 deletions(-) create mode 100644 testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/SimpleWebXmlParser.java create mode 100644 testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowDeployerHelper.java create mode 100644 testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowWarClassLoader.java create mode 100644 testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/ServletTestUtils.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowDemoFilterServletAdapterTest.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowDemoServletsAdapterTest.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowOfflineServletsAdapterTest.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowSessionServletAdapterTest.java diff --git a/.travis.yml b/.travis.yml index ef531a29f2..faf7b4708c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ env: - TESTS=group1 - TESTS=group2 - TESTS=group3 + - TESTS=group4 - TESTS=adapter jdk: diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml b/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml index 0dbd7a9851..ff476ed3bc 100644 --- a/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml @@ -66,6 +66,14 @@ keycloak-dependencies-server-all pom + + org.keycloak + keycloak-undertow-adapter + + + org.keycloak + keycloak-servlet-filter-adapter + diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java index f740217a11..9d299734b0 100644 --- a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java @@ -18,10 +18,13 @@ package org.keycloak.testsuite.arquillian.undertow; import io.undertow.Undertow; +import io.undertow.server.handlers.PathHandler; import io.undertow.servlet.Servlets; import io.undertow.servlet.api.DefaultServletConfig; import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.DeploymentManager; import io.undertow.servlet.api.FilterInfo; +import io.undertow.servlet.api.ServletContainer; import io.undertow.servlet.api.ServletInfo; import org.jboss.arquillian.container.spi.client.container.DeployableContainer; import org.jboss.arquillian.container.spi.client.container.DeploymentException; @@ -34,14 +37,20 @@ import org.jboss.logging.Logger; import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer; import org.jboss.resteasy.spi.ResteasyDeployment; import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.descriptor.api.Descriptor; import org.jboss.shrinkwrap.undertow.api.UndertowWebArchive; +import org.keycloak.common.util.reflections.Reflections; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.services.filters.KeycloakSessionServletFilter; import org.keycloak.services.resources.KeycloakApplication; import javax.servlet.DispatcherType; +import javax.servlet.ServletException; + +import java.lang.reflect.Field; import java.util.Collection; +import java.util.HashMap; import java.util.Map; public class KeycloakOnUndertow implements DeployableContainer { @@ -52,6 +61,8 @@ public class KeycloakOnUndertow implements DeployableContainer deployedArchivesToContextPath = new HashMap<>(); + private DeploymentInfo createAuthServerDeploymentInfo() { ResteasyDeployment deployment = new ResteasyDeployment(); deployment.setApplicationClass(KeycloakApplication.class.getName()); @@ -75,6 +86,8 @@ public class KeycloakOnUndertow implements DeployableContainer archive) { if (archive instanceof UndertowWebArchive) { return ((UndertowWebArchive) archive).getDeploymentInfo(); + } else if (archive instanceof WebArchive) { + return new UndertowDeployerHelper().getDeploymentInfo(configuration, (WebArchive)archive); } else { throw new IllegalArgumentException("UndertowContainer only supports UndertowWebArchive or WebArchive."); } @@ -93,7 +106,19 @@ public class KeycloakOnUndertow implements DeployableContainer archive) throws DeploymentException { DeploymentInfo di = getDeplotymentInfoFromArchive(archive); - undertow.deploy(di); + + ClassLoader parentCl = Thread.currentThread().getContextClassLoader(); + UndertowWarClassLoader classLoader = new UndertowWarClassLoader(parentCl, archive); + Thread.currentThread().setContextClassLoader(classLoader); + + try { + undertow.deploy(di); + } finally { + Thread.currentThread().setContextClassLoader(parentCl); + } + + deployedArchivesToContextPath.put(archive.getName(), di.getContextPath()); + return new ProtocolMetaData().addContext( createHttpContextForDeploymentInfo(di)); } @@ -151,7 +176,29 @@ public class KeycloakOnUndertow implements DeployableContainer archive) throws DeploymentException { - throw new UnsupportedOperationException("Not implemented"); + Field containerField = Reflections.findDeclaredField(UndertowJaxrsServer.class, "container"); + Reflections.setAccessible(containerField); + ServletContainer container = (ServletContainer) Reflections.getFieldValue(containerField, undertow); + + DeploymentManager deployment = container.getDeployment(archive.getName()); + if (deployment != null) { + try { + deployment.stop(); + } catch (ServletException se) { + throw new DeploymentException(se.getMessage(), se); + } + + deployment.undeploy(); + + Field rootField = Reflections.findDeclaredField(UndertowJaxrsServer.class, "root"); + Reflections.setAccessible(rootField); + PathHandler root = (PathHandler) Reflections.getFieldValue(rootField, undertow); + + String path = deployedArchivesToContextPath.get(archive.getName()); + root.removePrefixPath(path); + } else { + log.warnf("Deployment '%s' not found", archive.getName()); + } } @Override diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/SimpleWebXmlParser.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/SimpleWebXmlParser.java new file mode 100644 index 0000000000..18bceb2654 --- /dev/null +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/SimpleWebXmlParser.java @@ -0,0 +1,254 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed 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.keycloak.testsuite.arquillian.undertow; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + + +import javax.servlet.DispatcherType; +import javax.servlet.Filter; +import javax.servlet.Servlet; + +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.FilterInfo; +import io.undertow.servlet.api.LoginConfig; +import io.undertow.servlet.api.SecurityConstraint; +import io.undertow.servlet.api.SecurityInfo; +import io.undertow.servlet.api.ServletInfo; +import io.undertow.servlet.api.WebResourceCollection; +import org.jboss.logging.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * Simple web.xml parser just to handle our test deployments + * + * @author Marek Posolda + */ +class SimpleWebXmlParser { + + private static final Logger log = Logger.getLogger(SimpleWebXmlParser.class); + + void parseWebXml(Document webXml, DeploymentInfo di) { + try { + DocumentWrapper document = new DocumentWrapper(webXml); + + // SERVLETS + + Map servletMappings = new HashMap<>(); + List sm = document.getElementsByTagName("servlet-mapping"); + for (ElementWrapper mapping : sm) { + String servletName = mapping.getElementByTagName("servlet-name").getText(); + String path = mapping.getElementByTagName("url-pattern").getText(); + servletMappings.put(servletName, path); + } + + List servlets = document.getElementsByTagName("servlet"); + for (ElementWrapper servlet : servlets) { + String servletName = servlet.getElementByTagName("servlet-name").getText(); + String servletClass = servlet.getElementByTagName("servlet-class").getText(); + + Class servletClazz = (Class) Class.forName(servletClass); + ServletInfo undertowServlet = new ServletInfo(servletName, servletClazz); + + if (servletMappings.containsKey(servletName)) { + undertowServlet.addMapping(servletMappings.get(servletName)); + di.addServlet(undertowServlet); + } else { + log.warnf("Missing servlet-mapping for '%s'", servletName); + } + } + + // FILTERS + Map filterMappings = new HashMap<>(); + List fm = document.getElementsByTagName("filter-mapping"); + for (ElementWrapper mapping : fm) { + String filterName = mapping.getElementByTagName("filter-name").getText(); + String path = mapping.getElementByTagName("url-pattern").getText(); + filterMappings.put(filterName, path); + } + + List filters = document.getElementsByTagName("filter"); + for (ElementWrapper filter : filters) { + String filterName = filter.getElementByTagName("filter-name").getText(); + String filterClass = filter.getElementByTagName("filter-class").getText(); + + Class filterClazz = (Class) Class.forName(filterClass); + FilterInfo undertowFilter = new FilterInfo(filterName, filterClazz); + di.addFilter(undertowFilter); + + if (filterMappings.containsKey(filterName)) { + di.addFilterUrlMapping(filterName, filterMappings.get(filterName), DispatcherType.REQUEST); + } else { + log.warnf("Missing filter-mapping for '%s'", filterName); + } + } + + // CONTEXT PARAMS + List contextParams = document.getElementsByTagName("context-param"); + for (ElementWrapper param : contextParams) { + String paramName = param.getElementByTagName("param-name").getText(); + String paramValue = param.getElementByTagName("param-value").getText(); + di.addInitParameter(paramName, paramValue); + } + + + // ROLES + List securityRoles = document.getElementsByTagName("security-role"); + for (ElementWrapper sr : securityRoles) { + String roleName = sr.getElementByTagName("role-name").getText(); + di.addSecurityRole(roleName); + } + + + // SECURITY CONSTRAINTS + List secConstraints = document.getElementsByTagName("security-constraint"); + for (ElementWrapper constraint : secConstraints) { + String urlPattern = constraint.getElementByTagName("web-resource-collection") + .getElementByTagName("url-pattern") + .getText(); + + ElementWrapper authCsnt = constraint.getElementByTagName("auth-constraint"); + String roleName = authCsnt==null ? null : authCsnt + .getElementByTagName("role-name") + .getText(); + + SecurityConstraint undertowConstraint = new SecurityConstraint(); + WebResourceCollection collection = new WebResourceCollection(); + collection.addUrlPattern(urlPattern); + undertowConstraint.addWebResourceCollection(collection); + + if (roleName != null) { + undertowConstraint.addRoleAllowed(roleName); + } else { + undertowConstraint.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT); + } + di.addSecurityConstraint(undertowConstraint); + } + + // LOGIN CONFIG + ElementWrapper loginCfg = document.getElementByTagName("login-config"); + if (loginCfg != null) { + String mech = loginCfg.getElementByTagName("auth-method").getText(); + String realmName = loginCfg.getElementByTagName("realm-name").getText(); + + ElementWrapper form = loginCfg.getElementByTagName("form-login-config"); + if (form != null) { + String loginPage = form.getElementByTagName("form-login-page").getText(); + String errorPage = form.getElementByTagName("form-error-page").getText(); + di.setLoginConfig(new LoginConfig(mech, realmName, loginPage, errorPage)); + } else { + di.setLoginConfig(new LoginConfig(realmName).addFirstAuthMethod(mech)); + } + } + + } catch (ClassNotFoundException cnfe) { + throw new RuntimeException(cnfe); + } + } + + + private static abstract class XmlWrapper { + + + abstract List getElementsByTagName(String tagName); + + + abstract ElementWrapper getElementByTagName(String tagName); + + + List getElementsFromNodeList(NodeList nl) { + List result = new LinkedList<>(); + + for (int i=0; i 0) { + return new ElementWrapper((Element) nl.item(0)); + } else { + return null; + } + } + + } + + + private static class ElementWrapper extends XmlWrapper { + + private final Element element; + + public ElementWrapper(Element element) { + this.element = element; + } + + @Override + public List getElementsByTagName(String tagName) { + NodeList nl = element.getElementsByTagName(tagName); + return getElementsFromNodeList(nl); + } + + @Override + public ElementWrapper getElementByTagName(String tagName) { + NodeList nl = element.getElementsByTagName(tagName); + return getElementFromNodeList(nl); + } + + public String getText() { + return this.element.getTextContent(); + } + } + + + private static class DocumentWrapper extends XmlWrapper { + + private final Document document; + + public DocumentWrapper(Document document) { + this.document = document; + } + + + @Override + List getElementsByTagName(String tagName) { + NodeList nl = document.getElementsByTagName(tagName); + return getElementsFromNodeList(nl); + } + + + @Override + ElementWrapper getElementByTagName(String tagName) { + NodeList nl = document.getElementsByTagName(tagName); + return getElementFromNodeList(nl); + } + } + +} diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowDeployerHelper.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowDeployerHelper.java new file mode 100644 index 0000000000..bd632c35e5 --- /dev/null +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowDeployerHelper.java @@ -0,0 +1,194 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed 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.keycloak.testsuite.arquillian.undertow; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.util.Map; + +import javax.servlet.Servlet; +import javax.servlet.annotation.WebServlet; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import io.undertow.UndertowMessages; +import io.undertow.server.handlers.resource.Resource; +import io.undertow.server.handlers.resource.ResourceChangeListener; +import io.undertow.server.handlers.resource.ResourceManager; +import io.undertow.server.handlers.resource.URLResource; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.ServletInfo; +import org.jboss.logging.Logger; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ArchivePath; +import org.jboss.shrinkwrap.api.Node; +import org.jboss.shrinkwrap.api.asset.ClassAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +/** + * @author Marek Posolda + */ +class UndertowDeployerHelper { + + private static final Logger log = Logger.getLogger(UndertowDeployerHelper.class); + + DeploymentInfo getDeploymentInfo(KeycloakOnUndertowConfiguration config, WebArchive archive) { + String archiveName = archive.getName(); + String contextPath = "/" + archive.getName().substring(0, archive.getName().lastIndexOf('.')); + String appContextUrl = "http://" + config.getBindAddress() + ":" + config.getBindHttpPort() + contextPath; + + try { + DeploymentInfo di = new DeploymentInfo(); + + UndertowWarClassLoader classLoader = new UndertowWarClassLoader(UndertowDeployerHelper.class.getClassLoader(), archive); + di.setClassLoader(classLoader); + + di.setDeploymentName(archiveName); + di.setContextPath(contextPath); + + ResourceManager undertowResourcesWrapper = getResourceManager(appContextUrl, archive); + di.setResourceManager(undertowResourcesWrapper); + + if (archive.contains("/WEB-INF/web.xml")) { + Document webXml = loadXML(archive.get("/WEB-INF/web.xml").getAsset().openStream()); + new SimpleWebXmlParser().parseWebXml(webXml, di); + } + + addAnnotatedServlets(di, archive); + + return di; + } catch (Exception ioe) { + throw new RuntimeException("Error deploying " + archive.getName(), ioe); + } + } + + + private ResourceManager getResourceManager(final String appServerRoot, final WebArchive archive) throws IOException { + return new ResourceManager() { + + @Override + public Resource getResource(String path) throws IOException { + if (path == null || path.isEmpty()) { + return null; + } + + Node node = archive.get(path); + if (node == null) { + log.warnf("Application '%s' did not found resource on path %s", archive.getName(), path); + return null; + } else { + URL contextUrl = new URL(appServerRoot); + + URL myResourceUrl = new URL(contextUrl.getProtocol(), contextUrl.getHost(), contextUrl.getPort(), path, new URLStreamHandler() { + + @Override + protected URLConnection openConnection(URL u) throws IOException { + return new URLConnection(u) { + + @Override + public void connect() throws IOException { + } + + @Override + public InputStream getInputStream() throws IOException { + return node.getAsset().openStream(); + } + + }; + } + + }); + + return new URLResource(myResourceUrl, myResourceUrl.openConnection(), path); + } + } + + @Override + public boolean isResourceChangeListenerSupported() { + return false; + } + + @Override + public void registerResourceChangeListener(ResourceChangeListener listener) { + throw UndertowMessages.MESSAGES.resourceChangeListenerNotSupported(); + } + + @Override + public void removeResourceChangeListener(ResourceChangeListener listener) { + throw UndertowMessages.MESSAGES.resourceChangeListenerNotSupported(); + } + + + @Override + public void close() throws IOException { + // TODO: Should close open streams? + } + + }; + } + + + private Document loadXML(InputStream is) { + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + return dBuilder.parse(is); + } catch (ParserConfigurationException | SAXException | IOException e) { + throw new RuntimeException(e); + } + } + + + private void addAnnotatedServlets(DeploymentInfo di, Archive archive) { + Map classNodes = archive.getContent((ArchivePath path) -> { + + String stringPath = path.get(); + return (stringPath.startsWith("/WEB-INF/classes") && stringPath.endsWith("class")); + + }); + + for (Map.Entry entry : classNodes.entrySet()) { + Node n = entry.getValue(); + ClassAsset classAsset = (ClassAsset) n.getAsset(); + Class clazz = classAsset.getSource(); + + WebServlet annotation = clazz.getAnnotation(WebServlet.class); + if (annotation != null) { + ServletInfo undertowServlet = new ServletInfo(clazz.getSimpleName(), (Class) clazz); + + String[] mappings = annotation.value(); + if (mappings != null) { + for (String urlPattern : mappings) { + undertowServlet.addMapping(urlPattern); + } + } + + di.addServlet(undertowServlet); + } + } + + } + + +} diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowWarClassLoader.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowWarClassLoader.java new file mode 100644 index 0000000000..895ae818c2 --- /dev/null +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/UndertowWarClassLoader.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed 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.keycloak.testsuite.arquillian.undertow; + + + +import java.io.InputStream; + +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.Node; + +/** + * @author Marek Posolda + */ +public class UndertowWarClassLoader extends ClassLoader { + + private final Archive archive; + + public UndertowWarClassLoader(ClassLoader parent, Archive archive) { + super(parent); + this.archive = archive; + } + + + @Override + public InputStream getResourceAsStream(String name) { + InputStream is = super.getResourceAsStream(name); + if (is == null) { + String resourcePath = "/WEB-INF/classes"; + if (!name.startsWith("/")) { + resourcePath = resourcePath + "/"; + } + resourcePath = resourcePath + name; + + Node node = archive.get(resourcePath); + if (node == null) { + return null; + } else { + return node.getAsset().openStream(); + } + } else { + return is; + } + } + +} diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/CustomerServlet.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/CustomerServlet.java index b4fd9a50f9..c6a72e1dd6 100644 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/CustomerServlet.java +++ b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/CustomerServlet.java @@ -18,6 +18,7 @@ package org.keycloak.testsuite.adapter.servlet; import org.keycloak.KeycloakSecurityContext; +import org.keycloak.common.util.UriUtils; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; @@ -50,13 +51,7 @@ public class CustomerServlet extends HttpServlet { //Clear principal form database-service by calling logout StringBuilder result = new StringBuilder(); - String urlBase; - - if (System.getProperty("app.server.ssl.required", "false").equals("true")) { - urlBase = System.getProperty("app.server.ssl.base.url", "https://localhost:8643"); - } else { - urlBase = System.getProperty("app.server.base.url", "http://localhost:8280"); - } + String urlBase = ServletTestUtils.getUrlBase(req); URL url = new URL(urlBase + "/customer-db/"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); @@ -78,13 +73,7 @@ public class CustomerServlet extends HttpServlet { //try { StringBuilder result = new StringBuilder(); - String urlBase; - - if (System.getProperty("app.server.ssl.required", "false").equals("true")) { - urlBase = System.getProperty("app.server.ssl.base.url", "https://localhost:8643"); - } else { - urlBase = System.getProperty("app.server.base.url", "http://localhost:8280"); - } + String urlBase = ServletTestUtils.getUrlBase(req); URL url = new URL(urlBase + "/customer-db/"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); @@ -114,4 +103,5 @@ public class CustomerServlet extends HttpServlet { // client.close(); // } } + } diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/InputServlet.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/InputServlet.java index 5fb04e9435..9fce3d0001 100644 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/InputServlet.java +++ b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/InputServlet.java @@ -18,6 +18,7 @@ package org.keycloak.testsuite.adapter.servlet; import org.junit.Assert; +import org.keycloak.common.util.UriUtils; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; @@ -37,12 +38,7 @@ public class InputServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - String appBase; - if (System.getProperty("app.server.ssl.required", "false").equals("true")) { - appBase = System.getProperty("app.server.ssl.base.url", "https://localhost:8643"); - } else { - appBase = System.getProperty("app.server.base.url", "http://localhost:8280"); - } + String appBase = ServletTestUtils.getUrlBase(req); String actionUrl = appBase + "/input-portal/secured/post"; if (req.getRequestURI().endsWith("insecure")) { @@ -82,7 +78,7 @@ public class InputServlet extends HttpServlet { resp.setContentType("text/plain"); PrintWriter pw = resp.getWriter(); - pw.printf("parameter="+req.getParameter("parameter")); + pw.printf("parameter=" + req.getParameter("parameter")); pw.flush(); } diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/OfflineTokenServlet.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/OfflineTokenServlet.java index b40fc89c27..f1a0a2b638 100644 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/OfflineTokenServlet.java +++ b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/OfflineTokenServlet.java @@ -13,9 +13,6 @@ import java.io.IOException; */ public class OfflineTokenServlet extends AbstractShowTokensServlet { - private static final String OFFLINE_CLIENT_APP_URI = (System.getProperty("app.server.ssl.required", "false").equals("true")) ? - System.getProperty("app.server.ssl.base.url", "https://localhost:8643") + "/offline-client" : - System.getProperty("app.server.base.url", "http://localhost:8280") + "/offline-client"; private static final String ADAPTER_ROOT_URL = (System.getProperty("auth.server.ssl.required", "false").equals("true")) ? System.getProperty("auth.server.ssl.base.url", "https://localhost:8543") : System.getProperty("auth.server.base.url", "http://localhost:8180"); @@ -25,7 +22,7 @@ public class OfflineTokenServlet extends AbstractShowTokensServlet { if (req.getRequestURI().endsWith("logout")) { - UriBuilder redirectUriBuilder = UriBuilder.fromUri(OFFLINE_CLIENT_APP_URI); + UriBuilder redirectUriBuilder = UriBuilder.fromUri(ServletTestUtils.getUrlBase(req) + "/offline-client"); if (req.getParameter(OAuth2Constants.SCOPE) != null) { redirectUriBuilder.queryParam(OAuth2Constants.SCOPE, req.getParameter(OAuth2Constants.SCOPE)); } diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/ServletTestUtils.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/ServletTestUtils.java new file mode 100644 index 0000000000..0697b5c65d --- /dev/null +++ b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/ServletTestUtils.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed 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.keycloak.testsuite.adapter.servlet; + +import javax.servlet.http.HttpServletRequest; + +import org.keycloak.common.util.UriUtils; + +/** + * @author Marek Posolda + */ +public class ServletTestUtils { + + // TODO: Couldn't just always read urlBase from req.getRequestURI() ? + public static String getUrlBase(HttpServletRequest req) { + if (System.getProperty("app.server.ssl.required", "false").equals("true")) { + return System.getProperty("app.server.ssl.base.url", "https://localhost:8643"); + } + + String urlBase = System.getProperty("app.server.base.url"); + + if (urlBase == null) { + String authServer = System.getProperty("auth.server.container", "auth-server-undertow"); + if (authServer.contains("undertow")) { + urlBase = UriUtils.getOrigin(req.getRequestURL().toString()); + } else { + urlBase = "http://localhost:8280"; + } + } + + return urlBase; + } +} diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml index aded7a5304..a0eb15cba5 100644 --- a/testsuite/integration-arquillian/tests/base/pom.xml +++ b/testsuite/integration-arquillian/tests/base/pom.xml @@ -40,6 +40,9 @@ - **/cluster/**/*Test.java + + + **/adapter/undertow/**/*Test.java @@ -103,6 +106,7 @@ ${exclude.account} ${exclude.client} ${exclude.cluster} + ${exclude.undertow.adapter} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/ContainerInfo.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/ContainerInfo.java index dde3c8f365..68c9f17c20 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/ContainerInfo.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/ContainerInfo.java @@ -43,6 +43,10 @@ public class ContainerInfo { this.contextRoot = contextRoot; } + public boolean isUndertow() { + return getQualifier().toLowerCase().contains("undertow"); + } + public boolean isAS7() { return getQualifier().toLowerCase().contains("as7"); } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentArchiveProcessor.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentArchiveProcessor.java index 00deb0a53a..65cebd6f8c 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentArchiveProcessor.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentArchiveProcessor.java @@ -19,7 +19,10 @@ package org.keycloak.testsuite.arquillian; import org.apache.tools.ant.DirectoryScanner; import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; +import org.jboss.arquillian.core.api.InstanceProducer; +import org.jboss.arquillian.core.api.annotation.Inject; import org.jboss.arquillian.test.spi.TestClass; +import org.jboss.arquillian.test.spi.annotation.ClassScoped; import org.jboss.logging.Logger; import org.jboss.logging.Logger.Level; import org.jboss.shrinkwrap.api.Archive; @@ -62,6 +65,10 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor { public static final String SAML_ADAPTER_CONFIG_PATH = "/WEB-INF/keycloak-saml.xml"; public static final String JBOSS_DEPLOYMENT_XML_PATH = "/WEB-INF/jboss-deployment-structure.xml"; + @Inject + @ClassScoped + private InstanceProducer testContextProducer; + @Override public void process(Archive archive, TestClass testClass) { log.info("Processing archive " + archive.getName()); @@ -158,6 +165,12 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor { public void addFilterDependencies(Archive archive, TestClass testClass) { log.info("Adding filter dependencies to " + archive.getName()); + + TestContext testContext = testContextProducer.get(); + if (testContext.getAppServerInfo().isUndertow()) { + return; + } + String dependency = testClass.getAnnotation(UseServletFilter.class).filterDependency(); ((WebArchive) archive).addAsLibraries(KeycloakDependenciesResolver.resolveDependencies((dependency + ":" + System.getProperty("project.version")))); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java index 87950ab156..805f1fde30 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java @@ -146,7 +146,7 @@ public abstract class AbstractKeycloakTest { setDefaultPageUriParameters(); driverSettings(); - + TestEventsLogger.setDriver(driver); if (!suiteContext.isAdminPasswordUpdated()) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java index a7e5992012..f57b858bdf 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java @@ -126,7 +126,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd @Deployment(name = CustomerPortal.DEPLOYMENT_NAME) protected static WebArchive customerPortal() { - return servletDeployment(CustomerPortal.DEPLOYMENT_NAME, CustomerServlet.class, ErrorServlet.class); + return servletDeployment(CustomerPortal.DEPLOYMENT_NAME, CustomerServlet.class, ErrorServlet.class, ServletTestUtils.class); } @Deployment(name = CustomerPortalNoConf.DEPLOYMENT_NAME) @@ -156,7 +156,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd @Deployment(name = InputPortal.DEPLOYMENT_NAME) protected static WebArchive inputPortal() { - return servletDeployment(InputPortal.DEPLOYMENT_NAME, "keycloak.json", InputServlet.class); + return servletDeployment(InputPortal.DEPLOYMENT_NAME, "keycloak.json", InputServlet.class, ServletTestUtils.class); } @Deployment(name = TokenMinTTLPage.DEPLOYMENT_NAME) @@ -194,7 +194,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertEquals(driver.getCurrentUrl(), inputPortal + "/secured/post"); + assertCurrentUrlEquals(driver, inputPortal + "/secured/post"); String pageSource = driver.getPageSource(); assertTrue(pageSource.contains("parameter=hello")); @@ -641,6 +641,8 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd String value = "hello"; Client client = ClientBuilder.newClient(); + //pause(1000000); + Response response = client.target(basicAuthPage .setTemplateValues("mposolda", "password", value).buildUri()).request().get(); @@ -797,7 +799,8 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd String serverLogPath = null; - if (System.getProperty("app.server").equals("wildfly") || System.getProperty("app.server").equals("eap6") || System.getProperty("app.server").equals("eap")) { + String appServer = System.getProperty("app.server"); + if (appServer != null && (appServer.equals("wildfly") || appServer.equals("eap6") || appServer.equals("eap"))) { serverLogPath = System.getProperty("app.server.home") + "/standalone/log/server.log"; } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractOfflineServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractOfflineServletsAdapterTest.java index b8c10b6dac..e686545146 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractOfflineServletsAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractOfflineServletsAdapterTest.java @@ -27,6 +27,7 @@ import java.util.List; import static org.keycloak.testsuite.auth.page.AuthRealm.TEST; import static org.keycloak.testsuite.util.IOUtil.loadRealm; import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith; +import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith; import static org.keycloak.testsuite.util.WaitUtils.pause; import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement; @@ -49,7 +50,7 @@ public abstract class AbstractOfflineServletsAdapterTest extends AbstractServlet @Deployment(name = OfflineToken.DEPLOYMENT_NAME) protected static WebArchive offlineClient() { - return servletDeployment(OfflineToken.DEPLOYMENT_NAME, AdapterActionsFilter.class, AbstractShowTokensServlet.class, OfflineTokenServlet.class, ErrorServlet.class); + return servletDeployment(OfflineToken.DEPLOYMENT_NAME, AdapterActionsFilter.class, AbstractShowTokensServlet.class, OfflineTokenServlet.class, ErrorServlet.class, ServletTestUtils.class); } @Override @@ -92,8 +93,10 @@ public abstract class AbstractOfflineServletsAdapterTest extends AbstractServlet // Ensure that logout works for webapp (even if offline token will be still valid in Keycloak DB) offlineTokenPage.logout(); + assertCurrentUrlDoesntStartWith(offlineTokenPage); loginPage.assertCurrent(); offlineTokenPage.navigateTo(); + assertCurrentUrlDoesntStartWith(offlineTokenPage); loginPage.assertCurrent(); setAdapterAndServerTimeOffset(0); @@ -177,6 +180,7 @@ public abstract class AbstractOfflineServletsAdapterTest extends AbstractServlet //This was necessary to be introduced, otherwise other testcases will fail offlineTokenPage.logout(); + assertCurrentUrlDoesntStartWith(offlineTokenPage); loginPage.assertCurrent(); events.clear(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSessionServletAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSessionServletAdapterTest.java index a018bddc7b..a95a00e12d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSessionServletAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSessionServletAdapterTest.java @@ -144,7 +144,7 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets sessionPortalPage.navigateTo(); assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertEquals(driver.getCurrentUrl(), sessionPortalPage.toString()); + assertCurrentUrlEquals(sessionPortalPage); String pageSource = driver.getPageSource(); assertTrue(pageSource.contains("Counter=1")); @@ -164,7 +164,7 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets // bburke should be still logged with original httpSession in our browser window sessionPortalPage.navigateTo(); - assertEquals(driver.getCurrentUrl(), sessionPortalPage.toString()); + assertCurrentUrlEquals(sessionPortalPage); String pageSource = driver.getPageSource(); assertTrue(pageSource.contains("Counter=3")); String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()) @@ -186,7 +186,7 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets sessionPortalPage.navigateTo(); assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); login.form().login("bburke@redhat.com", "password"); - assertEquals(driver.getCurrentUrl(), sessionPortalPage.toString()); + assertCurrentUrlEquals(sessionPortalPage); String pageSource = driver.getPageSource(); assertTrue(pageSource.contains("Counter=1")); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowDemoFilterServletAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowDemoFilterServletAdapterTest.java new file mode 100644 index 0000000000..e910a2ac9c --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowDemoFilterServletAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed 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.keycloak.testsuite.adapter.undertow.servlet; + +import org.keycloak.testsuite.adapter.servlet.AbstractDemoFilterServletAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("auth-server-undertow") +public class UndertowDemoFilterServletAdapterTest extends AbstractDemoFilterServletAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowDemoServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowDemoServletsAdapterTest.java new file mode 100644 index 0000000000..c1be0ca889 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowDemoServletsAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed 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.keycloak.testsuite.adapter.undertow.servlet; + +import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("auth-server-undertow") +public class UndertowDemoServletsAdapterTest extends AbstractDemoServletsAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowOfflineServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowOfflineServletsAdapterTest.java new file mode 100644 index 0000000000..517d18ab0d --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowOfflineServletsAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed 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.keycloak.testsuite.adapter.undertow.servlet; + +import org.keycloak.testsuite.adapter.servlet.AbstractOfflineServletsAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("auth-server-undertow") +public class UndertowOfflineServletsAdapterTest extends AbstractOfflineServletsAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowSessionServletAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowSessionServletAdapterTest.java new file mode 100644 index 0000000000..73c6a227c8 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowSessionServletAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed 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.keycloak.testsuite.adapter.undertow.servlet; + +import org.keycloak.testsuite.adapter.servlet.AbstractSessionServletAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("auth-server-undertow") +public class UndertowSessionServletAdapterTest extends AbstractSessionServletAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java index 1b0f8c0c1c..90ee6cefa8 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java @@ -56,6 +56,11 @@ public class URLAssert { currentUrlEqual(driver, page.toString())); } + public static void assertCurrentUrlEquals(WebDriver driver, final String url) { + assertTrue("Expected URL: " + url + "; actual: " + driver.getCurrentUrl(), + currentUrlEqual(driver, url)); + } + public static void assertCurrentUrlStartsWith(AbstractPage page) { assertCurrentUrlStartsWith(page.getDriver(), page.toString()); } diff --git a/travis-run-tests.sh b/travis-run-tests.sh index 78cf554d20..2c6ee2991e 100755 --- a/travis-run-tests.sh +++ b/travis-run-tests.sh @@ -6,19 +6,22 @@ fi if [ $1 == "group1" ]; then mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.a**.*Test +fi + +if [ $1 == "group2" ]; then mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.b**.*Test mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.cli**.*Test mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.com**.*Test fi -if [ $1 == "group2" ]; then +if [ $1 == "group3" ]; then mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.d**.*Test mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.e**.*Test mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.f**.*Test mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.i**.*Test fi -if [ $1 == "group3" ]; then +if [ $1 == "group4" ]; then mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.k**.*Test mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.m**.*Test mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.o**.*Test