Files
x/config/parsing/auth/parse_test.go
T
ginuerzh 2b1e4ca3a7 test(parsing): add 229 unit tests across 18 config/parsing packages
Covering nil-input safety, plugin backends (HTTP/gRPC/default), loaders
(File/HTTP/Redis), selector strategies, edge cases (empty/invalid inputs),
and hop-to-node metadata inheritance. All tests passing.
2026-05-24 13:34:33 +08:00

243 lines
5.4 KiB
Go

package auth
import (
"io"
"testing"
"github.com/go-gost/core/logger"
"github.com/go-gost/x/config"
xlogger "github.com/go-gost/x/logger"
)
func TestMain(m *testing.M) {
logger.SetDefault(xlogger.NewLogger(xlogger.OutputOption(io.Discard)))
m.Run()
}
func TestInfo_Nil(t *testing.T) {
if u := Info(nil); u != nil {
t.Fatal("expected nil for nil config")
}
}
func TestInfo_EmptyUsername(t *testing.T) {
u := Info(&config.AuthConfig{Username: ""})
if u != nil {
t.Fatal("expected nil for empty username")
}
}
func TestInfo_UsernameOnly(t *testing.T) {
u := Info(&config.AuthConfig{Username: "user"})
if u == nil {
t.Fatal("expected non-nil userinfo")
}
if u.Username() != "user" {
t.Fatalf("username = %q, want %q", u.Username(), "user")
}
if _, hasPassword := u.Password(); hasPassword {
t.Fatal("expected no password")
}
}
func TestInfo_UsernameAndPassword(t *testing.T) {
u := Info(&config.AuthConfig{Username: "user", Password: "pass"})
if u == nil {
t.Fatal("expected non-nil userinfo")
}
if u.Username() != "user" {
t.Fatalf("username = %q, want %q", u.Username(), "user")
}
if p, ok := u.Password(); !ok || p != "pass" {
t.Fatalf("password = %q, want %q", p, "pass")
}
}
func TestInfo_WithFile(t *testing.T) {
// File that doesn't exist - should fall back to username
u := Info(&config.AuthConfig{
Username: "fallback",
Password: "pass",
File: "/nonexistent/auth_file",
})
if u == nil {
t.Fatal("expected non-nil userinfo (fallback)")
}
if u.Username() != "fallback" {
t.Fatalf("username = %q, want %q", u.Username(), "fallback")
}
}
func TestParseAutherFromAuth_Nil(t *testing.T) {
a := ParseAutherFromAuth(nil)
if a != nil {
t.Fatal("expected nil for nil auth config")
}
}
func TestParseAutherFromAuth_EmptyUsername(t *testing.T) {
a := ParseAutherFromAuth(&config.AuthConfig{Username: ""})
if a != nil {
t.Fatal("expected nil for empty username")
}
}
func TestParseAutherFromAuth_Valid(t *testing.T) {
a := ParseAutherFromAuth(&config.AuthConfig{
Username: "user",
Password: "pass",
})
if a == nil {
t.Fatal("expected non-nil authenticator")
}
}
func TestParseAuther_Nil(t *testing.T) {
a := ParseAuther(nil)
if a != nil {
t.Fatal("expected nil for nil config")
}
}
func TestParseAuther_WithUsers(t *testing.T) {
a := ParseAuther(&config.AutherConfig{
Name: "test-auth",
Auths: []*config.AuthConfig{
{Username: "u1", Password: "p1"},
{Username: "u2", Password: "p2"},
{Username: "", Password: "nope"}, // skipped
},
})
if a == nil {
t.Fatal("expected non-nil authenticator")
}
}
func TestParseAuther_WithEmptyAuths(t *testing.T) {
a := ParseAuther(&config.AutherConfig{
Name: "empty-auth",
Auths: []*config.AuthConfig{},
})
if a == nil {
t.Fatal("expected non-nil authenticator")
}
}
func TestParseAuther_PluginHTTP(t *testing.T) {
a := ParseAuther(&config.AutherConfig{
Name: "http-plugin",
Plugin: &config.PluginConfig{
Type: "http",
Addr: "127.0.0.1:9000",
},
})
if a == nil {
t.Fatal("expected non-nil plugin authenticator")
}
}
func TestParseAuther_PluginGRPC(t *testing.T) {
a := ParseAuther(&config.AutherConfig{
Name: "grpc-plugin",
Plugin: &config.PluginConfig{
Type: "grpc",
Addr: "127.0.0.1:9001",
Token: "secret",
TLS: &config.TLSConfig{
Secure: true,
ServerName: "auth.local",
},
},
})
if a == nil {
t.Fatal("expected non-nil plugin authenticator")
}
}
func TestParseAuther_PluginDefaultType(t *testing.T) {
// Default plugin type should be treated as gRPC
a := ParseAuther(&config.AutherConfig{
Name: "default-plugin",
Plugin: &config.PluginConfig{
Addr: "127.0.0.1:9002",
},
})
if a == nil {
t.Fatal("expected non-nil plugin authenticator")
}
}
func TestInfo_ParseFile(t *testing.T) {
// parseInfo with empty reader should return nil
u := Info(&config.AuthConfig{
File: "/nonexistent/file",
})
if u != nil {
t.Fatal("expected nil for nonexistent file (should not crash)")
}
}
func TestList_ReturnsEntries(t *testing.T) {
// The registry returns a lazy wrapper for any non-empty name.
got := List("test-auther", "test-auther-2")
if len(got) != 2 {
t.Fatalf("expected 2 entries, got %d", len(got))
}
}
func TestList_EmptyNameReturnsNothing(t *testing.T) {
// Empty names are filtered by the registry Get.
got := List("")
if len(got) != 0 {
t.Fatal("expected empty list for empty name")
}
}
func TestParseAuther_HTTPLoader(t *testing.T) {
a := ParseAuther(&config.AutherConfig{
Name: "http-loader-auth",
HTTP: &config.HTTPLoader{
URL: "http://localhost:8080/auth",
},
})
if a == nil {
t.Fatal("expected non-nil authenticator")
}
}
func TestParseAuther_FileLoader(t *testing.T) {
a := ParseAuther(&config.AutherConfig{
Name: "file-loader-auth",
File: &config.FileLoader{
Path: "/tmp/auth.txt",
},
})
if a == nil {
t.Fatal("expected non-nil authenticator")
}
}
func TestParseAuther_RedisLoader(t *testing.T) {
a := ParseAuther(&config.AutherConfig{
Name: "redis-loader-auth",
Redis: &config.RedisLoader{
Addr: "127.0.0.1:6379",
},
})
if a == nil {
t.Fatal("expected non-nil authenticator")
}
}
func TestInfo_Integration(t *testing.T) {
// Verify Info returns *url.Userinfo whose String() matches the standard library.
u := Info(&config.AuthConfig{Username: "alice", Password: "secret"})
if u == nil {
t.Fatal("expected non-nil")
}
want := "alice:secret"
if u.String() != want {
t.Fatalf("String() = %q, want %q", u.String(), want)
}
}