keycloak-aplcache

KEYCLOAK-1678 Reorganized containers handling. (WIP: adapter-libs

2/4/2016 5:24:58 PM

Changes

testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/ContainersTestEnricher.java 362(+0 -362)

Details

diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AppServerTestEnricher.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AppServerTestEnricher.java
new file mode 100644
index 0000000..b47981b
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AppServerTestEnricher.java
@@ -0,0 +1,187 @@
+package org.keycloak.testsuite.arquillian;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.jboss.arquillian.container.spi.Container;
+import org.jboss.arquillian.container.test.api.ContainerController;
+import org.jboss.arquillian.core.api.Instance;
+import org.jboss.arquillian.core.api.InstanceProducer;
+import org.jboss.arquillian.core.api.annotation.Inject;
+import org.jboss.arquillian.core.api.annotation.Observes;
+import org.jboss.arquillian.test.spi.annotation.ClassScoped;
+import org.jboss.arquillian.test.spi.event.suite.BeforeClass;
+import org.jboss.logging.Logger;
+import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.getAuthServerContextRoot;
+import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.getAuthServerQualifier;
+import org.keycloak.testsuite.arquillian.annotation.AdapterLibsLocationProperty;
+import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
+import static org.keycloak.testsuite.util.IOUtil.execCommand;
+import org.keycloak.testsuite.util.LogChecker;
+import static org.keycloak.testsuite.util.WaitUtils.pause;
+
+/**
+ *
+ * @author tkyjovsk
+ */
+public class AppServerTestEnricher {
+
+    protected final Logger log = Logger.getLogger(this.getClass());
+
+    @Inject
+    @ClassScoped
+    private InstanceProducer<TestContext> testContextProducer;
+    private TestContext testContext;
+
+    @Inject
+    private Instance<ContainerController> containerController;
+
+    public static String getAppServerQualifier(Class testClass) {
+        Class<? extends AuthServerTestEnricher> annotatedClass = getNearestSuperclassWithAnnotation(testClass, AppServerContainer.class);
+
+        String appServerQ = (annotatedClass == null ? null
+                : annotatedClass.getAnnotation(AppServerContainer.class).value());
+
+        return appServerQ;
+    }
+
+    public static String getAppServerContextRoot() {
+        return getAppServerContextRoot(0);
+    }
+
+    public static String getAppServerContextRoot(int clusterPortOffset) {
+        int httpPort = Integer.parseInt(System.getProperty("app.server.http.port")); // property must be set
+        int httpsPort = Integer.parseInt(System.getProperty("app.server.https.port")); // property must be set
+        boolean sslRequired = Boolean.parseBoolean(System.getProperty("app.server.ssl.required"));
+
+        return sslRequired
+                ? "https://localhost:" + (httpsPort + clusterPortOffset)
+                : "http://localhost:" + (httpPort + clusterPortOffset);
+    }
+
+    private ContainerInfo initializeAppServerInfo(Container appServerContainer) {
+        return initializeAppServerInfo(appServerContainer, 0);
+    }
+
+    private ContainerInfo initializeAppServerInfo(Container appServerContainer, int clusterPortOffset) {
+        ContainerInfo appServerInfo = new ContainerInfo(appServerContainer);
+        try {
+
+            String appServerContextRootStr = isRelative(testContext.getTestClass())
+                    ? getAuthServerContextRoot(clusterPortOffset)
+                    : getAppServerContextRoot(clusterPortOffset);
+
+            appServerInfo.setContextRoot(new URL(appServerContextRootStr));
+
+        } catch (MalformedURLException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+        return appServerInfo;
+    }
+
+    public void updateTestContextWithAppServerInfo(@Observes BeforeClass event) {
+        testContext = testContextProducer.get();
+        String appServerQualifier = getAppServerQualifier(testContext.getTestClass());
+        for (Container container : testContext.getSuiteContext().getArquillianContainers()) {
+            if (container.getContainerConfiguration().getContainerName().equals(appServerQualifier)) {
+                testContext.setAppServerInfo(initializeAppServerInfo(container));
+            }
+        }
+        // validate app server
+        if (appServerQualifier != null && testContext.getAppServerInfo() == null) {
+            throw new RuntimeException(String.format("No app server container matching '%s' was activated. Check if defined and enabled in arquillian.xml.", appServerQualifier));
+        }
+        log.info("\n\n" + testContext);
+    }
+
+    public void startAppServer(@Observes(precedence = -1) BeforeClass event) throws MalformedURLException, InterruptedException, IOException {
+        ContainerController controller = containerController.get();
+        if (testContext.isAdapterTest()) {
+            String appServerQualifier = testContext.getAppServerInfo().getQualifier();
+            if (!controller.isStarted(appServerQualifier)) {
+                controller.start(appServerQualifier);
+            }
+            log.info("\n\n\nAPP SERVER STARTED\n\n\n");
+            // install adapter libs on JBoss-based container via CLI
+//            if (testContext.getAppServerInfo().isJBossBased()) {
+                installAdapterLibsUsingJBossCLIClient(testContext.getAppServerInfo());
+//            }
+        }
+    }
+
+    private void installAdapterLibsUsingJBossCLIClient(ContainerInfo appServerInfo) throws InterruptedException, IOException {
+        
+        log.info("Installing adapter via CLI client");
+        
+        if (!appServerInfo.isJBossBased()) {
+            throw new IllegalArgumentException("App server must be JBoss-based to run jboss-cli-client.");
+        }
+
+        String jbossHomePath = appServerInfo.getProperties().get("jbossHome");
+
+        File bin = new File(jbossHomePath + "/bin");
+        String command = "java -jar " + jbossHomePath + "/bin/client/jboss-cli-client.jar";
+        String adapterScript = "adapter-install.cli";
+        String samlAdapterScript = "adapter-install-saml.cli";
+        String managementPort = appServerInfo.getProperties().get("managementPort");
+
+        String controllerArg = " --controller=localhost:" + managementPort;
+        if (new File(bin, adapterScript).exists()) {
+            log.info("Installing adapter to app server via cli script");
+            execCommand(command + " --connect --file=" + adapterScript + controllerArg, bin);
+        }
+        if (new File(bin, samlAdapterScript).exists()) {
+            log.info("Installing saml adapter to app server via cli script");
+            execCommand(command + " --connect --file=" + samlAdapterScript + controllerArg, bin);
+        }
+        if (new File(bin, adapterScript).exists() || new File(bin, samlAdapterScript).exists()) {
+            log.info("Restarting container");
+            execCommand(command + " --connect --command=reload" + controllerArg, bin);
+            log.info("Container restarted");
+            pause(5000);
+            LogChecker.checkJBossServerLog(jbossHomePath);
+        }
+    }
+
+    /**
+     *
+     * @param testClass
+     * @param annotationClass
+     * @return testClass or the nearest superclass of testClass annotated with
+     * annotationClass
+     */
+    public static Class getNearestSuperclassWithAnnotation(Class testClass, Class annotationClass) {
+        return testClass.isAnnotationPresent(annotationClass) ? testClass
+                : (testClass.getSuperclass().equals(Object.class) ? null // stop recursion
+                        : getNearestSuperclassWithAnnotation(testClass.getSuperclass(), annotationClass)); // continue recursion
+    }
+
+    public static boolean hasAppServerContainerAnnotation(Class testClass) {
+        return getNearestSuperclassWithAnnotation(testClass, AppServerContainer.class) != null;
+    }
+
+    public static boolean isRelative(Class testClass) {
+        return getAppServerQualifier(testClass).equals(getAuthServerQualifier());
+    }
+
+    public static String getAdapterLibsLocationProperty(Class testClass) {
+        Class<? extends AuthServerTestEnricher> annotatedClass = getNearestSuperclassWithAnnotation(testClass, AdapterLibsLocationProperty.class);
+        return (annotatedClass == null ? null
+                : annotatedClass.getAnnotation(AdapterLibsLocationProperty.class).value());
+    }
+
+    public static boolean isWildflyAppServer(Class testClass) {
+        return getAppServerQualifier(testClass).contains("wildfly");
+    }
+
+    public static boolean isTomcatAppServer(Class testClass) {
+        return getAppServerQualifier(testClass).contains("tomcat");
+    }
+
+    public static boolean isOSGiAppServer(Class testClass) {
+        String q = getAppServerQualifier(testClass);
+        return q.contains("karaf") || q.contains("fuse");
+    }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java
new file mode 100644
index 0000000..86176cb
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java
@@ -0,0 +1,198 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+
+import org.jboss.arquillian.container.spi.Container;
+import org.jboss.arquillian.container.spi.ContainerRegistry;
+import org.jboss.arquillian.container.spi.event.StartContainer;
+import org.jboss.arquillian.container.spi.event.StartSuiteContainers;
+import org.jboss.arquillian.container.test.api.ContainerController;
+import org.jboss.arquillian.core.api.Event;
+import org.jboss.arquillian.core.api.Instance;
+import org.jboss.arquillian.core.api.InstanceProducer;
+import org.jboss.arquillian.core.api.annotation.Inject;
+import org.jboss.arquillian.core.api.annotation.Observes;
+import org.jboss.arquillian.test.spi.annotation.ClassScoped;
+import org.jboss.arquillian.test.spi.annotation.SuiteScoped;
+import org.jboss.arquillian.test.spi.event.suite.BeforeClass;
+import org.jboss.arquillian.test.spi.event.suite.BeforeSuite;
+import org.jboss.logging.Logger;
+import org.keycloak.testsuite.util.LogChecker;
+
+/**
+ *
+ * @author tkyjovsk
+ * @author vramik
+ */
+public class AuthServerTestEnricher {
+    
+    protected final Logger log = Logger.getLogger(this.getClass());
+    
+    @Inject
+    private Instance<ContainerRegistry> containerRegistry;
+    
+    @Inject
+    private Instance<ContainerController> containerController;
+    
+    @Inject
+    private Event<StartContainer> startContainerEvent;
+    
+    private static final String AUTH_SERVER_CONTAINER_PROPERTY = "auth.server.container";
+    private static final String AUTH_SERVER_CONTAINER_DEFAULT = "auth-server-undertow";
+    
+    private static final String MIGRATED_AUTH_SERVER_CONTAINER_PROPERTY = "migrated.auth.server.container";
+    
+    @Inject
+    @SuiteScoped
+    private InstanceProducer<SuiteContext> suiteContextProducer;
+    private SuiteContext suiteContext;
+    
+    @Inject
+    @ClassScoped
+    private InstanceProducer<TestContext> testContextProducer;
+    
+    public static String getAuthServerQualifier() {
+        return System.getProperty(AUTH_SERVER_CONTAINER_PROPERTY, AUTH_SERVER_CONTAINER_DEFAULT);
+    }
+    
+    public static String getMigratedAuthServerQualifier() {
+        return System.getProperty(MIGRATED_AUTH_SERVER_CONTAINER_PROPERTY); // == null if migration not enabled
+    }
+    
+    public static String getAuthServerContextRoot() {
+        return getAuthServerContextRoot(0);
+    }
+    
+    public static String getAuthServerContextRoot(int clusterPortOffset) {
+        int httpPort = Integer.parseInt(System.getProperty("auth.server.http.port")); // property must be set
+        int httpsPort = Integer.parseInt(System.getProperty("auth.server.https.port")); // property must be set
+        boolean sslRequired = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required"));
+        
+        return sslRequired
+                ? "https://localhost:" + (httpsPort + clusterPortOffset)
+                : "http://localhost:" + (httpPort + clusterPortOffset);
+    }
+    
+    public void initializeSuiteContext(@Observes(precedence = 2) BeforeSuite event) {
+        suiteContext = new SuiteContext(new ArrayList<>(containerRegistry.get().getContainers()));
+        
+        String authServerQualifier = getAuthServerQualifier();
+        String migratedAuthServerQualifier = getMigratedAuthServerQualifier();
+
+        // init authServerInfo and authServerBackendsInfo
+        if (authServerQualifier.startsWith("auth-server-")) {
+            
+            boolean authServerCluster = authServerQualifier.endsWith("-cluster");
+            
+            String authServerType = authServerQualifier.replaceAll("^auth-server-", "").replaceAll("-cluster$", "");
+            String authServerFrontend = authServerCluster
+                    ? "auth-server-" + authServerType + "-balancer" // in cluster mode the load-balancer container serves as auth server frontend
+                    : authServerQualifier; // single-node mode
+            String authServerBackend = "auth-server-" + authServerType + "-backend";
+            int backends = 0;
+            for (Container container : suiteContext.getArquillianContainers()) {
+                // frontend
+                if (container.getContainerConfiguration().getContainerName().equals(authServerFrontend)) {
+                    suiteContext.setAuthServerInfo(initializeAuthServerInfo(container));
+                }
+                // backends
+                if (container.getContainerConfiguration().getContainerName().startsWith(authServerBackend)) {
+                    suiteContext.getAuthServerBackendsInfo().add(initializeAuthServerInfo(container, ++backends));
+                }
+            }
+
+            // validate auth server setup
+            if (suiteContext.getAuthServerInfo() == null) {
+                throw new RuntimeException(String.format("No auth server activated. A container matching '%s' needs to be enabled in arquillian.xml.", authServerFrontend));
+            }
+            if (authServerCluster && !suiteContext.getAuthServerBackendsInfo().isEmpty()) {
+                throw new RuntimeException(String.format("No cluster backend nodes activated. Containers matching '%sN' need to be enabled in arquillian.xml.", authServerBackend));
+            }
+            
+        } else {
+            throw new IllegalArgumentException(String.format("Value of %s should start with 'auth-server-' prefix.", AUTH_SERVER_CONTAINER_PROPERTY));
+        }
+        
+        if (migratedAuthServerQualifier != null) {
+            // init migratedAuthServerInfo
+            if (migratedAuthServerQualifier.startsWith("migrated-auth-server-")) {
+                for (Container container : suiteContext.getArquillianContainers()) {
+                    // migrated auth server
+                    if (container.getContainerConfiguration().getContainerName().equals(migratedAuthServerQualifier)) {
+                        suiteContext.setMigratedAuthServerInfo(initializeAuthServerInfo(container));
+                    }
+                }
+            } else {
+                throw new IllegalArgumentException(String.format("Value of %s should start with 'migrated-auth-server-' prefix.", MIGRATED_AUTH_SERVER_CONTAINER_PROPERTY));
+            }
+            // validate setup
+            if (suiteContext.getMigratedAuthServerInfo() == null) {
+                throw new RuntimeException(String.format("Migration test was enabled but no auth server from which to migrate was activated. "
+                        + "A container matching '%s' needs to be enabled in arquillian.xml.", migratedAuthServerQualifier));
+            }
+        }
+        
+        suiteContextProducer.set(suiteContext);
+        log.info("\n\n" + suiteContext);
+    }
+    
+    public void initializeTestContext(@Observes(precedence = 1) BeforeClass event) {
+        TestContext testContext = new TestContext(suiteContext, event.getTestClass().getJavaClass());
+        testContextProducer.set(testContext);
+    }
+    
+    private ContainerInfo initializeAuthServerInfo(Container authServerContainer) {
+        return initializeAuthServerInfo(authServerContainer, 0);
+    }
+    
+    private ContainerInfo initializeAuthServerInfo(Container authServerContainer, int clusterPortOffset) {
+        ContainerInfo authServerInfo = new ContainerInfo(authServerContainer);
+        try {
+            authServerInfo.setContextRoot(new URL(getAuthServerContextRoot(clusterPortOffset)));
+        } catch (MalformedURLException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+        return authServerInfo;
+    }
+    
+    public void startMigratedContainer(@Observes(precedence = 2) StartSuiteContainers event) {
+        if (suiteContext.isAuthServerMigrationEnabled()) {
+            log.info("\n\n### Starting keycloak " + System.getProperty("version", "- previous") + " ###\n");
+            startContainerEvent.fire(new StartContainer(suiteContext.getMigratedAuthServerInfo().getArquillianContainer()));
+        }
+    }
+    
+    public void stopMigratedContainer(@Observes(precedence = 1) StartSuiteContainers event) {
+        if (suiteContext.isAuthServerMigrationEnabled()) {
+            containerController.get().stop(suiteContext.getAuthServerInfo().getQualifier());
+        }
+    }
+    
+    public void checkServerLogs(@Observes(precedence = -1) BeforeSuite event) throws IOException, InterruptedException {
+        boolean checkLog = System.getProperty("auth.server.log.check", "true").equals("true");
+        if (checkLog && suiteContext.getAuthServerInfo().isJBossBased()) {
+            String jbossHomePath = suiteContext.getAuthServerInfo().getProperties().get("jbossHome");
+            LogChecker.checkJBossServerLog(jbossHomePath);
+        }
+    }
+    
+}
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
new file mode 100644
index 0000000..68ae059
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/ContainerInfo.java
@@ -0,0 +1,64 @@
+package org.keycloak.testsuite.arquillian;
+
+import java.net.URL;
+import java.util.Map;
+import org.jboss.arquillian.container.spi.Container;
+
+/**
+ *
+ * @author tkyjovsk
+ */
+public class ContainerInfo {
+
+    private URL contextRoot;
+    private Container arquillianContainer;
+
+    public ContainerInfo(Container arquillianContainer) {
+        if (arquillianContainer == null) {
+            throw new IllegalArgumentException();
+        }
+        this.arquillianContainer = arquillianContainer;
+    }
+
+    public Container getArquillianContainer() {
+        return arquillianContainer;
+    }
+
+    public Map<String, String> getProperties() {
+        return getArquillianContainer().getContainerConfiguration().getContainerProperties();
+    }
+
+    public String getQualifier() {
+        return getArquillianContainer().getName();
+    }
+
+    public URL getContextRoot() {
+        return contextRoot;
+    }
+
+    public void setContextRoot(URL contextRoot) {
+        this.contextRoot = contextRoot;
+    }
+
+    public boolean isAS7() {
+        return getQualifier().contains("as7");
+    }
+
+    public boolean isWildfly() {
+        return getQualifier().contains("Wildfly");
+    }
+
+    public boolean isEAP() {
+        return getQualifier().contains("eap");
+    }
+
+    public boolean isJBossBased() {
+        return isAS7() || isWildfly() || isEAP();
+    }
+
+    @Override
+    public String toString() {
+        return getQualifier();
+    }
+
+}
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 74e20c1..da482a8 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
@@ -37,8 +37,12 @@ import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.getAdapterLibsLocationProperty;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.hasAppServerContainerAnnotation;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isRelative;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isTomcatAppServer;
 
-import static org.keycloak.testsuite.arquillian.ContainersTestEnricher.*;
+import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.*;
 import static org.keycloak.testsuite.util.IOUtil.*;
 
 ;
@@ -122,7 +126,7 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
                         adapterConfig.setAuthServerUrl("/auth");
 //                ac.setRealmKey(null); // TODO verify if realm key is required for relative scneario
                     } else {
-                        adapterConfig.setAuthServerUrl(getAuthServerContextRootFromSystemProperty() + "/auth");
+                        adapterConfig.setAuthServerUrl(getAuthServerContextRoot() + "/auth");
                         adapterConfig.setRealmKey(REALM_KEY);
                     }
                     
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java
index b45d50f..b867c7c 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java
@@ -23,7 +23,7 @@ import org.jboss.arquillian.container.spi.client.deployment.TargetDescription;
 import org.jboss.arquillian.container.test.impl.client.deployment.AnnotationDeploymentScenarioGenerator;
 import org.jboss.arquillian.test.spi.TestClass;
 import org.jboss.logging.Logger;
-import static org.keycloak.testsuite.arquillian.ContainersTestEnricher.*;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.getAppServerQualifier;
 
 /**
  * Changes target container for all Arquillian deployments based on value of
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java
index 621483c..7154b8a 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java
@@ -47,7 +47,8 @@ public class KeycloakArquillianExtension implements LoadableExtension {
         builder
                 .service(DeploymentScenarioGenerator.class, DeploymentTargetModifier.class)
                 .service(ApplicationArchiveProcessor.class, DeploymentArchiveProcessor.class)
-                .observer(ContainersTestEnricher.class);
+                .observer(AuthServerTestEnricher.class)
+                .observer(AppServerTestEnricher.class);
 
         builder
                 .service(DeployableContainer.class, CustomUndertowContainer.class);
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/provider/URLProvider.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/provider/URLProvider.java
index f883f64..301fc86 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/provider/URLProvider.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/provider/URLProvider.java
@@ -33,6 +33,7 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashSet;
 import java.util.Set;
+import org.keycloak.testsuite.arquillian.SuiteContext;
 
 public class URLProvider extends URLResourceProvider {
 
@@ -44,6 +45,8 @@ public class URLProvider extends URLResourceProvider {
     private final boolean appServerSslRequired = Boolean.parseBoolean(System.getProperty("app.server.ssl.required"));
 
     @Inject
+    Instance<SuiteContext> suiteContext;
+    @Inject
     Instance<TestContext> testContext;
 
     private static final Set<String> fixedUrls = new HashSet<>();
@@ -97,10 +100,10 @@ public class URLProvider extends URLResourceProvider {
         // inject context roots if annotation present
         for (Annotation a : qualifiers) {
             if (AuthServerContext.class.isAssignableFrom(a.annotationType())) {
-                return testContext.get().getAuthServerContextRoot();
+                return suiteContext.get().getAuthServerInfo().getContextRoot();
             }
             if (AppServerContext.class.isAssignableFrom(a.annotationType())) {
-                return testContext.get().getAppServerContextRoot();
+                return testContext.get().getAppServerInfo().getContextRoot();
             }
         }
 
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/SuiteContext.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/SuiteContext.java
index fb91a7b..cf58916 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/SuiteContext.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/SuiteContext.java
@@ -14,11 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite.arquillian;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import org.jboss.arquillian.container.spi.Container;
 import static org.keycloak.testsuite.util.MailServerConfiguration.*;
 
 /**
@@ -27,10 +29,18 @@ import static org.keycloak.testsuite.util.MailServerConfiguration.*;
  */
 public final class SuiteContext {
 
+    private final List<Container> arquillianContainers;
+
+    private ContainerInfo authServerInfo;
+    private final List<ContainerInfo> authServerBackendsInfo = new ArrayList<>();
+
+    private ContainerInfo migratedAuthServerInfo;
+
     private boolean adminPasswordUpdated;
     private final Map<String, String> smtpServer = new HashMap<>();
-    
-    public SuiteContext() {
+
+    public SuiteContext(List<Container> arquillianContainers) {
+        this.arquillianContainers = arquillianContainers;
         this.adminPasswordUpdated = false;
         smtpServer.put("from", FROM);
         smtpServer.put("host", HOST);
@@ -48,4 +58,44 @@ public final class SuiteContext {
     public Map<String, String> getSmtpServer() {
         return smtpServer;
     }
+
+    public ContainerInfo getAuthServerInfo() {
+        return authServerInfo;
+    }
+
+    public void setAuthServerInfo(ContainerInfo authServerInfo) {
+        this.authServerInfo = authServerInfo;
+    }
+
+    public List<ContainerInfo> getAuthServerBackendsInfo() {
+        return authServerBackendsInfo;
+    }
+
+    public ContainerInfo getMigratedAuthServerInfo() {
+        return migratedAuthServerInfo;
+    }
+
+    public void setMigratedAuthServerInfo(ContainerInfo migratedAuthServerInfo) {
+        this.migratedAuthServerInfo = migratedAuthServerInfo;
+    }
+
+    public boolean isAuthServerCluster() {
+        return !authServerBackendsInfo.isEmpty();
+    }
+
+    public boolean isAuthServerMigrationEnabled() {
+        return migratedAuthServerInfo != null;
+    }
+
+    public List<Container> getArquillianContainers() {
+        return arquillianContainers;
+    }
+
+    @Override
+    public String toString() {
+        return "SUITE CONTEXT:\n"
+                + "Auth server: " + authServerInfo.getQualifier() + "\n"
+                +(isAuthServerCluster() ? "Auth server cluster: " + getAuthServerBackendsInfo().size() + " nodes+\n" : "");
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/TestContext.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/TestContext.java
index b4c67ef..673bc7c 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/TestContext.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/TestContext.java
@@ -14,10 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite.arquillian;
 
-import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  *
@@ -25,43 +25,67 @@ import java.net.URL;
  */
 public final class TestContext {
 
-    private URL authServerContextRoot;
-    private URL appServerContextRoot;
+    private final SuiteContext suiteContext;
+
+    private final Class testClass;
+
+    private ContainerInfo appServerInfo;
+    private final List<ContainerInfo> appServerBackendsInfo = new ArrayList<>();
 
     private boolean adminLoggedIn;
 
-    public TestContext() {
+    public TestContext(SuiteContext suiteContext, Class testClass) {
+        this.suiteContext = suiteContext;
+        this.testClass = testClass;
         this.adminLoggedIn = false;
     }
 
-    public TestContext(URL authServerContextRoot, URL appServerContextRoot) {
-        this();
-        this.authServerContextRoot = authServerContextRoot;
-        this.appServerContextRoot = appServerContextRoot;
+    public boolean isAdminLoggedIn() {
+        return adminLoggedIn;
     }
 
-    public URL getAuthServerContextRoot() {
-        return authServerContextRoot;
+    public void setAdminLoggedIn(boolean adminLoggedIn) {
+        this.adminLoggedIn = adminLoggedIn;
     }
 
-    public URL getAppServerContextRoot() {
-        return appServerContextRoot;
+    public ContainerInfo getAppServerInfo() {
+        return appServerInfo;
     }
 
-    public boolean isAdminLoggedIn() {
-        return adminLoggedIn;
+    public void setAppServerInfo(ContainerInfo appServerInfo) {
+        this.appServerInfo = appServerInfo;
     }
 
-    public void setAdminLoggedIn(boolean adminLoggedIn) {
-        this.adminLoggedIn = adminLoggedIn;
+    public List<ContainerInfo> getAppServerBackendsInfo() {
+        return appServerBackendsInfo;
+    }
+
+    public Class getTestClass() {
+        return testClass;
+    }
+
+    public boolean isAdapterTest() {
+        return appServerInfo != null;
+    }
+
+    public boolean isRelativeAdapterTest() {
+        return isAdapterTest()
+                && appServerInfo.getQualifier().equals(
+                        suiteContext.getAuthServerInfo().getQualifier()); // app server == auth server
+    }
+
+    public boolean isClusteredAdapterTest() {
+        return isAdapterTest() && !appServerBackendsInfo.isEmpty();
     }
 
-    public void setAuthServerContextRoot(URL authServerContextRoot) {
-        this.authServerContextRoot = authServerContextRoot;
+    public SuiteContext getSuiteContext() {
+        return suiteContext;
     }
 
-    public void setAppServerContextRoot(URL appServerContextRoot) {
-        this.appServerContextRoot = appServerContextRoot;
+    @Override
+    public String toString() {
+        return "TEST CONTEXT: " + getTestClass().getCanonicalName() + "\n"
+                + (isAdapterTest() ? "App server container: " + getAppServerInfo() + "\n" : "");
     }
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java
index 4661df8..ba45448 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java
@@ -101,9 +101,9 @@ public class AccountManagement extends AuthRealm {
         save.click();
     }
 
-    public RealmResource realmResource() {
-        return keycloak().realm(getAuthRealm());
-    }
+//    public RealmResource realmResource() {
+//        return keycloak().realm(getAuthRealm());
+//    }
 
     public void waitForAccountLinkPresent() {
         waitUntilElement(accountLink, "account link should be present").is().present();
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthServer.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthServer.java
index 7dae6b6..14f1e26 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthServer.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthServer.java
@@ -41,11 +41,11 @@ public class AuthServer extends AuthServerContextRoot {
         return uri.getScheme() + "://" + uri.getAuthority() + "/auth";
     }
 
-    @ArquillianResource
-    protected Keycloak keycloak;
-
-    public Keycloak keycloak() {
-        return keycloak;
-    }
+//    @ArquillianResource
+//    protected Keycloak keycloak;
+//
+//    public Keycloak keycloak() {
+//        return keycloak;
+//    }
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java
index 081b1d4..fa42371 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java
@@ -59,9 +59,9 @@ public class AdminConsoleRealm extends AdminConsoleRealmsRoot {
         return configureMenu;
     }
 
-    public RealmResource realmResource() {
-        return realmsResource().realm(getConsoleRealm());
-    }
+//    public RealmResource realmResource() {
+//        return realmsResource().realm(getConsoleRealm());
+//    }
 
     public class ConfigureMenu {
 
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealmsRoot.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealmsRoot.java
index 5e3048f..467dc21 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealmsRoot.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealmsRoot.java
@@ -59,8 +59,8 @@ public class AdminConsoleRealmsRoot extends AdminConsole {
     @FindBy(css = "realm-selector")
     protected RealmSelector realmSelector;
 
-    public RealmsResource realmsResource() {
-        return keycloak.realms();
-    }
+//    public RealmsResource realmsResource() {
+//        return keycloak.realms();
+//    }
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java
index 36c692b..23103d3 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite.util;
 
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -33,6 +32,8 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 import java.io.*;
+import java.util.concurrent.TimeUnit;
+import org.jboss.logging.Logger;
 
 /**
  *
@@ -40,6 +41,8 @@ import java.io.*;
  */
 public class IOUtil {
 
+    private static final Logger log = Logger.getLogger(IOUtil.class);
+
     public static <T> T loadJson(InputStream is, Class<T> type) {
         try {
             return JsonSerialization.readValue(is, type);
@@ -71,7 +74,7 @@ public class IOUtil {
             DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
             DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
             return dBuilder.parse(is);
-        } catch (ParserConfigurationException|SAXException|IOException e) {
+        } catch (ParserConfigurationException | SAXException | IOException e) {
             throw new RuntimeException(e);
         }
     }
@@ -99,4 +102,36 @@ public class IOUtil {
         }
         node.setTextContent(node.getTextContent().replace(regex, replacement));
     }
+
+    public static void execCommand(String command, File dir) throws IOException, InterruptedException {
+        Process process = Runtime.getRuntime().exec(command, null, dir);
+        if (process.waitFor(10, TimeUnit.SECONDS)) {
+            if (process.exitValue() != 0) {
+                getOutput("ERROR", process.getErrorStream());
+                throw new RuntimeException("Adapter installation failed. Process exitValue: "
+                        + process.exitValue());
+            }
+            getOutput("OUTPUT", process.getInputStream());
+            log.debug("process.isAlive(): " + process.isAlive());
+        } else {
+            if (process.isAlive()) {
+                process.destroyForcibly();
+            }
+            throw new RuntimeException("Timeout after 10 seconds.");
+        }
+    }
+
+    public static void getOutput(String type, InputStream is) throws IOException {
+        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+        StringBuilder builder = new StringBuilder();
+        builder.append("<").append(type).append(">");
+        System.out.println(builder);
+        builder = new StringBuilder();
+        while (reader.ready()) {
+            System.out.println(reader.readLine());
+        }
+        builder.append("</").append(type).append(">");
+        System.out.println(builder);
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LogChecker.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LogChecker.java
new file mode 100644
index 0000000..8e16b34
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LogChecker.java
@@ -0,0 +1,37 @@
+package org.keycloak.testsuite.util;
+
+import java.io.File;
+import java.io.IOException;
+import org.apache.commons.io.FileUtils;
+import org.jboss.logging.Logger;
+
+/**
+ *
+ * @author vramik
+ * @author tkyjovsk
+ */
+public class LogChecker {
+
+    private static final Logger log = Logger.getLogger(LogChecker.class);
+
+    public static void checkServerLog(File logFile) throws IOException {
+        log.info(String.format("Checking server log: '%s'", logFile.getAbsolutePath()));
+        String logContent = FileUtils.readFileToString(logFile);
+
+        boolean containsError
+                = logContent.contains("ERROR")
+                || logContent.contains("SEVERE")
+                || logContent.contains("Exception ");
+
+        //There is expected string "Exception" in server log: Adding provider 
+        //singleton org.keycloak.services.resources.ModelExceptionMapper
+        if (containsError) {
+            throw new RuntimeException(String.format("Server log file contains ERROR: '%s'", logFile.getPath()));
+        }
+    }
+
+    public static void checkJBossServerLog(String jbossHome) throws IOException {
+        checkServerLog(new File(jbossHome + "/standalone/log/server.log"));
+    }
+
+}
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 9d3040f..92dc9c5 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
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite;
 
 import org.keycloak.testsuite.arquillian.TestContext;
@@ -33,9 +32,12 @@ import org.junit.Before;
 import org.junit.runner.RunWith;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.admin.client.resource.RealmsResource;
+import org.keycloak.models.Constants;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import static org.keycloak.testsuite.admin.Users.setPasswordFor;
+import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
 import org.keycloak.testsuite.arquillian.SuiteContext;
 import org.keycloak.testsuite.auth.page.WelcomePage;
 import org.keycloak.testsuite.util.OAuthClient;
@@ -66,11 +68,9 @@ public abstract class AbstractKeycloakTest {
 
     @ArquillianResource
     protected TestContext testContext;
-    
-    @ArquillianResource
+
     protected Keycloak adminClient;
 
-    @ArquillianResource
     protected OAuthClient oauthClient;
 
     protected List<RealmRepresentation> testRealmReps;
@@ -100,6 +100,11 @@ public abstract class AbstractKeycloakTest {
 
     @Before
     public void beforeAbstractKeycloakTest() {
+        adminClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
+                MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
+        oauthClient = new OAuthClient(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
+
+        
         adminUser = createAdminUserRepresentation();
 
         setDefaultPageUriParameters();
@@ -195,5 +200,9 @@ public abstract class AbstractKeycloakTest {
     public void removeRealm(RealmRepresentation realm) {
         adminClient.realms().realm(realm.getRealm()).remove();
     }
+    
+    public RealmsResource realmsResouce() {
+        return adminClient.realms();
+    }
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java
index fa115af..656df2f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java
@@ -25,7 +25,7 @@ import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.testsuite.AbstractAuthTest;
 import org.keycloak.testsuite.adapter.page.AppServerContextRoot;
-import org.keycloak.testsuite.arquillian.ContainersTestEnricher;
+import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
 import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
 
 import java.io.IOException;
@@ -78,7 +78,7 @@ public abstract class AbstractAdapterTest extends AbstractAuthTest {
     public abstract void addAdapterTestRealms(List<RealmRepresentation> testRealms);
 
     public boolean isRelative() {
-        return ContainersTestEnricher.isRelative(this.getClass());
+        return testContext.isRelativeAdapterTest();
     }
 
     protected void modifyClientRedirectUris(RealmRepresentation realm, String regex, String replacement) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AbstractClientRegistrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AbstractClientRegistrationTest.java
index fc572a1..c7085b3 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AbstractClientRegistrationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AbstractClientRegistrationTest.java
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite.client;
 
 import org.junit.After;
@@ -46,7 +45,7 @@ public abstract class AbstractClientRegistrationTest extends AbstractKeycloakTes
 
     @Before
     public void before() throws Exception {
-        reg = ClientRegistration.create().url(testContext.getAuthServerContextRoot() + "/auth", "test").build();
+        reg = ClientRegistration.create().url(suiteContext.getAuthServerInfo().getContextRoot() + "/auth", "test").build();
     }
 
     @After
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AdapterInstallationConfigTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AdapterInstallationConfigTest.java
index 55a9475..4272025 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AdapterInstallationConfigTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/AdapterInstallationConfigTest.java
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.keycloak.testsuite.client;
 
 import org.junit.Before;
@@ -87,7 +86,7 @@ public class AdapterInstallationConfigTest extends AbstractClientRegistrationTes
         AdapterConfig config = reg.getAdapterConfig(client.getClientId());
         assertNotNull(config);
 
-        assertEquals(testContext.getAuthServerContextRoot() + "/auth", config.getAuthServerUrl());
+        assertEquals(suiteContext.getAuthServerInfo().getContextRoot() + "/auth", config.getAuthServerUrl());
         assertEquals("test", config.getRealm());
 
         assertEquals(1, config.getCredentials().size());
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ContainersTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ContainersTest.java
new file mode 100644
index 0000000..27053ae
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ContainersTest.java
@@ -0,0 +1,34 @@
+package org.keycloak.testsuite;
+
+import java.util.List;
+import org.jboss.arquillian.container.test.api.ContainerController;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
+
+/**
+ *
+ * @author tkyjovsk
+ */
+public class ContainersTest extends AbstractKeycloakTest {
+
+    @ArquillianResource
+    ContainerController controller;
+
+    @Override
+    public void addTestRealms(List<RealmRepresentation> testRealms) {
+    }
+
+    
+    @Test
+    public void testAuthServer() {
+
+        log.info("AUTH SERVER should be started.");
+        assertTrue(controller.isStarted(AuthServerTestEnricher.getAuthServerQualifier()));
+        
+    }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
index 8c8f9b2..57e1692 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
@@ -1,19 +1,19 @@
 <!--
-  ~ 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.
-  -->
+~ 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.
+-->
 
 <arquillian xmlns="http://jboss.org/schema/arquillian"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -44,10 +44,73 @@
         <property name="deploymentExportPath">target/deployments</property>
     </engine>
     
-    <!-- PREVIOUS VERSIONS KEYCLOAK FOR MIGRATION TESTS -->
-    <!-- IT HAS TO BE LISTED ABOWE KEYCLOAK AUTH SERVERS -->
+    <!-- KEYCLOAK AUTH SERVERS -->
+    
+    <container qualifier="auth-server-undertow" mode="suite" >
+        <configuration>
+            <property name="enabled">${auth.server.undertow}</property>
+            <property name="bindAddress">localhost</property>
+            <property name="adapterImplClass">org.keycloak.testsuite.arquillian.undertow.CustomUndertowContainer</property>
+            <property name="bindHttpPort">${auth.server.http.port}</property>
+        </configuration>
+    </container>
+    
+    <container qualifier="auth-server-wildfly" mode="suite" >
+        <configuration>
+            <property name="enabled">${auth.server.wildfly}</property>
+            <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
+            <property name="jbossHome">${keycloak.home}</property>
+            <property name="javaVmArguments">-Djboss.socket.binding.port-offset=${auth.server.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m ${adapter.test.props}</property>
+            <property name="managementPort">${auth.server.management.port}</property>
+            <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
+        </configuration>
+    </container>
+    
+    <group qualifier="auth-server-wildfly-cluster">
+        <container qualifier="auth-server-wildfly-balancer" mode="suite" >
+            <configuration>
+                <property name="enabled">${auth.server.wildfly.cluster}</property>
+                <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
+                <property name="jbossHome">${wildfly.home}</property>
+                <property name="javaVmArguments">
+                    -Djboss.socket.binding.port-offset=${auth.server.port.offset} 
+                    -Xms64m -Xmx512m -XX:MaxPermSize=256m 
+                    ${adapter.test.props}
+                </property>
+                <property name="managementPort">${auth.server.management.port}</property>
+                <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
+            </configuration>
+        </container>
+        <container qualifier="auth-server-wildfly-backend1" mode="manual" >
+            <configuration>
+                <property name="enabled">${auth.server.wildfly.cluster}</property>
+                <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
+                <property name="jbossHome">${keycloak.backend1.home}</property>
+                <property name="javaVmArguments">
+                    -Djboss.socket.binding.port-offset=${auth.server.backend1.port.offset} 
+                    -Xms64m -Xmx512m -XX:MaxPermSize=256m 
+                    ${adapter.test.props}
+                </property>
+                <property name="managementPort">${auth.server.backend1.management.port}</property>
+                <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
+            </configuration>
+        </container>
+    </group>
+    
+    <container qualifier="auth-server-eap7" mode="suite" >
+        <configuration>
+            <property name="enabled">${auth.server.eap7}</property>
+            <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
+            <property name="jbossHome">${keycloak.home}</property>
+            <property name="javaVmArguments">-Djboss.socket.binding.port-offset=${auth.server.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m ${adapter.test.props}</property>
+            <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
+            <property name="managementPort">${auth.server.management.port}</property>
+        </configuration>
+    </container>
+
+    <!-- PREVIOUS VERSIONS OF KEYCLOAK FOR MIGRATION TESTS -->
     
-    <container qualifier="keycloak-1.6.1.Final" mode="suite" >
+    <container qualifier="migrated-auth-server-wildfly_kc16" mode="manual" >
         <configuration>
             <property name="enabled">${migration.kc16}</property>
             <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
@@ -66,7 +129,7 @@
         </configuration>
     </container>
     
-    <container qualifier="keycloak-1.5.1.Final" mode="suite" >
+    <container qualifier="migrated-auth-server-wildfly_kc15" mode="manual" >
         <configuration>
             <property name="enabled">${migration.kc15}</property>
             <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
@@ -85,7 +148,7 @@
         </configuration>
     </container>
     
-    <container qualifier="keycloak-1.4.0.Final" mode="suite" >
+    <container qualifier="migrated-auth-server-wildfly_kc14" mode="manual" >
         <configuration>
             <property name="enabled">${migration.kc14}</property>
             <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
@@ -96,7 +159,7 @@
         </configuration>
     </container>
     
-    <container qualifier="keycloak-1.3.1.Final" mode="suite" >
+    <container qualifier="migrated-auth-server-wildfly_kc13" mode="manual" >
         <configuration>
             <property name="enabled">${migration.kc13}</property>
             <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
@@ -107,7 +170,7 @@
         </configuration>
     </container>
     
-    <container qualifier="keycloak-1.2.0.Final" mode="suite" >
+    <container qualifier="migrated-auth-server-wildfly_kc12" mode="manual" >
         <configuration>
             <property name="enabled">${migration.kc12}</property>
             <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
@@ -118,37 +181,5 @@
         </configuration>
     </container>
     
-    <!-- KEYCLOAK AUTH SERVERS -->
-    
-    <container qualifier="auth-server-undertow" mode="suite" >
-        <configuration>
-            <property name="enabled">${auth.server.undertow}</property>
-            <property name="bindAddress">localhost</property>
-            <property name="adapterImplClass">org.keycloak.testsuite.arquillian.undertow.CustomUndertowContainer</property>
-            <property name="bindHttpPort">${auth.server.http.port}</property>
-        </configuration>
-    </container>
-    
-    <container qualifier="auth-server-wildfly" mode="suite" >
-        <configuration>
-            <property name="enabled">${auth.server.wildfly}</property>
-            <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
-            <property name="jbossHome">${keycloak.home}</property>
-            <property name="javaVmArguments">-Djboss.socket.binding.port-offset=${auth.server.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m ${adapter.test.props}</property>
-            <property name="managementPort">${auth.server.management.port}</property>
-            <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
-        </configuration>
-    </container>
-    
-    <container qualifier="auth-server-eap7" mode="suite" >
-        <configuration>
-            <property name="enabled">${auth.server.eap7}</property>
-            <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
-            <property name="jbossHome">${keycloak.home}</property>
-            <property name="javaVmArguments">-Djboss.socket.binding.port-offset=${auth.server.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m ${adapter.test.props}</property>
-            <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
-            <property name="managementPort">${auth.server.management.port}</property>
-        </configuration>
-    </container>
-    
+
 </arquillian>
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java
index bb70843..864ebee 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java
@@ -108,8 +108,6 @@ public class Client extends Clients {
 
     }
 
-    public ClientResource clientResource() {
-        return clientsResource().get(getId());
-    }
+
 
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java
index 58fac4d..945e72f 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java
@@ -126,8 +126,4 @@ public class Clients extends AdminConsoleRealm {
         }
     }
 
-    public ClientsResource clientsResource() {
-        return realmResource().clients();
-    }
-
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java
index 3542af2..67bbf52 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java
@@ -22,9 +22,5 @@ public class ClientRoles extends Client {
     public RolesTable roles() {
         return table;
     }
-    
-    public RolesResource rolesResource() {
-        return clientResource().roles();
-    }
 
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/idp/IdentityProviderSettings.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/idp/IdentityProviderSettings.java
index 275ddf4..f3f91a7 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/idp/IdentityProviderSettings.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/idp/IdentityProviderSettings.java
@@ -92,8 +92,4 @@ public class IdentityProviderSettings extends AdminConsoleRealm {
         return rows;
     }
     
-    public IdentityProvidersResource identityProviders() {
-        return realmResource().identityProviders();
-    }
-    
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/roles/Roles.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/roles/Roles.java
index 910e470..6c86255 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/roles/Roles.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/roles/Roles.java
@@ -35,8 +35,4 @@ public class Roles extends AdminConsoleRealm {
 
     }
 
-    public RolesResource rolesResource() {
-        return realmResource().roles();
-    }
-
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/User.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/User.java
index fba2adb..7cea05c 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/User.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/User.java
@@ -1,6 +1,5 @@
 package org.keycloak.testsuite.console.page.users;
 
-import org.keycloak.admin.client.resource.UserResource;
 import org.keycloak.testsuite.console.page.fragment.Breadcrumb;
 import static org.keycloak.testsuite.console.page.fragment.Breadcrumb.BREADCRUMB_XPATH;
 import org.openqa.selenium.WebElement;
@@ -76,8 +75,4 @@ public class User extends Users {
 
     }
     
-    public UserResource userResource() {
-        return usersResource().get(getId());
-    }
-
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/UserRoleMappings.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/UserRoleMappings.java
index 3a05b68..32c6bac 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/UserRoleMappings.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/UserRoleMappings.java
@@ -20,9 +20,5 @@ public class UserRoleMappings extends User {
     public UserRoleMappingsForm form() {
         return form;
     }
-    
-    public RoleMappingResource roleMappingResource() {
-        return userResource().roles();
-    }
 
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/Users.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/Users.java
index d5ffcb5..9e083a7 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/Users.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/users/Users.java
@@ -22,7 +22,6 @@ import org.openqa.selenium.support.FindBy;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.keycloak.admin.client.resource.UsersResource;
 import org.keycloak.representations.idm.UserRepresentation;
 
 import org.keycloak.testsuite.console.page.AdminConsoleRealm;
@@ -135,8 +134,4 @@ public class Users extends AdminConsoleRealm {
 
     }
     
-    public UsersResource usersResource() {
-        return realmResource().users();
-    }
-
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
index eb2fb5b..633b550 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
@@ -17,7 +17,6 @@
  */
 package org.keycloak.testsuite.console;
 
-import org.jboss.arquillian.graphene.findby.FindByJQuery;
 import org.jboss.arquillian.graphene.page.Page;
 import static org.junit.Assert.assertTrue;
 import org.junit.Before;
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java
index 0847294..f646675 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java
@@ -8,6 +8,8 @@ import java.util.Map;
 import org.jboss.arquillian.graphene.page.Page;
 import static org.junit.Assert.assertEquals;
 import org.junit.Before;
+import org.keycloak.admin.client.resource.ClientResource;
+import org.keycloak.admin.client.resource.ClientsResource;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 import static org.keycloak.testsuite.auth.page.login.OIDCLogin.OIDC;
@@ -50,7 +52,7 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
 
     public final String TEST_CLIENT_ID = "test-client";
     public final String TEST_REDIRECT_URIS = "http://example.test/app/*";
-    
+
     @Page
     protected Clients clientsPage;
     @Page
@@ -87,12 +89,12 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
         client.setConsentRequired(false);
         return client;
     }
-    
+
     public static ClientRepresentation createOidcClientRep(OidcAccessType accessType, String clientId, String... redirectUris) {
         ClientRepresentation client = createClientRep(clientId);
-       
+
         client.setProtocol(OIDC);
-        
+
         switch (accessType) {
             case BEARER_ONLY:
                 client.setBearerOnly(true);
@@ -116,24 +118,24 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
         }
         return client;
     }
-    
+
     public static ClientRepresentation createSamlClientRep(String clinetId) {
         ClientRepresentation client = createClientRep(clinetId);
-        
+
         client.setProtocol(SAML);
-        
+
         client.setFrontchannelLogout(true);
         client.setAttributes(getSAMLAttributes());
-        
+
         return client;
     }
-    
+
     private static void setRedirectUris(ClientRepresentation client, String... redirectUris) {
         List<String> redirectUrisList = new ArrayList<>();
         redirectUrisList.addAll(Arrays.asList(redirectUris));
         client.setRedirectUris(redirectUrisList);
     }
-    
+
     protected static void setExpectedWebOrigins(ClientRepresentation client) {
         List<String> webOrigins = new ArrayList<>();
         for (String redirectUri : client.getRedirectUris()) {
@@ -143,7 +145,7 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
         }
         client.setWebOrigins(webOrigins);
     }
-    
+
     public ClientRepresentation findClientByClientId(String clientId) {
         ClientRepresentation found = null;
         for (ClientRepresentation clientRepresentation : testRealmResource().clients().findAll()) {
@@ -154,7 +156,7 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
         }
         return found;
     }
-    
+
     public void assertClientSettingsEqual(ClientRepresentation c1, ClientRepresentation c2) {
         assertEqualsStringAttributes(c1.getClientId(), c2.getClientId());
         assertEqualsStringAttributes(c1.getName(), c2.getName());
@@ -174,38 +176,37 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
             }
             assertEqualsBooleanAttributes(c1.isSurrogateAuthRequired(), c2.isSurrogateAuthRequired());
             assertEqualsBooleanAttributes(c1.isServiceAccountsEnabled(), c2.isServiceAccountsEnabled());
-        }
-        else if (c1.getProtocol().equals(SAML)) {
+        } else if (c1.getProtocol().equals(SAML)) {
             assertEqualsBooleanAttributes(c1.isFrontchannelLogout(), c2.isFrontchannelLogout());
         }
     }
-    
+
     public void assertClientSamlAttributes(Map<String, String> expected, Map<String, String> actual) {
         for (String key : expected.keySet()) {
             assertEquals("Expected attribute " + key, expected.get(key), actual.get(key));
         }
     }
-    
+
     protected static Map<String, String> getSAMLAttributes() {
         Map<String, String> attributes = new HashMap<>();
         attributes.put(SAML_ASSERTION_SIGNATURE, "true");
         attributes.put(SAML_AUTHNSTATEMENT, "false");
-	attributes.put(SAML_CLIENT_SIGNATURE,	"true");
-	attributes.put(SAML_ENCRYPT, "true");
-	attributes.put(SAML_FORCE_POST_BINDING, "true");
-	attributes.put(SAML_MULTIVALUED_ROLES, "false");
-	attributes.put(SAML_SERVER_SIGNATURE,	"true");
-	attributes.put(SAML_SIGNATURE_ALGORITHM, "RSA_SHA512");
-	attributes.put(SAML_ASSERTION_CONSUMER_URL_POST, "http://example0.test");
-	attributes.put(SAML_ASSERTION_CONSUMER_URL_REDIRECT, "http://example1.test");
-	attributes.put(SAML_FORCE_NAME_ID_FORMAT, "true");
-	attributes.put(SAML_NAME_ID_FORMAT, "email");
-	attributes.put(SAML_SIGNATURE_CANONICALIZATION_METHOD, "http://www.w3.org/2001/10/xml-exc-c14n#WithComments");
-	attributes.put(SAML_SINGLE_LOGOUT_SERVICE_URL_POST, "http://example2.test");
-	attributes.put(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT, "http://example3.test");
+        attributes.put(SAML_CLIENT_SIGNATURE, "true");
+        attributes.put(SAML_ENCRYPT, "true");
+        attributes.put(SAML_FORCE_POST_BINDING, "true");
+        attributes.put(SAML_MULTIVALUED_ROLES, "false");
+        attributes.put(SAML_SERVER_SIGNATURE, "true");
+        attributes.put(SAML_SIGNATURE_ALGORITHM, "RSA_SHA512");
+        attributes.put(SAML_ASSERTION_CONSUMER_URL_POST, "http://example0.test");
+        attributes.put(SAML_ASSERTION_CONSUMER_URL_REDIRECT, "http://example1.test");
+        attributes.put(SAML_FORCE_NAME_ID_FORMAT, "true");
+        attributes.put(SAML_NAME_ID_FORMAT, "email");
+        attributes.put(SAML_SIGNATURE_CANONICALIZATION_METHOD, "http://www.w3.org/2001/10/xml-exc-c14n#WithComments");
+        attributes.put(SAML_SINGLE_LOGOUT_SERVICE_URL_POST, "http://example2.test");
+        attributes.put(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT, "http://example3.test");
         return attributes;
     }
-    
+
     public ProtocolMapperRepresentation findClientMapperByName(String clientId, String mapperName) {
         ProtocolMapperRepresentation found = null;
         for (ProtocolMapperRepresentation mapper : testRealmResource().clients().get(clientId).getProtocolMappers().getMappers()) {
@@ -215,4 +216,13 @@ public abstract class AbstractClientTest extends AbstractConsoleTest {
         }
         return found;
     }
+
+    public ClientsResource clientsResource() {
+        return testRealmResource().clients();
+    }
+
+    public ClientResource clientResource(String id) {
+        return clientsResource().get(id);
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java
index d3aa64f..14fff17 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java
@@ -153,11 +153,11 @@ public class ClientSettingsTest extends AbstractClientTest {
         c.setPublicClient(true);
         c.setBearerOnly(true);
 
-        Response r = clientsPage.clientsResource().create(c);
+        Response r = clientsResource().create(c);
         r.close();
         clientSettingsPage.setId(getCreatedId(r));
 
-        c = clientSettingsPage.clientResource().toRepresentation();
+        c = clientResource(clientSettingsPage.getId()).toRepresentation();
         assertTrue(c.isBearerOnly());
         assertTrue(c.isPublicClient());
     }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java
index c257564..ddbaa8c 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java
@@ -18,6 +18,7 @@ import javax.ws.rs.core.Response;
 import java.util.List;
 
 import static org.junit.Assert.assertEquals;
+import org.keycloak.admin.client.resource.ClientsResource;
 import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.CONFIDENTIAL;
 
 
@@ -50,12 +51,12 @@ public class AdminEventsTest extends AbstractConsoleTest {
     @Test
     public void clientsAdminEventsTest() {
         newClient = AbstractClientTest.createOidcClientRep(CONFIDENTIAL, "test_client", "http://example.test/test_client/*");
-        Response response = clientsPage.clientsResource().create(newClient);
+        Response response = clientsResource().create(newClient);
         String id = ApiUtil.getCreatedId(response);
         response.close();
         newClient.setClientId("test_client2");
-        clientsPage.clientsResource().get(id).update(newClient);
-        clientsPage.clientsResource().get(id).remove();
+        clientsResource().get(id).update(newClient);
+        clientsResource().get(id).remove();
 
         adminEventsPage.navigateTo();
         adminEventsPage.table().filter();
@@ -85,4 +86,8 @@ public class AdminEventsTest extends AbstractConsoleTest {
         resultList.get(0).findElement(By.xpath("//td[text()='DELETE']"));
         resultList.get(0).findElement(By.xpath("//td[text()='clients/" + id + "']"));
     }
+    
+    public ClientsResource clientsResource() {
+        return testRealmResource().clients();
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/AbstractRolesTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/AbstractRolesTest.java
index 701e798..cb66b8f 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/AbstractRolesTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/AbstractRolesTest.java
@@ -2,6 +2,7 @@ package org.keycloak.testsuite.console.roles;
 
 import org.jboss.arquillian.graphene.page.Page;
 import org.junit.Before;
+import org.keycloak.admin.client.resource.RoleMappingResource;
 import org.keycloak.testsuite.console.AbstractConsoleTest;
 import org.keycloak.testsuite.console.page.roles.Roles;
 import org.keycloak.testsuite.console.page.users.User;
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java
index 67baad2..202d004 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java
@@ -4,6 +4,7 @@ import org.jboss.arquillian.graphene.page.Page;
 import static org.junit.Assert.assertTrue;
 import org.junit.Before;
 import org.junit.Test;
+import org.keycloak.admin.client.resource.RolesResource;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import static org.keycloak.testsuite.admin.ApiUtil.createUserWithAdminClient;
@@ -31,7 +32,7 @@ public class DefaultRolesTest extends AbstractRolesTest {
     public void beforeDefaultRolesTest() {
         // create a role via admin client
         defaultRoleRep = new RoleRepresentation("default-role", "", false);
-        rolesPage.rolesResource().create(defaultRoleRep);
+        rolesResource().create(defaultRoleRep);
 
         defaultRolesPage.navigateTo();
         // navigate to default roles page
@@ -58,4 +59,8 @@ public class DefaultRolesTest extends AbstractRolesTest {
         assertTrue(userRolesPage.form().isAssignedRole(defaultRoleName));
     }
 
+    public RolesResource rolesResource() {
+        return testRealmResource().roles();
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/users/AbstractUserTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/users/AbstractUserTest.java
index 3ddf899..585080d 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/users/AbstractUserTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/users/AbstractUserTest.java
@@ -2,6 +2,8 @@ package org.keycloak.testsuite.console.users;
 
 import org.jboss.arquillian.graphene.page.Page;
 import org.junit.Before;
+import org.keycloak.admin.client.resource.UserResource;
+import org.keycloak.admin.client.resource.UsersResource;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.console.AbstractConsoleTest;
 import org.keycloak.testsuite.console.page.users.CreateUser;
@@ -35,5 +37,13 @@ public abstract class AbstractUserTest extends AbstractConsoleTest {
         createUserPage.form().setValues(user);
         createUserPage.form().save();
     }
-
+    
+    public UsersResource usersResource() {
+        return testRealmResource().users();
+    }
+    
+    public UserResource userResource(String id) {
+        return usersResource().get(id);
+    }
+    
 }