3 * Copyright 2014 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
27 "golang.org/x/net/context"
29 "google.golang.org/grpc/connectivity"
30 "google.golang.org/grpc/credentials"
31 "google.golang.org/grpc/keepalive"
32 "google.golang.org/grpc/naming"
33 _ "google.golang.org/grpc/resolver/passthrough"
34 "google.golang.org/grpc/test/leakcheck"
35 "google.golang.org/grpc/testdata"
38 func assertState(wantState connectivity.State, cc *ClientConn) (connectivity.State, bool) {
39 ctx, cancel := context.WithTimeout(context.Background(), time.Second)
41 var state connectivity.State
42 for state = cc.GetState(); state != wantState && cc.WaitForStateChange(ctx, state); state = cc.GetState() {
44 return state, state == wantState
47 func TestConnectivityStates(t *testing.T) {
48 defer leakcheck.Check(t)
49 servers, resolver, cleanup := startServers(t, 2, math.MaxUint32)
51 cc, err := Dial("passthrough:///foo.bar.com", WithBalancer(RoundRobin(resolver)), WithInsecure())
53 t.Fatalf("Dial(\"foo.bar.com\", WithBalancer(_)) = _, %v, want _ <nil>", err)
56 wantState := connectivity.Ready
57 if state, ok := assertState(wantState, cc); !ok {
58 t.Fatalf("asserState(%s) = %s, false, want %s, true", wantState, state, wantState)
60 // Send an update to delete the server connection (tearDown addrConn).
61 update := []*naming.Update{
64 Addr: "localhost:" + servers[0].port,
67 resolver.w.inject(update)
68 wantState = connectivity.TransientFailure
69 if state, ok := assertState(wantState, cc); !ok {
70 t.Fatalf("asserState(%s) = %s, false, want %s, true", wantState, state, wantState)
72 update[0] = &naming.Update{
74 Addr: "localhost:" + servers[1].port,
76 resolver.w.inject(update)
77 wantState = connectivity.Ready
78 if state, ok := assertState(wantState, cc); !ok {
79 t.Fatalf("asserState(%s) = %s, false, want %s, true", wantState, state, wantState)
84 func TestDialTimeout(t *testing.T) {
85 defer leakcheck.Check(t)
86 conn, err := Dial("passthrough:///Non-Existent.Server:80", WithTimeout(time.Millisecond), WithBlock(), WithInsecure())
90 if err != context.DeadlineExceeded {
91 t.Fatalf("Dial(_, _) = %v, %v, want %v", conn, err, context.DeadlineExceeded)
95 func TestTLSDialTimeout(t *testing.T) {
96 defer leakcheck.Check(t)
97 creds, err := credentials.NewClientTLSFromFile(testdata.Path("ca.pem"), "x.test.youtube.com")
99 t.Fatalf("Failed to create credentials %v", err)
101 conn, err := Dial("passthrough:///Non-Existent.Server:80", WithTransportCredentials(creds), WithTimeout(time.Millisecond), WithBlock())
105 if err != context.DeadlineExceeded {
106 t.Fatalf("Dial(_, _) = %v, %v, want %v", conn, err, context.DeadlineExceeded)
110 func TestDefaultAuthority(t *testing.T) {
111 defer leakcheck.Check(t)
112 target := "Non-Existent.Server:8080"
113 conn, err := Dial(target, WithInsecure())
115 t.Fatalf("Dial(_, _) = _, %v, want _, <nil>", err)
118 if conn.authority != target {
119 t.Fatalf("%v.authority = %v, want %v", conn, conn.authority, target)
123 func TestTLSServerNameOverwrite(t *testing.T) {
124 defer leakcheck.Check(t)
125 overwriteServerName := "over.write.server.name"
126 creds, err := credentials.NewClientTLSFromFile(testdata.Path("ca.pem"), overwriteServerName)
128 t.Fatalf("Failed to create credentials %v", err)
130 conn, err := Dial("passthrough:///Non-Existent.Server:80", WithTransportCredentials(creds))
132 t.Fatalf("Dial(_, _) = _, %v, want _, <nil>", err)
135 if conn.authority != overwriteServerName {
136 t.Fatalf("%v.authority = %v, want %v", conn, conn.authority, overwriteServerName)
140 func TestWithAuthority(t *testing.T) {
141 defer leakcheck.Check(t)
142 overwriteServerName := "over.write.server.name"
143 conn, err := Dial("passthrough:///Non-Existent.Server:80", WithInsecure(), WithAuthority(overwriteServerName))
145 t.Fatalf("Dial(_, _) = _, %v, want _, <nil>", err)
148 if conn.authority != overwriteServerName {
149 t.Fatalf("%v.authority = %v, want %v", conn, conn.authority, overwriteServerName)
153 func TestWithAuthorityAndTLS(t *testing.T) {
154 defer leakcheck.Check(t)
155 overwriteServerName := "over.write.server.name"
156 creds, err := credentials.NewClientTLSFromFile(testdata.Path("ca.pem"), overwriteServerName)
158 t.Fatalf("Failed to create credentials %v", err)
160 conn, err := Dial("passthrough:///Non-Existent.Server:80", WithTransportCredentials(creds), WithAuthority("no.effect.authority"))
162 t.Fatalf("Dial(_, _) = _, %v, want _, <nil>", err)
165 if conn.authority != overwriteServerName {
166 t.Fatalf("%v.authority = %v, want %v", conn, conn.authority, overwriteServerName)
170 func TestDialContextCancel(t *testing.T) {
171 defer leakcheck.Check(t)
172 ctx, cancel := context.WithCancel(context.Background())
174 if _, err := DialContext(ctx, "Non-Existent.Server:80", WithBlock(), WithInsecure()); err != context.Canceled {
175 t.Fatalf("DialContext(%v, _) = _, %v, want _, %v", ctx, err, context.Canceled)
179 // blockingBalancer mimics the behavior of balancers whose initialization takes a long time.
180 // In this test, reading from blockingBalancer.Notify() blocks forever.
181 type blockingBalancer struct {
185 func newBlockingBalancer() Balancer {
186 return &blockingBalancer{ch: make(chan []Address)}
188 func (b *blockingBalancer) Start(target string, config BalancerConfig) error {
191 func (b *blockingBalancer) Up(addr Address) func(error) {
194 func (b *blockingBalancer) Get(ctx context.Context, opts BalancerGetOptions) (addr Address, put func(), err error) {
195 return Address{}, nil, nil
197 func (b *blockingBalancer) Notify() <-chan []Address {
200 func (b *blockingBalancer) Close() error {
205 func TestDialWithBlockingBalancer(t *testing.T) {
206 defer leakcheck.Check(t)
207 ctx, cancel := context.WithCancel(context.Background())
208 dialDone := make(chan struct{})
210 DialContext(ctx, "Non-Existent.Server:80", WithBlock(), WithInsecure(), WithBalancer(newBlockingBalancer()))
217 // securePerRPCCredentials always requires transport security.
218 type securePerRPCCredentials struct{}
220 func (c securePerRPCCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
224 func (c securePerRPCCredentials) RequireTransportSecurity() bool {
228 func TestCredentialsMisuse(t *testing.T) {
229 defer leakcheck.Check(t)
230 tlsCreds, err := credentials.NewClientTLSFromFile(testdata.Path("ca.pem"), "x.test.youtube.com")
232 t.Fatalf("Failed to create authenticator %v", err)
234 // Two conflicting credential configurations
235 if _, err := Dial("passthrough:///Non-Existent.Server:80", WithTransportCredentials(tlsCreds), WithBlock(), WithInsecure()); err != errCredentialsConflict {
236 t.Fatalf("Dial(_, _) = _, %v, want _, %v", err, errCredentialsConflict)
238 // security info on insecure connection
239 if _, err := Dial("passthrough:///Non-Existent.Server:80", WithPerRPCCredentials(securePerRPCCredentials{}), WithBlock(), WithInsecure()); err != errTransportCredentialsMissing {
240 t.Fatalf("Dial(_, _) = _, %v, want _, %v", err, errTransportCredentialsMissing)
244 func TestWithBackoffConfigDefault(t *testing.T) {
245 defer leakcheck.Check(t)
246 testBackoffConfigSet(t, &DefaultBackoffConfig)
249 func TestWithBackoffConfig(t *testing.T) {
250 defer leakcheck.Check(t)
251 b := BackoffConfig{MaxDelay: DefaultBackoffConfig.MaxDelay / 2}
253 setDefaults(&expected) // defaults should be set
254 testBackoffConfigSet(t, &expected, WithBackoffConfig(b))
257 func TestWithBackoffMaxDelay(t *testing.T) {
258 defer leakcheck.Check(t)
259 md := DefaultBackoffConfig.MaxDelay / 2
260 expected := BackoffConfig{MaxDelay: md}
261 setDefaults(&expected)
262 testBackoffConfigSet(t, &expected, WithBackoffMaxDelay(md))
265 func testBackoffConfigSet(t *testing.T, expected *BackoffConfig, opts ...DialOption) {
266 opts = append(opts, WithInsecure())
267 conn, err := Dial("passthrough:///foo:80", opts...)
269 t.Fatalf("unexpected error dialing connection: %v", err)
273 if conn.dopts.bs == nil {
274 t.Fatalf("backoff config not set")
277 actual, ok := conn.dopts.bs.(BackoffConfig)
279 t.Fatalf("unexpected type of backoff config: %#v", conn.dopts.bs)
282 if actual != *expected {
283 t.Fatalf("unexpected backoff config on connection: %v, want %v", actual, expected)
287 // emptyBalancer returns an empty set of servers.
288 type emptyBalancer struct {
292 func newEmptyBalancer() Balancer {
293 return &emptyBalancer{ch: make(chan []Address, 1)}
295 func (b *emptyBalancer) Start(_ string, _ BalancerConfig) error {
299 func (b *emptyBalancer) Up(_ Address) func(error) {
302 func (b *emptyBalancer) Get(_ context.Context, _ BalancerGetOptions) (Address, func(), error) {
303 return Address{}, nil, nil
305 func (b *emptyBalancer) Notify() <-chan []Address {
308 func (b *emptyBalancer) Close() error {
313 func TestNonblockingDialWithEmptyBalancer(t *testing.T) {
314 defer leakcheck.Check(t)
315 ctx, cancel := context.WithCancel(context.Background())
317 dialDone := make(chan error)
319 dialDone <- func() error {
320 conn, err := DialContext(ctx, "Non-Existent.Server:80", WithInsecure(), WithBalancer(newEmptyBalancer()))
327 if err := <-dialDone; err != nil {
328 t.Fatalf("unexpected error dialing connection: %s", err)
332 func TestClientUpdatesParamsAfterGoAway(t *testing.T) {
333 defer leakcheck.Check(t)
334 lis, err := net.Listen("tcp", "localhost:0")
336 t.Fatalf("Failed to listen. Err: %v", err)
339 addr := lis.Addr().String()
343 cc, err := Dial(addr, WithBlock(), WithInsecure(), WithKeepaliveParams(keepalive.ClientParameters{
344 Time: 50 * time.Millisecond,
345 Timeout: 1 * time.Millisecond,
346 PermitWithoutStream: true,
349 t.Fatalf("Dial(%s, _) = _, %v, want _, <nil>", addr, err)
352 time.Sleep(1 * time.Second)
354 defer cc.mu.RUnlock()
356 if v < 100*time.Millisecond {
357 t.Fatalf("cc.dopts.copts.Keepalive.Time = %v , want 100ms", v)