keycloak-aplcache

Details

diff --git a/testsuite/integration-arquillian/HOW-TO-RUN.md b/testsuite/integration-arquillian/HOW-TO-RUN.md
index edaf038..1c519b1 100644
--- a/testsuite/integration-arquillian/HOW-TO-RUN.md
+++ b/testsuite/integration-arquillian/HOW-TO-RUN.md
@@ -165,10 +165,10 @@ Assumed you downloaded `jboss-fuse-karaf-6.3.0.redhat-229.zip`
 ### DB migration test
 
 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
  - 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
  
 
@@ -191,7 +191,41 @@ This test will:
       -Dkeycloak.connectionsJpa.url=jdbc:mysql://$DB_HOST/keycloak \
       -Dkeycloak.connectionsJpa.user=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
 This will start latest Keycloak and import the realm JSON file, which was previously exported from Keycloak 1.9.8.Final
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 6ca5135..e583608 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
@@ -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()) {
             log.info("\n\n### Run preMigration task on keycloak " + System.getProperty("migrated.auth.server.version", "- previous") + " ###\n\n");
             suiteContext.getMigrationContext().runPreMigrationTask();
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/migration/MigrationContext.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/migration/MigrationContext.java
index 18eea83..aa62f8a 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/migration/MigrationContext.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/migration/MigrationContext.java
@@ -17,8 +17,16 @@
 
 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.keycloak.OAuth2Constants;
+import org.keycloak.common.util.StreamUtil;
 import org.keycloak.testsuite.util.OAuthClient;
 
 /**
@@ -28,19 +36,36 @@ public class MigrationContext {
 
     public static final Logger logger = Logger.getLogger(MigrationContext.class);
 
-    private String offlineToken;
 
-    public String getOfflineToken() {
-        return offlineToken;
+    public String loadOfflineToken() throws Exception {
+        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
-    public void runPreMigrationTask() {
-        requestOfflineToken();
+    public void runPreMigrationTask() throws Exception {
+        String offlineToken = requestOfflineToken();
+        saveOfflineToken(offlineToken);
     }
 
-    private void requestOfflineToken() {
+    private String requestOfflineToken() {
         logger.info("Requesting offline token on the old container");
         try {
             OAuthClient oauth = new OAuthClient();
@@ -49,10 +74,33 @@ public class MigrationContext {
             oauth.realm("Migration");
             oauth.clientId("migration-test-client");
             OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("b2c07929-69e3-44c6-8d7f-76939000b3e4", "migration-test-user", "admin");
-            offlineToken = tokenResponse.getRefreshToken();
+            return tokenResponse.getRefreshToken();
         } catch (Exception 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";
+    }
+
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java
index 1315b18..04a758e 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java
@@ -123,7 +123,7 @@ public class MigrationTest extends AbstractKeycloakTest {
     
     @Test
     @Migration(versionFrom = "1.9.8.Final")
-    public void migration1_9_8Test() {
+    public void migration1_9_8Test() throws Exception {
         testMigratedData();
         testMigrationTo2_0_0();
         testMigrationTo2_1_0();
@@ -200,7 +200,7 @@ public class MigrationTest extends AbstractKeycloakTest {
         testDuplicateEmailSupport(masterRealm, migrationRealm);
     }
 
-    private void testMigrationTo2_5_1() {
+    private void testMigrationTo2_5_1() throws Exception {
         testOfflineTokenLogin();
     }
     
@@ -407,12 +407,12 @@ public class MigrationTest extends AbstractKeycloakTest {
         }
     }
 
-    private void testOfflineTokenLogin() {
+    private void testOfflineTokenLogin() throws Exception {
         if (isImportMigrationMode()) {
             log.info("Skip offline token login test in the 'import' migrationMode");
         } else {
             log.info("test login with old offline token");
-            String oldOfflineToken = suiteContext.getMigrationContext().getOfflineToken();
+            String oldOfflineToken = suiteContext.getMigrationContext().loadOfflineToken();
             Assert.assertNotNull(oldOfflineToken);
 
             oauth.realm(MIGRATION);