android-emulator-runner icon indicating copy to clipboard operation
android-emulator-runner copied to clipboard

Using an emulator snapshot?

Open swannodette opened this issue 5 years ago • 12 comments

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.

swannodette avatar Jul 01 '20 17:07 swannodette

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.

ychescale9 avatar Jul 02 '20 00:07 ychescale9

Thanks for the quick reply! Let me put together a simple workflow w/o the unnecessary bits.

swannodette avatar Jul 04 '20 23:07 swannodette

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

swannodette avatar Jul 06 '20 14:07 swannodette

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 avatar Jul 09 '20 13:07 ychescale9

@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?

swannodette avatar Jul 09 '20 13:07 swannodette

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:

  1. 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"
  2. start an emulator from the avd created: emulator -avd "avd_1"
  3. go to the emulator settings and take a snapshot
  4. copy the new snapshot to another location cp -R ~/.android/avd_1.avd/snapshots/snap_2020-07-09_23-18-46 mysnapshots
  5. 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"
  6. 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/
  7. start the emulator with the new AVD using the snapshot: emulator -avd "avd_2" -snapshot snap_2020-07-09_23-18-46
  8. The emulator does a full boot and ignores the snapshot.

ychescale9 avatar Jul 09 '20 14:07 ychescale9

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.

ychescale9 avatar Jul 31 '20 04:07 ychescale9

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.

amq avatar Dec 13 '20 10:12 amq

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.

chrisbanes avatar Jun 08 '21 15:06 chrisbanes

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.

chrisbanes avatar Jun 08 '21 16:06 chrisbanes

Thanks! I'll take a look at this soon.

ychescale9 avatar Jun 08 '21 16:06 ychescale9

@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.

ychescale9 avatar Jun 18 '21 06:06 ychescale9

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.

Hey y'all, gonna close this for now

mrk-han avatar Nov 02 '22 04:11 mrk-han