-
Notifications
You must be signed in to change notification settings - Fork 244
/
helper_run.go
101 lines (88 loc) · 2.92 KB
/
helper_run.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package helper
import (
"fmt"
"os/exec"
"path/filepath"
"runtime"
"time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
)
func runningCmd(cmd *exec.Cmd) string {
prog := filepath.Base(cmd.Path)
return fmt.Sprintf("Running %s with args %v", prog, cmd.Args)
}
func CmdRunner(program string, args ...string) *gexec.Session {
//prefix ginkgo verbose output with program name
prefix := fmt.Sprintf("[%s] ", filepath.Base(program))
prefixWriter := gexec.NewPrefixedWriter(prefix, GinkgoWriter)
command := exec.Command(program, args...)
fmt.Fprintln(GinkgoWriter, runningCmd(command))
session, err := gexec.Start(command, prefixWriter, prefixWriter)
Expect(err).NotTo(HaveOccurred())
return session
}
// CmdShouldPass returns stdout if command succeeds
func CmdShouldPass(program string, args ...string) string {
session := CmdRunner(program, args...)
Eventually(session).Should(gexec.Exit(0), runningCmd(session.Command))
return string(session.Wait().Out.Contents())
}
// CmdShouldRunWithTimeout waits for a certain duration and then returns stdout
func CmdShouldRunWithTimeout(timeout time.Duration, program string, args ...string) string {
session := CmdRunner(program, args...)
time.Sleep(timeout)
session.Terminate()
return string(session.Out.Contents())
}
// CmdShouldRunAndTerminate waits and returns stdout after a closed signal is passed on the closed channel
func CmdShouldRunAndTerminate(timeoutAfter time.Duration, stopChan <-chan bool, program string, args ...string) string {
session := CmdRunner(program, args...)
timeout := time.After(timeoutAfter)
select {
case <-stopChan:
if session != nil {
if runtime.GOOS == "windows" {
session.Kill()
} else {
session.Terminate()
}
}
case <-timeout:
if session != nil {
if runtime.GOOS == "windows" {
session.Kill()
} else {
session.Terminate()
}
}
}
if session == nil {
return ""
}
return string(session.Out.Contents())
}
// CmdShouldFail returns stderr if command fails
func CmdShouldFail(program string, args ...string) string {
session := CmdRunner(program, args...)
Consistently(session).ShouldNot(gexec.Exit(0), runningCmd(session.Command))
return string(session.Wait().Err.Contents())
}
// CmdShouldFailWithRetry runs a command and checks if it fails, if it doesn't then it retries
func CmdShouldFailWithRetry(maxRetry, intervalSeconds int, program string, args ...string) string {
for i := 0; i < maxRetry; i++ {
fmt.Fprintf(GinkgoWriter, "try %d of %d\n", i, maxRetry)
session := CmdRunner(program, args...)
session.Wait()
// if exit code is 0 which means the program succeeded and hence we retry
if session.ExitCode() == 0 {
time.Sleep(time.Duration(intervalSeconds) * time.Second)
} else {
Consistently(session).ShouldNot(gexec.Exit(0), runningCmd(session.Command))
return string(session.Err.Contents())
}
}
Fail(fmt.Sprintf("Failed after %d retries", maxRetry))
return ""
}