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 "syscall" 28) 29 30var ( 31 chdir = flag.String("p", "", "Change to a path before executing test") 32 touch = flag.String("f", "", "Write a file on success") 33) 34 35// This will copy the stdout from the test process to our stdout 36// unless it only contains "PASS\n". 37func handleStdout(stdout io.Reader) { 38 reader := bufio.NewReader(stdout) 39 40 // This is intentionally 6 instead of 5 to check for EOF 41 buf, _ := reader.Peek(6) 42 if bytes.Equal(buf, []byte("PASS\n")) { 43 return 44 } 45 46 io.Copy(os.Stdout, reader) 47} 48 49func main() { 50 flag.Parse() 51 52 if flag.NArg() == 0 { 53 fmt.Fprintln(os.Stderr, "error: must pass at least one test executable") 54 os.Exit(1) 55 } 56 57 test, err := filepath.Abs(flag.Arg(0)) 58 if err != nil { 59 fmt.Fprintf(os.Stderr, "error: Failed to locate test binary: %s", err) 60 } 61 62 cmd := exec.Command(test, flag.Args()[1:]...) 63 if *chdir != "" { 64 cmd.Dir = *chdir 65 } 66 67 cmd.Stderr = os.Stderr 68 stdout, err := cmd.StdoutPipe() 69 if err != nil { 70 fmt.Fprintln(os.Stderr, err) 71 os.Exit(1) 72 } 73 74 err = cmd.Start() 75 if err != nil { 76 fmt.Fprintln(os.Stderr, err) 77 os.Exit(1) 78 } 79 80 handleStdout(stdout) 81 82 if err = cmd.Wait(); err != nil { 83 if e, ok := err.(*exec.ExitError); ok { 84 if status, ok := e.Sys().(syscall.WaitStatus); ok && status.Exited() { 85 os.Exit(status.ExitStatus()) 86 } else if status.Signaled() { 87 fmt.Fprintf(os.Stderr, "test got signal %s\n", status.Signal()) 88 os.Exit(1) 89 } 90 } 91 fmt.Fprintln(os.Stderr, err) 92 os.Exit(1) 93 } 94 95 if *touch != "" { 96 err = ioutil.WriteFile(*touch, []byte{}, 0666) 97 if err != nil { 98 panic(err) 99 } 100 } 101 102 os.Exit(0) 103} 104