Possibility to execute DB migration tests for Quarkus distribution (#12688)

Closes #12685
This commit is contained in:
Martin Bartoš 2022-07-11 12:23:41 +02:00 committed by GitHub
parent 7fccdb10d8
commit 17f1d04960
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 5912 additions and 16 deletions

View file

@ -286,11 +286,35 @@ Run the test (Update according to your DB connection, versions etc):
-Dprevious.product.unpacked.folder.name=keycloak-$OLD_KEYCLOAK_VERSION \
-Dmigration.import.file.name=migration-realm-$OLD_KEYCLOAK_VERSION.json \
-Dauth.server.ssl.required=false \
-Djdbc.mvn.version=2.2.4
-Djdbc.mvn.version=2.2.4 \
-Dsurefire.failIfNoSpecifiedTests=false
For the available versions of old keycloak server, you can take a look to [this directory](tests/base/src/test/resources/migration-test) .
### DB migration test with Quarkus
It is possible to execute DB migration tests for Keycloak with Quarkus distribution by specifying auth server as `-Pauth-server-quarkus`
and instead of the `auth-server-migration-legacy`, use only `auth-server-migration`.
The first version of Keycloak on Quarkus is version `17.0.0`.
Therefore, it is not possible to define the older version.
You can execute those tests as follows:
```
export OLD_KEYCLOAK_VERSION=17.0.0
mvn -B -f testsuite/integration-arquillian/pom.xml \
clean install \
-Pjpa,auth-server-quarkus,db-mariadb,auth-server-migration \
-Dtest=MigrationTest \
-Dmigration.mode=auto \
-Dmigrated.auth.server.version=$OLD_KEYCLOAK_VERSION \
-Dprevious.product.unpacked.folder.name=keycloak-$OLD_KEYCLOAK_VERSION \
-Dmigration.import.file.name=migration-realm-$OLD_KEYCLOAK_VERSION.json \
-Dauth.server.ssl.required=false \
-Djdbc.mvn.version=2.2.4 \
-Dsurefire.failIfNoSpecifiedTests=false
```
### DB migration test with manual mode
Same test as above, but it uses manual migration mode. During startup of the new Keycloak server, Liquibase won't automatically perform DB update, but it

View file

@ -457,6 +457,7 @@ public class AuthServerTestEnricher {
if (suiteContext.isAuthServerMigrationEnabled()) {
log.info("## STOP old container: " + suiteContext.getMigratedAuthServerInfo().getQualifier());
stopContainerEvent.fire(new StopContainer(suiteContext.getMigratedAuthServerInfo().getArquillianContainer()));
suiteContext.setMigratedAuthServerInfo(null);
}
}

View file

@ -32,6 +32,7 @@ public class KeycloakQuarkusConfiguration implements ContainerConfiguration {
private String profile;
private String javaOpts;
private boolean reaugmentBeforeStart;
private String importFile = System.getProperty("migration.import.file.name");
@Override
public void validate() throws ConfigurationException {
@ -155,4 +156,13 @@ public class KeycloakQuarkusConfiguration implements ContainerConfiguration {
this.debugPort = debugPort;
}
public String getImportFile() {
return importFile;
}
public void setImportFile(String importFile) {
this.importFile = importFile;
}
}

View file

@ -8,13 +8,15 @@ import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
@ -22,7 +24,6 @@ import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@ -70,6 +71,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
@Override
public void start() throws LifecycleException {
try {
importRealm();
container = startContainer();
waitForReadiness();
} catch (Exception e) {
@ -127,6 +129,28 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
}
private void importRealm() throws IOException, URISyntaxException {
if (suiteContext.get().isAuthServerMigrationEnabled() && configuration.getImportFile() != null) {
final String importFileName = configuration.getImportFile();
log.infof("Importing realm from file '%s'", importFileName);
final URL url = getClass().getResource("/migration-test/" + importFileName);
if (url == null) throw new IllegalArgumentException("Cannot find migration import file");
final Path path = Paths.get(url.toURI());
final File wrkDir = configuration.getProvidersPath().resolve("bin").toFile();
final List<String> commands = new ArrayList<>();
commands.add(getCommand());
commands.add("import");
commands.add("--file=" + wrkDir.toPath().relativize(path));
final ProcessBuilder pb = new ProcessBuilder(commands);
pb.directory(wrkDir).inheritIO().start();
}
}
private Process startContainer() throws IOException {
ProcessBuilder pb = new ProcessBuilder(getProcessCommands());
File wrkDir = configuration.getProvidersPath().resolve("bin").toFile();

View file

@ -42,15 +42,16 @@ public class MigrationTestExecutionDecider implements TestExecutionDecider {
if (migrationTest && migrationAnnotation != null) {
log.info("migration from version: " + migratedAuthServerVersion);
String versionFrom = migrationAnnotation.versionFrom();
final String versionPrefix = migrationAnnotation.versionPrefix();
if (migratedAuthServerVersion.startsWith(versionFrom)) {
if (migratedAuthServerVersion.startsWith(versionPrefix)) {
return ExecutionDecision.execute();
} else {
return ExecutionDecision.dontExecute(method.getName() + "doesn't fit with migration version.");
}
}
if ((migrationTest && migrationAnnotation == null) || (!migrationTest && migrationAnnotation != null)) {
if (migrationTest || migrationAnnotation != null) {
return ExecutionDecision.dontExecute("Migration test and no migration annotation or no migration test and migration annotation");
}
return ExecutionDecision.execute();

View file

@ -31,5 +31,5 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
@Target({ElementType.METHOD})
public @interface Migration {
String versionFrom();
String versionPrefix();
}

View file

@ -60,7 +60,19 @@ public class MigrationTest extends AbstractMigrationTest {
}
@Test
@Migration(versionFrom = "9.")
@Migration(versionPrefix = "17.")
public void migration17_xTest() throws Exception{
testMigratedData(false);
testMigrationTo18_x();
// Always test offline-token login during migration test
testOfflineTokenLogin();
testExtremelyLongClientAttribute(migrationRealm);
}
@Test
@Migration(versionPrefix = "9.")
@AuthServerContainerExclude(AuthServer.QUARKUS)
public void migration9_xTest() throws Exception {
testMigratedData(false);
testMigrationTo12_x(true);
@ -72,7 +84,8 @@ public class MigrationTest extends AbstractMigrationTest {
}
@Test
@Migration(versionFrom = "4.")
@Migration(versionPrefix = "4.")
@AuthServerContainerExclude(AuthServer.QUARKUS)
public void migration4_xTest() throws Exception {
testMigratedData();
testMigrationTo5_x();
@ -89,7 +102,8 @@ public class MigrationTest extends AbstractMigrationTest {
}
@Test
@Migration(versionFrom = "3.")
@Migration(versionPrefix = "3.")
@AuthServerContainerExclude(AuthServer.QUARKUS)
public void migration3_xTest() throws Exception {
testMigratedData();
testMigrationTo4_x();
@ -106,7 +120,8 @@ public class MigrationTest extends AbstractMigrationTest {
}
@Test
@Migration(versionFrom = "2.")
@Migration(versionPrefix = "2.")
@AuthServerContainerExclude(AuthServer.QUARKUS)
public void migration2_xTest() throws Exception {
//the realm with special characters in its id was successfully migrated (no error during migration)
//removing it now as testMigratedData() expects specific clients and roles
@ -132,7 +147,8 @@ public class MigrationTest extends AbstractMigrationTest {
}
@Test
@Migration(versionFrom = "1.")
@Migration(versionPrefix = "1.")
@AuthServerContainerExclude(AuthServer.QUARKUS)
public void migration1_xTest() throws Exception {
testMigratedData(false);
testMigrationTo2_x();

View file

@ -751,13 +751,16 @@
<property name="enabled">${auth.server.migration}</property>
<property name="adapterImplClass">org.keycloak.testsuite.arquillian.containers.KeycloakQuarkusServerDeployableContainer</property>
<property name="bindHttpPortOffset">${auth.server.port.offset}</property>
<property name="javaOpts">-Xms512m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=512m -Djava.net.preferIPv4Stack=true</property>
<property name="javaVmArguments">
${migration.import.props.previous}
<property name="importFile">${migration.import.file.name}</property>
<property name="javaOpts">
-Xms512m
-Xmx512m
-XX:MetaspaceSize=96M
-XX:MaxMetaspaceSize=512m
-Djava.net.preferIPv4Stack=true
${auth.server.memory.settings}
-Dauth.server.db.host=${auth.server.db.host}
</property>
<property name="managementPort">${auth.server.management.port}</property>
</configuration>
</container>

View file

@ -1932,6 +1932,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<migration.import.file.name>${migration.import.file.name}</migration.import.file.name>
<migrated.auth.server.version>${migrated.auth.server.version}</migrated.auth.server.version>
<auth.server.migration>true</auth.server.migration>
<keycloak.migration.home>${containers.home}/auth-server-migration</keycloak.migration.home>