diff --git a/src/androidTest/java/eu/siacs/conversations/persistance/DatabaseBackendTest.java b/src/androidTest/java/eu/siacs/conversations/persistance/DatabaseBackendTest.java index 87683d8b770cf73c0c81b76d9bf53807e4236417..fec00214eaab49eee9294258f3a5d2a6791828ba 100644 --- a/src/androidTest/java/eu/siacs/conversations/persistance/DatabaseBackendTest.java +++ b/src/androidTest/java/eu/siacs/conversations/persistance/DatabaseBackendTest.java @@ -17,6 +17,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import eu.siacs.conversations.entities.Account; @@ -112,6 +114,56 @@ public class DatabaseBackendTest { private static ConversationFixture NO_CACHED_MUC_USERS; private static ConversationFixture[] FIXTURES; + private Set getCheogramSchema(SQLiteDatabase db) { + var schema = new HashSet(); + + var cursor = db.rawQuery( + "SELECT name FROM cheogram.sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'", + null + ); + final var tables = new java.util.ArrayList(); + while (cursor.moveToNext()) { + tables.add(cursor.getString(0)); + } + cursor.close(); + + for (final var table : tables) { + cursor = db.rawQuery("PRAGMA cheogram.table_info(" + table + ")", null); + while (cursor.moveToNext()) { + final var colName = cursor.getString(cursor.getColumnIndexOrThrow("name")); + final var colType = cursor.getString(cursor.getColumnIndexOrThrow("type")); + schema.add("table:" + table + ":col:" + colName + ":" + colType); + } + cursor.close(); + } + + cursor = db.rawQuery( + "SELECT name, tbl_name, sql FROM cheogram.sqlite_master WHERE type='index' AND sql IS NOT NULL", + null + ); + while (cursor.moveToNext()) { + final var name = cursor.getString(0); + final var tbl = cursor.getString(1); + final var sql = cursor.getString(2); + schema.add("index:" + name + ":" + tbl + ":" + sql); + } + cursor.close(); + + return schema; + } + + private int getCheogramVersion(SQLiteDatabase db) { + final var cursor = db.rawQuery("PRAGMA cheogram.user_version", null); + var version = -1; + try { + cursor.moveToNext(); + version = cursor.getInt(0); + } finally { + cursor.close(); + } + return version; + } + @BeforeClass public static void setupClass() throws JSONException { final var occupantIdFeature = new Feature(); @@ -232,6 +284,28 @@ public class DatabaseBackendTest { ); } + @Test + public void cheogramMigrateIsIdempotent() throws Exception { + final var sqDb = db.getWritableDatabase(); + + final var schemaAfterFirst = getCheogramSchema(sqDb); + int versionAfterFirst = getCheogramVersion(sqDb); + + Assert.assertTrue("Version should be > 0 after migration", versionAfterFirst > 0); + + final var migrateMethod = DatabaseBackend.class.getDeclaredMethod("cheogramMigrate", SQLiteDatabase.class); + migrateMethod.setAccessible(true); + migrateMethod.invoke(db, sqDb); + + final var schemaAfterSecond = getCheogramSchema(sqDb); + var versionAfterSecond = getCheogramVersion(sqDb); + + Assert.assertEquals("Schema should be identical after re-running migration", + schemaAfterFirst, schemaAfterSecond); + Assert.assertEquals("Version should be unchanged after re-running migration", + versionAfterFirst, versionAfterSecond); + } + @Test public void updateConversationWritesMucOccupantsCache() throws Exception { final var conversation = NO_CACHED_MUC_USERS.extractAndConfigure(db);