forked from redhat-developer/odo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helper_generic.go
179 lines (159 loc) · 4.75 KB
/
helper_generic.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package helper
import (
"bytes"
"encoding/json"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
"github.com/openshift/odo/pkg/util"
)
// RandString returns a random string of given length
func RandString(n int) string {
return util.GenerateRandomString(n)
}
// WaitForCmdOut runs a command until it gets
// the expected output.
// It accepts 5 arguments, program (program to be run)
// args (arguments to the program)
// timeout (the time to wait for the output)
// errOnFail (flag to set if test should fail if command fails)
// check (function with output check logic)
// It times out if the command doesn't fetch the
// expected output within the timeout period.
func WaitForCmdOut(program string, args []string, timeout int, errOnFail bool, check func(output string) bool, includeStdErr ...bool) bool {
pingTimeout := time.After(time.Duration(timeout) * time.Minute)
// this is a test package so time.Tick() is acceptable
// nolint
tick := time.Tick(time.Second)
for {
select {
case <-pingTimeout:
Fail(fmt.Sprintf("Timeout out after %v minutes", timeout))
case <-tick:
session := CmdRunner(program, args...)
if errOnFail {
Eventually(session).Should(gexec.Exit(0), runningCmd(session.Command))
} else {
Eventually(session).Should(gexec.Exit(), runningCmd(session.Command))
}
session.Wait()
output := string(session.Out.Contents())
if len(includeStdErr) > 0 && includeStdErr[0] {
output += "\n"
output += string(session.Err.Contents())
}
if check(strings.TrimSpace(string(output))) {
return true
}
}
}
}
// MatchAllInOutput ensures all strings are in output
func MatchAllInOutput(output string, tomatch []string) {
for _, i := range tomatch {
Expect(output).To(ContainSubstring(i))
}
}
// DontMatchAllInOutput ensures all strings are not in output
func DontMatchAllInOutput(output string, tonotmatch []string) {
for _, i := range tonotmatch {
Expect(output).ToNot(ContainSubstring(i))
}
}
// Unindented returns the unindented version of the jsonStr passed to it
func Unindented(jsonStr string) (string, error) {
var tmpMap map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &tmpMap)
if err != nil {
return "", err
}
obj, err := json.Marshal(tmpMap)
if err != nil {
return "", err
}
return string(obj), err
}
// ExtractSubString extracts substring from output, beginning at start and before end
func ExtractSubString(output, start, end string) string {
i := strings.Index(output, start)
if i >= 0 {
j := strings.Index(output[i:], end)
if j >= 0 {
return output[i : i+j]
}
}
return ""
}
// WatchNonRetCmdStdOut run odo watch and get the cmdSTDOUT output into buffer.
// startIndicatorFunc sets true and startSimulationCh starts, when buffer contain "Waiting for something to change"
// check function checks for the changes into the buffer
func WatchNonRetCmdStdOut(cmdStr string, timeout time.Duration, check func(output string) bool, startSimulationCh chan bool, startIndicatorFunc func(output string) bool) (bool, error) {
var cmd *exec.Cmd
var buf bytes.Buffer
cmdStrParts := strings.Split(cmdStr, " ")
cmdName := cmdStrParts[0]
fmt.Println("Running command: ", cmdStrParts)
if len(cmdStrParts) > 1 {
cmdStrParts = cmdStrParts[1:]
cmd = exec.Command(cmdName, cmdStrParts...)
} else {
cmd = exec.Command(cmdName)
}
cmd.Stdout = &buf
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
timeoutCh := make(chan bool)
go func() {
time.Sleep(timeout)
timeoutCh <- true
}()
if err := cmd.Start(); err != nil {
return false, err
}
startedFileModification := false
for {
select {
case <-timeoutCh:
Fail("Timeout out after " + string(timeout) + " minutes")
case <-ticker.C:
if !startedFileModification && startIndicatorFunc(buf.String()) {
startedFileModification = true
startSimulationCh <- true
}
if check(buf.String()) {
if err := cmd.Process.Kill(); err != nil {
return true, err
}
return true, nil
}
}
}
}
// GetUserHomeDir gets the user home directory
func GetUserHomeDir() string {
homeDir, err := os.UserHomeDir()
Expect(err).NotTo(HaveOccurred())
return homeDir
}
// LocalKubeconfigSet sets the KUBECONFIG to the temporary config file
func LocalKubeconfigSet(context string) {
originalKubeCfg := os.Getenv("KUBECONFIG")
if originalKubeCfg == "" {
homeDir := GetUserHomeDir()
originalKubeCfg = filepath.Join(homeDir, ".kube", "config")
}
copyKubeConfigFile(originalKubeCfg, filepath.Join(context, "config"))
}
// GetCliRunner gets the running cli against Kubernetes or OpenShift
func GetCliRunner() CliRunner {
if os.Getenv("KUBERNETES") == "true" {
return NewKubectlRunner("kubectl")
}
return NewOcRunner("oc")
}