Files
netbird/client/internal/routemanager/server/server_test.go

67 lines
1.8 KiB
Go

package server
import (
"context"
"net/netip"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
firewall "github.com/netbirdio/netbird/client/firewall/manager"
"github.com/netbirdio/netbird/client/internal/peer"
"github.com/netbirdio/netbird/route"
)
// routingFirewall records the routing lifecycle calls the router makes. The
// embedded interface covers the methods this test never reaches.
type routingFirewall struct {
firewall.Manager
removed []firewall.RouterPair
enabled int
disabled int
}
func (f *routingFirewall) RemoveNatRule(pair firewall.RouterPair) error {
f.removed = append(f.removed, pair)
return nil
}
func (f *routingFirewall) EnableRouting() error {
f.enabled++
return nil
}
func (f *routingFirewall) DisableRouting() error {
f.disabled++
return nil
}
// TestRouterCleanUpReleasesRouting covers the shutdown path: the router holds a
// routing reference for as long as it serves routes, and CleanUp has to give it
// back. Without that the sysctls the reference enabled (IPv6 forwarding and the
// accept_ra values that keep RA handling working alongside it) stay applied
// after the client stops, leaving the host configured as a router.
func TestRouterCleanUpReleasesRouting(t *testing.T) {
fw := &routingFirewall{}
r := &Router{
ctx: context.Background(),
firewall: fw,
statusRecorder: peer.NewRecorder("https://mgm"),
routes: map[route.ID]*route.Route{
"route-1": {
ID: "route-1",
Network: netip.MustParsePrefix("192.168.55.0/24"),
NetworkType: route.IPv4Network,
Masquerade: true,
},
},
}
r.CleanUp()
require.Len(t, fw.removed, 1, "the route's NAT rule must be removed")
assert.Equal(t, 1, fw.disabled, "CleanUp must release the routing reference")
}