...

Source file src/google.golang.org/grpc/balancer/base/balancer_test.go

Documentation: google.golang.org/grpc/balancer/base

     1  /*
     2   *
     3   * Copyright 2020 gRPC authors.
     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.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package base
    20  
    21  import (
    22  	"context"
    23  	"testing"
    24  	"time"
    25  
    26  	"google.golang.org/grpc/attributes"
    27  	"google.golang.org/grpc/balancer"
    28  	"google.golang.org/grpc/connectivity"
    29  	"google.golang.org/grpc/resolver"
    30  )
    31  
    32  type testClientConn struct {
    33  	balancer.ClientConn
    34  	newSubConn func([]resolver.Address, balancer.NewSubConnOptions) (balancer.SubConn, error)
    35  }
    36  
    37  func (c *testClientConn) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
    38  	return c.newSubConn(addrs, opts)
    39  }
    40  
    41  func (c *testClientConn) UpdateState(balancer.State) {}
    42  
    43  type testSubConn struct {
    44  	updateState func(balancer.SubConnState)
    45  }
    46  
    47  func (sc *testSubConn) UpdateAddresses(addresses []resolver.Address) {}
    48  
    49  func (sc *testSubConn) Connect() {}
    50  
    51  func (sc *testSubConn) Shutdown() {}
    52  
    53  func (sc *testSubConn) GetOrBuildProducer(balancer.ProducerBuilder) (balancer.Producer, func()) {
    54  	return nil, nil
    55  }
    56  
    57  // testPickBuilder creates balancer.Picker for test.
    58  type testPickBuilder struct {
    59  	validate func(info PickerBuildInfo)
    60  }
    61  
    62  func (p *testPickBuilder) Build(info PickerBuildInfo) balancer.Picker {
    63  	p.validate(info)
    64  	return nil
    65  }
    66  
    67  func TestBaseBalancerReserveAttributes(t *testing.T) {
    68  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    69  	defer cancel()
    70  	validated := make(chan struct{}, 1)
    71  	v := func(info PickerBuildInfo) {
    72  		defer func() { validated <- struct{}{} }()
    73  		for _, sc := range info.ReadySCs {
    74  			if sc.Address.Addr == "1.1.1.1" {
    75  				if sc.Address.Attributes == nil {
    76  					t.Errorf("in picker.validate, got address %+v with nil attributes, want not nil", sc.Address)
    77  				}
    78  				foo, ok := sc.Address.Attributes.Value("foo").(string)
    79  				if !ok || foo != "2233niang" {
    80  					t.Errorf("in picker.validate, got address[1.1.1.1] with invalid attributes value %v, want 2233niang", sc.Address.Attributes.Value("foo"))
    81  				}
    82  			} else if sc.Address.Addr == "2.2.2.2" {
    83  				if sc.Address.Attributes != nil {
    84  					t.Error("in b.subConns, got address[2.2.2.2] with not nil attributes, want nil")
    85  				}
    86  			}
    87  		}
    88  	}
    89  	pickBuilder := &testPickBuilder{validate: v}
    90  	b := (&baseBuilder{pickerBuilder: pickBuilder}).Build(&testClientConn{
    91  		newSubConn: func(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
    92  			return &testSubConn{updateState: opts.StateListener}, nil
    93  		},
    94  	}, balancer.BuildOptions{}).(*baseBalancer)
    95  
    96  	b.UpdateClientConnState(balancer.ClientConnState{
    97  		ResolverState: resolver.State{
    98  			Addresses: []resolver.Address{
    99  				{Addr: "1.1.1.1", Attributes: attributes.New("foo", "2233niang")},
   100  				{Addr: "2.2.2.2", Attributes: nil},
   101  			},
   102  		},
   103  	})
   104  	select {
   105  	case <-validated:
   106  	case <-ctx.Done():
   107  		t.Fatalf("timed out waiting for UpdateClientConnState to call picker.Build")
   108  	}
   109  
   110  	for sc := range b.scStates {
   111  		sc.(*testSubConn).updateState(balancer.SubConnState{ConnectivityState: connectivity.Ready, ConnectionError: nil})
   112  		select {
   113  		case <-validated:
   114  		case <-ctx.Done():
   115  			t.Fatalf("timed out waiting for UpdateClientConnState to call picker.Build")
   116  		}
   117  	}
   118  }
   119  

View as plain text