Repository: go-kratos/kratos
Pull request #2179 (2022-07-10 02:07:45)

test(contrib/config/consul): add unit test for contrib/config/consul
#### Description (what this PR does / why we need it):
add unit test for contrib/config/consul


#### Which issue(s) this PR fixes (resolves / be part of):
part of #2135 


codecov-commenter: # [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2179?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) Report
> Merging [#2179](https://codecov.io/gh/go-kratos/kratos/pull/2179?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (713a1fe) into [main](https://codecov.io/gh/go-kratos/kratos/commit/2209da5e2440d08db7c1db0c1531d0919aede773?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (2209da5) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##             main    #2179   +/-   ##
=======================================
  Coverage   82.12%   82.12%           
=======================================
  Files          86       86           
  Lines        3743     3743           
=======================================
  Hits         3074     3074           
  Misses        480      480           
  Partials      189      189           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2179?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2179?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Last update [2209da5...713a1fe](https://codecov.io/gh/go-kratos/kratos/pull/2179?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos).


Patch:
diff --git a/transport/grpc/interceptor.go b/transport/grpc/interceptor.go
index 3f3827f6..26daedfb 100644
--- a/transport/grpc/interceptor.go
+++ b/transport/grpc/interceptor.go
@@ -17,12 +17,15 @@ func (s *Server) unaryServerInterceptor() grpc.UnaryServerInterceptor {
 		defer cancel()
 		md, _ := grpcmd.FromIncomingContext(ctx)
 		replyHeader := grpcmd.MD{}
-		ctx = transport.NewServerContext(ctx, &Transport{
-			endpoint:    s.endpoint.String(),
+		tr := &Transport{
 			operation:   info.FullMethod,
 			reqHeader:   headerCarrier(md),
 			replyHeader: headerCarrier(replyHeader),
-		})
+		}
+		if s.endpoint != nil {
+			tr.endpoint = s.endpoint.String()
+		}
+		ctx = transport.NewServerContext(ctx, tr)
 		if s.timeout > 0 {
 			ctx, cancel = context.WithTimeout(ctx, s.timeout)
 			defer cancel()
diff --git a/transport/grpc/server.go b/transport/grpc/server.go
index 31c03f75..0131692e 100644
--- a/transport/grpc/server.go
+++ b/transport/grpc/server.go
@@ -156,8 +156,6 @@ func NewServer(opts ...ServerOption) *Server {
 	}
 	srv.Server = grpc.NewServer(grpcOpts...)
 	srv.metadata = apimd.NewServer(srv.Server)
-	// listen and endpoint
-	srv.err = srv.listenAndEndpoint()
 	// internal register
 	grpc_health_v1.RegisterHealthServer(srv.Server, srv.health)
 	apimd.RegisterMetadataServer(srv.Server, srv.metadata)
@@ -169,7 +167,7 @@ func NewServer(opts ...ServerOption) *Server {
 // examples:
 //   grpc://127.0.0.1:9000?isSecure=false
 func (s *Server) Endpoint() (*url.URL, error) {
-	if s.err != nil {
+	if err := s.listenAndEndpoint(); err != nil {
 		return nil, s.err
 	}
 	return s.endpoint, nil
@@ -177,7 +175,7 @@ func (s *Server) Endpoint() (*url.URL, error) {
 
 // Start start the gRPC server.
 func (s *Server) Start(ctx context.Context) error {
-	if s.err != nil {
+	if err := s.listenAndEndpoint(); err != nil {
 		return s.err
 	}
 	s.baseCtx = ctx
@@ -198,15 +196,17 @@ func (s *Server) listenAndEndpoint() error {
 	if s.lis == nil {
 		lis, err := net.Listen(s.network, s.address)
 		if err != nil {
+			s.err = err
+			return err
+		}
+		addr, err := host.Extract(s.address, lis)
+		if err != nil {
+			_ = s.lis.Close()
+			s.err = err
 			return err
 		}
 		s.lis = lis
+		s.endpoint = endpoint.NewEndpoint(endpoint.Scheme("grpc", s.tlsConf != nil), addr)
 	}
-	addr, err := host.Extract(s.address, s.lis)
-	if err != nil {
-		_ = s.lis.Close()
-		return err
-	}
-	s.endpoint = endpoint.NewEndpoint(endpoint.Scheme("grpc", s.tlsConf != nil), addr)
-	return nil
+	return s.err
 }
diff --git a/transport/http/server.go b/transport/http/server.go
index c45a7269..64c42df1 100644
--- a/transport/http/server.go
+++ b/transport/http/server.go
@@ -153,7 +153,6 @@ func NewServer(opts ...ServerOption) *Server {
 		Handler:   FilterChain(srv.filters...)(srv.router),
 		TLSConfig: srv.tlsConf,
 	}
-	srv.err = srv.listenAndEndpoint()
 	return srv
 }
 
@@ -208,14 +207,15 @@ func (s *Server) filter() mux.MiddlewareFunc {
 			}
 
 			tr := &Transport{
-				endpoint:     s.endpoint.String(),
 				operation:    pathTemplate,
 				reqHeader:    headerCarrier(req.Header),
 				replyHeader:  headerCarrier(w.Header()),
 				request:      req,
 				pathTemplate: pathTemplate,
 			}
-
+			if s.endpoint != nil {
+				tr.endpoint = s.endpoint.String()
+			}
 			tr.request = req.WithContext(transport.NewServerContext(ctx, tr))
 			next.ServeHTTP(w, tr.request)
 		})
@@ -227,16 +227,16 @@ func (s *Server) filter() mux.MiddlewareFunc {
 //   https://127.0.0.1:8000
 //   Legacy: http://127.0.0.1:8000?isSecure=false
 func (s *Server) Endpoint() (*url.URL, error) {
-	if s.err != nil {
-		return nil, s.err
+	if err := s.listenAndEndpoint(); err != nil {
+		return nil, err
 	}
 	return s.endpoint, nil
 }
 
 // Start start the HTTP server.
 func (s *Server) Start(ctx context.Context) error {
-	if s.err != nil {
-		return s.err
+	if err := s.listenAndEndpoint(); err != nil {
+		return err
 	}
 	s.BaseContext = func(net.Listener) context.Context {
 		return ctx
@@ -264,15 +264,17 @@ func (s *Server) listenAndEndpoint() error {
 	if s.lis == nil {
 		lis, err := net.Listen(s.network, s.address)
 		if err != nil {
+			s.err = err
+			return err
+		}
+		addr, err := host.Extract(s.address, lis)
+		if err != nil {
+			_ = s.lis.Close()
+			s.err = err
 			return err
 		}
 		s.lis = lis
+		s.endpoint = endpoint.NewEndpoint(endpoint.Scheme("http", s.tlsConf != nil), addr)
 	}
-	addr, err := host.Extract(s.address, s.lis)
-	if err != nil {
-		_ = s.lis.Close()
-		return err
-	}
-	s.endpoint = endpoint.NewEndpoint(endpoint.Scheme("http", s.tlsConf != nil), addr)
-	return nil
+	return s.err
 }


Test patch:
diff --git a/contrib/config/consul/config_test.go b/contrib/config/consul/config_test.go
index 8e952736..a82a2036 100644
--- a/contrib/config/consul/config_test.go
+++ b/contrib/config/consul/config_test.go
@@ -3,7 +3,9 @@ package consul
 import (
 	"reflect"
 	"testing"
+	"time"
 
+	"github.com/go-kratos/kratos/v2/config"
 	"github.com/hashicorp/consul/api"
 )
 
@@ -99,3 +101,158 @@ func TestExtToFormat(t *testing.T) {
 		t.Errorf("kvs[0].Format is %s", kvs[0].Format)
 	}
 }
+
+func Test_source_Watch(t *testing.T) {
+	client, err := api.NewClient(&api.Config{
+		Address: "127.0.0.1:8500",
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	source, err := New(client, WithPath(testPath))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	type fields struct {
+		source config.Source
+	}
+
+	type args struct {
+		key   string
+		value string
+	}
+
+	tests := []struct {
+		name      string
+		fields    fields
+		args      args
+		want      string
+		wantErr   bool
+		deferFunc func(t *testing.T)
+	}{
+		{
+			name:   "normal",
+			fields: fields{source: source},
+			args: args{
+				key:   testKey,
+				value: "test value",
+			},
+			want:    "test value",
+			wantErr: false,
+			deferFunc: func(t *testing.T) {
+				_, err := client.KV().Delete(testKey, nil)
+				if err != nil {
+					t.Error(err)
+				}
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if tt.deferFunc != nil {
+				defer tt.deferFunc(t)
+			}
+
+			got, err := tt.fields.source.Watch()
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Watch() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+			time.Sleep(100 * time.Millisecond)
+			_, err = client.KV().Put(&api.KVPair{Key: tt.args.key, Value: []byte(tt.args.value)}, nil)
+			if err != nil {
+				t.Error(err)
+			}
+
+			next, err := got.Next()
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Watch() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+			if len(next) != 1 {
+				t.Error("watch is error")
+			}
+
+			if !reflect.DeepEqual(string(next[0].Value), tt.want) {
+				t.Errorf("Watch got = %v, want %v", string(next[0].Value), tt.want)
+			}
+		})
+	}
+}
+
+func Test_source_Load(t *testing.T) {
+	client, err := api.NewClient(&api.Config{
+		Address: "127.0.0.1:8500",
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	source, err := New(client, WithPath(testPath))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	type args struct {
+		key   string
+		value string
+	}
+	type fields struct {
+		source config.Source
+	}
+	tests := []struct {
+		name      string
+		args      args
+		fields    fields
+		want      []*config.KeyValue
+		wantErr   bool
+		deferFunc func(t *testing.T)
+	}{
+		{
+			name: "normal",
+			args: args{
+				key:   testKey,
+				value: "test value",
+			},
+			fields: fields{
+				source: source,
+			},
+			want: []*config.KeyValue{
+				{
+					Key:   "key",
+					Value: []byte("test value"),
+				},
+			},
+			deferFunc: func(t *testing.T) {
+				_, err1 := client.KV().Delete(testKey, nil)
+				if err1 != nil {
+					t.Error(err)
+				}
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if tt.deferFunc != nil {
+				defer tt.deferFunc(t)
+			}
+			_, err = client.KV().Put(&api.KVPair{Key: tt.args.key, Value: []byte(tt.args.value)}, nil)
+			if err != nil {
+				t.Error(err)
+			}
+			got, err := tt.fields.source.Load()
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Load() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+			if !reflect.DeepEqual(got[0], tt.want[0]) {
+				t.Errorf("Load() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/errors/errors_test.go b/errors/errors_test.go
index f76d5151..5196d0b6 100644
--- a/errors/errors_test.go
+++ b/errors/errors_test.go
@@ -114,20 +114,37 @@ func TestCause(t *testing.T) {
 }
 
 func TestOther(t *testing.T) {
+	err := Errorf(10001, "test code 10001", "message")
+	// Code
 	if !reflect.DeepEqual(Code(nil), 200) {
 		t.Errorf("Code(nil) = %v, want %v", Code(nil), 200)
 	}
 	if !reflect.DeepEqual(Code(errors.New("test")), UnknownCode) {
 		t.Errorf(`Code(errors.New("test")) = %v, want %v`, Code(nil), 200)
 	}
-	if !reflect.DeepEqual(Reason(errors.New("test")), UnknownReason) {
-		t.Errorf(`Reason(errors.New("test")) = %v, want %v`, Reason(nil), UnknownReason)
-	}
-	err := Errorf(10001, "test code 10001", "message")
 	if !reflect.DeepEqual(Code(err), 10001) {
 		t.Errorf(`Code(err) = %v, want %v`, Code(err), 10001)
 	}
+	// Reason
+	if !reflect.DeepEqual(Reason(nil), UnknownReason) {
+		t.Errorf(`Reason(nil) = %v, want %v`, Reason(nil), UnknownReason)
+	}
+	if !reflect.DeepEqual(Reason(errors.New("test")), UnknownReason) {
+		t.Errorf(`Reason(errors.New("test")) = %v, want %v`, Reason(nil), UnknownReason)
+	}
 	if !reflect.DeepEqual(Reason(err), "test code 10001") {
 		t.Errorf(`Reason(err) = %v, want %v`, Reason(err), "test code 10001")
 	}
+	// Clone
+	err400 := Newf(http.StatusBadRequest, "BAD_REQUEST", "param invalid")
+	err400.Metadata = map[string]string{
+		"key1": "val1",
+		"key2": "val2",
+	}
+	if cerr := Clone(err400); cerr == nil || cerr.Error() != err400.Error() {
+		t.Errorf("Clone(err) = %v, want %v", Clone(err400), err400)
+	}
+	if cerr := Clone(nil); cerr != nil {
+		t.Errorf("Clone(nil) = %v, want %v", Clone(err400), err400)
+	}
 }