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.
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user