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

Unified Diff: ct/go/util/util.go

Issue 1295043002: Revert of 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ct/go/adb/adb.go ('k') | go/exec/exec.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ct/go/util/util.go
diff --git a/ct/go/util/util.go b/ct/go/util/util.go
index 6b9afb013281967fb67bba823466be8718185ffd..1a22fe57b2d2f767d0805136488ecb911c4f74c2 100644
--- a/ct/go/util/util.go
+++ b/ct/go/util/util.go
@@ -6,11 +6,12 @@
"fmt"
"io/ioutil"
"os"
+ "os/exec"
"path/filepath"
"strconv"
+ "strings"
"time"
- "go.skia.org/infra/go/exec"
"go.skia.org/infra/go/util"
"github.com/skia-dev/glog"
@@ -85,23 +86,63 @@
glog.Infof("===== %s took %s =====", name, elapsed)
}
+// WriteLog implements the io.Writer interface and writes to glog and an output
+// file (if specified).
+type WriteLog struct {
+ LogFunc func(format string, args ...interface{})
+ OutputFile *os.File
+}
+
+func (wl WriteLog) Write(p []byte) (n int, err error) {
+ wl.LogFunc("%s", string(p))
+ // Write to file if specified.
+ if wl.OutputFile != nil {
+ if n, err := wl.OutputFile.WriteString(string(p)); err != nil {
+ glog.Errorf("Could not write to %s: %s", wl.OutputFile.Name(), err)
+ return n, err
+ }
+ }
+ return len(p), nil
+}
+
// ExecuteCmd executes the specified binary with the specified args and env.
// Stdout and Stderr are written to stdoutFile and stderrFile respectively if
// specified. If not specified then stdout and stderr will be outputted only to
// glog. Note: It is the responsibility of the caller to close stdoutFile and
// stderrFile.
func ExecuteCmd(binary string, args, env []string, timeout time.Duration, stdoutFile, stderrFile *os.File) error {
- return exec.Run(&exec.Command{
- Name: binary,
- Args: args,
- Env: env,
- InheritPath: true,
- Timeout: timeout,
- LogStdout: true,
- Stdout: stdoutFile,
- LogStderr: true,
- Stderr: stderrFile,
- })
+ // Add the current PATH to the env.
+ env = append(env, "PATH="+os.Getenv("PATH"))
+
+ // Create the cmd obj.
+ cmd := exec.Command(binary, args...)
+ cmd.Env = env
+
+ // Attach WriteLog to command.
+ cmd.Stdout = WriteLog{LogFunc: glog.Infof, OutputFile: stdoutFile}
+ cmd.Stderr = WriteLog{LogFunc: glog.Errorf, OutputFile: stderrFile}
+
+ // Execute cmd.
+ glog.Infof("Executing %s %s", strings.Join(cmd.Env, " "), strings.Join(cmd.Args, " "))
+ util.LogErr(cmd.Start())
+ done := make(chan error)
+ go func() {
+ done <- cmd.Wait()
+ }()
+ select {
+ case <-time.After(timeout):
+ if err := cmd.Process.Kill(); err != nil {
+ return fmt.Errorf("Failed to kill timed out process: %s", err)
+ }
+ <-done // allow goroutine to exit
+ glog.Errorf("Command killed since it took longer than %f secs", timeout.Seconds())
+ return fmt.Errorf("Command killed since it took longer than %f secs", timeout.Seconds())
+ case err := <-done:
+ if err != nil {
+ return fmt.Errorf("Process done with error: %s", err)
+ }
+ }
+ return nil
}
// SyncDir runs "git pull" and "gclient sync" on the specified directory.
« no previous file with comments | « ct/go/adb/adb.go ('k') | go/exec/exec.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698