@@ -9,6 +9,7 @@ package util
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
@@ -176,6 +177,25 @@ func Address(network, host string) string {
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// AddressUnspecifiedLess is a comparator function preferring least specific network address (most widely listening,
|
||||
// namely preferring 0.0.0.0 over some IP), if both IPs are equal, it prefers the less restrictive network (prefers tcp
|
||||
// over tcp4)
|
||||
func AddressUnspecifiedLess(a, b net.Addr) bool {
|
||||
aIsUnspecified := false
|
||||
bIsUnspecified := false
|
||||
if host, _, err := net.SplitHostPort(a.String()); err == nil {
|
||||
aIsUnspecified = host == "" || net.ParseIP(host).IsUnspecified()
|
||||
}
|
||||
if host, _, err := net.SplitHostPort(b.String()); err == nil {
|
||||
bIsUnspecified = host == "" || net.ParseIP(host).IsUnspecified()
|
||||
}
|
||||
|
||||
if aIsUnspecified == bIsUnspecified {
|
||||
return len(a.Network()) < len(b.Network())
|
||||
}
|
||||
return aIsUnspecified
|
||||
}
|
||||
|
||||
// AsService wraps the given function to implement suture.Service by calling
|
||||
// that function on serve and closing the passed channel when Stop is called.
|
||||
func AsService(fn func(ctx context.Context), creator string) suture.Service {
|
||||
|
||||
@@ -227,6 +227,50 @@ func TestCopyMatching(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type mockedAddr struct {
|
||||
network string
|
||||
addr string
|
||||
}
|
||||
|
||||
func (a mockedAddr) Network() string {
|
||||
return a.network
|
||||
}
|
||||
|
||||
func (a mockedAddr) String() string {
|
||||
return a.addr
|
||||
}
|
||||
|
||||
func TestInspecifiedAddressLess(t *testing.T) {
|
||||
cases := []struct {
|
||||
netA string
|
||||
addrA string
|
||||
netB string
|
||||
addrB string
|
||||
}{
|
||||
// B is assumed the winner.
|
||||
{"tcp", "127.0.0.1:1234", "tcp", ":1235"},
|
||||
{"tcp", "127.0.0.1:1234", "tcp", "0.0.0.0:1235"},
|
||||
{"tcp4", "0.0.0.0:1234", "tcp", "0.0.0.0:1235"}, // tcp4 on the first one
|
||||
}
|
||||
|
||||
for i, testCase := range cases {
|
||||
addrs := []mockedAddr{
|
||||
{testCase.netA, testCase.addrA},
|
||||
{testCase.netB, testCase.addrB},
|
||||
}
|
||||
|
||||
if AddressUnspecifiedLess(addrs[0], addrs[1]) {
|
||||
t.Error(i, "unexpected")
|
||||
}
|
||||
if !AddressUnspecifiedLess(addrs[1], addrs[0]) {
|
||||
t.Error(i, "unexpected")
|
||||
}
|
||||
if AddressUnspecifiedLess(addrs[0], addrs[0]) || AddressUnspecifiedLess(addrs[1], addrs[1]) {
|
||||
t.Error(i, "unexpected")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUtilStopTwicePanic(t *testing.T) {
|
||||
name := "foo"
|
||||
s := AsService(func(ctx context.Context) {
|
||||
|
||||
Reference in New Issue
Block a user