package app import ( "errors" "net" "reflect" "testing" ) func TestServerURLsForWildcardAddr(t *testing.T) { urls, err := serverURLsWithLocalIPv4Addrs(":8080", func() ([]string, error) { return []string{ "192.168.1.100", "127.0.0.1", "192.168.1.100", "10.0.0.2", }, nil }) if err != nil { t.Fatalf("serverURLsWithLocalIPv4Addrs returned error: %v", err) } want := []string{ "http://localhost:8080", "http://127.0.0.1:8080", "http://192.168.1.100:8080", "http://10.0.0.2:8080", } if !reflect.DeepEqual(urls, want) { t.Fatalf("urls = %#v, want %#v", urls, want) } } func TestServerURLsForZeroIPv4Addr(t *testing.T) { urls, err := serverURLsWithLocalIPv4Addrs("0.0.0.0:8080", func() ([]string, error) { return []string{"192.168.1.100"}, nil }) if err != nil { t.Fatalf("serverURLsWithLocalIPv4Addrs returned error: %v", err) } want := []string{ "http://localhost:8080", "http://127.0.0.1:8080", "http://192.168.1.100:8080", } if !reflect.DeepEqual(urls, want) { t.Fatalf("urls = %#v, want %#v", urls, want) } } func TestServerURLsForSpecificIPv4Addr(t *testing.T) { urls, err := serverURLsWithLocalIPv4Addrs("192.168.1.100:8080", func() ([]string, error) { t.Fatal("local IPv4 addrs should not be discovered for a specific bind address") return nil, nil }) if err != nil { t.Fatalf("serverURLsWithLocalIPv4Addrs returned error: %v", err) } want := []string{"http://192.168.1.100:8080"} if !reflect.DeepEqual(urls, want) { t.Fatalf("urls = %#v, want %#v", urls, want) } } func TestServerURLsForLocalhostAddr(t *testing.T) { urls, err := serverURLsWithLocalIPv4Addrs("localhost:8080", func() ([]string, error) { t.Fatal("local IPv4 addrs should not be discovered for a hostname bind address") return nil, nil }) if err != nil { t.Fatalf("serverURLsWithLocalIPv4Addrs returned error: %v", err) } want := []string{"http://localhost:8080"} if !reflect.DeepEqual(urls, want) { t.Fatalf("urls = %#v, want %#v", urls, want) } } func TestServerURLsReturnsFallbackURLsWhenDiscoveryFails(t *testing.T) { wantErr := errors.New("interfaces unavailable") urls, err := serverURLsWithLocalIPv4Addrs(":8080", func() ([]string, error) { return nil, wantErr }) if !errors.Is(err, wantErr) { t.Fatalf("serverURLsWithLocalIPv4Addrs error = %v, want %v", err, wantErr) } want := []string{ "http://localhost:8080", "http://127.0.0.1:8080", } if !reflect.DeepEqual(urls, want) { t.Fatalf("urls = %#v, want %#v", urls, want) } } func TestIsUsableLocalIPv4(t *testing.T) { tests := []struct { name string ip net.IP want bool }{ {name: "private", ip: net.ParseIP("192.168.1.100"), want: true}, {name: "zero", ip: net.ParseIP("0.0.0.0"), want: false}, {name: "loopback", ip: net.ParseIP("127.0.0.1"), want: false}, {name: "ipv6", ip: net.ParseIP("2001:db8::1"), want: false}, {name: "multicast", ip: net.ParseIP("224.0.0.1"), want: false}, {name: "link local", ip: net.ParseIP("169.254.1.2"), want: false}, {name: "nil", ip: nil, want: false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := isUsableLocalIPv4(tt.ip); got != tt.want { t.Fatalf("isUsableLocalIPv4(%v) = %v, want %v", tt.ip, got, tt.want) } }) } }