build: Add Avdl configuration
authorDa Risk <da_risk@geekorum.com>
Mon, 11 May 2020 20:38:34 -0400
changeset 661 f3f18143704a
parent 660 05559ff7bbe1
child 662 452e49493842
build: Add Avdl configuration
app/build.gradle.kts
buildSrc/build.gradle.kts
buildSrc/src/main/kotlin/Avdl.kt
buildSrc/src/main/kotlin/android-avdl.gradle.kts
gradle.properties
manage_feeds/build.gradle.kts
--- a/app/build.gradle.kts	Mon Apr 20 20:24:36 2020 -0400
+++ b/app/build.gradle.kts	Mon May 11 20:38:34 2020 -0400
@@ -34,6 +34,7 @@
     id("com.geekorum.build.android-tests")
     id("com.geekorum.build.android-signing")
     id("com.geekorum.build.android-genymotion")
+    id("com.geekorum.build.android-avdl")
     id("com.geekorum.build.android-release-universal-apk")
     id("com.geekorum.build.play-store-publish")
     id("androidx.navigation.safeargs.kotlin")
--- a/buildSrc/build.gradle.kts	Mon Apr 20 20:24:36 2020 -0400
+++ b/buildSrc/build.gradle.kts	Mon May 11 20:38:34 2020 -0400
@@ -38,6 +38,9 @@
         // we publish 1.4.2 version with fixes
         url = uri("https://raw.githubusercontent.com/fbarthelery/genymotion-gradle-plugin/master/repo/")
     }
+    maven {
+        url = uri("https://kotlin.bintray.com/kotlinx")
+    }
 }
 
 dependencies {
@@ -47,4 +50,5 @@
     implementation("com.genymotion:plugin:1.4.2")
     implementation("gradle.plugin.com.hierynomus.gradle.plugins:license-gradle-plugin:0.15.0")
     implementation("com.github.triplet.gradle:play-publisher:2.7.5")
+    implementation("com.geekorum.gradle.avdl:flydroid:0.0.2")
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buildSrc/src/main/kotlin/Avdl.kt	Mon May 11 20:38:34 2020 -0400
@@ -0,0 +1,140 @@
+/*
+ * Geekdroid is a utility library for development on the Android
+ * Platform.
+ *
+ * Copyright (C) 2017-2020 by Frederic-Charles Barthelery.
+ *
+ * This file is part of Geekdroid.
+ *
+ * Geekdroid is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Geekdroid is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Geekdroid.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.geekorum.build
+
+import com.android.build.gradle.AppPlugin
+import com.android.build.gradle.DynamicFeaturePlugin
+import com.android.build.gradle.LibraryPlugin
+import com.android.build.gradle.TestedExtension
+import com.android.build.gradle.api.TestVariant
+import com.geekorum.gradle.avdl.AvdlExtension
+import com.geekorum.gradle.avdl.providers.flydroid.FlydroidPlugin
+import com.geekorum.gradle.avdl.providers.flydroid.flydroid
+import com.geekorum.gradle.avdl.tasks.LaunchDeviceTask
+import com.geekorum.gradle.avdl.tasks.StopDeviceTask
+import com.geekorum.gradle.avdl.tasks.orderForTask
+import com.geekorum.gradle.avdl.tasks.registerAvdlDevicesTask
+import org.gradle.api.Project
+import org.gradle.api.Task
+import org.gradle.api.provider.Provider
+import org.gradle.api.services.BuildService
+import org.gradle.api.services.BuildServiceParameters
+import org.gradle.api.tasks.TaskContainer
+import org.gradle.api.tasks.TaskProvider
+import org.gradle.kotlin.dsl.*
+
+
+fun Project.configureAvdlDevices(flydroidUrl: String, flydroidKey: String) {
+    apply<FlydroidPlugin>()
+
+    val oneInstrumentedTestService = gradle.sharedServices.registerIfAbsent(
+        "oneInstrumentedTest", OneInstrumentedTestService::class.java) {
+        maxParallelUsages.set(1)
+    }
+
+    rootProject.serializeInstrumentedTestTask(oneInstrumentedTestService)
+
+    val android = the<TestedExtension>()
+    configure<AvdlExtension> {
+        devices {
+            android.testVariants.all {
+                register("android-n-${project.path}-$baseName") {
+                    setup = flydroid {
+                        url = flydroidUrl
+                        this.flydroidKey = flydroidKey
+                        // android-q images fail, don't manage to start the tests
+                        image = "android-n"
+//                        useTunnel = true
+                    }
+                }
+            }
+        }
+    }
+
+    tasks {
+        var lastStopTask: TaskProvider<out Task>? = null
+        var lastTestTask: TaskProvider<out Task>? = null
+        android.testVariants.all {
+            val (startTask, stopTask ) =
+                registerAvdlDevicesTaskForVariant(this, listOf("android-n-${project.path}-$baseName"))
+            listOf(startTask, stopTask).forEach {
+                it.configure {
+                    usesService(oneInstrumentedTestService)
+                }
+            }
+
+            lastStopTask?.let {
+                startTask.configure {
+                    mustRunAfter(it)
+                }
+            }
+            lastTestTask?.let {
+                startTask.configure {
+                    mustRunAfter(it)
+                }
+            }
+            lastStopTask = stopTask
+            lastTestTask = connectedInstrumentTestProvider
+        }
+    }
+
+    afterEvaluate {
+        // ensure that launchDeviceTask are run after StopDeviceTask of previous project
+        rootProject.tasks {
+            getByPath(":manage_feeds:launchAvdlFreeDebugAndroidTest")
+                .mustRunAfter(":app:stopAvdlFreeDebugAndroidTest", ":app:stopAvdlGoogleDebugAndroidTest")
+            getByPath(":manage_feeds:launchAvdlGoogleDebugAndroidTest")
+                .mustRunAfter(":app:stopAvdlFreeDebugAndroidTest", ":app:stopAvdlGoogleDebugAndroidTest")
+        }
+    }
+}
+
+private fun TaskContainer.registerAvdlDevicesTaskForVariant(
+    variant: TestVariant, devices: List<String>
+): Pair<TaskProvider<LaunchDeviceTask>, TaskProvider<StopDeviceTask>> {
+    val tasks =
+        registerAvdlDevicesTask(variant.name, devices)
+    tasks.orderForTask(variant.connectedInstrumentTestProvider)
+    return tasks
+}
+
+
+private fun Project.serializeInstrumentedTestTask(oneInstrumentedTestService: Provider<OneInstrumentedTestService>) {
+    fun Project.configureTestTasks() {
+        extensions.configure<TestedExtension> {
+            testVariants.all {
+                connectedInstrumentTestProvider.configure {
+                    usesService(oneInstrumentedTestService)
+                }
+            }
+        }
+    }
+
+    allprojects {
+        val project = this
+        plugins.withType<AppPlugin> { project.configureTestTasks() }
+        plugins.withType<DynamicFeaturePlugin> { project.configureTestTasks() }
+        plugins.withType<LibraryPlugin> { project.configureTestTasks() }
+    }
+}
+
+abstract class OneInstrumentedTestService : BuildService<BuildServiceParameters.None>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buildSrc/src/main/kotlin/android-avdl.gradle.kts	Mon May 11 20:38:34 2020 -0400
@@ -0,0 +1,39 @@
+/*
+ * Geekttrss is a RSS feed reader application on the Android Platform.
+ *
+ * Copyright (C) 2017-2020 by Frederic-Charles Barthelery.
+ *
+ * This file is part of Geekttrss.
+ *
+ * Geekttrss is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Geekttrss is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.geekorum.build
+
+/**
+ * This defines the configuration to run tests with gradle-avdl.
+ * The CI will run the test on on the following devices.
+ * To run this your project must have declared the following gradle properties
+ * via command line or your gradle.properties
+ * RUN_TESTS_ON_AVDL=true
+ */
+
+private val runTestOnAvdl = findProperty("RUN_TESTS_ON_AVDL") as String?
+val runTests =  runTestOnAvdl?.toBoolean() ?: false
+
+if (runTests) {
+    val flydroidUrl = checkNotNull(findProperty("FLYDROID_URL") as String?) { "FLYDROID_URL property not specified" }
+    val flydroidKey = checkNotNull(findProperty("FLYDROID_KEY") as String?) { "FLYDROID_KEY property not specified" }
+
+    configureAvdlDevices(flydroidUrl, flydroidKey)
+}
--- a/gradle.properties	Mon Apr 20 20:24:36 2020 -0400
+++ b/gradle.properties	Mon May 11 20:38:34 2020 -0400
@@ -28,8 +28,10 @@
 # specify path of geekdroid source to use them instead of the prebuilt library
 # GEEKDROID_PROJECT_DIR=/home/darisk/devel/geekorum/geekdroid/
 
-# Genymotion configuration
-#RUN_TESTS_ON_GENYMOTION_CLOUD=true
+# avdl configuration
+# RUN_TESTS_ON_AVDL=true
+# FLYDROID_URL=https://flydroid.example.com
+# FLYDROID_KEY=my-flydroid-api-key
 
 # Signature configuration
 #RELEASE_STORE_FILE=/some/path/to/a/keystores/file.jks
--- a/manage_feeds/build.gradle.kts	Mon Apr 20 20:24:36 2020 -0400
+++ b/manage_feeds/build.gradle.kts	Mon May 11 20:38:34 2020 -0400
@@ -27,6 +27,7 @@
     kotlin("kapt")
     id("com.geekorum.build.android-tests")
     id("com.geekorum.build.android-genymotion")
+    id("com.geekorum.build.android-avdl")
     id("androidx.navigation.safeargs.kotlin")
 }