Skip to content

Commit 78aa51b

Browse files
authored
pickfirst: Stop test servers without closing listeners (#7872)
1 parent 00272e8 commit 78aa51b

File tree

1 file changed

+56
-43
lines changed

1 file changed

+56
-43
lines changed

balancer/pickfirst/pickfirstleaf/pickfirstleaf_ext_test.go

+56-43
Original file line numberDiff line numberDiff line change
@@ -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.
72105
func 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

13101324
type backendManager struct {
1311-
backends []*stubserver.StubServer
1325+
backends []*testServer
13121326
}
13131327

13141328
func (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

Comments
 (0)