1
18
19 package grpc
20
21 import (
22 "context"
23 "fmt"
24 "net"
25 "testing"
26
27 "github.com/google/go-cmp/cmp"
28 "google.golang.org/grpc/attributes"
29 "google.golang.org/grpc/balancer"
30 "google.golang.org/grpc/credentials/insecure"
31 "google.golang.org/grpc/internal/balancer/stub"
32 "google.golang.org/grpc/resolver"
33 "google.golang.org/grpc/resolver/manual"
34 )
35
36 type wrapResolverBuilder struct {
37 resolver.Builder
38 scheme string
39 }
40
41 func (w *wrapResolverBuilder) Scheme() string {
42 return w.scheme
43 }
44
45 func init() {
46 resolver.Register(&wrapResolverBuilder{Builder: resolver.Get("passthrough"), scheme: "casetest"})
47 resolver.Register(&wrapResolverBuilder{Builder: resolver.Get("dns"), scheme: "caseTest"})
48 }
49
50 func (s) TestResolverCaseSensitivity(t *testing.T) {
51
52
53
54
55
56 target := "caseTest:///localhost:1234"
57 addrCh := make(chan string, 1)
58 customDialer := func(ctx context.Context, addr string) (net.Conn, error) {
59 select {
60 case addrCh <- addr:
61 default:
62 }
63 return nil, fmt.Errorf("not dialing with custom dialer")
64 }
65
66 cc, err := Dial(target, WithContextDialer(customDialer), WithTransportCredentials(insecure.NewCredentials()))
67 if err != nil {
68 t.Fatalf("Unexpected Dial(%q) error: %v", target, err)
69 }
70 cc.Connect()
71 if got, want := <-addrCh, "localhost:1234"; got != want {
72 cc.Close()
73 t.Fatalf("Dialer got address %q; wanted %q", got, want)
74 }
75 cc.Close()
76
77
78 select {
79 case <-addrCh:
80 default:
81 }
82
83 res := &wrapResolverBuilder{Builder: resolver.Get("dns"), scheme: "caseTest2"}
84
85
86
87 target = "caseTest2:///localhost:1234"
88 cc, err = Dial(target, WithContextDialer(customDialer), WithResolvers(res), WithTransportCredentials(insecure.NewCredentials()))
89 if err != nil {
90 t.Fatalf("Unexpected Dial(%q) error: %v", target, err)
91 }
92 cc.Connect()
93 if got, want := <-addrCh, target; got != want {
94 cc.Close()
95 t.Fatalf("Dialer got address %q; wanted %q", got, want)
96 }
97 cc.Close()
98 }
99
100
101
102 func (s) TestResolverAddressesToEndpoints(t *testing.T) {
103 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
104 defer cancel()
105
106 const scheme = "testresolveraddressestoendpoints"
107 r := manual.NewBuilderWithScheme(scheme)
108
109 stateCh := make(chan balancer.ClientConnState, 1)
110 bf := stub.BalancerFuncs{
111 UpdateClientConnState: func(_ *stub.BalancerData, ccs balancer.ClientConnState) error {
112 stateCh <- ccs
113 return nil
114 },
115 }
116 balancerName := "stub-balancer-" + scheme
117 stub.Register(balancerName, bf)
118
119 a1 := attributes.New("x", "y")
120 a2 := attributes.New("a", "b")
121 r.InitialState(resolver.State{Addresses: []resolver.Address{{Addr: "addr1", BalancerAttributes: a1}, {Addr: "addr2", BalancerAttributes: a2}}})
122
123 cc, err := Dial(r.Scheme()+":///",
124 WithTransportCredentials(insecure.NewCredentials()),
125 WithResolvers(r),
126 WithDefaultServiceConfig(fmt.Sprintf(`{"loadBalancingConfig": [{"%s":{}}]}`, balancerName)))
127 if err != nil {
128 t.Fatalf("Unexpected error dialing: %v", err)
129 }
130 defer cc.Close()
131
132 select {
133 case got := <-stateCh:
134 want := []resolver.Endpoint{
135 {Addresses: []resolver.Address{{Addr: "addr1"}}, Attributes: a1},
136 {Addresses: []resolver.Address{{Addr: "addr2"}}, Attributes: a2},
137 }
138 if diff := cmp.Diff(got.ResolverState.Endpoints, want); diff != "" {
139 t.Errorf("Did not receive expected endpoints. Diff (-got +want):\n%v", diff)
140 }
141 case <-ctx.Done():
142 t.Fatalf("timed out waiting for endpoints")
143 }
144 }
145
146
147
148 func (s) TestResolverAddressesWithTypedNilAttribute(t *testing.T) {
149 r := manual.NewBuilderWithScheme(t.Name())
150 resolver.Register(r)
151
152 addrAttr := attributes.New("typed_nil", (*stringerVal)(nil))
153 r.InitialState(resolver.State{Addresses: []resolver.Address{{Addr: "addr1", Attributes: addrAttr}}})
154
155 cc, err := Dial(r.Scheme()+":///", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r))
156 if err != nil {
157 t.Fatalf("Unexpected error dialing: %v", err)
158 }
159 defer cc.Close()
160 }
161
162 type stringerVal struct{ s string }
163
164 func (s stringerVal) String() string { return s.s }
165
View as plain text