Skip to content

Commit

Permalink
Increase boot timeout, better error messages (#40)
Browse files Browse the repository at this point in the history
* Increase boot timeout, better error messages

* Cleanup
  • Loading branch information
ofalvai authored Jul 7, 2022
1 parent a403826 commit e7f4b61
Showing 1 changed file with 31 additions and 15 deletions.
46 changes: 31 additions & 15 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@ var (
)

const (
maxAttempts = 5
bootTimeout = time.Duration(10) * time.Minute
deviceCheckInterval = time.Duration(5) * time.Second
maxBootAttempts = 5
)

func runningDeviceInfos(androidHome string) (map[string]string, error) {
cmd := command.New(filepath.Join(androidHome, "platform-tools", "adb"), "devices")
out, err := cmd.RunAndReturnTrimmedCombinedOutput()
if err != nil {
log.Printf(err.Error())
return map[string]string{}, fmt.Errorf("command failed, error: %s", err)
}

Expand Down Expand Up @@ -229,32 +232,45 @@ func startEmulator(emulatorPath string, args []string, androidHome string, runni

log.Infof("Starting device")
log.Donef("$ %s", deviceStartCmd.PrintableCommandArgs())
// start the emlator as a detached process
emulatorWaitCh := make(chan error, 1)

// The emulator command won't exit after the boot completes, so we start the command and not wait for its result.
// Instead, we have a loop with 3 channels:
// 1. One that waits for the emulator process to exit
// 2. A boot timeout timer
// 3. A ticker that periodically checks if the device has become online
if err := deviceStartCmd.GetCmd().Start(); err != nil {
failf("Failed to run device start command: %v", err)
}

emulatorWaitCh := make(chan error, 1)
go func() {
emulatorWaitCh <- deviceStartCmd.GetCmd().Wait()
}()

timeoutTimer := time.NewTimer(bootTimeout)

deviceCheckTicker := time.NewTicker(deviceCheckInterval)

var serial string
const bootWaitTime = time.Duration(300)
timeout := time.NewTimer(bootWaitTime * time.Second)
deviceCheckTicker := time.NewTicker(5 * time.Second)
retry := false
waitLoop:
for {
select {
case err := <-emulatorWaitCh:
log.Warnf("Emulator log: %s", output)
log.Warnf("Emulator process exited early")
if err != nil {
failf("Emulator exited unexpectedly: %v", err)
log.Errorf("Emulator exit reason: %v", err)
} else {
log.Warnf("A possible cause can be the emulator process having received a KILL signal.")
}
failf("Emulator exited early, without error. A possible cause can be the emulator process having received a KILL signal.")
case <-timeout.C:
log.Warnf("Emulator log: %s", output)
failf("Failed to boot emulator device within %d seconds.", bootWaitTime)
log.Printf("Emulator log: %s", output)
failf("Emulator exited early, see logs above.")
case <-timeoutTimer.C:
// Include error before and after printing the emulator log because it's so long
errorMsg := fmt.Sprintf("Failed to boot emulator device within %d seconds.", bootTimeout/time.Second)
log.Errorf(errorMsg)
log.Printf("Emulator log: %s", output)
failf(errorMsg)
case <-deviceCheckTicker.C:
var err error
serial, err = queryNewDeviceSerial(androidHome, runningDevices)
Expand All @@ -269,17 +285,17 @@ waitLoop:
if err := deviceStartCmd.GetCmd().Process.Kill(); err != nil {
failf("Couldn't finish emulator process: %v", err)
}
if attempt < maxAttempts {
if attempt < maxBootAttempts {
log.Warnf("Trying to start emulator process again...")
retry = true
break waitLoop
} else {
failf("Failed to boot device due to faults after %d tries", maxAttempts)
failf("Failed to boot device due to faults after %d tries", maxBootAttempts)
}
}
}
}
timeout.Stop()
timeoutTimer.Stop()
deviceCheckTicker.Stop()
if retry {
return startEmulator(emulatorPath, args, androidHome, runningDevices, attempt+1)
Expand Down

0 comments on commit e7f4b61

Please sign in to comment.