Skip to content

Commit

Permalink
Improve error handling and cleanup in tests
Browse files Browse the repository at this point in the history
Fix fatal error handling in goroutine and connection cleanup.
  • Loading branch information
at-wat committed Mar 5, 2020
1 parent 6969c90 commit 5bc0a3f
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 60 deletions.
17 changes: 9 additions & 8 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"context"
"crypto/tls"
"fmt"
"net"
"testing"
"time"

"github.com/pion/dtls/v2/internal/net/dpipe"
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
"github.com/pion/logging"
"github.com/pion/transport/test"
Expand All @@ -19,7 +19,7 @@ func TestSimpleReadWrite(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

ca, cb := net.Pipe()
ca, cb := dpipe.Pipe()
certificate, err := selfsign.GenerateSelfSigned()
if err != nil {
t.Fatal(err)
Expand All @@ -32,14 +32,17 @@ func TestSimpleReadWrite(t *testing.T) {
LoggerFactory: logging.NewDefaultLoggerFactory(),
}, false)
if sErr != nil {
t.Error(err)
t.Error(sErr)
return
}
buf := make([]byte, 1024)
if _, sErr = server.Read(buf); sErr != nil {
t.Error(err)
t.Error(sErr)
}
gotHello <- struct{}{}
if sErr = server.Close(); sErr != nil {
t.Error(sErr)
}
}()

client, err := testClient(ctx, ca, &Config{
Expand All @@ -59,9 +62,7 @@ func TestSimpleReadWrite(t *testing.T) {
t.Error("timeout")
}

if err = ca.Close(); err != nil {
t.Error(err)
} else if err = cb.Close(); err != nil {
if err = client.Close(); err != nil {
t.Error(err)
}
}
Expand All @@ -70,7 +71,7 @@ func benchmarkConn(b *testing.B, n int64) {
b.Run(fmt.Sprintf("%d", n), func(b *testing.B) {
ctx := context.Background()

ca, cb := net.Pipe()
ca, cb := dpipe.Pipe()
certificate, err := selfsign.GenerateSelfSigned()
server := make(chan *Conn)
go func() {
Expand Down
101 changes: 62 additions & 39 deletions conn_go_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,19 @@ import (
"testing"
"time"

"github.com/pion/dtls/v2/internal/net/dpipe"
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
"github.com/pion/transport/test"
)

func TestContextConfig(t *testing.T) {
// Limit runtime in case of deadlocks
lim := test.TimeOut(time.Second * 20)
defer lim.Stop()

report := test.CheckRoutines(t)
defer report()

addrListen, err := net.ResolveUDPAddr("udp", "localhost:0")
if err != nil {
t.Fatalf("Unexpected error: %v", err)
Expand Down Expand Up @@ -41,64 +50,74 @@ func TestContextConfig(t *testing.T) {
}

dials := map[string]struct {
f func() (net.Conn, error)
f func() (func() (net.Conn, error), func())
order []byte
}{
"Dial": {
f: func() (net.Conn, error) {
return Dial("udp", addr, config)
f: func() (func() (net.Conn, error), func()) {
return func() (net.Conn, error) {
return Dial("udp", addr, config)
}, func() {
}
},
order: []byte{0, 1, 2},
},
"DialWithContext": {
f: func() (net.Conn, error) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Millisecond)
defer cancel()
return DialWithContext(ctx, "udp", addr, config)
f: func() (func() (net.Conn, error), func()) {
ctx, cancel := context.WithTimeout(context.Background(), 80*time.Millisecond)
return func() (net.Conn, error) {
return DialWithContext(ctx, "udp", addr, config)
}, func() {
cancel()
}
},
order: []byte{0, 2, 1},
},
"Client": {
f: func() (net.Conn, error) {
ca, _ := net.Pipe()
defer func() {
_ = ca.Close()
}()
return Client(ca, config)
f: func() (func() (net.Conn, error), func()) {
ca, _ := dpipe.Pipe()
return func() (net.Conn, error) {
return Client(ca, config)
}, func() {
_ = ca.Close()
}
},
order: []byte{0, 1, 2},
},
"ClientWithContext": {
f: func() (net.Conn, error) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Millisecond)
defer cancel()
ca, _ := net.Pipe()
defer func() {
_ = ca.Close()
}()
return ClientWithContext(ctx, ca, config)
f: func() (func() (net.Conn, error), func()) {
ctx, cancel := context.WithTimeout(context.Background(), 80*time.Millisecond)
ca, _ := dpipe.Pipe()
return func() (net.Conn, error) {
return ClientWithContext(ctx, ca, config)
}, func() {
cancel()
_ = ca.Close()
}
},
order: []byte{0, 2, 1},
},
"Server": {
f: func() (net.Conn, error) {
ca, _ := net.Pipe()
defer func() {
_ = ca.Close()
}()
return Server(ca, config)
f: func() (func() (net.Conn, error), func()) {
ca, _ := dpipe.Pipe()
return func() (net.Conn, error) {
return Server(ca, config)
}, func() {
_ = ca.Close()
}
},
order: []byte{0, 1, 2},
},
"ServerWithContext": {
f: func() (net.Conn, error) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Millisecond)
defer cancel()
ca, _ := net.Pipe()
defer func() {
_ = ca.Close()
}()
return ServerWithContext(ctx, ca, config)
f: func() (func() (net.Conn, error), func()) {
ctx, cancel := context.WithTimeout(context.Background(), 80*time.Millisecond)
ca, _ := dpipe.Pipe()
return func() (net.Conn, error) {
return ServerWithContext(ctx, ca, config)
}, func() {
cancel()
_ = ca.Close()
}
},
order: []byte{0, 2, 1},
},
Expand All @@ -110,19 +129,23 @@ func TestContextConfig(t *testing.T) {
done := make(chan struct{})

go func() {
conn, err := dial.f()
d, cancel := dial.f()
conn, err := d()
defer cancel()
if err != errConnectTimeout {
t.Errorf("Expected error: '%v', got: '%v'", errConnectTimeout, err)
close(done)
return
}
done <- struct{}{}
_ = conn.Close()
if err == nil {
_ = conn.Close()
}
}()

var order []byte
early := time.After(30 * time.Millisecond)
late := time.After(50 * time.Millisecond)
early := time.After(20 * time.Millisecond)
late := time.After(60 * time.Millisecond)
func() {
for len(order) < 3 {
select {
Expand Down
31 changes: 27 additions & 4 deletions conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,12 @@ func TestSRTPConfiguration(t *testing.T) {
res := <-c
if res.err != nil || test.WantClientError != nil {
if !(res.err != nil && test.WantClientError != nil && res.err.Error() == test.WantClientError.Error()) {
t.Errorf("TestSRTPConfiguration: Client Error Mismatch '%s': expected(%v) actual(%v)", test.Name, test.WantClientError, res.err)
t.Fatalf("TestSRTPConfiguration: Client Error Mismatch '%s': expected(%v) actual(%v)", test.Name, test.WantClientError, res.err)
}
}
if res.c == nil {
return
}

actualClientSRTP, _ := res.c.SelectedSRTPProtectionProfile()
if actualClientSRTP != test.ExpectedProfile {
Expand Down Expand Up @@ -726,8 +729,16 @@ func TestExtendedMasterSecret(t *testing.T) {
c <- result{client, err}
}()

_, err := testServer(ctx, cb, tt.serverCfg, true)
server, err := testServer(ctx, cb, tt.serverCfg, true)
res := <-c
defer func() {
if server != nil {
_ = server.Close()
}
if res.c != nil {
_ = res.c.Close()
}
}()

if tt.expectedClientErr != nil {
if res.err.Error() != tt.expectedClientErr.Error() {
Expand Down Expand Up @@ -818,16 +829,28 @@ func TestServerCertificate(t *testing.T) {
tt := tt
t.Run(name, func(t *testing.T) {
ca, cb := dpipe.Pipe()

srvCh := make(chan *Conn)
go func() {
_, _ = Server(cb, tt.serverCfg)
s, _ := Server(cb, tt.serverCfg)
srvCh <- s
}()
_, err := Client(ca, tt.clientCfg)

cli, err := Client(ca, tt.clientCfg)
if !tt.wantErr && err != nil {
t.Errorf("TestClientCertificate: Client failed(%v)", err)
}
if tt.wantErr && err == nil {
t.Fatal("Error expected")
}

srv := <-srvCh
if cli != nil {
_ = cli.Close()
}
if srv != nil {
_ = srv.Close()
}
})
}
}
Expand Down
36 changes: 27 additions & 9 deletions e2e/e2e_lossy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ const (
DTLS Client/Server over a lossy transport, just asserts it can handle at increasing increments
*/
func TestPionE2ELossy(t *testing.T) {
// Check for leaking routines
report := transportTest.CheckRoutines(t)
defer report()

type runResult struct {
dtlsConn *dtls.Conn
err error
Expand Down Expand Up @@ -111,6 +115,10 @@ func TestPionE2ELossy(t *testing.T) {
}
test := test
t.Run(name, func(t *testing.T) {
// Limit runtime in case of deadlocks
lim := transportTest.TimeOut(lossyTestTimeout + time.Second)
defer lim.Stop()

rand.Seed(time.Now().UTC().UnixNano())
chosenLoss := rand.Intn(9) + test.LossChanceRange
serverDone := make(chan runResult)
Expand Down Expand Up @@ -154,6 +162,19 @@ func TestPionE2ELossy(t *testing.T) {

testTimer := time.NewTimer(lossyTestTimeout)
var serverConn, clientConn *dtls.Conn
defer func() {
if serverConn != nil {
if err = serverConn.Close(); err != nil {
t.Error(err)
}
}
if clientConn != nil {
if err = clientConn.Close(); err != nil {
t.Error(err)
}
}
}()

for {
if serverConn != nil && clientConn != nil {
break
Expand All @@ -163,27 +184,24 @@ func TestPionE2ELossy(t *testing.T) {
select {
case serverResult := <-serverDone:
if serverResult.err != nil {
t.Fatalf("Fail, serverError: clientComplete(%t) serverComplete(%t) LossChance(%d) error(%v)", clientConn != nil, serverConn != nil, chosenLoss, serverResult.err)
t.Errorf("Fail, serverError: clientComplete(%t) serverComplete(%t) LossChance(%d) error(%v)", clientConn != nil, serverConn != nil, chosenLoss, serverResult.err)
return
}

serverConn = serverResult.dtlsConn
case clientResult := <-clientDone:
if clientResult.err != nil {
t.Fatalf("Fail, clientError: clientComplete(%t) serverComplete(%t) LossChance(%d) error(%v)", clientConn != nil, serverConn != nil, chosenLoss, clientResult.err)
t.Errorf("Fail, clientError: clientComplete(%t) serverComplete(%t) LossChance(%d) error(%v)", clientConn != nil, serverConn != nil, chosenLoss, clientResult.err)
return
}

clientConn = clientResult.dtlsConn
case <-testTimer.C:
t.Fatalf("Test expired: clientComplete(%t) serverComplete(%t) LossChance(%d)", clientConn != nil, serverConn != nil, chosenLoss)
t.Errorf("Test expired: clientComplete(%t) serverComplete(%t) LossChance(%d)", clientConn != nil, serverConn != nil, chosenLoss)
return
case <-time.After(10 * time.Millisecond):
}
}

if err = serverConn.Close(); err != nil {
t.Fatal(err)
}

clientConn.Close() //nolint
})
}
}

0 comments on commit 5bc0a3f

Please sign in to comment.