diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 6724e1717..bed379953 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -2,8 +2,6 @@ name: Go on: push: - branches: - - main pull_request: branches: - main @@ -11,6 +9,7 @@ on: jobs: build: + name: build & test runs-on: ubuntu-latest services: etcd: diff --git a/.golangci.yml b/.golangci.yml index 1c35f5ca3..843234ec1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -19,6 +19,7 @@ linters: - goconst - goimports - gomnd + - gocyclo - ineffassign - lll - prealloc @@ -53,3 +54,15 @@ linters-settings: check-shadowing: true whitespace: multi-func: true + lll: + line-length: 160 + gomnd: + settings: + mnd: + # don't include the "operation" and "assign" + checks: argument,case,condition,return + goconst: + ignore-tests: true + gocyclo: + # recommend 10-20 + min-complexity: 30 diff --git a/Makefile b/Makefile index 6229ef156..9b011b7ba 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,8 @@ all: .PHONY: uninstall .PHONY: clean .PHONY: fmt +.PHONY: test +.PHONY: lint install: all ifeq ($(user),root) @@ -54,4 +56,14 @@ clean: @echo "clean finished" fmt: - @gofmt -s -w . \ No newline at end of file + @gofmt -s -w . + +test: + @go test ./... + +# golangci-lint +LINTER := bin/golangci-lint +$(LINTER): + curl -L https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s v1.42.0 +lint: $(LINTER) + @eval '${LINTER} run --timeout=5m' \ No newline at end of file diff --git a/api/metadata/server.go b/api/metadata/server.go index a0fd6a65c..00fdcb1b3 100644 --- a/api/metadata/server.go +++ b/api/metadata/server.go @@ -18,6 +18,7 @@ import ( dpb "google.golang.org/protobuf/types/descriptorpb" ) +//nolint:lll //go:generate protoc --proto_path=. --proto_path=../../third_party --go_out=paths=source_relative:. --go-grpc_out=paths=source_relative:. --go-http_out=paths=source_relative:. metadata.proto // Server is api meta server diff --git a/app.go b/app.go index 9d5657f09..fbae6a01b 100644 --- a/app.go +++ b/app.go @@ -36,23 +36,23 @@ type App struct { // New create an application lifecycle manager. func New(opts ...Option) *App { - options := options{ + o := options{ ctx: context.Background(), logger: log.NewHelper(log.DefaultLogger), sigs: []os.Signal{syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT}, registrarTimeout: 10 * time.Second, } if id, err := uuid.NewUUID(); err == nil { - options.id = id.String() + o.id = id.String() } - for _, o := range opts { - o(&options) + for _, opt := range opts { + opt(&o) } - ctx, cancel := context.WithCancel(options.ctx) + ctx, cancel := context.WithCancel(o.ctx) return &App{ ctx: ctx, cancel: cancel, - opts: options, + opts: o, } } @@ -99,7 +99,8 @@ func (a *App) Run() error { } wg.Wait() if a.opts.registrar != nil { - ctx, cancel := context.WithTimeout(a.opts.ctx, a.opts.registrarTimeout) + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(a.opts.ctx, a.opts.registrarTimeout) defer cancel() if err := a.opts.registrar.Register(ctx, instance); err != nil { return err @@ -143,7 +144,7 @@ func (a *App) Stop() error { } func (a *App) buildInstance() (*registry.ServiceInstance, error) { - var endpoints []string + endpoints := make([]string, 0) //nolint:gomnd for _, e := range a.opts.endpoints { endpoints = append(endpoints, e.String()) } diff --git a/app_test.go b/app_test.go index 9281b6fd8..37195e7b1 100644 --- a/app_test.go +++ b/app_test.go @@ -21,7 +21,7 @@ func TestApp(t *testing.T) { Server(hs, gs), ) time.AfterFunc(time.Second, func() { - app.Stop() + _ = app.Stop() }) if err := app.Run(); err != nil { t.Fatal(err) @@ -83,8 +83,10 @@ func TestApp_Endpoint(t *testing.T) { name string endpoint []string metadata map[string]string - }{id: "1", version: "v1", name: "kratos-v1", endpoint: []string{"https://go-kratos.dev", "localhost"}, - metadata: map[string]string{}}, + }{ + id: "1", version: "v1", name: "kratos-v1", endpoint: []string{"https://go-kratos.dev", "localhost"}, + metadata: map[string]string{}, + }, }, { id: "2", @@ -98,8 +100,10 @@ func TestApp_Endpoint(t *testing.T) { name string endpoint []string metadata map[string]string - }{id: "2", version: "v2", name: "kratos-v2", endpoint: []string{"test"}, - metadata: map[string]string{"kratos": "https://github.com/go-kratos/kratos"}}, + }{ + id: "2", version: "v2", name: "kratos-v2", endpoint: []string{"test"}, + metadata: map[string]string{"kratos": "https://github.com/go-kratos/kratos"}, + }, }, { id: "3", @@ -113,8 +117,10 @@ func TestApp_Endpoint(t *testing.T) { name string endpoint []string metadata map[string]string - }{id: "3", version: "v3", name: "kratos-v3", endpoint: []string{}, - metadata: map[string]string{}}, + }{ + id: "3", version: "v3", name: "kratos-v3", endpoint: []string{}, + metadata: map[string]string{}, + }, }, } for _, tt := range tests { diff --git a/config/config.go b/config/config.go index 7f4aa53b6..c3ce750ba 100644 --- a/config/config.go +++ b/config/config.go @@ -48,18 +48,18 @@ type config struct { // New new a config with options. func New(opts ...Option) Config { - options := options{ + o := options{ logger: log.DefaultLogger, decoder: defaultDecoder, resolver: defaultResolver, } - for _, o := range opts { - o(&options) + for _, opt := range opts { + opt(&o) } return &config{ - opts: options, - reader: newReader(options), - log: log.NewHelper(options.logger), + opts: o, + reader: newReader(o), + log: log.NewHelper(o.logger), } } @@ -103,7 +103,7 @@ func (c *config) Load() error { if err != nil { return err } - if err := c.reader.Merge(kvs...); err != nil { + if err = c.reader.Merge(kvs...); err != nil { c.log.Errorf("failed to merge config source: %v", err) return err } diff --git a/config/config_test.go b/config/config_test.go index 061465871..5f1f9474e 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -39,13 +39,13 @@ const ( type testConfigStruct struct { Server struct { - Http struct { + HTTP struct { Addr string `json:"addr"` Port int `json:"port"` Timeout float64 `json:"timeout"` EnableSSL bool `json:"enable_ssl"` } `json:"http"` - GRpc struct { + GRPC struct { Addr string `json:"addr"` Port int `json:"port"` Timeout float64 `json:"timeout"` @@ -60,17 +60,17 @@ type testConfigStruct struct { Endpoints []string `json:"endpoints"` } -type testJsonSource struct { +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 newTestJSONSource(data string) *testJSONSource { + return &testJSONSource{data: data, sig: make(chan struct{}), err: make(chan struct{})} } -func (p *testJsonSource) Load() ([]*KeyValue, error) { +func (p *testJSONSource) Load() ([]*KeyValue, error) { kv := &KeyValue{ Key: "json", Value: []byte(p.data), @@ -79,7 +79,7 @@ func (p *testJsonSource) Load() ([]*KeyValue, error) { return []*KeyValue{kv}, nil } -func (p *testJsonSource) Watch() (Watcher, error) { +func (p *testJSONSource) Watch() (Watcher, error) { return newTestWatcher(p.sig, p.err), nil } @@ -120,7 +120,7 @@ func TestConfig(t *testing.T) { ) c := New( - WithSource(newTestJsonSource(_testJSON)), + WithSource(newTestJSONSource(_testJSON)), WithDecoder(defaultDecoder), WithResolver(defaultResolver), WithLogger(log.DefaultLogger), @@ -128,7 +128,7 @@ func TestConfig(t *testing.T) { err = c.Close() assert.Nil(t, err) - jSource := newTestJsonSource(_testJSON) + jSource := newTestJSONSource(_testJSON) opts := options{ sources: []Source{jSource}, decoder: defaultDecoder, @@ -156,10 +156,10 @@ func TestConfig(t *testing.T) { var testConf testConfigStruct err = cf.Scan(&testConf) assert.Nil(t, err) - assert.Equal(t, httpAddr, testConf.Server.Http.Addr) - assert.Equal(t, httpTimeout, testConf.Server.Http.Timeout) - assert.Equal(t, true, testConf.Server.Http.EnableSSL) - assert.Equal(t, grpcPort, testConf.Server.GRpc.Port) + assert.Equal(t, httpAddr, testConf.Server.HTTP.Addr) + assert.Equal(t, httpTimeout, testConf.Server.HTTP.Timeout) + assert.Equal(t, true, testConf.Server.HTTP.EnableSSL) + assert.Equal(t, grpcPort, testConf.Server.GRPC.Port) assert.Equal(t, endpoint1, testConf.Endpoints[0]) assert.Equal(t, 2, len(testConf.Endpoints)) } diff --git a/config/env/env.go b/config/env/env.go index b024fc0a8..6c104f1c1 100644 --- a/config/env/env.go +++ b/config/env/env.go @@ -23,7 +23,7 @@ func (e *env) load(envStrings []string) []*config.KeyValue { var kv []*config.KeyValue for _, envstr := range envStrings { var k, v string - subs := strings.SplitN(envstr, "=", 2) + subs := strings.SplitN(envstr, "=", 2) //nolint:gomnd k = subs[0] if len(subs) > 1 { v = subs[1] diff --git a/config/env/env_test.go b/config/env/env_test.go index a7d49ef9b..0ddb7c933 100644 --- a/config/env/env_test.go +++ b/config/env/env_test.go @@ -36,10 +36,10 @@ func TestEnvWithPrefix(t *testing.T) { data = []byte(_testJSON) ) defer os.Remove(path) - if err := os.MkdirAll(path, 0700); err != nil { + if err := os.MkdirAll(path, 0o700); err != nil { t.Error(err) } - if err := ioutil.WriteFile(filename, data, 0666); err != nil { + if err := ioutil.WriteFile(filename, data, 0o666); err != nil { t.Error(err) } @@ -148,10 +148,10 @@ func TestEnvWithoutPrefix(t *testing.T) { data = []byte(_testJSON) ) defer os.Remove(path) - if err := os.MkdirAll(path, 0700); err != nil { + if err := os.MkdirAll(path, 0o700); err != nil { t.Error(err) } - if err := ioutil.WriteFile(filename, data, 0666); err != nil { + if err := ioutil.WriteFile(filename, data, 0o666); err != nil { t.Error(err) } diff --git a/config/file/file_test.go b/config/file/file_test.go index 5f9621fa2..383c2e185 100644 --- a/config/file/file_test.go +++ b/config/file/file_test.go @@ -90,10 +90,10 @@ func TestFile(t *testing.T) { data = []byte(_testJSON) ) defer os.Remove(path) - if err := os.MkdirAll(path, 0700); err != nil { + if err := os.MkdirAll(path, 0o700); err != nil { t.Error(err) } - if err := ioutil.WriteFile(file, data, 0666); err != nil { + if err := ioutil.WriteFile(file, data, 0o666); err != nil { t.Error(err) } testSource(t, file, data) @@ -125,7 +125,7 @@ func testWatchFile(t *testing.T, path string) { assert.Equal(t, string(kvs[0].Value), _testJSONUpdate) newFilepath := filepath.Join(filepath.Dir(path), "test1.json") - if err := os.Rename(path, newFilepath); err != nil { + if err = os.Rename(path, newFilepath); err != nil { t.Error(err) } kvs, err = watch.Next() @@ -181,7 +181,7 @@ func testSource(t *testing.T, path string, data []byte) { func TestConfig(t *testing.T) { path := filepath.Join(t.TempDir(), "test_config.json") defer os.Remove(path) - if err := ioutil.WriteFile(path, []byte(_testJSON), 0666); err != nil { + if err := ioutil.WriteFile(path, []byte(_testJSON), 0o666); err != nil { t.Error(err) } c := config.New(config.WithSource( @@ -293,7 +293,7 @@ func testScan(t *testing.T, c config.Config) { func TestMergeDataRace(t *testing.T) { path := filepath.Join(t.TempDir(), "test_config.json") defer os.Remove(path) - if err := ioutil.WriteFile(path, []byte(_testJSON), 0666); err != nil { + if err := ioutil.WriteFile(path, []byte(_testJSON), 0o666); err != nil { t.Error(err) } c := config.New(config.WithSource( diff --git a/config/options.go b/config/options.go index d1cbeced8..0f584a701 100644 --- a/config/options.go +++ b/config/options.go @@ -84,7 +84,7 @@ func defaultDecoder(src *KeyValue, target map[string]interface{}) error { // placeholder format in ${key:default}. func defaultResolver(input map[string]interface{}) error { mapper := func(name string) string { - args := strings.SplitN(strings.TrimSpace(name), ":", 2) + args := strings.SplitN(strings.TrimSpace(name), ":", 2) //nolint:gomnd if v, has := readValue(input, args[0]); has { s, _ := v.String() return s @@ -127,7 +127,7 @@ func expand(s string, mapping func(string) string) string { r := regexp.MustCompile(`\${(.*?)}`) re := r.FindAllStringSubmatch(s, -1) for _, i := range re { - if len(i) == 2 { + if len(i) == 2 { //nolint:gomnd s = strings.ReplaceAll(s, i[0], mapping(i[1])) } } diff --git a/config/options_test.go b/config/options_test.go index dd6bc538e..7aa89424e 100644 --- a/config/options_test.go +++ b/config/options_test.go @@ -13,7 +13,7 @@ func TestDefaultDecoder(t *testing.T) { Value: []byte("config"), Format: "", } - target := make(map[string]interface{}, 0) + target := make(map[string]interface{}) err := defaultDecoder(src, target) assert.Nil(t, err) assert.Equal(t, map[string]interface{}{ @@ -25,7 +25,7 @@ func TestDefaultDecoder(t *testing.T) { Value: []byte("2233"), Format: "", } - target = make(map[string]interface{}, 0) + target = make(map[string]interface{}) err = defaultDecoder(src, target) assert.Nil(t, err) assert.Equal(t, map[string]interface{}{ diff --git a/config/reader_test.go b/config/reader_test.go index 2cec467af..0802c5728 100644 --- a/config/reader_test.go +++ b/config/reader_test.go @@ -120,22 +120,20 @@ a: assert.NoError(t, err) assert.Equal(t, true, vvz) - vv, ok = r.Value("aasasdg=234l.asdfk,") + _, ok = r.Value("aasasdg=234l.asdfk,") assert.False(t, ok) - vv, ok = r.Value("aas......asdg=234l.asdfk,") + _, ok = r.Value("aas......asdg=234l.asdfk,") assert.False(t, ok) - vv, ok = r.Value("a.b.Y.") + _, ok = r.Value("a.b.Y.") assert.False(t, ok) }) } } func TestReader_Source(t *testing.T) { - var ( - err error - ) + var err error opts := options{ decoder: func(kv *KeyValue, v map[string]interface{}) error { if codec := encoding.GetCodec(kv.Format); codec != nil { @@ -151,6 +149,7 @@ func TestReader_Source(t *testing.T) { Value: []byte(`{"a": {"b": {"X": 1}}}`), Format: "json", }) + assert.NoError(t, err) b, err := r.Source() assert.NoError(t, err) assert.Equal(t, []byte(`{"a":{"b":{"X":1}}}`), b) diff --git a/config/value.go b/config/value.go index 8c6b50f82..7c028d44b 100644 --- a/config/value.go +++ b/config/value.go @@ -42,6 +42,7 @@ func (v *atomicValue) Bool() (bool, error) { } return false, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load())) } + func (v *atomicValue) Int() (int64, error) { switch val := v.Load().(type) { case int: @@ -53,10 +54,11 @@ func (v *atomicValue) Int() (int64, error) { case float64: return int64(val), nil case string: - return strconv.ParseInt(val, 10, 64) + return strconv.ParseInt(val, 10, 64) //nolint:gomnd } return 0, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load())) } + func (v *atomicValue) Float() (float64, error) { switch val := v.Load().(type) { case float64: @@ -68,10 +70,11 @@ func (v *atomicValue) Float() (float64, error) { case int64: return float64(val), nil case string: - return strconv.ParseFloat(val, 64) + return strconv.ParseFloat(val, 64) //nolint:gomnd } return 0.0, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load())) } + func (v *atomicValue) String() (string, error) { switch val := v.Load().(type) { case string: @@ -87,6 +90,7 @@ func (v *atomicValue) String() (string, error) { } return "", fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load())) } + func (v *atomicValue) Duration() (time.Duration, error) { val, err := v.Int() if err != nil { @@ -94,6 +98,7 @@ func (v *atomicValue) Duration() (time.Duration, error) { } return time.Duration(val), nil } + func (v *atomicValue) Scan(obj interface{}) error { data, err := json.Marshal(v.Load()) if err != nil { diff --git a/config/value_test.go b/config/value_test.go index 87f18091d..acc754e0d 100644 --- a/config/value_test.go +++ b/config/value_test.go @@ -9,8 +9,7 @@ import ( ) func Test_atomicValue_Bool(t *testing.T) { - var vlist []interface{} - vlist = []interface{}{"1", "t", "T", "true", "TRUE", "True", true, 1, int32(1)} + vlist := []interface{}{"1", "t", "T", "true", "TRUE", "True", true, 1, int32(1)} for _, x := range vlist { v := atomicValue{} v.Store(x) @@ -38,8 +37,7 @@ func Test_atomicValue_Bool(t *testing.T) { } func Test_atomicValue_Int(t *testing.T) { - var vlist []interface{} - vlist = []interface{}{"123123", float64(123123), int64(123123), int32(123123), 123123} + vlist := []interface{}{"123123", float64(123123), int64(123123), int32(123123), 123123} for _, x := range vlist { v := atomicValue{} v.Store(x) @@ -58,8 +56,7 @@ func Test_atomicValue_Int(t *testing.T) { } func Test_atomicValue_Float(t *testing.T) { - var vlist []interface{} - vlist = []interface{}{"123123.1", float64(123123.1)} + vlist := []interface{}{"123123.1", float64(123123.1)} for _, x := range vlist { v := atomicValue{} v.Store(x) @@ -87,8 +84,7 @@ func (t ts) String() string { } func Test_atomicValue_String(t *testing.T) { - var vlist []interface{} - vlist = []interface{}{"1", float64(1), int64(1), 1, int64(1)} + vlist := []interface{}{"1", float64(1), int64(1), 1, int64(1)} for _, x := range vlist { v := atomicValue{} v.Store(x) @@ -114,8 +110,7 @@ func Test_atomicValue_String(t *testing.T) { } func Test_atomicValue_Duration(t *testing.T) { - var vlist []interface{} - vlist = []interface{}{int64(5)} + vlist := []interface{}{int64(5)} for _, x := range vlist { v := atomicValue{} v.Store(x) diff --git a/encoding/encoding_test.go b/encoding/encoding_test.go index f39cef12f..d28865677 100644 --- a/encoding/encoding_test.go +++ b/encoding/encoding_test.go @@ -69,12 +69,10 @@ type PanicTestFunc func() // didPanic returns true if the function passed to it panics. Otherwise, it returns false. func didPanic(f PanicTestFunc) (bool, interface{}, string) { - didPanic := false var message interface{} var stack string func() { - defer func() { if message = recover(); message != nil { didPanic = true @@ -84,9 +82,7 @@ func didPanic(f PanicTestFunc) (bool, interface{}, string) { // call the target function f() - }() return didPanic, message, stack - } diff --git a/encoding/form/form.go b/encoding/form/form.go index 9bb14e17d..1019e14ee 100644 --- a/encoding/form/form.go +++ b/encoding/form/form.go @@ -10,8 +10,12 @@ import ( "google.golang.org/protobuf/proto" ) -// Name is form codec name -const Name = "x-www-form-urlencoded" +const ( + // Name is form codec name + Name = "x-www-form-urlencoded" + // Null value string + nullStr = "null" +) func init() { decoder := form.NewDecoder() diff --git a/encoding/form/form_test.go b/encoding/form/form_test.go index 09f175fbf..15d63b016 100644 --- a/encoding/form/form_test.go +++ b/encoding/form/form_test.go @@ -37,7 +37,7 @@ func TestFormCodecMarshal(t *testing.T) { require.NoError(t, err) require.Equal(t, []byte("username=kratos"), content) - m := TestModel{ + m := &TestModel{ ID: 1, Name: "kratos", } @@ -55,7 +55,7 @@ func TestFormCodecUnmarshal(t *testing.T) { content, err := encoding.GetCodec(contentType).Marshal(req) require.NoError(t, err) - var bindReq = new(LoginRequest) + bindReq := new(LoginRequest) err = encoding.GetCodec(contentType).Unmarshal(content, bindReq) require.NoError(t, err) require.Equal(t, "kratos", bindReq.Username) @@ -72,7 +72,7 @@ func TestProtoEncodeDecode(t *testing.T) { content, err := encoding.GetCodec(contentType).Marshal(in) require.NoError(t, err) require.Equal(t, "id=2233&numberOne=2233&simples=3344&simples=5566&very_simple.component=5566", string(content)) - var in2 = &complex.Complex{} + in2 := &complex.Complex{} err = encoding.GetCodec(contentType).Unmarshal(content, in2) require.NoError(t, err) require.Equal(t, int64(2233), in2.Id) diff --git a/encoding/form/proto_decode.go b/encoding/form/proto_decode.go index 94b12d9c8..9936b8e92 100644 --- a/encoding/form/proto_decode.go +++ b/encoding/form/proto_decode.go @@ -105,7 +105,7 @@ func populateRepeatedField(fd protoreflect.FieldDescriptor, list protoreflect.Li } func populateMapField(fd protoreflect.FieldDescriptor, mp protoreflect.Map, values []string) error { - if len(values) != 2 { + if len(values) != 2 { //nolint:gomnd return fmt.Errorf("more than one value provided for key %q in map %q", values[0], fd.FullName()) } key, err := parseField(fd.MapKey(), values[0]) @@ -138,7 +138,7 @@ func parseField(fd protoreflect.FieldDescriptor, value string) (protoreflect.Val } v := enum.Descriptor().Values().ByName(protoreflect.Name(value)) if v == nil { - i, err := strconv.ParseInt(value, 10, 32) + i, err := strconv.ParseInt(value, 10, 32) //nolint:gomnd if err != nil { return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value) } @@ -149,37 +149,37 @@ func parseField(fd protoreflect.FieldDescriptor, value string) (protoreflect.Val } return protoreflect.ValueOfEnum(v.Number()), nil case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: - v, err := strconv.ParseInt(value, 10, 32) + v, err := strconv.ParseInt(value, 10, 32) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } return protoreflect.ValueOfInt32(int32(v)), nil case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - v, err := strconv.ParseInt(value, 10, 64) + v, err := strconv.ParseInt(value, 10, 64) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } return protoreflect.ValueOfInt64(v), nil case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: - v, err := strconv.ParseUint(value, 10, 32) + v, err := strconv.ParseUint(value, 10, 32) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } return protoreflect.ValueOfUint32(uint32(v)), nil case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - v, err := strconv.ParseUint(value, 10, 64) + v, err := strconv.ParseUint(value, 10, 64) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } return protoreflect.ValueOfUint64(v), nil case protoreflect.FloatKind: - v, err := strconv.ParseFloat(value, 32) + v, err := strconv.ParseFloat(value, 32) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } return protoreflect.ValueOfFloat32(float32(v)), nil case protoreflect.DoubleKind: - v, err := strconv.ParseFloat(value, 64) + v, err := strconv.ParseFloat(value, 64) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } @@ -203,7 +203,7 @@ func parseMessage(md protoreflect.MessageDescriptor, value string) (protoreflect var msg proto.Message switch md.FullName() { case "google.protobuf.Timestamp": - if value == "null" { + if value == nullStr { break } t, err := time.Parse(time.RFC3339Nano, value) @@ -212,7 +212,7 @@ func parseMessage(md protoreflect.MessageDescriptor, value string) (protoreflect } msg = timestamppb.New(t) case "google.protobuf.Duration": - if value == "null" { + if value == nullStr { break } d, err := time.ParseDuration(value) @@ -221,37 +221,37 @@ func parseMessage(md protoreflect.MessageDescriptor, value string) (protoreflect } msg = durationpb.New(d) case "google.protobuf.DoubleValue": - v, err := strconv.ParseFloat(value, 64) + v, err := strconv.ParseFloat(value, 64) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } msg = wrapperspb.Double(v) case "google.protobuf.FloatValue": - v, err := strconv.ParseFloat(value, 32) + v, err := strconv.ParseFloat(value, 32) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } msg = wrapperspb.Float(float32(v)) case "google.protobuf.Int64Value": - v, err := strconv.ParseInt(value, 10, 64) + v, err := strconv.ParseInt(value, 10, 64) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } msg = wrapperspb.Int64(v) case "google.protobuf.Int32Value": - v, err := strconv.ParseInt(value, 10, 32) + v, err := strconv.ParseInt(value, 10, 32) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } msg = wrapperspb.Int32(int32(v)) case "google.protobuf.UInt64Value": - v, err := strconv.ParseUint(value, 10, 64) + v, err := strconv.ParseUint(value, 10, 64) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } msg = wrapperspb.UInt64(v) case "google.protobuf.UInt32Value": - v, err := strconv.ParseUint(value, 10, 32) + v, err := strconv.ParseUint(value, 10, 32) //nolint:gomnd if err != nil { return protoreflect.Value{}, err } diff --git a/encoding/form/proto_encode.go b/encoding/form/proto_encode.go index 45a5f08f0..13fbcde4e 100644 --- a/encoding/form/proto_encode.go +++ b/encoding/form/proto_encode.go @@ -132,7 +132,7 @@ func encodeField(fieldDescriptor protoreflect.FieldDescriptor, value protoreflec return strconv.FormatBool(value.Bool()), nil case protoreflect.EnumKind: if fieldDescriptor.Enum().FullName() == "google.protobuf.NullValue" { - return "null", nil + return nullStr, nil } desc := fieldDescriptor.Enum().Values().ByNumber(value.Enum()) return string(desc.Name()), nil diff --git a/encoding/proto/proto_test.go b/encoding/proto/proto_test.go index 13bc685f9..bba1b0c0c 100644 --- a/encoding/proto/proto_test.go +++ b/encoding/proto/proto_test.go @@ -1,9 +1,10 @@ package proto import ( - "github.com/stretchr/testify/assert" "testing" + "github.com/stretchr/testify/assert" + testData "github.com/go-kratos/kratos/v2/internal/testdata/encoding" ) diff --git a/encoding/xml/xml_test.go b/encoding/xml/xml_test.go index 685d7bc07..6c53c3dd0 100644 --- a/encoding/xml/xml_test.go +++ b/encoding/xml/xml_test.go @@ -65,15 +65,15 @@ func TestCodec_Unmarshal(t *testing.T) { `B` + `A` + `` + - ``}, + ``, + }, } for _, tt := range tests { vt := reflect.TypeOf(tt.want) dest := reflect.New(vt.Elem()).Interface() data := []byte(tt.InputXML) - codec := codec{} - err := codec.Unmarshal(data, dest) + err := (codec{}).Unmarshal(data, dest) if err != nil { t.Errorf("unmarshal(%#v, %#v): %s", tt.InputXML, dest, err) } @@ -84,7 +84,6 @@ func TestCodec_Unmarshal(t *testing.T) { } func TestCodec_NilUnmarshal(t *testing.T) { - tests := []struct { want interface{} InputXML string @@ -97,7 +96,8 @@ func TestCodec_NilUnmarshal(t *testing.T) { `B` + `A` + `` + - ``}, + ``, + }, } for _, tt := range tests { diff --git a/encoding/yaml/yaml_test.go b/encoding/yaml/yaml_test.go index 6459e6569..5cb746497 100644 --- a/encoding/yaml/yaml_test.go +++ b/encoding/yaml/yaml_test.go @@ -7,7 +7,6 @@ import ( ) func TestCodec_Unmarshal(t *testing.T) { - tests := []struct { data string value interface{} @@ -18,45 +17,59 @@ func TestCodec_Unmarshal(t *testing.T) { }, { "{}", &struct{}{}, - }, { + }, + { "v: hi", map[string]string{"v": "hi"}, - }, { + }, + { "v: hi", map[string]interface{}{"v": "hi"}, - }, { + }, + { "v: true", map[string]string{"v": "true"}, - }, { + }, + { "v: true", map[string]interface{}{"v": true}, - }, { + }, + { "v: 10", map[string]interface{}{"v": 10}, - }, { + }, + { "v: 0b10", map[string]interface{}{"v": 2}, - }, { + }, + { "v: 0xA", map[string]interface{}{"v": 10}, - }, { + }, + { "v: 4294967296", map[string]int64{"v": 4294967296}, - }, { + }, + { "v: 0.1", map[string]interface{}{"v": 0.1}, - }, { + }, + { "v: .1", map[string]interface{}{"v": 0.1}, - }, { + }, + { "v: .Inf", map[string]interface{}{"v": math.Inf(+1)}, - }, { + }, + { "v: -.Inf", map[string]interface{}{"v": math.Inf(-1)}, - }, { + }, + { "v: -10", map[string]interface{}{"v": -10}, - }, { + }, + { "v: -.1", map[string]interface{}{"v": -0.1}, }, @@ -77,7 +90,6 @@ func TestCodec_Unmarshal(t *testing.T) { if err != nil { t.Fatalf("(codec{}).Unmarshal should not return err") } - } func TestCodec_Marshal(t *testing.T) { diff --git a/errors/errors.go b/errors/errors.go index 2f561d075..351830cb4 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -73,7 +73,7 @@ func Errorf(code int, reason, format string, a ...interface{}) error { // It supports wrapped errors. func Code(err error) int { if err == nil { - return 200 + return 200 //nolint:gomnd } if se := FromError(err); se != nil { return int(se.Code) diff --git a/errors/errors_test.go b/errors/errors_test.go index b7e5fd1b0..b92879505 100644 --- a/errors/errors_test.go +++ b/errors/errors_test.go @@ -8,9 +8,7 @@ import ( ) func TestError(t *testing.T) { - var ( - base *Error - ) + var base *Error err := Newf(http.StatusBadRequest, "reason", "message") err2 := Newf(http.StatusBadRequest, "reason", "message") err3 := err.WithMetadata(map[string]string{ @@ -45,7 +43,7 @@ func TestError(t *testing.T) { gs := err.GRPCStatus() se := FromError(gs.Err()) - if se.Reason != se.Reason { + if se.Reason != "reason" { t.Errorf("got %+v want %+v", se, err) } } diff --git a/errors/types.go b/errors/types.go index e72d5555b..f561870b0 100644 --- a/errors/types.go +++ b/errors/types.go @@ -1,3 +1,4 @@ +// nolint:gomnd package errors // BadRequest new BadRequest error that is mapped to a 400 response. diff --git a/internal/context/context_test.go b/internal/context/context_test.go index 19d5b35d9..bfbddc05b 100644 --- a/internal/context/context_test.go +++ b/internal/context/context_test.go @@ -10,18 +10,20 @@ import ( ) func TestContext(t *testing.T) { - ctx1 := context.WithValue(context.Background(), "go-kratos", "https://github.com/go-kratos/") - ctx2 := context.WithValue(context.Background(), "kratos", "https://go-kratos.dev/") + type ctxKey1 struct{} + type ctxKey2 struct{} + ctx1 := context.WithValue(context.Background(), ctxKey1{}, "https://github.com/go-kratos/") + ctx2 := context.WithValue(context.Background(), ctxKey2{}, "https://go-kratos.dev/") ctx, cancel := Merge(ctx1, ctx2) defer cancel() - got := ctx.Value("go-kratos") + got := ctx.Value(ctxKey1{}) value1, ok := got.(string) assert.Equal(t, ok, true) assert.Equal(t, value1, "https://github.com/go-kratos/") - // - got2 := ctx.Value("kratos") + + got2 := ctx.Value(ctxKey2{}) value2, ok := got2.(string) assert.Equal(t, ok, true) assert.Equal(t, value2, "https://go-kratos.dev/") @@ -30,15 +32,27 @@ func TestContext(t *testing.T) { t.Log(value2) } -func TestMerge2(t *testing.T) { +func TestMerge(t *testing.T) { + type ctxKey1 struct{} + type ctxKey2 struct{} ctx, cancel := context.WithCancel(context.Background()) cancel() - ctx1 := context.WithValue(context.Background(), "go-kratos", "https://github.com/go-kratos/") - ctx2 := context.WithValue(ctx, "kratos", "https://go-kratos.dev/") + ctx1 := context.WithValue(context.Background(), ctxKey1{}, "https://github.com/go-kratos/") + ctx2 := context.WithValue(ctx, ctxKey2{}, "https://go-kratos.dev/") ctx, cancel = Merge(ctx1, ctx2) defer cancel() + got := ctx.Value(ctxKey1{}) + value1, ok := got.(string) + assert.Equal(t, ok, true) + assert.Equal(t, value1, "https://github.com/go-kratos/") + + got2 := ctx.Value(ctxKey2{}) + value2, ok := got2.(string) + assert.Equal(t, ok, true) + assert.Equal(t, value2, "https://go-kratos.dev/") + t.Log(ctx) } @@ -165,7 +179,6 @@ func Test_mergeCtx_Deadline(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - var parent1, parent2 context.Context var cancel1, cancel2 context.CancelFunc if reflect.DeepEqual(tt.fields.parent1Timeout, time.Time{}) { diff --git a/internal/host/host.go b/internal/host/host.go index dd7c23e73..3f1418aaf 100644 --- a/internal/host/host.go +++ b/internal/host/host.go @@ -8,14 +8,12 @@ import ( // ExtractHostPort from address func ExtractHostPort(addr string) (host string, port uint64, err error) { - var ( - ports string - ) + var ports string host, ports, err = net.SplitHostPort(addr) if err != nil { return } - port, err = strconv.ParseUint(ports, 10, 16) + port, err = strconv.ParseUint(ports, 10, 16) //nolint:gomnd if err != nil { return } diff --git a/internal/host/host_test.go b/internal/host/host_test.go index cf866274d..f8f63629d 100644 --- a/internal/host/host_test.go +++ b/internal/host/host_test.go @@ -1,9 +1,10 @@ package host import ( - "github.com/stretchr/testify/assert" "net" "testing" + + "github.com/stretchr/testify/assert" ) func TestValidIP(t *testing.T) { @@ -118,4 +119,5 @@ func TestExtractHostPort(t *testing.T) { if err == nil { t.Fatalf("expected: not nil got %v", nil) } + t.Logf("host port: %s, %d", host, port) } diff --git a/internal/httputil/http_test.go b/internal/httputil/http_test.go index 11b934a37..fcf9a0203 100644 --- a/internal/httputil/http_test.go +++ b/internal/httputil/http_test.go @@ -1,9 +1,10 @@ package httputil import ( - "google.golang.org/grpc/codes" "net/http" "testing" + + "google.golang.org/grpc/codes" ) func TestContentSubtype(t *testing.T) { @@ -31,7 +32,6 @@ func TestContentSubtype(t *testing.T) { } func TestGRPCCodeFromStatus(t *testing.T) { - tests := []struct { name string code int @@ -95,7 +95,6 @@ func TestStatusFromGRPCCode(t *testing.T) { } func TestContentType(t *testing.T) { - tests := []struct { name string subtype string diff --git a/log/filter.go b/log/filter.go index 48ef7097a..9258f3f36 100644 --- a/log/filter.go +++ b/log/filter.go @@ -3,6 +3,8 @@ package log // FilterOption is filter option. type FilterOption func(*Filter) +const fuzzyStr = "***" + // FilterLevel with filter level. func FilterLevel(level Level) FilterOption { return func(opts *Filter) { @@ -72,10 +74,10 @@ func (f *Filter) Log(level Level, keyvals ...interface{}) error { continue } if _, ok := f.key[keyvals[i]]; ok { - keyvals[v] = "***" + keyvals[v] = fuzzyStr } if _, ok := f.value[keyvals[v]]; ok { - keyvals[v] = "***" + keyvals[v] = fuzzyStr } } } diff --git a/log/filter_test.go b/log/filter_test.go index 386ee81cb..4033a7c2c 100644 --- a/log/filter_test.go +++ b/log/filter_test.go @@ -19,6 +19,7 @@ func TestFilterAll(t *testing.T) { log.Infow("username", "kratos") log.Warn("warn log") } + func TestFilterLevel(t *testing.T) { logger := With(DefaultLogger, "ts", DefaultTimestamp, "caller", DefaultCaller) log := NewHelper(NewFilter(NewFilter(logger, FilterLevel(LevelWarn)))) @@ -32,7 +33,7 @@ func TestFilterLevel(t *testing.T) { func TestFilterCaller(t *testing.T) { logger := With(DefaultLogger, "ts", DefaultTimestamp, "caller", DefaultCaller) log := NewFilter(logger) - log.Log(LevelDebug, "msg1", "te1st debug") + _ = log.Log(LevelDebug, "msg1", "te1st debug") logHelper := NewHelper(NewFilter(logger)) logHelper.Log(LevelDebug, "msg1", "te1st debug") } @@ -83,7 +84,7 @@ func testFilterFunc(level Level, keyvals ...interface{}) bool { } for i := 0; i < len(keyvals); i++ { if keyvals[i] == "password" { - keyvals[i+1] = "***" + keyvals[i+1] = fuzzyStr } } return false diff --git a/log/helper_test.go b/log/helper_test.go index 42282a3ca..7afc344c0 100644 --- a/log/helper_test.go +++ b/log/helper_test.go @@ -46,18 +46,20 @@ func BenchmarkHelperPrintw(b *testing.B) { } } +type traceKey struct{} + func TestContext(t *testing.T) { logger := With(NewStdLogger(os.Stdout), "trace", Trace(), ) log := NewHelper(logger) - ctx := context.WithValue(context.Background(), "trace_id", "2233") + ctx := context.WithValue(context.Background(), traceKey{}, "2233") log.WithContext(ctx).Info("got trace!") } func Trace() Valuer { return func(ctx context.Context) interface{} { - s := ctx.Value("trace_id").(string) + s := ctx.Value(traceKey{}).(string) return s } } diff --git a/log/log.go b/log/log.go index 1a5032ac2..d5d2a89b6 100644 --- a/log/log.go +++ b/log/log.go @@ -5,10 +5,8 @@ import ( "log" ) -var ( - // DefaultLogger is default logger. - DefaultLogger Logger = NewStdLogger(log.Writer()) -) +// DefaultLogger is default logger. +var DefaultLogger Logger = NewStdLogger(log.Writer()) // Logger is a logger interface. type Logger interface { diff --git a/log/log_test.go b/log/log_test.go index a320f8da4..27a25ad6f 100644 --- a/log/log_test.go +++ b/log/log_test.go @@ -8,7 +8,7 @@ import ( func TestInfo(t *testing.T) { logger := DefaultLogger logger = With(logger, "ts", DefaultTimestamp, "caller", DefaultCaller) - logger.Log(LevelInfo, "key1", "value1") + _ = logger.Log(LevelInfo, "key1", "value1") } func TestWrapper(t *testing.T) { @@ -16,5 +16,5 @@ func TestWrapper(t *testing.T) { err := NewStdLogger(os.Stderr) l := With(MultiLogger(out, err), "ts", DefaultTimestamp, "caller", DefaultCaller) - l.Log(LevelInfo, "msg", "test") + _ = l.Log(LevelInfo, "msg", "test") } diff --git a/log/std.go b/log/std.go index a26258d09..8d79f5c53 100644 --- a/log/std.go +++ b/log/std.go @@ -40,7 +40,7 @@ func (l *stdLogger) Log(level Level, keyvals ...interface{}) error { for i := 0; i < len(keyvals); i += 2 { _, _ = fmt.Fprintf(buf, " %s=%v", keyvals[i], keyvals[i+1]) } - _ = l.log.Output(4, buf.String()) + _ = l.log.Output(4, buf.String()) //nolint:gomnd buf.Reset() l.pool.Put(buf) return nil diff --git a/log/std_test.go b/log/std_test.go index dc11b3a89..0f11fe2f9 100644 --- a/log/std_test.go +++ b/log/std_test.go @@ -6,8 +6,8 @@ func TestStdLogger(t *testing.T) { logger := DefaultLogger logger = With(logger, "caller", DefaultCaller, "ts", DefaultTimestamp) - logger.Log(LevelInfo, "msg", "test debug") - logger.Log(LevelInfo, "msg", "test info") - logger.Log(LevelInfo, "msg", "test warn") - logger.Log(LevelInfo, "msg", "test error") + _ = logger.Log(LevelInfo, "msg", "test debug") + _ = logger.Log(LevelInfo, "msg", "test info") + _ = logger.Log(LevelInfo, "msg", "test warn") + _ = logger.Log(LevelInfo, "msg", "test error") } diff --git a/log/value.go b/log/value.go index ba17f0f13..8f247715b 100644 --- a/log/value.go +++ b/log/value.go @@ -9,8 +9,9 @@ import ( ) var ( + defaultDepth = 3 // DefaultCaller is a Valuer that returns the file and line. - DefaultCaller = Caller(3) + DefaultCaller = Caller(defaultDepth) // DefaultTimestamp is a Valuer that returns the current wallclock time. DefaultTimestamp = Timestamp(time.RFC3339) diff --git a/log/value_test.go b/log/value_test.go index 713ba7b8b..adc3ed9b9 100644 --- a/log/value_test.go +++ b/log/value_test.go @@ -5,5 +5,5 @@ import "testing" func TestValue(t *testing.T) { logger := DefaultLogger logger = With(logger, "ts", DefaultTimestamp, "caller", DefaultCaller) - logger.Log(LevelInfo, "msg", "helloworld") + _ = logger.Log(LevelInfo, "msg", "helloworld") } diff --git a/metadata/metadata_test.go b/metadata/metadata_test.go index 55439b16f..b7f7173b0 100644 --- a/metadata/metadata_test.go +++ b/metadata/metadata_test.go @@ -241,7 +241,7 @@ func TestMergeToClientContext(t *testing.T) { func TestMetadata_Range(t *testing.T) { md := Metadata{"kratos": "kratos", "https://go-kratos.dev/": "https://go-kratos.dev/", "go-kratos": "go-kratos"} - var tmp = Metadata{} + tmp := Metadata{} md.Range(func(k, v string) bool { if k == "https://go-kratos.dev/" || k == "kratos" { tmp[k] = v diff --git a/middleware/logging/logging_test.go b/middleware/logging/logging_test.go index 425e30729..0427d11e8 100644 --- a/middleware/logging/logging_test.go +++ b/middleware/logging/logging_test.go @@ -11,9 +11,7 @@ import ( "github.com/go-kratos/kratos/v2/transport" ) -var ( - _ transport.Transporter = &Transport{} -) +var _ transport.Transporter = &Transport{} type Transport struct { kind transport.Kind @@ -24,23 +22,27 @@ type Transport struct { func (tr *Transport) Kind() transport.Kind { return tr.kind } + func (tr *Transport) Endpoint() string { return tr.endpoint } + func (tr *Transport) Operation() string { return tr.operation } + func (tr *Transport) RequestHeader() transport.Header { return nil } + func (tr *Transport) ReplyHeader() transport.Header { return nil } func TestHTTP(t *testing.T) { - var err = errors.New("reply.error") - var bf = bytes.NewBuffer(nil) - var logger = log.NewStdLogger(bf) + err := errors.New("reply.error") + bf := bytes.NewBuffer(nil) + logger := log.NewStdLogger(bf) tests := []struct { name string @@ -48,29 +50,32 @@ func TestHTTP(t *testing.T) { err error ctx context.Context }{ - {"http-server@fail", + { + "http-server@fail", Server, err, func() context.Context { return transport.NewServerContext(context.Background(), &Transport{kind: transport.KindHTTP, endpoint: "endpoint", operation: "/package.service/method"}) }(), }, - {"http-server@succ", + { + "http-server@succ", Server, nil, func() context.Context { return transport.NewServerContext(context.Background(), &Transport{kind: transport.KindHTTP, endpoint: "endpoint", operation: "/package.service/method"}) }(), }, - {"http-client@succ", + { + "http-client@succ", Client, nil, func() context.Context { return transport.NewClientContext(context.Background(), &Transport{kind: transport.KindHTTP, endpoint: "endpoint", operation: "/package.service/method"}) - }(), }, - {"http-client@fail", + { + "http-client@fail", Client, err, func() context.Context { diff --git a/middleware/metrics/metrics_test.go b/middleware/metrics/metrics_test.go index 10f5bfe34..3cb2a1b2f 100644 --- a/middleware/metrics/metrics_test.go +++ b/middleware/metrics/metrics_test.go @@ -2,8 +2,9 @@ package metrics import ( "context" - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestMetrics(t *testing.T) { diff --git a/middleware/recovery/recovery.go b/middleware/recovery/recovery.go index ed9613e96..83083c054 100644 --- a/middleware/recovery/recovery.go +++ b/middleware/recovery/recovery.go @@ -51,7 +51,7 @@ func Recovery(opts ...Option) middleware.Middleware { return func(ctx context.Context, req interface{}) (reply interface{}, err error) { defer func() { if rerr := recover(); rerr != nil { - buf := make([]byte, 64<<10) + buf := make([]byte, 64<<10) //nolint:gomnd n := runtime.Stack(buf, false) buf = buf[:n] logger.Errorf("%v: %+v\n%s\n", rerr, req, buf) diff --git a/middleware/selector/selector_test.go b/middleware/selector/selector_test.go index 8a00fc07b..4554e295a 100644 --- a/middleware/selector/selector_test.go +++ b/middleware/selector/selector_test.go @@ -9,9 +9,7 @@ import ( "github.com/go-kratos/kratos/v2/transport" ) -var ( - _ transport.Transporter = &Transport{} -) +var _ transport.Transporter = &Transport{} type Transport struct { kind transport.Kind @@ -22,21 +20,24 @@ type Transport struct { func (tr *Transport) Kind() transport.Kind { return tr.kind } + func (tr *Transport) Endpoint() string { return tr.endpoint } + func (tr *Transport) Operation() string { return tr.operation } + func (tr *Transport) RequestHeader() transport.Header { return nil } + func (tr *Transport) ReplyHeader() transport.Header { return nil } func TestMatch(t *testing.T) { - tests := []struct { name string ctx context.Context @@ -67,13 +68,12 @@ func TestMatch(t *testing.T) { } next = Server(testMiddleware).Prefix("/hello/").Regex(`/test/[0-9]+`). Path("/example/kratos").Build()(next) - next(test.ctx, test.name) + _, _ = next(test.ctx, test.name) }) } } func TestMatchClient(t *testing.T) { - tests := []struct { name string ctx context.Context @@ -104,7 +104,7 @@ func TestMatchClient(t *testing.T) { } next = Client(testMiddleware).Prefix("/hello/").Regex(`/test/[0-9]+`). Path("/example/kratos").Build()(next) - next(test.ctx, test.name) + _, _ = next(test.ctx, test.name) }) } } diff --git a/middleware/tracing/metadata.go b/middleware/tracing/metadata.go index 687d89fec..7e8cbe951 100644 --- a/middleware/tracing/metadata.go +++ b/middleware/tracing/metadata.go @@ -2,6 +2,7 @@ package tracing import ( "context" + "github.com/go-kratos/kratos/v2" "github.com/go-kratos/kratos/v2/metadata" "go.opentelemetry.io/otel/propagation" diff --git a/middleware/tracing/metadata_test.go b/middleware/tracing/metadata_test.go index 22a14993d..2d0588f41 100644 --- a/middleware/tracing/metadata_test.go +++ b/middleware/tracing/metadata_test.go @@ -36,7 +36,7 @@ func TestMetadata_Inject(t *testing.T) { t.Run(tt.name, func(t *testing.T) { a := kratos.New(kratos.Name(tt.args.appName)) ctx := kratos.NewContext(context.Background(), a) - var m = new(Metadata) + m := new(Metadata) m.Inject(ctx, tt.args.carrier) if res := tt.args.carrier.Get(serviceHeader); tt.want != res { t.Errorf("Get(serviceHeader) :%s want: %s", res, tt.want) diff --git a/middleware/tracing/span.go b/middleware/tracing/span.go index b8acf3708..81334872a 100644 --- a/middleware/tracing/span.go +++ b/middleware/tracing/span.go @@ -96,7 +96,7 @@ func setServerSpan(ctx context.Context, span trace.Span, m interface{}) { func parseFullMethod(fullMethod string) (string, []attribute.KeyValue) { name := strings.TrimLeft(fullMethod, "/") parts := strings.SplitN(name, "/", 2) - if len(parts) != 2 { + if len(parts) != 2 { //nolint:gomnd // Invalid format, does not follow `/package.service/method`. return name, []attribute.KeyValue{attribute.Key("rpc.operation").String(fullMethod)} } diff --git a/middleware/tracing/statsHandler.go b/middleware/tracing/statsHandler.go index 70c9efdc2..b5cb1233b 100644 --- a/middleware/tracing/statsHandler.go +++ b/middleware/tracing/statsHandler.go @@ -9,8 +9,7 @@ import ( ) // ClientHandler is tracing ClientHandler -type ClientHandler struct { -} +type ClientHandler struct{} // HandleConn exists to satisfy gRPC stats.Handler. func (c *ClientHandler) HandleConn(ctx context.Context, cs stats.ConnStats) { diff --git a/middleware/tracing/tracing_test.go b/middleware/tracing/tracing_test.go index 7725c0308..40ada4dac 100644 --- a/middleware/tracing/tracing_test.go +++ b/middleware/tracing/tracing_test.go @@ -11,9 +11,7 @@ import ( "go.opentelemetry.io/otel/trace" ) -var ( - _ transport.Transporter = &Transport{} -) +var _ transport.Transporter = &Transport{} type headerCarrier http.Header @@ -50,11 +48,18 @@ func (tr *Transport) RequestHeader() transport.Header { return tr.header } func (tr *Transport) ReplyHeader() transport.Header { return tr.header } func TestTracing(t *testing.T) { - var carrier = headerCarrier{} + carrier := headerCarrier{} tp := tracesdk.NewTracerProvider(tracesdk.WithSampler(tracesdk.TraceIDRatioBased(0))) // caller use Inject - tracer := NewTracer(trace.SpanKindClient, WithTracerProvider(tp), WithPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{}))) + tracer := NewTracer( + trace.SpanKindClient, + WithTracerProvider(tp), + WithPropagator( + propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{}), + ), + ) + ts := &Transport{kind: transport.KindHTTP, header: carrier} ctx, aboveSpan := tracer.Start(transport.NewClientContext(context.Background(), ts), ts.Operation(), ts.RequestHeader()) diff --git a/options_test.go b/options_test.go index c7f34287b..199457597 100644 --- a/options_test.go +++ b/options_test.go @@ -56,8 +56,9 @@ func TestEndpoint(t *testing.T) { } func TestContext(t *testing.T) { + type ctxKey = struct{} o := &options{} - v := context.WithValue(context.TODO(), "a", "b") + v := context.WithValue(context.TODO(), ctxKey{}, "b") Context(v)(o) assert.Equal(t, v, o.ctx) } @@ -102,6 +103,7 @@ type mockRegistrar struct{} func (m *mockRegistrar) Register(ctx context.Context, service *registry.ServiceInstance) error { return nil } + func (m *mockRegistrar) Deregister(ctx context.Context, service *registry.ServiceInstance) error { return nil } diff --git a/registry/consul/registry.go b/registry/consul/registry.go index 5101686c2..be828ecbb 100644 --- a/registry/consul/registry.go +++ b/registry/consul/registry.go @@ -76,9 +76,7 @@ func (r *Registry) GetService(ctx context.Context, name string) (services []*reg if ss == nil { return nil, fmt.Errorf("service %s not found in registry", name) } - for _, s := range ss { - services = append(services, s) - } + services = append(services, ss...) return } @@ -93,9 +91,7 @@ func (r *Registry) ListServices() (allServices map[string][]*registry.ServiceIns if ss == nil { continue } - for _, s := range ss { - services = append(services, s) - } + services = append(services, ss...) allServices[name] = services } return diff --git a/transport/grpc/client.go b/transport/grpc/client.go index f2495e801..9982bcf9d 100644 --- a/transport/grpc/client.go +++ b/transport/grpc/client.go @@ -100,13 +100,13 @@ func dial(ctx context.Context, insecure bool, opts ...ClientOption) (*grpc.Clien for _, o := range opts { o(&options) } - var ints = []grpc.UnaryClientInterceptor{ + ints := []grpc.UnaryClientInterceptor{ unaryClientInterceptor(options.middleware, options.timeout), } if len(options.ints) > 0 { ints = append(ints, options.ints...) } - var grpcOpts = []grpc.DialOption{ + grpcOpts := []grpc.DialOption{ grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, roundrobin.Name)), grpc.WithChainUnaryInterceptor(ints...), } diff --git a/transport/grpc/client_test.go b/transport/grpc/client_test.go index 89122cbf2..f18b61833 100644 --- a/transport/grpc/client_test.go +++ b/transport/grpc/client_test.go @@ -40,6 +40,7 @@ type mockRegistry struct{} func (m *mockRegistry) GetService(ctx context.Context, serviceName string) ([]*registry.ServiceInstance, error) { return nil, nil } + func (m *mockRegistry) Watch(ctx context.Context, serviceName string) (registry.Watcher, error) { return nil, nil } @@ -71,9 +72,10 @@ func TestUnaryClientInterceptor(t *testing.T) { req := &struct{}{} resp := &struct{}{} - err := f(context.TODO(), "hello", req, resp, &grpc.ClientConn{}, func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, opts ...grpc.CallOption) error { - return nil - }) + err := f(context.TODO(), "hello", req, resp, &grpc.ClientConn{}, + func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, opts ...grpc.CallOption) error { + return nil + }) assert.NoError(t, err) } diff --git a/transport/grpc/resolver/direct/builder.go b/transport/grpc/resolver/direct/builder.go index dd1ba1148..560d0ec0e 100644 --- a/transport/grpc/resolver/direct/builder.go +++ b/transport/grpc/resolver/direct/builder.go @@ -20,7 +20,7 @@ func NewBuilder() resolver.Builder { } func (d *directBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) { - var addrs []resolver.Address + addrs := make([]resolver.Address, 0) for _, addr := range strings.Split(target.Endpoint, ",") { addrs = append(addrs, resolver.Address{Addr: addr}) } diff --git a/transport/grpc/resolver/direct/builder_test.go b/transport/grpc/resolver/direct/builder_test.go index 8db9cddda..3ae747e02 100644 --- a/transport/grpc/resolver/direct/builder_test.go +++ b/transport/grpc/resolver/direct/builder_test.go @@ -1,10 +1,11 @@ package direct import ( + "testing" + "github.com/stretchr/testify/assert" "google.golang.org/grpc/resolver" "google.golang.org/grpc/serviceconfig" - "testing" ) func TestDirectBuilder_Scheme(t *testing.T) { @@ -12,8 +13,7 @@ func TestDirectBuilder_Scheme(t *testing.T) { assert.Equal(t, "direct", b.Scheme()) } -type mockConn struct { -} +type mockConn struct{} func (m *mockConn) UpdateState(resolver.State) error { return nil diff --git a/transport/grpc/resolver/discovery/builder_test.go b/transport/grpc/resolver/discovery/builder_test.go index c68120c5d..81ffcdcce 100644 --- a/transport/grpc/resolver/discovery/builder_test.go +++ b/transport/grpc/resolver/discovery/builder_test.go @@ -2,13 +2,14 @@ package discovery import ( "context" + "testing" + "time" + "github.com/go-kratos/kratos/v2/log" "github.com/go-kratos/kratos/v2/registry" "github.com/stretchr/testify/assert" "google.golang.org/grpc/resolver" "google.golang.org/grpc/serviceconfig" - "testing" - "time" ) type mockLogger struct { @@ -42,12 +43,12 @@ func TestWithTimeout(t *testing.T) { assert.Equal(t, v, o.timeout) } -type mockDiscovery struct { -} +type mockDiscovery struct{} func (m *mockDiscovery) GetService(ctx context.Context, serviceName string) ([]*registry.ServiceInstance, error) { return nil, nil } + func (m *mockDiscovery) Watch(ctx context.Context, serviceName string) (registry.Watcher, error) { return &testWatch{}, nil } @@ -57,8 +58,7 @@ func TestBuilder_Scheme(t *testing.T) { assert.Equal(t, "discovery", b.Scheme()) } -type mockConn struct { -} +type mockConn struct{} func (m *mockConn) UpdateState(resolver.State) error { return nil diff --git a/transport/grpc/resolver/discovery/resolver.go b/transport/grpc/resolver/discovery/resolver.go index c7eeb32e5..a02f2cc57 100644 --- a/transport/grpc/resolver/discovery/resolver.go +++ b/transport/grpc/resolver/discovery/resolver.go @@ -45,7 +45,7 @@ func (r *discoveryResolver) watch() { } func (r *discoveryResolver) update(ins []*registry.ServiceInstance) { - var addrs []resolver.Address + addrs := make([]resolver.Address, 0) for _, in := range ins { endpoint, err := endpoint.ParseEndpoint(in.Endpoints, "grpc", !r.insecure) if err != nil { diff --git a/transport/grpc/server.go b/transport/grpc/server.go index c2aaf2fbf..4b1fe9b16 100644 --- a/transport/grpc/server.go +++ b/transport/grpc/server.go @@ -25,8 +25,10 @@ import ( "google.golang.org/grpc/reflection" ) -var _ transport.Server = (*Server)(nil) -var _ transport.Endpointer = (*Server)(nil) +var ( + _ transport.Server = (*Server)(nil) + _ transport.Endpointer = (*Server)(nil) +) // ServerOption is gRPC server option. type ServerOption func(o *Server) @@ -119,13 +121,13 @@ func NewServer(opts ...ServerOption) *Server { for _, o := range opts { o(srv) } - var ints = []grpc.UnaryServerInterceptor{ + ints := []grpc.UnaryServerInterceptor{ srv.unaryServerInterceptor(), } if len(srv.ints) > 0 { ints = append(ints, srv.ints...) } - var grpcOpts = []grpc.ServerOption{ + grpcOpts := []grpc.ServerOption{ grpc.ChainUnaryInterceptor(ints...), } if srv.tlsConf != nil { diff --git a/transport/grpc/server_test.go b/transport/grpc/server_test.go index 1e9d6c327..4af5e4541 100644 --- a/transport/grpc/server_test.go +++ b/transport/grpc/server_test.go @@ -3,14 +3,15 @@ package grpc import ( "context" "crypto/tls" - "github.com/go-kratos/kratos/v2/log" - "github.com/go-kratos/kratos/v2/middleware" - "google.golang.org/grpc" "net/url" "strings" "testing" "time" + "github.com/go-kratos/kratos/v2/log" + "github.com/go-kratos/kratos/v2/middleware" + "google.golang.org/grpc" + "github.com/stretchr/testify/assert" ) @@ -35,7 +36,7 @@ func TestServer(t *testing.T) { }() time.Sleep(time.Second) testClient(t, srv) - srv.Stop(ctx) + _ = srv.Stop(ctx) } func testClient(t *testing.T, srv *Server) { @@ -48,7 +49,7 @@ func testClient(t *testing.T, srv *Server) { if err != nil { t.Fatal(err) } - conn.Close() + _ = conn.Close() } func TestNetwork(t *testing.T) { @@ -141,7 +142,8 @@ type testResp struct { func TestServer_unaryServerInterceptor(t *testing.T) { u, err := url.Parse("grpc://hello/world") assert.NoError(t, err) - srv := &Server{ctx: context.Background(), + srv := &Server{ + ctx: context.Background(), endpoint: u, middleware: []middleware.Middleware{EmptyMiddleware()}, timeout: time.Duration(10), diff --git a/transport/grpc/transport.go b/transport/grpc/transport.go index b025cc7f0..3f07e7443 100644 --- a/transport/grpc/transport.go +++ b/transport/grpc/transport.go @@ -5,9 +5,7 @@ import ( "google.golang.org/grpc/metadata" ) -var ( - _ transport.Transporter = &Transport{} -) +var _ transport.Transporter = &Transport{} // Transport is a gRPC transport. type Transport struct { diff --git a/transport/grpc/transport_test.go b/transport/grpc/transport_test.go index 6cbb4c260..c0684054e 100644 --- a/transport/grpc/transport_test.go +++ b/transport/grpc/transport_test.go @@ -1,9 +1,10 @@ package grpc import ( - "github.com/stretchr/testify/assert" "testing" + "github.com/stretchr/testify/assert" + "github.com/go-kratos/kratos/v2/transport" ) @@ -30,7 +31,6 @@ func TestTransport_RequestHeader(t *testing.T) { o := &Transport{reqHeader: v} assert.Equal(t, "1", o.RequestHeader().Get("a")) assert.Equal(t, "", o.RequestHeader().Get("notfound")) - } func TestTransport_ReplyHeader(t *testing.T) { diff --git a/transport/http/binding/encode.go b/transport/http/binding/encode.go index 103cfa6fe..c5dbd0cc6 100644 --- a/transport/http/binding/encode.go +++ b/transport/http/binding/encode.go @@ -30,7 +30,7 @@ func EncodeURL(pathTemplate string, msg proto.Message, needQuery bool) string { } pathParams := make(map[string]struct{}) path := reg.ReplaceAllStringFunc(pathTemplate, func(in string) string { - if len(in) < 4 { + if len(in) < 4 { //nolint:gomnd // ** explain the 4 number here :-) ** return in } key := in[2 : len(in)-1] diff --git a/transport/http/client_test.go b/transport/http/client_test.go index 8aaee2b51..0a2872c5d 100644 --- a/transport/http/client_test.go +++ b/transport/http/client_test.go @@ -16,8 +16,7 @@ import ( "github.com/stretchr/testify/assert" ) -type mockRoundTripper struct { -} +type mockRoundTripper struct{} func (rt *mockRoundTripper) RoundTrip(req *nethttp.Request) (resp *nethttp.Response, err error) { return @@ -47,7 +46,6 @@ func TestWithBlock(t *testing.T) { } func TestWithBalancer(t *testing.T) { - } func TestWithTLSConfig(t *testing.T) { @@ -106,8 +104,7 @@ func TestWithErrorDecoder(t *testing.T) { assert.NotNil(t, o.errorDecoder) } -type mockDiscovery struct { -} +type mockDiscovery struct{} func (*mockDiscovery) GetService(ctx context.Context, serviceName string) ([]*registry.ServiceInstance, error) { return nil, nil diff --git a/transport/http/context.go b/transport/http/context.go index 0c68329c7..bc54134f5 100644 --- a/transport/http/context.go +++ b/transport/http/context.go @@ -75,12 +75,14 @@ func (c *wrapper) Vars() url.Values { } return vars } + func (c *wrapper) Form() url.Values { if err := c.req.ParseForm(); err != nil { return url.Values{} } return c.req.Form } + func (c *wrapper) Query() url.Values { return c.req.URL.Query() } diff --git a/transport/http/resolver.go b/transport/http/resolver.go index ebb42f72c..cb882b16b 100644 --- a/transport/http/resolver.go +++ b/transport/http/resolver.go @@ -120,7 +120,7 @@ func newResolver(ctx context.Context, discovery registry.Discovery, target *Targ } func (r *resolver) update(services []*registry.ServiceInstance) { - var nodes []*registry.ServiceInstance + nodes := make([]*registry.ServiceInstance, 0) for _, in := range services { ept, err := endpoint.ParseEndpoint(in.Endpoints, "http", !r.insecure) if err != nil { diff --git a/transport/http/router_test.go b/transport/http/router_test.go index b2b50f65b..cc9f0a0b7 100644 --- a/transport/http/router_test.go +++ b/transport/http/router_test.go @@ -4,16 +4,19 @@ import ( "context" "encoding/json" "fmt" - "github.com/stretchr/testify/assert" "log" "net/http" "strings" "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/go-kratos/kratos/v2/internal/host" ) +const appJSONStr = "application/json" + type User struct { Name string `json:"name"` } @@ -37,6 +40,7 @@ func authFilter(next http.Handler) http.Handler { next.ServeHTTP(w, r) }) } + func loggingFilter(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Do stuff here @@ -85,7 +89,7 @@ func TestRoute(t *testing.T) { }() time.Sleep(time.Second) testRoute(t, srv) - srv.Stop(ctx) + _ = srv.Stop(ctx) } func testRoute(t *testing.T, srv *Server) { @@ -103,18 +107,18 @@ func testRoute(t *testing.T, srv *Server) { if resp.StatusCode != 200 { t.Fatalf("code: %d", resp.StatusCode) } - if v := resp.Header.Get("Content-Type"); v != "application/json" { + if v := resp.Header.Get("Content-Type"); v != appJSONStr { t.Fatalf("contentType: %s", v) } u := new(User) - if err := json.NewDecoder(resp.Body).Decode(u); err != nil { + if err = json.NewDecoder(resp.Body).Decode(u); err != nil { t.Fatal(err) } if u.Name != "foo" { t.Fatalf("got %s want foo", u.Name) } // POST - resp, err = http.Post(base+"/users", "application/json", strings.NewReader(`{"name":"bar"}`)) + resp, err = http.Post(base+"/users", appJSONStr, strings.NewReader(`{"name":"bar"}`)) if err != nil { t.Fatal(err) } @@ -122,7 +126,7 @@ func testRoute(t *testing.T, srv *Server) { if resp.StatusCode != 201 { t.Fatalf("code: %d", resp.StatusCode) } - if v := resp.Header.Get("Content-Type"); v != "application/json" { + if v := resp.Header.Get("Content-Type"); v != appJSONStr { t.Fatalf("contentType: %s", v) } u = new(User) @@ -134,7 +138,7 @@ func testRoute(t *testing.T, srv *Server) { } // PUT req, _ := http.NewRequest("PUT", base+"/users", strings.NewReader(`{"name":"bar"}`)) - req.Header.Set("Content-Type", "application/json") + req.Header.Set("Content-Type", appJSONStr) resp, err = http.DefaultClient.Do(req) if err != nil { t.Fatal(err) @@ -143,7 +147,7 @@ func testRoute(t *testing.T, srv *Server) { if resp.StatusCode != 200 { t.Fatalf("code: %d", resp.StatusCode) } - if v := resp.Header.Get("Content-Type"); v != "application/json" { + if v := resp.Header.Get("Content-Type"); v != appJSONStr { t.Fatalf("contentType: %s", v) } u = new(User) diff --git a/transport/http/server.go b/transport/http/server.go index e6bf2bd06..fd78ab3b0 100644 --- a/transport/http/server.go +++ b/transport/http/server.go @@ -4,13 +4,14 @@ import ( "context" "crypto/tls" "errors" - "github.com/go-kratos/kratos/v2/internal/endpoint" "net" "net/http" "net/url" "sync" "time" + "github.com/go-kratos/kratos/v2/internal/endpoint" + "github.com/go-kratos/kratos/v2/internal/host" "github.com/go-kratos/kratos/v2/log" "github.com/go-kratos/kratos/v2/middleware" @@ -19,8 +20,10 @@ import ( "github.com/gorilla/mux" ) -var _ transport.Server = (*Server)(nil) -var _ transport.Endpointer = (*Server)(nil) +var ( + _ transport.Server = (*Server)(nil) + _ transport.Endpointer = (*Server)(nil) +) // ServerOption is an HTTP server option. type ServerOption func(*Server) diff --git a/transport/http/server_test.go b/transport/http/server_test.go index 2fa62c283..12449f667 100644 --- a/transport/http/server_test.go +++ b/transport/http/server_test.go @@ -5,8 +5,6 @@ import ( "crypto/tls" "encoding/json" "fmt" - "github.com/go-kratos/kratos/v2/errors" - "github.com/go-kratos/kratos/v2/middleware" "io/ioutil" "net/http" "net/url" @@ -14,6 +12,9 @@ import ( "testing" "time" + "github.com/go-kratos/kratos/v2/errors" + "github.com/go-kratos/kratos/v2/middleware" + "github.com/go-kratos/kratos/v2/internal/host" "github.com/stretchr/testify/assert" ) @@ -26,7 +27,7 @@ type testData struct { func TestServer(t *testing.T) { fn := func(w http.ResponseWriter, r *http.Request) { - json.NewEncoder(w).Encode(testData{Path: r.RequestURI}) + _ = json.NewEncoder(w).Encode(testData{Path: r.RequestURI}) } ctx := context.Background() srv := NewServer() @@ -44,7 +45,7 @@ func TestServer(t *testing.T) { }() time.Sleep(time.Second) testClient(t, srv) - srv.Stop(ctx) + _ = srv.Stop(ctx) } func testClient(t *testing.T, srv *Server) { @@ -74,6 +75,7 @@ func testClient(t *testing.T, srv *Server) { if err != nil { t.Fatal(err) } + defer client.Close() for _, test := range tests { var res testData url := fmt.Sprintf(e.String() + test.path) @@ -82,12 +84,12 @@ func testClient(t *testing.T, srv *Server) { t.Fatal(err) } resp, err := client.Do(req) - if test.path == "/index/notfound" && err != nil { if e, ok := err.(*errors.Error); ok && e.Code == http.StatusNotFound { continue } } + defer resp.Body.Close() if err != nil { t.Fatal(err) @@ -122,13 +124,12 @@ func testClient(t *testing.T, srv *Server) { t.Errorf("expected %s got %s", test.path, res.Path) } } - } func BenchmarkServer(b *testing.B) { fn := func(w http.ResponseWriter, r *http.Request) { data := &testData{Path: r.RequestURI} - json.NewEncoder(w).Encode(data) + _ = json.NewEncoder(w).Encode(data) if r.Context().Value(testKey{}) != "test" { w.WriteHeader(500) } @@ -154,7 +155,7 @@ func BenchmarkServer(b *testing.B) { err := client.Invoke(context.Background(), "POST", "/index", nil, &res) assert.NoError(b, err) } - srv.Stop(ctx) + _ = srv.Stop(ctx) } func TestNetwork(t *testing.T) { @@ -179,7 +180,7 @@ func TestTimeout(t *testing.T) { } func TestLogger(t *testing.T) { - //todo + // todo } func TestEndpoint(t *testing.T) { @@ -189,7 +190,6 @@ func TestEndpoint(t *testing.T) { Endpoint(u)(o) assert.Equal(t, "hello", o.endpoint.Host) assert.Equal(t, "http", o.endpoint.Scheme) - } func TestMiddleware(t *testing.T) { diff --git a/transport/http/transport.go b/transport/http/transport.go index 07c822001..fad5f6f7e 100644 --- a/transport/http/transport.go +++ b/transport/http/transport.go @@ -7,9 +7,7 @@ import ( "github.com/go-kratos/kratos/v2/transport" ) -var ( - _ transport.Transporter = &Transport{} -) +var _ transport.Transporter = &Transport{} // Transport is an HTTP transport. type Transport struct { diff --git a/transport/transport.go b/transport/transport.go index 45f2f5491..42510df30 100644 --- a/transport/transport.go +++ b/transport/transport.go @@ -65,8 +65,10 @@ const ( KindHTTP Kind = "http" ) -type serverTransportKey struct{} -type clientTransportKey struct{} +type ( + serverTransportKey struct{} + clientTransportKey struct{} +) // NewServerContext returns a new Context that carries value. func NewServerContext(ctx context.Context, tr Transporter) context.Context {