Skip to content

Commit

Permalink
Wait for emulator boot before adb shell interactions (#57)
Browse files Browse the repository at this point in the history
* Wait for emulator boot before adb shell interactions

* Logging and doc updates

* *
  • Loading branch information
ofalvai authored Jan 23, 2025
1 parent 22f5307 commit 9bc13d4
Show file tree
Hide file tree
Showing 19 changed files with 586 additions and 83 deletions.
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ Run instrumented and UI tests on a virtual Android device. Once some basic input

Some system images are pre-installed on the virtual machines. In this case the step won't have to spend time downloading the requested image. To check the list of pre-installed images for each stack, visit the [system reports](https://stacks.bitrise.io).

### Troubleshooting
The emulator needs some time to boot up. The earlier you place the Step in your Workflow, the more tasks, such as cloning or caching, you can complete in your Workflow before the emulator starts working.
We recommend that you also add **Wait for Android emulator** Step to your Workflow as it acts as a shield preventing the AVD Manager to kick in too early. Make sure you add the **Wait for Android emulator** Step BEFORE the Step with which you want to use the **AVD Manager**.
By default, the Step waits for the emulator to boot up and disables system animations in order to make tests faster and more reliable. If you want to disable these, set the **Disable animations** input to `no`. In this case, make sure to add the [Wait for Android emulator Step](https://github.com/bitrise-steplib/steps-wait-for-android-emulator) to the right part of your workflow.

### Useful links
- [Getting started with Android apps](https://devcenter.bitrise.io/getting-started/getting-started-with-android-apps/)
Expand Down Expand Up @@ -50,7 +48,7 @@ You can also run this step directly with [Bitrise CLI](https://github.com/bitris
| `api_level` | The device will run with the specified system image version. | required | `26` |
| `tag` | Select OS tag to have the required toolset on the device. | required | `google_apis` |
| `abi` | Select which ABI to use running the emulator. Availability depends on API level. Please use `sdkmanager --list` command to see the available ABIs. | required | `x86` |
| `disable_animations` | Disable animations on the emulator in order to make tests faster and more stable. Animations can be enabled/disabled from the test code too, so if your tests do need animations, set this step input to `no` and control the settings yourself. | required | `yes` |
| `disable_animations` | Disable animations on the emulator in order to make tests faster and more stable. Note: when this input is `yes`, the step will pause and wait for the device to boot up. Animations can be enabled/disabled from the test code too, so if your tests do need animations, set this step input to `no` and control the settings yourself. | required | `yes` |
| `emulator_id` | Set the device's ID. (This will be the name under $HOME/.android/avd/) | required | `emulator` |
| `create_command_flags` | Flags used when running the command to create the emulator. | | `--sdcard 2048M` |
| `start_command_flags` | Flags used when running the command to start the emulator. | | `-camera-back none -camera-front none` |
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module github.com/bitrise-steplib/steps-avd-manager
go 1.21

require (
github.com/bitrise-io/go-android v0.0.0-20210527143215-3ad22ad02e2e
github.com/bitrise-io/go-steputils v1.0.2
github.com/bitrise-io/go-utils v1.0.2
github.com/bitrise-io/go-android/v2 v2.0.0-alpha.10
github.com/bitrise-io/go-steputils v1.0.6
github.com/bitrise-io/go-utils v1.0.13
github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.23
github.com/hashicorp/go-retryablehttp v0.7.7
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
Expand All @@ -15,7 +15,7 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-version v1.3.0 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.22.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
145 changes: 123 additions & 22 deletions go.sum

Large diffs are not rendered by default.

35 changes: 21 additions & 14 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (
"strings"
"time"

"github.com/bitrise-io/go-android/sdk"
"github.com/bitrise-io/go-android/v2/adbmanager"
"github.com/bitrise-io/go-android/v2/sdk"
"github.com/bitrise-io/go-steputils/stepconf"
"github.com/bitrise-io/go-steputils/tools"
"github.com/bitrise-io/go-utils/command"
Expand All @@ -26,7 +27,6 @@ import (

type config struct {
AndroidHome string `env:"ANDROID_HOME"`
AndroidSDKRoot string `env:"ANDROID_SDK_ROOT"`
APILevel int `env:"api_level,required"`
Tag string `env:"tag,opt[google_apis,google_apis_playstore,aosp_atd,google_atd,android-wear,android-tv,default]"`
DeviceProfile string `env:"profile,required"`
Expand Down Expand Up @@ -95,16 +95,12 @@ func main() {

// Initialize Android SDK
log.Infof("Initialize Android SDK")
androidSdk, err := sdk.NewDefaultModel(sdk.Environment{
AndroidHome: cfg.AndroidHome,
AndroidSDKRoot: cfg.AndroidSDKRoot,
})
androidSdk, err := sdk.New(cfg.AndroidHome)
if err != nil {
failf("Failed to initialize Android SDK: %s", err)
}

androidHome := androidSdk.GetAndroidHome()
adbClient := adb.New(androidHome, cmdFactory, logger)
adbClient := adb.New(cfg.AndroidHome, cmdFactory, logger)
runningDevicesBeforeBoot, err := adbClient.Devices()
if err != nil {
failf("Failed to check running devices, error: %s", err)
Expand All @@ -118,7 +114,7 @@ func main() {
var (
sdkManagerPath = filepath.Join(cmdlineToolsPath, "sdkmanager")
avdManagerPath = filepath.Join(cmdlineToolsPath, "avdmanager")
emulatorPath = filepath.Join(androidHome, "emulator", "emulator")
emulatorPath = filepath.Join(cfg.AndroidHome, "emulator", "emulator")

pkg = fmt.Sprintf("system-images;android-%d;%s;%s", cfg.APILevel, cfg.Tag, cfg.Abi)
yes, no = strings.Repeat("yes\n", 20), strings.Repeat("no\n", 20)
Expand All @@ -136,7 +132,7 @@ func main() {

if cfg.EmulatorBuildNumber != emuBuildNumberPreinstalled {
httpClient := retryhttp.NewClient(logger)
emuInstaller := emuinstaller.NewEmuInstaller(androidHome, cmdFactory, logger, httpClient)
emuInstaller := emuinstaller.NewEmuInstaller(cfg.AndroidHome, cmdFactory, logger, httpClient)
if err := emuInstaller.Install(cfg.EmulatorBuildNumber); err != nil {
failf("Failed to install emulator build %s: %s", cfg.EmulatorBuildNumber, err)
}
Expand Down Expand Up @@ -207,21 +203,32 @@ func main() {
}
args = append(args, startCustomFlags...)

serial := startEmulator(adbClient, emulatorPath, args, androidHome, runningDevicesBeforeBoot, 1)
serial := startEmulator(adbClient, emulatorPath, args, cfg.AndroidHome, runningDevicesBeforeBoot, 1)

if cfg.DisableAnimations {
// We need to wait for the device to boot before we can disable animations
adb, err := adbmanager.New(androidSdk, cmdFactory, logger)
if err != nil {
failf("Failed to create ADB model: %s", err)
}
err = adb.WaitForDevice(serial, bootTimeout)
if err != nil {
failf(err.Error())
}

err = adbClient.DisableAnimations(serial)
if err != nil {
failf("Failed to disable animations: %s", err)
}
log.Donef("Done")
}

if err := tools.ExportEnvironmentWithEnvman("BITRISE_EMULATOR_SERIAL", serial); err != nil {
log.Warnf("Failed to export environment (BITRISE_EMULATOR_SERIAL), error: %s", err)
}
log.Printf("- Device with serial: %s started", serial)

log.Donef("- Done")
log.Printf("")
log.Infof("Step outputs")
log.Printf("$BITRISE_EMULATOR_SERIAL=%s", serial)
}

func startEmulator(adbClient adb.ADB, emulatorPath string, args []string, androidHome string, runningDevices map[string]string, attempt int) string {
Expand Down
6 changes: 3 additions & 3 deletions step.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ description: |-
Some system images are pre-installed on the virtual machines. In this case the step won't have to spend time downloading the requested image. To check the list of pre-installed images for each stack, visit the [system reports](https://stacks.bitrise.io).
### Troubleshooting
The emulator needs some time to boot up. The earlier you place the Step in your Workflow, the more tasks, such as cloning or caching, you can complete in your Workflow before the emulator starts working.
We recommend that you also add **Wait for Android emulator** Step to your Workflow as it acts as a shield preventing the AVD Manager to kick in too early. Make sure you add the **Wait for Android emulator** Step BEFORE the Step with which you want to use the **AVD Manager**.
By default, the Step waits for the emulator to boot up and disables system animations in order to make tests faster and more reliable. If you want to disable these, set the **Disable animations** input to `no`. In this case, make sure to add the [Wait for Android emulator Step](https://github.com/bitrise-steplib/steps-wait-for-android-emulator) to the right part of your workflow.
### Useful links
- [Getting started with Android apps](https://devcenter.bitrise.io/getting-started/getting-started-with-android-apps/)
Expand Down Expand Up @@ -93,6 +91,8 @@ inputs:
description: |-
Disable animations on the emulator in order to make tests faster and more stable.
Note: when this input is `yes`, the step will pause and wait for the device to boot up.
Animations can be enabled/disabled from the test code too, so if your tests do need animations, set this step input to `no` and control the settings yourself.
is_required: true
value_options:
Expand Down
145 changes: 145 additions & 0 deletions vendor/github.com/bitrise-io/go-android/v2/adbmanager/adbmanager.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 48 additions & 0 deletions vendor/github.com/bitrise-io/go-android/v2/adbmanager/boot.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions vendor/github.com/bitrise-io/go-utils/command/command.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9bc13d4

Please sign in to comment.