go.etcd.io/etcd@v3.3.27+incompatible/tests/e2e/util.go (about) 1 // Copyright 2017 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package e2e 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "math/rand" 21 "strings" 22 "time" 23 24 "github.com/coreos/etcd/pkg/expect" 25 ) 26 27 func waitReadyExpectProc(exproc *expect.ExpectProcess, readyStrs []string) error { 28 c := 0 29 matchSet := func(l string) bool { 30 for _, s := range readyStrs { 31 if strings.Contains(l, s) { 32 c++ 33 break 34 } 35 } 36 return c == len(readyStrs) 37 } 38 _, err := exproc.ExpectFunc(matchSet) 39 return err 40 } 41 42 func spawnWithExpect(args []string, expected string) error { 43 return spawnWithExpects(args, []string{expected}...) 44 } 45 46 func spawnWithExpects(args []string, xs ...string) error { 47 _, err := spawnWithExpectLines(args, xs...) 48 return err 49 } 50 51 func spawnWithExpectLines(args []string, xs ...string) ([]string, error) { 52 proc, err := spawnCmd(args) 53 if err != nil { 54 return nil, err 55 } 56 // process until either stdout or stderr contains 57 // the expected string 58 var ( 59 lines []string 60 lineFunc = func(txt string) bool { return true } 61 ) 62 for _, txt := range xs { 63 for { 64 l, lerr := proc.ExpectFunc(lineFunc) 65 if lerr != nil { 66 proc.Close() 67 return nil, fmt.Errorf("%v (expected %q, got %q)", lerr, txt, lines) 68 } 69 lines = append(lines, l) 70 if strings.Contains(l, txt) { 71 break 72 } 73 } 74 } 75 perr := proc.Close() 76 if len(xs) == 0 && proc.LineCount() != noOutputLineCount { // expect no output 77 return nil, fmt.Errorf("unexpected output (got lines %q, line count %d)", lines, proc.LineCount()) 78 } 79 return lines, perr 80 } 81 82 func randomLeaseID() int64 { 83 return rand.New(rand.NewSource(time.Now().UnixNano())).Int63() 84 } 85 86 func dataMarshal(data interface{}) (d string, e error) { 87 m, err := json.Marshal(data) 88 if err != nil { 89 return "", err 90 } 91 return string(m), nil 92 } 93 94 func closeWithTimeout(p *expect.ExpectProcess, d time.Duration) error { 95 errc := make(chan error, 1) 96 go func() { errc <- p.Close() }() 97 select { 98 case err := <-errc: 99 return err 100 case <-time.After(d): 101 p.Stop() 102 // retry close after stopping to collect SIGQUIT data, if any 103 closeWithTimeout(p, time.Second) 104 } 105 return fmt.Errorf("took longer than %v to Close process %+v", d, p) 106 } 107 108 func toTLS(s string) string { 109 return strings.Replace(s, "http://", "https://", 1) 110 }