Files
tailscale/feature/relayserver/relayserver_test.go
M. J. Fromberger 3c32f87624 feature/relayserver: use eventbus.Monitor to simplify lifecycle management (#17234)
Instead of using separate channels to manage the lifecycle of the eventbus
client, use the recently-added eventbus.Monitor, which handles signaling the
processing loop to stop and waiting for it to complete.  This allows us to
simplify some of the setup and cleanup code in the relay server.

Updates #15160

Change-Id: Ia1a47ce2e5a31bc8f546dca4c56c3141a40d67af
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-10-02 09:18:55 -07:00

171 lines
4.2 KiB
Go

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package relayserver
import (
"testing"
"tailscale.com/ipn"
"tailscale.com/tsd"
"tailscale.com/types/ptr"
"tailscale.com/util/eventbus"
)
func Test_extension_profileStateChanged(t *testing.T) {
prefsWithPortOne := ipn.Prefs{RelayServerPort: ptr.To(1)}
prefsWithNilPort := ipn.Prefs{RelayServerPort: nil}
type fields struct {
port *int
}
type args struct {
prefs ipn.PrefsView
sameNode bool
}
tests := []struct {
name string
fields fields
args args
wantPort *int
wantBusRunning bool
}{
{
name: "no changes non-nil port",
fields: fields{
port: ptr.To(1),
},
args: args{
prefs: prefsWithPortOne.View(),
sameNode: true,
},
wantPort: ptr.To(1),
wantBusRunning: true,
},
{
name: "prefs port nil",
fields: fields{
port: ptr.To(1),
},
args: args{
prefs: prefsWithNilPort.View(),
sameNode: true,
},
wantPort: nil,
wantBusRunning: false,
},
{
name: "prefs port changed",
fields: fields{
port: ptr.To(2),
},
args: args{
prefs: prefsWithPortOne.View(),
sameNode: true,
},
wantPort: ptr.To(1),
wantBusRunning: true,
},
{
name: "sameNode false",
fields: fields{
port: ptr.To(1),
},
args: args{
prefs: prefsWithPortOne.View(),
sameNode: false,
},
wantPort: ptr.To(1),
wantBusRunning: true,
},
{
name: "prefs port non-nil extension port nil",
fields: fields{
port: nil,
},
args: args{
prefs: prefsWithPortOne.View(),
sameNode: false,
},
wantPort: ptr.To(1),
wantBusRunning: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sys := tsd.NewSystem()
bus := sys.Bus.Get()
e := &extension{
port: tt.fields.port,
bus: bus,
}
defer e.disconnectFromBusLocked()
e.profileStateChanged(ipn.LoginProfileView{}, tt.args.prefs, tt.args.sameNode)
if tt.wantBusRunning != (e.eventSubs != nil) {
t.Errorf("wantBusRunning: %v != (e.eventSubs != nil): %v", tt.wantBusRunning, e.eventSubs != nil)
}
if (tt.wantPort == nil) != (e.port == nil) {
t.Errorf("(tt.wantPort == nil): %v != (e.port == nil): %v", tt.wantPort == nil, e.port == nil)
} else if tt.wantPort != nil && *tt.wantPort != *e.port {
t.Errorf("wantPort: %d != *e.port: %d", *tt.wantPort, *e.port)
}
})
}
}
func Test_extension_handleBusLifetimeLocked(t *testing.T) {
tests := []struct {
name string
shutdown bool
port *int
eventSubs *eventbus.Monitor
hasNodeAttrDisableRelayServer bool
wantBusRunning bool
}{
{
name: "want running",
shutdown: false,
port: ptr.To(1),
hasNodeAttrDisableRelayServer: false,
wantBusRunning: true,
},
{
name: "shutdown true",
shutdown: true,
port: ptr.To(1),
hasNodeAttrDisableRelayServer: false,
wantBusRunning: false,
},
{
name: "port nil",
shutdown: false,
port: nil,
hasNodeAttrDisableRelayServer: false,
wantBusRunning: false,
},
{
name: "hasNodeAttrDisableRelayServer true",
shutdown: false,
port: nil,
hasNodeAttrDisableRelayServer: true,
wantBusRunning: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &extension{
bus: eventbus.New(),
shutdown: tt.shutdown,
port: tt.port,
eventSubs: tt.eventSubs,
hasNodeAttrDisableRelayServer: tt.hasNodeAttrDisableRelayServer,
}
e.handleBusLifetimeLocked()
defer e.disconnectFromBusLocked()
if tt.wantBusRunning != (e.eventSubs != nil) {
t.Errorf("wantBusRunning: %v != (e.eventSubs != nil): %v", tt.wantBusRunning, e.eventSubs != nil)
}
})
}
}