Skip to content

Commit

Permalink
Remove race condition from bdns_test.go (letsencrypt#1906)
Browse files Browse the repository at this point in the history
This PR, makes testing the bdns package more reliable. A race condition in TestMain was resulting in the test running before the test dns server had started. This is fixed by actively polling for the DNS server to be ready before starting the test suite.

Furthermore, a 1 millisecond server read/write timeout was proving to time out on occasion. This is fixed increasing to a 1 second read/write timeout to increase test reliability. 

FYI: ran package bdns tests 1000 times with 22 failures previously, after this PR ran 1000 times with 0 failures.

fixes letsencrypt#1317
  • Loading branch information
benileo authored and cpu committed Jun 8, 2016
1 parent e804c18 commit 51425ca
Showing 1 changed file with 24 additions and 7 deletions.
31 changes: 24 additions & 7 deletions bdns/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,10 @@ func mockDNSQuery(w dns.ResponseWriter, r *dns.Msg) {
return
}

func serveLoopResolver(stopChan chan bool) chan bool {
func serveLoopResolver(stopChan chan bool) {
dns.HandleFunc(".", mockDNSQuery)
server := &dns.Server{Addr: dnsLoopbackAddr, Net: "tcp", ReadTimeout: time.Millisecond, WriteTimeout: time.Millisecond}
waitChan := make(chan bool, 1)
server := &dns.Server{Addr: dnsLoopbackAddr, Net: "tcp", ReadTimeout: time.Second, WriteTimeout: time.Second}
go func() {
waitChan <- true
err := server.ListenAndServe()
if err != nil {
fmt.Println(err)
Expand All @@ -190,13 +188,32 @@ func serveLoopResolver(stopChan chan bool) chan bool {
fmt.Println(err)
}
}()
return waitChan
}

func pollServer() {
backoff := time.Duration(200 * time.Millisecond)
ctx, _ := context.WithTimeout(context.Background(), time.Duration(5*time.Second))
ticker := time.NewTicker(backoff)

for {
select {
case <-ctx.Done():
fmt.Fprintln(os.Stderr, "Timeout reached while testing for the dns server to come up")
os.Exit(1)
case <-ticker.C:
conn, _ := dns.DialTimeout("tcp", dnsLoopbackAddr, backoff)
if conn != nil {
_ = conn.Close()
return
}
}
}
}

func TestMain(m *testing.M) {
stop := make(chan bool, 1)
wait := serveLoopResolver(stop)
<-wait
serveLoopResolver(stop)
pollServer()
ret := m.Run()
stop <- true
os.Exit(ret)
Expand Down

0 comments on commit 51425ca

Please sign in to comment.