From 1aa0fcff465a7eb92836bdf343222cb34e9c6d33 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Mon, 25 Feb 2019 10:52:42 +0100 Subject: [PATCH] misc/android: serialize adb commands on android emulators Android emulator builders are soon to join the trybot set. To avoid flaky runs, work around a longstanding adb bug where concurrent adb commands sometimes fail. I haven't seen the problem on actual devices until recently. It seems that the recently added "adb wait-for-device" can introduce flakyness with errors such as: adb: error: failed to get feature set: protocol fault (couldn't read status): Connection reset by peer Instead of working around that, give up and serialize use of adb everywhere. Fixes #23795 Updates #23824 Change-Id: If347c9981fa32ff8a1e14b7454f122ef682450a6 Reviewed-on: https://go-review.googlesource.com/c/163625 Reviewed-by: Brad Fitzpatrick --- misc/android/go_android_exec.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/misc/android/go_android_exec.go b/misc/android/go_android_exec.go index 1a8ae7070e..0055fb832a 100644 --- a/misc/android/go_android_exec.go +++ b/misc/android/go_android_exec.go @@ -60,6 +60,19 @@ func main() { log.SetFlags(0) log.SetPrefix("go_android_exec: ") + // Concurrent use of adb is flaky, so serialize adb commands. + // See https://github.com/golang/go/issues/23795 or + // https://issuetracker.google.com/issues/73230216. + lockPath := filepath.Join(os.TempDir(), "go_android_exec-adb-lock") + lock, err := os.OpenFile(lockPath, os.O_CREATE|os.O_RDWR, 0666) + if err != nil { + log.Fatal(err) + } + defer lock.Close() + if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX); err != nil { + log.Fatal(err) + } + // In case we're booting a device or emulator alongside androidtest.bash // wait for it to be ready. adb wait-for-device is not enough, we have to // wait for sys.boot_completed. @@ -87,15 +100,7 @@ func main() { // E.g. template.test from the {html,text}/template packages. binName := fmt.Sprintf("%s-%d", filepath.Base(os.Args[1]), os.Getpid()) deviceBin := fmt.Sprintf("%s/%s", deviceGotmp, binName) - - // The push of the binary happens in parallel with other tests. - // Unfortunately, a simultaneous call to adb shell hold open - // file descriptors, so it is necessary to push then move to - // avoid a "text file busy" error on execution. - // https://code.google.com/p/android/issues/detail?id=65857 - run("push", os.Args[1], deviceBin+"-tmp") - run("shell", "cp '"+deviceBin+"-tmp' '"+deviceBin+"'") - run("shell", "rm '"+deviceBin+"-tmp'") + run("push", os.Args[1], deviceBin) // Forward SIGQUIT from the go command to show backtraces from // the binary instead of from this wrapper.