Honor exit codes in run_android_tests.go. adb kindly doesn't forward exit codes until N (https://code.google.com/p/android/issues/detail?id=3254), so we need to work around it. Otherwise all our test failures have been silently ignored (oops!). Change-Id: I03440db7dd77e6b9af5445b309b67dc719cea054 Reviewed-on: https://boringssl-review.googlesource.com/8190 Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/util/run_android_tests.go b/util/run_android_tests.go index fc94d33..6502a16 100644 --- a/util/run_android_tests.go +++ b/util/run_android_tests.go
@@ -15,6 +15,7 @@ package main import ( + "bytes" "encoding/json" "flag" "fmt" @@ -23,6 +24,7 @@ "os" "os/exec" "path/filepath" + "strconv" "strings" ) @@ -56,6 +58,55 @@ return cmd.Run() } +func adbShell(shellCmd string) (int, error) { + var args []string + if len(*device) > 0 { + args = append([]string{"-s", *device}, args...) + } + args = append(args, "shell") + + const delimiter = "___EXIT_CODE___" + + // Older versions of adb and Android do not preserve the exit + // code, so work around this. + // https://code.google.com/p/android/issues/detail?id=3254 + shellCmd += "; echo " + delimiter + " $?" + args = append(args, shellCmd) + + cmd := exec.Command(*adbPath, args...) + stdout, err := cmd.StdoutPipe() + if err != nil { + return 0, err + } + cmd.Stderr = os.Stderr + if err := cmd.Start(); err != nil { + return 0, err + } + + var stdoutBytes bytes.Buffer + for { + var buf [1024]byte + n, err := stdout.Read(buf[:]) + stdoutBytes.Write(buf[:n]) + os.Stdout.Write(buf[:n]) + if err != nil { + break + } + } + + if err := cmd.Wait(); err != nil { + return 0, err + } + + stdoutStr := stdoutBytes.String() + idx := strings.LastIndex(stdoutStr, delimiter) + if idx < 0 { + return 0, fmt.Errorf("Could not find delimiter in output.") + } + + return strconv.Atoi(strings.TrimSpace(stdoutStr[idx+len(delimiter):])) +} + func goTool(args ...string) error { cmd := exec.Command("go", args...) cmd.Stdout = os.Stdout @@ -227,17 +278,21 @@ os.Exit(1) } + var unitTestExit int if enableUnitTests() { fmt.Printf("Running unit tests...\n") - if err := adb("shell", fmt.Sprintf("cd /data/local/tmp/boringssl-tmp && ./util/all_tests -json-output results.json %s", *allTestsArgs)); err != nil { + unitTestExit, err = adbShell(fmt.Sprintf("cd /data/local/tmp/boringssl-tmp && ./util/all_tests -json-output results.json %s", *allTestsArgs)) + if err != nil { fmt.Printf("Failed to run unit tests: %s\n", err) os.Exit(1) } } + var sslTestExit int if enableSSLTests() { fmt.Printf("Running SSL tests...\n") - if err := adb("shell", fmt.Sprintf("cd /data/local/tmp/boringssl-tmp/ssl/test/runner && ./runner -json-output ../../../results.json %s", *runnerArgs)); err != nil { + sslTestExit, err = adbShell(fmt.Sprintf("cd /data/local/tmp/boringssl-tmp/ssl/test/runner && ./runner -json-output ../../../results.json %s", *runnerArgs)) + if err != nil { fmt.Printf("Failed to run SSL tests: %s\n", err) os.Exit(1) } @@ -249,4 +304,12 @@ os.Exit(1) } } + + if unitTestExit != 0 { + os.Exit(unitTestExit) + } + + if sslTestExit != 0 { + os.Exit(sslTestExit) + } }