in e2e_tests/compute/instance.go [108:170]
func (i *Instance) WaitForSerialOutput(positiveRegexes []*regexp.Regexp, negativeRegexes []*regexp.Regexp, port int64, interval, timeout time.Duration) error {
var start int64
var errs int
matches := make([]bool, len(positiveRegexes))
tick := time.Tick(interval)
timedout := time.After(timeout)
for {
select {
case <-timedout:
var patterns []string
for _, regex := range positiveRegexes {
patterns = append(patterns, regex.String())
}
return fmt.Errorf("timed out waiting for regexes [%s]", strings.Join(patterns, ","))
case <-tick:
resp, err := i.client.GetSerialPortOutput(i.Project, i.Zone, i.Name, port, start)
if err != nil {
status, sErr := i.client.InstanceStatus(i.Project, i.Zone, i.Name)
if sErr != nil {
err = fmt.Errorf("%v, error getting InstanceStatus: %v", err, sErr)
} else {
err = fmt.Errorf("%v, InstanceStatus: %q", err, status)
}
// Wait until machine restarts to evaluate SerialOutput.
if isTerminal(status) {
continue
}
// Retry up to 3 times in a row on any error if we successfully got InstanceStatus.
if errs < 3 {
errs++
continue
}
return err
}
start = resp.Next
for _, ln := range strings.Split(resp.Contents, "\n") {
for _, regex := range negativeRegexes {
if regex.MatchString(ln) {
return fmt.Errorf("matched negative regexes [%s]", regex)
}
}
for i, regex := range positiveRegexes {
if regex.MatchString(ln) {
matches[i] = true
}
}
matched := 0
for _, match := range matches {
if match {
matched++
}
}
if matched == len(positiveRegexes) {
return nil
}
}
errs = 0
}
}
}