package config import ( "errors" "reflect" "testing" "github.com/go-kratos/kratos/v2/log" ) const ( _testJSON = ` { "server":{ "http":{ "addr":"0.0.0.0", "port":80, "timeout":0.5, "enable_ssl":true }, "grpc":{ "addr":"0.0.0.0", "port":10080, "timeout":0.2 } }, "data":{ "database":{ "driver":"mysql", "source":"root:root@tcp(127.0.0.1:3306)/karta_id?parseTime=true" } }, "endpoints":[ "www.aaa.com", "www.bbb.org" ] }` ) type testConfigStruct struct { Server struct { HTTP struct { Addr string `json:"addr"` Port int `json:"port"` Timeout float64 `json:"timeout"` EnableSSL bool `json:"enable_ssl"` } `json:"http"` GRPC struct { Addr string `json:"addr"` Port int `json:"port"` Timeout float64 `json:"timeout"` } `json:"grpc"` } `json:"server"` Data struct { Database struct { Driver string `json:"driver"` Source string `json:"source"` } `json:"database"` } `json:"data"` Endpoints []string `json:"endpoints"` } type testJSONSource struct { data string sig chan struct{} err chan struct{} } func newTestJSONSource(data string) *testJSONSource { return &testJSONSource{data: data, sig: make(chan struct{}), err: make(chan struct{})} } func (p *testJSONSource) Load() ([]*KeyValue, error) { kv := &KeyValue{ Key: "json", Value: []byte(p.data), Format: "json", } return []*KeyValue{kv}, nil } func (p *testJSONSource) Watch() (Watcher, error) { return newTestWatcher(p.sig, p.err), nil } type testWatcher struct { sig chan struct{} err chan struct{} exit chan struct{} } func newTestWatcher(sig, err chan struct{}) Watcher { return &testWatcher{sig: sig, err: err, exit: make(chan struct{})} } func (w *testWatcher) Next() ([]*KeyValue, error) { select { case <-w.sig: return nil, nil case <-w.err: return nil, errors.New("error") case <-w.exit: return nil, nil } } func (w *testWatcher) Stop() error { close(w.exit) return nil } func TestConfig(t *testing.T) { var ( err error httpAddr = "0.0.0.0" httpTimeout = 0.5 grpcPort = 10080 endpoint1 = "www.aaa.com" databaseDriver = "mysql" ) c := New( WithSource(newTestJSONSource(_testJSON)), WithDecoder(defaultDecoder), WithResolver(defaultResolver), WithLogger(log.GetLogger()), ) err = c.Close() if err != nil { t.Fatal("t is not nil") } jSource := newTestJSONSource(_testJSON) opts := options{ sources: []Source{jSource}, decoder: defaultDecoder, resolver: defaultResolver, logger: log.GetLogger(), } cf := &config{} cf.opts = opts cf.reader = newReader(opts) cf.log = log.NewHelper(opts.logger) err = cf.Load() if err != nil { t.Fatal("t is not nil") } val, err := cf.Value("data.database.driver").String() if err != nil { t.Fatal("t is not nil") } if !reflect.DeepEqual(databaseDriver, val) { t.Fatal(`databaseDriver is not equal to val`) } err = cf.Watch("endpoints", func(key string, value Value) { }) if err != nil { t.Fatal("t is not nil") } jSource.sig <- struct{}{} jSource.err <- struct{}{} var testConf testConfigStruct err = cf.Scan(&testConf) if err != nil { t.Fatal("t is not nil") } if !reflect.DeepEqual(httpAddr, testConf.Server.HTTP.Addr) { t.Fatal(`httpAddr is not equal to testConf.Server.HTTP.Addr`) } if !reflect.DeepEqual(httpTimeout, testConf.Server.HTTP.Timeout) { t.Fatal(`httpTimeout is not equal to testConf.Server.HTTP.Timeout`) } if !reflect.DeepEqual(true, testConf.Server.HTTP.EnableSSL) { t.Fatal(`testConf.Server.HTTP.EnableSSL is not equal to true`) } if !reflect.DeepEqual(grpcPort, testConf.Server.GRPC.Port) { t.Fatal(`grpcPort is not equal to testConf.Server.GRPC.Port`) } if !reflect.DeepEqual(endpoint1, testConf.Endpoints[0]) { t.Fatal(`endpoint1 is not equal to testConf.Endpoints[0]`) } if !reflect.DeepEqual(len(testConf.Endpoints), 2) { t.Fatal(`len(testConf.Endpoints) is not equal to 2`) } }