Skip to content

Commit 31151d2

Browse files
committed
One more test.
1 parent f139211 commit 31151d2

File tree

3 files changed

+88
-6
lines changed

3 files changed

+88
-6
lines changed

clientconn.go

-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ func UseCompressor(name string) CallOption {
121121
func WithWaitForServerSettings() DialOption {
122122
return func(o *dialOptions) {
123123
o.waitForServerSettings = true
124-
o.block = true
125124
}
126125
}
127126

clientconn_test.go

+77-4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import (
3232
"google.golang.org/grpc/credentials"
3333
"google.golang.org/grpc/keepalive"
3434
"google.golang.org/grpc/naming"
35+
"google.golang.org/grpc/resolver"
36+
"google.golang.org/grpc/resolver/manual"
3537
_ "google.golang.org/grpc/resolver/passthrough"
3638
"google.golang.org/grpc/test/leakcheck"
3739
"google.golang.org/grpc/testdata"
@@ -46,6 +48,77 @@ func assertState(wantState connectivity.State, cc *ClientConn) (connectivity.Sta
4648
return state, state == wantState
4749
}
4850

51+
func TestDialWithMultipleBackendsNotSendingServerPreface(t *testing.T) {
52+
defer leakcheck.Check(t)
53+
numServers := 2
54+
servers := make([]net.Listener, numServers)
55+
var err error
56+
for i := 0; i < numServers; i++ {
57+
servers[i], err = net.Listen("tcp", "localhost:0")
58+
if err != nil {
59+
t.Fatalf("Error while listening. Err: %v", err)
60+
}
61+
}
62+
dones := make([]chan struct{}, numServers)
63+
for i := 0; i < numServers; i++ {
64+
dones[i] = make(chan struct{})
65+
}
66+
for i := 0; i < numServers; i++ {
67+
go func(i int) {
68+
defer func() {
69+
close(dones[i])
70+
}()
71+
conn, err := servers[i].Accept()
72+
if err != nil {
73+
t.Errorf("Error while accepting. Err: %v", err)
74+
return
75+
}
76+
defer conn.Close()
77+
switch i {
78+
case 0: // 1st server accepts the connection and immediately closes it.
79+
case 1: // 2nd server accepts the connection and sends settings frames.
80+
framer := http2.NewFramer(conn, conn)
81+
if err := framer.WriteSettings(http2.Setting{}); err != nil {
82+
t.Errorf("Error while writing settings frame. %v", err)
83+
return
84+
}
85+
conn.SetDeadline(time.Now().Add(time.Second))
86+
buf := make([]byte, 1024)
87+
for { // Make sure the connection stays healthy.
88+
_, err = conn.Read(buf)
89+
if err == nil {
90+
continue
91+
}
92+
if nerr, ok := err.(net.Error); !ok || !nerr.Timeout() {
93+
t.Errorf("Server expected the conn.Read(_) to timeout instead got error: %v", err)
94+
}
95+
return
96+
}
97+
}
98+
}(i)
99+
}
100+
r, cleanup := manual.GenerateAndRegisterManualResolver()
101+
defer cleanup()
102+
resolvedAddrs := make([]resolver.Address, numServers)
103+
for i := 0; i < numServers; i++ {
104+
resolvedAddrs[i] = resolver.Address{Addr: servers[i].Addr().String()}
105+
}
106+
r.BootstrapWithAddrs(resolvedAddrs)
107+
client, err := Dial(r.Scheme()+":///test.server", WithInsecure())
108+
if err != nil {
109+
t.Errorf("Dial failed. Err: %v", err)
110+
} else {
111+
defer client.Close()
112+
}
113+
time.Sleep(time.Second) // Close the servers after a second for cleanup.
114+
for _, s := range servers {
115+
s.Close()
116+
}
117+
for _, done := range dones {
118+
<-done
119+
}
120+
}
121+
49122
func TestDialWaitsForServerSettings(t *testing.T) {
50123
defer leakcheck.Check(t)
51124
server, err := net.Listen("tcp", "localhost:0")
@@ -78,7 +151,7 @@ func TestDialWaitsForServerSettings(t *testing.T) {
78151
<-dialDone // Close conn only after dial returns.
79152
}()
80153
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
81-
client, err := DialContext(ctx, server.Addr().String(), WithInsecure(), WithWaitForServerSettings())
154+
client, err := DialContext(ctx, server.Addr().String(), WithInsecure(), WithWaitForServerSettings(), WithBlock())
82155
close(dialDone)
83156
if err != nil {
84157
cancel()
@@ -197,15 +270,15 @@ func TestBackoffWhenNoServerPrefaceReceived(t *testing.T) {
197270
t.Errorf("Error while accepting. Err: %v", err)
198271
return
199272
}
200-
now := time.Now()
273+
meow := time.Now()
201274
conn.Close()
202-
dr := now.Sub(prevAt)
275+
dr := meow.Sub(prevAt)
203276
if dr <= prevDuration {
204277
t.Errorf("Client backoff did not increase with retries. Previoud duration: %v, current duration: %v", prevDuration, dr)
205278
return
206279
}
207280
prevDuration = dr
208-
prevAt = now
281+
prevAt = meow
209282
}
210283
}()
211284
client, err := Dial(server.Addr().String(), WithInsecure())

resolver/manual/manual.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,22 @@ type Resolver struct {
3939
scheme string
4040

4141
// Fields actually belong to the resolver.
42-
cc resolver.ClientConn
42+
cc resolver.ClientConn
43+
bootstrapAddrs []resolver.Address
44+
}
45+
46+
// BootstrapWithAddrs adds resloved addresses to the resolver so that
47+
// NewAddress doesn't need to be explicitly called after Dial.
48+
func (r *Resolver) BootstrapWithAddrs(addrs []resolver.Address) {
49+
r.bootstrapAddrs = addrs
4350
}
4451

4552
// Build returns itself for Resolver, because it's both a builder and a resolver.
4653
func (r *Resolver) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOption) (resolver.Resolver, error) {
4754
r.cc = cc
55+
if r.bootstrapAddrs != nil {
56+
r.NewAddress(r.bootstrapAddrs)
57+
}
4858
return r, nil
4959
}
5060

0 commit comments

Comments
 (0)