Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: ct/go/util/util.go

Issue 1290913004: Add a library for running external commands, providing timeouts and test injection. (Closed) Base URL: https://skia.googlesource.com/buildbot@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Utility that contains methods for both CT master and worker scripts. 1 // Utility that contains methods for both CT master and worker scripts.
2 package util 2 package util
3 3
4 import ( 4 import (
5 "bufio" 5 "bufio"
6 "fmt" 6 "fmt"
7 "io/ioutil" 7 "io/ioutil"
8 "os" 8 "os"
9 "os/exec"
10 "path/filepath" 9 "path/filepath"
11 "strconv" 10 "strconv"
12 "strings"
13 "time" 11 "time"
14 12
13 "go.skia.org/infra/go/exec"
15 "go.skia.org/infra/go/util" 14 "go.skia.org/infra/go/util"
16 15
17 "github.com/skia-dev/glog" 16 "github.com/skia-dev/glog"
18 ) 17 )
19 18
20 const ( 19 const (
21 MAX_SYNC_TRIES = 3 20 MAX_SYNC_TRIES = 3
22 ) 21 )
23 22
24 // GetCTWorkers returns an array of all CT workers. 23 // GetCTWorkers returns an array of all CT workers.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 if err := os.Remove(taskFilePath); err != nil { 78 if err := os.Remove(taskFilePath); err != nil {
80 glog.Errorf("Could not delete %s: %s", taskFilePath, err) 79 glog.Errorf("Could not delete %s: %s", taskFilePath, err)
81 } 80 }
82 } 81 }
83 82
84 func TimeTrack(start time.Time, name string) { 83 func TimeTrack(start time.Time, name string) {
85 elapsed := time.Since(start) 84 elapsed := time.Since(start)
86 glog.Infof("===== %s took %s =====", name, elapsed) 85 glog.Infof("===== %s took %s =====", name, elapsed)
87 } 86 }
88 87
89 // WriteLog implements the io.Writer interface and writes to glog and an output
90 // file (if specified).
91 type WriteLog struct {
92 LogFunc func(format string, args ...interface{})
93 OutputFile *os.File
94 }
95
96 func (wl WriteLog) Write(p []byte) (n int, err error) {
97 wl.LogFunc("%s", string(p))
98 // Write to file if specified.
99 if wl.OutputFile != nil {
100 if n, err := wl.OutputFile.WriteString(string(p)); err != nil {
101 glog.Errorf("Could not write to %s: %s", wl.OutputFile.N ame(), err)
102 return n, err
103 }
104 }
105 return len(p), nil
106 }
107
108 // ExecuteCmd executes the specified binary with the specified args and env. 88 // ExecuteCmd executes the specified binary with the specified args and env.
109 // Stdout and Stderr are written to stdoutFile and stderrFile respectively if 89 // Stdout and Stderr are written to stdoutFile and stderrFile respectively if
110 // specified. If not specified then stdout and stderr will be outputted only to 90 // specified. If not specified then stdout and stderr will be outputted only to
111 // glog. Note: It is the responsibility of the caller to close stdoutFile and 91 // glog. Note: It is the responsibility of the caller to close stdoutFile and
112 // stderrFile. 92 // stderrFile.
113 func ExecuteCmd(binary string, args, env []string, timeout time.Duration, stdout File, stderrFile *os.File) error { 93 func ExecuteCmd(binary string, args, env []string, timeout time.Duration, stdout File, stderrFile *os.File) error {
114 » // Add the current PATH to the env. 94 » return exec.Run(&exec.Command{
115 » env = append(env, "PATH="+os.Getenv("PATH")) 95 » » Name: binary,
116 96 » » Args: args,
117 » // Create the cmd obj. 97 » » Env: env,
118 » cmd := exec.Command(binary, args...) 98 » » InheritPath: true,
119 » cmd.Env = env 99 » » Timeout: timeout,
120 100 » » LogStdout: true,
121 » // Attach WriteLog to command. 101 » » Stdout: stdoutFile,
122 » cmd.Stdout = WriteLog{LogFunc: glog.Infof, OutputFile: stdoutFile} 102 » » LogStderr: true,
123 » cmd.Stderr = WriteLog{LogFunc: glog.Errorf, OutputFile: stderrFile} 103 » » Stderr: stderrFile,
124 104 » })
125 » // Execute cmd.
126 » glog.Infof("Executing %s %s", strings.Join(cmd.Env, " "), strings.Join(c md.Args, " "))
127 » util.LogErr(cmd.Start())
128 » done := make(chan error)
129 » go func() {
130 » » done <- cmd.Wait()
131 » }()
132 » select {
133 » case <-time.After(timeout):
134 » » if err := cmd.Process.Kill(); err != nil {
135 » » » return fmt.Errorf("Failed to kill timed out process: %s" , err)
136 » » }
137 » » <-done // allow goroutine to exit
138 » » glog.Errorf("Command killed since it took longer than %f secs", timeout.Seconds())
139 » » return fmt.Errorf("Command killed since it took longer than %f s ecs", timeout.Seconds())
140 » case err := <-done:
141 » » if err != nil {
142 » » » return fmt.Errorf("Process done with error: %s", err)
143 » » }
144 » }
145 » return nil
146 } 105 }
147 106
148 // SyncDir runs "git pull" and "gclient sync" on the specified directory. 107 // SyncDir runs "git pull" and "gclient sync" on the specified directory.
149 func SyncDir(dir string) error { 108 func SyncDir(dir string) error {
150 err := os.Chdir(dir) 109 err := os.Chdir(dir)
151 if err != nil { 110 if err != nil {
152 return fmt.Errorf("Could not chdir to %s: %s", dir, err) 111 return fmt.Errorf("Could not chdir to %s: %s", dir, err)
153 } 112 }
154 113
155 for i := 0; i < MAX_SYNC_TRIES; i++ { 114 for i := 0; i < MAX_SYNC_TRIES; i++ {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 } 177 }
219 178
220 // CleanTmpDir deletes all tmp files from the caller because telemetry tends to 179 // CleanTmpDir deletes all tmp files from the caller because telemetry tends to
221 // generate a lot of temporary artifacts there and they take up root disk space. 180 // generate a lot of temporary artifacts there and they take up root disk space.
222 func CleanTmpDir() { 181 func CleanTmpDir() {
223 files, _ := ioutil.ReadDir(os.TempDir()) 182 files, _ := ioutil.ReadDir(os.TempDir())
224 for _, f := range files { 183 for _, f := range files {
225 util.RemoveAll(filepath.Join(os.TempDir(), f.Name())) 184 util.RemoveAll(filepath.Join(os.TempDir(), f.Name()))
226 } 185 }
227 } 186 }
OLDNEW
« no previous file with comments | « ct/go/adb/adb.go ('k') | go/exec/exec.go » ('j') | go/exec/exec_test.go » ('J')

Powered by Google App Engine
This is Rietveld 408576698