Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task: Use GMD (Gradle Managed Devices) to run Espresso tests #53

Merged
merged 1 commit into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 26 additions & 58 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ jobs:
name: Espresso tests
# Android emulators require hardware acceleration (HAXM on Mac & Windows, QEMU on Linux) from the host to run fast.
# The macOS VM provided by GitHub Actions is the only one that currently supports it.
runs-on: macos-latest
runs-on: ubuntu-latest
timeout-minutes: 45
env:
JAVA_TOOL_OPTIONS: -Xmx4g
Expand All @@ -339,22 +339,33 @@ jobs:
# Allow tests to continue on other devices if they fail on one device.
fail-fast: false
matrix:
api-level: [26, 30]
target: [google_apis]
arch: [x86_64]
api-level: [28, 31]

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
ls /dev/kvm

- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

- name: Setup JDK
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17.0.10

- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Setup Android SDK
uses: android-actions/setup-android@v3

- name: Validate gradle wrapper
uses: gradle/wrapper-validation-action@v1
Expand All @@ -363,58 +374,15 @@ jobs:
- name: Create Local Properties File
run: touch local.properties

- name: AVD cache
uses: actions/cache@v2
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
~/.android/debug.keystore
key: avd-${{ matrix.api-level }}-${{ matrix.arch }}-${{ matrix.target }}

- name: Assemble Android tests
uses: gradle/gradle-build-action@v2
with:
arguments: assembleAndroidTest
- name: Accept Android licenses
run: yes | "$ANDROID_HOME"/cmdline-tools/latest/bin/sdkmanager --licenses || true

- name: Run emulator to generate snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/[email protected]
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: ${{ matrix.arch }}
profile: Galaxy Nexus
cores: 2
sdcard-path-or-size: 100M
avd-name: api${{ matrix.api-level }}-${{ matrix.arch }}-${{ matrix.target }}
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: false
channel: stable
script: echo "Generated AVD snapshot for caching."

## Actual task
- name: Run Android tests on API ${{ matrix.api-level }} / ${{ matrix.arch }} / ${{ matrix.target }}
uses: reactivecircus/[email protected]
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: ${{ matrix.arch }}
profile: Galaxy Nexus
cores: 2
ram-size: 2048M
sdcard-path-or-size: 100M
avd-name: api${{ matrix.api-level }}-${{ matrix.arch }}-${{ matrix.target }}
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
channel: stable
script: |
echo $GITHUB_REPOSITORY
adb devices
./gradlew apps:forlago:connectedCheck
- name: Run Espresso tests on Pixel6 Api${{ matrix.api-level }} AOSP
run:
./gradlew :apps:forlago:pixel6Api${{ matrix.api-level }}aospDebugAndroidTest
-Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true
-Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
--max-workers=1

- name: Make file path compatible with upload-artifact
run: find . -path '*/build/*' -name '*:*' -exec bash -c 'mv "$0" "${0//:/_}"' {} \;
Expand All @@ -423,7 +391,7 @@ jobs:
if: always()
uses: actions/upload-artifact@v3
with:
name: instrumentation-test-results-${{ matrix.api-level }}-${{ matrix.arch }}-${{ matrix.target }}
name: instrumentation-test-results-${{ matrix.api-level }}
path: |
**/build/reports/*
**/build/outputs/*/connected/*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.leinardi.forlago.gmd

import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.ManagedVirtualDevice
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.invoke

/**
* Configure project for Gradle managed devices
*/
internal fun configureGradleManagedDevices(
commonExtension: CommonExtension<*, *, *, *, *, *>,
) {
val pixel6Api31 = DeviceConfig("Pixel 6", 31, "aosp")
val pixel6Api28 = DeviceConfig("Pixel 6", 28, "aosp")

val allDevices = listOf(pixel6Api31, pixel6Api28)

commonExtension.testOptions {
managedDevices {
devices {
allDevices.forEach { deviceConfig ->
create<ManagedVirtualDevice>(deviceConfig.taskName).apply {
device = deviceConfig.device
apiLevel = deviceConfig.apiLevel
systemImageSource = deviceConfig.systemImageSource
}
}
}
}
}
}

private data class DeviceConfig(
val device: String,
val apiLevel: Int,
val systemImageSource: String,
) {
val taskName = buildString {
append(device.lowercase().replace(" ", ""))
append("Api")
append(apiLevel.toString())
append(systemImageSource.replace("-", ""))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import com.android.build.gradle.internal.tasks.factory.dependsOn
import com.leinardi.forlago.gmd.configureGradleManagedDevices
import com.mikepenz.aboutlibraries.plugin.DuplicateMode
import com.mikepenz.aboutlibraries.plugin.DuplicateRule
import com.project.starter.easylauncher.filter.ChromeLikeFilter
Expand Down Expand Up @@ -51,6 +52,7 @@ android {
testOptions {
execution = "ANDROIDX_TEST_ORCHESTRATOR"
}
configureGradleManagedDevices(this)
kotlinOptions {
freeCompilerArgs = freeCompilerArgs + listOf(
"-opt-in=androidx.compose.material.ExperimentalMaterialApi",
Expand Down
Loading