From a264c1588674499829e13d054ee8250c9e9b5e08 Mon Sep 17 00:00:00 2001 From: Tomas Kyjovsky Date: Sun, 7 Feb 2016 19:38:40 +0100 Subject: [PATCH 1/6] KEYCLOAK-1678: Configuration of remote (tcp) H2 datasource for wildfly. --- .../integration-arquillian/servers/pom.xml | 7 ++ .../servers/wildfly/pom.xml | 95 ++++++++++++++----- .../src/main/xslt/datasource-jdbc-url.xsl | 36 +++++++ 3 files changed, 113 insertions(+), 25 deletions(-) create mode 100644 testsuite/integration-arquillian/servers/wildfly/src/main/xslt/datasource-jdbc-url.xsl diff --git a/testsuite/integration-arquillian/servers/pom.xml b/testsuite/integration-arquillian/servers/pom.xml index 070dfb6799..a164099c19 100644 --- a/testsuite/integration-arquillian/servers/pom.xml +++ b/testsuite/integration-arquillian/servers/pom.xml @@ -40,6 +40,13 @@ wildfly + + auth-server-wildfly-cluster + + wildfly + + + auth-server-eap7 diff --git a/testsuite/integration-arquillian/servers/wildfly/pom.xml b/testsuite/integration-arquillian/servers/wildfly/pom.xml index a39738aa6d..87f8674d01 100644 --- a/testsuite/integration-arquillian/servers/wildfly/pom.xml +++ b/testsuite/integration-arquillian/servers/wildfly/pom.xml @@ -1,20 +1,20 @@ +~ 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. +--> @@ -254,16 +254,16 @@ copy-resources - ${keycloak.server.home}/standalone/configuration - - - src/main/keystore - - keycloak.jks - keycloak.truststore - - - + ${keycloak.server.home}/standalone/configuration + + + src/main/keystore + + keycloak.jks + keycloak.truststore + + + @@ -412,5 +412,50 @@ + + + auth-server-wildfly-cluster + + + + org.codehaus.mojo + xml-maven-plugin + + + configure-wildfly-datasource + process-resources + + transform + + + + + + ${keycloak.server.home}/standalone/configuration + + standalone-ha.xml + + src/main/xslt/datasource-jdbc-url.xsl + ${keycloak.server.home}/standalone/configuration + + + pool.name + KeycloakDS + + + jdbc.url + jdbc:h2:tcp://${jboss.bind.address:localhost}:9092/mem:keycloak;DB_CLOSE_DELAY=-1 + + + + + + + + + + + + diff --git a/testsuite/integration-arquillian/servers/wildfly/src/main/xslt/datasource-jdbc-url.xsl b/testsuite/integration-arquillian/servers/wildfly/src/main/xslt/datasource-jdbc-url.xsl new file mode 100644 index 0000000000..589ee4cc1d --- /dev/null +++ b/testsuite/integration-arquillian/servers/wildfly/src/main/xslt/datasource-jdbc-url.xsl @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 89250a69fb96735f2aa67944ba9cb2d742b6f24f Mon Sep 17 00:00:00 2001 From: Tomas Kyjovsky Date: Sun, 7 Feb 2016 19:39:30 +0100 Subject: [PATCH 2/6] KEYCLOAK-1678: H2TestEnricher for running H2 server instance during integration tests. --- .../KeycloakArquillianExtension.java | 4 +- .../arquillian/h2/H2TestEnricher.java | 40 +++++++++++++++++++ .../integration-arquillian/tests/pom.xml | 4 +- 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/h2/H2TestEnricher.java 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 7154b8a335..275974f842 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 @@ -26,6 +26,7 @@ import org.jboss.arquillian.core.spi.LoadableExtension; import org.jboss.arquillian.graphene.location.CustomizableURLResourceProvider; import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider; import org.jboss.arquillian.test.spi.execution.TestExecutionDecider; +import org.keycloak.testsuite.arquillian.h2.H2TestEnricher; import org.keycloak.testsuite.arquillian.migration.MigrationTestExecutionDecider; import org.keycloak.testsuite.arquillian.undertow.CustomUndertowContainer; @@ -48,7 +49,8 @@ public class KeycloakArquillianExtension implements LoadableExtension { .service(DeploymentScenarioGenerator.class, DeploymentTargetModifier.class) .service(ApplicationArchiveProcessor.class, DeploymentArchiveProcessor.class) .observer(AuthServerTestEnricher.class) - .observer(AppServerTestEnricher.class); + .observer(AppServerTestEnricher.class) + .observer(H2TestEnricher.class); builder .service(DeployableContainer.class, CustomUndertowContainer.class); diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/h2/H2TestEnricher.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/h2/H2TestEnricher.java new file mode 100644 index 0000000000..705cbad80e --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/h2/H2TestEnricher.java @@ -0,0 +1,40 @@ +package org.keycloak.testsuite.arquillian.h2; + +import java.sql.SQLException; +import org.jboss.arquillian.core.api.annotation.Observes; +import org.jboss.arquillian.test.spi.event.suite.AfterSuite; +import org.jboss.arquillian.test.spi.event.suite.BeforeSuite; +import org.jboss.logging.Logger; +import org.h2.tools.Server; + +/** + * Starts H2 before suite and stops it after. + * + * @author tkyjovsk + */ +public class H2TestEnricher { + + protected final Logger log = Logger.getLogger(this.getClass()); + + boolean runH2 = Boolean.parseBoolean(System.getProperty("run.h2", "false")); + + private Server server = null; + + public void startH2(@Observes(precedence = 2) BeforeSuite event) throws SQLException { + if (runH2) { + log.info("Starting H2 database."); + server = Server.createTcpServer(); + server.start(); + log.info(String.format("URL: %s", server.getURL())); + } + } + + public void stopH2(@Observes(precedence = -2) AfterSuite event) { + if (runH2 && server.isRunning(false)) { + log.info("Stopping H2 database."); + server.stop(); + assert !server.isRunning(false); + } + } + +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml index 92c02bd178..b8047837cd 100644 --- a/testsuite/integration-arquillian/tests/pom.xml +++ b/testsuite/integration-arquillian/tests/pom.xml @@ -398,6 +398,7 @@ com.h2database h2 + compile org.hibernate @@ -450,6 +451,7 @@ ${containers.home}/keycloak-${project.version} ${keycloak.home}/standalone/configuration + 1.3.173 @@ -476,7 +478,7 @@ - + auth-server-eap7 From a275a2479730afbc0e02ca75d26afeb2f8b76011 Mon Sep 17 00:00:00 2001 From: Tomas Kyjovsky Date: Mon, 8 Feb 2016 16:12:47 +0100 Subject: [PATCH 3/6] Added auth-server-wildfly-cluster profile. --- .../base/src/test/resources/arquillian.xml | 16 +++- .../integration-arquillian/tests/pom.xml | 95 +++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) 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 6c13daa20b..9ad14da3a7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml @@ -71,7 +71,7 @@ ${auth.server.wildfly.cluster} org.jboss.as.arquillian.container.managed.ManagedDeployableContainer - ${wildfly.home} + ${keycloak.balancer.home} -Djboss.socket.binding.port-offset=${auth.server.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m @@ -95,6 +95,20 @@ ${startup.timeout.sec} + + + ${auth.server.wildfly.cluster} + org.jboss.as.arquillian.container.managed.ManagedDeployableContainer + ${keycloak.backend2.home} + + -Djboss.socket.binding.port-offset=${auth.server.backend2.port.offset} + -Xms64m -Xmx512m -XX:MaxPermSize=256m + ${adapter.test.props} + + ${auth.server.backend2.management.port} + ${startup.timeout.sec} + + diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml index 5170ebf7ba..715cadbe03 100644 --- a/testsuite/integration-arquillian/tests/pom.xml +++ b/testsuite/integration-arquillian/tests/pom.xml @@ -451,6 +451,101 @@ + + + + auth-server-wildfly-cluster + + auth-server-wildfly-cluster + 300 + + 1.3.173 + + ${containers.home}/balancer/wildfly-${project.version} + ${containers.home}/node1/keycloak-${project.version} + ${containers.home}/node2/keycloak-${project.version} + + ${keycloak.backend1.home} + ${keycloak.home}/standalone/configuration + + + + org.wildfly + wildfly-arquillian-container-managed + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + true + false + ${adapter.test.props} + + ${keycloak.balancer.home} + ${keycloak.backend1.home} + ${keycloak.backend2.home} + + + 101 + 102 + + 8181 + 8181 + + 8544 + 8545 + + 10091 + 10092 + + 10100 + 10101 + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack-auth-server-wildfly + generate-test-resources + + unpack + + + + + org.keycloak.testsuite + integration-arquillian-server-wildfly + ${project.version} + zip + balancer + ${containers.home} + + + org.keycloak.testsuite + integration-arquillian-server-wildfly + ${project.version} + zip + backend + ${containers.home} + + + true + + + + + + + + auth-server-eap7 From db25a81d23cf88bc4991edbce27b3b2ac020c7a4 Mon Sep 17 00:00:00 2001 From: Tomas Kyjovsky Date: Tue, 9 Feb 2016 05:20:19 +0100 Subject: [PATCH 4/6] KEYCLOAK-1678 Added module for building wildfly mod_cluster load balancer. --- .../integration-arquillian/servers/pom.xml | 1 + .../servers/wildfly-balancer/assembly.xml | 46 +++++++ .../servers/wildfly-balancer/pom.xml | 118 ++++++++++++++++++ .../src/main/xslt/mod_cluster.xsl | 73 +++++++++++ 4 files changed, 238 insertions(+) create mode 100644 testsuite/integration-arquillian/servers/wildfly-balancer/assembly.xml create mode 100644 testsuite/integration-arquillian/servers/wildfly-balancer/pom.xml create mode 100644 testsuite/integration-arquillian/servers/wildfly-balancer/src/main/xslt/mod_cluster.xsl diff --git a/testsuite/integration-arquillian/servers/pom.xml b/testsuite/integration-arquillian/servers/pom.xml index a164099c19..a4a3c81b60 100644 --- a/testsuite/integration-arquillian/servers/pom.xml +++ b/testsuite/integration-arquillian/servers/pom.xml @@ -44,6 +44,7 @@ auth-server-wildfly-cluster wildfly + wildfly-balancer diff --git a/testsuite/integration-arquillian/servers/wildfly-balancer/assembly.xml b/testsuite/integration-arquillian/servers/wildfly-balancer/assembly.xml new file mode 100644 index 0000000000..a3e36ae773 --- /dev/null +++ b/testsuite/integration-arquillian/servers/wildfly-balancer/assembly.xml @@ -0,0 +1,46 @@ + + + + + wildfly-balancer + + + zip + + + false + + + + ${wildfly.balancer.home} + wildfly-balancer-${project.version} + + **/*.sh + + + + ${wildfly.balancer.home} + wildfly-balancer-${project.version} + + **/*.sh + + 0755 + + + + diff --git a/testsuite/integration-arquillian/servers/wildfly-balancer/pom.xml b/testsuite/integration-arquillian/servers/wildfly-balancer/pom.xml new file mode 100644 index 0000000000..895be72eb1 --- /dev/null +++ b/testsuite/integration-arquillian/servers/wildfly-balancer/pom.xml @@ -0,0 +1,118 @@ + + + + + + org.keycloak.testsuite + integration-arquillian-servers + 1.9.0.Final-SNAPSHOT + + 4.0.0 + + integration-arquillian-server-wildfly-balancer + pom + Wildfly Load Balancer + + + ${project.build.directory}/unpacked/wildfly-${wildfly.version} + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack-wildfly + generate-resources + + unpack + + + + + org.wildfly + wildfly-dist + ${wildfly.version} + zip + ${project.build.directory}/unpacked + + + + + + + + + org.codehaus.mojo + xml-maven-plugin + + + configure-mod-cluster + process-resources + + transform + + + + + ${wildfly.balancer.home}/standalone/configuration + + standalone.xml + + src/main/xslt/mod_cluster.xsl + ${wildfly.balancer.home}/standalone/configuration + + + + + + + + + maven-assembly-plugin + + + create-zip + package + + single + + + + assembly.xml + + false + + + + + + + + diff --git a/testsuite/integration-arquillian/servers/wildfly-balancer/src/main/xslt/mod_cluster.xsl b/testsuite/integration-arquillian/servers/wildfly-balancer/src/main/xslt/mod_cluster.xsl new file mode 100644 index 0000000000..9cb3774a74 --- /dev/null +++ b/testsuite/integration-arquillian/servers/wildfly-balancer/src/main/xslt/mod_cluster.xsl @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 4a8b19cfce42b9025f07a7b9f80ed2eb6925260d Mon Sep 17 00:00:00 2001 From: Tomas Kyjovsky Date: Tue, 9 Feb 2016 05:21:11 +0100 Subject: [PATCH 5/6] KEYCLOAK-1678 Added initial cluster test for 2-node cluster. --- .../integration-arquillian/tests/base/pom.xml | 30 +--- .../arquillian/AppServerTestEnricher.java | 11 +- .../arquillian/AuthServerTestEnricher.java | 7 +- .../testsuite/arquillian/SuiteContext.java | 8 +- .../keycloak/testsuite/ContainersTest.java | 34 ----- .../cluster/AbstractClusterTest.java | 59 ++++++++ .../testsuite/cluster/TwoNodeClusterTest.java | 131 ++++++++++++++++++ .../base/src/test/resources/arquillian.xml | 6 + .../integration-arquillian/tests/pom.xml | 52 +++++-- 9 files changed, 260 insertions(+), 78 deletions(-) delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ContainersTest.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/TwoNodeClusterTest.java diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml index e08b2ade8b..a0e7f09c95 100644 --- a/testsuite/integration-arquillian/tests/base/pom.xml +++ b/testsuite/integration-arquillian/tests/base/pom.xml @@ -35,7 +35,10 @@ - - - - - + + **/migration/**/*Test.java + + **/cluster/**/*Test.java @@ -108,29 +111,4 @@ - - - no-account - - - **/account/**/*Test.java - - - - no-client - - - **/client/**/*Test.java - - - - adapters-only - - **/account/**/*Test.java - **/client/**/*Test.java - **/migration/**/*Test.java - - - - 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 index 9289593232..e8703b450d 100644 --- 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 @@ -40,9 +40,10 @@ public class AppServerTestEnricher { String appServerQ = (annotatedClass == null ? null : annotatedClass.getAnnotation(AppServerContainer.class).value()); - return appServerQ == null || appServerQ.isEmpty() - ? getAuthServerQualifier() // app server == auth server - : appServerQ; + return annotatedClass == null ? null // no @AppServerContainer annotation --> no adapter test + : (appServerQ == null || appServerQ.isEmpty() // @AppServerContainer annotation present but qualifier not set --> relative adapter test + ? getAuthServerQualifier() // app server == auth server + : appServerQ); } public static String getAppServerContextRoot() { @@ -129,7 +130,7 @@ public class AppServerTestEnricher { String jbossHomePath = appServerInfo.getProperties().get("jbossHome"); File bin = new File(jbossHomePath + "/bin"); - + File clientJar = new File(jbossHomePath + "/bin/client/jboss-cli-client.jar"); if (!clientJar.exists()) { clientJar = new File(jbossHomePath + "/bin/client/jboss-client.jar"); // AS7 @@ -137,7 +138,7 @@ public class AppServerTestEnricher { if (!clientJar.exists()) { throw new IOException("JBoss CLI client JAR not found."); } - + String command = "java -jar " + clientJar.getAbsolutePath(); String adapterScript = "adapter-install.cli"; String samlAdapterScript = "adapter-install-saml.cli"; 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 index 5000e3b482..9cbfce6e6a 100644 --- 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 @@ -110,7 +110,10 @@ public class AuthServerTestEnricher { boolean authServerCluster = authServerQualifier.endsWith("-cluster"); - String authServerType = authServerQualifier.replaceAll("^auth-server-", "").replaceAll("-cluster$", ""); + String authServerType = authServerQualifier.replaceAll("auth-server-", "").replaceAll("-cluster", ""); + + log.info("authServerType:" + authServerType); + String authServerFrontend = authServerCluster ? "auth-server-" + authServerType + "-balancer" // in cluster mode the load-balancer container serves as auth server frontend : authServerQualifier; // single-node mode @@ -133,7 +136,7 @@ public class AuthServerTestEnricher { 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()) { + 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)); } 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 c4bd23b45a..929c23d2b7 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 @@ -93,9 +93,13 @@ public final class SuiteContext { @Override public String toString() { + String containers = "Auth server: " + (isAuthServerCluster() ? "\nFrontend: " : "") + + authServerInfo.getQualifier() + "\n"; + for (ContainerInfo bInfo : getAuthServerBackendsInfo()) { + containers += "Backend: " + bInfo + "\n"; + } return "SUITE CONTEXT:\n" - + "Auth server: " + authServerInfo.getQualifier() + "\n" - +(isAuthServerCluster() ? "Auth server cluster: " + getAuthServerBackendsInfo().size() + " nodes+\n" : ""); + + containers; } } 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 deleted file mode 100644 index 27053aef54..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ContainersTest.java +++ /dev/null @@ -1,34 +0,0 @@ -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 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/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java new file mode 100644 index 0000000000..9dd6089e06 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java @@ -0,0 +1,59 @@ +package org.keycloak.testsuite.cluster; + +import java.util.ArrayList; +import java.util.List; +import org.jboss.arquillian.container.test.api.ContainerController; +import org.jboss.arquillian.test.api.ArquillianResource; +import static org.junit.Assert.assertTrue; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.models.Constants; +import org.keycloak.testsuite.AbstractKeycloakTest; +import org.keycloak.testsuite.arquillian.ContainerInfo; +import static org.keycloak.testsuite.auth.page.AuthRealm.ADMIN; +import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER; + +/** + * + * @author tkyjovsk + */ +public abstract class AbstractClusterTest extends AbstractKeycloakTest { + + @ArquillianResource + protected ContainerController controller; + + protected List backendAdminClients = new ArrayList<>(); + + public void startBackendNodes(int count) { + if (count < 0 || count > 10) { + throw new IllegalArgumentException(); + } + assertTrue(suiteContext.getAuthServerBackendsInfo().size() >= count); + for (int i = 0; i < count; i++) { + + ContainerInfo backendNode = suiteContext.getAuthServerBackendsInfo().get(i); + + controller.start(backendNode.getQualifier()); + assertTrue(controller.isStarted(backendNode.getQualifier())); + + log.info("Initializing admin client for: '" + backendNode.getContextRoot() + "/auth'"); + backendAdminClients.add(Keycloak.getInstance(backendNode.getContextRoot() + "/auth", + MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID)); + } + } + + protected ContainerInfo backendInfo(int i) { + return suiteContext.getAuthServerBackendsInfo().get(i); + } + + protected void startBackendNode(int i) { + String container = backendInfo(i).getQualifier(); + if (!controller.isStarted(container)) { + controller.start(container); + } + } + + protected void stopBackendNode(int i) { + controller.kill(backendInfo(i).getQualifier()); + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/TwoNodeClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/TwoNodeClusterTest.java new file mode 100644 index 0000000000..0984124c0a --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/TwoNodeClusterTest.java @@ -0,0 +1,131 @@ +package org.keycloak.testsuite.cluster; + +import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testsuite.arquillian.ContainerInfo; +import static org.keycloak.testsuite.auth.page.AuthRealm.TEST; +import static org.keycloak.testsuite.util.WaitUtils.pause; + +/** + * + * @author tkyjovsk + */ +public class TwoNodeClusterTest extends AbstractClusterTest { + + @Override + public void addTestRealms(List testRealms) { + } + + @Before + public void beforeTwoNodeClusterTest() { + startBackendNodes(2); + pause(3000); + } + + @Test + public void testRealm() { + testRealm(TEST, false); + } + + @Test + public void testRealmWithFailover() { + testRealm(TEST + "_fo", true); + } + + public void testRealm(String realm, boolean containerFailover) { + RealmRepresentation testRealm = new RealmRepresentation(); + testRealm.setRealm(realm); + testRealm.setEnabled(true); + + // CREATE on node1 + log.info("Creating test realm via node1."); + backend1AdminClient().realms().create(testRealm); + log.info("Test realm created."); + + // check if created on node1 + RealmRepresentation testRealmOnBackend1 = backend1AdminClient().realms().realm(realm).toRepresentation(); + assertEquals(testRealmOnBackend1.getRealm(), testRealm.getRealm()); + if (containerFailover) { + stopBackend1(); + } + + // check if created on node2 + RealmRepresentation testRealmOnBackend2 = backend2AdminClient().realms().realm(realm).toRepresentation(); + assertEquals(testRealmOnBackend1.getId(), testRealmOnBackend2.getId()); + assertEquals(testRealmOnBackend1.getRealm(), testRealmOnBackend2.getRealm()); + + failback(); + + // UPDATE on node2 + testRealmOnBackend2.setRealm(realm + "_updated"); + backend2AdminClient().realms().realm(realm).update(testRealmOnBackend2); + if (containerFailover) { + stopBackend2(); + } + // check if updated on node1 + testRealmOnBackend1 = backend1AdminClient().realms().realm(realm).toRepresentation(); + assertEquals(testRealmOnBackend1.getId(), testRealmOnBackend2.getId()); + assertEquals(testRealmOnBackend1.getRealm(), testRealmOnBackend2.getRealm()); + + failback(); + + // DELETE on node1 + backend1AdminClient().realms().realm(realm).remove(); + if (containerFailover) { + stopBackend1(); + } + // check if deleted on node2 + boolean testRealmOnBackend2Exists = false; + for (RealmRepresentation realmOnBackend2 : backend2AdminClient().realms().findAll()) { + if (realm.equals(realmOnBackend2.getRealm()) + || testRealmOnBackend1.getId().equals(realmOnBackend2.getId())) { + testRealmOnBackend2Exists = true; + break; + } + } + assertFalse(testRealmOnBackend2Exists); + } + + protected ContainerInfo backend1Info() { + return backendInfo(0); + } + + protected ContainerInfo backend2Info() { + return backendInfo(1); + } + + protected Keycloak backend1AdminClient() { + return backendAdminClients.get(0); + } + + protected Keycloak backend2AdminClient() { + return backendAdminClients.get(1); + } + + protected void startBackend1() { + startBackendNode(0); + } + + protected void startBackend2() { + startBackendNode(1); + } + + protected void failback() { + startBackend1(); + startBackend2(); + } + + protected void stopBackend1() { + stopBackendNode(0); + } + + protected void stopBackend2() { + stopBackendNode(1); + } + +} 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 9ad14da3a7..404f5b5fe3 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml @@ -86,11 +86,14 @@ ${auth.server.wildfly.cluster} org.jboss.as.arquillian.container.managed.ManagedDeployableContainer ${keycloak.backend1.home} + standalone-ha.xml -Djboss.socket.binding.port-offset=${auth.server.backend1.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m ${adapter.test.props} + -Djboss.node.name=node1 + ${auth.server.backend1.management.port} ${startup.timeout.sec} @@ -100,11 +103,14 @@ ${auth.server.wildfly.cluster} org.jboss.as.arquillian.container.managed.ManagedDeployableContainer ${keycloak.backend2.home} + standalone-ha.xml -Djboss.socket.binding.port-offset=${auth.server.backend2.port.offset} -Xms64m -Xmx512m -XX:MaxPermSize=256m ${adapter.test.props} + -Djboss.node.name=node2 + ${auth.server.backend2.management.port} ${startup.timeout.sec} diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml index 715cadbe03..4e35234120 100644 --- a/testsuite/integration-arquillian/tests/pom.xml +++ b/testsuite/integration-arquillian/tests/pom.xml @@ -159,7 +159,27 @@ - + + + no-account + + **/account/**/*Test.java + + + + no-client + + **/client/**/*Test.java + + + + no-base + + **/account/**/*Test.java + **/client/**/*Test.java + + + common-test-dependencies @@ -456,12 +476,15 @@ auth-server-wildfly-cluster + + - + auth-server-wildfly-cluster 300 1.3.173 - ${containers.home}/balancer/wildfly-${project.version} + ${containers.home}/balancer/wildfly-balancer-${project.version} ${containers.home}/node1/keycloak-${project.version} ${containers.home}/node2/keycloak-${project.version} @@ -482,6 +505,8 @@ maven-surefire-plugin + true + true false ${adapter.test.props} @@ -495,7 +520,7 @@ 102 8181 - 8181 + 8182 8544 8545 @@ -522,19 +547,24 @@ org.keycloak.testsuite - integration-arquillian-server-wildfly + integration-arquillian-server-wildfly-balancer ${project.version} zip - balancer - ${containers.home} + ${containers.home}/balancer org.keycloak.testsuite integration-arquillian-server-wildfly ${project.version} zip - backend - ${containers.home} + ${containers.home}/node1 + + + org.keycloak.testsuite + integration-arquillian-server-wildfly + ${project.version} + zip + ${containers.home}/node2 true @@ -635,6 +665,10 @@ migrated.auth.server.version + + + - + @@ -840,7 +874,7 @@ - + From 655a5a1401625ccb881caa42197766d558a17780 Mon Sep 17 00:00:00 2001 From: Tomas Kyjovsky Date: Tue, 9 Feb 2016 05:29:20 +0100 Subject: [PATCH 6/6] KEYCLOAK-1678 Enabled exclusion pattern for cluster test by default. --- testsuite/integration-arquillian/tests/base/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml index a0e7f09c95..cc84be1e51 100644 --- a/testsuite/integration-arquillian/tests/base/pom.xml +++ b/testsuite/integration-arquillian/tests/base/pom.xml @@ -78,6 +78,7 @@ ${exclude.account} ${exclude.client} ${exclude.migration} + ${exclude.cluster}