@@ -67,20 +67,54 @@ func Test(t *testing.T) {
6767 grpctest .RunSubTests (t , s {})
6868}
6969
70+ // testServer is a server than can be stopped and resumed without closing
71+ // the listener. This guarantees the same port number (and address) is used
72+ // after restart. When a server is stopped, it accepts and closes all tcp
73+ // connections from clients.
74+ type testServer struct {
75+ stubserver.StubServer
76+ lis * testutils.RestartableListener
77+ }
78+
79+ func (s * testServer ) stop () {
80+ s .lis .Stop ()
81+ }
82+
83+ func (s * testServer ) resume () {
84+ s .lis .Restart ()
85+ }
86+
87+ func newTestServer (t * testing.T ) * testServer {
88+ l , err := testutils .LocalTCPListener ()
89+ if err != nil {
90+ t .Fatalf ("Failed to create listener: %v" , err )
91+ }
92+ rl := testutils .NewRestartableListener (l )
93+ ss := stubserver.StubServer {
94+ EmptyCallF : func (context.Context , * testpb.Empty ) (* testpb.Empty , error ) { return & testpb.Empty {}, nil },
95+ Listener : rl ,
96+ }
97+ return & testServer {
98+ StubServer : ss ,
99+ lis : rl ,
100+ }
101+ }
102+
70103// setupPickFirstLeaf performs steps required for pick_first tests. It starts a
71104// bunch of backends exporting the TestService, and creates a ClientConn to them.
72105func setupPickFirstLeaf (t * testing.T , backendCount int , opts ... grpc.DialOption ) (* grpc.ClientConn , * manual.Resolver , * backendManager ) {
73106 t .Helper ()
74107 r := manual .NewBuilderWithScheme ("whatever" )
75- backends := make ([]* stubserver. StubServer , backendCount )
108+ backends := make ([]* testServer , backendCount )
76109 addrs := make ([]resolver.Address , backendCount )
77110
78111 for i := 0 ; i < backendCount ; i ++ {
79- backend := stubserver .StartTestService (t , nil )
112+ server := newTestServer (t )
113+ backend := stubserver .StartTestService (t , & server .StubServer )
80114 t .Cleanup (func () {
81115 backend .Stop ()
82116 })
83- backends [i ] = backend
117+ backends [i ] = server
84118 addrs [i ] = resolver.Address {Addr : backend .Address }
85119 }
86120
@@ -264,8 +298,7 @@ func (s) TestPickFirstLeaf_ResolverUpdates_DisjointLists(t *testing.T) {
264298 stateSubscriber := & ccStateSubscriber {}
265299 internal .SubscribeToConnectivityStateChanges .(func (cc * grpc.ClientConn , s grpcsync.Subscriber ) func ())(cc , stateSubscriber )
266300
267- bm .backends [0 ].S .Stop ()
268- bm .backends [0 ].S = nil
301+ bm .backends [0 ].stop ()
269302 r .UpdateState (resolver.State {Addresses : []resolver.Address {addrs [0 ], addrs [1 ]}})
270303 var bal * stateStoringBalancer
271304 select {
@@ -287,8 +320,7 @@ func (s) TestPickFirstLeaf_ResolverUpdates_DisjointLists(t *testing.T) {
287320 t .Errorf ("SubConn states mismatch (-want +got):\n %s" , diff )
288321 }
289322
290- bm .backends [2 ].S .Stop ()
291- bm .backends [2 ].S = nil
323+ bm .backends [2 ].stop ()
292324 r .UpdateState (resolver.State {Addresses : []resolver.Address {addrs [2 ], addrs [3 ]}})
293325
294326 if err := pickfirst .CheckRPCsToBackend (ctx , cc , addrs [3 ]); err != nil {
@@ -327,8 +359,7 @@ func (s) TestPickFirstLeaf_ResolverUpdates_ActiveBackendInUpdatedList(t *testing
327359 stateSubscriber := & ccStateSubscriber {}
328360 internal .SubscribeToConnectivityStateChanges .(func (cc * grpc.ClientConn , s grpcsync.Subscriber ) func ())(cc , stateSubscriber )
329361
330- bm .backends [0 ].S .Stop ()
331- bm .backends [0 ].S = nil
362+ bm .backends [0 ].stop ()
332363 r .UpdateState (resolver.State {Addresses : []resolver.Address {addrs [0 ], addrs [1 ]}})
333364 var bal * stateStoringBalancer
334365 select {
@@ -350,8 +381,7 @@ func (s) TestPickFirstLeaf_ResolverUpdates_ActiveBackendInUpdatedList(t *testing
350381 t .Errorf ("SubConn states mismatch (-want +got):\n %s" , diff )
351382 }
352383
353- bm .backends [2 ].S .Stop ()
354- bm .backends [2 ].S = nil
384+ bm .backends [2 ].stop ()
355385 r .UpdateState (resolver.State {Addresses : []resolver.Address {addrs [2 ], addrs [1 ]}})
356386
357387 // Verify that the ClientConn stays in READY.
@@ -391,8 +421,7 @@ func (s) TestPickFirstLeaf_ResolverUpdates_InActiveBackendInUpdatedList(t *testi
391421 stateSubscriber := & ccStateSubscriber {}
392422 internal .SubscribeToConnectivityStateChanges .(func (cc * grpc.ClientConn , s grpcsync.Subscriber ) func ())(cc , stateSubscriber )
393423
394- bm .backends [0 ].S .Stop ()
395- bm .backends [0 ].S = nil
424+ bm .backends [0 ].stop ()
396425 r .UpdateState (resolver.State {Addresses : []resolver.Address {addrs [0 ], addrs [1 ]}})
397426 var bal * stateStoringBalancer
398427 select {
@@ -414,11 +443,9 @@ func (s) TestPickFirstLeaf_ResolverUpdates_InActiveBackendInUpdatedList(t *testi
414443 t .Errorf ("SubConn states mismatch (-want +got):\n %s" , diff )
415444 }
416445
417- bm .backends [2 ].S .Stop ()
418- bm .backends [2 ].S = nil
419- if err := bm .backends [0 ].StartServer (); err != nil {
420- t .Fatalf ("Failed to re-start test backend: %v" , err )
421- }
446+ bm .backends [2 ].stop ()
447+ bm .backends [0 ].resume ()
448+
422449 r .UpdateState (resolver.State {Addresses : []resolver.Address {addrs [0 ], addrs [2 ]}})
423450
424451 if err := pickfirst .CheckRPCsToBackend (ctx , cc , addrs [0 ]); err != nil {
@@ -456,8 +483,7 @@ func (s) TestPickFirstLeaf_ResolverUpdates_IdenticalLists(t *testing.T) {
456483 stateSubscriber := & ccStateSubscriber {}
457484 internal .SubscribeToConnectivityStateChanges .(func (cc * grpc.ClientConn , s grpcsync.Subscriber ) func ())(cc , stateSubscriber )
458485
459- bm .backends [0 ].S .Stop ()
460- bm .backends [0 ].S = nil
486+ bm .backends [0 ].stop ()
461487 r .UpdateState (resolver.State {Addresses : []resolver.Address {addrs [0 ], addrs [1 ]}})
462488 var bal * stateStoringBalancer
463489 select {
@@ -554,14 +580,11 @@ func (s) TestPickFirstLeaf_StopConnectedServer_FirstServerRestart(t *testing.T)
554580 }
555581
556582 // Shut down the connected server.
557- bm .backends [0 ].S .Stop ()
558- bm .backends [0 ].S = nil
583+ bm .backends [0 ].stop ()
559584 testutils .AwaitState (ctx , t , cc , connectivity .Idle )
560585
561586 // Start the new target server.
562- if err := bm .backends [0 ].StartServer (); err != nil {
563- t .Fatalf ("Failed to start server: %v" , err )
564- }
587+ bm .backends [0 ].resume ()
565588
566589 if err := pickfirst .CheckRPCsToBackend (ctx , cc , addrs [0 ]); err != nil {
567590 t .Fatal (err )
@@ -620,14 +643,11 @@ func (s) TestPickFirstLeaf_StopConnectedServer_SecondServerRestart(t *testing.T)
620643 }
621644
622645 // Shut down the connected server.
623- bm .backends [1 ].S .Stop ()
624- bm .backends [1 ].S = nil
646+ bm .backends [1 ].stop ()
625647 testutils .AwaitState (ctx , t , cc , connectivity .Idle )
626648
627649 // Start the new target server.
628- if err := bm .backends [1 ].StartServer (); err != nil {
629- t .Fatalf ("Failed to start server: %v" , err )
630- }
650+ bm .backends [1 ].resume ()
631651
632652 if err := pickfirst .CheckRPCsToBackend (ctx , cc , addrs [1 ]); err != nil {
633653 t .Fatal (err )
@@ -692,14 +712,11 @@ func (s) TestPickFirstLeaf_StopConnectedServer_SecondServerToFirst(t *testing.T)
692712 }
693713
694714 // Shut down the connected server.
695- bm .backends [1 ].S .Stop ()
696- bm .backends [1 ].S = nil
715+ bm .backends [1 ].stop ()
697716 testutils .AwaitState (ctx , t , cc , connectivity .Idle )
698717
699718 // Start the new target server.
700- if err := bm .backends [0 ].StartServer (); err != nil {
701- t .Fatalf ("Failed to start server: %v" , err )
702- }
719+ bm .backends [0 ].resume ()
703720
704721 if err := pickfirst .CheckRPCsToBackend (ctx , cc , addrs [0 ]); err != nil {
705722 t .Fatal (err )
@@ -763,14 +780,11 @@ func (s) TestPickFirstLeaf_StopConnectedServer_FirstServerToSecond(t *testing.T)
763780 }
764781
765782 // Shut down the connected server.
766- bm .backends [0 ].S .Stop ()
767- bm .backends [0 ].S = nil
783+ bm .backends [0 ].stop ()
768784 testutils .AwaitState (ctx , t , cc , connectivity .Idle )
769785
770786 // Start the new target server.
771- if err := bm .backends [1 ].StartServer (); err != nil {
772- t .Fatalf ("Failed to start server: %v" , err )
773- }
787+ bm .backends [1 ].resume ()
774788
775789 if err := pickfirst .CheckRPCsToBackend (ctx , cc , addrs [1 ]); err != nil {
776790 t .Fatal (err )
@@ -1308,14 +1322,13 @@ type scState struct {
13081322}
13091323
13101324type backendManager struct {
1311- backends []* stubserver. StubServer
1325+ backends []* testServer
13121326}
13131327
13141328func (b * backendManager ) stopAllExcept (index int ) {
13151329 for idx , b := range b .backends {
13161330 if idx != index {
1317- b .S .Stop ()
1318- b .S = nil
1331+ b .stop ()
13191332 }
13201333 }
13211334}
0 commit comments