crypto/tls: deflake TestConnReadNonzeroAndEOF

Fixes #7683

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/83080048
This commit is contained in:
Brad Fitzpatrick 2014-04-02 14:31:57 -07:00
parent a56b0bf7e2
commit 53431b940d

View File

@ -5,6 +5,7 @@
package tls package tls
import ( import (
"fmt"
"io" "io"
"net" "net"
"strings" "strings"
@ -161,21 +162,41 @@ func TestDialTimeout(t *testing.T) {
// (non-zero, nil) when a Close (alertCloseNotify) is sitting right // (non-zero, nil) when a Close (alertCloseNotify) is sitting right
// behind the application data in the buffer. // behind the application data in the buffer.
func TestConnReadNonzeroAndEOF(t *testing.T) { func TestConnReadNonzeroAndEOF(t *testing.T) {
// This test is racy: it assumes that after a write to a
// localhost TCP connection, the peer TCP connection can
// immediately read it. Because it's racy, we skip this test
// in short mode, and then retry it several times with an
// increasing sleep in between our final write (via srv.Close
// below) and the following read.
if testing.Short() {
t.Skip("skipping in short mode")
}
var err error
for delay := time.Millisecond; delay <= 64*time.Millisecond; delay *= 2 {
if err = testConnReadNonzeroAndEOF(t, delay); err == nil {
return
}
}
t.Error(err)
}
func testConnReadNonzeroAndEOF(t *testing.T, delay time.Duration) error {
ln := newLocalListener(t) ln := newLocalListener(t)
defer ln.Close() defer ln.Close()
srvCh := make(chan *Conn, 1) srvCh := make(chan *Conn, 1)
var serr error
go func() { go func() {
sconn, err := ln.Accept() sconn, err := ln.Accept()
if err != nil { if err != nil {
t.Error(err) serr = err
srvCh <- nil srvCh <- nil
return return
} }
serverConfig := *testConfig serverConfig := *testConfig
srv := Server(sconn, &serverConfig) srv := Server(sconn, &serverConfig)
if err := srv.Handshake(); err != nil { if err := srv.Handshake(); err != nil {
t.Error("handshake: %v", err) serr = fmt.Errorf("handshake: %v", err)
srvCh <- nil srvCh <- nil
return return
} }
@ -191,7 +212,7 @@ func TestConnReadNonzeroAndEOF(t *testing.T) {
srv := <-srvCh srv := <-srvCh
if srv == nil { if srv == nil {
return return serr
} }
buf := make([]byte, 6) buf := make([]byte, 6)
@ -199,16 +220,18 @@ func TestConnReadNonzeroAndEOF(t *testing.T) {
srv.Write([]byte("foobar")) srv.Write([]byte("foobar"))
n, err := conn.Read(buf) n, err := conn.Read(buf)
if n != 6 || err != nil || string(buf) != "foobar" { if n != 6 || err != nil || string(buf) != "foobar" {
t.Fatalf("Read = %d, %v, data %q; want 6, nil, foobar", n, err, buf) return fmt.Errorf("Read = %d, %v, data %q; want 6, nil, foobar", n, err, buf)
} }
srv.Write([]byte("abcdef")) srv.Write([]byte("abcdef"))
srv.Close() srv.Close()
time.Sleep(delay)
n, err = conn.Read(buf) n, err = conn.Read(buf)
if n != 6 || string(buf) != "abcdef" { if n != 6 || string(buf) != "abcdef" {
t.Fatalf("Read = %d, buf= %q; want 6, abcdef", n, buf) return fmt.Errorf("Read = %d, buf= %q; want 6, abcdef", n, buf)
} }
if err != io.EOF { if err != io.EOF {
t.Errorf("Second Read error = %v; want io.EOF", err) return fmt.Errorf("Second Read error = %v; want io.EOF", err)
} }
return nil
} }