Fix the tests on Windows

This commit is contained in:
Joe Turki
2025-09-22 17:39:54 +03:00
parent 92565e1979
commit ee3a2e4341
5 changed files with 103 additions and 31 deletions

View File

@@ -131,6 +131,7 @@ func TestActiveTCP(t *testing.T) {
LoggerFactory: loggerFactory,
HostAcceptanceMinWait: &hostAcceptanceMinWait,
InterfaceFilter: problematicNetworkInterfaces,
IncludeLoopback: true,
}
if testCase.useMDNS {
cfg.MulticastDNSMode = MulticastDNSModeQueryAndGather
@@ -145,7 +146,9 @@ func TestActiveTCP(t *testing.T) {
LoggerFactory: loggerFactory,
HostAcceptanceMinWait: &hostAcceptanceMinWait,
InterfaceFilter: problematicNetworkInterfaces,
IncludeLoopback: true,
})
req.NoError(err)
req.NotNil(activeAgent)

View File

@@ -470,7 +470,7 @@ func TestInvalidAgentStarts(t *testing.T) {
}()
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
defer cancel()
_, err = agent.Dial(ctx, "", "bar")
@@ -1817,12 +1817,35 @@ func TestAcceptAggressiveNomination(t *testing.T) { //nolint:cyclop
}
}
time.Sleep(1 * time.Second)
select {
case selected := <-selectedCh:
require.True(t, selected.Equal(expectNewSelectedCandidate))
default:
require.False(t, tc.isExpectedToSwitch)
// Wait until either we observe the expected switch or the timeout elapses,
// Ugly but makes the tests less flaky, especially on Windows.
timeout := 3 * time.Second
deadline := time.Now().Add(timeout)
observedExpected := false
waitLoop:
for time.Now().Before(deadline) {
select {
case selected := <-selectedCh:
if tc.isExpectedToSwitch {
if selected.Equal(expectNewSelectedCandidate) {
observedExpected = true
break waitLoop
}
}
default:
time.Sleep(10 * time.Millisecond)
}
}
if tc.isExpectedToSwitch {
if !observedExpected {
// Verify the agent's final selected pair if we didn't observe the event directly.
require.True(t, aAgent.getSelectedPair().Remote.Equal(expectNewSelectedCandidate))
}
} else {
// Ensure no switch happened by checking the agent's final selected pair.
require.True(t, aAgent.getSelectedPair().Remote.Equal(expectNewSelectedCandidate))
}
})
@@ -1957,11 +1980,13 @@ func TestAlwaysSentKeepAlive(t *testing.T) { //nolint:cyclop
require.NotEqual(t, lastSent, newLastSent)
lastSent = newLastSent
// sleep, so there is difference in sent time of local candidate
time.Sleep(10 * time.Millisecond)
agent.checkKeepalive()
newLastSent = pair.Local.LastSent()
require.NotEqual(t, lastSent, newLastSent)
// Wait for enough time to pass so there is difference in sent time of local candidate.
require.Eventually(t, func() bool {
agent.checkKeepalive()
newLastSent = pair.Local.LastSent()
return !lastSent.Equal(newLastSent)
}, 1*time.Second, 50*time.Millisecond)
}
func TestRoleConflict(t *testing.T) {

View File

@@ -16,6 +16,37 @@ import (
"github.com/stretchr/testify/require"
)
// newMuxForAddr creates a UDPMuxDefault with the correct socket family for the given address.
// This fixes Windows dual-stack issues where IPv6 sockets don't receive IPv4 traffic by default.
func newMuxForAddr(t *testing.T, addr *net.UDPAddr, loggerFactory logging.LoggerFactory) *UDPMuxDefault {
t.Helper()
var (
network string
laddr *net.UDPAddr
)
switch {
case addr.IP == nil || addr.IP.IsUnspecified():
network = "udp4"
laddr = &net.UDPAddr{IP: net.IPv4zero, Port: addr.Port}
case addr.IP.To4() != nil:
network = "udp4"
laddr = &net.UDPAddr{IP: net.IPv4zero, Port: addr.Port}
default:
network = "udp6"
laddr = &net.UDPAddr{IP: net.IPv6unspecified, Port: addr.Port}
}
pc, err := net.ListenUDP(network, laddr)
require.NoError(t, err)
t.Cleanup(func() { _ = pc.Close() })
return NewUDPMuxDefault(UDPMuxParams{
Logger: loggerFactory.NewLogger("ice"),
UDPConn: pc,
})
}
// TestMuxAgent is an end to end test over UDP mux, ensuring two agents could connect over mux.
func TestMuxAgent(t *testing.T) {
defer test.CheckRoutines(t)()
@@ -32,14 +63,8 @@ func TestMuxAgent(t *testing.T) {
for subTest, addr := range caseAddrs {
muxAddr := addr
t.Run(subTest, func(t *testing.T) {
c, err := net.ListenUDP("udp", muxAddr)
require.NoError(t, err)
loggerFactory := logging.NewDefaultLoggerFactory()
udpMux := NewUDPMuxDefault(UDPMuxParams{
Logger: loggerFactory.NewLogger("ice"),
UDPConn: c,
})
udpMux := newMuxForAddr(t, muxAddr, loggerFactory)
muxedA, err := NewAgent(&AgentConfig{
UDPMux: udpMux,

View File

@@ -12,6 +12,7 @@ import (
"io"
"net"
"net/url"
"runtime"
"sort"
"strconv"
"sync"
@@ -345,15 +346,18 @@ func TestTURNConcurrency(t *testing.T) {
}()
urls := []*stun.URI{}
for i := 0; i <= 10; i++ {
urls = append(urls, &stun.URI{
Scheme: scheme,
Host: localhostIPStr,
Username: "username",
Password: "password",
Proto: protocol,
Port: serverPort + 1 + i,
})
// avoid long delay on unreachable ports on Windows
if runtime.GOOS != "windows" {
for i := 0; i <= 10; i++ {
urls = append(urls, &stun.URI{
Scheme: scheme,
Host: localhostIPStr,
Username: "username",
Password: "password",
Proto: protocol,
Port: serverPort + 1 + i,
})
}
}
urls = append(urls, &stun.URI{
Scheme: scheme,

View File

@@ -162,15 +162,30 @@ func TestMultiUDPMux_GetConn_NoUDPMuxAvailable(t *testing.T) {
_ = multi.Close()
}()
// tweak the port so it doesn't match.
// Pick a port that is guaranteed not to match any listening address
addrs := multi.GetListenAddresses()
require.NotEmpty(t, addrs)
udpAddr, ok := addrs[0].(*net.UDPAddr)
require.True(t, ok, "expected *net.UDPAddr")
// change the port to something different so addr.String() is not in localAddrToMux.
missing := &net.UDPAddr{IP: udpAddr.IP, Port: udpAddr.Port + 1, Zone: udpAddr.Zone}
// Build a set of in-use ports
inUse := make(map[int]struct{}, len(addrs))
for _, a := range addrs {
if ua, ok := a.(*net.UDPAddr); ok {
inUse[ua.Port] = struct{}{}
}
}
// Find a nearby port not in use
newPort := udpAddr.Port + 1
for i := 0; i < 100; i++ {
if _, exists := inUse[newPort]; !exists {
break
}
newPort++
}
missing := &net.UDPAddr{IP: udpAddr.IP, Port: newPort, Zone: udpAddr.Zone}
pc, getErr := multi.GetConn("missing-ufrag", missing)
require.Nil(t, pc)