Skip to content
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
38 changes: 22 additions & 16 deletions .github/workflows/agent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ concurrency:
jobs:
agent-build:
name: "Agent build & test"
runs-on: macos-26
runs-on: ubuntu-latest
timeout-minutes: 45
permissions:
contents: read
Expand Down Expand Up @@ -58,6 +58,27 @@ jobs:
run: ./gradlew validateScreenshotTest -PGEMINI_API_KEY=dummy_key
working-directory: agent

- 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

- name: Setup GMD
run: |
./gradlew :app:pixel7Api37Setup \
--info \
-Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true \
-Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
working-directory: agent

- name: Run instrumentation tests
run: |
./gradlew :app:pixel7Api37StandardDebugAndroidTest -PGEMINI_API_KEY=dummy_key \
-Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true \
-Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
working-directory: agent

- name: Build Debug and Release APKs
run: ./gradlew assembleDebug assembleRelease -PGEMINI_API_KEY=dummy_key
working-directory: agent
Expand All @@ -67,18 +88,3 @@ jobs:
with:
name: agent-apks
path: agent/app/build/outputs/apk/**/*.apk

# - name: Setup GMD
# run: |
# ./gradlew :app:pixel7Api35Setup \
# --info \
# -Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true \
# -Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
# working-directory: agent
#
# - name: Run instrumentation tests
# run: |
# ./gradlew :app:pixel7Api35Check -PGEMINI_API_KEY=dummy_key \
# -Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true \
# -Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
# working-directory: agent
6 changes: 3 additions & 3 deletions agent/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ android {
}
managedDevices {
localDevices {
create("pixel7Api35") {
create("pixel7Api37") {
device = "Pixel 7"
apiLevel = 35
systemImageSource = "aosp-atd"
apiLevel = 37
systemImageSource = "google_apis"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.example.appfunctions.agent.domain

import android.content.Context
import android.os.ParcelFileDescriptor
import androidx.appfunctions.AppFunctionManager
import androidx.appfunctions.AppFunctionName
import androidx.test.core.app.ApplicationProvider
Expand All @@ -25,6 +26,7 @@ import com.example.appfunctions.agent.data.FakeAppFunctionService
import com.example.appfunctions.agent.domain.appfunction.GetAppFunctionStatesUseCase
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
Expand All @@ -42,9 +44,29 @@ class GetAppFunctionStatesUseCaseTest {
useCase = GetAppFunctionStatesUseCase(appFunctionManager)

// Adopt shell permission identity
InstrumentationRegistry.getInstrumentation()
.uiAutomation
.adoptShellPermissionIdentity("android.permission.EXECUTE_APP_FUNCTIONS")
val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation
uiAutomation.adoptShellPermissionIdentity("android.permission.EXECUTE_APP_FUNCTIONS")

waitForFakeFunctionIndexed()
}

private fun waitForFakeFunctionIndexed() {
val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation
val command = "cmd app_function list-app-functions --package ${context.packageName}"
var output = ""
val timeoutMs = 10_000L
val startTime = System.currentTimeMillis()
while (System.currentTimeMillis() - startTime < timeoutMs) {
output =
ParcelFileDescriptor.AutoCloseInputStream(
uiAutomation.executeShellCommand(command),
).bufferedReader().use { it.readText() }
if (output.contains("fakeFunction")) {
return
}
Thread.sleep(500)
}
fail("Timed out waiting for fakeFunction to be indexed. Output of '$command': $output")
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.example.appfunctions.agent.domain

import android.content.Context
import android.os.ParcelFileDescriptor
import androidx.appfunctions.AppFunctionManager
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
Expand All @@ -28,6 +29,7 @@ import com.example.appfunctions.agent.domain.appfunction.GetAppFunctionsUseCase
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
Expand Down Expand Up @@ -55,6 +57,27 @@ class GetAppFunctionsUseCaseTest {
InstrumentationRegistry.getInstrumentation()
.uiAutomation
.adoptShellPermissionIdentity("android.permission.EXECUTE_APP_FUNCTIONS")

waitForFakeFunctionIndexed()
}

private fun waitForFakeFunctionIndexed() {
val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation
val command = "cmd app_function list-app-functions --package ${context.packageName}"
var output = ""
val timeoutMs = 10_000L
val startTime = System.currentTimeMillis()
while (System.currentTimeMillis() - startTime < timeoutMs) {
output =
ParcelFileDescriptor.AutoCloseInputStream(
uiAutomation.executeShellCommand(command),
).bufferedReader().use { it.readText() }
if (output.contains("fakeFunction")) {
return
}
Thread.sleep(500)
}
fail("Timed out waiting for fakeFunction to be indexed. Output of '$command': $output")
}

@Test
Expand Down
Loading