1// Copyright 2015 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package main 16 17import ( 18 "bufio" 19 "bytes" 20 "flag" 21 "fmt" 22 "io" 23 "io/ioutil" 24 "os" 25 "os/exec" 26 "path/filepath" 27 "runtime" 28 "syscall" 29) 30 31var ( 32 chdir = flag.String("p", "", "Change to a path before executing test") 33 touch = flag.String("f", "", "Write a file on success") 34) 35 36// This will copy the stdout from the test process to our stdout 37// unless it only contains "PASS\n". 38func handleStdout(stdout io.Reader) { 39 reader := bufio.NewReader(stdout) 40 41 // This is intentionally 6 instead of 5 to check for EOF 42 buf, _ := reader.Peek(6) 43 if bytes.Equal(buf, []byte("PASS\n")) { 44 return 45 } 46 47 io.Copy(os.Stdout, reader) 48} 49 50func main() { 51 flag.Parse() 52 53 if flag.NArg() == 0 { 54 fmt.Fprintln(os.Stderr, "error: must pass at least one test executable") 55 os.Exit(1) 56 } 57 58 test, err := filepath.Abs(flag.Arg(0)) 59 if err != nil { 60 fmt.Fprintln(os.Stderr, "error: Failed to locate test binary:", err) 61 } 62 63 cmd := exec.Command(test, flag.Args()[1:]...) 64 if *chdir != "" { 65 cmd.Dir = *chdir 66 67 // GOROOT is commonly a relative path in Android, make it 68 // absolute if we're changing directories. 69 if absRoot, err := filepath.Abs(runtime.GOROOT()); err == nil { 70 os.Setenv("GOROOT", absRoot) 71 } else { 72 fmt.Fprintln(os.Stderr, "error: Failed to locate GOROOT:", err) 73 } 74 } 75 76 cmd.Stderr = os.Stderr 77 stdout, err := cmd.StdoutPipe() 78 if err != nil { 79 fmt.Fprintln(os.Stderr, err) 80 os.Exit(1) 81 } 82 83 err = cmd.Start() 84 if err != nil { 85 fmt.Fprintln(os.Stderr, err) 86 os.Exit(1) 87 } 88 89 handleStdout(stdout) 90 91 if err = cmd.Wait(); err != nil { 92 if e, ok := err.(*exec.ExitError); ok { 93 if status, ok := e.Sys().(syscall.WaitStatus); ok && status.Exited() { 94 os.Exit(status.ExitStatus()) 95 } else if status.Signaled() { 96 fmt.Fprintf(os.Stderr, "test got signal %s\n", status.Signal()) 97 os.Exit(1) 98 } 99 } 100 fmt.Fprintln(os.Stderr, err) 101 os.Exit(1) 102 } 103 104 if *touch != "" { 105 err = ioutil.WriteFile(*touch, []byte{}, 0666) 106 if err != nil { 107 panic(err) 108 } 109 } 110 111 os.Exit(0) 112} 113