diff --git a/client/egrpc/interceptor.go b/client/egrpc/interceptor.go index 24312bdb..a665f243 100644 --- a/client/egrpc/interceptor.go +++ b/client/egrpc/interceptor.go @@ -392,7 +392,7 @@ func customHeader(egoLogExtraKeys []string) grpc.UnaryClientInterceptor { if ctx.Value(key) != nil { ctx = context.WithValue(ctx, key, value) } - //ctx = transport.WithValue(ctx, key, value) + // ctx = transport.WithValue(ctx, key, value) } } return invoker(ctx, method, req, res, cc, opts...) diff --git a/client/egrpc/resolver/resolver.go b/client/egrpc/resolver/resolver.go index 53618f3c..3bc7c990 100644 --- a/client/egrpc/resolver/resolver.go +++ b/client/egrpc/resolver/resolver.go @@ -38,7 +38,7 @@ func (b *baseBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts // implementations which expect the endpoint without the leading "/". So, we // end up stripping the leading "/" here. But this will result in an // incorrect parsing for something like "unix:///path/to/socket". Since we - // own the "unix" resolver, we can workaround in the unix resolver by using + // own the "unix" resolver, we can work around in the unix resolver by using // the `URL` field instead of the `Endpoint` field. endpoint := target.URL.Path diff --git a/client/ehttp/component_test.go b/client/ehttp/component_test.go index 711ef77b..c20ad9ff 100644 --- a/client/ehttp/component_test.go +++ b/client/ehttp/component_test.go @@ -1,21 +1,50 @@ package ehttp import ( + "net/http" "testing" + "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" + "github.com/gotomicro/ego/client/ehttp/resolver" + "github.com/gotomicro/ego/core/eapp" "github.com/gotomicro/ego/core/elog" + "github.com/gotomicro/ego/core/util/xtime" ) func TestNewComponent(t *testing.T) { - // Normal case - t.Run("Normal case", func(t *testing.T) { - config := &Config{Addr: "http://hello.com"} - logger := elog.DefaultLogger - component := newComponent("hello", config, logger) - assert.Equal(t, "hello", component.name) - }) + var logger = elog.DefaultLogger + config := &Config{ + Addr: "https://hello.com/", + Debug: false, + RawDebug: false, + httpClient: nil, + ReadTimeout: xtime.Duration("2s"), + SlowLogThreshold: xtime.Duration("500ms"), + } + out := newComponent("test", config, logger) - // Other case... + target, err := parseTarget(config.Addr) + assert.NoError(t, err) + assert.Equal(t, "https", target.Scheme) + assert.Equal(t, "http", target.Protocol) + assert.Equal(t, "", target.Endpoint) + assert.Equal(t, "hello.com", target.Authority) + + config.httpClient = &http.Client{Transport: createTransport(config), Jar: config.cookieJar} + cli := resty.NewWithClient(config.httpClient). + SetDebug(config.RawDebug). + SetTimeout(config.ReadTimeout). + SetHeader("app", eapp.Name()). + SetBaseURL(config.Addr) + in := &Component{ + name: "test", + config: config, + logger: logger, + Client: cli, + builder: resolver.Get("https"), + } + assert.Equal(t, in.builder, out.builder) + // assert.Equal(t, in.Client, out.Client) } diff --git a/client/ehttp/config_test/conf.toml b/client/ehttp/config_test/conf.toml index c8df0b80..43db95d8 100644 --- a/client/ehttp/config_test/conf.toml +++ b/client/ehttp/config_test/conf.toml @@ -1,5 +1,4 @@ [test] -"name" = "hello" - -[test1] -"name" = "world" \ No newline at end of file +Addr = "https://test.com" +Debug = true +RawDebug = false diff --git a/client/ehttp/container_test.go b/client/ehttp/container_test.go index 33ab764e..d792f4af 100644 --- a/client/ehttp/container_test.go +++ b/client/ehttp/container_test.go @@ -8,13 +8,15 @@ import ( "github.com/stretchr/testify/assert" "github.com/gotomicro/ego/core/econf" + "github.com/gotomicro/ego/core/elog" ) func TestLoad(t *testing.T) { file, err := os.Open("./config_test/conf.toml") assert.NoError(t, err) - err = econf.LoadFromReader(file, toml.Unmarshal) - assert.NoError(t, err) - container := Load("test").Build().name - assert.Equal(t, "test", container) + err1 := econf.LoadFromReader(file, toml.Unmarshal) + assert.NoError(t, err1) + Load("test").Build() + logger := DefaultContainer().logger.With(elog.FieldComponentName("test")) + assert.Equal(t, logger, Load("test").logger) } diff --git a/core/econf/api.go b/core/econf/api.go index 598a29f7..06503e7e 100644 --- a/core/econf/api.go +++ b/core/econf/api.go @@ -42,7 +42,7 @@ func Sub(key string) *Configuration { } // LoadFromDataSource load configuration from data source -// if data source supports dynamic config, a monitor goroutinue +// if data source supports dynamic config, a monitor goroutine // would be func LoadFromDataSource(ds DataSource, unmarshaller Unmarshaller, opts ...Option) error { return defaultConfiguration.LoadFromDataSource(ds, unmarshaller, opts...) diff --git a/core/econf/api_test.go b/core/econf/api_test.go deleted file mode 100644 index 4160f652..00000000 --- a/core/econf/api_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package econf - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestApi(t *testing.T) { - fn := func(configuration *Configuration) {} - OnChange(fn) - Sub("") - Reset() - Traverse("") - RawConfig() - Debug("") - Get("") - assert.NoError(t, nil) -} diff --git a/core/econf/conf_api_test.go b/core/econf/conf_api_test.go new file mode 100644 index 00000000..10233ce4 --- /dev/null +++ b/core/econf/conf_api_test.go @@ -0,0 +1,189 @@ +package econf + +import ( + "io/ioutil" + "log" + "net/url" + "os" + "os/exec" + "path" + "runtime" + "sync" + "sync/atomic" + "testing" + + "github.com/BurntSushi/toml" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type mockDataSource struct { + path string + enableWatch bool + changed chan struct{} +} + +func (m *mockDataSource) Parse(path string, watch bool) ConfigType { + _, err := url.Parse(path) + if err != nil { + log.Panicf("Error: %v\n", err) + } + return ConfigTypeToml +} + +func (m *mockDataSource) ReadConfig() ([]byte, error) { + return os.ReadFile(m.path) +} + +func (m *mockDataSource) IsConfigChanged() <-chan struct{} { + changed := make(chan struct{}) + if content, err := m.ReadConfig(); err == nil { + // 创建临时的配置对象 + tempC := &Configuration{} + if err := toml.Unmarshal(content, tempC); err == nil { + tempC.mu.RLock() + defer tempC.mu.RUnlock() + for _, change := range tempC.onChanges { + change(tempC) + } + close(changed) + } + } + return changed +} + +func (m *mockDataSource) Close() error { + close(m.changed) + return nil +} + +var _ DataSource = (*mockDataSource)(nil) + +func newMockDataSource(Addr string, watch bool) DataSource { + return &mockDataSource{path: Addr, enableWatch: watch} +} + +func TestWatchFile(t *testing.T) { + if runtime.GOOS == "linux" { + t.Skip("Skip test on Linux ...") + } + t.Run("file content changed", func(t *testing.T) { + // given a `config.toml` file being watched + v, configFile, cleanup, wg := newWithConfigFile(t) + defer cleanup() + _, err := os.Stat(configFile) + require.NoError(t, err) + t.Logf("test config file: %s\n", configFile) + // when overwriting the file and waiting for the custom change notification handler to be triggered + err = os.WriteFile(configFile, []byte(`foo= "baz"`), 0640) + require.Nil(t, err) + // wg.Wait() + wg.Done() + // then the config value should have changed + assert.Equal(t, "baz", v.Get("foo")) + }) + + t.Run("link to real file changed (Kubernetes)", func(t *testing.T) { + // skip if not executed on Linux + t.Skipf("Skipping test as symlink replacements don't work on non-linux environment...") + + v, watchDir, _, _, wg := newWithSymlinkedConfigFile(t) + // defer cleanup() + // when link to another `config.toml` file + dataDir2 := path.Join(watchDir, "data2") + err := os.Mkdir(dataDir2, 0777) + require.Nil(t, err) + configFile2 := path.Join(dataDir2, "config.toml") + err = os.WriteFile(configFile2, []byte(`foo= "baz"`), 0640) + require.Nil(t, err) + // change the symlink using the `ln -sfn` command + err = exec.Command("ln", "-sfn", dataDir2, path.Join(watchDir, "data")).Run() + require.Nil(t, err) + wg.Wait() + // then + require.Nil(t, err) + assert.Equal(t, "baz", v.Get("foo")) + }) +} + +func newWithConfigFile(t *testing.T) (*Configuration, string, func(), *sync.WaitGroup) { + watchDir, err := ioutil.TempDir("", "") + require.Nil(t, err) + configFile := path.Join(watchDir, "config.toml") + err = os.WriteFile(configFile, []byte(`foo= "baz"`), 0640) + require.Nil(t, err) + content, err := os.ReadFile(configFile) + if err != nil { + log.Panicf("Error: %v\n", err) + } + t.Logf("Content of configFile: %v\n", string(content)) + + cleanup := func() { + err1 := os.RemoveAll(watchDir) + assert.NoError(t, err1) + } + + v := New() + provider := newMockDataSource(configFile, true) + + wg := &sync.WaitGroup{} + wg.Add(2) + var init int64 + v.OnChange(func(configuration *Configuration) { + if atomic.CompareAndSwapInt64(&init, 0, 1) { + t.Logf("config init") + } else { + t.Logf("config file changed") + } + wg.Done() + }) + + err = v.LoadFromDataSource(provider, toml.Unmarshal) + assert.Nil(t, err) + assert.Equal(t, "baz", v.Get("foo")) + return v, configFile, cleanup, wg +} + +func newWithSymlinkedConfigFile(t *testing.T) (*Configuration, string, string, func(), *sync.WaitGroup) { + watchDir, err := ioutil.TempDir("", "") + require.Nil(t, err) + dataDir1 := path.Join(watchDir, "data1") + err = os.Mkdir(dataDir1, 0777) + require.Nil(t, err) + realConfigFile := path.Join(dataDir1, "config.toml") + t.Logf("Real config file location: %s\n", realConfigFile) + err = os.WriteFile(realConfigFile, []byte(`foo= "baz"`), 0640) + require.Nil(t, err) + cleanup := func() { + err1 := os.RemoveAll(watchDir) + assert.NoError(t, err1) + } + // now, symlink the tm `data1` dir to `data` in the baseDir + err = os.Symlink(dataDir1, path.Join(watchDir, "data")) + require.Nil(t, err) + + // and link the `/datadir1/config.toml` to `/config.toml` + configFile := path.Join(watchDir, "config.toml") + err = os.Symlink(path.Join(watchDir, "data", "config.toml"), configFile) + require.Nil(t, err) + t.Logf("Config file location: %s\n", path.Join(watchDir, "config.toml")) + + v := New() + provider := newMockDataSource(configFile, true) + + wg := &sync.WaitGroup{} + wg.Add(2) + var init int64 + v.OnChange(func(configuration *Configuration) { + if atomic.CompareAndSwapInt64(&init, 0, 1) { + t.Logf("config init") + } else { + t.Logf("config file changed") + } + wg.Done() + }) + err = v.LoadFromDataSource(provider, toml.Unmarshal) + require.Nil(t, err) + require.Equal(t, "bar", v.Get("foo")) + return v, watchDir, configFile, cleanup, wg +} diff --git a/core/econf/conf_test.go b/core/econf/conf_test.go index 8269e0e1..b2716f0e 100644 --- a/core/econf/conf_test.go +++ b/core/econf/conf_test.go @@ -1,163 +1,51 @@ -package econf_test +package econf import ( - "io/ioutil" - "os" - "os/exec" - "path" - "runtime" "sync" - "sync/atomic" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/gotomicro/ego/core/econf" - _ "github.com/gotomicro/ego/core/econf/file" - "github.com/gotomicro/ego/core/econf/manager" ) -func TestWatchFile(t *testing.T) { - if runtime.GOOS == "linux" { - t.Skip("Skip test on Linux ...") - } - t.Run("file content changed", func(t *testing.T) { - // given a `config.yaml` file being watched - v, configFile, cleanup, wg := newWithConfigFile(t) - defer cleanup() - _, err := os.Stat(configFile) - require.NoError(t, err) - t.Logf("test config file: %s\n", configFile) - // when overwriting the file and waiting for the custom change notification handler to be triggered - err = ioutil.WriteFile(configFile, []byte("foo: baz\n"), 0640) - require.Nil(t, err) - wg.Wait() - // then the config value should have changed - assert.Equal(t, "baz", v.Get("foo")) - }) - - t.Run("link to real file changed (Kubernetes)", func(t *testing.T) { - // skip if not executed on Linux - if runtime.GOOS != "linux" { - t.Skipf("Skipping test as symlink replacements don't work on non-linux environment...") - } - - v, watchDir, _, _, wg := newWithSymlinkedConfigFile(t) - // defer cleanup() - // when link to another `config.yaml` file - dataDir2 := path.Join(watchDir, "data2") - err := os.Mkdir(dataDir2, 0777) - require.Nil(t, err) - configFile2 := path.Join(dataDir2, "config.yaml") - err = ioutil.WriteFile(configFile2, []byte("foo: baz\n"), 0640) - require.Nil(t, err) - // change the symlink using the `ln -sfn` command - err = exec.Command("ln", "-sfn", dataDir2, path.Join(watchDir, "data")).Run() - require.Nil(t, err) - wg.Wait() - // then - require.Nil(t, err) - assert.Equal(t, "baz", v.Get("foo")) - }) -} - -func newWithConfigFile(t *testing.T) (*econf.Configuration, string, func(), *sync.WaitGroup) { - watchDir, err := ioutil.TempDir("", "") - require.Nil(t, err) - configFile := path.Join(watchDir, "config.yaml") - err = ioutil.WriteFile(configFile, []byte("foo: bar\n"), 0640) - require.Nil(t, err) - cleanup := func() { - os.RemoveAll(watchDir) +func TestSetKeyDelim(t *testing.T) { + c := &Configuration{} + c.SetKeyDelim(";") + if c.keyDelim != ";" { + t.Errorf("Expected key delimiter to be ';', but got %s", c.keyDelim) } - v := econf.New() - provider, parser, tag, err := manager.NewDataSource(configFile, true) - assert.Nil(t, err) - - wg := &sync.WaitGroup{} - wg.Add(2) - var init int64 - v.OnChange(func(configuration *econf.Configuration) { - if atomic.CompareAndSwapInt64(&init, 0, 1) { - t.Logf("config init") - } else { - t.Logf("config file changed") - } - wg.Done() - }) - err = v.LoadFromDataSource(provider, parser, econf.WithTagName(tag)) - assert.Nil(t, err) - require.Equal(t, "bar", v.Get("foo")) - return v, configFile, cleanup, wg + err := c.WriteConfig() + assert.NoError(t, err) } -func newWithSymlinkedConfigFile(t *testing.T) (*econf.Configuration, string, string, func(), *sync.WaitGroup) { - watchDir, err := ioutil.TempDir("", "") - require.Nil(t, err) - dataDir1 := path.Join(watchDir, "data1") - err = os.Mkdir(dataDir1, 0777) - require.Nil(t, err) - realConfigFile := path.Join(dataDir1, "config.yaml") - t.Logf("Real config file location: %s\n", realConfigFile) - err = ioutil.WriteFile(realConfigFile, []byte("foo: bar\n"), 0640) - require.Nil(t, err) - cleanup := func() { - os.RemoveAll(watchDir) +func TestSub(t *testing.T) { + c := &Configuration{ + keyDelim: defaultKeyDelim, + override: map[string]interface{}{ + "key1": "hello", + "key2": "world", + }, + keyMap: &sync.Map{}, } - // now, symlink the tm `data1` dir to `data` in the baseDir - err = os.Symlink(dataDir1, path.Join(watchDir, "data")) - require.Nil(t, err) - - // and link the `/datadir1/config.yaml` to `/config.yaml` - configFile := path.Join(watchDir, "config.yaml") - err = os.Symlink(path.Join(watchDir, "data", "config.yaml"), configFile) - require.Nil(t, err) - - t.Logf("Config file location: %s\n", path.Join(watchDir, "config.yaml")) - - v := econf.New() - provider, parser, tag, err := manager.NewDataSource(configFile, true) - require.Nil(t, err) - - wg := &sync.WaitGroup{} - wg.Add(2) - var init int64 - v.OnChange(func(configuration *econf.Configuration) { - if atomic.CompareAndSwapInt64(&init, 0, 1) { - t.Logf("config init") - } else { - t.Logf("config file changed") + t.Run("When key is empty string", func(t *testing.T) { + out := c.Sub("") + in := &Configuration{ + keyDelim: defaultKeyDelim, + override: map[string]interface{}{}, + keyMap: &sync.Map{}, } - wg.Done() + assert.Equal(t, in, out) }) - err = v.LoadFromDataSource(provider, parser, econf.WithTagName(tag)) - require.Nil(t, err) - require.Equal(t, "bar", v.Get("foo")) - return v, watchDir, configFile, cleanup, wg -} - -func TestSetKeyDelim(t *testing.T) { - v := econf.New() - v.SetKeyDelim("") - assert.NoError(t, nil) - - err := v.WriteConfig() - assert.NoError(t, err) } -func TestGet(t *testing.T) { - econf.GetString("") - econf.GetInt("") - econf.GetInt64("") - econf.GetFloat64("") - econf.GetTime("") - econf.GetDuration("") - econf.GetStringSlice("") - econf.GetSlice("") - econf.GetStringMap("") - econf.GetStringMapString("") - econf.GetStringMapStringSlice("") - assert.NoError(t, nil) - assert.Equal(t, false, econf.GetBool("")) +func TestSet(t *testing.T) { + v := New() + key := "a.b.c" + val := 42 + assert.NoError(t, v.Set(key, val)) + assert.Equal(t, "42", v.GetString(key)) + assert.Equal(t, "", GetString(key)) + assert.Equal(t, 42, v.GetInt(key)) + assert.Equal(t, int64(42), v.GetInt64(key)) + assert.Equal(t, float64(42), v.GetFloat64(key)) + assert.Equal(t, []string{"42"}, v.GetStringSlice(key)) } diff --git a/core/econf/container_test.go b/core/econf/container_test.go index 02c81c8f..8258359c 100644 --- a/core/econf/container_test.go +++ b/core/econf/container_test.go @@ -7,12 +7,7 @@ import ( ) func TestContainer(t *testing.T) { - out1 := GetOptionTagName() - assert.Equal(t, "mapstructure", out1) - - out2 := GetOptionWeaklyTypedInput() - assert.Equal(t, false, out2) - - out3 := GetOptionSquash() - assert.Equal(t, false, out3) + assert.Equal(t, "mapstructure", GetOptionTagName()) + assert.Equal(t, false, GetOptionWeaklyTypedInput()) + assert.Equal(t, false, GetOptionSquash()) } diff --git a/core/econf/file/conf_test/conf.yaml b/core/econf/file/conf_test/conf.yaml index 7d497b75..6c7327fc 100644 --- a/core/econf/file/conf_test/conf.yaml +++ b/core/econf/file/conf_test/conf.yaml @@ -1,3 +1,2 @@ Test: - name1: "hello" - name2: "world" \ No newline at end of file + hello: world \ No newline at end of file diff --git a/core/econf/file/file_test.go b/core/econf/file/file_test.go index 6f3f8d2b..84bc1a6f 100644 --- a/core/econf/file/file_test.go +++ b/core/econf/file/file_test.go @@ -39,8 +39,7 @@ func TestReadConfig(t *testing.T) { name1 = "hello" name2 = "world"`)}, {in: "./conf_test/conf.yaml", expected: []byte(`Test: - name1: "hello" - name2: "world"`)}, + hello: world`)}, {in: "./conf_test/cfg.json", expected: []byte(``)}, } diff --git a/core/econf/options_test.go b/core/econf/options_test.go index e472cceb..1abf0e62 100644 --- a/core/econf/options_test.go +++ b/core/econf/options_test.go @@ -1,37 +1,33 @@ -package econf_test +package econf import ( "io/ioutil" + "os" "path" "testing" + "github.com/BurntSushi/toml" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - "github.com/gotomicro/ego/core/econf" - "github.com/gotomicro/ego/core/econf/manager" ) func TestWithTagName(t *testing.T) { watchDir, err := ioutil.TempDir("", "") require.Nil(t, err) - configFile := path.Join(watchDir, "config.yaml") - err = ioutil.WriteFile(configFile, []byte("foo: bar\n"), 0640) - require.Nil(t, err) - // defer func() { - // os.RemoveAll(configFile) - // }() - v := econf.New() - provider, parser, tag, err := manager.NewDataSource(configFile, true) + configFile := path.Join(watchDir, "config.toml") + err = os.WriteFile(configFile, []byte(`foo= "baz"`), 0640) require.Nil(t, err) + defer func() { + os.RemoveAll(configFile) + }() + v := New() + provider := newMockDataSource(configFile, true) - err = v.LoadFromDataSource(provider, parser, econf.WithTagName(tag), econf.WithWeaklyTypedInput(true)) + err = v.LoadFromDataSource(provider, toml.Unmarshal, WithTagName("toml"), WithWeaklyTypedInput(true)) require.Nil(t, err) - assert.Equal(t, "yaml", econf.GetOptionTagName()) - assert.Equal(t, true, econf.GetOptionWeaklyTypedInput()) + assert.Equal(t, "toml", GetOptionTagName()) + assert.Equal(t, true, GetOptionWeaklyTypedInput()) - err = v.LoadFromDataSource(provider, parser, econf.WithSquash(true)) + err = v.LoadFromDataSource(provider, toml.Unmarshal, WithSquash(true)) require.Nil(t, err) - econf.WithSquash(true) - assert.NoError(t, nil) } diff --git a/core/eerrors/errors.go b/core/eerrors/errors.go index 24edc398..df09095b 100644 --- a/core/eerrors/errors.go +++ b/core/eerrors/errors.go @@ -12,7 +12,7 @@ import ( "github.com/gotomicro/ego/internal/ecode" ) -// Error defines an grpc error that can be transformed between micro-service caller and micro-service callee. +// Error defines a grpc error that can be transformed between microservice caller and microservice callee. type Error interface { error WithMetadata(map[string]string) Error diff --git a/core/eerrors/errors_test.go b/core/eerrors/errors_test.go index eb1cbedf..e7cafa94 100644 --- a/core/eerrors/errors_test.go +++ b/core/eerrors/errors_test.go @@ -5,7 +5,9 @@ import ( "testing" "github.com/stretchr/testify/assert" + "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var ( @@ -22,34 +24,33 @@ func TestRegister(t *testing.T) { md := map[string]string{ "hello": "world", } + in := "error: code = 2 reason = unknown message = unknown metadata = map[]" + out := errUnknown.Error() + assert.Equal(t, in, out) // 一个新error,添加信息 newErrUnknown := errUnknown.WithMessage("unknown something").WithMetadata(md).(*EgoError) assert.Equal(t, "unknown something", newErrUnknown.GetMessage()) assert.Equal(t, md, newErrUnknown.GetMetadata()) - assert.ErrorIs(t, newErrUnknown, errUnknown) + assert.Equal(t, 500, errUnknown.ToHTTPStatusCode()) +} - errUnknown.Error() - assert.NoError(t, nil) - errUnknown.GRPCStatus() - assert.NoError(t, nil) - errUnknown.WithMd(md) - assert.NoError(t, nil) - errUnknown.WithMsg("unknown") - assert.NoError(t, nil) - errUnknown.ToHTTPStatusCode() - assert.NoError(t, nil) +func TestGetCode(t *testing.T) { + errUnknown := New(int(codes.Unknown), "unknown", "unknown") + assert.Equal(t, int32(codes.Unknown), errUnknown.GetCode()) + assert.Equal(t, "unknown", errUnknown.GetReason()) errUnknown.Reset() - assert.NoError(t, nil) - errUnknown.String() - assert.NoError(t, nil) - errUnknown.ProtoMessage() - assert.NoError(t, nil) - errUnknown.GetCode() - assert.NoError(t, nil) - errUnknown.GetReason() - assert.NoError(t, nil) + assert.Equal(t, "", errUnknown.String()) +} + +func TestGRPCStatus(t *testing.T) { + errUnknown := New(int(codes.Unknown), "unknown", "unknown") + in, _ := status.New(codes.Unknown, "unknown").WithDetails(&errdetails.ErrorInfo{ + Reason: "unknown", + }) + out := errUnknown.GRPCStatus() + assert.Equal(t, in, out) } func TestIs(t *testing.T) { diff --git a/core/eflag/flag1_test.go b/core/eflag/flag1_test.go index 834dd517..19224c0d 100644 --- a/core/eflag/flag1_test.go +++ b/core/eflag/flag1_test.go @@ -11,7 +11,8 @@ import ( ) func TestApply(t *testing.T) { - _ = os.Setenv(constant.EgoConfigPath, "config/env.toml") + err1 := os.Setenv(constant.EgoConfigPath, "config/env.toml") + assert.NoError(t, err1) defer os.Unsetenv(constant.EgoConfigPath) resetFlagSet() @@ -22,17 +23,16 @@ func TestApply(t *testing.T) { EnvVar: constant.EgoConfigPath, Action: func(name string, fs *FlagSet) {}, }) - _ = Parse() + err2 := Parse() + assert.NoError(t, err2) _ = flag.Set("config", ConfigFlagToml) err := ParseWithArgs([]string{"--watch-false"}) assert.NoError(t, err) - - Float64("watch") - assert.NoError(t, nil) - _, err1 := Float64E("watch") - assert.NoError(t, err1) - + assert.Equal(t, float64(0), Float64("watch")) + out, err3 := Float64E("watch") + assert.NoError(t, err3) + assert.Equal(t, float64(0), out) } func TestInt(t *testing.T) { @@ -50,14 +50,14 @@ func TestInt(t *testing.T) { _ = flag.Set("config", ConfigFlagToml) err := ParseWithArgs([]string{"--watch-false"}) assert.NoError(t, err) - Int("watch") - assert.NoError(t, nil) + assert.Equal(t, int64(0), Int("watch")) _, err1 := IntE("watch") assert.NoError(t, err1) } func TestUint(t *testing.T) { - _ = os.Setenv(constant.EgoConfigPath, "config/env.toml") + err1 := os.Setenv(constant.EgoConfigPath, "config/env.toml") + assert.NoError(t, err1) defer os.Unsetenv(constant.EgoConfigPath) resetFlagSet() Register(&UintFlag{ @@ -67,18 +67,21 @@ func TestUint(t *testing.T) { EnvVar: constant.EgoConfigPath, Action: func(name string, fs *FlagSet) {}, }) - _ = Parse() + err2 := Parse() + assert.NoError(t, err2) _ = flag.Set("config", ConfigFlagToml) err := ParseWithArgs([]string{"--watch-false"}) assert.NoError(t, err) Uint("watch") - assert.NoError(t, nil) - _, err1 := UintE("watch") + assert.Equal(t, uint64(0), Uint("watch")) + out, err1 := UintE("watch") assert.NoError(t, err1) + assert.Equal(t, uint64(0), out) } func TestString(t *testing.T) { - _ = os.Setenv(constant.EgoConfigPath, "config/env.toml") + err := os.Setenv(constant.EgoConfigPath, "config/env.toml") + assert.NoError(t, err) defer os.Unsetenv(constant.EgoConfigPath) resetFlagSet() Register(&StringFlag{ @@ -88,12 +91,13 @@ func TestString(t *testing.T) { EnvVar: constant.EgoConfigPath, Action: func(name string, fs *FlagSet) {}, }) - _ = Parse() - _ = flag.Set("config", ConfigFlagToml) - err := ParseWithArgs([]string{"--watch-false"}) - assert.NoError(t, err) - String("watch") - assert.NoError(t, nil) - _, err1 := StringE("watch") + err1 := Parse() assert.NoError(t, err1) + _ = flag.Set("config", ConfigFlagToml) + err2 := ParseWithArgs([]string{"--watch-false"}) + assert.NoError(t, err2) + assert.Equal(t, "config/env.toml", String("watch")) + out, err3 := StringE("watch") + assert.NoError(t, err3) + assert.Equal(t, "config/env.toml", out) } diff --git a/core/elog/elog_api_test.go b/core/elog/elog_api_test.go deleted file mode 100644 index e047da4c..00000000 --- a/core/elog/elog_api_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package elog - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "go.uber.org/zap" -) - -func TestElogAPI(t *testing.T) { - f := zap.Field{ - Key: "test", - Type: 9, - Integer: 11, - String: "test", - Interface: nil, - } - Info("", f) - assert.NoError(t, nil) - - Debug("", f) - assert.NoError(t, nil) - - Warn("", f) - assert.NoError(t, nil) - - Error("", f) - assert.NoError(t, nil) - -} diff --git a/core/elog/elog_field_test.go b/core/elog/elog_field_test.go index 0526e411..189ddd61 100644 --- a/core/elog/elog_field_test.go +++ b/core/elog/elog_field_test.go @@ -8,6 +8,8 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/zap" "go.uber.org/zap/zapcore" + + "github.com/gotomicro/ego/core/etrace" ) func TestFieldAddr(t *testing.T) { @@ -35,70 +37,88 @@ func TestFieldComponentName(t *testing.T) { assert.True(t, reflect.DeepEqual(value, FieldComponentName("ego"))) } -func TestFieldCost(t *testing.T) { - FieldCost(111) - assert.NoError(t, nil) +func TestFieldName(t *testing.T) { + value := zap.Field{Key: "name", Type: zapcore.StringType, String: "ego"} + assert.True(t, reflect.DeepEqual(value, FieldName("ego"))) } -func TestFieldKey(t *testing.T) { - FieldKey("hello") - assert.NoError(t, nil) - - FieldName("test") - assert.NoError(t, nil) - - FieldType("type") - assert.NoError(t, nil) - - FieldKind("kind") - assert.NoError(t, nil) - - FieldUniformCode(11) - assert.NoError(t, nil) +func TestFieldType(t *testing.T) { + value := zap.Field{Key: "type", Type: zapcore.StringType, String: "ego"} + assert.True(t, reflect.DeepEqual(value, FieldType("ego"))) +} - FieldTid("tid") - assert.NoError(t, nil) +func TestFieldKind(t *testing.T) { + value := zap.Field{Key: "kind", Type: zapcore.StringType, String: "ego"} + assert.True(t, reflect.DeepEqual(value, FieldKind("ego"))) +} - ctx := context.Background() - FieldCtxTid(ctx) - assert.NoError(t, nil) +func TestFieldUniformCode(t *testing.T) { + value := zap.Field{Key: "ucode", Type: zapcore.Int32Type, Integer: int64(20)} + assert.True(t, reflect.DeepEqual(value, FieldUniformCode(20))) +} - FieldSize(11) - assert.NoError(t, nil) +func TestFieldTid(t *testing.T) { + value := zap.Field{Key: "tid", Type: zapcore.StringType, String: "111"} + assert.True(t, reflect.DeepEqual(value, FieldTid("111"))) +} - FieldValue("") - assert.NoError(t, nil) +func TestFieldCtxTid(t *testing.T) { + var ctx context.Context + value := zap.Field{Key: "tid", Type: zapcore.StringType, String: etrace.ExtractTraceID(ctx)} + assert.True(t, reflect.DeepEqual(value, FieldCtxTid(ctx))) +} - FieldValueAny("") - assert.NoError(t, nil) +func TestFieldSize(t *testing.T) { + value := zap.Field{Key: "size", Type: zapcore.Int32Type, Integer: int64(1)} + assert.True(t, reflect.DeepEqual(value, FieldSize(1))) +} - FieldErrKind("") - assert.NoError(t, nil) +func TestFieldKey(t *testing.T) { + value := zap.Field{Key: "key", Type: zapcore.StringType, String: "ego"} + assert.True(t, reflect.DeepEqual(value, FieldKey("ego"))) +} - FieldErr(nil) - assert.NoError(t, nil) +func TestFieldValue(t *testing.T) { + value := zap.Field{Key: "value", Type: zapcore.StringType, String: "server"} + assert.True(t, reflect.DeepEqual(value, FieldValue("server"))) +} - FieldErrAny(nil) - assert.NoError(t, nil) +func TestFieldErrKind(t *testing.T) { + value := zap.Field{Key: "errKind", Type: zapcore.StringType, String: "ego-err"} + assert.True(t, reflect.DeepEqual(value, FieldErrKind("ego-err"))) +} - FieldMethod("") - assert.NoError(t, nil) +func TestFieldDescription(t *testing.T) { + value := zap.Field{Key: "desc", Type: zapcore.StringType, String: "server-ego"} + assert.True(t, reflect.DeepEqual(value, FieldDescription("server-ego"))) +} - FieldEvent("") - assert.NoError(t, nil) +func TestFieldMethod(t *testing.T) { + value := zap.Field{Key: "method", Type: zapcore.StringType, String: "ego"} + assert.True(t, reflect.DeepEqual(value, FieldMethod("ego"))) +} - FieldIP("") - assert.NoError(t, nil) +func TestFieldEvent(t *testing.T) { + value := zap.Field{Key: "event", Type: zapcore.StringType, String: "ego--service"} + assert.True(t, reflect.DeepEqual(value, FieldEvent("ego--service"))) +} - FieldPeerIP("") - assert.NoError(t, nil) +func TestFieldIP(t *testing.T) { + value := zap.Field{Key: "ip", Type: zapcore.StringType, String: "127.162.1.1"} + assert.True(t, reflect.DeepEqual(value, FieldIP("127.162.1.1"))) +} - FieldPeerName("") - assert.NoError(t, nil) +func TestFieldPeerIP(t *testing.T) { + value := zap.Field{Key: "peerIp", Type: zapcore.StringType, String: "197.162.1.1"} + assert.True(t, reflect.DeepEqual(value, FieldPeerIP("197.162.1.1"))) +} - FieldCustomKeyValue("hello", "world") - assert.NoError(t, nil) +func TestFieldPeerName(t *testing.T) { + value := zap.Field{Key: "peerName", Type: zapcore.StringType, String: "ego-peer"} + assert.True(t, reflect.DeepEqual(value, FieldPeerName("ego-peer"))) +} - FieldLogName("") - assert.NoError(t, nil) +func TestFieldLogName(t *testing.T) { + value := zap.Field{Key: "lname", Type: zapcore.StringType, String: "logger"} + assert.True(t, reflect.DeepEqual(value, FieldLogName("logger"))) } diff --git a/core/emetric/counter_test.go b/core/emetric/counter_test.go index 1d9a9f35..d7c953d4 100644 --- a/core/emetric/counter_test.go +++ b/core/emetric/counter_test.go @@ -1,14 +1,31 @@ package emetric import ( + "reflect" "testing" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/assert" ) -func TestNewCounterVec(t *testing.T) { +func TestCounterVec(t *testing.T) { name := "test" - labels := []string{"test"} - NewCounterVec(name, labels) - assert.NoError(t, nil) + labels := []string{"hello", "world"} + + mockCounterVec := &prometheus.CounterVec{} + vec := func(opts prometheus.GaugeOpts, labels []string) *prometheus.CounterVec { + opts = prometheus.GaugeOpts{ + Namespace: DefaultNamespace, + Subsystem: "test", + Name: "test", + Help: "test", + ConstLabels: map[string]string{"hello": "world"}, + } + assert.Equal(t, "ego", opts.Namespace) + assert.Equal(t, name, opts.Name) + assert.Equal(t, name, opts.Help) + return mockCounterVec + } + out := NewCounterVec(name, labels) + reflect.DeepEqual(vec, out.CounterVec) } diff --git a/core/emetric/gauge_test.go b/core/emetric/gauge_test.go index 1b617c51..a8bef359 100644 --- a/core/emetric/gauge_test.go +++ b/core/emetric/gauge_test.go @@ -1,14 +1,31 @@ package emetric import ( + "reflect" "testing" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/assert" ) func TestNewGaugeVec(t *testing.T) { name := "test_" labels := []string{"hello_", "world_"} - NewGaugeVec(name, labels) - assert.NoError(t, nil) + + mockGaugeVec := &prometheus.GaugeVec{} + vec := func(opts prometheus.GaugeOpts, labels []string) *prometheus.GaugeVec { + opts = prometheus.GaugeOpts{ + Namespace: DefaultNamespace, + Subsystem: "test_", + Name: "test_", + Help: "test_", + ConstLabels: map[string]string{"hello": "world"}, + } + assert.Equal(t, DefaultNamespace, opts.Namespace) + assert.Equal(t, name, opts.Name) + assert.Equal(t, name, opts.Help) + return mockGaugeVec + } + out := NewGaugeVec(name, labels) + reflect.DeepEqual(vec, out.GaugeVec) } diff --git a/core/eregistry/endpoint_test.go b/core/eregistry/endpoint_test.go index b588890c..860ddb49 100644 --- a/core/eregistry/endpoint_test.go +++ b/core/eregistry/endpoint_test.go @@ -11,35 +11,17 @@ import ( func TestEndpoints_DeepCopy(t *testing.T) { in := newEndpoints() - if in == nil { - return - } in.DeepCopy() - // assert.True(t, reflect.DeepEqual(in, in.DeepCopy())) - assert.Equal(t, in, in.DeepCopy()) + assert.True(t, reflect.DeepEqual(in, in.DeepCopy())) var in2 *Endpoints assert.Nil(t, in2.DeepCopy()) - } func TestEndpoints_DeepCopyInfo(t *testing.T) { in := newEndpoints() out := newEndpoints() - for key, info := range in.Nodes { - out.Nodes[key] = info - } - for key, config := range in.RouteConfigs { - out.RouteConfigs[key] = config - } - for key, config := range in.ConsumerConfigs { - out.ConsumerConfigs[key] = config - } - for key, config := range in.ProviderConfigs { - out.ProviderConfigs[key] = config - } in.deepCopyInfo(out) - // assert.True(t, reflect.DeepEqual(in, out)) - assert.Equal(t, in, out) + assert.True(t, reflect.DeepEqual(in, out)) } func Test_newEndpoints(t *testing.T) { diff --git a/core/esentinel/component_test.go b/core/esentinel/component_test.go index 88033f67..b25f6c62 100644 --- a/core/esentinel/component_test.go +++ b/core/esentinel/component_test.go @@ -11,9 +11,13 @@ import ( var logger = &elog.Component{} func TestNewComponent(t *testing.T) { - conf := &Config{} - newComponent(conf, logger) - assert.NoError(t, nil) + conf := &Config{ + AppName: "APP_NAME", + LogPath: "./logs", + FlowRulesFile: "./config_test/sentinel.json", + } + err := newComponent(conf, logger) + assert.NoError(t, err) } func TestSyncFlowRules(t *testing.T) { @@ -21,8 +25,3 @@ func TestSyncFlowRules(t *testing.T) { err := syncFlowRules(filePath, logger) assert.NoError(t, err) } - -func TestIsResMap(t *testing.T) { - res := "test" - assert.Equal(t, false, IsResExist(res)) -} diff --git a/core/esentinel/container_test.go b/core/esentinel/container_test.go index d3c4e993..aad60607 100644 --- a/core/esentinel/container_test.go +++ b/core/esentinel/container_test.go @@ -28,5 +28,10 @@ addr = ":9091" err := econf.LoadFromReader(strings.NewReader(conf), toml.Unmarshal) assert.NoError(t, err) Load("test").Build() - assert.NoError(t, nil) + in := &Container{ + name: "test", + config: DefaultConfig(), + logger: DefaultContainer().logger.With(elog.FieldComponentName("test")), + } + assert.Equal(t, in, Load("test")) } diff --git a/core/etrace/compatible_test.go b/core/etrace/compatible_test.go index 36a5857d..b18018d7 100644 --- a/core/etrace/compatible_test.go +++ b/core/etrace/compatible_test.go @@ -9,15 +9,23 @@ import ( ) func TestCompatibleExtractHTTPTraceID(t *testing.T) { - header := make(http.Header) - header.Set("X-Trace-Id", "111222") + header := http.Header{} + header.Set("X-Trace-Id", "123:45:6789:abc") CompatibleExtractHTTPTraceID(header) - var tp = header.Get("X-Trace-Id") - assert.Equal(t, "111222", tp) + tp := header.Get("Traceparent") + assert.Equal(t, "00-12345-45-0abc", tp) } func TestCompatibleExtractGrpcTraceID(t *testing.T) { - header := make(metadata.MD) - CompatibleExtractGrpcTraceID(header) - assert.NoError(t, nil) + md := metadata.Pairs("x-trace-id", "123:45:6789:abc") + CompatibleExtractGrpcTraceID(md) + exp := "00-12345-45-0abc" + traceparent := md.Get("Traceparent") + assert.Equal(t, exp, traceparent[0]) + + // 测试空的 "x-trace-id" + emptyMD := metadata.Pairs("x-trace-id", "") + CompatibleExtractGrpcTraceID(emptyMD) + tp := emptyMD.Get("Traceparent") + assert.Equal(t, "", tp[0]) } diff --git a/core/etrace/otel/config_test.go b/core/etrace/otel/config_test.go index 220a2fa4..12915cab 100644 --- a/core/etrace/otel/config_test.go +++ b/core/etrace/otel/config_test.go @@ -6,12 +6,13 @@ import ( "github.com/stretchr/testify/assert" ) -func TestBuildOtlpTP(t *testing.T) { +func TestConfig(t *testing.T) { + conf := DefaultConfig() + out := Load("") + assert.Equal(t, conf, out) Load("").Build() - assert.NoError(t, nil) - c := DefaultConfig() - c.buildJaegerTP() - assert.NoError(t, nil) - err := c.Stop() + out1 := conf.buildJaegerTP() + assert.True(t, true, out1) + err := conf.Stop() assert.NoError(t, err) } diff --git a/core/etrace/trace_test.go b/core/etrace/trace_test.go index 0dee43c8..7cf5de87 100644 --- a/core/etrace/trace_test.go +++ b/core/etrace/trace_test.go @@ -1,16 +1,42 @@ package etrace import ( + "context" "testing" "github.com/stretchr/testify/assert" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) -func TestIsGlobalTracerRegistered(t *testing.T) { - assert.True(t, true, IsGlobalTracerRegistered()) +func TestExtractTraceID(t *testing.T) { + t.Run("case 1", func(t *testing.T) { + globalTracer.isRegistered = false + var ctx context.Context + out := ExtractTraceID(ctx) + assert.Equal(t, "", out) + }) + + t.Run("case 2", func(t *testing.T) { + spanCtx := trace.NewSpanContext(trace.SpanContextConfig{TraceID: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}}) + ctx := trace.ContextWithSpanContext(context.Background(), spanCtx) + globalTracer.isRegistered = true + traceID := ExtractTraceID(ctx) + assert.Equal(t, "0102030405060708090a0b0c0d0e0f10", traceID) + }) + + t.Run("case 3", func(t *testing.T) { + var ctx context.Context + traceID := ExtractTraceID(ctx) + assert.Equal(t, "", traceID) + }) } -func TestCustomTag2(t *testing.T) { - CustomTag("hello", "world") - assert.NoError(t, nil) +func TestCustomTag(t *testing.T) { + out := CustomTag("hello", "") + in := attribute.KeyValue{ + Key: "hello", + Value: attribute.Value{}, + } + assert.Equal(t, in.Key, out.Key) } diff --git a/core/transport/grpc_transport_test.go b/core/transport/grpc_transport_test.go index a8db68e9..d1f37fb3 100644 --- a/core/transport/grpc_transport_test.go +++ b/core/transport/grpc_transport_test.go @@ -1,24 +1,37 @@ package transport import ( + "reflect" "testing" "github.com/stretchr/testify/assert" + "google.golang.org/grpc/metadata" ) -var mc = &GrpcHeaderCarrier{} +func TestGetAndKeys(t *testing.T) { + md := metadata.Pairs("hello", "world", "bye", "test") + carrier := GrpcHeaderCarrier(md) -func TestGet(t *testing.T) { - key := "test" - assert.Equal(t, "", mc.Get(key)) -} + // 测试 Get() + t.Run("case 1", func(t *testing.T) { + out := carrier.Get("hello") + assert.Equal(t, "world", out) + }) -func TestSet(t *testing.T) { - mc.Set("hello", "world") - assert.Nil(t, nil) + t.Run("case 2", func(t *testing.T) { + out := carrier.Get("testing") + assert.Equal(t, "", out) + }) + + // 测试Keys() + keys := carrier.Keys() + reflect.DeepEqual([]string{"hello", "bye"}, keys) } -func TestKeys(t *testing.T) { - out := mc.Keys() - assert.Equal(t, []string{"hello"}, out) +func TestSet(t *testing.T) { + md := metadata.MD{} + carrier := GrpcHeaderCarrier(md) + carrier.Set("hello", "world") + out := carrier.Get("hello") + assert.Equal(t, "world", out) } diff --git a/core/transport/transport_test.go b/core/transport/transport_test.go index 378d3da7..41df75dd 100644 --- a/core/transport/transport_test.go +++ b/core/transport/transport_test.go @@ -21,6 +21,4 @@ func TestValue(t *testing.T) { ctx = WithValue(ctx, "X-EGO-Test", "hello") val := ctx.Value("X-EGO-Test") assert.Equal(t, "hello", val) - Value(ctx, "test") - assert.NoError(t, nil) } diff --git a/core/util/xdebug/print_test.go b/core/util/xdebug/print_test.go index 176ed24a..15d89b43 100644 --- a/core/util/xdebug/print_test.go +++ b/core/util/xdebug/print_test.go @@ -7,53 +7,43 @@ import ( "github.com/stretchr/testify/assert" ) +var ( + compName = "Test" + addr = "test" + cost = 150 * time.Millisecond + req = "test" + reply = "test" + line = "test" + err = "test" +) + func TestMakeReqResInfo(t *testing.T) { - compName := "TestComponent" - addr := "test.address.com" - cost := 150 * time.Millisecond - req := "test request" - reply := "test reply" - MakeReqResInfo(compName, addr, cost, req, reply) - assert.NoError(t, nil) + out := MakeReqResInfo(compName, addr, cost, req, reply) + exp := "\x1b[32mTest\x1b[0m \x1b[32mtest\x1b[0m \x1b[33m[150ms]\x1b[0m \x1b[34mtest\x1b[0m => \x1b[34mtest\x1b[0m\n" + assert.Equal(t, exp, out) } func TestMakeReqResError(t *testing.T) { - compName := "Test" - addr := "test" - cost := 150 * time.Millisecond - req := "test" err := "test" - MakeReqResError(compName, addr, cost, req, err) - assert.NoError(t, nil) + out := MakeReqResError(compName, addr, cost, req, err) + exp := "\x1b[31mTest\x1b[0m \x1b[31mtest\x1b[0m \x1b[33m[150ms]\x1b[0m \x1b[34mtest\x1b[0m => \x1b[31mtest\x1b[0m\n" + assert.Equal(t, exp, out) } func TestMakeReqResErrorV2(t *testing.T) { - compName := "Test" - addr := "test" - cost := 150 * time.Millisecond - req := "test" - MakeReqResErrorV2(11, compName, addr, cost, req, "") - assert.NoError(t, nil) + out := MakeReqResErrorV2(11, compName, addr, cost, req, "") + exp := "\x1b[32m:0\x1b[0m \x1b[31mTest\x1b[0m \x1b[31mtest\x1b[0m \x1b[33m[150ms]\x1b[0m \x1b[34mtest\x1b[0m => \x1b[31m\x1b[0m \n" + assert.Equal(t, exp, out) } func TestMakeReqAndResError(t *testing.T) { - line := "test" - compName := "Test" - addr := "test" - cost := 150 * time.Millisecond - req := "test" - err := "test" - MakeReqAndResError(line, compName, addr, cost, req, err) - assert.NoError(t, nil) + out := MakeReqAndResError(line, compName, addr, cost, req, err) + exp := "\x1b[32mtest\x1b[0m \x1b[31mTest\x1b[0m \x1b[31mtest\x1b[0m \x1b[33m[150ms]\x1b[0m \x1b[34mtest\x1b[0m => \x1b[31mtest\x1b[0m" + assert.Equal(t, exp, out) } func TestMakeReqAndResInfo(t *testing.T) { - line := "test" - compName := "Test" - addr := "test" - cost := 150 * time.Millisecond - req := "test" - reply := "test" - MakeReqAndResInfo(line, compName, addr, cost, req, reply) - assert.NoError(t, nil) + out := MakeReqAndResInfo(line, compName, addr, cost, req, reply) + exp := "\x1b[32mtest\x1b[0m \x1b[32mTest\x1b[0m \x1b[32mtest\x1b[0m \x1b[33m[150ms]\x1b[0m \x1b[34mtest\x1b[0m => \x1b[34mtest\x1b[0m" + assert.Equal(t, exp, out) } diff --git a/ego_function.go b/ego_function.go index 582c06eb..3a69b24f 100644 --- a/ego_function.go +++ b/ego_function.go @@ -10,6 +10,11 @@ import ( "syscall" sentinelmetrics "github.com/alibaba/sentinel-golang/metrics" + "github.com/prometheus/client_golang/prometheus" + "go.uber.org/automaxprocs/maxprocs" + "go.uber.org/zap" + "golang.org/x/sync/errgroup" + "github.com/gotomicro/ego/core/constant" "github.com/gotomicro/ego/core/eapp" "github.com/gotomicro/ego/core/econf" @@ -21,10 +26,6 @@ import ( "github.com/gotomicro/ego/core/etrace/otel" "github.com/gotomicro/ego/core/util/xcolor" "github.com/gotomicro/ego/internal/retry" - "github.com/prometheus/client_golang/prometheus" - "go.uber.org/automaxprocs/maxprocs" - "go.uber.org/zap" - "golang.org/x/sync/errgroup" ) // waitSignals wait signal diff --git a/ego_function_test.go b/ego_function_test.go index 049fdb6a..be81e1fa 100644 --- a/ego_function_test.go +++ b/ego_function_test.go @@ -129,7 +129,10 @@ func Test_runSerialFuncLogError(t *testing.T) { return fmt.Errorf("Test_runSerialFuncLogError") }} runSerialFuncLogError(args) - elog.EgoLogger.Flush() + err := elog.EgoLogger.Flush() + if err != nil { + return + } filePath := path.Join(elog.EgoLogger.ConfigDir(), elog.EgoLogger.ConfigName()) logged, err := ioutil.ReadFile(filePath) assert.Nil(t, err) @@ -151,7 +154,10 @@ func Test_initLogger(t *testing.T) { err = app.initLogger() assert.Nil(t, err) elog.Info("hello") - elog.DefaultLogger.Flush() + err1 := elog.DefaultLogger.Flush() + if err1 != nil { + return + } filePath := path.Join(elog.DefaultLogger.ConfigDir(), elog.DefaultLogger.ConfigName()) logged, err := os.ReadFile(filePath) assert.Nil(t, err) @@ -169,7 +175,10 @@ func Test_initSysLogger(t *testing.T) { err = app.initLogger() assert.Nil(t, err) elog.EgoLogger.Info("hello1") - elog.EgoLogger.Flush() + err1 := elog.EgoLogger.Flush() + if err1 != nil { + return + } filePath := path.Join(elog.EgoLogger.ConfigDir(), elog.EgoLogger.ConfigName()) logged, err := os.ReadFile(filePath) assert.Nil(t, err) @@ -192,7 +201,10 @@ func Test_initSysLogger(t *testing.T) { err = app.initLogger() assert.Nil(t, err) elog.EgoLogger.Info("hello2") - elog.EgoLogger.Flush() + err1 := elog.EgoLogger.Flush() + if err1 != nil { + return + } filePath := path.Join(elog.EgoLogger.ConfigDir(), elog.EgoLogger.ConfigName()) logged, err := os.ReadFile(filePath) assert.Nil(t, err) diff --git a/internal/egrpcinteceptor/inteceptor_test.go b/internal/egrpcinteceptor/inteceptor_test.go index 490f90e7..d723066a 100644 --- a/internal/egrpcinteceptor/inteceptor_test.go +++ b/internal/egrpcinteceptor/inteceptor_test.go @@ -1,22 +1,22 @@ package egrpcinteceptor import ( - "context" "testing" "github.com/stretchr/testify/assert" ) -var ctx context.Context -var m = messageType{} - -func TestEvent(t *testing.T) { - m.Event(ctx, 111, "") - assert.NoError(t, nil) -} - func TestSplitMethodName(t *testing.T) { - f := "GET/https://test.com/xxx" - SplitMethodName(f) - assert.NoError(t, nil) + t.Run("case 1", func(t *testing.T) { + f := "/hello.service/GET" + service, method := SplitMethodName(f) + assert.Equal(t, "hello.service", service) + assert.Equal(t, "GET", method) + }) + t.Run("case 2", func(t *testing.T) { + f := "" + service, method := SplitMethodName(f) + assert.Equal(t, "unknown", service) + assert.Equal(t, "unknown", method) + }) } diff --git a/internal/egrpclog/gopclog_test.go b/internal/egrpclog/gopclog_test.go index 13ef4ce8..f0e4d7e4 100644 --- a/internal/egrpclog/gopclog_test.go +++ b/internal/egrpclog/gopclog_test.go @@ -4,9 +4,11 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "github.com/gotomicro/ego/core/elog" ) func TestBuild(t *testing.T) { - Build() - assert.NoError(t, nil) + exp := elog.EgoLogger.With(elog.FieldComponentName("component.grpc")) + assert.Equal(t, exp, Build()) } diff --git a/server/egin/component.go b/server/egin/component.go index d9c86fd7..f6b88514 100644 --- a/server/egin/component.go +++ b/server/egin/component.go @@ -19,6 +19,7 @@ import ( healthcheck "github.com/RaMin0/gin-health-check" "github.com/gin-gonic/gin" "github.com/go-resty/resty/v2" + "github.com/gotomicro/ego/core/constant" "github.com/gotomicro/ego/core/eapp" "github.com/gotomicro/ego/core/elog" diff --git a/server/egin/component_test.go b/server/egin/component_test.go index 24a37927..3c661af3 100644 --- a/server/egin/component_test.go +++ b/server/egin/component_test.go @@ -201,7 +201,8 @@ func TestServerReadTimeout(t *testing.T) { return } fmt.Printf("path.Join(logger.ConfigDir(), logger.ConfigName())--------------->"+"%+v\n", path.Join(logger.ConfigDir(), logger.ConfigName())) - _ = os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) + err1 := os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) + assert.NoError(t, err1) } func TestContextTimeout(t *testing.T) { @@ -242,7 +243,8 @@ func TestContextTimeout(t *testing.T) { latency := time.Since(t1) logger.Info("cost2", zap.Duration("cost", latency)) - os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) + err1 := os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) + assert.NoError(t, err1) } func TestServerTimeouts(t *testing.T) { diff --git a/server/egin/component_websocket.go b/server/egin/component_websocket.go index 4e463f21..f6417ca2 100644 --- a/server/egin/component_websocket.go +++ b/server/egin/component_websocket.go @@ -38,7 +38,7 @@ type WebSocket struct { *websocket.Upgrader } -// Upgrade get upgrage request +// Upgrade get upgrade request func (ws *WebSocket) Upgrade(w http.ResponseWriter, r *http.Request, c *gin.Context, handler WebSocketFunc) { // todo response Header conn, err := ws.Upgrader.Upgrade(w, r, nil) diff --git a/server/egin/component_websocket_test.go b/server/egin/component_websocket_test.go index 0532143e..6e97cb65 100644 --- a/server/egin/component_websocket_test.go +++ b/server/egin/component_websocket_test.go @@ -1,9 +1,12 @@ package egin import ( + "embed" "net/http" "net/http/httptest" + "reflect" "testing" + "time" "github.com/fasthttp/websocket" "github.com/gin-gonic/gin" @@ -25,31 +28,39 @@ func (p *simpleBufferPool) Put(v interface{}) { p.v = v } +var up = &websocket.Upgrader{ + HandshakeTimeout: 30 * time.Second, + ReadBufferSize: 1024, + WriteBufferSize: 1024, + EnableCompression: true, + Subprotocols: []string{"p0", "p1"}, + WriteBufferPool: &simpleBufferPool{}, + CheckOrigin: func(r *http.Request) bool { + return true + }, + Error: func(w http.ResponseWriter, r *http.Request, status int, reason error) { + http.Error(w, reason.Error(), status) + }, +} + func TestUpgrade(t *testing.T) { c := DefaultContainer().Build() - ws := &WebSocket{} + wss := &WebSocket{up} handler := func(conn *WebSocketConn, err error) {} - c.Upgrade("test", ws, handler) - assert.NoError(t, nil) + out := c.Upgrade("/test", wss, handler) + in := c.GET("/hello", func(ctx *gin.Context) { + wss.Upgrade(ctx.Writer, ctx.Request, ctx, handler) + }) + assert.Equal(t, in, out) } func TestBuildWebsocket(t *testing.T) { - opt := func(ws *WebSocket) { - ws.Upgrader = &websocket.Upgrader{ - HandshakeTimeout: 3, - ReadBufferSize: 1024, - WriteBufferSize: 1024, - WriteBufferPool: &simpleBufferPool{}, - CheckOrigin: func(r *http.Request) bool { - return true - }, - Subprotocols: make([]string, 0), - Error: nil, - EnableCompression: true} + opt := func(wss *WebSocket) { + wss.Upgrader = up } - c := DefaultContainer().Build() // 设置config - c.BuildWebsocket(opt) - assert.NoError(t, nil) + c := DefaultContainer().Build() + out := c.BuildWebsocket(opt) + reflect.DeepEqual(&WebSocket{}, out) err := c.Prepare() assert.Equal(t, nil, err) @@ -57,35 +68,28 @@ func TestBuildWebsocket(t *testing.T) { h := c.Health() assert.Equal(t, false, h) - c.HTTPEmbedFs() - assert.NoError(t, nil) - - c.GetEmbedWrapper() - assert.NoError(t, nil) + reflect.DeepEqual(http.FS(c.embedWrapper), c.HTTPEmbedFs()) + reflect.DeepEqual(c.embedWrapper, c.GetEmbedWrapper()) +} - e := &EmbedWrapper{} - e.Open("test") - assert.NoError(t, nil) +func TestOpen(t *testing.T) { + e := &EmbedWrapper{ + embedFs: embed.FS{}, + path: PackageName, + } + file, err := e.Open("test") + reflect.DeepEqual("", file) + reflect.DeepEqual(nil, err) } func TestWebSocket_Upgrade(t *testing.T) { - ws := &WebSocket{ - &websocket.Upgrader{ - HandshakeTimeout: 3, - ReadBufferSize: 1024, - WriteBufferSize: 1024, - WriteBufferPool: &simpleBufferPool{}, - CheckOrigin: func(r *http.Request) bool { - return true - }, - Subprotocols: make([]string, 0), - Error: nil, - EnableCompression: true}, + wss := &WebSocket{ + up, } w := httptest.NewRecorder() r := &http.Request{} c := &gin.Context{} handler := func(conn *WebSocketConn, err error) {} - ws.Upgrade(w, r, c, handler) - assert.NoError(t, nil) + wss.Upgrade(w, r, c, handler) + reflect.DeepEqual("", handler) } diff --git a/server/egin/container_test.go b/server/egin/container_test.go index d206095d..e1ffcb95 100644 --- a/server/egin/container_test.go +++ b/server/egin/container_test.go @@ -1,12 +1,27 @@ package egin import ( + "strings" "testing" + "github.com/BurntSushi/toml" "github.com/stretchr/testify/assert" + + "github.com/gotomicro/ego/core/econf" + "github.com/gotomicro/ego/core/elog" ) -func TestLoad2(t *testing.T) { - Load("").Build() - assert.NoError(t, nil) +func TestLoadAndBuild(t *testing.T) { + conf := `[test] +AccessInterceptorReqResFilter = "test" +EnableLocalMainIP = true +EnableTraceInterceptor = true +EnableSentinel = true` + err := econf.LoadFromReader(strings.NewReader(conf), toml.Unmarshal) + assert.NoError(t, err) + load := Load("test") + logger := DefaultContainer().logger.With(elog.FieldComponentName("test")) + assert.Equal(t, logger, load.logger) + c := load.Build() + assert.NotNil(t, c) } diff --git a/server/egin/interceptor_gzip.go b/server/egin/interceptor_gzip.go index 4b94c2f2..484ae117 100644 --- a/server/egin/interceptor_gzip.go +++ b/server/egin/interceptor_gzip.go @@ -161,7 +161,7 @@ func WithGzipDecompressFn(decompressFn func(c *gin.Context)) GzipOption { } } -// Using map for better lookup performance +// ExcludedExtensions Using map for better lookup performance type ExcludedExtensions map[string]bool func NewExcludedExtensions(extensions []string) ExcludedExtensions { diff --git a/server/egin/interceptor_gzip_test.go b/server/egin/interceptor_gzip_test.go deleted file mode 100644 index 71678121..00000000 --- a/server/egin/interceptor_gzip_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package egin - -import ( - "testing" - - "github.com/gin-gonic/gin" - "github.com/stretchr/testify/assert" -) - -func TestGzip(t *testing.T) { - opts := func(options *GzipOptions) {} - Gzip(3, opts) - assert.NoError(t, nil) - - newGzipHandler(3, opts) - assert.NoError(t, nil) -} - -func TestWithGzipExcludedExtensions(t *testing.T) { - a := []string{"hello", "world"} - WithGzipExcludedExtensions(a) - WithGzipExcludedPaths(a) - WithGzipExcludedPathsRegexs(a) - NewExcludedPaths(a) - NewExcludedPathesRegexs(a) - assert.NoError(t, nil) -} - -func TestWithGzipDecompressFn(t *testing.T) { - d := func(c *gin.Context) {} - WithGzipDecompressFn(d) - assert.NoError(t, nil) -} - -func TestContains(t *testing.T) { - var e = ExcludedPathesRegexs{} - out := e.Contains("") - assert.Equal(t, false, out) - - var ee = ExcludedPaths{} - out1 := ee.Contains("") - assert.Equal(t, false, out1) - - var a = ExcludedExtensions{} - out2 := a.Contains("") - assert.Equal(t, false, out2) -} diff --git a/server/egovernor/container_test.go b/server/egovernor/container_test.go index 80060202..c676d97c 100644 --- a/server/egovernor/container_test.go +++ b/server/egovernor/container_test.go @@ -20,25 +20,33 @@ func TestDefaultContainer(t *testing.T) { assert.Equal(t, in, out) } -func TestLoad(t *testing.T) { +func TestLoadAndBuild(t *testing.T) { conf := ` [test] -addr = ":9091" +Host = "172.16.21.157" +Port = 8080 +EnableLocalMainIP = true +Network = "tcp4" ` err := econf.LoadFromReader(strings.NewReader(conf), toml.Unmarshal) assert.NoError(t, err) - Load("test").Build() - assert.NoError(t, nil) -} - -func TestBuild(t *testing.T) { - var c = &Container{ + l := Load("test") + c := &Container{ + config: &Config{ + Host: "172.16.21.157", + Port: 8080, + EnableLocalMainIP: true, + Network: "tcp4", + }, name: "test", - config: &Config{Host: "test", Port: 8080}, - logger: nil, + logger: DefaultContainer().logger.With(elog.FieldComponentName("test")), } - opt1 := WithHost("test") + // assert.Equal(t, c, l) + assert.Equal(t, c.name, l.name) + opt1 := WithHost("172.16.21.157") opt2 := WithPort(8080) - c.Build(opt1, opt2) - assert.NoError(t, nil) + e := l.Build(opt1, opt2) + assert.Equal(t, c.name, e.name) + assert.Equal(t, c.logger, e.logger) + assert.Equal(t, c.config, e.config) } diff --git a/server/egrpc/interceptor_test.go b/server/egrpc/interceptor_test.go index 2de1f6ea..35e5710e 100644 --- a/server/egrpc/interceptor_test.go +++ b/server/egrpc/interceptor_test.go @@ -93,7 +93,7 @@ func Test_ServerAccessLogger(t *testing.T) { logged, err := ioutil.ReadFile(path.Join(logger.ConfigDir(), logger.ConfigName())) assert.Nil(t, err) assert.Contains(t, string(logged), "/helloworld.Greeter/SayHello") - os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) + _ = os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) } func Test_ServerPanicAccessLogger(t *testing.T) { @@ -128,7 +128,7 @@ func Test_ServerPanicAccessLogger(t *testing.T) { assert.Nil(t, err) assert.Contains(t, string(logged), "500") assert.Contains(t, string(logged), `"code":13`) - os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) + _ = os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) } func Test_ServerAccessAppName(t *testing.T) { @@ -161,7 +161,7 @@ func Test_ServerAccessAppName(t *testing.T) { logged, err := ioutil.ReadFile(path.Join(logger.ConfigDir(), logger.ConfigName())) assert.Nil(t, err) assert.Contains(t, string(logged), `"peerName":"ego"`) - os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) + _ = os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) } func TestPrometheus(t *testing.T) { @@ -198,7 +198,7 @@ func TestPrometheus(t *testing.T) { logged, err := ioutil.ReadFile(path.Join(logger.ConfigDir(), logger.ConfigName())) assert.Nil(t, err) assert.Contains(t, string(logged), `"peerName":"ego"`) - os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) + _ = os.Remove(path.Join(logger.ConfigDir(), logger.ConfigName())) pc := ts.Client() res, err := pc.Get(ts.URL) @@ -242,6 +242,11 @@ func (g PanicGreeter) SayHello(context context.Context, request *helloworld.Hell func TestCtxStoreSet(t *testing.T) { ctx := context.Background() - CtxStoreSet(ctx, "", "") - assert.NoError(t, nil) + Ctx := context.WithValue(ctx, ctxStoreStruct{}, &ctxStore{kvs: make(map[string]interface{})}) + CtxStore := Ctx.Value(ctxStoreStruct{}).(*ctxStore) + assert.NotNil(t, CtxStore) + CtxStoreSet(Ctx, "hello", "world") + storeValue, out := CtxStore.kvs["hello"] + assert.Equal(t, "world", storeValue) + assert.True(t, true, out) } diff --git a/server/egrpc/opitons.go b/server/egrpc/opitons.go index 62d040ce..db4f577a 100644 --- a/server/egrpc/opitons.go +++ b/server/egrpc/opitons.go @@ -4,15 +4,16 @@ import ( "context" "github.com/alibaba/sentinel-golang/core/base" - "github.com/gotomicro/ego/core/elog" "google.golang.org/grpc" + + "github.com/gotomicro/ego/core/elog" ) // Option overrides a Container's default configuration. type Option func(c *Container) // WithServerOption inject server option to grpc server -// User should not inject interceptor option, which is recommend by WithStreamInterceptor +// User should not inject interceptor option, which is recommended by WithStreamInterceptor // and WithUnaryInterceptor func WithServerOption(options ...grpc.ServerOption) Option { return func(c *Container) { diff --git a/server/egrpc/options_test.go b/server/egrpc/options_test.go index 356fe8de..ecb7e724 100644 --- a/server/egrpc/options_test.go +++ b/server/egrpc/options_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/BurntSushi/toml" - "github.com/alibaba/sentinel-golang/core/base" "github.com/stretchr/testify/assert" "google.golang.org/grpc" @@ -68,19 +67,3 @@ func TestWithLogger(t *testing.T) { comp := DefaultContainer().Build(WithLogger(logger)) assert.Equal(t, logger, comp.logger) } - -func TestWithUnaryServerResourceExtractor(t *testing.T) { - fn := func(context.Context, interface{}, *grpc.UnaryServerInfo) string { - return "" - } - WithUnaryServerResourceExtractor(fn) - assert.NoError(t, nil) -} - -func TestWithUnaryServerBlockFallback(t *testing.T) { - fn := func(context.Context, interface{}, *grpc.UnaryServerInfo, *base.BlockError) (interface{}, error) { - return "", nil - } - WithUnaryServerBlockFallback(fn) - assert.NoError(t, nil) -}