dubbo.apache.org/dubbo-go/v3@v3.1.1/common/rpc_service_test.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package common 19 20 import ( 21 "context" 22 "reflect" 23 "testing" 24 ) 25 26 import ( 27 "github.com/stretchr/testify/assert" 28 ) 29 30 import ( 31 "dubbo.apache.org/dubbo-go/v3/common/constant" 32 ) 33 34 const ( 35 referenceTestPath = "com.test.Path" 36 referenceTestPathDistinct = "com.test.Path1" 37 testInterfaceName = "testService" 38 testProtocol = "testprotocol" 39 testSuiteMethodExpectedString = "interface {}" 40 ) 41 42 type TestService struct{} 43 44 func (s *TestService) MethodOne(ctx context.Context, arg1, arg2, arg3 interface{}) error { 45 return nil 46 } 47 48 func (s *TestService) MethodTwo(arg1, arg2, arg3 interface{}) (interface{}, error) { 49 return struct{}{}, nil 50 } 51 52 func (s *TestService) MethodThree() error { 53 return nil 54 } 55 56 func (s *TestService) Reference() string { 57 return referenceTestPath 58 } 59 60 func (s *TestService) MethodMapper() map[string]string { 61 return map[string]string{ 62 "MethodTwo": "methodTwo", 63 } 64 } 65 66 type testService struct{} 67 68 func (s *testService) Method1(ctx context.Context, args testService, rsp *struct{}) error { 69 return nil 70 } 71 72 func (s *testService) Method2(ctx context.Context, args []interface{}) (testService, error) { 73 return testService{}, nil 74 } 75 76 func (s *testService) Method3(ctx context.Context, args []interface{}, rsp *struct{}) { 77 } 78 79 func (s *testService) Method4(ctx context.Context, args []interface{}, rsp *struct{}) *testService { 80 return nil 81 } 82 83 func (s *testService) Reference() string { 84 return referenceTestPath 85 } 86 87 type TestService1 struct{} 88 89 func (s *TestService1) Reference() string { 90 return referenceTestPathDistinct 91 } 92 93 func TestServiceMapRegister(t *testing.T) { 94 // lowercase 95 s0 := &testService{} 96 // methods, err := ServiceMap.Register("testporotocol", s0) 97 _, err := ServiceMap.Register(testInterfaceName, "testporotocol", "", "v0", s0) 98 assert.EqualError(t, err, "type testService is not exported") 99 100 // succ 101 s := &TestService{} 102 methods, err := ServiceMap.Register(testInterfaceName, "testporotocol", "", "v1", s) 103 assert.NoError(t, err) 104 assert.Equal(t, "MethodOne,MethodThree,methodTwo", methods) 105 106 // repeat 107 _, err = ServiceMap.Register(testInterfaceName, "testporotocol", "", "v1", s) 108 assert.EqualError(t, err, "service already defined: testService:v1") 109 110 // no method 111 s1 := &TestService1{} 112 _, err = ServiceMap.Register(testInterfaceName, "testporotocol", "", "v2", s1) 113 assert.EqualError(t, err, "type testService:v2 has no exported methods of suitable type") 114 115 ServiceMap = &serviceMap{ 116 serviceMap: make(map[string]map[string]*Service), 117 interfaceMap: make(map[string][]*Service), 118 } 119 } 120 121 func TestServiceMapUnRegister(t *testing.T) { 122 s := &TestService{} 123 _, err := ServiceMap.Register("TestService", testProtocol, "", "v1", s) 124 assert.NoError(t, err) 125 assert.NotNil(t, ServiceMap.GetService(testProtocol, "TestService", "", "v1")) 126 assert.Equal(t, 1, len(ServiceMap.GetInterface("TestService"))) 127 128 err = ServiceMap.UnRegister("", "", ServiceKey("TestService", "", "v1")) 129 assert.EqualError(t, err, "protocol or ServiceKey is nil") 130 131 err = ServiceMap.UnRegister("", "protocol", ServiceKey("TestService", "", "v1")) 132 assert.EqualError(t, err, "no services for protocol") 133 134 err = ServiceMap.UnRegister("", testProtocol, ServiceKey("TestService", "", "v0")) 135 assert.EqualError(t, err, "no service for TestService:v0") 136 137 // success 138 err = ServiceMap.UnRegister("TestService", testProtocol, ServiceKey("TestService", "", "v1")) 139 assert.NoError(t, err) 140 } 141 142 func TestMethodTypeSuiteContext(t *testing.T) { 143 mt := &MethodType{ctxType: reflect.TypeOf(context.TODO())} 144 ctx := context.Background() 145 key := constant.DubboCtxKey("key") 146 ctx = context.WithValue(ctx, key, "value") 147 assert.Equal(t, reflect.ValueOf(ctx), mt.SuiteContext(ctx)) 148 } 149 150 func TestSuiteMethod(t *testing.T) { 151 s := &TestService{} 152 method, ok := reflect.TypeOf(s).MethodByName("MethodOne") 153 assert.True(t, ok) 154 methodType := suiteMethod(method) 155 method = methodType.Method() 156 assert.Equal(t, "func(*common.TestService, context.Context, interface {}, interface {}, interface {}) error", method.Type.String()) 157 at := methodType.ArgsType() 158 assert.Equal(t, testSuiteMethodExpectedString, at[0].String()) 159 assert.Equal(t, testSuiteMethodExpectedString, at[1].String()) 160 assert.Equal(t, testSuiteMethodExpectedString, at[2].String()) 161 ct := methodType.CtxType() 162 assert.Equal(t, "context.Context", ct.String()) 163 rt := methodType.ReplyType() 164 assert.Nil(t, rt) 165 166 method, ok = reflect.TypeOf(s).MethodByName("MethodTwo") 167 assert.True(t, ok) 168 methodType = suiteMethod(method) 169 method = methodType.Method() 170 assert.Equal(t, "func(*common.TestService, interface {}, interface {}, interface {}) (interface {}, error)", method.Type.String()) 171 at = methodType.ArgsType() 172 assert.Equal(t, testSuiteMethodExpectedString, at[0].String()) 173 assert.Equal(t, testSuiteMethodExpectedString, at[1].String()) 174 assert.Equal(t, testSuiteMethodExpectedString, at[2].String()) 175 assert.Nil(t, methodType.CtxType()) 176 rt = methodType.ReplyType() 177 assert.Equal(t, testSuiteMethodExpectedString, rt.String()) 178 179 method, ok = reflect.TypeOf(s).MethodByName("MethodThree") 180 assert.True(t, ok) 181 methodType = suiteMethod(method) 182 method = methodType.Method() 183 assert.Equal(t, "func(*common.TestService) error", method.Type.String()) 184 at = methodType.ArgsType() 185 assert.Equal(t, 0, len(at)) 186 assert.Nil(t, methodType.CtxType()) 187 rt = methodType.ReplyType() 188 assert.Nil(t, rt) 189 190 // wrong number of in return 191 s1 := &testService{} 192 method, ok = reflect.TypeOf(s1).MethodByName("Reference") 193 assert.True(t, ok) 194 methodType = suiteMethod(method) 195 assert.Nil(t, methodType) 196 197 // args not exported 198 method, ok = reflect.TypeOf(s1).MethodByName("Method1") 199 assert.True(t, ok) 200 methodType = suiteMethod(method) 201 assert.Nil(t, methodType) 202 203 // Reply not exported 204 method, ok = reflect.TypeOf(s1).MethodByName("Method2") 205 assert.True(t, ok) 206 methodType = suiteMethod(method) 207 assert.Nil(t, methodType) 208 209 // no return 210 method, ok = reflect.TypeOf(s1).MethodByName("Method3") 211 assert.True(t, ok) 212 methodType = suiteMethod(method) 213 assert.Nil(t, methodType) 214 215 // return value is not error 216 method, ok = reflect.TypeOf(s1).MethodByName("Method4") 217 assert.True(t, ok) 218 methodType = suiteMethod(method) 219 assert.Nil(t, methodType) 220 } 221 222 type ServiceWithoutRef struct{} 223 224 func TestGetReference(t *testing.T) { 225 s0 := &TestService{} 226 ref0 := GetReference(s0) 227 assert.Equal(t, referenceTestPath, ref0) 228 229 //s1 := TestService{} 230 //ref1 := GetReference(s1) 231 //assert.Equal(t, referenceTestPath, ref1) 232 233 s2 := &struct { 234 TestService 235 }{} 236 ref2 := GetReference(s2) 237 assert.Equal(t, referenceTestPath, ref2) 238 239 expectedReference := "ServiceWithoutRef" 240 s3 := &ServiceWithoutRef{} 241 ref3 := GetReference(s3) 242 assert.Equal(t, expectedReference, ref3) 243 244 s4 := ServiceWithoutRef{} 245 ref4 := GetReference(s4) 246 assert.Equal(t, expectedReference, ref4) 247 248 s5 := &struct { 249 ServiceWithoutRef 250 }{} 251 ref5 := GetReference(s5) 252 assert.Equal(t, expectedReference, ref5) 253 }