github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/tests/process.go (about) 1 package tests 2 3 import ( 4 "io" 5 "io/ioutil" 6 "os" 7 "os/exec" 8 "time" 9 ) 10 11 // execution process 12 type Process struct { 13 ExecPath string 14 Args []string 15 Pid int 16 StartTime time.Time 17 EndTime time.Time 18 Cmd *exec.Cmd `json:"-"` 19 ExitState *os.ProcessState `json:"-"` 20 StdinPipe io.WriteCloser `json:"-"` 21 StdoutPipe io.ReadCloser `json:"-"` 22 StderrPipe io.ReadCloser `json:"-"` 23 } 24 25 // dir: The working directory. If "", os.Getwd() is used. 26 // name: Command name 27 // args: Args to command. (should not include name) 28 func StartProcess(dir string, name string, args []string) (*Process, error) { 29 proc, err := CreateProcess(dir, name, args) 30 if err != nil { 31 return nil, err 32 } 33 // cmd start 34 if err := proc.Cmd.Start(); err != nil { 35 return nil, err 36 } 37 proc.Pid = proc.Cmd.Process.Pid 38 39 return proc, nil 40 } 41 42 // Same as StartProcess but doesn't start the process 43 func CreateProcess(dir string, name string, args []string) (*Process, error) { 44 var cmd = exec.Command(name, args...) // is not yet started. 45 // cmd dir 46 if dir == "" { 47 pwd, err := os.Getwd() 48 if err != nil { 49 panic(err) 50 } 51 cmd.Dir = pwd 52 } else { 53 cmd.Dir = dir 54 } 55 // cmd stdin 56 stdin, err := cmd.StdinPipe() 57 if err != nil { 58 return nil, err 59 } 60 61 stdout, err := cmd.StdoutPipe() 62 if err != nil { 63 return nil, err 64 } 65 66 stderr, err := cmd.StderrPipe() 67 if err != nil { 68 return nil, err 69 } 70 71 proc := &Process{ 72 ExecPath: name, 73 Args: args, 74 StartTime: time.Now(), 75 Cmd: cmd, 76 ExitState: nil, 77 StdinPipe: stdin, 78 StdoutPipe: stdout, 79 StderrPipe: stderr, 80 } 81 return proc, nil 82 } 83 84 // stop the process 85 func (proc *Process) Stop(kill bool) error { 86 if kill { 87 // fmt.Printf("Killing process %v\n", proc.Cmd.Process) 88 return proc.Cmd.Process.Kill() 89 } 90 return proc.Cmd.Process.Signal(os.Interrupt) 91 } 92 93 // wait for the process 94 func (proc *Process) Wait() { 95 err := proc.Cmd.Wait() 96 if err != nil { 97 // fmt.Printf("Process exit: %v\n", err) 98 if exitError, ok := err.(*exec.ExitError); ok { 99 proc.ExitState = exitError.ProcessState 100 } 101 } 102 proc.ExitState = proc.Cmd.ProcessState 103 proc.EndTime = time.Now() // TODO make this goroutine-safe 104 } 105 106 // ReadAll calls ioutil.ReadAll on the StdoutPipe and StderrPipe. 107 func (proc *Process) ReadAll() (stdout []byte, stderr []byte, err error) { 108 outbz, err := ioutil.ReadAll(proc.StdoutPipe) 109 if err != nil { 110 return nil, nil, err 111 } 112 errbz, err := ioutil.ReadAll(proc.StderrPipe) 113 if err != nil { 114 return nil, nil, err 115 } 116 return outbz, errbz, nil 117 }