From 543e3b7b08c3d8c5c116eadc9556b00bf6fec3ee Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Mon, 19 Oct 2026 13:27:54 +0000 Subject: [PATCH] servertest: close server state during cleanup Release the NodeStore and database after clients and background workers stop. --- hscontrol/servertest/lifecycle_test.go | 10 ++++++++++ hscontrol/servertest/server.go | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/hscontrol/servertest/lifecycle_test.go b/hscontrol/servertest/lifecycle_test.go index b83bd1983..1ffa93abd 100644 --- a/hscontrol/servertest/lifecycle_test.go +++ b/hscontrol/servertest/lifecycle_test.go @@ -660,3 +660,13 @@ func describeNetmap(c *servertest.TestClient) string { return out.String() } + +func TestServerStateCleanup(t *testing.T) { + var srv *servertest.TestServer + + t.Run("server", func(t *testing.T) { srv = servertest.NewServer(t) }) + + database, err := srv.State().DB().DB.DB() + require.NoError(t, err) + require.ErrorContains(t, database.Ping(), "database is closed") +} diff --git a/hscontrol/servertest/server.go b/hscontrol/servertest/server.go index 329a57e56..1550d764b 100644 --- a/hscontrol/servertest/server.go +++ b/hscontrol/servertest/server.go @@ -203,6 +203,14 @@ func NewServer(tb testing.TB, opts ...ServerOption) *TestServer { tb.Fatalf("servertest: NewHeadscale: %v", err) } + // Registered first so clients, HTTP, and background subsystems stop first. + tb.Cleanup(func() { + err := app.GetState().Close() + if err != nil { + tb.Errorf("servertest: close state: %v", err) + } + }) + // Set a minimal DERP map so MapResponse generation works. app.GetState().SetDERPMap(&tailcfg.DERPMap{ Regions: map[tailcfg.DERPRegionID]*tailcfg.DERPRegion{