From 4eb065786a6f6eef9462502426392c45445a71f1 Mon Sep 17 00:00:00 2001 From: lpusok <7979773+lpusok@users.noreply.github.com> Date: Thu, 1 Sep 2022 11:52:32 +0200 Subject: [PATCH] [BE-231] Disable emulator update (#44) - Added no update option to the channel selector, this is the new default. If selected no sdkmanager command is run, and the preinstalled emulator and system image will be used. - Added headless_mode input, the default is true, this will not introduce a behavior change. --- README.md | 3 +- e2e/bitrise.yml | 7 ++- main.go | 46 +++++++++++++------ step.yml | 29 ++++++++++-- .../go-utils/sliceutil/sliceutil.go | 46 +++++++++++++++++++ vendor/modules.txt | 1 + 6 files changed, 112 insertions(+), 20 deletions(-) create mode 100644 vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil.go diff --git a/README.md b/README.md index 64efc1a..c05d71e 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,8 @@ You can also run this step directly with [Bitrise CLI](https://github.com/bitris | `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 512M` | | `start_command_flags` | Flags used when running the command to start the emulator. | | `-camera-back none -camera-front none` | -| `emulator_channel` | Select which channel to use with `sdkmanager` to fetch `emulator` package. Available channels are 0 (Stable), 1 (Beta), 2 (Dev), and 3 (Canary). | required | `0` | +| `emulator_channel` | Select which channel to use with `sdkmanager` to fetch *emulator* package. Available options are no update, or channels 0 (Stable), 1 (Beta), 2 (Dev), and 3 (Canary). - `no update`: The *emulator* preinstalled on the Stack will be used. *system-image* will be updated to the latest Stable version. To update *emulator* and *system image* to the latest available in a given channel: - `0`: Stable channel - `1`: Beta channel - `2`: Dev channel - `3`: Canary channel | required | `no update` | +| `headless_mode` | In headless mode the emulator is not launched in the foreground. If this input is set, the emulator will not be visible but tests (even the screenshots) will run just like if the emulator ran in the foreground. | required | `yes` |
diff --git a/e2e/bitrise.yml b/e2e/bitrise.yml index e073659..3bd7fe0 100644 --- a/e2e/bitrise.yml +++ b/e2e/bitrise.yml @@ -59,6 +59,8 @@ workflows: - content: | #!/bin/bash set -ex + + echo "BITRISE_EMULATOR_SERIAL: $BITRISE_EMULATOR_SERIAL" if [ "$BITRISE_EMULATOR_SERIAL" = "emulator-5554" ] then exit 0 @@ -78,8 +80,9 @@ workflows: #!/bin/bash set -euxo pipefail sleep 15 - $ANDROID_HOME/platform-tools/adb shell "screencap -p /sdcard/screen.png" - $ANDROID_HOME/platform-tools/adb pull "/sdcard/screen.png" "./screen_$EMU_VER.png" + cd $BITRISE_DEPLOY_DIR + $ANDROID_HOME/platform-tools/adb -s $BITRISE_EMULATOR_SERIAL shell "screencap -p /sdcard/screen.png" + $ANDROID_HOME/platform-tools/adb -s $BITRISE_EMULATOR_SERIAL pull "/sdcard/screen.png" "./screen_$EMU_VER.png" _kill-emulator: steps: diff --git a/main.go b/main.go index 3e90ee3..934cfb0 100755 --- a/main.go +++ b/main.go @@ -15,6 +15,7 @@ import ( "github.com/bitrise-io/go-steputils/tools" "github.com/bitrise-io/go-utils/command" "github.com/bitrise-io/go-utils/log" + "github.com/bitrise-io/go-utils/sliceutil" "github.com/bitrise-io/go-utils/v2/system" "github.com/kballard/go-shellquote" ) @@ -30,7 +31,8 @@ type config struct { StartCommandArgs string `env:"start_command_flags"` ID string `env:"emulator_id,required"` Abi string `env:"abi,opt[x86,armeabi-v7a,arm64-v8a,x86_64]"` - EmulatorChannel string `env:"emulator_channel,opt[0,1,2,3]"` + EmulatorChannel string `env:"emulator_channel,opt[no update,0,1,2,3]"` + IsHeadlessMode bool `env:"headless_mode,opt[yes,no]"` } var ( @@ -41,6 +43,7 @@ const ( bootTimeout = time.Duration(10) * time.Minute deviceCheckInterval = time.Duration(5) * time.Second maxBootAttempts = 5 + noUpdate = "no update" ) func runningDeviceInfos(androidHome string) (map[string]string, error) { @@ -178,19 +181,27 @@ func main() { failf("Failed to parse start command args, error: %s", err) } - for _, phase := range []phase{ - { - "Updating emulator", - command.New(sdkManagerPath, "--verbose", "--channel="+cfg.EmulatorChannel, "emulator"). - SetStdin(strings.NewReader(yes)), // hitting yes in case it waits for accepting license - }, + var ( + systemImageChannel = "0" + phases []phase + ) + if cfg.EmulatorChannel != noUpdate { + systemImageChannel = cfg.EmulatorChannel + phases = []phase{ + { + "Updating emulator", + command.New(sdkManagerPath, "--verbose", "--channel="+cfg.EmulatorChannel, "emulator"). + SetStdin(strings.NewReader(yes)), // hitting yes in case it waits for accepting license + }, + } + } + phases = append(phases, []phase{ { "Updating system-image packages", - command.New(sdkManagerPath, "--verbose", "--channel="+cfg.EmulatorChannel, pkg). + command.New(sdkManagerPath, "--verbose", "--channel="+systemImageChannel, pkg). SetStdin(strings.NewReader(yes)), // hitting yes in case it waits for accepting license }, - { "Creating device", command.New(avdManagerPath, append([]string{ @@ -202,7 +213,9 @@ func main() { "--abi", cfg.Abi}, createCustomFlags...)...). SetStdin(strings.NewReader(no)), // hitting no in case it asks for creating hw profile }, - } { + }...) + + for _, phase := range phases { log.Infof(phase.name) log.Donef("$ %s", phase.command.PrintableCommandArgs()) @@ -213,17 +226,22 @@ func main() { fmt.Println() } - args := append([]string{ + args := []string{ "@" + cfg.ID, "-verbose", "-show-kernel", "-no-audio", - "-no-window", - "-no-boot-anim", "-netdelay", "none", "-no-snapshot", "-wipe-data", - "-gpu", "auto"}, startCustomFlags...) + } + if !sliceutil.IsStringInSlice("-gpu", startCustomFlags) { + args = append(args, []string{"-gpu", "auto"}...) + } + if cfg.IsHeadlessMode { + args = append(args, []string{"-no-window", "-no-boot-anim"}...) + } + args = append(args, startCustomFlags...) serial := startEmulator(emulatorPath, args, androidHome, runningDevices, 1) diff --git a/step.yml b/step.yml index b222bb0..4eb2e46 100755 --- a/step.yml +++ b/step.yml @@ -107,19 +107,42 @@ inputs: summary: Flags used when running the command to start the emulator. description: Flags used when running the command to start the emulator. is_required: false -- emulator_channel: "0" +- emulator_channel: no update opts: category: Debug title: Emulator channel - summary: Select which channel to use with `sdkmanager` to fetch `emulator` package. Available channels are 0 (Stable), 1 (Beta), 2 (Dev), and 3 (Canary). - description: Select which channel to use with `sdkmanager` to fetch `emulator` package. Available channels are 0 (Stable), 1 (Beta), 2 (Dev), and 3 (Canary). + summary: Select which channel to use with `sdkmanager` to fetch *emulator* package. Available options are no update, or channels 0 (Stable), 1 (Beta), 2 (Dev), and 3 (Canary). + description: |- + Select which channel to use with `sdkmanager` to fetch *emulator* package. Available options are no update, or channels 0 (Stable), 1 (Beta), 2 (Dev), and 3 (Canary). + + - `no update`: The *emulator* preinstalled on the Stack will be used. *system-image* will be updated to the latest Stable version. + + To update *emulator* and *system image* to the latest available in a given channel: + - `0`: Stable channel + - `1`: Beta channel + - `2`: Dev channel + - `3`: Canary channel is_expand: true is_required: true value_options: + - no update - "0" - "1" - "2" - "3" +- headless_mode: "yes" + opts: + category: Debug + title: Run the emulator in headless mode + summary: In headless mode the emulator is not launched in the foreground. + description: |- + In headless mode the emulator is not launched in the foreground. + + If this input is set, the emulator will not be visible but tests (even the screenshots) will run just like if the emulator ran in the foreground. + is_required: true + value_options: + - "yes" + - "no" outputs: - BITRISE_EMULATOR_SERIAL: diff --git a/vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil.go b/vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil.go new file mode 100644 index 0000000..94b1a2c --- /dev/null +++ b/vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil.go @@ -0,0 +1,46 @@ +package sliceutil + +import "strings" + +// UniqueStringSlice - returns a cleaned up list, +// where every item is unique. +// Does NOT guarantee any ordering, the result can +// be in any order! +func UniqueStringSlice(strs []string) []string { + lookupMap := map[string]interface{}{} + for _, aStr := range strs { + lookupMap[aStr] = 1 + } + uniqueStrs := []string{} + for k := range lookupMap { + uniqueStrs = append(uniqueStrs, k) + } + return uniqueStrs +} + +// IndexOfStringInSlice ... +func IndexOfStringInSlice(searchFor string, searchIn []string) int { + for idx, anItm := range searchIn { + if anItm == searchFor { + return idx + } + } + return -1 +} + +// IsStringInSlice ... +func IsStringInSlice(searchFor string, searchIn []string) bool { + return IndexOfStringInSlice(searchFor, searchIn) >= 0 +} + +// CleanWhitespace removes leading and trailing white space from each element of the input slice. +// Elements that end up as empty strings are excluded from the result depending on the value of the omitEmpty flag. +func CleanWhitespace(list []string, omitEmpty bool) (items []string) { + for _, e := range list { + e = strings.TrimSpace(e) + if !omitEmpty || len(e) > 0 { + items = append(items, e) + } + } + return +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 0e8a347..9167a5f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -13,6 +13,7 @@ github.com/bitrise-io/go-utils/log github.com/bitrise-io/go-utils/parseutil github.com/bitrise-io/go-utils/pathutil github.com/bitrise-io/go-utils/pointers +github.com/bitrise-io/go-utils/sliceutil # github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.8 ## explicit github.com/bitrise-io/go-utils/v2/system