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官方驱动进行测试
|
// 可选:如果使用MongoDB官方驱动进行测试
|
||||||
// replace github.com/mongodb/mongo-go-driver => github.com/mongodb/mongo-go-driver/v2 v2.0.0
|
// 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/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