From 841335d14b34705162f2e59df08ae80be2c424cb Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Sun, 10 May 2026 14:02:10 -0400 Subject: [PATCH] webrtc: add NAT1To1IPs multi-IP and fallback tests (issue #20) --- core/webrtc/ice_test.go | 73 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/core/webrtc/ice_test.go b/core/webrtc/ice_test.go index 99294c1..63f21a3 100644 --- a/core/webrtc/ice_test.go +++ b/core/webrtc/ice_test.go @@ -48,3 +48,76 @@ func TestBuildICEConfig_InvalidConfig(t *testing.T) { t.Error("BuildICEConfig should reject invalid config") } } + +// TestBuildICEConfig_NAT1To1IPs_Multi verifies that a list of multiple +// NAT1To1 IPs is accepted and a SettingEngine is returned, allowing +// dual-homed servers to advertise host candidates on all interfaces. +func TestBuildICEConfig_NAT1To1IPs_Multi(t *testing.T) { + c := DefaultConfig() + c.NAT1To1IPs = []string{"10.0.0.1", "203.0.113.10"} + _, se, err := BuildICEConfig(c) + if err != nil { + t.Fatalf("BuildICEConfig with multiple NAT1To1IPs: %v", err) + } + if se == nil { + t.Fatal("SettingEngine should not be nil when NAT1To1IPs is set") + } + // Smoke-test: Pion should accept the engine without panicking. + api := webrtc.NewAPI(webrtc.WithSettingEngine(*se)) + if api == nil { + t.Fatal("NewAPI returned nil") + } +} + +// TestBuildICEConfig_NAT1To1IPs_FallsBackToPublicIP verifies that when +// NAT1To1IPs is empty but PublicIP is set, the single IP is promoted to +// the NAT1To1 list (backward-compat path). +func TestBuildICEConfig_NAT1To1IPs_FallsBackToPublicIP(t *testing.T) { + c := DefaultConfig() + c.PublicIP = "198.51.100.1" + c.NAT1To1IPs = nil + _, se, err := BuildICEConfig(c) + if err != nil { + t.Fatalf("BuildICEConfig (PublicIP fallback): %v", err) + } + if se == nil { + t.Fatal("SettingEngine should be set when PublicIP is used as fallback") + } +} + +// TestBuildICEConfig_NAT1To1IPs_TakesPrecedenceOverPublicIP verifies that +// when both NAT1To1IPs and PublicIP are set, a SettingEngine is still +// returned (the subsystem merges them; BuildICEConfig sees only NAT1To1IPs). +func TestBuildICEConfig_NAT1To1IPs_TakesPrecedenceOverPublicIP(t *testing.T) { + c := DefaultConfig() + c.PublicIP = "198.51.100.1" + c.NAT1To1IPs = []string{"10.0.0.1", "198.51.100.1"} + _, se, err := BuildICEConfig(c) + if err != nil { + t.Fatalf("BuildICEConfig (NAT1To1IPs + PublicIP): %v", err) + } + if se == nil { + t.Fatal("SettingEngine should not be nil when NAT1To1IPs is set") + } +} + +// TestBuildICEConfig_NAT1To1IPs_NeitherSet verifies that with no IP hints +// the function still succeeds (STUN-only mode). A SettingEngine is still +// returned because the default UDPPortRange is non-zero. +func TestBuildICEConfig_NAT1To1IPs_NeitherSet(t *testing.T) { + c := DefaultConfig() + c.PublicIP = "" + c.NAT1To1IPs = nil + _, se, err := BuildICEConfig(c) + if err != nil { + t.Fatalf("BuildICEConfig (STUN-only): %v", err) + } + // UDPPortRange.Low > 0 in DefaultConfig, so se is non-nil; verify it + // builds without error. + if se != nil { + api := webrtc.NewAPI(webrtc.WithSettingEngine(*se)) + if api == nil { + t.Fatal("NewAPI returned nil in STUN-only mode") + } + } +}