add config
Path: .git/config [core] repositoryformatversion = 0 filemode = true bare = false
This commit is contained in:
parent
41e4973850
commit
651256a0c2
|
@ -0,0 +1,91 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"encoding/json"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// Config 系统配置结构体
|
||||
type Config struct {
|
||||
Server ServerConfig `yaml:"server" json:"server"`
|
||||
Storage StorageConfig `yaml:"storage" json:"storage"`
|
||||
}
|
||||
|
||||
// ServerConfig 服务器配置
|
||||
type ServerConfig struct {
|
||||
Host string `yaml:"host" json:"host"`
|
||||
Port int `yaml:"port" json:"port"`
|
||||
}
|
||||
|
||||
// StorageConfig 存储配置
|
||||
type StorageConfig struct {
|
||||
Engine string `yaml:"engine" json:"engine"`
|
||||
DataPath string `yaml:"dataPath" json:"dataPath"`
|
||||
}
|
||||
|
||||
var (
|
||||
configInstance *Config
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
// NewDefaultConfig 创建默认配置
|
||||
func NewDefaultConfig() *Config {
|
||||
return &Config{
|
||||
Server: ServerConfig{
|
||||
Host: "0.0.0.0",
|
||||
Port: 27017,
|
||||
},
|
||||
Storage: StorageConfig{
|
||||
Engine: "memory",
|
||||
DataPath: "/var/lib/goaidb",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ParseConfig 解析配置文件
|
||||
// 支持JSON和YAML格式
|
||||
// 返回解析后的配置对象和错误信息
|
||||
func ParseConfig(filePath string) (*Config, error) {
|
||||
// 检查文件是否存在
|
||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("配置文件不存在: %s", filePath)
|
||||
}
|
||||
|
||||
// 读取文件内容
|
||||
data, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取配置文件失败: %v", err)
|
||||
}
|
||||
|
||||
// 根据文件扩展名选择解析方式
|
||||
var cfg Config
|
||||
switch filepath.Ext(filePath) {
|
||||
case ".json":
|
||||
if err := json.Unmarshal(data, &cfg); err != nil {
|
||||
return nil, fmt.Errorf("JSON解析失败: %v", err)
|
||||
}
|
||||
case ".yaml", ".yml":
|
||||
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
||||
return nil, fmt.Errorf("YAML解析失败: %v", err)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("不支持的配置文件格式")
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// GetConfig 获取全局配置实例
|
||||
func GetConfig() *Config {
|
||||
once.Do(func() {
|
||||
configInstance = NewDefaultConfig()
|
||||
})
|
||||
return configInstance
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseConfig_JSON(t *testing.T) {
|
||||
// 创建临时JSON配置文件
|
||||
tmpFile, err := os.CreateTemp("", "*.json")
|
||||
assert.NoError(t, err)
|
||||
defer os.Remove(tmpFile.Name())
|
||||
|
||||
// 写入测试配置内容
|
||||
testConfig := `{
|
||||
"server": {
|
||||
"host": "127.0.0.1",
|
||||
"port": 8080
|
||||
},
|
||||
"storage": {
|
||||
"engine": "rocksdb",
|
||||
"dataPath": "/test/data"
|
||||
}
|
||||
}`
|
||||
|
||||
_, err = tmpFile.WriteString(testConfig)
|
||||
assert.NoError(t, err)
|
||||
tmpFile.Close()
|
||||
|
||||
// 测试解析功能
|
||||
cfg, err := ParseConfig(tmpFile.Name())
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, cfg)
|
||||
assert.Equal(t, "127.0.0.1", cfg.Server.Host)
|
||||
assert.Equal(t, 8080, cfg.Server.Port)
|
||||
assert.Equal(t, "rocksdb", cfg.Storage.Engine)
|
||||
assert.Equal(t, "/test/data", cfg.Storage.DataPath)
|
||||
}
|
||||
|
||||
func TestParseConfig_YAML(t *testing.T) {
|
||||
// 创建临时YAML配置文件
|
||||
tmpFile, err := os.CreateTemp("", "*.yaml")
|
||||
assert.NoError(t, err)
|
||||
defer os.Remove(tmpFile.Name())
|
||||
|
||||
// 写入测试配置内容
|
||||
testConfig := `server:
|
||||
host: 127.0.0.1
|
||||
port: 8080
|
||||
storage:
|
||||
engine: rocksdb
|
||||
dataPath: /test/data`
|
||||
|
||||
_, err = tmpFile.WriteString(testConfig)
|
||||
assert.NoError(t, err)
|
||||
tmpFile.Close()
|
||||
|
||||
// 测试解析功能
|
||||
cfg, err := ParseConfig(tmpFile.Name())
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, cfg)
|
||||
assert.Equal(t, "127.0.0.1", cfg.Server.Host)
|
||||
assert.Equal(t, 8080, cfg.Server.Port)
|
||||
assert.Equal(t, "rocksdb", cfg.Storage.Engine)
|
||||
assert.Equal(t, "/test/data", cfg.Storage.DataPath)
|
||||
}
|
||||
|
||||
func TestParseConfig_Default(t *testing.T) {
|
||||
// 测试默认配置
|
||||
cfg := GetConfig()
|
||||
assert.NotNil(t, cfg)
|
||||
assert.Equal(t, "0.0.0.0", cfg.Server.Host)
|
||||
assert.Equal(t, 27017, cfg.Server.Port)
|
||||
assert.Equal(t, "memory", cfg.Storage.Engine)
|
||||
assert.Equal(t, "/var/lib/goaidb", cfg.Storage.DataPath)
|
||||
}
|
||||
|
||||
func TestParseConfig_InvalidFormat(t *testing.T) {
|
||||
// 创建临时无效格式配置文件
|
||||
tmpFile, err := os.CreateTemp("", "*.txt")
|
||||
assert.NoError(t, err)
|
||||
defer os.Remove(tmpFile.Name())
|
||||
|
||||
// 写入任意内容
|
||||
_, err = tmpFile.WriteString("invalid config content")
|
||||
assert.NoError(t, err)
|
||||
tmpFile.Close()
|
||||
|
||||
// 测试不支持的格式
|
||||
_, err = ParseConfig(tmpFile.Name())
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "不支持的配置文件格式")
|
||||
}
|
||||
|
||||
func TestParseConfig_FileNotFound(t *testing.T) {
|
||||
// 测试不存在的文件
|
||||
notExistFile := filepath.Join("not", "exist", "config.json")
|
||||
_, err := ParseConfig(notExistFile)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "配置文件不存在")
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
# 00000: 配置设计实现
|
||||
|
||||
## 目标
|
||||
|
||||
- 设计配置文件结构,并实现配置文件解析功能。
|
||||
- 配置文件需要支持json和yaml格式
|
||||
- 实现完整的单元测试覆盖
|
||||
|
||||
## 子任务分解
|
||||
- [x] 设计配置文件结构
|
||||
- [x] 实现配置文件解析功能
|
||||
- [x] 设计默认配置数据
|
||||
- [x] 实现全局方法获取指定配置项的值
|
||||
- [x] 实现JSON格式解析测试
|
||||
- [x] 实现YAML格式解析测试
|
||||
- [x] 实现默认配置测试
|
||||
- [x] 实现错误处理测试
|
||||
|
||||
## 完成状态
|
||||
✅ 已完成
|
8
go.mod
8
go.mod
|
@ -5,3 +5,11 @@ go 1.23
|
|||
// 可选:如果使用MongoDB官方驱动进行测试
|
||||
// replace github.com/mongodb/mongo-go-driver => github.com/mongodb/mongo-go-driver/v2 v2.0.0
|
||||
// require github.com/mongodb/mongo-go-driver/v2 v2.0.0
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
Loading…
Reference in New Issue