Add a Kotlin codegen flavor to Room's Kotlin test app.
This will enable us to test the integration app with both Java and Kotlin codegen.
Test: ./gradlew :room:integration-tests:room-testapp-kotlin:connectedWithKspGenKotlinDebugAndroidTest
Change-Id: I5166dc89db18c0a458f7d97f6101e252adb9be28
diff --git a/room/integration-tests/kotlintestapp/build.gradle b/room/integration-tests/kotlintestapp/build.gradle
index e23da19..35f2d71 100644
--- a/room/integration-tests/kotlintestapp/build.gradle
+++ b/room/integration-tests/kotlintestapp/build.gradle
@@ -18,7 +18,7 @@
// -Dorg.gradle.debug=true
// -Dkotlin.compiler.execution.strategy="in-process"
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+import com.google.devtools.ksp.gradle.KspTask
plugins {
id("AndroidXPlugin")
@@ -45,7 +45,8 @@
sourceSets {
androidTestWithKapt.assets.srcDirs += files("$projectDir/schemas".toString())
- androidTestWithKsp.assets.srcDirs += files("$projectDir/schemas-ksp".toString())
+ androidTestWithKspGenJava.assets.srcDirs += files("$projectDir/schemas-ksp".toString())
+ androidTestWithKspGenKotlin.assets.srcDirs += files("$projectDir/schemas-ksp".toString())
}
flavorDimensions "processorConfiguration"
@@ -60,7 +61,10 @@
}
}
}
- withKsp {
+ withKspGenJava {
+ dimension "processorConfiguration"
+ }
+ withKspGenKotlin {
dimension "processorConfiguration"
}
}
@@ -79,7 +83,10 @@
implementation(libs.multidex)
// depend on the shadowed version so that it tests with the shipped artifact
// this is a temporary attribute until KSP and AndroidX plugin supports variants.
- kspAndroidTestWithKsp(
+ kspAndroidTestWithKspGenJava(
+ project(path: ":room:room-compiler", configuration: "shadowAndImplementation")
+ )
+ kspAndroidTestWithKspGenKotlin(
project(path: ":room:room-compiler", configuration: "shadowAndImplementation")
)
kaptAndroidTestWithKapt(
@@ -118,7 +125,13 @@
testImplementation(libs.mockitoCore)
}
-// KSP does not support argument per flavor so we set it to global instead.
+// KSP does not support argument per flavor so we set schema location globally, for other per
+// flavor options we use flavor named tasks. See https://github.com/google/ksp/issues/861.
ksp {
arg("room.schemaLocation","$projectDir/schemas-ksp".toString())
}
+tasks.withType(KspTask).configureEach { kspTask ->
+ if (kspTask.name.contains("GenKotlin")) {
+ kspTask.apOptions.put("room.generateKotlin", "true")
+ }
+}
diff --git a/room/integration-tests/kotlintestapp/schemas-ksp/androidx.room.integration.kotlintestapp.migration.MigrationDbKotlin/8.json b/room/integration-tests/kotlintestapp/schemas-ksp/androidx.room.integration.kotlintestapp.migration.MigrationDbKotlin/8.json
new file mode 100644
index 0000000..5ff99a1
--- /dev/null
+++ b/room/integration-tests/kotlintestapp/schemas-ksp/androidx.room.integration.kotlintestapp.migration.MigrationDbKotlin/8.json
@@ -0,0 +1,120 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 8,
+ "identityHash": "7c65736dc87e4f5bf7bf54e1ef798ec2",
+ "entities": [
+ {
+ "tableName": "Entity1",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_Entity1_name",
+ "unique": true,
+ "columnNames": [
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Entity1_name` ON `${TABLE_NAME}` (`name`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Entity2",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "addedInV3",
+ "columnName": "addedInV3",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Entity4",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": [
+ {
+ "table": "Entity1",
+ "onDelete": "NO ACTION",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "name"
+ ],
+ "referencedColumns": [
+ "name"
+ ]
+ }
+ ]
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7c65736dc87e4f5bf7bf54e1ef798ec2')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/room/integration-tests/kotlintestapp/schemas/androidx.room.integration.kotlintestapp.migration.MigrationDbKotlin/8.json b/room/integration-tests/kotlintestapp/schemas/androidx.room.integration.kotlintestapp.migration.MigrationDbKotlin/8.json
new file mode 100644
index 0000000..5ff99a1
--- /dev/null
+++ b/room/integration-tests/kotlintestapp/schemas/androidx.room.integration.kotlintestapp.migration.MigrationDbKotlin/8.json
@@ -0,0 +1,120 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 8,
+ "identityHash": "7c65736dc87e4f5bf7bf54e1ef798ec2",
+ "entities": [
+ {
+ "tableName": "Entity1",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_Entity1_name",
+ "unique": true,
+ "columnNames": [
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Entity1_name` ON `${TABLE_NAME}` (`name`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Entity2",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "addedInV3",
+ "columnName": "addedInV3",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Entity4",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": [
+ {
+ "table": "Entity1",
+ "onDelete": "NO ACTION",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "name"
+ ],
+ "referencedColumns": [
+ "name"
+ ]
+ }
+ ]
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7c65736dc87e4f5bf7bf54e1ef798ec2')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/RoomTestConfig.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/RoomTestConfig.kt
index 1d20a98..fb04b08 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/RoomTestConfig.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/RoomTestConfig.kt
@@ -27,7 +27,7 @@
* This can help enable/disable certain tests for ksp
*/
val isKsp
- get() = BuildConfig.FLAVOR == "withKsp"
+ get() = BuildConfig.FLAVOR.startsWith("withKsp")
}
/**
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/MigrationDbKotlin.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/MigrationDbKotlin.kt
index 4d21e0e..0aa25f1 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/MigrationDbKotlin.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/MigrationDbKotlin.kt
@@ -18,6 +18,7 @@
import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase
+import androidx.room.AutoMigration
import androidx.room.Dao
import androidx.room.Database
import androidx.room.Entity
@@ -33,10 +34,14 @@
@Database(
version = MigrationDbKotlin.LATEST_VERSION,
- entities = arrayOf(
- MigrationDbKotlin.Entity1::class, MigrationDbKotlin.Entity2::class,
+ entities = [
+ MigrationDbKotlin.Entity1::class,
+ MigrationDbKotlin.Entity2::class,
MigrationDbKotlin.Entity4::class
- )
+ ],
+ autoMigrations = [
+ AutoMigration(7, 8)
+ ]
)
abstract class MigrationDbKotlin : RoomDatabase() {
@@ -61,7 +66,8 @@
data class Entity3(
@PrimaryKey var id: Int = 0,
@get:Ignore var removedInV5: String?,
- var name: String?
+ var name: String?,
+ var addedInV8: Int = 1
) { // added in version 4, removed at 6
companion object {
val TABLE_NAME = "Entity3"
@@ -142,6 +148,6 @@
}
companion object {
- const val LATEST_VERSION = 7
+ const val LATEST_VERSION = 8
}
}
diff --git a/room/scripts/ksp-kapt-comparison.sh b/room/scripts/ksp-kapt-comparison.sh
index 2e19578..8de53fa 100755
--- a/room/scripts/ksp-kapt-comparison.sh
+++ b/room/scripts/ksp-kapt-comparison.sh
@@ -13,7 +13,7 @@
# move to the project directory
cd $PROJECT_DIR;
-KSP_TASK=":room:integration-tests:room-testapp-kotlin:kspWithKspDebugAndroidTestKotlin"
+KSP_TASK=":room:integration-tests:room-testapp-kotlin:kspWithKspGenJavaDebugAndroidTestKotlin"
KAPT_TASK=":room:integration-tests:room-testapp-kotlin:kaptGenerateStubsWithKaptDebugAndroidTestKotlin \
:room:integration-tests:room-testapp-kotlin:kaptWithKaptDebugAndroidTestKotlin"
# parses the given profile file, extracts task durations that we are interested in and adds them to the global tracking
diff --git a/room/scripts/profile.sh b/room/scripts/profile.sh
index e8c912e..1e34203 100755
--- a/room/scripts/profile.sh
+++ b/room/scripts/profile.sh
@@ -6,7 +6,7 @@
echo "usage: ./profile.sh <gradle tasks>
./profile.sh --name my_run \
--target gradle \
- :room:integration-tests:room-testapp-kotlin:kspWithKspDebugAndroidTestKotlin \
+ :room:integration-tests:room-testapp-kotlin:kspWithKspGenJavaDebugAndroidTestKotlin \
--filter *K2JVMCompiler*
./profile.sh --name my_run \
--target test \
@@ -93,7 +93,7 @@
ADDITIONAL_AGENT_PARAMS="$ADDITIONAL_AGENT_PARAMS,include=*AbstractKapt3Extension*"
AGENT_TARGET="gradle"
elif [ "$2" = "ksp" ]; then
- GRADLE_ARGS=":room:integration-tests:room-testapp-kotlin:kspWithKspDebugAndroidTestKotlin"
+ GRADLE_ARGS=":room:integration-tests:room-testapp-kotlin:kspWithKspGenJavaDebugAndroidTestKotlin"
ADDITIONAL_AGENT_PARAMS="$ADDITIONAL_AGENT_PARAMS,include=*AbstractKotlinSymbolProcessingExtension*"
AGENT_TARGET="gradle"
else