ipn,net,tsnet,wgengine: make an eventbus mandatory where it is used (#16594)

In the components where an event bus is already plumbed through, remove the
exceptions that allow it to be omitted, and update all the tests that relied on
those workarounds execute properly.

This change applies only to the places where we're already using the bus; it
does not enforce the existence of a bus in other components (yet),

Updates #15160

Change-Id: Iebb92243caba82b5eb420c49fc3e089a77454f65
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This commit is contained in:
M. J. Fromberger
2025-07-29 09:04:08 -07:00
committed by GitHub
parent e5e4386f33
commit b34cdc9710
11 changed files with 133 additions and 123 deletions

View File

@@ -377,7 +377,7 @@ func peersMap(s []tailcfg.NodeView) map[tailcfg.NodeID]tailcfg.NodeView {
}
func TestAllowExitNodeDNSProxyToServeName(t *testing.T) {
b := &LocalBackend{}
b := newTestLocalBackend(t)
if b.allowExitNodeDNSProxyToServeName("google.com") {
t.Fatal("unexpected true on backend with nil NetMap")
}

View File

@@ -99,7 +99,6 @@ import (
"tailscale.com/util/clientmetric"
"tailscale.com/util/deephash"
"tailscale.com/util/dnsname"
"tailscale.com/util/eventbus"
"tailscale.com/util/goroutines"
"tailscale.com/util/httpm"
"tailscale.com/util/mak"
@@ -618,15 +617,7 @@ func (b *LocalBackend) currentNode() *nodeBackend {
if v := b.currentNodeAtomic.Load(); v != nil || !testenv.InTest() {
return v
}
// Auto-init [nodeBackend] in tests for LocalBackend created without the
// NewLocalBackend() constructor. Same reasoning for checking b.sys.
var bus *eventbus.Bus
if b.sys == nil {
bus = eventbus.New()
} else {
bus = b.sys.Bus.Get()
}
v := newNodeBackend(cmp.Or(b.ctx, context.Background()), bus)
v := newNodeBackend(cmp.Or(b.ctx, context.Background()), b.sys.Bus.Get())
if b.currentNodeAtomic.CompareAndSwap(nil, v) {
v.ready()
}

View File

@@ -463,6 +463,7 @@ func newTestLocalBackendWithSys(t testing.TB, sys *tsd.System) *LocalBackend {
var logf logger.Logf = logger.Discard
if _, ok := sys.StateStore.GetOK(); !ok {
sys.Set(new(mem.Store))
t.Log("Added memory store for testing")
}
if _, ok := sys.Engine.GetOK(); !ok {
eng, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.HealthTracker(), sys.UserMetricsRegistry(), sys.Bus.Get())
@@ -471,6 +472,11 @@ func newTestLocalBackendWithSys(t testing.TB, sys *tsd.System) *LocalBackend {
}
t.Cleanup(eng.Close)
sys.Set(eng)
t.Log("Added fake userspace engine for testing")
}
if _, ok := sys.Dialer.GetOK(); !ok {
sys.Set(tsdial.NewDialer(netmon.NewStatic()))
t.Log("Added static dialer for testing")
}
lb, err := NewLocalBackend(logf, logid.PublicID{}, sys, 0)
if err != nil {

View File

@@ -28,6 +28,7 @@ import (
"tailscale.com/net/tsdial"
"tailscale.com/tailcfg"
"tailscale.com/tka"
"tailscale.com/tsd"
"tailscale.com/types/key"
"tailscale.com/types/netmap"
"tailscale.com/types/persist"
@@ -935,18 +936,21 @@ func TestTKAForceDisable(t *testing.T) {
defer ts.Close()
cc := fakeControlClient(t, client)
b := LocalBackend{
varRoot: temp,
cc: cc,
ccAuto: cc,
logf: t.Logf,
tka: &tkaState{
authority: authority,
storage: chonk,
},
pm: pm,
store: pm.Store(),
sys := tsd.NewSystem()
sys.Set(pm.Store())
b := newTestLocalBackendWithSys(t, sys)
b.SetVarRoot(temp)
b.SetControlClientGetterForTesting(func(controlclient.Options) (controlclient.Client, error) {
return cc, nil
})
b.mu.Lock()
b.tka = &tkaState{
authority: authority,
storage: chonk,
}
b.pm = pm
b.mu.Unlock()
if err := b.NetworkLockForceLocalDisable(); err != nil {
t.Fatalf("NetworkLockForceLocalDisable() failed: %v", err)

View File

@@ -21,10 +21,10 @@ import (
"tailscale.com/ipn"
"tailscale.com/ipn/store/mem"
"tailscale.com/tailcfg"
"tailscale.com/tsd"
"tailscale.com/tstest"
"tailscale.com/types/logger"
"tailscale.com/types/netmap"
"tailscale.com/util/eventbus"
"tailscale.com/util/must"
"tailscale.com/util/usermetric"
"tailscale.com/wgengine"
@@ -156,10 +156,9 @@ func TestHandlePeerAPI(t *testing.T) {
selfNode.CapMap = tailcfg.NodeCapMap{tailcfg.CapabilityDebug: nil}
}
var e peerAPITestEnv
lb := &LocalBackend{
logf: e.logBuf.Logf,
clock: &tstest.Clock{},
}
lb := newTestLocalBackend(t)
lb.logf = e.logBuf.Logf
lb.clock = &tstest.Clock{}
lb.currentNode().SetNetMap(&netmap.NetworkMap{SelfNode: selfNode.View()})
e.ph = &peerAPIHandler{
isSelf: tt.isSelf,
@@ -195,20 +194,20 @@ func TestPeerAPIReplyToDNSQueries(t *testing.T) {
h.isSelf = false
h.remoteAddr = netip.MustParseAddrPort("100.150.151.152:12345")
bus := eventbus.New()
defer bus.Close()
sys := tsd.NewSystem()
t.Cleanup(sys.Bus.Get().Close)
ht := new(health.Tracker)
reg := new(usermetric.Registry)
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, bus)
pm := must.Get(newProfileManager(new(mem.Store), t.Logf, ht))
h.ps = &peerAPIServer{
b: &LocalBackend{
e: eng,
pm: pm,
store: pm.Store(),
},
}
reg := new(usermetric.Registry)
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, sys.Bus.Get(), sys.Set)
sys.Set(pm.Store())
sys.Set(eng)
b := newTestLocalBackendWithSys(t, sys)
b.pm = pm
h.ps = &peerAPIServer{b: b}
if h.ps.b.OfferingExitNode() {
t.Fatal("unexpectedly offering exit node")
}
@@ -250,12 +249,12 @@ func TestPeerAPIPrettyReplyCNAME(t *testing.T) {
var h peerAPIHandler
h.remoteAddr = netip.MustParseAddrPort("100.150.151.152:12345")
bus := eventbus.New()
defer bus.Close()
sys := tsd.NewSystem()
t.Cleanup(sys.Bus.Get().Close)
ht := new(health.Tracker)
reg := new(usermetric.Registry)
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, bus)
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, sys.Bus.Get(), sys.Set)
pm := must.Get(newProfileManager(new(mem.Store), t.Logf, ht))
var a *appc.AppConnector
if shouldStore {
@@ -263,16 +262,14 @@ func TestPeerAPIPrettyReplyCNAME(t *testing.T) {
} else {
a = appc.NewAppConnector(t.Logf, &appctest.RouteCollector{}, nil, nil)
}
h.ps = &peerAPIServer{
b: &LocalBackend{
e: eng,
pm: pm,
store: pm.Store(),
// configure as an app connector just to enable the API.
appConnector: a,
},
}
sys.Set(pm.Store())
sys.Set(eng)
b := newTestLocalBackendWithSys(t, sys)
b.pm = pm
b.appConnector = a // configure as an app connector just to enable the API.
h.ps = &peerAPIServer{b: b}
h.ps.resolver = &fakeResolver{build: func(b *dnsmessage.Builder) {
b.CNAMEResource(
dnsmessage.ResourceHeader{
@@ -326,27 +323,29 @@ func TestPeerAPIReplyToDNSQueriesAreObserved(t *testing.T) {
var h peerAPIHandler
h.remoteAddr = netip.MustParseAddrPort("100.150.151.152:12345")
bus := eventbus.New()
defer bus.Close()
sys := tsd.NewSystem()
t.Cleanup(sys.Bus.Get().Close)
rc := &appctest.RouteCollector{}
ht := new(health.Tracker)
reg := new(usermetric.Registry)
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, bus)
pm := must.Get(newProfileManager(new(mem.Store), t.Logf, ht))
reg := new(usermetric.Registry)
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, sys.Bus.Get(), sys.Set)
var a *appc.AppConnector
if shouldStore {
a = appc.NewAppConnector(t.Logf, rc, &appc.RouteInfo{}, fakeStoreRoutes)
} else {
a = appc.NewAppConnector(t.Logf, rc, nil, nil)
}
h.ps = &peerAPIServer{
b: &LocalBackend{
e: eng,
pm: pm,
store: pm.Store(),
appConnector: a,
},
}
sys.Set(pm.Store())
sys.Set(eng)
b := newTestLocalBackendWithSys(t, sys)
b.pm = pm
b.appConnector = a
h.ps = &peerAPIServer{b: b}
h.ps.b.appConnector.UpdateDomains([]string{"example.com"})
h.ps.b.appConnector.Wait(ctx)
@@ -393,12 +392,13 @@ func TestPeerAPIReplyToDNSQueriesAreObservedWithCNAMEFlattening(t *testing.T) {
var h peerAPIHandler
h.remoteAddr = netip.MustParseAddrPort("100.150.151.152:12345")
bus := eventbus.New()
defer bus.Close()
sys := tsd.NewSystem()
t.Cleanup(sys.Bus.Get().Close)
ht := new(health.Tracker)
reg := new(usermetric.Registry)
rc := &appctest.RouteCollector{}
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, bus)
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, sys.Bus.Get(), sys.Set)
pm := must.Get(newProfileManager(new(mem.Store), t.Logf, ht))
var a *appc.AppConnector
if shouldStore {
@@ -406,14 +406,14 @@ func TestPeerAPIReplyToDNSQueriesAreObservedWithCNAMEFlattening(t *testing.T) {
} else {
a = appc.NewAppConnector(t.Logf, rc, nil, nil)
}
h.ps = &peerAPIServer{
b: &LocalBackend{
e: eng,
pm: pm,
store: pm.Store(),
appConnector: a,
},
}
sys.Set(pm.Store())
sys.Set(eng)
b := newTestLocalBackendWithSys(t, sys)
b.pm = pm
b.appConnector = a
h.ps = &peerAPIServer{b: b}
h.ps.b.appConnector.UpdateDomains([]string{"www.example.com"})
h.ps.b.appConnector.Wait(ctx)