123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- /*
- *
- * Copyright 2019 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- package grpc
- import (
- "fmt"
- "net"
- "testing"
- "google.golang.org/grpc/balancer"
- "google.golang.org/grpc/balancer/roundrobin"
- "google.golang.org/grpc/internal/balancer/stub"
- "google.golang.org/grpc/resolver"
- "google.golang.org/grpc/resolver/manual"
- )
- // TestBalancerErrorResolverPolling injects balancer errors and verifies
- // ResolveNow is called on the resolver with the appropriate backoff strategy
- // being consulted between ResolveNow calls.
- func (s) TestBalancerErrorResolverPolling(t *testing.T) {
- // The test balancer will return ErrBadResolverState iff the
- // ClientConnState contains no addresses.
- bf := stub.BalancerFuncs{
- UpdateClientConnState: func(_ *stub.BalancerData, s balancer.ClientConnState) error {
- if len(s.ResolverState.Addresses) == 0 {
- return balancer.ErrBadResolverState
- }
- return nil
- },
- }
- const balName = "BalancerErrorResolverPolling"
- stub.Register(balName, bf)
- testResolverErrorPolling(t,
- func(r *manual.Resolver) {
- // No addresses so the balancer will fail.
- r.CC.UpdateState(resolver.State{})
- }, func(r *manual.Resolver) {
- // UpdateState will block if ResolveNow is being called (which blocks on
- // rn), so call it in a goroutine. Include some address so the balancer
- // will be happy.
- go r.CC.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: "x"}}})
- },
- WithDefaultServiceConfig(fmt.Sprintf(`{ "loadBalancingConfig": [{"%v": {}}] }`, balName)))
- }
- // TestRoundRobinZeroAddressesResolverPolling reports no addresses to the round
- // robin balancer and verifies ResolveNow is called on the resolver with the
- // appropriate backoff strategy being consulted between ResolveNow calls.
- func (s) TestRoundRobinZeroAddressesResolverPolling(t *testing.T) {
- // We need to start a real server or else the connecting loop will call
- // ResolveNow after every iteration, even after a valid resolver result is
- // returned.
- lis, err := net.Listen("tcp", "localhost:0")
- if err != nil {
- t.Fatalf("Error while listening. Err: %v", err)
- }
- defer lis.Close()
- s := NewServer()
- defer s.Stop()
- go s.Serve(lis)
- testResolverErrorPolling(t,
- func(r *manual.Resolver) {
- // No addresses so the balancer will fail.
- r.CC.UpdateState(resolver.State{})
- }, func(r *manual.Resolver) {
- // UpdateState will block if ResolveNow is being called (which
- // blocks on rn), so call it in a goroutine. Include a valid
- // address so the balancer will be happy.
- go r.CC.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: lis.Addr().String()}}})
- },
- WithDefaultServiceConfig(fmt.Sprintf(`{ "loadBalancingConfig": [{"%v": {}}] }`, roundrobin.Name)))
- }
|