TestAddressAttributesInNewSubConn verifies that the Attributes passed from a balancer in the resolver.Address that is passes to NewSubConn reaches all the way to the ClientHandshake method of the credentials configured on the parent channel.
(t *testing.T)
| 377 | // way to the ClientHandshake method of the credentials configured on the parent |
| 378 | // channel. |
| 379 | func (s) TestAddressAttributesInNewSubConn(t *testing.T) { |
| 380 | const ( |
| 381 | testAttrKey = "foo" |
| 382 | testAttrVal = "bar" |
| 383 | attrBalancerName = "attribute-balancer" |
| 384 | ) |
| 385 | |
| 386 | // Register a stub balancer which adds attributes to the first address that |
| 387 | // it receives and then calls NewSubConn on it. |
| 388 | bf := stub.BalancerFuncs{ |
| 389 | UpdateClientConnState: func(bd *stub.BalancerData, ccs balancer.ClientConnState) error { |
| 390 | addrs := ccs.ResolverState.Addresses |
| 391 | if len(addrs) == 0 { |
| 392 | return nil |
| 393 | } |
| 394 | |
| 395 | // Only use the first address. |
| 396 | attr := attributes.New(testAttrKey, testAttrVal) |
| 397 | addrs[0].Attributes = attr |
| 398 | var sc balancer.SubConn |
| 399 | sc, err := bd.ClientConn.NewSubConn([]resolver.Address{addrs[0]}, balancer.NewSubConnOptions{ |
| 400 | StateListener: func(state balancer.SubConnState) { |
| 401 | bd.ClientConn.UpdateState(balancer.State{ConnectivityState: state.ConnectivityState, Picker: &aiPicker{result: balancer.PickResult{SubConn: sc}, err: state.ConnectionError}}) |
| 402 | }, |
| 403 | }) |
| 404 | if err != nil { |
| 405 | return err |
| 406 | } |
| 407 | sc.Connect() |
| 408 | return nil |
| 409 | }, |
| 410 | } |
| 411 | stub.Register(attrBalancerName, bf) |
| 412 | t.Logf("Registered balancer %s...", attrBalancerName) |
| 413 | |
| 414 | r := manual.NewBuilderWithScheme("whatever") |
| 415 | t.Logf("Registered manual resolver with scheme %s...", r.Scheme()) |
| 416 | |
| 417 | lis, err := net.Listen("tcp", "localhost:0") |
| 418 | if err != nil { |
| 419 | t.Fatal(err) |
| 420 | } |
| 421 | stub := &stubserver.StubServer{ |
| 422 | Listener: lis, |
| 423 | EmptyCallF: func(_ context.Context, _ *testpb.Empty) (*testpb.Empty, error) { |
| 424 | return &testpb.Empty{}, nil |
| 425 | }, |
| 426 | S: grpc.NewServer(), |
| 427 | } |
| 428 | stubserver.StartTestService(t, stub) |
| 429 | defer stub.S.Stop() |
| 430 | t.Logf("Started gRPC server at %s...", lis.Addr().String()) |
| 431 | |
| 432 | creds := &attrTransportCreds{} |
| 433 | dopts := []grpc.DialOption{ |
| 434 | grpc.WithTransportCredentials(creds), |
| 435 | grpc.WithResolvers(r), |
| 436 | grpc.WithDefaultServiceConfig(fmt.Sprintf(`{ "loadBalancingConfig": [{"%v": {}}] }`, attrBalancerName)), |
nothing calls this directly
no test coverage detected