@ -17,9 +17,17 @@ import (
"tailscale.com/util/must"
"tailscale.com/util/must"
)
)
func fakeStoreRoutes ( * RouteInfo ) error { return nil }
func TestUpdateDomains ( t * testing . T ) {
func TestUpdateDomains ( t * testing . T ) {
for _ , shouldStore := range [ ] bool { false , true } {
ctx := context . Background ( )
ctx := context . Background ( )
a := NewAppConnector ( t . Logf , nil )
var a * AppConnector
if shouldStore {
a = NewAppConnector ( t . Logf , nil , & RouteInfo { } , fakeStoreRoutes )
} else {
a = NewAppConnector ( t . Logf , nil , nil , nil )
}
a . UpdateDomains ( [ ] string { "example.com" } )
a . UpdateDomains ( [ ] string { "example.com" } )
a . Wait ( ctx )
a . Wait ( ctx )
@ -42,12 +50,19 @@ func TestUpdateDomains(t *testing.T) {
if got , want := xmaps . Keys ( a . domains ) , [ ] string { "up.example.com" } ; ! slices . Equal ( got , want ) {
if got , want := xmaps . Keys ( a . domains ) , [ ] string { "up.example.com" } ; ! slices . Equal ( got , want ) {
t . Errorf ( "got %v; want %v" , got , want )
t . Errorf ( "got %v; want %v" , got , want )
}
}
}
}
}
func TestUpdateRoutes ( t * testing . T ) {
func TestUpdateRoutes ( t * testing . T ) {
for _ , shouldStore := range [ ] bool { false , true } {
ctx := context . Background ( )
ctx := context . Background ( )
rc := & appctest . RouteCollector { }
rc := & appctest . RouteCollector { }
a := NewAppConnector ( t . Logf , rc )
var a * AppConnector
if shouldStore {
a = NewAppConnector ( t . Logf , rc , & RouteInfo { } , fakeStoreRoutes )
} else {
a = NewAppConnector ( t . Logf , rc , nil , nil )
}
a . updateDomains ( [ ] string { "*.example.com" } )
a . updateDomains ( [ ] string { "*.example.com" } )
// This route should be collapsed into the range
// This route should be collapsed into the range
@ -79,11 +94,18 @@ func TestUpdateRoutes(t *testing.T) {
if ! slices . EqualFunc ( rc . RemovedRoutes ( ) , wantRemoved , prefixEqual ) {
if ! slices . EqualFunc ( rc . RemovedRoutes ( ) , wantRemoved , prefixEqual ) {
t . Fatalf ( "unexpected removed routes: %v" , rc . RemovedRoutes ( ) )
t . Fatalf ( "unexpected removed routes: %v" , rc . RemovedRoutes ( ) )
}
}
}
}
}
func TestUpdateRoutesUnadvertisesContainedRoutes ( t * testing . T ) {
func TestUpdateRoutesUnadvertisesContainedRoutes ( t * testing . T ) {
for _ , shouldStore := range [ ] bool { false , true } {
rc := & appctest . RouteCollector { }
rc := & appctest . RouteCollector { }
a := NewAppConnector ( t . Logf , rc )
var a * AppConnector
if shouldStore {
a = NewAppConnector ( t . Logf , rc , & RouteInfo { } , fakeStoreRoutes )
} else {
a = NewAppConnector ( t . Logf , rc , nil , nil )
}
mak . Set ( & a . domains , "example.com" , [ ] netip . Addr { netip . MustParseAddr ( "192.0.2.1" ) } )
mak . Set ( & a . domains , "example.com" , [ ] netip . Addr { netip . MustParseAddr ( "192.0.2.1" ) } )
rc . SetRoutes ( [ ] netip . Prefix { netip . MustParsePrefix ( "192.0.2.1/32" ) } )
rc . SetRoutes ( [ ] netip . Prefix { netip . MustParsePrefix ( "192.0.2.1/32" ) } )
routes := [ ] netip . Prefix { netip . MustParsePrefix ( "192.0.2.0/24" ) }
routes := [ ] netip . Prefix { netip . MustParsePrefix ( "192.0.2.0/24" ) }
@ -92,11 +114,18 @@ func TestUpdateRoutesUnadvertisesContainedRoutes(t *testing.T) {
if ! slices . EqualFunc ( routes , rc . Routes ( ) , prefixEqual ) {
if ! slices . EqualFunc ( routes , rc . Routes ( ) , prefixEqual ) {
t . Fatalf ( "got %v, want %v" , rc . Routes ( ) , routes )
t . Fatalf ( "got %v, want %v" , rc . Routes ( ) , routes )
}
}
}
}
}
func TestDomainRoutes ( t * testing . T ) {
func TestDomainRoutes ( t * testing . T ) {
for _ , shouldStore := range [ ] bool { false , true } {
rc := & appctest . RouteCollector { }
rc := & appctest . RouteCollector { }
a := NewAppConnector ( t . Logf , rc )
var a * AppConnector
if shouldStore {
a = NewAppConnector ( t . Logf , rc , & RouteInfo { } , fakeStoreRoutes )
} else {
a = NewAppConnector ( t . Logf , rc , nil , nil )
}
a . updateDomains ( [ ] string { "example.com" } )
a . updateDomains ( [ ] string { "example.com" } )
a . ObserveDNSResponse ( dnsResponse ( "example.com." , "192.0.0.8" ) )
a . ObserveDNSResponse ( dnsResponse ( "example.com." , "192.0.0.8" ) )
a . Wait ( context . Background ( ) )
a . Wait ( context . Background ( ) )
@ -108,12 +137,19 @@ func TestDomainRoutes(t *testing.T) {
if got := a . DomainRoutes ( ) ; ! reflect . DeepEqual ( got , want ) {
if got := a . DomainRoutes ( ) ; ! reflect . DeepEqual ( got , want ) {
t . Fatalf ( "DomainRoutes: got %v, want %v" , got , want )
t . Fatalf ( "DomainRoutes: got %v, want %v" , got , want )
}
}
}
}
}
func TestObserveDNSResponse ( t * testing . T ) {
func TestObserveDNSResponse ( t * testing . T ) {
for _ , shouldStore := range [ ] bool { false , true } {
ctx := context . Background ( )
ctx := context . Background ( )
rc := & appctest . RouteCollector { }
rc := & appctest . RouteCollector { }
a := NewAppConnector ( t . Logf , rc )
var a * AppConnector
if shouldStore {
a = NewAppConnector ( t . Logf , rc , & RouteInfo { } , fakeStoreRoutes )
} else {
a = NewAppConnector ( t . Logf , rc , nil , nil )
}
// a has no domains configured, so it should not advertise any routes
// a has no domains configured, so it should not advertise any routes
a . ObserveDNSResponse ( dnsResponse ( "example.com." , "192.0.0.8" ) )
a . ObserveDNSResponse ( dnsResponse ( "example.com." , "192.0.0.8" ) )
@ -176,12 +212,19 @@ func TestObserveDNSResponse(t *testing.T) {
if ! slices . Contains ( a . domains [ "example.com" ] , netip . MustParseAddr ( "192.0.2.1" ) ) {
if ! slices . Contains ( a . domains [ "example.com" ] , netip . MustParseAddr ( "192.0.2.1" ) ) {
t . Errorf ( "missing %v from %v" , "192.0.2.1" , a . domains [ "exmaple.com" ] )
t . Errorf ( "missing %v from %v" , "192.0.2.1" , a . domains [ "exmaple.com" ] )
}
}
}
}
}
func TestWildcardDomains ( t * testing . T ) {
func TestWildcardDomains ( t * testing . T ) {
for _ , shouldStore := range [ ] bool { false , true } {
ctx := context . Background ( )
ctx := context . Background ( )
rc := & appctest . RouteCollector { }
rc := & appctest . RouteCollector { }
a := NewAppConnector ( t . Logf , rc )
var a * AppConnector
if shouldStore {
a = NewAppConnector ( t . Logf , rc , & RouteInfo { } , fakeStoreRoutes )
} else {
a = NewAppConnector ( t . Logf , rc , nil , nil )
}
a . updateDomains ( [ ] string { "*.example.com" } )
a . updateDomains ( [ ] string { "*.example.com" } )
a . ObserveDNSResponse ( dnsResponse ( "foo.example.com." , "192.0.0.8" ) )
a . ObserveDNSResponse ( dnsResponse ( "foo.example.com." , "192.0.0.8" ) )
@ -206,6 +249,7 @@ func TestWildcardDomains(t *testing.T) {
if len ( a . wildcards ) != 1 {
if len ( a . wildcards ) != 1 {
t . Errorf ( "expected only one wildcard domain, got %v" , a . wildcards )
t . Errorf ( "expected only one wildcard domain, got %v" , a . wildcards )
}
}
}
}
}
// dnsResponse is a test helper that creates a DNS response buffer for the given domain and address
// dnsResponse is a test helper that creates a DNS response buffer for the given domain and address