test(transport) add test (#1325)

* test

* test client and server

* return

* add args

* calloption

* test
pull/1331/head
Windfarer 3 years ago committed by GitHub
parent ef6b347d6b
commit a128566cef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      transport/grpc/client_test.go
  2. 37
      transport/grpc/resolver/direct/builder_test.go
  3. 1
      transport/grpc/resolver/direct/resolver_test.go
  4. 81
      transport/grpc/resolver/discovery/builder_test.go
  5. 6
      transport/grpc/resolver/discovery/resolver.go
  6. 66
      transport/grpc/resolver/discovery/resolver_test.go
  7. 51
      transport/grpc/server_test.go
  8. 2
      transport/grpc/transport_test.go
  9. 68
      transport/http/calloption_test.go
  10. 16
      transport/http/client_test.go
  11. 1
      transport/http/context_test.go
  12. 15
      transport/http/router_test.go
  13. 17
      transport/http/server_test.go

@ -4,6 +4,7 @@ import (
"context"
"crypto/tls"
"testing"
"time"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/registry"
@ -18,6 +19,13 @@ func TestWithEndpoint(t *testing.T) {
assert.Equal(t, v, o.endpoint)
}
func TestWithTimeout(t *testing.T) {
o := &clientOptions{}
v := time.Duration(123)
WithTimeout(v)(o)
assert.Equal(t, v, o.timeout)
}
func TestWithMiddleware(t *testing.T) {
o := &clientOptions{}
v := []middleware.Middleware{
@ -50,6 +58,25 @@ func TestWithTLSConfig(t *testing.T) {
assert.Equal(t, v, o.tlsConf)
}
func EmptyMiddleware() middleware.Middleware {
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
return handler(ctx, req)
}
}
}
func TestUnaryClientInterceptor(t *testing.T) {
f := unaryClientInterceptor([]middleware.Middleware{EmptyMiddleware()}, time.Duration(100))
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
})
assert.NoError(t, err)
}
func TestWithUnaryInterceptor(t *testing.T) {
o := &clientOptions{}
v := []grpc.UnaryClientInterceptor{
@ -74,3 +101,12 @@ func TestWithOptions(t *testing.T) {
WithOptions(v...)(o)
assert.Equal(t, v, o.grpcOpts)
}
func TestDial(t *testing.T) {
o := &clientOptions{}
v := []grpc.DialOption{
grpc.EmptyDialOption{},
}
WithOptions(v...)(o)
assert.Equal(t, v, o.grpcOpts)
}

@ -0,0 +1,37 @@
package direct
import (
"github.com/stretchr/testify/assert"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/serviceconfig"
"testing"
)
func TestDirectBuilder_Scheme(t *testing.T) {
b := NewBuilder()
assert.Equal(t, "direct", b.Scheme())
}
type mockConn struct {
}
func (m *mockConn) UpdateState(resolver.State) error {
return nil
}
func (m *mockConn) ReportError(error) {}
func (m *mockConn) NewAddress(addresses []resolver.Address) {}
func (m *mockConn) NewServiceConfig(serviceConfig string) {}
func (m *mockConn) ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult {
return nil
}
func TestDirectBuilder_Build(t *testing.T) {
b := NewBuilder()
r, err := b.Build(resolver.Target{}, &mockConn{}, resolver.BuildOptions{})
assert.NoError(t, err)
r.ResolveNow(resolver.ResolveNowOptions{})
}

@ -0,0 +1,81 @@
package discovery
import (
"context"
"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 {
level log.Level
key string
val string
}
func (l *mockLogger) Log(level log.Level, keyvals ...interface{}) error {
l.level = level
l.key = keyvals[0].(string)
l.val = keyvals[1].(string)
return nil
}
func TestWithLogger(t *testing.T) {
b := &builder{}
WithLogger(&mockLogger{})(b)
}
func TestWithInsecure(t *testing.T) {
b := &builder{}
WithInsecure(true)(b)
assert.True(t, b.insecure)
}
func TestWithTimeout(t *testing.T) {
o := &builder{}
v := time.Duration(123)
WithTimeout(v)(o)
assert.Equal(t, v, o.timeout)
}
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
}
func TestBuilder_Scheme(t *testing.T) {
b := NewBuilder(&mockDiscovery{})
assert.Equal(t, "discovery", b.Scheme())
}
type mockConn struct {
}
func (m *mockConn) UpdateState(resolver.State) error {
return nil
}
func (m *mockConn) ReportError(error) {}
func (m *mockConn) NewAddress(addresses []resolver.Address) {}
func (m *mockConn) NewServiceConfig(serviceConfig string) {}
func (m *mockConn) ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult {
return nil
}
func TestBuilder_Build(t *testing.T) {
b := NewBuilder(&mockDiscovery{})
_, err := b.Build(resolver.Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "gprc://authority/endpoint"}, &mockConn{}, resolver.BuildOptions{})
assert.NoError(t, err)
}

@ -36,7 +36,7 @@ func (r *discoveryResolver) watch() {
if errors.Is(err, context.Canceled) {
return
}
r.log.Errorf("[resovler] Failed to watch discovery endpoint: %v", err)
r.log.Errorf("[resolver] Failed to watch discovery endpoint: %v", err)
time.Sleep(time.Second)
continue
}
@ -49,7 +49,7 @@ func (r *discoveryResolver) update(ins []*registry.ServiceInstance) {
for _, in := range ins {
endpoint, err := endpoint.ParseEndpoint(in.Endpoints, "grpc", !r.insecure)
if err != nil {
r.log.Errorf("[resovler] Failed to parse discovery endpoint: %v", err)
r.log.Errorf("[resolver] Failed to parse discovery endpoint: %v", err)
continue
}
if endpoint == "" {
@ -63,7 +63,7 @@ func (r *discoveryResolver) update(ins []*registry.ServiceInstance) {
addrs = append(addrs, addr)
}
if len(addrs) == 0 {
r.log.Warnf("[resovler] Zero endpoint found,refused to write, instances: %v", ins)
r.log.Warnf("[resolver] Zero endpoint found,refused to write, instances: %v", ins)
return
}
r.cc.UpdateState(resolver.State{Addresses: addrs})

@ -2,11 +2,13 @@ package discovery
import (
"context"
"errors"
"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"
)
@ -21,30 +23,57 @@ func (t *testClientConn) UpdateState(s resolver.State) error {
}
type testWatch struct {
err error
}
func (m *testWatch) Next() ([]*registry.ServiceInstance, error) {
time.Sleep(time.Millisecond * 200)
ins := []*registry.ServiceInstance{
{
ID: "mock_ID",
Name: "mock_Name",
Version: "mock_Version",
ID: "mock_ID",
Name: "mock_Name",
Version: "mock_Version",
Endpoints: []string{"grpc://127.0.0.1?isSecure=true"},
},
{
ID: "mock_ID2",
Name: "mock_Name2",
Version: "mock_Version2",
Endpoints: []string{""},
},
}
return ins, nil
return ins, m.err
}
// Watch creates a watcher according to the service name.
func (m *testWatch) Stop() error {
return nil
return m.err
}
func TestWatch(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
r := &discoveryResolver{
w: &testWatch{},
w: &testWatch{},
cc: &testClientConn{te: t},
log: log.NewHelper(log.DefaultLogger),
ctx: ctx,
cancel: cancel,
insecure: false,
}
go func() {
time.Sleep(time.Second * 2)
r.Close()
}()
r.watch()
t.Log("watch goroutine exited after 2 second")
}
func TestWatchError(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
r := &discoveryResolver{
w: &testWatch{err: errors.New("bad")},
cc: &testClientConn{te: t},
log: log.NewHelper(log.DefaultLogger),
ctx: ctx,
@ -55,6 +84,31 @@ func TestWatch(t *testing.T) {
r.Close()
}()
r.watch()
t.Log("watch goroutine exited after 2 second")
}
func TestWatchContextCancel(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
r := &discoveryResolver{
w: &testWatch{err: context.Canceled},
cc: &testClientConn{te: t},
log: log.NewHelper(log.DefaultLogger),
ctx: ctx,
cancel: cancel,
}
go func() {
time.Sleep(time.Second * 2)
r.Close()
}()
r.watch()
t.Log("watch goroutine exited after 2 second")
}
func TestParseAttributes(t *testing.T) {
a := parseAttributes(map[string]string{"a": "b"})
assert.Equal(t, "b", a.Value("a").(string))
x := a.WithValues("qq", "ww")
assert.Equal(t, "ww", x.Value("qq").(string))
assert.Nil(t, x.Value("notfound"))
}

@ -3,8 +3,10 @@ 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"
@ -17,7 +19,9 @@ type testKey struct{}
func TestServer(t *testing.T) {
ctx := context.Background()
ctx = context.WithValue(ctx, testKey{}, "test")
srv := NewServer()
srv := NewServer(Middleware([]middleware.Middleware{
func(middleware.Handler) middleware.Handler { return nil },
}...))
if e, err := srv.Endpoint(); err != nil || e == nil || strings.HasSuffix(e.Host, ":0") {
t.Fatal(e, err)
@ -69,16 +73,35 @@ func TestTimeout(t *testing.T) {
}
func TestMiddleware(t *testing.T) {
o := &clientOptions{}
o := &Server{}
v := []middleware.Middleware{
func(middleware.Handler) middleware.Handler { return nil },
}
WithMiddleware(v...)(o)
Middleware(v...)(o)
assert.Equal(t, v, o.middleware)
}
type mockLogger struct {
level log.Level
key string
val string
}
func (l *mockLogger) Log(level log.Level, keyvals ...interface{}) error {
l.level = level
l.key = keyvals[0].(string)
l.val = keyvals[1].(string)
return nil
}
func TestLogger(t *testing.T) {
//todo
o := &Server{}
v := &mockLogger{}
Logger(v)(o)
o.log.Log(log.LevelWarn, "foo", "bar")
assert.Equal(t, "foo", v.key)
assert.Equal(t, "bar", v.val)
assert.Equal(t, log.LevelWarn, v.level)
}
func TestTLSConfig(t *testing.T) {
@ -110,3 +133,23 @@ func TestOptions(t *testing.T) {
Options(v...)(o)
assert.Equal(t, v, o.grpcOpts)
}
type testResp struct {
Data string
}
func TestServer_unaryServerInterceptor(t *testing.T) {
u, err := url.Parse("grpc://hello/world")
assert.NoError(t, err)
srv := &Server{ctx: context.Background(),
endpoint: u,
middleware: []middleware.Middleware{EmptyMiddleware()},
timeout: time.Duration(10),
}
req := &struct{}{}
rv, err := srv.unaryServerInterceptor()(context.TODO(), req, &grpc.UnaryServerInfo{}, func(ctx context.Context, req interface{}) (i interface{}, e error) {
return &testResp{Data: "hi"}, nil
})
assert.NoError(t, err)
assert.Equal(t, "hi", rv.(*testResp).Data)
}

@ -29,6 +29,8 @@ func TestTransport_RequestHeader(t *testing.T) {
v.Set("a", "1")
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) {

@ -0,0 +1,68 @@
package http
import (
"net/http"
"testing"
"github.com/stretchr/testify/assert"
)
func TestEmptyCallOptions(t *testing.T) {
assert.NoError(t, EmptyCallOption{}.before(&callInfo{}))
EmptyCallOption{}.after(&callInfo{}, &csAttempt{})
}
func TestContentType(t *testing.T) {
assert.Equal(t, "aaa", ContentType("aaa").(ContentTypeCallOption).ContentType)
}
func TestContentTypeCallOption_before(t *testing.T) {
c := &callInfo{}
err := ContentType("aaa").before(c)
assert.NoError(t, err)
assert.Equal(t, "aaa", c.contentType)
}
func TestDefaultCallInfo(t *testing.T) {
path := "hi"
rv := defaultCallInfo(path)
assert.Equal(t, path, rv.pathTemplate)
assert.Equal(t, path, rv.operation)
assert.Equal(t, "application/json", rv.contentType)
}
func TestOperation(t *testing.T) {
assert.Equal(t, "aaa", Operation("aaa").(OperationCallOption).Operation)
}
func TestOperationCallOption_before(t *testing.T) {
c := &callInfo{}
err := Operation("aaa").before(c)
assert.NoError(t, err)
assert.Equal(t, "aaa", c.operation)
}
func TestPathTemplate(t *testing.T) {
assert.Equal(t, "aaa", PathTemplate("aaa").(PathTemplateCallOption).Pattern)
}
func TestPathTemplateCallOption_before(t *testing.T) {
c := &callInfo{}
err := PathTemplate("aaa").before(c)
assert.NoError(t, err)
assert.Equal(t, "aaa", c.pathTemplate)
}
func TestHeader(t *testing.T) {
h := http.Header{"A": []string{"123"}}
assert.Equal(t, "123", Header(&h).(HeaderCallOption).header.Get("A"))
}
func TestHeaderCallOption_after(t *testing.T) {
h := http.Header{"A": []string{"123"}}
c := &callInfo{}
cs := &csAttempt{res: &http.Response{Header: h}}
o := Header(&h)
o.after(c, cs)
assert.Equal(t, &h, o.(HeaderCallOption).header)
}

@ -3,6 +3,7 @@ package http
import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"io/ioutil"
nethttp "net/http"
@ -38,10 +39,25 @@ func TestWithTimeout(t *testing.T) {
assert.Equal(t, co.timeout, ov)
}
func TestWithBlock(t *testing.T) {
o := WithBlock()
co := &clientOptions{}
o(co)
assert.True(t, co.block)
}
func TestWithBalancer(t *testing.T) {
}
func TestWithTLSConfig(t *testing.T) {
ov := &tls.Config{}
o := WithTLSConfig(ov)
co := &clientOptions{}
o(co)
assert.Same(t, ov, co.tlsConf)
}
func TestWithUserAgent(t *testing.T) {
ov := "kratos"
o := WithUserAgent(ov)

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/stretchr/testify/assert"
"log"
"net/http"
"strings"
@ -166,3 +167,17 @@ func testRoute(t *testing.T, srv *Server) {
t.Fatal("cors failed")
}
}
func TestRouter_Group(t *testing.T) {
r := &Router{}
rr := r.Group("a", func(http.Handler) http.Handler { return nil })
assert.Equal(t, "a", rr.prefix)
}
func TestHandle(t *testing.T) {
r := newRouter("/", NewServer())
h := func(i Context) error {
return nil
}
r.GET("/get", h)
}

@ -9,6 +9,7 @@ import (
"github.com/go-kratos/kratos/v2/middleware"
"io/ioutil"
"net/http"
"net/url"
"strings"
"testing"
"time"
@ -181,13 +182,23 @@ func TestLogger(t *testing.T) {
//todo
}
func TestEndpoint(t *testing.T) {
u, err := url.Parse("http://hello/world")
assert.NoError(t, err)
o := &Server{}
Endpoint(u)(o)
assert.Equal(t, "hello", o.endpoint.Host)
assert.Equal(t, "http", o.endpoint.Scheme)
}
func TestMiddleware(t *testing.T) {
o := &clientOptions{}
o := &Server{}
v := []middleware.Middleware{
func(middleware.Handler) middleware.Handler { return nil },
}
WithMiddleware(v...)(o)
assert.Equal(t, v, o.middleware)
Middleware(v...)(o)
assert.Equal(t, v, o.ms)
}
func TestRequestDecoder(t *testing.T) {

Loading…
Cancel
Save