|
|
@@ -4,7 +4,6 @@
|
|
|
package appc
|
|
|
|
|
|
import (
|
|
|
- "context"
|
|
|
"net/netip"
|
|
|
"reflect"
|
|
|
"slices"
|
|
|
@@ -16,6 +15,7 @@ import (
|
|
|
"tailscale.com/appc/appctest"
|
|
|
"tailscale.com/tstest"
|
|
|
"tailscale.com/util/clientmetric"
|
|
|
+ "tailscale.com/util/eventbus/eventbustest"
|
|
|
"tailscale.com/util/mak"
|
|
|
"tailscale.com/util/must"
|
|
|
"tailscale.com/util/slicesx"
|
|
|
@@ -24,18 +24,20 @@ import (
|
|
|
func fakeStoreRoutes(*RouteInfo) error { return nil }
|
|
|
|
|
|
func TestUpdateDomains(t *testing.T) {
|
|
|
+ ctx := t.Context()
|
|
|
+ bus := eventbustest.NewBus(t)
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
- ctx := context.Background()
|
|
|
var a *AppConnector
|
|
|
if shouldStore {
|
|
|
a = NewAppConnector(Config{
|
|
|
Logf: t.Logf,
|
|
|
+ EventBus: bus,
|
|
|
RouteAdvertiser: &appctest.RouteCollector{},
|
|
|
RouteInfo: &RouteInfo{},
|
|
|
StoreRoutesFunc: fakeStoreRoutes,
|
|
|
})
|
|
|
} else {
|
|
|
- a = NewAppConnector(Config{Logf: t.Logf, RouteAdvertiser: &appctest.RouteCollector{}})
|
|
|
+ a = NewAppConnector(Config{Logf: t.Logf, EventBus: bus, RouteAdvertiser: &appctest.RouteCollector{}})
|
|
|
}
|
|
|
a.UpdateDomains([]string{"example.com"})
|
|
|
|
|
|
@@ -63,18 +65,20 @@ func TestUpdateDomains(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
func TestUpdateRoutes(t *testing.T) {
|
|
|
+ ctx := t.Context()
|
|
|
+ bus := eventbustest.NewBus(t)
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
- ctx := context.Background()
|
|
|
rc := &appctest.RouteCollector{}
|
|
|
var a *AppConnector
|
|
|
if shouldStore {
|
|
|
a = NewAppConnector(Config{
|
|
|
Logf: t.Logf,
|
|
|
+ EventBus: bus,
|
|
|
RouteAdvertiser: rc,
|
|
|
RouteInfo: &RouteInfo{}, StoreRoutesFunc: fakeStoreRoutes,
|
|
|
})
|
|
|
} else {
|
|
|
- a = NewAppConnector(Config{Logf: t.Logf, RouteAdvertiser: rc})
|
|
|
+ a = NewAppConnector(Config{Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc})
|
|
|
}
|
|
|
a.updateDomains([]string{"*.example.com"})
|
|
|
|
|
|
@@ -116,19 +120,21 @@ func TestUpdateRoutes(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
func TestUpdateRoutesUnadvertisesContainedRoutes(t *testing.T) {
|
|
|
- ctx := context.Background()
|
|
|
+ ctx := t.Context()
|
|
|
+ bus := eventbustest.NewBus(t)
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
rc := &appctest.RouteCollector{}
|
|
|
var a *AppConnector
|
|
|
if shouldStore {
|
|
|
a = NewAppConnector(Config{
|
|
|
Logf: t.Logf,
|
|
|
+ EventBus: bus,
|
|
|
RouteAdvertiser: rc,
|
|
|
RouteInfo: &RouteInfo{},
|
|
|
StoreRoutesFunc: fakeStoreRoutes,
|
|
|
})
|
|
|
} else {
|
|
|
- a = NewAppConnector(Config{Logf: t.Logf, RouteAdvertiser: rc})
|
|
|
+ a = NewAppConnector(Config{Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc})
|
|
|
}
|
|
|
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")})
|
|
|
@@ -143,24 +149,26 @@ func TestUpdateRoutesUnadvertisesContainedRoutes(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
func TestDomainRoutes(t *testing.T) {
|
|
|
+ bus := eventbustest.NewBus(t)
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
rc := &appctest.RouteCollector{}
|
|
|
var a *AppConnector
|
|
|
if shouldStore {
|
|
|
a = NewAppConnector(Config{
|
|
|
Logf: t.Logf,
|
|
|
+ EventBus: bus,
|
|
|
RouteAdvertiser: rc,
|
|
|
RouteInfo: &RouteInfo{},
|
|
|
StoreRoutesFunc: fakeStoreRoutes,
|
|
|
})
|
|
|
} else {
|
|
|
- a = NewAppConnector(Config{Logf: t.Logf, RouteAdvertiser: rc})
|
|
|
+ a = NewAppConnector(Config{Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc})
|
|
|
}
|
|
|
a.updateDomains([]string{"example.com"})
|
|
|
if err := a.ObserveDNSResponse(dnsResponse("example.com.", "192.0.0.8")); err != nil {
|
|
|
t.Errorf("ObserveDNSResponse: %v", err)
|
|
|
}
|
|
|
- a.Wait(context.Background())
|
|
|
+ a.Wait(t.Context())
|
|
|
|
|
|
want := map[string][]netip.Addr{
|
|
|
"example.com": {netip.MustParseAddr("192.0.0.8")},
|
|
|
@@ -173,19 +181,21 @@ func TestDomainRoutes(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
func TestObserveDNSResponse(t *testing.T) {
|
|
|
+ ctx := t.Context()
|
|
|
+ bus := eventbustest.NewBus(t)
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
- ctx := context.Background()
|
|
|
rc := &appctest.RouteCollector{}
|
|
|
var a *AppConnector
|
|
|
if shouldStore {
|
|
|
a = NewAppConnector(Config{
|
|
|
Logf: t.Logf,
|
|
|
+ EventBus: bus,
|
|
|
RouteAdvertiser: rc,
|
|
|
RouteInfo: &RouteInfo{},
|
|
|
StoreRoutesFunc: fakeStoreRoutes,
|
|
|
})
|
|
|
} else {
|
|
|
- a = NewAppConnector(Config{Logf: t.Logf, RouteAdvertiser: rc})
|
|
|
+ a = NewAppConnector(Config{Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc})
|
|
|
}
|
|
|
|
|
|
// a has no domains configured, so it should not advertise any routes
|
|
|
@@ -267,19 +277,21 @@ func TestObserveDNSResponse(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
func TestWildcardDomains(t *testing.T) {
|
|
|
+ ctx := t.Context()
|
|
|
+ bus := eventbustest.NewBus(t)
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
- ctx := context.Background()
|
|
|
rc := &appctest.RouteCollector{}
|
|
|
var a *AppConnector
|
|
|
if shouldStore {
|
|
|
a = NewAppConnector(Config{
|
|
|
Logf: t.Logf,
|
|
|
+ EventBus: bus,
|
|
|
RouteAdvertiser: rc,
|
|
|
RouteInfo: &RouteInfo{},
|
|
|
StoreRoutesFunc: fakeStoreRoutes,
|
|
|
})
|
|
|
} else {
|
|
|
- a = NewAppConnector(Config{Logf: t.Logf, RouteAdvertiser: rc})
|
|
|
+ a = NewAppConnector(Config{Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc})
|
|
|
}
|
|
|
|
|
|
a.updateDomains([]string{"*.example.com"})
|
|
|
@@ -422,8 +434,9 @@ func prefixes(in ...string) []netip.Prefix {
|
|
|
}
|
|
|
|
|
|
func TestUpdateRouteRouteRemoval(t *testing.T) {
|
|
|
+ ctx := t.Context()
|
|
|
+ bus := eventbustest.NewBus(t)
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
- ctx := context.Background()
|
|
|
rc := &appctest.RouteCollector{}
|
|
|
|
|
|
assertRoutes := func(prefix string, routes, removedRoutes []netip.Prefix) {
|
|
|
@@ -439,12 +452,13 @@ func TestUpdateRouteRouteRemoval(t *testing.T) {
|
|
|
if shouldStore {
|
|
|
a = NewAppConnector(Config{
|
|
|
Logf: t.Logf,
|
|
|
+ EventBus: bus,
|
|
|
RouteAdvertiser: rc,
|
|
|
RouteInfo: &RouteInfo{},
|
|
|
StoreRoutesFunc: fakeStoreRoutes,
|
|
|
})
|
|
|
} else {
|
|
|
- a = NewAppConnector(Config{Logf: t.Logf, RouteAdvertiser: rc})
|
|
|
+ a = NewAppConnector(Config{Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc})
|
|
|
}
|
|
|
// nothing has yet been advertised
|
|
|
assertRoutes("appc init", []netip.Prefix{}, []netip.Prefix{})
|
|
|
@@ -472,8 +486,9 @@ func TestUpdateRouteRouteRemoval(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
func TestUpdateDomainRouteRemoval(t *testing.T) {
|
|
|
+ ctx := t.Context()
|
|
|
+ bus := eventbustest.NewBus(t)
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
- ctx := context.Background()
|
|
|
rc := &appctest.RouteCollector{}
|
|
|
|
|
|
assertRoutes := func(prefix string, routes, removedRoutes []netip.Prefix) {
|
|
|
@@ -489,12 +504,13 @@ func TestUpdateDomainRouteRemoval(t *testing.T) {
|
|
|
if shouldStore {
|
|
|
a = NewAppConnector(Config{
|
|
|
Logf: t.Logf,
|
|
|
+ EventBus: bus,
|
|
|
RouteAdvertiser: rc,
|
|
|
RouteInfo: &RouteInfo{},
|
|
|
StoreRoutesFunc: fakeStoreRoutes,
|
|
|
})
|
|
|
} else {
|
|
|
- a = NewAppConnector(Config{Logf: t.Logf, RouteAdvertiser: rc})
|
|
|
+ a = NewAppConnector(Config{Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc})
|
|
|
}
|
|
|
assertRoutes("appc init", []netip.Prefix{}, []netip.Prefix{})
|
|
|
|
|
|
@@ -532,8 +548,9 @@ func TestUpdateDomainRouteRemoval(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
func TestUpdateWildcardRouteRemoval(t *testing.T) {
|
|
|
+ ctx := t.Context()
|
|
|
+ bus := eventbustest.NewBus(t)
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
- ctx := context.Background()
|
|
|
rc := &appctest.RouteCollector{}
|
|
|
|
|
|
assertRoutes := func(prefix string, routes, removedRoutes []netip.Prefix) {
|
|
|
@@ -549,12 +566,13 @@ func TestUpdateWildcardRouteRemoval(t *testing.T) {
|
|
|
if shouldStore {
|
|
|
a = NewAppConnector(Config{
|
|
|
Logf: t.Logf,
|
|
|
+ EventBus: bus,
|
|
|
RouteAdvertiser: rc,
|
|
|
RouteInfo: &RouteInfo{},
|
|
|
StoreRoutesFunc: fakeStoreRoutes,
|
|
|
})
|
|
|
} else {
|
|
|
- a = NewAppConnector(Config{Logf: t.Logf, RouteAdvertiser: rc})
|
|
|
+ a = NewAppConnector(Config{Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc})
|
|
|
}
|
|
|
assertRoutes("appc init", []netip.Prefix{}, []netip.Prefix{})
|
|
|
|
|
|
@@ -691,10 +709,12 @@ func TestMetricBucketsAreSorted(t *testing.T) {
|
|
|
// back into AppConnector via authReconfig. If everything is called
|
|
|
// synchronously, this results in a deadlock on AppConnector.mu.
|
|
|
func TestUpdateRoutesDeadlock(t *testing.T) {
|
|
|
- ctx := context.Background()
|
|
|
+ ctx := t.Context()
|
|
|
+ bus := eventbustest.NewBus(t)
|
|
|
rc := &appctest.RouteCollector{}
|
|
|
a := NewAppConnector(Config{
|
|
|
Logf: t.Logf,
|
|
|
+ EventBus: bus,
|
|
|
RouteAdvertiser: rc,
|
|
|
RouteInfo: &RouteInfo{},
|
|
|
StoreRoutesFunc: fakeStoreRoutes,
|