From ebece39852797208ff5b490ffb0de3c8e055a88c Mon Sep 17 00:00:00 2001 From: fangyincheng <fangyincheng@sina.com> Date: Fri, 17 May 2019 15:08:06 +0800 Subject: [PATCH] Tst&Mod:add test & formatting code --- common/proxy/proxy_test.go | 34 ++++++++++-- config/config_loader.go | 4 +- config/config_loader_test.go | 28 ++++++++++ config/mock_rpcservice.go | 2 +- config/reference_config_test.go | 2 +- config/service_config_test.go | 2 +- protocol/dubbo/client.go | 69 ++++++++++++------------ protocol/dubbo/client_test.go | 17 +++++- protocol/dubbo/dubbo_invoker.go | 8 +-- protocol/dubbo/listener.go | 7 ++- protocol/jsonrpc/http_test.go | 27 ++++++++-- protocol/jsonrpc/jsonrpc_invoker.go | 9 ++-- protocol/jsonrpc/jsonrpc_invoker_test.go | 5 +- protocol/jsonrpc/server.go | 25 ++++++--- 14 files changed, 168 insertions(+), 71 deletions(-) diff --git a/common/proxy/proxy_test.go b/common/proxy/proxy_test.go index 73a3fb8ba..8a7c8c880 100644 --- a/common/proxy/proxy_test.go +++ b/common/proxy/proxy_test.go @@ -12,11 +12,14 @@ import ( import ( "github.com/dubbo/go-for-apache-dubbo/common" + "github.com/dubbo/go-for-apache-dubbo/common/constant" "github.com/dubbo/go-for-apache-dubbo/protocol" ) type TestService struct { MethodOne func(context.Context, []interface{}, *struct{}) error + MethodTwo func([]interface{}, *struct{}) error + Echo func([]interface{}, *struct{}) error } func (s *TestService) Service() string { @@ -26,18 +29,30 @@ func (s *TestService) Version() string { return "" } +type TestServiceInt int + +func (s *TestServiceInt) Service() string { + return "com.test.TestServiceInt" +} +func (s *TestServiceInt) Version() string { + return "" +} + func TestProxy_Implement(t *testing.T) { invoker := protocol.NewBaseInvoker(common.URL{}) - p := NewProxy(invoker, nil, nil) - s := &TestService{MethodOne: func(i context.Context, i2 []interface{}, i3 *struct{}) error { - return errors.New("errors") - }} + p := NewProxy(invoker, nil, map[string]string{constant.ASYNC_KEY: "false"}) + s := &TestService{} p.Implement(s) err := p.Get().(*TestService).MethodOne(nil, nil, nil) assert.NoError(t, err) + err = p.Get().(*TestService).MethodTwo(nil, nil) + assert.NoError(t, err) + err = p.Get().(*TestService).Echo(nil, nil) + assert.NoError(t, err) // inherit & lowercase + p.rpc = nil type S1 struct { TestService methodOne func(context.Context, []interface{}, *struct{}) error @@ -51,7 +66,14 @@ func TestProxy_Implement(t *testing.T) { err = s1.methodOne(nil, nil, nil) assert.EqualError(t, err, "errors") + // no struct + p.rpc = nil + it := TestServiceInt(1) + p.Implement(&it) + assert.Nil(t, p.rpc) + // args number + p.rpc = nil type S2 struct { TestService MethodOne func([]interface{}) error @@ -61,6 +83,7 @@ func TestProxy_Implement(t *testing.T) { assert.Nil(t, s2.MethodOne) // returns number + p.rpc = nil type S3 struct { TestService MethodOne func(context.Context, []interface{}, *struct{}) (interface{}, error) @@ -70,6 +93,7 @@ func TestProxy_Implement(t *testing.T) { assert.Nil(t, s3.MethodOne) // returns type + p.rpc = nil type S4 struct { TestService MethodOne func(context.Context, []interface{}, *struct{}) interface{} @@ -79,6 +103,7 @@ func TestProxy_Implement(t *testing.T) { assert.Nil(t, s4.MethodOne) // reply type for number 3 + p.rpc = nil type S5 struct { TestService MethodOne func(context.Context, []interface{}, interface{}) error @@ -88,6 +113,7 @@ func TestProxy_Implement(t *testing.T) { assert.Nil(t, s5.MethodOne) // reply type for number 2 + p.rpc = nil type S6 struct { TestService MethodOne func([]interface{}, interface{}) error diff --git a/config/config_loader.go b/config/config_loader.go index e1f55b373..b364e7cb0 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -222,7 +222,7 @@ func Load() (map[string]*ReferenceConfig, map[string]*ServiceConfig) { length := len(consumerConfig.References) for index := 0; index < length; index++ { con := &consumerConfig.References[index] - rpcService := conServices[con.InterfaceName] + rpcService := GetConService(con.InterfaceName) if rpcService == nil { log.Warn("%s is not exsist!", con.InterfaceName) continue @@ -241,7 +241,7 @@ func Load() (map[string]*ReferenceConfig, map[string]*ServiceConfig) { length := len(providerConfig.Services) for index := 0; index < length; index++ { pro := &providerConfig.Services[index] - rpcService := proServices[pro.InterfaceName] + rpcService := GetProService(pro.InterfaceName) if rpcService == nil { log.Warn("%s is not exsist!", pro.InterfaceName) continue diff --git a/config/config_loader_test.go b/config/config_loader_test.go index b67835d56..ed96da81e 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -1,6 +1,7 @@ package config import ( + "github.com/dubbo/go-for-apache-dubbo/common" "path/filepath" "testing" ) @@ -9,6 +10,11 @@ import ( "github.com/stretchr/testify/assert" ) +import ( + "github.com/dubbo/go-for-apache-dubbo/cluster/cluster_impl" + "github.com/dubbo/go-for-apache-dubbo/common/extension" +) + func TestConfigLoader(t *testing.T) { conPath, err := filepath.Abs("./consumer_config.yml") assert.NoError(t, err) @@ -30,3 +36,25 @@ func TestConfigLoader(t *testing.T) { assert.NotNil(t, providerConfig) assert.NotEqual(t, ProviderConfig{}, GetProviderConfig()) } + +func TestLoad(t *testing.T) { + doInit() + doinit() + + SetConService(&MockService{}) + SetProService(&MockService{}) + + extension.SetProtocol("registry", GetProtocol) + extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster) + consumerConfig.References[0].Registries = []ConfigRegistry{"shanghai_reg1"} + + refConfigs, svcConfigs := Load() + assert.NotEqual(t, 0, len(refConfigs)) + assert.NotEqual(t, 0, len(svcConfigs)) + + conServices = map[string]common.RPCService{} + proServices = map[string]common.RPCService{} + common.ServiceMap.UnRegister("mock", "MockService") + consumerConfig = nil + providerConfig = nil +} diff --git a/config/mock_rpcservice.go b/config/mock_rpcservice.go index 1bd01bd4f..14641de4e 100644 --- a/config/mock_rpcservice.go +++ b/config/mock_rpcservice.go @@ -6,7 +6,7 @@ type MockService struct { } func (*MockService) Service() string { - return "mockservice" + return "MockService" } func (*MockService) Version() string { return "1.0" diff --git a/config/reference_config_test.go b/config/reference_config_test.go index 6e63b4bc3..a2ba14a66 100644 --- a/config/reference_config_test.go +++ b/config/reference_config_test.go @@ -61,7 +61,7 @@ func doInit() { }, References: []ReferenceConfig{ { - InterfaceName: "testInterface", + InterfaceName: "MockService", Protocol: "mock", Registries: []ConfigRegistry{"shanghai_reg1", "shanghai_reg2", "hangzhou_reg1", "hangzhou_reg2"}, Cluster: "failover", diff --git a/config/service_config_test.go b/config/service_config_test.go index 9f991e56c..f6874b15f 100644 --- a/config/service_config_test.go +++ b/config/service_config_test.go @@ -55,7 +55,7 @@ func doinit() { }, Services: []ServiceConfig{ { - InterfaceName: "testInterface", + InterfaceName: "MockService", Protocol: "mock", Registries: []ConfigRegistry{"shanghai_reg1", "shanghai_reg2", "hangzhou_reg1", "hangzhou_reg2"}, Cluster: "failover", diff --git a/protocol/dubbo/client.go b/protocol/dubbo/client.go index 6c50f51a2..7477a965a 100644 --- a/protocol/dubbo/client.go +++ b/protocol/dubbo/client.go @@ -83,38 +83,38 @@ type CallOptions struct { type CallOption func(*CallOptions) -func WithCallRequestTimeout(d time.Duration) CallOption { - return func(o *CallOptions) { - o.RequestTimeout = d - } -} - -func WithCallResponseTimeout(d time.Duration) CallOption { - return func(o *CallOptions) { - o.ResponseTimeout = d - } -} - -func WithCallSerialID(s SerialID) CallOption { - return func(o *CallOptions) { - o.SerialID = s - } -} - -func WithCallMeta_All(callMeta map[interface{}]interface{}) CallOption { - return func(o *CallOptions) { - o.Meta = callMeta - } -} - -func WithCallMeta(k, v interface{}) CallOption { - return func(o *CallOptions) { - if o.Meta == nil { - o.Meta = make(map[interface{}]interface{}) - } - o.Meta[k] = v - } -} +//func WithCallRequestTimeout(d time.Duration) CallOption { +// return func(o *CallOptions) { +// o.RequestTimeout = d +// } +//} +// +//func WithCallResponseTimeout(d time.Duration) CallOption { +// return func(o *CallOptions) { +// o.ResponseTimeout = d +// } +//} +// +//func WithCallSerialID(s SerialID) CallOption { +// return func(o *CallOptions) { +// o.SerialID = s +// } +//} +// +//func WithCallMeta_All(callMeta map[interface{}]interface{}) CallOption { +// return func(o *CallOptions) { +// o.Meta = callMeta +// } +//} + +//func WithCallMeta(k, v interface{}) CallOption { +// return func(o *CallOptions) { +// if o.Meta == nil { +// o.Meta = make(map[interface{}]interface{}) +// } +// o.Meta[k] = v +// } +//} type CallResponse struct { Opts CallOptions @@ -210,11 +210,14 @@ func (c *Client) call(ct CallType, addr string, svcUrl common.URL, method string var rsp *PendingResponse if ct != CT_OneWay { + p.Header.Type = hessian.PackageRequest_TwoWay rsp = NewPendingResponse() rsp.reply = reply rsp.callback = callback rsp.opts = opts } + // todo: it must be PackageRequest because of hessian2, but it is twoway actually + p.Header.Type = hessian.PackageRequest var ( err error @@ -281,8 +284,6 @@ func (c *Client) transfer(session getty.Session, pkg *DubboPackage, pkg.Body = []interface{}{} pkg.Header.Type = hessian.PackageHeartbeat pkg.Header.SerialID = byte(S_Dubbo) - } else { - pkg.Header.Type = hessian.PackageRequest } pkg.Header.ID = int64(sequence) diff --git a/protocol/dubbo/client_test.go b/protocol/dubbo/client_test.go index 7febfcc59..a22135ba9 100644 --- a/protocol/dubbo/client_test.go +++ b/protocol/dubbo/client_test.go @@ -3,13 +3,13 @@ package dubbo import ( "context" "errors" - "github.com/dubbogo/hessian2" "sync" "testing" "time" ) import ( + "github.com/dubbogo/hessian2" "github.com/stretchr/testify/assert" ) @@ -60,6 +60,11 @@ func TestClient_Call(t *testing.T) { assert.NoError(t, err) assert.Equal(t, User{Id: "1", Name: "username"}, *user) + user = &User{} + err = c.Call("127.0.0.1:20000", url, "GetUser0", []interface{}{"1", "username"}, user) + assert.NoError(t, err) + assert.Equal(t, User{Id: "1", Name: "username"}, *user) + // destroy proto.Destroy() } @@ -95,7 +100,7 @@ func InitTest(t *testing.T) (protocol.Protocol, common.URL) { methods, err := common.ServiceMap.Register("dubbo", &UserProvider{}) assert.NoError(t, err) - assert.Equal(t, "GetUser,GetUser1", methods) + assert.Equal(t, "GetUser,GetUser0,GetUser1", methods) // config SetClientConf(ClientConfig{ @@ -153,6 +158,8 @@ func InitTest(t *testing.T) (protocol.Protocol, common.URL) { assert.NoError(t, err) proto.Export(protocol.NewBaseInvoker(url)) + time.Sleep(time.Second * 2) + return proto, url } @@ -162,6 +169,12 @@ func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User return nil } +func (u *UserProvider) GetUser0(req []interface{}, rsp *User) error { + rsp.Id = req[0].(string) + rsp.Name = req[1].(string) + return nil +} + func (u *UserProvider) GetUser1(ctx context.Context, req []interface{}, rsp *User) error { return errors.New("error") } diff --git a/protocol/dubbo/dubbo_invoker.go b/protocol/dubbo/dubbo_invoker.go index c0e481837..72da3294b 100644 --- a/protocol/dubbo/dubbo_invoker.go +++ b/protocol/dubbo/dubbo_invoker.go @@ -53,17 +53,17 @@ func (di *DubboInvoker) Invoke(invocation protocol.Invocation) protocol.Result { } else { result.Err = di.client.CallOneway(url.Location, url, inv.MethodName(), inv.Arguments()) } - log.Debug("result.Err: %v, result.Rest: %v", result.Err, result.Rest) } else { if inv.Reply() == nil { result.Err = Err_No_Reply } else { - result.Err = di.client.Call(url.Location, url, inv.MethodName(), inv.Arguments(), inv.Reply()) - result.Rest = inv.Reply() // reply should be set to result.Rest when sync } - log.Debug("result.Err: %v, result.Rest: %v", result.Err, result.Rest) } + if result.Err == nil { + result.Rest = inv.Reply() + } + log.Debug("result.Err: %v, result.Rest: %v", result.Err, result.Rest) return &result } diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go index 99a11feeb..f180ca631 100644 --- a/protocol/dubbo/listener.go +++ b/protocol/dubbo/listener.go @@ -183,11 +183,11 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) { return } + twoway := true // not twoway if p.Header.Type&hessian.PackageRequest_TwoWay == 0x00 { + twoway = false h.reply(session, p, hessian.PackageResponse) - h.callService(p, nil) - return } invoker := h.exporter.GetInvoker() @@ -213,6 +213,9 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) { } h.callService(p, nil) + if !twoway { + return + } h.reply(session, p, hessian.PackageResponse) } diff --git a/protocol/jsonrpc/http_test.go b/protocol/jsonrpc/http_test.go index 8c681e8d0..522337cca 100644 --- a/protocol/jsonrpc/http_test.go +++ b/protocol/jsonrpc/http_test.go @@ -33,7 +33,7 @@ func TestHTTPClient_Call(t *testing.T) { methods, err := common.ServiceMap.Register("jsonrpc", &UserProvider{}) assert.NoError(t, err) - assert.Equal(t, "GetUser,GetUser1", methods) + assert.Equal(t, "GetUser,GetUser0,GetUser1", methods) // Export proto := GetProtocol() @@ -44,11 +44,9 @@ func TestHTTPClient_Call(t *testing.T) { "side=provider&timeout=3000×tamp=1556509797245") assert.NoError(t, err) proto.Export(protocol.NewBaseInvoker(url)) + time.Sleep(time.Second * 2) - client := NewHTTPClient(&HTTPOptions{ - HandshakeTimeout: time.Second, - HTTPTimeout: time.Second, - }) + client := NewHTTPClient(&HTTPOptions{}) // call GetUser ctx := context.WithValue(context.Background(), constant.DUBBOGO_CTX_KEY, map[string]string{ @@ -63,6 +61,19 @@ func TestHTTPClient_Call(t *testing.T) { assert.Equal(t, "1", reply.Id) assert.Equal(t, "username", reply.Name) + // call GetUser + ctx = context.WithValue(context.Background(), constant.DUBBOGO_CTX_KEY, map[string]string{ + "X-Proxy-Id": "dubbogo", + "X-Services": url.Path, + "X-Method": "GetUser", + }) + req = client.NewRequest(url, "GetUser0", []interface{}{"1", "username"}) + reply = &User{} + err = client.Call(ctx, url, req, reply) + assert.NoError(t, err) + assert.Equal(t, "1", reply.Id) + assert.Equal(t, "username", reply.Name) + // call GetUser1 ctx = context.WithValue(context.Background(), constant.DUBBOGO_CTX_KEY, map[string]string{ "X-Proxy-Id": "dubbogo", @@ -86,6 +97,12 @@ func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User return nil } +func (u *UserProvider) GetUser0(req []interface{}, rsp *User) error { + rsp.Id = req[0].(string) + rsp.Name = req[1].(string) + return nil +} + func (u *UserProvider) GetUser1(ctx context.Context, req []interface{}, rsp *User) error { return errors.New("error") } diff --git a/protocol/jsonrpc/jsonrpc_invoker.go b/protocol/jsonrpc/jsonrpc_invoker.go index 645fe8b0d..e427c554f 100644 --- a/protocol/jsonrpc/jsonrpc_invoker.go +++ b/protocol/jsonrpc/jsonrpc_invoker.go @@ -6,7 +6,6 @@ import ( import ( log "github.com/AlexStocks/log4go" - jerrors "github.com/juju/errors" ) import ( @@ -42,13 +41,11 @@ func (ji *JsonrpcInvoker) Invoke(invocation protocol.Invocation) protocol.Result "X-Services": url.Path, "X-Method": inv.MethodName(), }) - if err := ji.client.Call(ctx, url, req, inv.Reply()); err != nil { - log.Error("client.Call() return error:%+v", jerrors.ErrorStack(err)) - result.Err = err - } else { - log.Debug("result: %v", inv.Reply()) + result.Err = ji.client.Call(ctx, url, req, inv.Reply()) + if result.Err == nil { result.Rest = inv.Reply() } + log.Debug("result.Err: %v, result.Rest: %v", result.Err, result.Rest) return &result } diff --git a/protocol/jsonrpc/jsonrpc_invoker_test.go b/protocol/jsonrpc/jsonrpc_invoker_test.go index cde655623..8bf3f3e3c 100644 --- a/protocol/jsonrpc/jsonrpc_invoker_test.go +++ b/protocol/jsonrpc/jsonrpc_invoker_test.go @@ -2,7 +2,6 @@ package jsonrpc import ( "context" - "github.com/dubbo/go-for-apache-dubbo/protocol/invocation" "testing" "time" ) @@ -14,13 +13,14 @@ import ( import ( "github.com/dubbo/go-for-apache-dubbo/common" "github.com/dubbo/go-for-apache-dubbo/protocol" + "github.com/dubbo/go-for-apache-dubbo/protocol/invocation" ) func TestJsonrpcInvoker_Invoke(t *testing.T) { methods, err := common.ServiceMap.Register("jsonrpc", &UserProvider{}) assert.NoError(t, err) - assert.Equal(t, "GetUser,GetUser1", methods) + assert.Equal(t, "GetUser,GetUser0,GetUser1", methods) // Export proto := GetProtocol() @@ -31,6 +31,7 @@ func TestJsonrpcInvoker_Invoke(t *testing.T) { "side=provider&timeout=3000×tamp=1556509797245") assert.NoError(t, err) proto.Export(protocol.NewBaseInvoker(url)) + time.Sleep(time.Second * 2) client := NewHTTPClient(&HTTPOptions{ HandshakeTimeout: time.Second, diff --git a/protocol/jsonrpc/server.go b/protocol/jsonrpc/server.go index dba427b71..78c1b791e 100644 --- a/protocol/jsonrpc/server.go +++ b/protocol/jsonrpc/server.go @@ -367,13 +367,24 @@ func serveRequest(ctx context.Context, replyv := reflect.New(mtype.ReplyType().Elem()) // call service.method(args) - var errMsg string - returnValues := mtype.Method().Func.Call([]reflect.Value{ - svc.Rcvr(), - mtype.SuiteContext(ctx), - reflect.ValueOf(argvTmp), - reflect.ValueOf(replyv.Interface()), - }) + var ( + errMsg string + returnValues []reflect.Value + ) + if mtype.CtxType() == nil { + returnValues = mtype.Method().Func.Call([]reflect.Value{ + svc.Rcvr(), + reflect.ValueOf(argvTmp), + reflect.ValueOf(replyv.Interface()), + }) + } else { + returnValues = mtype.Method().Func.Call([]reflect.Value{ + svc.Rcvr(), + mtype.SuiteContext(ctx), + reflect.ValueOf(argvTmp), + reflect.ValueOf(replyv.Interface()), + }) + } // The return value for the method is an error. if retErr := returnValues[0].Interface(); retErr != nil { errMsg = retErr.(error).Error() -- GitLab