Using an emulator snapshot?
I'd like to use an emulator snapshot I created on my local machine, but I'm having a bit of trouble sorting out how I can use it from the runner. Locally the snapshot resides in ~/.android/avd/Nexus_6_API_29.avd/snapshots. So I copied that into the repo via git-lfs. Then in my job I copy the snapshot from the repo into same path - ~/.android/avd/Nexus_6_API_29.avd/snapshots. However when I set the emulator-options to emulator-options: -snapshot SNAPSHOT_NAME -gpu swiftshader_indirect, it doesn't appear to pick it up and there's no errors or anything about the snapshot not existing.
One obvious issue might be the fact that the avd name in the runner is test not Nexus_6_API_29, but I'm really not sure. So clarification about how this could be done would be welcome.
You can set avd-name to a custom name, but I’m not sure that’ll work as the action might overwrite your snapshot when creating the AVD.
Would you be able to share your full workflow? I haven’t tested with custom snapshot so maybe we’ll need to add a new config for specifying the path of your snapshot.
Thanks for the quick reply! Let me put together a simple workflow w/o the unnecessary bits.
I was trying something like the following. Let me know if you need more information. Thanks!
name: Tests
on: [push]
jobs:
android-sdk-test:
name: Android SDK Tests
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
with:
lfs: true
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: copy emulator snapshot
run: mkdir -p ~/.android/avd/Nexus_6_API_29.avd/snapshots; cp -R android/emulator-snapshots/snap_2020-06-30_16-59-43 ~/.android/avd/Nexus_6_API_29.avd/snapshots/
- name: run tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
profile: Nexus 6
emulator-options: -snapshot snap_2020-06-30_16-59-43 -gpu swiftshader_indirect
script: ./gradlew foo:test
I've played with snapshots a bit locally. Unfortunately it seems like a snapshot only works with the original avd that it was created from. Since our action creates a new avd every time, manually putting a snapshot in the Xxx.avd/snapshots/ directory won't work 😞 .
I'm not sure if sharing snapshots around e.g in CI is a supported use case as all the demos I've seen are about speeding up local emulator startup in subsequent runs. Let me ask around.
@ychescale9 thanks for the quick response and looking into it. To clarify our problem - our app behavior requires screenlock being enabled, as far as I can tell this has to be configured by interacting with the emulator. That's why we're using a snapshot, to avoid having to do the manual step before running tests. We can just use a pre-configured snapshot and run the tests. Perhaps there's another way to address this underlying issue that I'm missing?
Have you been able to automate this process elsewhere e.g. another CI service or internal CI server? If you've been doing this locally what are the steps involved? do you have a script that works locally?
This is roughly what I've tried locally that didn't work:
- create a new AVD:
avdmanager create avd --force -n "avd_1" --abi "google_apis/x86_64" --package "system-images;android-23;google_apis;x86_64" - start an emulator from the avd created: emulator -avd "avd_1"
- go to the emulator settings and take a snapshot
- copy the new snapshot to another location
cp -R ~/.android/avd_1.avd/snapshots/snap_2020-07-09_23-18-46 mysnapshots - create a new AVD (this is equivalent to the one created by the action on every run):
avdmanager create avd --force -n "avd_2" --abi "google_apis/x86_64" --package "system-images;android-23;google_apis;x86_64" - Copy the snapshot into the new AVD:
mkdir -P ~/.android/avd_2.avd/snapshots && cp -R mysnapshots/snap_2020-07-09_23-18-46 ~/.android/avd_2.avd/snapshots/ - start the emulator with the new AVD using the snapshot:
emulator -avd "avd_2" -snapshot snap_2020-07-09_23-18-46 - The emulator does a full boot and ignores the snapshot.
Finally got the official answer re. this use case from the Android Tools team.
So TLDR is snapshots currently are dependent on the AVD that created them so to restore state of emulator we need to share the entire avd which sounds like an entirely separate project / action if this is something we want to pursue.
What speaks against doing simply this?
- name: AVD cache
uses: actions/cache@v2
with:
path: ~/.android/avd
key: ${{ runner.os }}-avd-v1
- name: Instrumentation tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 27
target: google_apis
arch: x86
profile: pixel
avd-name: pixel
emulator-options: -snapshot snapshot -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -wipe-data -netfast -camera-back none -camera-front none -cores 2
script: ...
Should probably work if android-emulator-runner would check whether the AVD already exists.
I saw this which looks interesting: https://discuss.bitrise.io/t/android-emulator-in-90-seconds/1181.
Basically they cache the snapshot of a 'clean booted' emulator. Then restart the emulator with -no-snapshot-save to actually run the tests.
Tried this out in: https://github.com/google/accompanist/pull/471
It currently doesn't work as the runner uses --force when creating the emulator, which wipes out the cache.
Thanks! I'll take a look at this soon.
@chrisbanes I got snapshot caching working based on your suggestion: https://github.com/ReactiveCircus/android-emulator-runner/pull/159
With a snapshot the Emulator boot time is down to ~15 seconds.
I added a force-avd-creation input which when set to false will skip AVD creation if an existing AVD with the same avd-name is detected.
Finally got the official answer re. this use case from the Android Tools team.
So TLDR is snapshots currently are dependent on the AVD that created them so to restore state of emulator we need to share the entire
avdwhich sounds like an entirely separate project / action if this is something we want to pursue.
Hey y'all, gonna close this for now