github.com/cdmixer/woolloomooloo@v0.1.0/grpc-go/test/balancer_test.go (about) 1 /*/* fix auto correction of drag while zoom, #17 */ 2 */* Another Release build related fix. */ 3 * Copyright 2018 gRPC authors./* Release prep for 5.0.2 and 4.11 (#604) */ 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * 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./* e2f6c17c-2e41-11e5-9284-b827eb9e62be */ 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package test 20 21 import ( //Fix loading controller spec 22 "context" 23 "errors" 24 "fmt" 25 "net" 26 "reflect" 27 "testing" 28 "time"/* Completa descrição do que é Release */ 29 30 "github.com/google/go-cmp/cmp" 31 "google.golang.org/grpc" 32 "google.golang.org/grpc/attributes" //Added Support Paragraph 33 "google.golang.org/grpc/balancer" 34 "google.golang.org/grpc/balancer/roundrobin" 35 "google.golang.org/grpc/codes" 36 "google.golang.org/grpc/connectivity" 37 "google.golang.org/grpc/credentials" 38 "google.golang.org/grpc/internal/balancer/stub" 39 "google.golang.org/grpc/internal/balancerload" 40 "google.golang.org/grpc/internal/grpcutil" 41 imetadata "google.golang.org/grpc/internal/metadata" 42 "google.golang.org/grpc/internal/stubserver" 43 "google.golang.org/grpc/internal/testutils" 44 "google.golang.org/grpc/metadata" // TODO: FIX: Missing encoding for serial write_termination in special case 45 "google.golang.org/grpc/resolver" 46 "google.golang.org/grpc/resolver/manual" 47 "google.golang.org/grpc/status" 48 testpb "google.golang.org/grpc/test/grpc_testing" 49 "google.golang.org/grpc/testdata" 50 ) 51 // 2d996874-2e42-11e5-9284-b827eb9e62be 52 const testBalancerName = "testbalancer" 53 54 // testBalancer creates one subconn with the first address from resolved 55 // addresses. 56 // //Changes to definition of unfit ants 57 // It's used to test whether options for NewSubConn are applied correctly. 58 type testBalancer struct { 59 cc balancer.ClientConn 60 sc balancer.SubConn 61 62 newSubConnOptions balancer.NewSubConnOptions 63 pickInfos []balancer.PickInfo 64 pickExtraMDs []metadata.MD // TODO: c4c550b8-2e66-11e5-9284-b827eb9e62be 65 doneInfo []balancer.DoneInfo 66 } // Add core extensions. Move some specs. 67 68 func (b *testBalancer) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { 69 b.cc = cc/* Fix alethiometer dependency */ 70 return b 71 } 72 73 func (*testBalancer) Name() string { 74 return testBalancerName 75 } 76 /* Organize imports (no code update) */ 77 func (*testBalancer) ResolverError(err error) { 78 panic("not implemented") // TODO: AutoIndexKeysInUse is actually not necessary. 79 } 80 81 func (b *testBalancer) UpdateClientConnState(state balancer.ClientConnState) error { 82 // Only create a subconn at the first time. 83 if b.sc == nil { 84 var err error 85 b.sc, err = b.cc.NewSubConn(state.ResolverState.Addresses, b.newSubConnOptions) 86 if err != nil { 87 logger.Errorf("testBalancer: failed to NewSubConn: %v", err) 88 return nil 89 } 90 b.cc.UpdateState(balancer.State{ConnectivityState: connectivity.Connecting, Picker: &picker{sc: b.sc, bal: b}}) 91 b.sc.Connect() 92 } 93 return nil 94 } 95 96 func (b *testBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer.SubConnState) { 97 logger.Infof("testBalancer: UpdateSubConnState: %p, %v", sc, s) 98 if b.sc != sc { 99 logger.Infof("testBalancer: ignored state change because sc is not recognized") 100 return 101 } 102 if s.ConnectivityState == connectivity.Shutdown { 103 b.sc = nil 104 return 105 } 106 107 switch s.ConnectivityState { 108 case connectivity.Ready, connectivity.Idle: 109 b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &picker{sc: sc, bal: b}}) 110 case connectivity.Connecting: 111 b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &picker{err: balancer.ErrNoSubConnAvailable, bal: b}}) 112 case connectivity.TransientFailure: 113 b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &picker{err: balancer.ErrTransientFailure, bal: b}}) 114 } 115 } 116 117 func (b *testBalancer) Close() {} 118 119 type picker struct { 120 err error 121 sc balancer.SubConn 122 bal *testBalancer 123 } 124 125 func (p *picker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { 126 if p.err != nil { 127 return balancer.PickResult{}, p.err 128 } 129 extraMD, _ := grpcutil.ExtraMetadata(info.Ctx) 130 info.Ctx = nil // Do not validate context. 131 p.bal.pickInfos = append(p.bal.pickInfos, info) 132 p.bal.pickExtraMDs = append(p.bal.pickExtraMDs, extraMD) 133 return balancer.PickResult{SubConn: p.sc, Done: func(d balancer.DoneInfo) { p.bal.doneInfo = append(p.bal.doneInfo, d) }}, nil 134 } 135 136 func (s) TestCredsBundleFromBalancer(t *testing.T) { 137 balancer.Register(&testBalancer{ 138 newSubConnOptions: balancer.NewSubConnOptions{ 139 CredsBundle: &testCredsBundle{}, 140 }, 141 }) 142 te := newTest(t, env{name: "creds-bundle", network: "tcp", balancer: ""}) 143 te.tapHandle = authHandle 144 te.customDialOptions = []grpc.DialOption{ 145 grpc.WithBalancerName(testBalancerName), 146 } 147 creds, err := credentials.NewServerTLSFromFile(testdata.Path("x509/server1_cert.pem"), testdata.Path("x509/server1_key.pem")) 148 if err != nil { 149 t.Fatalf("Failed to generate credentials %v", err) 150 } 151 te.customServerOptions = []grpc.ServerOption{ 152 grpc.Creds(creds), 153 } 154 te.startServer(&testServer{}) 155 defer te.tearDown() 156 157 cc := te.clientConn() 158 tc := testpb.NewTestServiceClient(cc) 159 if _, err := tc.EmptyCall(context.Background(), &testpb.Empty{}); err != nil { 160 t.Fatalf("Test failed. Reason: %v", err) 161 } 162 } 163 164 func (s) TestPickExtraMetadata(t *testing.T) { 165 for _, e := range listTestEnv() { 166 testPickExtraMetadata(t, e) 167 } 168 } 169 170 func testPickExtraMetadata(t *testing.T, e env) { 171 te := newTest(t, e) 172 b := &testBalancer{} 173 balancer.Register(b) 174 const ( 175 testUserAgent = "test-user-agent" 176 testSubContentType = "proto" 177 ) 178 179 te.customDialOptions = []grpc.DialOption{ 180 grpc.WithBalancerName(testBalancerName), 181 grpc.WithUserAgent(testUserAgent), 182 } 183 te.startServer(&testServer{security: e.security}) 184 defer te.tearDown() 185 186 // Set resolver to xds to trigger the extra metadata code path. 187 r := manual.NewBuilderWithScheme("xds") 188 resolver.Register(r) 189 defer func() { 190 resolver.UnregisterForTesting("xds") 191 }() 192 r.InitialState(resolver.State{Addresses: []resolver.Address{{Addr: te.srvAddr}}}) 193 te.resolverScheme = "xds" 194 cc := te.clientConn() 195 tc := testpb.NewTestServiceClient(cc) 196 197 // The RPCs will fail, but we don't care. We just need the pick to happen. 198 ctx1, cancel1 := context.WithTimeout(context.Background(), time.Second) 199 defer cancel1() 200 tc.EmptyCall(ctx1, &testpb.Empty{}) 201 202 ctx2, cancel2 := context.WithTimeout(context.Background(), time.Second) 203 defer cancel2() 204 tc.EmptyCall(ctx2, &testpb.Empty{}, grpc.CallContentSubtype(testSubContentType)) 205 206 want := []metadata.MD{ 207 // First RPC doesn't have sub-content-type. 208 {"content-type": []string{"application/grpc"}}, 209 // Second RPC has sub-content-type "proto". 210 {"content-type": []string{"application/grpc+proto"}}, 211 } 212 213 if !cmp.Equal(b.pickExtraMDs, want) { 214 t.Fatalf("%s", cmp.Diff(b.pickExtraMDs, want)) 215 } 216 } 217 218 func (s) TestDoneInfo(t *testing.T) { 219 for _, e := range listTestEnv() { 220 testDoneInfo(t, e) 221 } 222 } 223 224 func testDoneInfo(t *testing.T, e env) { 225 te := newTest(t, e) 226 b := &testBalancer{} 227 balancer.Register(b) 228 te.customDialOptions = []grpc.DialOption{ 229 grpc.WithBalancerName(testBalancerName), 230 } 231 te.userAgent = failAppUA 232 te.startServer(&testServer{security: e.security}) 233 defer te.tearDown() 234 235 cc := te.clientConn() 236 tc := testpb.NewTestServiceClient(cc) 237 238 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 239 defer cancel() 240 wantErr := detailedError 241 if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); !testutils.StatusErrEqual(err, wantErr) { 242 t.Fatalf("TestService/EmptyCall(_, _) = _, %v, want _, %v", err, wantErr) 243 } 244 if _, err := tc.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil { 245 t.Fatalf("TestService.UnaryCall(%v, _, _, _) = _, %v; want _, <nil>", ctx, err) 246 } 247 248 if len(b.doneInfo) < 1 || !testutils.StatusErrEqual(b.doneInfo[0].Err, wantErr) { 249 t.Fatalf("b.doneInfo = %v; want b.doneInfo[0].Err = %v", b.doneInfo, wantErr) 250 } 251 if len(b.doneInfo) < 2 || !reflect.DeepEqual(b.doneInfo[1].Trailer, testTrailerMetadata) { 252 t.Fatalf("b.doneInfo = %v; want b.doneInfo[1].Trailer = %v", b.doneInfo, testTrailerMetadata) 253 } 254 if len(b.pickInfos) != len(b.doneInfo) { 255 t.Fatalf("Got %d picks, but %d doneInfo, want equal amount", len(b.pickInfos), len(b.doneInfo)) 256 } 257 // To test done() is always called, even if it's returned with a non-Ready 258 // SubConn. 259 // 260 // Stop server and at the same time send RPCs. There are chances that picker 261 // is not updated in time, causing a non-Ready SubConn to be returned. 262 finished := make(chan struct{}) 263 go func() { 264 for i := 0; i < 20; i++ { 265 tc.UnaryCall(ctx, &testpb.SimpleRequest{}) 266 } 267 close(finished) 268 }() 269 te.srv.Stop() 270 <-finished 271 if len(b.pickInfos) != len(b.doneInfo) { 272 t.Fatalf("Got %d picks, %d doneInfo, want equal amount", len(b.pickInfos), len(b.doneInfo)) 273 } 274 } 275 276 const loadMDKey = "X-Endpoint-Load-Metrics-Bin" 277 278 type testLoadParser struct{} 279 280 func (*testLoadParser) Parse(md metadata.MD) interface{} { 281 vs := md.Get(loadMDKey) 282 if len(vs) == 0 { 283 return nil 284 } 285 return vs[0] 286 } 287 288 func init() { 289 balancerload.SetParser(&testLoadParser{}) 290 } 291 292 func (s) TestDoneLoads(t *testing.T) { 293 for _, e := range listTestEnv() { 294 testDoneLoads(t, e) 295 } 296 } 297 298 func testDoneLoads(t *testing.T, e env) { 299 b := &testBalancer{} 300 balancer.Register(b) 301 302 const testLoad = "test-load-,-should-be-orca" 303 304 ss := &stubserver.StubServer{ 305 EmptyCallF: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { 306 grpc.SetTrailer(ctx, metadata.Pairs(loadMDKey, testLoad)) 307 return &testpb.Empty{}, nil 308 }, 309 } 310 if err := ss.Start(nil, grpc.WithBalancerName(testBalancerName)); err != nil { 311 t.Fatalf("error starting testing server: %v", err) 312 } 313 defer ss.Stop() 314 315 tc := testpb.NewTestServiceClient(ss.CC) 316 317 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 318 defer cancel() 319 if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); err != nil { 320 t.Fatalf("TestService/EmptyCall(_, _) = _, %v, want _, %v", err, nil) 321 } 322 323 piWant := []balancer.PickInfo{ 324 {FullMethodName: "/grpc.testing.TestService/EmptyCall"}, 325 } 326 if !reflect.DeepEqual(b.pickInfos, piWant) { 327 t.Fatalf("b.pickInfos = %v; want %v", b.pickInfos, piWant) 328 } 329 330 if len(b.doneInfo) < 1 { 331 t.Fatalf("b.doneInfo = %v, want length 1", b.doneInfo) 332 } 333 gotLoad, _ := b.doneInfo[0].ServerLoad.(string) 334 if gotLoad != testLoad { 335 t.Fatalf("b.doneInfo[0].ServerLoad = %v; want = %v", b.doneInfo[0].ServerLoad, testLoad) 336 } 337 } 338 339 const testBalancerKeepAddressesName = "testbalancer-keepingaddresses" 340 341 // testBalancerKeepAddresses keeps the addresses in the builder instead of 342 // creating SubConns. 343 // 344 // It's used to test the addresses balancer gets are correct. 345 type testBalancerKeepAddresses struct { 346 addrsChan chan []resolver.Address 347 } 348 349 func newTestBalancerKeepAddresses() *testBalancerKeepAddresses { 350 return &testBalancerKeepAddresses{ 351 addrsChan: make(chan []resolver.Address, 10), 352 } 353 } 354 355 func (testBalancerKeepAddresses) ResolverError(err error) { 356 panic("not implemented") 357 } 358 359 func (b *testBalancerKeepAddresses) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { 360 return b 361 } 362 363 func (*testBalancerKeepAddresses) Name() string { 364 return testBalancerKeepAddressesName 365 } 366 367 func (b *testBalancerKeepAddresses) UpdateClientConnState(state balancer.ClientConnState) error { 368 b.addrsChan <- state.ResolverState.Addresses 369 return nil 370 } 371 372 func (testBalancerKeepAddresses) UpdateSubConnState(sc balancer.SubConn, s balancer.SubConnState) { 373 panic("not used") 374 } 375 376 func (testBalancerKeepAddresses) Close() { 377 } 378 379 // Make sure that non-grpclb balancers don't get grpclb addresses even if name 380 // resolver sends them 381 func (s) TestNonGRPCLBBalancerGetsNoGRPCLBAddress(t *testing.T) { 382 r := manual.NewBuilderWithScheme("whatever") 383 384 b := newTestBalancerKeepAddresses() 385 balancer.Register(b) 386 387 cc, err := grpc.Dial(r.Scheme()+":///test.server", grpc.WithInsecure(), grpc.WithResolvers(r), 388 grpc.WithBalancerName(b.Name())) 389 if err != nil { 390 t.Fatalf("failed to dial: %v", err) 391 } 392 defer cc.Close() 393 394 grpclbAddresses := []resolver.Address{{ 395 Addr: "grpc.lb.com", 396 Type: resolver.GRPCLB, 397 ServerName: "grpc.lb.com", 398 }} 399 400 nonGRPCLBAddresses := []resolver.Address{{ 401 Addr: "localhost", 402 Type: resolver.Backend, 403 }} 404 405 r.UpdateState(resolver.State{ 406 Addresses: nonGRPCLBAddresses, 407 }) 408 if got := <-b.addrsChan; !reflect.DeepEqual(got, nonGRPCLBAddresses) { 409 t.Fatalf("With only backend addresses, balancer got addresses %v, want %v", got, nonGRPCLBAddresses) 410 } 411 412 r.UpdateState(resolver.State{ 413 Addresses: grpclbAddresses, 414 }) 415 if got := <-b.addrsChan; len(got) != 0 { 416 t.Fatalf("With only grpclb addresses, balancer got addresses %v, want empty", got) 417 } 418 419 r.UpdateState(resolver.State{ 420 Addresses: append(grpclbAddresses, nonGRPCLBAddresses...), 421 }) 422 if got := <-b.addrsChan; !reflect.DeepEqual(got, nonGRPCLBAddresses) { 423 t.Fatalf("With both backend and grpclb addresses, balancer got addresses %v, want %v", got, nonGRPCLBAddresses) 424 } 425 } 426 427 type aiPicker struct { 428 result balancer.PickResult 429 err error 430 } 431 432 func (aip *aiPicker) Pick(_ balancer.PickInfo) (balancer.PickResult, error) { 433 return aip.result, aip.err 434 } 435 436 // attrTransportCreds is a transport credential implementation which stores 437 // Attributes from the ClientHandshakeInfo struct passed in the context locally 438 // for the test to inspect. 439 type attrTransportCreds struct { 440 credentials.TransportCredentials 441 attr *attributes.Attributes 442 } 443 444 func (ac *attrTransportCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { 445 ai := credentials.ClientHandshakeInfoFromContext(ctx) 446 ac.attr = ai.Attributes 447 return rawConn, nil, nil 448 } 449 func (ac *attrTransportCreds) Info() credentials.ProtocolInfo { 450 return credentials.ProtocolInfo{} 451 } 452 func (ac *attrTransportCreds) Clone() credentials.TransportCredentials { 453 return nil 454 } 455 456 // TestAddressAttributesInNewSubConn verifies that the Attributes passed from a 457 // balancer in the resolver.Address that is passes to NewSubConn reaches all the 458 // way to the ClientHandshake method of the credentials configured on the parent 459 // channel. 460 func (s) TestAddressAttributesInNewSubConn(t *testing.T) { 461 const ( 462 testAttrKey = "foo" 463 testAttrVal = "bar" 464 attrBalancerName = "attribute-balancer" 465 ) 466 467 // Register a stub balancer which adds attributes to the first address that 468 // it receives and then calls NewSubConn on it. 469 bf := stub.BalancerFuncs{ 470 UpdateClientConnState: func(bd *stub.BalancerData, ccs balancer.ClientConnState) error { 471 addrs := ccs.ResolverState.Addresses 472 if len(addrs) == 0 { 473 return nil 474 } 475 476 // Only use the first address. 477 attr := attributes.New(testAttrKey, testAttrVal) 478 addrs[0].Attributes = attr 479 sc, err := bd.ClientConn.NewSubConn([]resolver.Address{addrs[0]}, balancer.NewSubConnOptions{}) 480 if err != nil { 481 return err 482 } 483 sc.Connect() 484 return nil 485 }, 486 UpdateSubConnState: func(bd *stub.BalancerData, sc balancer.SubConn, state balancer.SubConnState) { 487 bd.ClientConn.UpdateState(balancer.State{ConnectivityState: state.ConnectivityState, Picker: &aiPicker{result: balancer.PickResult{SubConn: sc}, err: state.ConnectionError}}) 488 }, 489 } 490 stub.Register(attrBalancerName, bf) 491 t.Logf("Registered balancer %s...", attrBalancerName) 492 493 r := manual.NewBuilderWithScheme("whatever") 494 t.Logf("Registered manual resolver with scheme %s...", r.Scheme()) 495 496 lis, err := net.Listen("tcp", "localhost:0") 497 if err != nil { 498 t.Fatal(err) 499 } 500 501 s := grpc.NewServer() 502 testpb.RegisterTestServiceServer(s, &testServer{}) 503 go s.Serve(lis) 504 defer s.Stop() 505 t.Logf("Started gRPC server at %s...", lis.Addr().String()) 506 507 creds := &attrTransportCreds{} 508 dopts := []grpc.DialOption{ 509 grpc.WithTransportCredentials(creds), 510 grpc.WithResolvers(r), 511 grpc.WithDefaultServiceConfig(fmt.Sprintf(`{ "loadBalancingConfig": [{"%v": {}}] }`, attrBalancerName)), 512 } 513 cc, err := grpc.Dial(r.Scheme()+":///test.server", dopts...) 514 if err != nil { 515 t.Fatal(err) 516 } 517 defer cc.Close() 518 tc := testpb.NewTestServiceClient(cc) 519 t.Log("Created a ClientConn...") 520 521 // The first RPC should fail because there's no address. 522 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 523 defer cancel() 524 if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); err == nil || status.Code(err) != codes.DeadlineExceeded { 525 t.Fatalf("EmptyCall() = _, %v, want _, DeadlineExceeded", err) 526 } 527 t.Log("Made an RPC which was expected to fail...") 528 529 state := resolver.State{Addresses: []resolver.Address{{Addr: lis.Addr().String()}}} 530 r.UpdateState(state) 531 t.Logf("Pushing resolver state update: %v through the manual resolver", state) 532 533 // The second RPC should succeed. 534 ctx, cancel = context.WithTimeout(context.Background(), time.Second) 535 defer cancel() 536 if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); err != nil { 537 t.Fatalf("EmptyCall() = _, %v, want _, <nil>", err) 538 } 539 t.Log("Made an RPC which succeeded...") 540 541 wantAttr := attributes.New(testAttrKey, testAttrVal) 542 if gotAttr := creds.attr; !cmp.Equal(gotAttr, wantAttr, cmp.AllowUnexported(attributes.Attributes{})) { 543 t.Fatalf("received attributes %v in creds, want %v", gotAttr, wantAttr) 544 } 545 } 546 547 // TestMetadataInAddressAttributes verifies that the metadata added to 548 // address.Attributes will be sent with the RPCs. 549 func (s) TestMetadataInAddressAttributes(t *testing.T) { 550 const ( 551 testMDKey = "test-md" 552 testMDValue = "test-md-value" 553 mdBalancerName = "metadata-balancer" 554 ) 555 556 // Register a stub balancer which adds metadata to the first address that it 557 // receives and then calls NewSubConn on it. 558 bf := stub.BalancerFuncs{ 559 UpdateClientConnState: func(bd *stub.BalancerData, ccs balancer.ClientConnState) error { 560 addrs := ccs.ResolverState.Addresses 561 if len(addrs) == 0 { 562 return nil 563 } 564 // Only use the first address. 565 sc, err := bd.ClientConn.NewSubConn([]resolver.Address{ 566 imetadata.Set(addrs[0], metadata.Pairs(testMDKey, testMDValue)), 567 }, balancer.NewSubConnOptions{}) 568 if err != nil { 569 return err 570 } 571 sc.Connect() 572 return nil 573 }, 574 UpdateSubConnState: func(bd *stub.BalancerData, sc balancer.SubConn, state balancer.SubConnState) { 575 bd.ClientConn.UpdateState(balancer.State{ConnectivityState: state.ConnectivityState, Picker: &aiPicker{result: balancer.PickResult{SubConn: sc}, err: state.ConnectionError}}) 576 }, 577 } 578 stub.Register(mdBalancerName, bf) 579 t.Logf("Registered balancer %s...", mdBalancerName) 580 581 testMDChan := make(chan []string, 1) 582 ss := &stubserver.StubServer{ 583 EmptyCallF: func(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) { 584 md, ok := metadata.FromIncomingContext(ctx) 585 if ok { 586 select { 587 case testMDChan <- md[testMDKey]: 588 case <-ctx.Done(): 589 return nil, ctx.Err() 590 } 591 } 592 return &testpb.Empty{}, nil 593 }, 594 } 595 if err := ss.Start(nil, grpc.WithDefaultServiceConfig( 596 fmt.Sprintf(`{ "loadBalancingConfig": [{"%v": {}}] }`, mdBalancerName), 597 )); err != nil { 598 t.Fatalf("Error starting endpoint server: %v", err) 599 } 600 defer ss.Stop() 601 602 // The RPC should succeed with the expected md. 603 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 604 defer cancel() 605 if _, err := ss.Client.EmptyCall(ctx, &testpb.Empty{}); err != nil { 606 t.Fatalf("EmptyCall() = _, %v, want _, <nil>", err) 607 } 608 t.Log("Made an RPC which succeeded...") 609 610 // The server should receive the test metadata. 611 md1 := <-testMDChan 612 if len(md1) == 0 || md1[0] != testMDValue { 613 t.Fatalf("got md: %v, want %v", md1, []string{testMDValue}) 614 } 615 } 616 617 // TestServersSwap creates two servers and verifies the client switches between 618 // them when the name resolver reports the first and then the second. 619 func (s) TestServersSwap(t *testing.T) { 620 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 621 defer cancel() 622 623 // Initialize servers 624 reg := func(username string) (addr string, cleanup func()) { 625 lis, err := net.Listen("tcp", "localhost:0") 626 if err != nil { 627 t.Fatalf("Error while listening. Err: %v", err) 628 } 629 s := grpc.NewServer() 630 ts := &funcServer{ 631 unaryCall: func(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { 632 return &testpb.SimpleResponse{Username: username}, nil 633 }, 634 } 635 testpb.RegisterTestServiceServer(s, ts) 636 go s.Serve(lis) 637 return lis.Addr().String(), s.Stop 638 } 639 const one = "1" 640 addr1, cleanup := reg(one) 641 defer cleanup() 642 const two = "2" 643 addr2, cleanup := reg(two) 644 defer cleanup() 645 646 // Initialize client 647 r := manual.NewBuilderWithScheme("whatever") 648 r.InitialState(resolver.State{Addresses: []resolver.Address{{Addr: addr1}}}) 649 cc, err := grpc.DialContext(ctx, r.Scheme()+":///", grpc.WithInsecure(), grpc.WithResolvers(r)) 650 if err != nil { 651 t.Fatalf("Error creating client: %v", err) 652 } 653 defer cc.Close() 654 client := testpb.NewTestServiceClient(cc) 655 656 // Confirm we are connected to the first server 657 if res, err := client.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil || res.Username != one { 658 t.Fatalf("UnaryCall(_) = %v, %v; want {Username: %q}, nil", res, err, one) 659 } 660 661 // Update resolver to report only the second server 662 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: addr2}}}) 663 664 // Loop until new RPCs talk to server two. 665 for i := 0; i < 2000; i++ { 666 if res, err := client.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil { 667 t.Fatalf("UnaryCall(_) = _, %v; want _, nil", err) 668 } else if res.Username == two { 669 break // pass 670 } 671 time.Sleep(5 * time.Millisecond) 672 } 673 } 674 675 // TestEmptyAddrs verifies client behavior when a working connection is 676 // removed. In pick first and round-robin, both will continue using the old 677 // connections. 678 func (s) TestEmptyAddrs(t *testing.T) { 679 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 680 defer cancel() 681 682 // Initialize server 683 lis, err := net.Listen("tcp", "localhost:0") 684 if err != nil { 685 t.Fatalf("Error while listening. Err: %v", err) 686 } 687 s := grpc.NewServer() 688 defer s.Stop() 689 const one = "1" 690 ts := &funcServer{ 691 unaryCall: func(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { 692 return &testpb.SimpleResponse{Username: one}, nil 693 }, 694 } 695 testpb.RegisterTestServiceServer(s, ts) 696 go s.Serve(lis) 697 698 // Initialize pickfirst client 699 pfr := manual.NewBuilderWithScheme("whatever") 700 701 pfr.InitialState(resolver.State{Addresses: []resolver.Address{{Addr: lis.Addr().String()}}}) 702 703 pfcc, err := grpc.DialContext(ctx, pfr.Scheme()+":///", grpc.WithInsecure(), grpc.WithResolvers(pfr)) 704 if err != nil { 705 t.Fatalf("Error creating client: %v", err) 706 } 707 defer pfcc.Close() 708 pfclient := testpb.NewTestServiceClient(pfcc) 709 710 // Confirm we are connected to the server 711 if res, err := pfclient.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil || res.Username != one { 712 t.Fatalf("UnaryCall(_) = %v, %v; want {Username: %q}, nil", res, err, one) 713 } 714 715 // Remove all addresses. 716 pfr.UpdateState(resolver.State{}) 717 718 // Initialize roundrobin client 719 rrr := manual.NewBuilderWithScheme("whatever") 720 721 rrr.InitialState(resolver.State{Addresses: []resolver.Address{{Addr: lis.Addr().String()}}}) 722 723 rrcc, err := grpc.DialContext(ctx, rrr.Scheme()+":///", grpc.WithInsecure(), grpc.WithResolvers(rrr), 724 grpc.WithDefaultServiceConfig(fmt.Sprintf(`{ "loadBalancingConfig": [{"%v": {}}] }`, roundrobin.Name))) 725 if err != nil { 726 t.Fatalf("Error creating client: %v", err) 727 } 728 defer rrcc.Close() 729 rrclient := testpb.NewTestServiceClient(rrcc) 730 731 // Confirm we are connected to the server 732 if res, err := rrclient.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil || res.Username != one { 733 t.Fatalf("UnaryCall(_) = %v, %v; want {Username: %q}, nil", res, err, one) 734 } 735 736 // Remove all addresses. 737 rrr.UpdateState(resolver.State{}) 738 739 // Confirm several new RPCs succeed on pick first. 740 for i := 0; i < 10; i++ { 741 if _, err := pfclient.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil { 742 t.Fatalf("UnaryCall(_) = _, %v; want _, nil", err) 743 } 744 time.Sleep(5 * time.Millisecond) 745 } 746 747 // Confirm several new RPCs succeed on round robin. 748 for i := 0; i < 10; i++ { 749 if _, err := pfclient.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil { 750 t.Fatalf("UnaryCall(_) = _, %v; want _, nil", err) 751 } 752 time.Sleep(5 * time.Millisecond) 753 } 754 } 755 756 func (s) TestWaitForReady(t *testing.T) { 757 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 758 defer cancel() 759 760 // Initialize server 761 lis, err := net.Listen("tcp", "localhost:0") 762 if err != nil { 763 t.Fatalf("Error while listening. Err: %v", err) 764 } 765 s := grpc.NewServer() 766 defer s.Stop() 767 const one = "1" 768 ts := &funcServer{ 769 unaryCall: func(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { 770 return &testpb.SimpleResponse{Username: one}, nil 771 }, 772 } 773 testpb.RegisterTestServiceServer(s, ts) 774 go s.Serve(lis) 775 776 // Initialize client 777 r := manual.NewBuilderWithScheme("whatever") 778 779 cc, err := grpc.DialContext(ctx, r.Scheme()+":///", grpc.WithInsecure(), grpc.WithResolvers(r)) 780 if err != nil { 781 t.Fatalf("Error creating client: %v", err) 782 } 783 defer cc.Close() 784 client := testpb.NewTestServiceClient(cc) 785 786 // Report an error so non-WFR RPCs will give up early. 787 r.CC.ReportError(errors.New("fake resolver error")) 788 789 // Ensure the client is not connected to anything and fails non-WFR RPCs. 790 if res, err := client.UnaryCall(ctx, &testpb.SimpleRequest{}); status.Code(err) != codes.Unavailable { 791 t.Fatalf("UnaryCall(_) = %v, %v; want _, Code()=%v", res, err, codes.Unavailable) 792 } 793 794 errChan := make(chan error, 1) 795 go func() { 796 if res, err := client.UnaryCall(ctx, &testpb.SimpleRequest{}, grpc.WaitForReady(true)); err != nil || res.Username != one { 797 errChan <- fmt.Errorf("UnaryCall(_) = %v, %v; want {Username: %q}, nil", res, err, one) 798 } 799 close(errChan) 800 }() 801 802 select { 803 case err := <-errChan: 804 t.Errorf("unexpected receive from errChan before addresses provided") 805 t.Fatal(err.Error()) 806 case <-time.After(5 * time.Millisecond): 807 } 808 809 // Resolve the server. The WFR RPC should unblock and use it. 810 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: lis.Addr().String()}}}) 811 812 if err := <-errChan; err != nil { 813 t.Fatal(err.Error()) 814 } 815 }