From 8bba4108aed29cf37cc7ab26eaf321e2da4a044a Mon Sep 17 00:00:00 2001 From: xujianhai666 Date: Sun, 21 Jul 2019 20:51:23 +0800 Subject: [PATCH] stash --- cluster/cluster_impl/failback_cluster_test.go | 21 +++ cluster/cluster_impl/failsafe_cluster_test.go | 121 ++++++++++++++++++ go.mod | 1 + go.sum | 5 + protocol/invoker.go | 1 + protocol/mock_invoker.go | 80 ++++++++++++ protocol/protocol/mock_invocation.go | 118 +++++++++++++++++ 7 files changed, 347 insertions(+) create mode 100644 cluster/cluster_impl/failback_cluster_test.go create mode 100644 cluster/cluster_impl/failsafe_cluster_test.go create mode 100644 protocol/mock_invoker.go create mode 100644 protocol/protocol/mock_invocation.go diff --git a/cluster/cluster_impl/failback_cluster_test.go b/cluster/cluster_impl/failback_cluster_test.go new file mode 100644 index 0000000000..57dec473c2 --- /dev/null +++ b/cluster/cluster_impl/failback_cluster_test.go @@ -0,0 +1,21 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cluster_impl + + + diff --git a/cluster/cluster_impl/failsafe_cluster_test.go b/cluster/cluster_impl/failsafe_cluster_test.go new file mode 100644 index 0000000000..7f050067b2 --- /dev/null +++ b/cluster/cluster_impl/failsafe_cluster_test.go @@ -0,0 +1,121 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cluster_impl + +import ( + "context" + "fmt" + "net/url" + "testing" + + "github.com/apache/dubbo-go/common/logger" + "github.com/stretchr/testify/assert" +) + +import ( + perrors "github.com/pkg/errors" +) + +import ( + "github.com/apache/dubbo-go/cluster/directory" + "github.com/apache/dubbo-go/cluster/loadbalance" + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/protocol" + "github.com/apache/dubbo-go/protocol/invocation" +) + +///////////////////////////// +// mock invoker +///////////////////////////// + +var returnsuccess bool + +type FailsafeMockInvoker struct { + url common.URL + available bool + destroyed bool +} + +func NewFailsafeMockInvoker(url common.URL) *FailsafeMockInvoker { + return &FailsafeMockInvoker{ + url: url, + available: true, + destroyed: false, + } +} + +func (bi *FailsafeMockInvoker) GetUrl() common.URL { + return bi.url +} + +func (bi *FailsafeMockInvoker) IsAvailable() bool { + return bi.available +} + +func (bi *FailsafeMockInvoker) IsDestroyed() bool { + return bi.destroyed +} + +func (bi *FailsafeMockInvoker) Invoke(invocation protocol.Invocation) protocol.Result { + var err error + if !returnsuccess { + err = perrors.New("error") + } + result := &protocol.RPCResult{Err: err, Rest: rest{tried: 0, success: returnsuccess}} + + return result +} + +func (bi *FailsafeMockInvoker) Destroy() { + logger.Infof("Destroy invoker: %v", bi.GetUrl().String()) + bi.destroyed = true + bi.available = false +} + +func failSafeInvoke(t *testing.T, urlParam url.Values) protocol.Result { + extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance) + failsafeCluster := NewFailsafeCluster() + + invokers := []protocol.Invoker{} + for i := 0; i < 10; i++ { + url, _ := common.NewURL(context.TODO(), fmt.Sprintf("dubbo://192.168.1.%v:20000/com.ikurento.user.UserProvider", i), common.WithParams(urlParam)) + invokers = append(invokers, NewFailsafeMockInvoker(url)) + } + + staticDir := directory.NewStaticDirectory(invokers) + clusterInvoker := failsafeCluster.Join(staticDir) + return clusterInvoker.Invoke(&invocation.RPCInvocation{}) +} + +func Test_FailSafeInvokeSuccess(t *testing.T) { + returnsuccess = true + urlParams := url.Values{} + result := failSafeInvoke(t, urlParams) + assert.NoError(t, result.Error()) + res := result.Result().(rest) + assert.True(t, res.success) +} + +func Test_FailSafeInvokeFail(t *testing.T) { + returnsuccess = false + urlParams := url.Values{} + result := failSafeInvoke(t, urlParams) + assert.NoError(t, result.Error()) + assert.Nil(t, result.Result()) +} diff --git a/go.mod b/go.mod index 213d7ee8e8..f194325bcc 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/apache/dubbo-go require ( github.com/dubbogo/getty v1.0.7 github.com/dubbogo/hessian2 v1.0.2 + github.com/golang/mock v1.3.1 github.com/pkg/errors v0.8.1 github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec github.com/stretchr/testify v1.3.0 diff --git a/go.sum b/go.sum index f39e814c86..5b0034c29e 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,8 @@ github.com/dubbogo/getty v1.0.7 h1:5Hg+JwXyCKm9Yr4yJkm98ahhnoa8c2h6br5QJxwQ+YU= github.com/dubbogo/getty v1.0.7/go.mod h1:cRMSuoCmwc5lULFFnYZTxyCfZhObmRTNbS7XRnPNHSo= github.com/dubbogo/hessian2 v1.0.2 h1:Ka9Z32ZszGAdCpgrGuZQmwkT0qe1pd3o9r7ERCDnSlQ= github.com/dubbogo/hessian2 v1.0.2/go.mod h1:XFGDn4oSZX26zkcfhkM/fCJrOqwQJxk/xgWW1KMJBKM= +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= @@ -25,10 +27,13 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 h1:kcXqo9vE6fsZY5X5Rd7R1l7fTgnWaDCVmln65REefiE= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= diff --git a/protocol/invoker.go b/protocol/invoker.go index fe6aab848c..039019e326 100644 --- a/protocol/invoker.go +++ b/protocol/invoker.go @@ -22,6 +22,7 @@ import ( "github.com/apache/dubbo-go/common/logger" ) +//go:generate mockgen -source ./invoker.go -destination ./mock_invoker.go --package protocol Invoker // Extension - Invoker type Invoker interface { common.Node diff --git a/protocol/mock_invoker.go b/protocol/mock_invoker.go new file mode 100644 index 0000000000..913cd26bd1 --- /dev/null +++ b/protocol/mock_invoker.go @@ -0,0 +1,80 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./invoker.go + +// Package protocol is a generated GoMock package. +package protocol + +import ( + common "github.com/apache/dubbo-go/common" + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockInvoker is a mock of Invoker interface +type MockInvoker struct { + ctrl *gomock.Controller + recorder *MockInvokerMockRecorder +} + +// MockInvokerMockRecorder is the mock recorder for MockInvoker +type MockInvokerMockRecorder struct { + mock *MockInvoker +} + +// NewMockInvoker creates a new mock instance +func NewMockInvoker(ctrl *gomock.Controller) *MockInvoker { + mock := &MockInvoker{ctrl: ctrl} + mock.recorder = &MockInvokerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockInvoker) EXPECT() *MockInvokerMockRecorder { + return m.recorder +} + +// GetUrl mocks base method +func (m *MockInvoker) GetUrl() common.URL { + ret := m.ctrl.Call(m, "GetUrl") + ret0, _ := ret[0].(common.URL) + return ret0 +} + +// GetUrl indicates an expected call of GetUrl +func (mr *MockInvokerMockRecorder) GetUrl() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUrl", reflect.TypeOf((*MockInvoker)(nil).GetUrl)) +} + +// IsAvailable mocks base method +func (m *MockInvoker) IsAvailable() bool { + ret := m.ctrl.Call(m, "IsAvailable") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsAvailable indicates an expected call of IsAvailable +func (mr *MockInvokerMockRecorder) IsAvailable() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsAvailable", reflect.TypeOf((*MockInvoker)(nil).IsAvailable)) +} + +// Destroy mocks base method +func (m *MockInvoker) Destroy() { + m.ctrl.Call(m, "Destroy") +} + +// Destroy indicates an expected call of Destroy +func (mr *MockInvokerMockRecorder) Destroy() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Destroy", reflect.TypeOf((*MockInvoker)(nil).Destroy)) +} + +// Invoke mocks base method +func (m *MockInvoker) Invoke(arg0 Invocation) Result { + ret := m.ctrl.Call(m, "Invoke", arg0) + ret0, _ := ret[0].(Result) + return ret0 +} + +// Invoke indicates an expected call of Invoke +func (mr *MockInvokerMockRecorder) Invoke(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Invoke", reflect.TypeOf((*MockInvoker)(nil).Invoke), arg0) +} diff --git a/protocol/protocol/mock_invocation.go b/protocol/protocol/mock_invocation.go new file mode 100644 index 0000000000..ec99283bea --- /dev/null +++ b/protocol/protocol/mock_invocation.go @@ -0,0 +1,118 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: invocation.go + +// Package mock_protocol is a generated GoMock package. +package mock_protocol + +import ( + x "." + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockInvocation is a mock of Invocation interface +type MockInvocation struct { + ctrl *gomock.Controller + recorder *MockInvocationMockRecorder +} + +// MockInvocationMockRecorder is the mock recorder for MockInvocation +type MockInvocationMockRecorder struct { + mock *MockInvocation +} + +// NewMockInvocation creates a new mock instance +func NewMockInvocation(ctrl *gomock.Controller) *MockInvocation { + mock := &MockInvocation{ctrl: ctrl} + mock.recorder = &MockInvocationMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockInvocation) EXPECT() *MockInvocationMockRecorder { + return m.recorder +} + +// MethodName mocks base method +func (m *MockInvocation) MethodName() string { + ret := m.ctrl.Call(m, "MethodName") + ret0, _ := ret[0].(string) + return ret0 +} + +// MethodName indicates an expected call of MethodName +func (mr *MockInvocationMockRecorder) MethodName() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MethodName", reflect.TypeOf((*MockInvocation)(nil).MethodName)) +} + +// ParameterTypes mocks base method +func (m *MockInvocation) ParameterTypes() []reflect.Type { + ret := m.ctrl.Call(m, "ParameterTypes") + ret0, _ := ret[0].([]reflect.Type) + return ret0 +} + +// ParameterTypes indicates an expected call of ParameterTypes +func (mr *MockInvocationMockRecorder) ParameterTypes() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParameterTypes", reflect.TypeOf((*MockInvocation)(nil).ParameterTypes)) +} + +// Arguments mocks base method +func (m *MockInvocation) Arguments() []interface{} { + ret := m.ctrl.Call(m, "Arguments") + ret0, _ := ret[0].([]interface{}) + return ret0 +} + +// Arguments indicates an expected call of Arguments +func (mr *MockInvocationMockRecorder) Arguments() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Arguments", reflect.TypeOf((*MockInvocation)(nil).Arguments)) +} + +// Reply mocks base method +func (m *MockInvocation) Reply() interface{} { + ret := m.ctrl.Call(m, "Reply") + ret0, _ := ret[0].(interface{}) + return ret0 +} + +// Reply indicates an expected call of Reply +func (mr *MockInvocationMockRecorder) Reply() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reply", reflect.TypeOf((*MockInvocation)(nil).Reply)) +} + +// Attachments mocks base method +func (m *MockInvocation) Attachments() map[string]string { + ret := m.ctrl.Call(m, "Attachments") + ret0, _ := ret[0].(map[string]string) + return ret0 +} + +// Attachments indicates an expected call of Attachments +func (mr *MockInvocationMockRecorder) Attachments() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Attachments", reflect.TypeOf((*MockInvocation)(nil).Attachments)) +} + +// AttachmentsByKey mocks base method +func (m *MockInvocation) AttachmentsByKey(arg0, arg1 string) string { + ret := m.ctrl.Call(m, "AttachmentsByKey", arg0, arg1) + ret0, _ := ret[0].(string) + return ret0 +} + +// AttachmentsByKey indicates an expected call of AttachmentsByKey +func (mr *MockInvocationMockRecorder) AttachmentsByKey(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AttachmentsByKey", reflect.TypeOf((*MockInvocation)(nil).AttachmentsByKey), arg0, arg1) +} + +// Invoker mocks base method +func (m *MockInvocation) Invoker() x.Invoker { + ret := m.ctrl.Call(m, "Invoker") + ret0, _ := ret[0].(x.Invoker) + return ret0 +} + +// Invoker indicates an expected call of Invoker +func (mr *MockInvocationMockRecorder) Invoker() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Invoker", reflect.TypeOf((*MockInvocation)(nil).Invoker)) +}