1// Copyright 2015 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 testutil provides test utility functions. 16package testutil 17 18import ( 19 "net/url" 20 "runtime" 21 "testing" 22 "time" 23) 24 25// WaitSchedule briefly sleeps in order to invoke the go scheduler. 26// TODO: improve this when we are able to know the schedule or status of target go-routine. 27func WaitSchedule() { 28 time.Sleep(10 * time.Millisecond) 29} 30 31func MustNewURLs(t *testing.T, urls []string) []url.URL { 32 if urls == nil { 33 return nil 34 } 35 var us []url.URL 36 for _, url := range urls { 37 u := MustNewURL(t, url) 38 us = append(us, *u) 39 } 40 return us 41} 42 43func MustNewURL(t *testing.T, s string) *url.URL { 44 u, err := url.Parse(s) 45 if err != nil { 46 t.Fatalf("parse %v error: %v", s, err) 47 } 48 return u 49} 50 51// FatalStack helps to fatal the test and print out the stacks of all running goroutines. 52func FatalStack(t *testing.T, s string) { 53 stackTrace := make([]byte, 1024*1024) 54 n := runtime.Stack(stackTrace, true) 55 t.Error(string(stackTrace[:n])) 56 t.Fatalf(s) 57} 58 59// ConditionFunc returns true when a condition is met. 60type ConditionFunc func() (bool, error) 61 62// Poll calls a condition function repeatedly on a polling interval until it returns true, returns an error 63// or the timeout is reached. If the condition function returns true or an error before the timeout, Poll 64// immediately returns with the true value or the error. If the timeout is exceeded, Poll returns false. 65func Poll(interval time.Duration, timeout time.Duration, condition ConditionFunc) (bool, error) { 66 timeoutCh := time.After(timeout) 67 ticker := time.NewTicker(interval) 68 defer ticker.Stop() 69 70 for { 71 select { 72 case <-timeoutCh: 73 return false, nil 74 case <-ticker.C: 75 success, err := condition() 76 if err != nil { 77 return false, err 78 } 79 if success { 80 return true, nil 81 } 82 } 83 } 84} 85