ReactiveCircus / android-emulator-runner

A GitHub Action for installing, configuring and running hardware-accelerated Android Emulators on macOS virtual machines.
Apache License 2.0
945 stars 185 forks source link

Error: Connection Refused on Port 5554 #330

Open Haidar0096 opened 1 year ago

Haidar0096 commented 1 year ago

I have this workflow (nothing fancy or complicated, just some steps to setup java and flutter, then running the tests on the emulator)

on:
  workflow_dispatch:
  # on push to main branch
  push:
    branches:
      - main

name: "Demo"

jobs:
  test:
    name: Run Flutter tests
    runs-on: macos-latest
    strategy:
      matrix:
        api-level: [26, 29, 30]
    steps:
      - run: echo Starting Tests at $(date)

      - name: checkout
        uses: actions/checkout@v3

      - name: Gradle cache
        uses: gradle/gradle-build-action@v2

      - name: Setup Java
        uses: actions/setup-java@v3
        with:
          distribution: "oracle"
          java-version: "17"

      - name: Setup Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: "3.7.5"

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

      - name: Restart adb server
        run: |
          adb kill-server
          echo "Killed adb server"
          adb start-server
          echo "Started adb server"

      - name: create AVD and generate snapshot for caching
        if: steps.avd-cache.outputs.cache-hit != 'true'
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: "x86_64"
          target: google_apis

          force-avd-creation: false
          emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: false
          script: echo "Generated AVD snapshot for caching."

      - name: run tests on android emulator
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: "x86_64"
          force-avd-creation: false
          emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: false
          script: flutter drive --driver=test_driver/integration_test_driver.dart --target=integration_test/app_test.dart --dart-define="testDeviceId=testingdevice123"

      - name: Launch iOS Simulator
        uses: futureware-tech/simulator-action@v2
        with:
          model: "iPhone 14"
      - name: Run tests on iOS Simulator 
        run: flutter drive --driver=test_driver/integration_test_driver.dart --target=integration_test/app_test.dart --dart-define="testDeviceId=testingdevice123"

when I run it, it sometimes succeed and sometimes fail with this error:

run tests on android emulator 10m 52s
Run reactivecircus/android-emulator-runner@v2
Configure emulator
Install Android SDK
Launch Emulator
Terminate Emulator
  /Users/runner/Library/Android/sdk/platform-tools/adb -s emulator-5554 emu kill
  error: could not connect to TCP port 5554: Connection refused
  The process '/Users/runner/Library/Android/sdk/platform-tools/adb' failed with exit code [1](https://github.com/Haidar0096/demo/actions/runs/4412981785/jobs/7732965220#step:10:1)
Error: Timeout waiting for emulator to boot.

or with this error:

9s
Run reactivecircus/android-emulator-runner@v2
Configure emulator
  API level: 33
  target: default
  CPU architecture: x86_64
  Hardware profile: 
  Cores: 2
  RAM size: 
  Heap size: 
  SD card path or size: 
  Disk size: 
  AVD name: test
  force avd creation: false
  emulator options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
  disable animations: false
  disable spellchecker: false
  disable Linux hardware acceleration: false
  enable hardware keyboard: false
  Channel: 0 (stable)
  Script:
  flutter drive --driver=test_driver/integration_test_driver.dart --target=integration_test/app_test.dart --dart-define="testDeviceId=testingdevice[1](https://github.com/Haidar0096/demo/actions/runs/4412784852/jobs/7732579855#step:11:1)23"
  Pre emulator launch script:
Install Android SDK
  /bin/sh -c \yes | sdkmanager --licenses > /dev/null
  Installing latest build tools, platform tools, and platform.
  /bin/sh -c \sdkmanager --install 'build-tools;[33](https://github.com/Haidar0096/demo/actions/runs/4412784852/jobs/7732579855#step:11:34).0.0' platform-tools 'platforms;android-33' > /dev/null
  Installing latest emulator.
  /bin/sh -c \sdkmanager --install emulator --channel=0 > /dev/null
  Installing system images.
  /bin/sh -c \sdkmanager --install 'system-images;android-33;default;x86_64' --channel=0 > /dev/null
  Warning: Failed to find package 'system-images;android-33;default;x86_64'
Terminate Emulator
  /Users/runner/Library/Android/sdk/platform-tools/adb -s emulator-55[54](https://github.com/Haidar0096/demo/actions/runs/4412784852/jobs/7732579855#step:11:57) emu kill
  error: could not connect to TCP port [55](https://github.com/Haidar0096/demo/actions/runs/4412784852/jobs/7732579855#step:11:58)54: Connection refused
  The process '/Users/runner/Library/Android/sdk/platform-tools/adb' failed with exit code 1
Error: The process '/bin/sh' failed with exit code 1

I searched alot before opening this issue, here and on google, and tried different solutions like restarting the adb and using a specific build for the emulator but it seems this action is not predictable, it still fails sometimes and succeeds sometimes even if I haven't changed the code at all. Is there something I can do to make sure it will always succeed?

dumbfingers commented 1 year ago

I met this problem just now. I think this line shows where it went wrong:

Warning: Failed to find package 'system-images;android-33;default;x86_64'

It is because not all combinations of system images are available in all API level.

maybe check with avdmanager to see if android 33 + default + x86_64 exists or not. Or change it to another arch like x86 or different API level

Haidar0096 commented 1 year ago

@dumbfingers this is not the only error, there are alot of other errors, I tried running an emulator with another api (26 for instance). The emulator launches, but because my app uses firebase, it gives the error:

E/FirebaseInstanceId(10912): Topic sync or token retrieval failed on hard failure exceptions: AUTHENTICATION_FAILED. Won't retry the operation.
I/flutter (10912): ══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
I/flutter (10912): The following FirebaseException was thrown running a test:
I/flutter (10912): [firebase_messaging/unknown] java.io.IOException: AUTHENTICATION_FAILED

I gave up on using this action for now until these 2 issues (booting the emulator and using firebase services) are solved. I already used all my account free minutes trying different configuartions but none of them work: newer api emulators (above 29) won't launch at all, and older ones which launch seem to now work with firebase push notifications.

proninyaroslav commented 1 year ago

I had similar problems with the API 33 emulator and it turned out that target: default tries to download the emulator without the Google API, which is missing in API 33. So my solution was to specify target: google_apis and arch: x86_64:

jobs:
  test:
    runs-on: macos-latest
    strategy:
      matrix:
        api-level: [21, 33]
        target: [google_apis]
        arch: [x86_64]
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Gradle cache
        uses: gradle/gradle-build-action@v2

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

      - name: Create AVD and generate snapshot for caching
        if: steps.avd-cache.outputs.cache-hit != 'true'
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          target: ${{ matrix.target }}
          arch: ${{ matrix.arch }}
          force-avd-creation: false
          emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: false
          script: echo "Generated AVD snapshot for caching."

      - name: Run tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          target: ${{ matrix.target }}
          arch: ${{ matrix.arch }}
          force-avd-creation: false
          emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: true
          script: ./gradlew connectedAndroidTest
Haidar0096 commented 1 year ago

I had similar problems with the API 33 emulator and it turned out that target: default tries to download the emulator without the Google API, which is missing in API 33. So my solution was to specify target: google_apis and arch: x86_64:

jobs:
  test:
    runs-on: macos-latest
    strategy:
      matrix:
        api-level: [21, 33]
        target: [google_apis]
        arch: [x86_64]
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Gradle cache
        uses: gradle/gradle-build-action@v2

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

      - name: Create AVD and generate snapshot for caching
        if: steps.avd-cache.outputs.cache-hit != 'true'
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          target: ${{ matrix.target }}
          arch: ${{ matrix.arch }}
          force-avd-creation: false
          emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: false
          script: echo "Generated AVD snapshot for caching."

      - name: Run tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          target: ${{ matrix.target }}
          arch: ${{ matrix.arch }}
          force-avd-creation: false
          emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: true
          script: ./gradlew connectedAndroidTest

@proninyaroslav I have 2 questions:

proninyaroslav commented 1 year ago

@Haidar0096 The emulator starts but I can't run Gradle, so this turned out to be pointless for me:

* What went wrong:
A problem occurred configuring root project 'OpenComicVine'.
> Could not resolve all files for configuration ':classpath'.
   > Could not resolve com.android.tools.build:gradle:7.4.2.
     Required by:
         project : > com.android.application:com.android.application.gradle.plugin:7.4.2
         project : > com.android.library:com.android.library.gradle.plugin:7.4.2
Haidar0096 commented 1 year ago

@Haidar0096 The emulator starts but I can't run Gradle, so this turned out to be pointless for me:

* What went wrong:
A problem occurred configuring root project 'OpenComicVine'.
> Could not resolve all files for configuration ':classpath'.
   > Could not resolve com.android.tools.build:gradle:7.4.2.
     Required by:
         project : > com.android.application:com.android.application.gradle.plugin:7.4.2
         project : > com.android.library:com.android.library.gradle.plugin:7.4.2

@proninyaroslav I tried booting the emulator with an older api (26 and 27) and it launches successfully, but it doesn't seem that the google_apis target is doing anything, I get firebase exception indicating that the connection to firebase fails https://stackoverflow.com/q/75758679/9142279

brandinooo98 commented 1 year ago

@Haidar0096 @proninyaroslav After following your footsteps I was able to find what was causing the gradle error. This error occurs because the default Java version is Java 1.8, but we require Java 11. Adding this to my workflow solved this issue:

    - name: set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
        cache: gradle
Haidar0096 commented 1 year ago

@brandinooo98 dude what gradle exception?

I am already setting up java to version 17:

      - name: Setup Java
        uses: actions/setup-java@v3
        with:
          distribution: "oracle"
          java-version: "17"

But there are 2 errors, first, the emulator won't boot.

And second, even if the emulator boots, firebase services fail to initialize, seems that setting google_apis as a target for the emulator has no effect and does not work