Fix FTL test APKs resolution

Change-Id: I390cdf45df6d8fce5bf388a4fd495205ed407a0c
pull/305/head
Wojtek Kaliciński 2 years ago
parent 7f5f4877a9
commit 17afcf4302

@ -14,8 +14,10 @@
* limitations under the License.
*/
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
import com.google.samples.apps.nowinandroid.configureKotlinAndroid
import com.google.samples.apps.nowinandroid.configurePrintApksTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
@ -32,6 +34,9 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 32
}
extensions.configure<ApplicationAndroidComponentsExtension> {
configurePrintApksTask(this)
}
}
}

@ -14,9 +14,11 @@
* limitations under the License.
*/
import com.android.build.api.variant.LibraryAndroidComponentsExtension
import com.android.build.gradle.LibraryExtension
import com.google.samples.apps.nowinandroid.configureFlavors
import com.google.samples.apps.nowinandroid.configureKotlinAndroid
import com.google.samples.apps.nowinandroid.configurePrintApksTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
@ -37,7 +39,9 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
defaultConfig.targetSdk = 32
configureFlavors(this)
}
extensions.configure<LibraryAndroidComponentsExtension> {
configurePrintApksTask(this)
}
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
configurations.configureEach {
@ -50,5 +54,4 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
}
}
}
}
}

@ -0,0 +1,90 @@
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid
import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.api.variant.BuiltArtifactsLoader
import com.android.build.api.variant.HasAndroidTest
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import java.io.File
internal fun Project.configurePrintApksTask(extension: AndroidComponentsExtension<*, *, *>) {
extension.onVariants { variant ->
if (variant is HasAndroidTest) {
val loader = variant.artifacts.getBuiltArtifactsLoader()
val artifact = variant.androidTest?.artifacts?.get(SingleArtifact.APK)
val testSources = variant.androidTest?.sources?.java?.all
if (artifact != null && testSources != null) {
tasks.register(
"${variant.name}PrintTestApk",
PrintApkLocationTask::class.java
) {
apkFolder.set(artifact)
builtArtifactsLoader.set(loader)
variantName.set(variant.name)
sources.set(testSources)
}
}
}
}
}
internal abstract class PrintApkLocationTask : DefaultTask() {
@get:InputDirectory
abstract val apkFolder: DirectoryProperty
@get:InputFiles
abstract val sources: ListProperty<Directory>
@get:Internal
abstract val builtArtifactsLoader: Property<BuiltArtifactsLoader>
@get:Input
abstract val variantName: Property<String>
@TaskAction
fun taskAction() {
val hasFiles = sources.orNull?.any { directory ->
directory.asFileTree.files.any { it.isFile }
} ?: throw RuntimeException("Cannot check androidTest sources")
// Don't print APK location if there are no androidTest source files
if (!hasFiles) {
return
}
val builtArtifacts = builtArtifactsLoader.get().load(apkFolder.get())
?: throw RuntimeException("Cannot load APKs")
if (builtArtifacts.elements.size != 1)
throw RuntimeException("Expected one APK !")
val apk = File(builtArtifacts.elements.single().outputFile).toPath()
println(apk)
}
}

@ -58,12 +58,12 @@ run_firebase_test_lab() {
set +e # To not exit on an error to retry flaky tests
local counter=0
local result=1
local module=$1
local testApk=$1
while [ $result != 0 -a $counter -lt $MAX_RETRY ]; do
gcloud firebase test android run \
--type instrumentation \
--app "app/build/outputs/apk/demo/debug/app-demo-debug.apk" \
--test "$module/build/outputs/apk/androidTest/demo/debug/$module-demo-debug-androidTest.apk" \
--test "$testApk" \
--device-ids $deviceIds \
--os-version-ids $osVersionIds \
--locales en \
@ -76,17 +76,14 @@ run_firebase_test_lab() {
# All modules with androidTest to run tests on.
# This command will create a list like ["app", "sync"] based on which subdirectories
# (assumed to be modules) have an androidTest source directory.
# The sed regex pulls out the module name from the matched directory
modules=($(find . -regex ".*/src/androidTest" | sed -E 's|\./([^/]*)/.*|\1|g'))
testApks=($(./gradlew -q demoDebugPrintTestApk))
# Run all modules in parallel with Firebase Test Lab, and fail if any fail
pids=""
result=0
for module in ${modules[@]}; do
run_firebase_test_lab $module &
for testApk in ${testApks[@]}; do
run_firebase_test_lab $testApk &
pids="$pids $!"
done

Loading…
Cancel
Save