mirror of
https://github.com/go-kratos/kratos.git
synced 2024-12-30 21:19:57 +02:00
test(transport) add test (#1325)
* test * test client and server * return * add args * calloption * test
This commit is contained in:
parent
ef6b347d6b
commit
a128566cef
@ -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)
|
||||
}
|
||||
|
37
transport/grpc/resolver/direct/builder_test.go
Normal file
37
transport/grpc/resolver/direct/builder_test.go
Normal file
@ -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{})
|
||||
}
|
1
transport/grpc/resolver/direct/resolver_test.go
Normal file
1
transport/grpc/resolver/direct/resolver_test.go
Normal file
@ -0,0 +1 @@
|
||||
package direct
|
81
transport/grpc/resolver/discovery/builder_test.go
Normal file
81
transport/grpc/resolver/discovery/builder_test.go
Normal file
@ -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) {
|
||||
|
68
transport/http/calloption_test.go
Normal file
68
transport/http/calloption_test.go
Normal file
@ -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)
|
||||
|
1
transport/http/context_test.go
Normal file
1
transport/http/context_test.go
Normal file
@ -0,0 +1 @@
|
||||
package http
|
@ -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…
Reference in New Issue
Block a user