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 extends Servlet> servletClazz = (Class extends Servlet>) 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 extends Filter> filterClazz = (Class extends Filter>) 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 extends Servlet>) 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