trpc.group/trpc-go/trpc-go@v1.0.3/client/config_test.go (about) 1 // 2 // 3 // Tencent is pleased to support the open source community by making tRPC available. 4 // 5 // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 // All rights reserved. 7 // 8 // If you have downloaded a copy of the tRPC source code from Tencent, 9 // please note that tRPC source code is licensed under the Apache 2.0 License, 10 // A copy of the Apache 2.0 License is included in this file. 11 // 12 // 13 14 package client_test 15 16 import ( 17 "context" 18 "errors" 19 "testing" 20 "time" 21 22 "github.com/stretchr/testify/assert" 23 "github.com/stretchr/testify/require" 24 yaml "gopkg.in/yaml.v3" 25 26 trpc "trpc.group/trpc-go/trpc-go" 27 "trpc.group/trpc-go/trpc-go/client" 28 "trpc.group/trpc-go/trpc-go/codec" 29 "trpc.group/trpc-go/trpc-go/filter" 30 "trpc.group/trpc-go/trpc-go/internal/rand" 31 "trpc.group/trpc-go/trpc-go/naming/registry" 32 "trpc.group/trpc-go/trpc-go/naming/selector" 33 "trpc.group/trpc-go/trpc-go/transport" 34 ) 35 36 func TestConfigOptions(t *testing.T) { 37 clientOpts := &client.Options{} 38 transportOpts := &transport.RoundTripOptions{} 39 40 node := ®istry.Node{ 41 Address: "127.0.0.1:8080", 42 Network: "udp", 43 Protocol: "trpc", 44 } 45 clientOpts.LoadNodeConfig(node) 46 for _, o := range clientOpts.CallOptions { 47 o(transportOpts) 48 } 49 assert.Equal(t, "127.0.0.1:8080", transportOpts.Address) 50 assert.Equal(t, "udp", transportOpts.Network) 51 assert.Equal(t, trpc.DefaultClientCodec, clientOpts.Codec) 52 53 filter.Register("Monitoring", filter.NoopServerFilter, filter.NoopClientFilter) 54 filter.Register("Authentication", filter.NoopServerFilter, filter.NoopClientFilter) 55 } 56 57 func TestConfigNoDiscovery(t *testing.T) { 58 backconfig := &client.BackendConfig{ 59 ServiceName: "trpc.test.helloworld3", // backend service name 60 Namespace: "Development", 61 Discovery: "no-exists", 62 Network: "tcp", 63 Timeout: 1000, 64 Protocol: "trpc", 65 Filter: []string{"Monitoring", "Authentication"}, 66 } 67 err := client.RegisterClientConfig("trpc.test.nodiscovery", backconfig) 68 assert.NotNil(t, err) 69 } 70 71 func TestConfigNoServiceRouter(t *testing.T) { 72 backconfig := &client.BackendConfig{ 73 ServiceName: "trpc.test.helloworld3", // backend service name 74 Namespace: "Development", 75 ServiceRouter: "no-exists", 76 Network: "tcp", 77 Timeout: 1000, 78 Protocol: "trpc", 79 Filter: []string{"Monitoring", "Authentication"}, 80 } 81 err := client.RegisterClientConfig("trpc.test.noservicerouter", backconfig) 82 assert.NotNil(t, err) 83 } 84 85 func TestConfigNoBalance(t *testing.T) { 86 backconfig := &client.BackendConfig{ 87 ServiceName: "trpc.test.helloworld3", // backend service name 88 Namespace: "Development", 89 Loadbalance: "no-exists", 90 Network: "tcp", 91 Timeout: 1000, 92 Protocol: "trpc", 93 Filter: []string{"Monitoring", "Authentication"}, 94 } 95 err := client.RegisterClientConfig("trpc.test.nobalance", backconfig) 96 assert.NotNil(t, err) 97 } 98 99 type testOptionsSelector struct { 100 f func(*selector.Options) 101 } 102 103 var testOptionsSelectorError = errors.New("test options selector error") 104 105 func (s *testOptionsSelector) Select(serviceName string, opt ...selector.Option) (*registry.Node, error) { 106 opts := &selector.Options{} 107 for _, o := range opt { 108 o(opts) 109 } 110 s.f(opts) 111 return nil, testOptionsSelectorError 112 } 113 114 func (s *testOptionsSelector) Report(node *registry.Node, cost time.Duration, err error) error { 115 return nil 116 } 117 118 func TestConfigCalleeMetadata(t *testing.T) { 119 ctx := context.Background() 120 reqBody := codec.Body{} 121 rspBody := codec.Body{} 122 calleeMetadata := map[string]string{ 123 "key1": "val1", 124 "key2": "val2", 125 } 126 backconfig := &client.BackendConfig{ 127 ServiceName: "trpc.test.helloworld3", // backend service name 128 Namespace: "Development", 129 Network: "tcp", 130 Timeout: 1000, 131 Protocol: "trpc", 132 CalleeMetadata: calleeMetadata, 133 } 134 err := client.RegisterClientConfig("trpc.test.client.metadata", backconfig) 135 assert.Nil(t, err) 136 137 s := &testOptionsSelector{ 138 f: func(opts *selector.Options) { 139 assert.Equal(t, calleeMetadata, opts.DestinationMetadata) 140 }, 141 } 142 selector.Register("test-options-selector", s) 143 cli := client.New() 144 assert.Equal(t, cli, client.DefaultClient) 145 ctx, msg := codec.WithNewMessage(ctx) 146 msg.WithCalleeServiceName("trpc.test.client.metadata") 147 err = cli.Invoke(ctx, reqBody, rspBody, 148 client.WithTarget("test-options-selector://trpc.test.client.metadata"), 149 ) 150 require.Contains(t, err.Error(), testOptionsSelectorError.Error()) 151 } 152 153 func TestConfigNoBreaker(t *testing.T) { 154 backconfig := &client.BackendConfig{ 155 ServiceName: "trpc.test.helloworld3", // backend service name 156 Namespace: "Development", 157 Circuitbreaker: "no-exists", 158 Network: "tcp", 159 Timeout: 1000, 160 Protocol: "trpc", 161 Filter: []string{"Monitoring", "Authentication"}, 162 } 163 err := client.RegisterClientConfig("trpc.test.nobreaker", backconfig) 164 assert.NotNil(t, err) 165 } 166 167 func TestConfigNoFilter(t *testing.T) { 168 backconfig := &client.BackendConfig{ 169 ServiceName: "trpc.test.helloworld3", // backend service name 170 Namespace: "Development", 171 Network: "tcp", 172 Timeout: 1000, 173 Protocol: "trpc", 174 Filter: []string{"Monitoring", "no-exists"}, 175 } 176 err := client.RegisterClientConfig("trpc.test.nofilter", backconfig) 177 assert.NotNil(t, err) 178 } 179 180 func TestConfigFilter(t *testing.T) { 181 backconfig := &client.BackendConfig{ 182 ServiceName: "trpc.test.helloworld3", // backend service name 183 Namespace: "Development", 184 Network: "tcp", 185 Timeout: 1000, 186 Protocol: "trpc", 187 Filter: []string{"Monitoring"}, 188 } 189 filter.Register("Monitoring", nil, filter.NoopClientFilter) 190 err := client.RegisterClientConfig("trpc.test.filter", backconfig) 191 assert.Nil(t, err) 192 } 193 194 func TestLoadClientFilterConfigSelectorFilter(t *testing.T) { 195 const callee = "test_selector_filter" 196 require.Nil(t, client.RegisterClientConfig(callee, &client.BackendConfig{ 197 Filter: []string{client.DefaultSelectorFilterName}, 198 })) 199 } 200 201 func TestRegisterConfigParallel(t *testing.T) { 202 safeRand := rand.NewSafeRand(time.Now().UnixNano()) 203 for i := 0; i < safeRand.Intn(100); i++ { 204 t.Run("Parallel", func(t *testing.T) { 205 t.Parallel() 206 backconfig := &client.BackendConfig{ 207 ServiceName: "trpc.test.helloworld1", // backend service name 208 Target: "ip://1.1.1.1:2222", // backend address 209 Network: "tcp", 210 Timeout: 1000, 211 Protocol: "trpc", 212 } 213 conf := map[string]*client.BackendConfig{ 214 "trpc.test.helloworld": backconfig, 215 } 216 err := client.RegisterConfig(conf) 217 assert.Nil(t, err) 218 assert.Equal(t, client.DefaultClientConfig(), conf) 219 }) 220 } 221 } 222 223 func TestLoadClientConfig(t *testing.T) { 224 err := client.LoadClientConfig("../testdata/trpc_go.yaml") 225 assert.Nil(t, err) 226 } 227 228 type testTransport struct{} 229 230 func (t *testTransport) RoundTrip(ctx context.Context, req []byte, 231 opts ...transport.RoundTripOption) ([]byte, error) { 232 return nil, nil 233 } 234 235 func TestConfigTransport(t *testing.T) { 236 t.Run("Client Config", func(t *testing.T) { 237 tr := &testTransport{} 238 transport.RegisterClientTransport("test-transport", tr) 239 var cfg client.BackendConfig 240 require.Nil(t, yaml.Unmarshal([]byte(` 241 transport: test-transport 242 `), &cfg)) 243 require.Equal(t, "test-transport", cfg.Transport) 244 require.Nil(t, client.RegisterClientConfig("trpc.test.hello", &cfg)) 245 }) 246 } 247 248 func TestConfigStreamFilter(t *testing.T) { 249 filterName := "sf1" 250 cfg := &client.BackendConfig{} 251 require.Nil(t, yaml.Unmarshal([]byte(` 252 stream_filter: 253 - sf1 254 `), cfg)) 255 require.Equal(t, filterName, cfg.StreamFilter[0]) 256 // return error if stream filter no registered 257 err := client.RegisterClientConfig("trpc.test.hello", cfg) 258 assert.NotNil(t, err) 259 260 client.RegisterStreamFilter("sf1", func(ctx context.Context, desc *client.ClientStreamDesc, 261 streamer client.Streamer) (client.ClientStream, error) { 262 return nil, nil 263 }) 264 require.Nil(t, client.RegisterClientConfig("trpc.test.hello", cfg)) 265 } 266 267 func TestConfig(t *testing.T) { 268 require.Nil(t, client.RegisterConfig(make(map[string]*client.BackendConfig))) 269 c := client.Config("empty") 270 assert.Equal(t, "", c.ServiceName) 271 assert.Equal(t, "tcp", c.Network) 272 assert.Equal(t, "trpc", c.Protocol) 273 274 backconfig := &client.BackendConfig{ 275 ServiceName: "trpc.test.helloworld1", // backend service name 276 Target: "ip://1.1.1.1:2222", // backend address 277 Network: "tcp", 278 Timeout: 1000, 279 Protocol: "trpc", 280 } 281 conf := map[string]*client.BackendConfig{ 282 "trpc.test.helloworld": backconfig, 283 } 284 285 err := client.RegisterConfig(conf) 286 assert.Nil(t, err) 287 assert.Equal(t, client.DefaultClientConfig(), conf) 288 289 require.Nil(t, client.RegisterClientConfig("trpc.test.helloworld2", backconfig)) 290 assert.Equal(t, "trpc.test.helloworld1", client.Config("trpc.test.helloworld2").ServiceName) 291 292 c = client.Config("no-exist") 293 assert.Equal(t, "", c.ServiceName) 294 assert.Equal(t, "tcp", c.Network) 295 assert.Equal(t, "trpc", c.Protocol) 296 297 c = client.Config("trpc.test.helloworld") 298 assert.Equal(t, "trpc.test.helloworld1", c.ServiceName) 299 assert.Equal(t, "tcp", c.Network) 300 assert.Equal(t, "ip://1.1.1.1:2222", c.Target) 301 assert.Equal(t, 1000, c.Timeout) 302 assert.Equal(t, "trpc", c.Protocol) 303 304 backconfig = &client.BackendConfig{ 305 ServiceName: "trpc.test.helloworld1", // backend service name 306 Network: "tcp", 307 Timeout: 1000, 308 Protocol: "trpc", 309 Compression: 1, 310 Password: "xxx", 311 CACert: "xxx", 312 } 313 require.Nil(t, client.RegisterClientConfig("trpc.test.helloworld3", backconfig)) 314 } 315 316 func TestRegisterWildcardClient(t *testing.T) { 317 cfg := client.Config("*") 318 t.Cleanup(func() { 319 client.RegisterClientConfig("*", cfg) 320 }) 321 client.RegisterClientConfig("*", &client.BackendConfig{ 322 DisableServiceRouter: true, 323 }) 324 325 ch := make(chan *client.Options, 1) 326 c := client.New() 327 ctx, _ := codec.EnsureMessage(context.Background()) 328 require.Nil(t, c.Invoke(ctx, nil, nil, client.WithFilter( 329 func(ctx context.Context, _, _ interface{}, _ filter.ClientHandleFunc) error { 330 ch <- client.OptionsFromContext(ctx) 331 // Skip next. 332 return nil 333 }))) 334 opts := <-ch 335 require.True(t, opts.DisableServiceRouter) 336 }