320 lines
7.9 KiB
Go
320 lines
7.9 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
func TestDefaultConfig(t *testing.T) {
|
|
cfg := DefaultConfig()
|
|
require.NotNil(t, cfg)
|
|
|
|
assert.Equal(t, 9826, cfg.Server.Port)
|
|
assert.Equal(t, 30*time.Second, cfg.Server.ReadTimeout)
|
|
assert.Equal(t, 30*time.Second, cfg.Server.WriteTimeout)
|
|
|
|
assert.Equal(t, "sqlite", cfg.Database.Driver)
|
|
assert.Equal(t, "", cfg.Database.Host)
|
|
assert.Equal(t, 3306, cfg.Database.Port)
|
|
assert.Equal(t, "", cfg.Database.User)
|
|
assert.Equal(t, "", cfg.Database.Password)
|
|
assert.Equal(t, "nex", cfg.Database.DBName)
|
|
assert.Equal(t, 10, cfg.Database.MaxIdleConns)
|
|
assert.Equal(t, 100, cfg.Database.MaxOpenConns)
|
|
assert.Equal(t, 1*time.Hour, cfg.Database.ConnMaxLifetime)
|
|
|
|
assert.Equal(t, "info", cfg.Log.Level)
|
|
assert.Equal(t, 100, cfg.Log.MaxSize)
|
|
assert.Equal(t, 10, cfg.Log.MaxBackups)
|
|
assert.Equal(t, 30, cfg.Log.MaxAge)
|
|
assert.Equal(t, true, cfg.Log.Compress)
|
|
}
|
|
|
|
func TestConfig_Validate(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
modify func(*Config)
|
|
wantErr bool
|
|
errMsg string
|
|
}{
|
|
{
|
|
name: "默认配置有效",
|
|
modify: func(c *Config) {},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "端口号为0无效",
|
|
modify: func(c *Config) { c.Server.Port = 0 },
|
|
wantErr: true,
|
|
errMsg: "配置验证失败",
|
|
},
|
|
{
|
|
name: "端口号超出范围无效",
|
|
modify: func(c *Config) { c.Server.Port = 70000 },
|
|
wantErr: true,
|
|
errMsg: "配置验证失败",
|
|
},
|
|
{
|
|
name: "端口号为1有效",
|
|
modify: func(c *Config) { c.Server.Port = 1 },
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "端口号为65535有效",
|
|
modify: func(c *Config) { c.Server.Port = 65535 },
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "无效日志级别",
|
|
modify: func(c *Config) { c.Log.Level = "invalid" },
|
|
wantErr: true,
|
|
errMsg: "配置验证失败",
|
|
},
|
|
{
|
|
name: "debug级别有效",
|
|
modify: func(c *Config) { c.Log.Level = "debug" },
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "warn级别有效",
|
|
modify: func(c *Config) { c.Log.Level = "warn" },
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "error级别有效",
|
|
modify: func(c *Config) { c.Log.Level = "error" },
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "SQLite模式路径为空无效",
|
|
modify: func(c *Config) { c.Database.Path = "" },
|
|
wantErr: true,
|
|
errMsg: "配置验证失败",
|
|
},
|
|
{
|
|
name: "driver值不合法",
|
|
modify: func(c *Config) { c.Database.Driver = "postgres" },
|
|
wantErr: true,
|
|
errMsg: "配置验证失败",
|
|
},
|
|
{
|
|
name: "MySQL配置有效",
|
|
modify: func(c *Config) {
|
|
c.Database.Driver = "mysql"
|
|
c.Database.Host = "localhost"
|
|
c.Database.Port = 3306
|
|
c.Database.User = "root"
|
|
c.Database.DBName = "nex"
|
|
c.Database.Path = ""
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "MySQL模式host为空无效",
|
|
modify: func(c *Config) {
|
|
c.Database.Driver = "mysql"
|
|
c.Database.Host = ""
|
|
c.Database.User = "root"
|
|
c.Database.DBName = "nex"
|
|
c.Database.Path = ""
|
|
},
|
|
wantErr: true,
|
|
errMsg: "配置验证失败",
|
|
},
|
|
{
|
|
name: "MySQL模式user为空无效",
|
|
modify: func(c *Config) {
|
|
c.Database.Driver = "mysql"
|
|
c.Database.Host = "localhost"
|
|
c.Database.User = ""
|
|
c.Database.DBName = "nex"
|
|
c.Database.Path = ""
|
|
},
|
|
wantErr: true,
|
|
errMsg: "配置验证失败",
|
|
},
|
|
{
|
|
name: "MySQL模式dbname为空无效",
|
|
modify: func(c *Config) {
|
|
c.Database.Driver = "mysql"
|
|
c.Database.Host = "localhost"
|
|
c.Database.User = "root"
|
|
c.Database.DBName = ""
|
|
c.Database.Path = ""
|
|
},
|
|
wantErr: true,
|
|
errMsg: "配置验证失败",
|
|
},
|
|
{
|
|
name: "MySQL模式忽略path字段",
|
|
modify: func(c *Config) {
|
|
c.Database.Driver = "mysql"
|
|
c.Database.Host = "localhost"
|
|
c.Database.User = "root"
|
|
c.Database.DBName = "nex"
|
|
c.Database.Path = ""
|
|
},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cfg := DefaultConfig()
|
|
tt.modify(cfg)
|
|
err := cfg.Validate()
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), tt.errMsg)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetConfigDir(t *testing.T) {
|
|
dir, err := GetConfigDir()
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, dir)
|
|
assert.Contains(t, dir, ".nex")
|
|
}
|
|
|
|
func TestGetDBPath(t *testing.T) {
|
|
path, err := GetDBPath()
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, path)
|
|
assert.Contains(t, path, "config.db")
|
|
}
|
|
|
|
func TestGetConfigPath(t *testing.T) {
|
|
path, err := GetConfigPath()
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, path)
|
|
assert.Contains(t, path, "config.yaml")
|
|
}
|
|
|
|
func TestSaveAndLoadConfig(t *testing.T) {
|
|
// 使用临时目录覆盖配置路径
|
|
dir := t.TempDir()
|
|
|
|
cfg := &Config{
|
|
Server: ServerConfig{
|
|
Port: 9999,
|
|
ReadTimeout: 10 * time.Second,
|
|
WriteTimeout: 20 * time.Second,
|
|
},
|
|
Database: DatabaseConfig{
|
|
Driver: "sqlite",
|
|
Path: filepath.Join(dir, "test.db"),
|
|
Port: 3306,
|
|
DBName: "nex",
|
|
MaxIdleConns: 5,
|
|
MaxOpenConns: 50,
|
|
ConnMaxLifetime: 30 * time.Minute,
|
|
},
|
|
Log: LogConfig{
|
|
Level: "debug",
|
|
Path: filepath.Join(dir, "log"),
|
|
MaxSize: 50,
|
|
MaxBackups: 5,
|
|
MaxAge: 7,
|
|
Compress: false,
|
|
},
|
|
}
|
|
|
|
// 保存配置
|
|
configPath := filepath.Join(dir, "config.yaml")
|
|
data, err := yaml.Marshal(cfg)
|
|
require.NoError(t, err)
|
|
err = os.WriteFile(configPath, data, 0644)
|
|
require.NoError(t, err)
|
|
|
|
// 加载配置
|
|
data, err = os.ReadFile(configPath)
|
|
require.NoError(t, err)
|
|
loaded := &Config{}
|
|
err = yaml.Unmarshal(data, loaded)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, cfg.Server.Port, loaded.Server.Port)
|
|
assert.Equal(t, cfg.Log.Level, loaded.Log.Level)
|
|
assert.Equal(t, cfg.Database.MaxIdleConns, loaded.Database.MaxIdleConns)
|
|
assert.Equal(t, cfg.Log.Compress, loaded.Log.Compress)
|
|
}
|
|
|
|
func TestCLIConfig(t *testing.T) {
|
|
// 测试 CLI 参数配置(简化版本)
|
|
// 注意:由于 flag.Parse 只能调用一次,这里只测试配置加载流程
|
|
t.Run("配置加载流程", func(t *testing.T) {
|
|
// 使用默认配置路径测试
|
|
cfg := DefaultConfig()
|
|
require.NotNil(t, cfg)
|
|
|
|
// 验证默认值正确
|
|
assert.Equal(t, 9826, cfg.Server.Port)
|
|
assert.Equal(t, "info", cfg.Log.Level)
|
|
})
|
|
}
|
|
|
|
func TestEnvConfig(t *testing.T) {
|
|
// 测试环境变量配置(简化版本)
|
|
t.Run("环境变量前缀", func(t *testing.T) {
|
|
// 验证环境变量前缀设置正确
|
|
// 实际的环境变量测试需要独立的进程,这里只验证配置结构
|
|
cfg := DefaultConfig()
|
|
require.NotNil(t, cfg)
|
|
assert.Equal(t, 9826, cfg.Server.Port)
|
|
})
|
|
}
|
|
|
|
func TestConfigPriority(t *testing.T) {
|
|
// 测试配置优先级(简化版本)
|
|
t.Run("默认值设置", func(t *testing.T) {
|
|
cfg := DefaultConfig()
|
|
require.NotNil(t, cfg)
|
|
|
|
// 验证所有默认值
|
|
assert.Equal(t, 9826, cfg.Server.Port)
|
|
assert.Equal(t, 30*time.Second, cfg.Server.ReadTimeout)
|
|
assert.Equal(t, 30*time.Second, cfg.Server.WriteTimeout)
|
|
assert.Equal(t, "sqlite", cfg.Database.Driver)
|
|
assert.Equal(t, 3306, cfg.Database.Port)
|
|
assert.Equal(t, "nex", cfg.Database.DBName)
|
|
assert.Equal(t, 10, cfg.Database.MaxIdleConns)
|
|
assert.Equal(t, 100, cfg.Database.MaxOpenConns)
|
|
assert.Equal(t, 1*time.Hour, cfg.Database.ConnMaxLifetime)
|
|
assert.Equal(t, "info", cfg.Log.Level)
|
|
assert.Equal(t, 100, cfg.Log.MaxSize)
|
|
assert.Equal(t, 10, cfg.Log.MaxBackups)
|
|
assert.Equal(t, 30, cfg.Log.MaxAge)
|
|
assert.Equal(t, true, cfg.Log.Compress)
|
|
})
|
|
}
|
|
|
|
func TestPrintSummary(t *testing.T) {
|
|
t.Run("SQLite模式摘要", func(t *testing.T) {
|
|
cfg := DefaultConfig()
|
|
assert.NotPanics(t, func() {
|
|
cfg.PrintSummary()
|
|
})
|
|
})
|
|
t.Run("MySQL模式摘要", func(t *testing.T) {
|
|
cfg := DefaultConfig()
|
|
cfg.Database.Driver = "mysql"
|
|
cfg.Database.Host = "db.example.com"
|
|
cfg.Database.Port = 3306
|
|
cfg.Database.User = "nex"
|
|
cfg.Database.DBName = "nex"
|
|
assert.NotPanics(t, func() {
|
|
cfg.PrintSummary()
|
|
})
|
|
})
|
|
}
|