Merge pull request #4069 from mposolda/master

KEYCLOAK-4271 Migration test for offline tokens - manual mode
This commit is contained in:
Marek Posolda 2017-04-25 10:10:19 +02:00 committed by GitHub
commit e48340121b
4 changed files with 96 additions and 14 deletions

View file

@ -165,10 +165,10 @@ Assumed you downloaded `jboss-fuse-karaf-6.3.0.redhat-229.zip`
### DB migration test ### DB migration test
This test will: This test will:
- start Keycloak 1.9.8 - start Keycloak 1.9.8 (replace with the other version if needed)
- import realm and some data to MySQL DB - import realm and some data to MySQL DB
- stop Keycloak 1.9.8 - stop Keycloak 1.9.8
- start latest KEycloak, which automatically updates DB from 1.9.8 - start latest Keycloak, which automatically updates DB from 1.9.8
- Do some test that data are correct - Do some test that data are correct
@ -192,6 +192,40 @@ This test will:
-Dkeycloak.connectionsJpa.user=keycloak \ -Dkeycloak.connectionsJpa.user=keycloak \
-Dkeycloak.connectionsJpa.password=keycloak -Dkeycloak.connectionsJpa.password=keycloak
### 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
just exports the needed SQL into the script. This SQL script then needs to be manually executed against the DB.
1) Prepare MySQL DB (Same as above)
2) Run the test (Update according to your DB connection, versions etc). This step will end with failure, but that's expected:
mvn -f testsuite/integration-arquillian/pom.xml \
clean install \
-Pauth-server-wildfly,jpa,clean-jpa,auth-server-migration \
-Dtest=MigrationTest \
-Dmigration.mode=manual \
-Dmigrated.auth.server.version=1.9.8.Final \
-Djdbc.mvn.groupId=mysql \
-Djdbc.mvn.version=5.1.29 \
-Djdbc.mvn.artifactId=mysql-connector-java \
-Dkeycloak.connectionsJpa.url=jdbc:mysql://$DB_HOST/keycloak \
-Dkeycloak.connectionsJpa.user=keycloak \
-Dkeycloak.connectionsJpa.password=keycloak
3) Manually execute the SQL script against your DB. With Mysql, you can use this command (KEYCLOAK_SRC points to the directory with the Keycloak codebase):
mysql -h $DB_HOST -u keycloak -pkeycloak < $KEYCLOAK_SRC/testsuite/integration-arquillian/tests/base/target/containers/auth-server-wildfly/keycloak-database-update.sql
4) Finally run the migration test, which will verify that DB migration was successful. This should end with success:
mvn -f testsuite/integration-arquillian/tests/base/pom.xml \
clean install \
-Pauth-server-wildfly \
-Dskip.add.user.json=true \
-Dmigrated.auth.server.version=1.9.8.Final \
-Dtest=MigrationTest
### JSON export/import migration test ### JSON export/import migration test
This will start latest Keycloak and import the realm JSON file, which was previously exported from Keycloak 1.9.8.Final This will start latest Keycloak and import the realm JSON file, which was previously exported from Keycloak 1.9.8.Final

View file

@ -178,7 +178,7 @@ public class AuthServerTestEnricher {
} }
} }
public void runPreMigrationTask(@Observes(precedence = 2) StartSuiteContainers event) { public void runPreMigrationTask(@Observes(precedence = 2) StartSuiteContainers event) throws Exception {
if (suiteContext.isAuthServerMigrationEnabled()) { if (suiteContext.isAuthServerMigrationEnabled()) {
log.info("\n\n### Run preMigration task on keycloak " + System.getProperty("migrated.auth.server.version", "- previous") + " ###\n\n"); log.info("\n\n### Run preMigration task on keycloak " + System.getProperty("migrated.auth.server.version", "- previous") + " ###\n\n");
suiteContext.getMigrationContext().runPreMigrationTask(); suiteContext.getMigrationContext().runPreMigrationTask();

View file

@ -17,8 +17,16 @@
package org.keycloak.testsuite.arquillian.migration; package org.keycloak.testsuite.arquillian.migration;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.PrintWriter;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.common.util.StreamUtil;
import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.OAuthClient;
/** /**
@ -28,19 +36,36 @@ public class MigrationContext {
public static final Logger logger = Logger.getLogger(MigrationContext.class); public static final Logger logger = Logger.getLogger(MigrationContext.class);
private String offlineToken;
public String getOfflineToken() { public String loadOfflineToken() throws Exception {
return offlineToken; String file = getOfflineTokenLocation();
logger.infof("Reading previously saved offline token from the file: %s", file);
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
String offlineToken = StreamUtil.readString(fis);
File f = new File(file);
f.delete();
logger.infof("Deleted file with offline token: %s", file);
return offlineToken;
} finally {
if (fis != null) {
fis.close();
}
}
} }
// Do some actions on the old container // Do some actions on the old container
public void runPreMigrationTask() { public void runPreMigrationTask() throws Exception {
requestOfflineToken(); String offlineToken = requestOfflineToken();
saveOfflineToken(offlineToken);
} }
private void requestOfflineToken() { private String requestOfflineToken() {
logger.info("Requesting offline token on the old container"); logger.info("Requesting offline token on the old container");
try { try {
OAuthClient oauth = new OAuthClient(); OAuthClient oauth = new OAuthClient();
@ -49,10 +74,33 @@ public class MigrationContext {
oauth.realm("Migration"); oauth.realm("Migration");
oauth.clientId("migration-test-client"); oauth.clientId("migration-test-client");
OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("b2c07929-69e3-44c6-8d7f-76939000b3e4", "migration-test-user", "admin"); OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("b2c07929-69e3-44c6-8d7f-76939000b3e4", "migration-test-user", "admin");
offlineToken = tokenResponse.getRefreshToken(); return tokenResponse.getRefreshToken();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
private void saveOfflineToken(String offlineToken) throws Exception {
String file = getOfflineTokenLocation();
logger.infof("Saving offline token to file: %s", file);
PrintWriter writer = null;
try {
writer = new PrintWriter(new BufferedWriter(new FileWriter(file)));
writer.print(offlineToken);
} finally {
if (writer != null) {
writer.close();
}
}
}
// Needs to save offline token inside "basedir". There are issues with saving into directory "target" as it's cleared among restarts and
// using "mvn install" instead of "mvn clean install" doesn't work ATM. Improve if needed...
private String getOfflineTokenLocation() {
return System.getProperty("basedir") + "/offline-token.txt";
}
} }

View file

@ -123,7 +123,7 @@ public class MigrationTest extends AbstractKeycloakTest {
@Test @Test
@Migration(versionFrom = "1.9.8.Final") @Migration(versionFrom = "1.9.8.Final")
public void migration1_9_8Test() { public void migration1_9_8Test() throws Exception {
testMigratedData(); testMigratedData();
testMigrationTo2_0_0(); testMigrationTo2_0_0();
testMigrationTo2_1_0(); testMigrationTo2_1_0();
@ -200,7 +200,7 @@ public class MigrationTest extends AbstractKeycloakTest {
testDuplicateEmailSupport(masterRealm, migrationRealm); testDuplicateEmailSupport(masterRealm, migrationRealm);
} }
private void testMigrationTo2_5_1() { private void testMigrationTo2_5_1() throws Exception {
testOfflineTokenLogin(); testOfflineTokenLogin();
} }
@ -407,12 +407,12 @@ public class MigrationTest extends AbstractKeycloakTest {
} }
} }
private void testOfflineTokenLogin() { private void testOfflineTokenLogin() throws Exception {
if (isImportMigrationMode()) { if (isImportMigrationMode()) {
log.info("Skip offline token login test in the 'import' migrationMode"); log.info("Skip offline token login test in the 'import' migrationMode");
} else { } else {
log.info("test login with old offline token"); log.info("test login with old offline token");
String oldOfflineToken = suiteContext.getMigrationContext().getOfflineToken(); String oldOfflineToken = suiteContext.getMigrationContext().loadOfflineToken();
Assert.assertNotNull(oldOfflineToken); Assert.assertNotNull(oldOfflineToken);
oauth.realm(MIGRATION); oauth.realm(MIGRATION);