veyron/lib/expect: add expectSetRE method as per blackbox.

Change-Id: I22ff523a218dab33e806a6989c06762b2a2ed0bc
diff --git a/lib/expect/expect.go b/lib/expect/expect.go
index 4950758..e7da3a3 100644
--- a/lib/expect/expect.go
+++ b/lib/expect/expect.go
@@ -272,6 +272,59 @@
 	return m[0][1]
 }
 
+// ExpectSetRE verifies whether the supplied set of regular expression
+// parameters matches the next n (where n is the number of parameters)
+// lines of input. Each line is read and matched against the supplied
+// patterns in the order that they are supplied as parameters. Consequently
+// the set may contain repetitions if the same pattern is expected multiple
+// times.
+func (s *Session) ExpectSetRE(expected ...string) {
+	if s.Failed() {
+		return
+	}
+	regexps := make([]*regexp.Regexp, len(expected))
+	for i, expRE := range expected {
+		re, err := regexp.Compile(expRE)
+		if err != nil {
+			s.error(err)
+			return
+		}
+		regexps[i] = re
+	}
+	actual := make([]string, len(expected))
+	for i := 0; i < len(expected); i++ {
+		line, err := s.read(readLine)
+		line = strings.TrimRight(line, "\n")
+		s.log(err, "ExpectSetRE: %s", line)
+		if err != nil {
+			s.error(err)
+			return
+		}
+		actual[i] = line
+	}
+	// Match each line against all regexp's and remove each regexp
+	// that matches.
+	for _, l := range actual {
+		found := false
+		for i, re := range regexps {
+			if re == nil {
+				continue
+			}
+			if re.MatchString(l) {
+				// We remove each RE that matches.
+				found = true
+				regexps[i] = nil
+				break
+			}
+		}
+		if !found {
+			s.error(fmt.Errorf("found no match for %q", l))
+			return
+		}
+	}
+
+}
+
 // ReadLine reads the next line, if any, from the input stream. It will set
 // the error state to io.EOF if it has read past the end of the stream.
 // ReadLine has no effect if an error has already occurred.
diff --git a/lib/expect/expect_test.go b/lib/expect/expect_test.go
index c85d803..8fa62da 100644
--- a/lib/expect/expect_test.go
+++ b/lib/expect/expect_test.go
@@ -87,6 +87,27 @@
 	s.ExpectEOF()
 }
 
+func TestExpectSetRE(t *testing.T) {
+	buf := []byte{}
+	buffer := bytes.NewBuffer(buf)
+	buffer.WriteString("bar=baz\n")
+	buffer.WriteString("abc\n")
+	buffer.WriteString("def\n")
+	buffer.WriteString("abc\n")
+	s := expect.NewSession(nil, bufio.NewReader(buffer), time.Minute)
+	s.ExpectSetRE("^bar=.*$", "def$", "^abc$", "^a..$")
+	if s.Error() != nil {
+		t.Errorf("unexpected error: %s", s.Error())
+	}
+	buffer.WriteString("ooh\n")
+	buffer.WriteString("aah\n")
+	s.ExpectSetRE("bar=.*", "def")
+	if got, want := s.Error(), "expect_test.go:104: found no match for \"ooh\""; got == nil || got.Error() != want {
+		t.Errorf("got %v, want %q", got, want)
+	}
+	s.ExpectEOF()
+}
+
 func TestRead(t *testing.T) {
 	buf := []byte{}
 	buffer := bytes.NewBuffer(buf)