Some checks failed
CI/CD Pipeline / Test (push) Failing after 22m19s
CI/CD Pipeline / Security Scan (push) Failing after 5m57s
CI/CD Pipeline / Build (amd64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (amd64, linux) (push) Has been skipped
CI/CD Pipeline / Build (amd64, windows) (push) Has been skipped
CI/CD Pipeline / Build (arm64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (arm64, linux) (push) Has been skipped
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Create Release (push) Has been skipped
364 lines
11 KiB
Go
364 lines
11 KiB
Go
package unit
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/smartystreets/goconvey/convey"
|
|
"github.com/subconverter-go/internal/config"
|
|
)
|
|
|
|
// TestConfigManagerCreation 测试配置管理器创建
|
|
func TestConfigManagerCreation(t *testing.T) {
|
|
convey.Convey("配置管理器创建测试", t, func() {
|
|
convey.Convey("创建默认配置管理器", func() {
|
|
manager, err := config.NewConfigManager("")
|
|
convey.So(err, convey.ShouldBeNil)
|
|
convey.So(manager, convey.ShouldNotBeNil)
|
|
|
|
// 验证默认配置
|
|
cfg := manager.GetConfig()
|
|
convey.So(cfg, convey.ShouldNotBeNil)
|
|
convey.So(cfg.Server.Host, convey.ShouldEqual, "0.0.0.0")
|
|
convey.So(cfg.Server.Port, convey.ShouldEqual, 25500)
|
|
convey.So(cfg.Logging.Level, convey.ShouldEqual, "info")
|
|
convey.So(cfg.Conversion.DefaultTarget, convey.ShouldEqual, "clash")
|
|
|
|
// 清理
|
|
manager.Close()
|
|
})
|
|
|
|
convey.Convey("创建带配置文件的配置管理器", func() {
|
|
// 创建临时配置文件
|
|
tempDir := t.TempDir()
|
|
configFile := filepath.Join(tempDir, "test.yaml")
|
|
configContent := `
|
|
server:
|
|
host: "127.0.0.1"
|
|
port: 8080
|
|
logging:
|
|
level: "debug"
|
|
format: "json"
|
|
security:
|
|
access_tokens: ["test-token"]
|
|
`
|
|
|
|
err := os.WriteFile(configFile, []byte(configContent), 0644)
|
|
convey.So(err, convey.ShouldBeNil)
|
|
|
|
// 创建配置管理器
|
|
manager, err := config.NewConfigManager(configFile)
|
|
convey.So(err, convey.ShouldBeNil)
|
|
convey.So(manager, convey.ShouldNotBeNil)
|
|
|
|
// 验证配置
|
|
cfg := manager.GetConfig()
|
|
convey.So(cfg.Server.Host, convey.ShouldEqual, "127.0.0.1")
|
|
convey.So(cfg.Server.Port, convey.ShouldEqual, 8080)
|
|
convey.So(cfg.Logging.Level, convey.ShouldEqual, "debug")
|
|
convey.So(len(cfg.Security.AccessTokens), convey.ShouldEqual, 1)
|
|
convey.So(cfg.Security.AccessTokens[0], convey.ShouldEqual, "test-token")
|
|
|
|
// 清理
|
|
manager.Close()
|
|
})
|
|
})
|
|
}
|
|
|
|
// TestConfigManagerDefaults 测试默认配置
|
|
func TestConfigManagerDefaults(t *testing.T) {
|
|
convey.Convey("默认配置测试", t, func() {
|
|
manager, err := config.NewConfigManager("")
|
|
convey.So(err, convey.ShouldBeNil)
|
|
defer manager.Close()
|
|
|
|
cfg := manager.GetConfig()
|
|
|
|
convey.Convey("服务器默认配置", func() {
|
|
convey.So(cfg.Server.Host, convey.ShouldEqual, "0.0.0.0")
|
|
convey.So(cfg.Server.Port, convey.ShouldEqual, 25500)
|
|
convey.So(cfg.Server.ReadTimeout, convey.ShouldEqual, 30)
|
|
convey.So(cfg.Server.WriteTimeout, convey.ShouldEqual, 30)
|
|
convey.So(cfg.Server.MaxRequestSize, convey.ShouldEqual, 10*1024*1024)
|
|
})
|
|
|
|
convey.Convey("日志默认配置", func() {
|
|
convey.So(cfg.Logging.Level, convey.ShouldEqual, "info")
|
|
convey.So(cfg.Logging.Format, convey.ShouldEqual, "json")
|
|
convey.So(cfg.Logging.Output, convey.ShouldEqual, "stdout")
|
|
})
|
|
|
|
convey.Convey("安全默认配置", func() {
|
|
convey.So(len(cfg.Security.AccessTokens), convey.ShouldEqual, 0)
|
|
convey.So(len(cfg.Security.CorsOrigins), convey.ShouldEqual, 1)
|
|
convey.So(cfg.Security.CorsOrigins[0], convey.ShouldEqual, "*")
|
|
convey.So(cfg.Security.RateLimit, convey.ShouldEqual, 0)
|
|
convey.So(cfg.Security.Timeout, convey.ShouldEqual, 60)
|
|
})
|
|
|
|
convey.Convey("转换默认配置", func() {
|
|
convey.So(cfg.Conversion.DefaultTarget, convey.ShouldEqual, "clash")
|
|
convey.So(cfg.Conversion.DefaultEmoji, convey.ShouldBeFalse)
|
|
convey.So(cfg.Conversion.DefaultUDP, convey.ShouldBeFalse)
|
|
convey.So(cfg.Conversion.MaxNodes, convey.ShouldEqual, 0)
|
|
convey.So(cfg.Conversion.CacheTimeout, convey.ShouldEqual, 60)
|
|
})
|
|
})
|
|
}
|
|
|
|
// TestConfigManagerEnvironmentVariables 测试环境变量配置
|
|
func TestConfigManagerEnvironmentVariables(t *testing.T) {
|
|
convey.Convey("环境变量配置测试", t, func() {
|
|
// 设置环境变量
|
|
os.Setenv("SUBCONVERTER_HOST", "192.168.1.100")
|
|
os.Setenv("SUBCONVERTER_PORT", "9000")
|
|
os.Setenv("SUBCONVERTER_LOG_LEVEL", "debug")
|
|
os.Setenv("SUBCONVERTER_ACCESS_TOKENS", "test-token")
|
|
defer func() {
|
|
os.Unsetenv("SUBCONVERTER_HOST")
|
|
os.Unsetenv("SUBCONVERTER_PORT")
|
|
os.Unsetenv("SUBCONVERTER_LOG_LEVEL")
|
|
os.Unsetenv("SUBCONVERTER_ACCESS_TOKENS")
|
|
}()
|
|
|
|
manager, err := config.NewConfigManager("")
|
|
convey.So(err, convey.ShouldBeNil)
|
|
defer manager.Close()
|
|
|
|
cfg := manager.GetConfig()
|
|
|
|
convey.So(cfg.Server.Host, convey.ShouldEqual, "192.168.1.100")
|
|
convey.So(cfg.Server.Port, convey.ShouldEqual, 9000)
|
|
convey.So(cfg.Logging.Level, convey.ShouldEqual, "debug")
|
|
convey.So(len(cfg.Security.AccessTokens), convey.ShouldEqual, 1)
|
|
convey.So(cfg.Security.AccessTokens[0], convey.ShouldEqual, "test-token")
|
|
})
|
|
}
|
|
|
|
// TestConfigManagerUpdateConfig 测试配置更新
|
|
func TestConfigManagerUpdateConfig(t *testing.T) {
|
|
convey.Convey("配置更新测试", t, func() {
|
|
manager, err := config.NewConfigManager("")
|
|
convey.So(err, convey.ShouldBeNil)
|
|
defer manager.Close()
|
|
|
|
convey.Convey("更新配置", func() {
|
|
newConfig := manager.GetConfig().Clone()
|
|
newConfig.Server.Host = "127.0.0.1"
|
|
newConfig.Server.Port = 8080
|
|
newConfig.Logging.Level = "debug"
|
|
|
|
err := manager.UpdateConfig(newConfig)
|
|
convey.So(err, convey.ShouldBeNil)
|
|
|
|
// 验证配置已更新
|
|
updatedConfig := manager.GetConfig()
|
|
convey.So(updatedConfig.Server.Host, convey.ShouldEqual, "127.0.0.1")
|
|
convey.So(updatedConfig.Server.Port, convey.ShouldEqual, 8080)
|
|
convey.So(updatedConfig.Logging.Level, convey.ShouldEqual, "debug")
|
|
})
|
|
|
|
convey.Convey("无效配置处理", func() {
|
|
invalidConfig := manager.GetConfig().Clone()
|
|
invalidConfig.Server.Port = -1 // 无效端口
|
|
|
|
err := manager.UpdateConfig(invalidConfig)
|
|
convey.So(err, convey.ShouldNotBeNil)
|
|
convey.So(err.Error(), convey.ShouldContain, "invalid port")
|
|
})
|
|
})
|
|
}
|
|
|
|
// TestConfigManagerPartialAccess 测试配置部分访问
|
|
func TestConfigManagerPartialAccess(t *testing.T) {
|
|
convey.Convey("配置部分访问测试", t, func() {
|
|
manager, err := config.NewConfigManager("")
|
|
convey.So(err, convey.ShouldBeNil)
|
|
defer manager.Close()
|
|
|
|
convey.Convey("获取服务器配置", func() {
|
|
serverConfig := manager.GetServerConfig()
|
|
convey.So(serverConfig, convey.ShouldNotBeNil)
|
|
convey.So(serverConfig.Host, convey.ShouldEqual, "0.0.0.0")
|
|
convey.So(serverConfig.Port, convey.ShouldEqual, 25500)
|
|
|
|
// 修改返回的配置不应该影响原始配置
|
|
serverConfig.Host = "modified"
|
|
originalConfig := manager.GetConfig()
|
|
convey.So(originalConfig.Server.Host, convey.ShouldEqual, "0.0.0.0")
|
|
})
|
|
|
|
convey.Convey("获取日志配置", func() {
|
|
loggingConfig := manager.GetLoggingConfig()
|
|
convey.So(loggingConfig, convey.ShouldNotBeNil)
|
|
convey.So(loggingConfig.Level, convey.ShouldEqual, "info")
|
|
convey.So(loggingConfig.Format, convey.ShouldEqual, "json")
|
|
})
|
|
|
|
convey.Convey("获取安全配置", func() {
|
|
securityConfig := manager.GetSecurityConfig()
|
|
convey.So(securityConfig, convey.ShouldNotBeNil)
|
|
convey.So(len(securityConfig.AccessTokens), convey.ShouldEqual, 0)
|
|
convey.So(securityConfig.RateLimit, convey.ShouldEqual, 0)
|
|
})
|
|
|
|
convey.Convey("获取转换配置", func() {
|
|
conversionConfig := manager.GetConversionConfig()
|
|
convey.So(conversionConfig, convey.ShouldNotBeNil)
|
|
convey.So(conversionConfig.DefaultTarget, convey.ShouldEqual, "clash")
|
|
convey.So(conversionConfig.DefaultEmoji, convey.ShouldBeFalse)
|
|
})
|
|
})
|
|
}
|
|
|
|
// TestConfigManagerSaveConfig 测试配置保存
|
|
func TestConfigManagerSaveConfig(t *testing.T) {
|
|
convey.Convey("配置保存测试", t, func() {
|
|
tempDir := t.TempDir()
|
|
configFile := filepath.Join(tempDir, "test.yaml")
|
|
|
|
// 创建配置管理器
|
|
manager, err := config.NewConfigManager(configFile)
|
|
convey.So(err, convey.ShouldBeNil)
|
|
defer manager.Close()
|
|
|
|
convey.Convey("保存配置到文件", func() {
|
|
// 修改配置
|
|
newConfig := manager.GetConfig().Clone()
|
|
newConfig.Server.Host = "127.0.0.1"
|
|
newConfig.Server.Port = 9090
|
|
newConfig.Logging.Level = "debug"
|
|
|
|
err := manager.UpdateConfig(newConfig)
|
|
convey.So(err, convey.ShouldBeNil)
|
|
|
|
// 检查文件是否存在
|
|
_, err = os.Stat(configFile)
|
|
convey.So(err, convey.ShouldBeNil)
|
|
|
|
// 从文件重新加载配置验证
|
|
newManager, err := config.NewConfigManager(configFile)
|
|
convey.So(err, convey.ShouldBeNil)
|
|
defer newManager.Close()
|
|
|
|
loadedConfig := newManager.GetConfig()
|
|
convey.So(loadedConfig.Server.Host, convey.ShouldEqual, "127.0.0.1")
|
|
convey.So(loadedConfig.Server.Port, convey.ShouldEqual, 9090)
|
|
convey.So(loadedConfig.Logging.Level, convey.ShouldEqual, "debug")
|
|
})
|
|
})
|
|
}
|
|
|
|
// TestConfigManagerBasicAccess 测试基本配置访问
|
|
func TestConfigManagerBasicAccess(t *testing.T) {
|
|
convey.Convey("基本配置访问测试", t, func() {
|
|
manager, err := config.NewConfigManager("")
|
|
convey.So(err, convey.ShouldBeNil)
|
|
defer manager.Close()
|
|
|
|
convey.Convey("GetString方法", func() {
|
|
host := manager.GetString("server.host")
|
|
convey.So(host, convey.ShouldEqual, "0.0.0.0")
|
|
|
|
level := manager.GetString("logging.level")
|
|
convey.So(level, convey.ShouldEqual, "info")
|
|
})
|
|
|
|
convey.Convey("GetInt方法", func() {
|
|
port := manager.GetInt("server.port")
|
|
convey.So(port, convey.ShouldEqual, 25500)
|
|
|
|
timeout := manager.GetInt("conversion.timeout_seconds")
|
|
convey.So(timeout, convey.ShouldEqual, 30)
|
|
})
|
|
|
|
convey.Convey("GetBool方法", func() {
|
|
cors := manager.GetBool("server.enable_cors")
|
|
convey.So(cors, convey.ShouldBeTrue)
|
|
|
|
auth := manager.GetBool("security.enable_auth")
|
|
convey.So(auth, convey.ShouldBeFalse)
|
|
})
|
|
|
|
convey.Convey("GetStringSlice方法", func() {
|
|
formats := manager.GetStringSlice("conversion.supported_formats")
|
|
convey.So(formats, convey.ShouldNotBeNil)
|
|
convey.So(len(formats) > 0, convey.ShouldBeTrue)
|
|
convey.So(formats, convey.ShouldContain, "clash")
|
|
})
|
|
|
|
convey.Convey("IsSet方法", func() {
|
|
convey.So(manager.IsSet("server.host"), convey.ShouldBeTrue)
|
|
convey.So(manager.IsSet("nonexistent.key"), convey.ShouldBeFalse)
|
|
})
|
|
|
|
convey.Convey("Set方法", func() {
|
|
manager.Set("test.key", "test_value")
|
|
value := manager.GetString("test.key")
|
|
convey.So(value, convey.ShouldEqual, "test_value")
|
|
})
|
|
})
|
|
}
|
|
|
|
// TestConfigManagerWatchConfig 测试配置监听
|
|
func TestConfigManagerWatchConfig(t *testing.T) {
|
|
convey.Convey("配置监听测试", t, func() {
|
|
tempDir := t.TempDir()
|
|
configFile := filepath.Join(tempDir, "test.yaml")
|
|
|
|
// 创建初始配置文件
|
|
configContent := `
|
|
server:
|
|
host: "0.0.0.0"
|
|
port: 25500
|
|
logging:
|
|
level: "info"
|
|
`
|
|
|
|
err := os.WriteFile(configFile, []byte(configContent), 0644)
|
|
convey.So(err, convey.ShouldBeNil)
|
|
|
|
// 创建配置管理器
|
|
manager, err := config.NewConfigManager(configFile)
|
|
convey.So(err, convey.ShouldBeNil)
|
|
defer manager.Close()
|
|
|
|
configChanged := make(chan bool, 1)
|
|
|
|
// 开始监听配置变化
|
|
manager.WatchConfig(func(cfg *config.Configuration) {
|
|
configChanged <- true
|
|
})
|
|
|
|
convey.Convey("监听配置文件变化", func() {
|
|
// 修改配置文件
|
|
newConfigContent := `
|
|
server:
|
|
host: "127.0.0.1"
|
|
port: 8080
|
|
logging:
|
|
level: "debug"
|
|
`
|
|
|
|
err := os.WriteFile(configFile, []byte(newConfigContent), 0644)
|
|
convey.So(err, convey.ShouldBeNil)
|
|
|
|
// 等待配置变化事件
|
|
select {
|
|
case changed := <-configChanged:
|
|
convey.So(changed, convey.ShouldBeTrue)
|
|
|
|
// 验证配置已更新
|
|
updatedConfig := manager.GetConfig()
|
|
convey.So(updatedConfig.Server.Host, convey.ShouldEqual, "127.0.0.1")
|
|
convey.So(updatedConfig.Server.Port, convey.ShouldEqual, 8080)
|
|
convey.So(updatedConfig.Logging.Level, convey.ShouldEqual, "debug")
|
|
|
|
case <-time.After(2 * time.Second):
|
|
convey.So(false, convey.ShouldBeTrue) // 超时失败
|
|
}
|
|
})
|
|
})
|
|
} |