db: migrate tests from check.v1 to testify

Migrate all database tests from gopkg.in/check.v1 Suite-based testing
to standard Go tests with testify assert/require.

Changes:
- Remove empty Suite files (hscontrol/suite_test.go, hscontrol/mapper/suite_test.go)
- Convert hscontrol/db/suite_test.go to modern helpers only
- Convert 6 Suite test methods in node_test.go to standalone tests
- Convert 5 Suite test methods in api_key_test.go to standalone tests
- Fix stale global variable reference in db_test.go

The legacy TestListPeers Suite method was renamed to TestListPeersManyNodes
to avoid conflict with the existing modern TestListPeers function, as they
test different aspects (basic peer listing vs ID filtering).
This commit is contained in:
Kristoffer Dalby 2026-01-16 16:32:36 +00:00
parent d9cbb96603
commit 424e26d636
6 changed files with 118 additions and 199 deletions

View file

@ -9,89 +9,103 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"gopkg.in/check.v1"
) )
func (*Suite) TestCreateAPIKey(c *check.C) { func TestCreateAPIKey(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
apiKeyStr, apiKey, err := db.CreateAPIKey(nil) apiKeyStr, apiKey, err := db.CreateAPIKey(nil)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(apiKey, check.NotNil) require.NotNil(t, apiKey)
// Did we get a valid key? // Did we get a valid key?
c.Assert(apiKey.Prefix, check.NotNil) assert.NotNil(t, apiKey.Prefix)
c.Assert(apiKey.Hash, check.NotNil) assert.NotNil(t, apiKey.Hash)
c.Assert(apiKeyStr, check.Not(check.Equals), "") assert.NotEmpty(t, apiKeyStr)
_, err = db.ListAPIKeys() _, err = db.ListAPIKeys()
c.Assert(err, check.IsNil) require.NoError(t, err)
keys, err := db.ListAPIKeys() keys, err := db.ListAPIKeys()
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(len(keys), check.Equals, 1) assert.Len(t, keys, 1)
} }
func (*Suite) TestAPIKeyDoesNotExist(c *check.C) { func TestAPIKeyDoesNotExist(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
key, err := db.GetAPIKey("does-not-exist") key, err := db.GetAPIKey("does-not-exist")
c.Assert(err, check.NotNil) require.Error(t, err)
c.Assert(key, check.IsNil) assert.Nil(t, key)
} }
func (*Suite) TestValidateAPIKeyOk(c *check.C) { func TestValidateAPIKeyOk(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
nowPlus2 := time.Now().Add(2 * time.Hour) nowPlus2 := time.Now().Add(2 * time.Hour)
apiKeyStr, apiKey, err := db.CreateAPIKey(&nowPlus2) apiKeyStr, apiKey, err := db.CreateAPIKey(&nowPlus2)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(apiKey, check.NotNil) require.NotNil(t, apiKey)
valid, err := db.ValidateAPIKey(apiKeyStr) valid, err := db.ValidateAPIKey(apiKeyStr)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(valid, check.Equals, true) assert.True(t, valid)
} }
func (*Suite) TestValidateAPIKeyNotOk(c *check.C) { func TestValidateAPIKeyNotOk(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
nowMinus2 := time.Now().Add(time.Duration(-2) * time.Hour) nowMinus2 := time.Now().Add(time.Duration(-2) * time.Hour)
apiKeyStr, apiKey, err := db.CreateAPIKey(&nowMinus2) apiKeyStr, apiKey, err := db.CreateAPIKey(&nowMinus2)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(apiKey, check.NotNil) require.NotNil(t, apiKey)
valid, err := db.ValidateAPIKey(apiKeyStr) valid, err := db.ValidateAPIKey(apiKeyStr)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(valid, check.Equals, false) assert.False(t, valid)
now := time.Now() now := time.Now()
apiKeyStrNow, apiKey, err := db.CreateAPIKey(&now) apiKeyStrNow, apiKey, err := db.CreateAPIKey(&now)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(apiKey, check.NotNil) require.NotNil(t, apiKey)
validNow, err := db.ValidateAPIKey(apiKeyStrNow) validNow, err := db.ValidateAPIKey(apiKeyStrNow)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(validNow, check.Equals, false) assert.False(t, validNow)
validSilly, err := db.ValidateAPIKey("nota.validkey") validSilly, err := db.ValidateAPIKey("nota.validkey")
c.Assert(err, check.NotNil) require.Error(t, err)
c.Assert(validSilly, check.Equals, false) assert.False(t, validSilly)
validWithErr, err := db.ValidateAPIKey("produceerrorkey") validWithErr, err := db.ValidateAPIKey("produceerrorkey")
c.Assert(err, check.NotNil) require.Error(t, err)
c.Assert(validWithErr, check.Equals, false) assert.False(t, validWithErr)
} }
func (*Suite) TestExpireAPIKey(c *check.C) { func TestExpireAPIKey(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
nowPlus2 := time.Now().Add(2 * time.Hour) nowPlus2 := time.Now().Add(2 * time.Hour)
apiKeyStr, apiKey, err := db.CreateAPIKey(&nowPlus2) apiKeyStr, apiKey, err := db.CreateAPIKey(&nowPlus2)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(apiKey, check.NotNil) require.NotNil(t, apiKey)
valid, err := db.ValidateAPIKey(apiKeyStr) valid, err := db.ValidateAPIKey(apiKeyStr)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(valid, check.Equals, true) assert.True(t, valid)
err = db.ExpireAPIKey(apiKey) err = db.ExpireAPIKey(apiKey)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(apiKey.Expiration, check.NotNil) assert.NotNil(t, apiKey.Expiration)
notValid, err := db.ValidateAPIKey(apiKeyStr) notValid, err := db.ValidateAPIKey(apiKeyStr)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(notValid, check.Equals, false) assert.False(t, notValid)
} }
func TestAPIKeyWithPrefix(t *testing.T) { func TestAPIKeyWithPrefix(t *testing.T) {

View file

@ -255,7 +255,7 @@ func TestPostgresMigrationAndDataValidation(t *testing.T) {
t.Fatalf("failed to restore postgres database: %s", err) t.Fatalf("failed to restore postgres database: %s", err)
} }
db = newHeadscaleDBFromPostgresURL(t, u) db := newHeadscaleDBFromPostgresURL(t, u)
if tt.wantFunc != nil { if tt.wantFunc != nil {
tt.wantFunc(t, db) tt.wantFunc(t, db)

View file

@ -18,7 +18,6 @@ import (
"github.com/juanfont/headscale/hscontrol/util" "github.com/juanfont/headscale/hscontrol/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gopkg.in/check.v1"
"gorm.io/gorm" "gorm.io/gorm"
"tailscale.com/net/tsaddr" "tailscale.com/net/tsaddr"
"tailscale.com/tailcfg" "tailscale.com/tailcfg"
@ -26,70 +25,85 @@ import (
"tailscale.com/types/ptr" "tailscale.com/types/ptr"
) )
func (s *Suite) TestGetNode(c *check.C) { func TestGetNode(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
user := db.CreateUserForTest("test") user := db.CreateUserForTest("test")
_, err := db.getNode(types.UserID(user.ID), "testnode") _, err = db.getNode(types.UserID(user.ID), "testnode")
c.Assert(err, check.NotNil) require.Error(t, err)
node := db.CreateNodeForTest(user, "testnode") node := db.CreateNodeForTest(user, "testnode")
_, err = db.getNode(types.UserID(user.ID), "testnode") _, err = db.getNode(types.UserID(user.ID), "testnode")
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(node.Hostname, check.Equals, "testnode") assert.Equal(t, "testnode", node.Hostname)
} }
func (s *Suite) TestGetNodeByID(c *check.C) { func TestGetNodeByID(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
user := db.CreateUserForTest("test") user := db.CreateUserForTest("test")
_, err := db.GetNodeByID(0) _, err = db.GetNodeByID(0)
c.Assert(err, check.NotNil) require.Error(t, err)
node := db.CreateNodeForTest(user, "testnode") node := db.CreateNodeForTest(user, "testnode")
retrievedNode, err := db.GetNodeByID(node.ID) retrievedNode, err := db.GetNodeByID(node.ID)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(retrievedNode.Hostname, check.Equals, "testnode") assert.Equal(t, "testnode", retrievedNode.Hostname)
} }
func (s *Suite) TestHardDeleteNode(c *check.C) { func TestHardDeleteNode(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
user := db.CreateUserForTest("test") user := db.CreateUserForTest("test")
node := db.CreateNodeForTest(user, "testnode3") node := db.CreateNodeForTest(user, "testnode3")
err := db.DeleteNode(node) err = db.DeleteNode(node)
c.Assert(err, check.IsNil) require.NoError(t, err)
_, err = db.getNode(types.UserID(user.ID), "testnode3") _, err = db.getNode(types.UserID(user.ID), "testnode3")
c.Assert(err, check.NotNil) require.Error(t, err)
} }
func (s *Suite) TestListPeers(c *check.C) { func TestListPeersManyNodes(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
user := db.CreateUserForTest("test") user := db.CreateUserForTest("test")
_, err := db.GetNodeByID(0) _, err = db.GetNodeByID(0)
c.Assert(err, check.NotNil) require.Error(t, err)
nodes := db.CreateNodesForTest(user, 11, "testnode") nodes := db.CreateNodesForTest(user, 11, "testnode")
firstNode := nodes[0] firstNode := nodes[0]
peersOfFirstNode, err := db.ListPeers(firstNode.ID) peersOfFirstNode, err := db.ListPeers(firstNode.ID)
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(len(peersOfFirstNode), check.Equals, 10) assert.Len(t, peersOfFirstNode, 10)
c.Assert(peersOfFirstNode[0].Hostname, check.Equals, "testnode-1") assert.Equal(t, "testnode-1", peersOfFirstNode[0].Hostname)
c.Assert(peersOfFirstNode[5].Hostname, check.Equals, "testnode-6") assert.Equal(t, "testnode-6", peersOfFirstNode[5].Hostname)
c.Assert(peersOfFirstNode[9].Hostname, check.Equals, "testnode-10") assert.Equal(t, "testnode-10", peersOfFirstNode[9].Hostname)
} }
func (s *Suite) TestExpireNode(c *check.C) { func TestExpireNode(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
user, err := db.CreateUser(types.User{Name: "test"}) user, err := db.CreateUser(types.User{Name: "test"})
c.Assert(err, check.IsNil) require.NoError(t, err)
pak, err := db.CreatePreAuthKey(user.TypedID(), false, false, nil, nil) pak, err := db.CreatePreAuthKey(user.TypedID(), false, false, nil, nil)
c.Assert(err, check.IsNil) require.NoError(t, err)
_, err = db.getNode(types.UserID(user.ID), "testnode") _, err = db.getNode(types.UserID(user.ID), "testnode")
c.Assert(err, check.NotNil) require.Error(t, err)
nodeKey := key.NewNode() nodeKey := key.NewNode()
machineKey := key.NewMachine() machineKey := key.NewMachine()
@ -107,30 +121,33 @@ func (s *Suite) TestExpireNode(c *check.C) {
db.DB.Save(node) db.DB.Save(node)
nodeFromDB, err := db.getNode(types.UserID(user.ID), "testnode") nodeFromDB, err := db.getNode(types.UserID(user.ID), "testnode")
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(nodeFromDB, check.NotNil) require.NotNil(t, nodeFromDB)
c.Assert(nodeFromDB.IsExpired(), check.Equals, false) assert.False(t, nodeFromDB.IsExpired())
now := time.Now() now := time.Now()
err = db.NodeSetExpiry(nodeFromDB.ID, now) err = db.NodeSetExpiry(nodeFromDB.ID, now)
c.Assert(err, check.IsNil) require.NoError(t, err)
nodeFromDB, err = db.getNode(types.UserID(user.ID), "testnode") nodeFromDB, err = db.getNode(types.UserID(user.ID), "testnode")
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(nodeFromDB.IsExpired(), check.Equals, true) assert.True(t, nodeFromDB.IsExpired())
} }
func (s *Suite) TestSetTags(c *check.C) { func TestSetTags(t *testing.T) {
db, err := newSQLiteTestDB()
require.NoError(t, err)
user, err := db.CreateUser(types.User{Name: "test"}) user, err := db.CreateUser(types.User{Name: "test"})
c.Assert(err, check.IsNil) require.NoError(t, err)
pak, err := db.CreatePreAuthKey(user.TypedID(), false, false, nil, nil) pak, err := db.CreatePreAuthKey(user.TypedID(), false, false, nil, nil)
c.Assert(err, check.IsNil) require.NoError(t, err)
_, err = db.getNode(types.UserID(user.ID), "testnode") _, err = db.getNode(types.UserID(user.ID), "testnode")
c.Assert(err, check.NotNil) require.Error(t, err)
nodeKey := key.NewNode() nodeKey := key.NewNode()
machineKey := key.NewMachine() machineKey := key.NewMachine()
@ -146,27 +163,23 @@ func (s *Suite) TestSetTags(c *check.C) {
} }
trx := db.DB.Save(node) trx := db.DB.Save(node)
c.Assert(trx.Error, check.IsNil) require.NoError(t, trx.Error)
// assign simple tags // assign simple tags
sTags := []string{"tag:test", "tag:foo"} sTags := []string{"tag:test", "tag:foo"}
err = db.SetTags(node.ID, sTags) err = db.SetTags(node.ID, sTags)
c.Assert(err, check.IsNil) require.NoError(t, err)
node, err = db.getNode(types.UserID(user.ID), "testnode") node, err = db.getNode(types.UserID(user.ID), "testnode")
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert(node.Tags, check.DeepEquals, sTags) assert.Equal(t, sTags, node.Tags)
// assign duplicate tags, expect no errors but no doubles in DB // assign duplicate tags, expect no errors but no doubles in DB
eTags := []string{"tag:bar", "tag:test", "tag:unknown", "tag:test"} eTags := []string{"tag:bar", "tag:test", "tag:unknown", "tag:test"}
err = db.SetTags(node.ID, eTags) err = db.SetTags(node.ID, eTags)
c.Assert(err, check.IsNil) require.NoError(t, err)
node, err = db.getNode(types.UserID(user.ID), "testnode") node, err = db.getNode(types.UserID(user.ID), "testnode")
c.Assert(err, check.IsNil) require.NoError(t, err)
c.Assert( assert.Equal(t, []string{"tag:bar", "tag:test", "tag:unknown"}, node.Tags)
node.Tags,
check.DeepEquals,
[]string{"tag:bar", "tag:test", "tag:unknown"},
)
} }
func TestHeadscale_generateGivenName(t *testing.T) { func TestHeadscale_generateGivenName(t *testing.T) {

View file

@ -10,48 +10,11 @@ import (
"github.com/juanfont/headscale/hscontrol/types" "github.com/juanfont/headscale/hscontrol/types"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"gopkg.in/check.v1"
"zombiezen.com/go/postgrestest" "zombiezen.com/go/postgrestest"
) )
func Test(t *testing.T) {
check.TestingT(t)
}
var _ = check.Suite(&Suite{})
type Suite struct{}
var (
tmpDir string
db *HSDatabase
)
func (s *Suite) SetUpTest(c *check.C) {
s.ResetDB(c)
}
func (s *Suite) TearDownTest(c *check.C) {
// os.RemoveAll(tmpDir)
}
func (s *Suite) ResetDB(c *check.C) {
// if len(tmpDir) != 0 {
// os.RemoveAll(tmpDir)
// }
var err error
db, err = newSQLiteTestDB()
if err != nil {
c.Fatal(err)
}
}
// TODO(kradalby): make this a t.Helper when we dont depend
// on check test framework.
func newSQLiteTestDB() (*HSDatabase, error) { func newSQLiteTestDB() (*HSDatabase, error) {
var err error tmpDir, err := os.MkdirTemp("", "headscale-db-test-*")
tmpDir, err = os.MkdirTemp("", "headscale-db-test-*")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -59,7 +22,7 @@ func newSQLiteTestDB() (*HSDatabase, error) {
log.Printf("database path: %s", tmpDir+"/headscale_test.db") log.Printf("database path: %s", tmpDir+"/headscale_test.db")
zerolog.SetGlobalLevel(zerolog.Disabled) zerolog.SetGlobalLevel(zerolog.Disabled)
db, err = NewHeadscaleDatabase( db, err := NewHeadscaleDatabase(
types.DatabaseConfig{ types.DatabaseConfig{
Type: types.DatabaseSqlite, Type: types.DatabaseSqlite,
Sqlite: types.SqliteConfig{ Sqlite: types.SqliteConfig{

View file

@ -1,15 +0,0 @@
package mapper
import (
"testing"
"gopkg.in/check.v1"
)
func Test(t *testing.T) {
check.TestingT(t)
}
var _ = check.Suite(&Suite{})
type Suite struct{}

View file

@ -1,56 +0,0 @@
package hscontrol
import (
"os"
"testing"
"github.com/juanfont/headscale/hscontrol/types"
"gopkg.in/check.v1"
)
func Test(t *testing.T) {
check.TestingT(t)
}
var _ = check.Suite(&Suite{})
type Suite struct{}
var (
tmpDir string
app *Headscale
)
func (s *Suite) SetUpTest(c *check.C) {
s.ResetDB(c)
}
func (s *Suite) TearDownTest(c *check.C) {
os.RemoveAll(tmpDir)
}
func (s *Suite) ResetDB(c *check.C) {
if len(tmpDir) != 0 {
os.RemoveAll(tmpDir)
}
var err error
tmpDir, err = os.MkdirTemp("", "autoygg-client-test2")
if err != nil {
c.Fatal(err)
}
cfg := types.Config{
NoisePrivateKeyPath: tmpDir + "/noise_private.key",
Database: types.DatabaseConfig{
Type: "sqlite3",
Sqlite: types.SqliteConfig{
Path: tmpDir + "/headscale_test.db",
},
},
OIDC: types.OIDCConfig{},
}
app, err = NewHeadscale(&cfg)
if err != nil {
c.Fatal(err)
}
}