111 lines
2.6 KiB
Go
111 lines
2.6 KiB
Go
package config
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestLoadWithDefaults(t *testing.T) {
|
|
cfgPath := testConfigPath(t, "valid.toml")
|
|
|
|
cfg, err := Load(cfgPath)
|
|
if err != nil {
|
|
t.Fatalf("Load 返回错误: %v", err)
|
|
}
|
|
if cfg.Global.CacheTTL.DurationValue() == 0 {
|
|
t.Fatalf("CacheTTL 应该自动填充默认值")
|
|
}
|
|
if cfg.Global.StoragePath == "" {
|
|
t.Fatalf("StoragePath 应该被保留")
|
|
}
|
|
if cfg.Global.ListenPort == 0 {
|
|
t.Fatalf("ListenPort 应当被解析")
|
|
}
|
|
if cfg.EffectiveCacheTTL(cfg.Hubs[0]) != cfg.Global.CacheTTL.DurationValue() {
|
|
t.Fatalf("Hub 未设置 TTL 时应退回全局 TTL")
|
|
}
|
|
}
|
|
|
|
func TestValidateRejectsBadHub(t *testing.T) {
|
|
cfgPath := testConfigPath(t, "missing.toml")
|
|
|
|
if _, err := Load(cfgPath); err == nil {
|
|
t.Fatalf("不合法的配置应返回错误")
|
|
}
|
|
}
|
|
|
|
func TestEffectiveCacheTTLOverrides(t *testing.T) {
|
|
cfg := &Config{Global: GlobalConfig{CacheTTL: Duration(time.Hour)}}
|
|
hub := HubConfig{CacheTTL: Duration(2 * time.Hour)}
|
|
if ttl := cfg.EffectiveCacheTTL(hub); ttl != 2*time.Hour {
|
|
t.Fatalf("覆盖 TTL 应该优先生效")
|
|
}
|
|
}
|
|
|
|
func TestValidateEnforcesListenPortRange(t *testing.T) {
|
|
cfg := validConfig()
|
|
cfg.Global.ListenPort = 70000
|
|
if err := cfg.Validate(); err == nil {
|
|
t.Fatalf("ListenPort 超出范围应当报错")
|
|
}
|
|
}
|
|
|
|
func TestHubTypeValidation(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
hubType string
|
|
shouldErr bool
|
|
}{
|
|
{"docker ok", "docker", false},
|
|
{"npm ok", "npm", false},
|
|
{"go ok", "go", false},
|
|
{"pypi ok", "pypi", false},
|
|
{"missing type", "", true},
|
|
{"unsupported type", "rubygems", true},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
cfg := validConfig()
|
|
cfg.Hubs[0].Type = tc.hubType
|
|
err := cfg.Validate()
|
|
if tc.shouldErr && err == nil {
|
|
t.Fatalf("expected error for type %q", tc.hubType)
|
|
}
|
|
if !tc.shouldErr && err != nil {
|
|
t.Fatalf("unexpected error for type %q: %v", tc.hubType, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateRequiresCredentialPairs(t *testing.T) {
|
|
cfg := validConfig()
|
|
cfg.Hubs[0].Username = "foo"
|
|
if err := cfg.Validate(); err == nil {
|
|
t.Fatalf("仅提供 Username 时应报错")
|
|
}
|
|
}
|
|
|
|
func validConfig() *Config {
|
|
return &Config{
|
|
Global: GlobalConfig{
|
|
ListenPort: 5000,
|
|
StoragePath: "./data",
|
|
CacheTTL: Duration(time.Hour),
|
|
MaxMemoryCache: 1,
|
|
MaxRetries: 1,
|
|
InitialBackoff: Duration(time.Second),
|
|
UpstreamTimeout: Duration(time.Second),
|
|
},
|
|
Hubs: []HubConfig{
|
|
{
|
|
Name: "npm",
|
|
Domain: "npm.local",
|
|
Type: "npm",
|
|
Upstream: "https://registry.npmjs.org",
|
|
},
|
|
},
|
|
}
|
|
}
|