Skip to content

Commit b826a42

Browse files
committed
DataConnectCacheDatabaseMigrator.kt, DataConnectCacheDatabaseMigratorUnitTest.kt: Improve user_version error message and add tests
The error message for an invalid `user_version` in `DataConnectCacheDatabaseMigrator` was improved to include the version number in both decimal and hexadecimal formats. This provides more context for debugging. Additionally, unit tests were added to `DataConnectCacheDatabaseMigratorUnitTest` to verify the behavior of the `user_version` migration. These tests cover setting the `user_version` in a new database, ensuring it remains unchanged if already correct, and verifying that an exception is thrown for invalid versions. ### Changes * DataConnectCacheDatabaseMigrator.kt: * Updated `InvalidUserVersionException` to include the `user_version` in both decimal and hexadecimal formats. * Removed an unnecessary type check when reading the schema version from the database. * DataConnectCacheDatabaseMigratorUnitTest.kt: * Added a test to ensure `InvalidUserVersionException` is thrown for invalid `user_version` values and that the error message is correct. * Added a test to verify that `user_version` is set correctly in a new database. * Added a test to verify that `user_version` is not changed if it is already correct.
1 parent abf53e9 commit b826a42

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

firebase-dataconnect/src/main/kotlin/com/google/firebase/dataconnect/sqlite2/DataConnectCacheDatabaseMigrator.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.google.firebase.dataconnect.sqlite2
1818

1919
import android.annotation.SuppressLint
20-
import android.database.Cursor
2120
import android.database.sqlite.SQLiteDatabase
2221
import com.google.firebase.dataconnect.core.Logger
2322
import com.google.firebase.dataconnect.core.LoggerGlobals.debug
@@ -140,8 +139,11 @@ private constructor(private val sqliteDatabase: SQLiteDatabase, private val logg
140139
RunMigrationStepResult.StepExecuted(newSchemaVersion = "1.0.0")
141140
}
142141
else -> {
143-
logger.debug { "user_version $userVersion is unsupported; aborting" }
144-
throw InvalidUserVersionException("user_version is $userVersion, but expected 0 or 1")
142+
throw InvalidUserVersionException(
143+
"user_version $userVersion (${userVersion.to0xHexString()}) is unknown;" +
144+
" expected 0 or 1;" +
145+
" aborting to avoid corrupting the contents of the database"
146+
)
145147
}
146148
}
147149
}
@@ -150,7 +152,7 @@ private constructor(private val sqliteDatabase: SQLiteDatabase, private val logg
150152
val schemaVersion: String? =
151153
sqliteDatabase.rawQuery(logger, "SELECT text FROM metadata WHERE name = 'schema_version'") {
152154
cursor ->
153-
if (cursor.moveToNext() && cursor.getType(0) == Cursor.FIELD_TYPE_STRING) {
155+
if (cursor.moveToNext()) {
154156
cursor.getString(0)
155157
} else {
156158
null

firebase-dataconnect/src/test/kotlin/com/google/firebase/dataconnect/sqlite2/DataConnectCacheDatabaseMigratorUnitTest.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package com.google.firebase.dataconnect.sqlite2
1818

1919
import com.google.firebase.dataconnect.core.Logger
2020
import com.google.firebase.dataconnect.sqlite2.DataConnectCacheDatabaseMigrator.InvalidApplicationIdException
21+
import com.google.firebase.dataconnect.sqlite2.DataConnectCacheDatabaseMigrator.InvalidUserVersionException
2122
import com.google.firebase.dataconnect.sqlite2.SQLiteDatabaseExts.getApplicationId
2223
import com.google.firebase.dataconnect.sqlite2.SQLiteDatabaseExts.setApplicationId
2324
import com.google.firebase.dataconnect.testutil.DataConnectLogLevelRule
@@ -111,6 +112,55 @@ class DataConnectCacheDatabaseMigratorUnitTest {
111112
}
112113
}
113114

115+
@Test
116+
fun `migrate() user_version should set the value in a new database`() {
117+
val mockLogger: Logger = mockk(relaxed = true)
118+
val userVersion =
119+
DataConnectSQLiteDatabaseOpener.open(dbFile, mockLogger).use { db ->
120+
DataConnectCacheDatabaseMigrator.migrate(db, mockLogger)
121+
db.version
122+
}
123+
userVersion shouldBe 1
124+
}
125+
126+
@Test
127+
fun `migrate() user_version should leave value alone if already correct`() {
128+
val mockLogger: Logger = mockk(relaxed = true)
129+
val userVersion =
130+
DataConnectSQLiteDatabaseOpener.open(dbFile, mockLogger).use { db ->
131+
DataConnectCacheDatabaseMigrator.migrate(db, mockLogger)
132+
DataConnectCacheDatabaseMigrator.migrate(db, mockLogger)
133+
db.version
134+
}
135+
userVersion shouldBe 1
136+
}
137+
138+
@Test
139+
fun `migrate() user_version should throw if the value is invalid`() = runTest {
140+
checkAll(propTestConfig, Arb.int()) { userVersion ->
141+
assume(userVersion != 0 && userVersion != 1)
142+
val mockLogger: Logger = mockk(relaxed = true)
143+
144+
val exception =
145+
DataConnectSQLiteDatabaseOpener.open(null, mockLogger).use { db ->
146+
db.version = userVersion
147+
shouldThrow<InvalidUserVersionException> {
148+
DataConnectCacheDatabaseMigrator.migrate(db, mockLogger)
149+
}
150+
}
151+
152+
assertSoftly {
153+
exception.message shouldContainWithNonAbuttingText "user_version"
154+
exception.message shouldContainWithNonAbuttingText "0"
155+
exception.message shouldContainWithNonAbuttingText "1"
156+
exception.message shouldContainWithNonAbuttingTextIgnoringCase userVersion.to0xHexString()
157+
exception.message shouldContainWithNonAbuttingText userVersion.toString()
158+
exception.message shouldContainWithNonAbuttingTextIgnoringCase "unknown"
159+
exception.message shouldContainWithNonAbuttingTextIgnoringCase "aborting"
160+
}
161+
}
162+
}
163+
114164
private companion object {
115165

116166
@OptIn(ExperimentalKotest::class)

0 commit comments

Comments
 (0)