Skip to content

Commit 7271c22

Browse files
Copilotkirklandsign
andcommitted
Make workflow generic and add model download to SanityCheck
1. Renamed workflow to "Android Emulator Tests" (generic, not DL3-specific) 2. Added demo_path input parameter for flexibility 3. Updated SanityCheck.kt to download model if not present 4. Updated run-ci-tests.sh to be generic (uses DEMO_NAME) 5. Updated README to reflect model auto-download in tests Co-authored-by: kirklandsign <107070759+kirklandsign@users.noreply.github.com>
1 parent 44fd8f8 commit 7271c22

4 files changed

Lines changed: 77 additions & 23 deletions

File tree

.github/workflows/android-emulator.yml

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# This source code is licensed under the BSD-style license found in the
55
# LICENSE file in the root directory of this source tree.
66

7-
name: DL3 Android Emulator
7+
name: Android Emulator Tests
88

99
on:
1010
pull_request:
@@ -13,6 +13,12 @@ on:
1313
- 'dl3/android/**'
1414
- '.github/workflows/android-emulator.yml'
1515
workflow_dispatch:
16+
inputs:
17+
demo_path:
18+
description: 'Path to Android demo (e.g., dl3/android/DeepLabV3Demo)'
19+
required: false
20+
default: 'dl3/android/DeepLabV3Demo'
21+
type: string
1622

1723
permissions:
1824
contents: read
@@ -23,12 +29,20 @@ jobs:
2329
env:
2430
API_LEVEL: 34
2531
ARCH: x86_64
32+
DEMO_PATH: ${{ inputs.demo_path || 'dl3/android/DeepLabV3Demo' }}
2633

27-
name: Instrumentation Test DL3
34+
name: Instrumentation Test Android Emulator
2835
steps:
2936
- name: Checkout repository
3037
uses: actions/checkout@v4
3138

39+
- name: Determine demo name
40+
id: demo-info
41+
run: |
42+
DEMO_NAME=$(basename "${{ env.DEMO_PATH }}")
43+
echo "demo_name=$DEMO_NAME" >> $GITHUB_OUTPUT
44+
echo "Testing: $DEMO_NAME"
45+
3246
- name: Enable KVM group perms
3347
run: |
3448
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
@@ -51,7 +65,7 @@ jobs:
5165
path: |
5266
~/.android/avd/*
5367
~/.android/adb*
54-
key: avd-${{ env.API_LEVEL }}-${{ env.ARCH }}-ram8G-disk8G-dl3-v1
68+
key: avd-${{ env.API_LEVEL }}-${{ env.ARCH }}-ram8G-disk8G-${{ steps.demo-info.outputs.demo_name }}-v1
5569

5670
- name: Create AVD and generate snapshot for caching
5771
if: steps.avd-cache.outputs.cache-hit != 'true'
@@ -64,7 +78,7 @@ jobs:
6478
force-avd-creation: true
6579
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -no-snapshot-save -memory 8192
6680
disable-animations: false
67-
working-directory: dl3/android/DeepLabV3Demo
81+
working-directory: ${{ env.DEMO_PATH }}
6882
script: echo "Generated AVD snapshot for caching."
6983

7084
- name: Run instrumentation tests
@@ -77,13 +91,13 @@ jobs:
7791
force-avd-creation: true
7892
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -no-snapshot-save -memory 8192
7993
disable-animations: true
80-
working-directory: dl3/android/DeepLabV3Demo
94+
working-directory: ${{ env.DEMO_PATH }}
8195
script: bash ./scripts/run-ci-tests.sh
8296

8397
- name: Upload logcat
8498
if: always()
8599
uses: actions/upload-artifact@v4
86100
with:
87-
name: logcat-dl3
88-
path: /tmp/logcat-dl3.txt
101+
name: logcat-${{ steps.demo-info.outputs.demo_name }}
102+
path: /tmp/logcat-*.txt
89103
retention-days: 7

dl3/android/DeepLabV3Demo/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ Open `app/src/androidTest/java/org/pytorch/executorchexamples/dl3/SanityCheck.kt
106106

107107
### Test Files
108108
- **SanityCheck.kt**: Basic module forward pass test
109+
- Downloads model automatically if not present
109110
- Tests model loading from app's private storage
110-
- Validates model output shape
111-
- Skips gracefully if model not yet downloaded
111+
- Validates model output shape (batch_size × classes × width × height)
112112

113113
> **Note**: UI workflow tests for the Compose-based interface are planned for a future update.
114114

dl3/android/DeepLabV3Demo/app/src/androidTest/java/org/pytorch/executorchexamples/dl3/SanityCheck.kt

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,43 +9,79 @@
99
package org.pytorch.executorchexamples.dl3
1010

1111
import android.content.Context
12+
import android.util.Log
1213
import androidx.test.core.app.ApplicationProvider
1314
import androidx.test.filters.SmallTest
1415
import org.junit.Assert.assertEquals
15-
import org.junit.Assume.assumeTrue
1616
import org.junit.Before
1717
import org.junit.Test
1818
import org.pytorch.executorch.Module
1919
import org.pytorch.executorch.Tensor
2020
import java.io.File
21+
import java.io.FileOutputStream
22+
import java.net.HttpURLConnection
23+
import java.net.URL
2124

2225
/**
2326
* Sanity check test for model loading.
2427
*
25-
* This test will skip if the model file is not available.
26-
* The model should be in the app's private storage (same location as MainActivity uses).
28+
* This test downloads the model if not available and validates model functionality.
29+
* The model is stored in the app's private storage (same location as MainActivity uses).
2730
*/
2831
@SmallTest
2932
class SanityCheck {
3033

3134
companion object {
3235
private const val MODEL_FILENAME = "dl3_xnnpack_fp32.pte"
36+
private const val MODEL_URL = "https://ossci-android.s3.amazonaws.com/executorch/models/snapshot-20260116/dl3_xnnpack_fp32.pte"
37+
private const val TAG = "SanityCheck"
3338
}
3439

3540
private lateinit var modelPath: String
41+
private lateinit var context: Context
3642

3743
@Before
3844
fun setUp() {
3945
// Use the app's private files directory (same as MainActivity)
40-
val context = ApplicationProvider.getApplicationContext<Context>()
46+
context = ApplicationProvider.getApplicationContext()
4147
modelPath = "${context.filesDir.absolutePath}/$MODEL_FILENAME"
4248

43-
// Check if model file exists, skip test if not
49+
// Download model if not present
4450
val modelFile = File(modelPath)
45-
assumeTrue(
46-
"Model file not found at $modelPath. Run UIWorkflowTest first to download the model.",
47-
modelFile.exists()
48-
)
51+
if (!modelFile.exists()) {
52+
Log.i(TAG, "Model not found at $modelPath, downloading...")
53+
downloadModel()
54+
} else {
55+
Log.i(TAG, "Model found at $modelPath")
56+
}
57+
}
58+
59+
private fun downloadModel() {
60+
try {
61+
val url = URL(MODEL_URL)
62+
val connection = url.openConnection() as HttpURLConnection
63+
connection.requestMethod = "GET"
64+
connection.instanceFollowRedirects = true
65+
connection.connect()
66+
67+
if (connection.responseCode != HttpURLConnection.HTTP_OK) {
68+
throw RuntimeException("Server returned HTTP ${connection.responseCode}")
69+
}
70+
71+
connection.inputStream.use { input ->
72+
FileOutputStream(modelPath).use { output ->
73+
val buffer = ByteArray(4096)
74+
var bytesRead: Int
75+
while (input.read(buffer).also { bytesRead = it } != -1) {
76+
output.write(buffer, 0, bytesRead)
77+
}
78+
}
79+
}
80+
Log.i(TAG, "Model downloaded successfully to $modelPath")
81+
} catch (e: Exception) {
82+
Log.e(TAG, "Failed to download model", e)
83+
throw RuntimeException("Failed to download model: ${e.message}", e)
84+
}
4985
}
5086

5187
@Test

dl3/android/DeepLabV3Demo/scripts/run-ci-tests.sh

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55
# This source code is licensed under the BSD-style license found in the
66
# LICENSE file in the root directory of this source tree.
77

8-
# CI test script for running DL3 instrumentation tests
9-
# The model will be downloaded automatically by the app during the test
8+
# CI test script for running Android instrumentation tests
9+
# The model will be downloaded automatically by the test if needed
1010

1111
set -ex
1212

13+
DEMO_NAME=$(basename "$PWD")
14+
1315
echo "=== Test Configuration ==="
14-
echo "DL3 Demo - Model will be downloaded by the app"
16+
echo "Demo: $DEMO_NAME"
17+
echo "Model will be downloaded by the test if not present"
1518

1619
echo "=== Emulator Memory Info ==="
1720
adb shell cat /proc/meminfo | head -5
@@ -20,8 +23,9 @@ echo "=== Emulator Disk Space ==="
2023
adb shell df -h /data
2124

2225
# Start logcat capture
26+
LOGCAT_FILE="/tmp/logcat-${DEMO_NAME}.txt"
2327
adb logcat -c
24-
adb logcat > /tmp/logcat-dl3.txt &
28+
adb logcat > "$LOGCAT_FILE" &
2529
LOGCAT_PID=$!
2630

2731
echo "=== Starting Gradle ==="
@@ -41,6 +45,6 @@ else
4145
fi
4246

4347
echo "=== Checking for test results in logcat ==="
44-
grep "UIWorkflowTest" /tmp/logcat-dl3.txt || echo "No UIWorkflowTest logs found"
48+
grep "SanityCheck" "$LOGCAT_FILE" || echo "No SanityCheck logs found"
4549

4650
exit $TEST_EXIT_CODE

0 commit comments

Comments
 (0)