dockerfiles/anylink/dtls-2.0.9/e2e/e2e_lossy_test.go

208 lines
4.6 KiB
Go

package e2e
import (
"crypto/tls"
"fmt"
"math/rand"
"testing"
"time"
"github.com/pion/dtls/v2"
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
transportTest "github.com/pion/transport/test"
)
const (
flightInterval = time.Millisecond * 100
lossyTestTimeout = 30 * time.Second
)
/*
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
}
serverCert, err := selfsign.GenerateSelfSigned()
if err != nil {
t.Fatal(err)
}
clientCert, err := selfsign.GenerateSelfSigned()
if err != nil {
t.Fatal(err)
}
for _, test := range []struct {
LossChanceRange int
DoClientAuth bool
CipherSuites []dtls.CipherSuiteID
MTU int
}{
{
LossChanceRange: 0,
},
{
LossChanceRange: 10,
},
{
LossChanceRange: 20,
},
{
LossChanceRange: 50,
},
{
LossChanceRange: 0,
DoClientAuth: true,
},
{
LossChanceRange: 10,
DoClientAuth: true,
},
{
LossChanceRange: 20,
DoClientAuth: true,
},
{
LossChanceRange: 50,
DoClientAuth: true,
},
{
LossChanceRange: 0,
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
},
{
LossChanceRange: 10,
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
},
{
LossChanceRange: 20,
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
},
{
LossChanceRange: 50,
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
},
{
LossChanceRange: 10,
MTU: 100,
DoClientAuth: true,
},
{
LossChanceRange: 20,
MTU: 100,
DoClientAuth: true,
},
{
LossChanceRange: 50,
MTU: 100,
DoClientAuth: true,
},
} {
name := fmt.Sprintf("Loss%d_MTU%d", test.LossChanceRange, test.MTU)
if test.DoClientAuth {
name += "_WithCliAuth"
}
for _, ciph := range test.CipherSuites {
name += "_With" + ciph.String()
}
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 //nolint:gosec
serverDone := make(chan runResult)
clientDone := make(chan runResult)
br := transportTest.NewBridge()
if err = br.SetLossChance(chosenLoss); err != nil {
t.Fatal(err)
}
go func() {
cfg := &dtls.Config{
FlightInterval: flightInterval,
CipherSuites: test.CipherSuites,
InsecureSkipVerify: true,
MTU: test.MTU,
}
if test.DoClientAuth {
cfg.Certificates = []tls.Certificate{clientCert}
}
client, startupErr := dtls.Client(br.GetConn0(), cfg)
clientDone <- runResult{client, startupErr}
}()
go func() {
cfg := &dtls.Config{
Certificates: []tls.Certificate{serverCert},
FlightInterval: flightInterval,
MTU: test.MTU,
}
if test.DoClientAuth {
cfg.ClientAuth = dtls.RequireAnyClientCert
}
server, startupErr := dtls.Server(br.GetConn1(), cfg)
serverDone <- runResult{server, startupErr}
}()
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
}
br.Tick()
select {
case serverResult := <-serverDone:
if serverResult.err != nil {
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.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.Errorf("Test expired: clientComplete(%t) serverComplete(%t) LossChance(%d)", clientConn != nil, serverConn != nil, chosenLoss)
return
case <-time.After(10 * time.Millisecond):
}
}
})
}
}