Skip to content

Commit 0673105

Browse files
authored
clusterresolver: switch a couple of tests to e2e style (#6394)
1 parent 0b3a81e commit 0673105

File tree

2 files changed

+224
-299
lines changed

2 files changed

+224
-299
lines changed

xds/internal/balancer/clusterresolver/clusterresolver_test.go

Lines changed: 1 addition & 299 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,10 @@
1919
package clusterresolver
2020

2121
import (
22-
"context"
23-
"fmt"
2422
"testing"
2523
"time"
2624

27-
"github.com/google/go-cmp/cmp"
28-
"github.com/google/go-cmp/cmp/cmpopts"
29-
"google.golang.org/grpc/balancer"
30-
"google.golang.org/grpc/connectivity"
3125
"google.golang.org/grpc/internal/grpctest"
32-
iserviceconfig "google.golang.org/grpc/internal/serviceconfig"
33-
"google.golang.org/grpc/internal/testutils"
34-
"google.golang.org/grpc/resolver"
35-
xdsinternal "google.golang.org/grpc/xds/internal"
36-
"google.golang.org/grpc/xds/internal/balancer/clusterimpl"
37-
"google.golang.org/grpc/xds/internal/balancer/outlierdetection"
38-
"google.golang.org/grpc/xds/internal/balancer/priority"
39-
"google.golang.org/grpc/xds/internal/testutils/fakeclient"
40-
"google.golang.org/grpc/xds/internal/xdsclient"
41-
"google.golang.org/grpc/xds/internal/xdsclient/xdsresource"
4226
)
4327

4428
const (
@@ -47,295 +31,13 @@ const (
4731
testEDSService = "test-eds-service-name"
4832
testClusterName = "test-cluster-name"
4933
testClusterName2 = "google_cfe_some-name"
34+
testBalancerNameFooBar = "foo.bar"
5035
)
5136

52-
var (
53-
// A non-empty endpoints update which is expected to be accepted by the EDS
54-
// LB policy.
55-
defaultEndpointsUpdate = xdsresource.EndpointsUpdate{
56-
Localities: []xdsresource.Locality{
57-
{
58-
Endpoints: []xdsresource.Endpoint{{Address: "endpoint1"}},
59-
ID: xdsinternal.LocalityID{Zone: "zone"},
60-
Priority: 1,
61-
Weight: 100,
62-
},
63-
},
64-
}
65-
)
66-
67-
func init() {
68-
balancer.Register(bb{})
69-
}
70-
7137
type s struct {
7238
grpctest.Tester
73-
74-
cleanup func()
75-
}
76-
77-
func (ss s) Teardown(t *testing.T) {
78-
xdsclient.ClearAllCountersForTesting()
79-
ss.Tester.Teardown(t)
80-
if ss.cleanup != nil {
81-
ss.cleanup()
82-
}
8339
}
8440

8541
func Test(t *testing.T) {
8642
grpctest.RunSubTests(t, s{})
8743
}
88-
89-
const testBalancerNameFooBar = "foo.bar"
90-
91-
func newNoopTestClientConn() *noopTestClientConn {
92-
return &noopTestClientConn{}
93-
}
94-
95-
// noopTestClientConn is used in EDS balancer config update tests that only
96-
// cover the config update handling, but not SubConn/load-balancing.
97-
type noopTestClientConn struct {
98-
balancer.ClientConn
99-
}
100-
101-
func (t *noopTestClientConn) NewSubConn([]resolver.Address, balancer.NewSubConnOptions) (balancer.SubConn, error) {
102-
return nil, nil
103-
}
104-
105-
func (noopTestClientConn) Target() string { return testEDSService }
106-
107-
type scStateChange struct {
108-
sc balancer.SubConn
109-
state balancer.SubConnState
110-
}
111-
112-
type fakeChildBalancer struct {
113-
cc balancer.ClientConn
114-
subConnState *testutils.Channel
115-
clientConnState *testutils.Channel
116-
resolverError *testutils.Channel
117-
}
118-
119-
func (f *fakeChildBalancer) UpdateClientConnState(state balancer.ClientConnState) error {
120-
f.clientConnState.Send(state)
121-
return nil
122-
}
123-
124-
func (f *fakeChildBalancer) ResolverError(err error) {
125-
f.resolverError.Send(err)
126-
}
127-
128-
func (f *fakeChildBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
129-
f.subConnState.Send(&scStateChange{sc: sc, state: state})
130-
}
131-
132-
func (f *fakeChildBalancer) Close() {}
133-
134-
func (f *fakeChildBalancer) ExitIdle() {}
135-
136-
func (f *fakeChildBalancer) waitForClientConnStateChangeVerifyBalancerConfig(ctx context.Context, wantCCS balancer.ClientConnState) error {
137-
ccs, err := f.clientConnState.Receive(ctx)
138-
if err != nil {
139-
return err
140-
}
141-
gotCCS := ccs.(balancer.ClientConnState)
142-
if diff := cmp.Diff(gotCCS, wantCCS, cmpopts.IgnoreFields(balancer.ClientConnState{}, "ResolverState")); diff != "" {
143-
return fmt.Errorf("received unexpected ClientConnState, diff (-got +want): %v", diff)
144-
}
145-
return nil
146-
}
147-
148-
func (f *fakeChildBalancer) waitForSubConnStateChange(ctx context.Context, wantState *scStateChange) error {
149-
val, err := f.subConnState.Receive(ctx)
150-
if err != nil {
151-
return err
152-
}
153-
gotState := val.(*scStateChange)
154-
if !cmp.Equal(gotState, wantState, cmp.AllowUnexported(scStateChange{})) {
155-
return fmt.Errorf("got subconnStateChange %v, want %v", gotState, wantState)
156-
}
157-
return nil
158-
}
159-
160-
func newFakeChildBalancer(cc balancer.ClientConn) balancer.Balancer {
161-
return &fakeChildBalancer{
162-
cc: cc,
163-
subConnState: testutils.NewChannelWithSize(10),
164-
clientConnState: testutils.NewChannelWithSize(10),
165-
resolverError: testutils.NewChannelWithSize(10),
166-
}
167-
}
168-
169-
type fakeSubConn struct{}
170-
171-
func (*fakeSubConn) UpdateAddresses([]resolver.Address) { panic("implement me") }
172-
func (*fakeSubConn) Connect() { panic("implement me") }
173-
func (*fakeSubConn) GetOrBuildProducer(balancer.ProducerBuilder) (balancer.Producer, func()) {
174-
panic("implement me")
175-
}
176-
177-
// waitForNewChildLB makes sure that a new child LB is created by the top-level
178-
// clusterResolverBalancer.
179-
func waitForNewChildLB(ctx context.Context, ch *testutils.Channel) (*fakeChildBalancer, error) {
180-
val, err := ch.Receive(ctx)
181-
if err != nil {
182-
return nil, fmt.Errorf("error when waiting for a new edsLB: %v", err)
183-
}
184-
return val.(*fakeChildBalancer), nil
185-
}
186-
187-
// setup overrides the functions which are used to create the xdsClient and the
188-
// edsLB, creates fake version of them and makes them available on the provided
189-
// channels. The returned cancel function should be called by the test for
190-
// cleanup.
191-
func setup(childLBCh *testutils.Channel) (*fakeclient.Client, func()) {
192-
xdsC := fakeclient.NewClientWithName(testBalancerNameFooBar)
193-
194-
origNewChildBalancer := newChildBalancer
195-
newChildBalancer = func(_ balancer.Builder, cc balancer.ClientConn, _ balancer.BuildOptions) balancer.Balancer {
196-
childLB := newFakeChildBalancer(cc)
197-
defer func() { childLBCh.Send(childLB) }()
198-
return childLB
199-
}
200-
return xdsC, func() { newChildBalancer = origNewChildBalancer }
201-
}
202-
203-
// TestSubConnStateChange verifies if the top-level clusterResolverBalancer passes on
204-
// the subConnState to appropriate child balancer.
205-
func (s) TestSubConnStateChange(t *testing.T) {
206-
edsLBCh := testutils.NewChannel()
207-
xdsC, cleanup := setup(edsLBCh)
208-
defer cleanup()
209-
210-
builder := balancer.Get(Name)
211-
edsB := builder.Build(newNoopTestClientConn(), balancer.BuildOptions{})
212-
if edsB == nil {
213-
t.Fatalf("builder.Build(%s) failed and returned nil", Name)
214-
}
215-
defer edsB.Close()
216-
217-
if err := edsB.UpdateClientConnState(balancer.ClientConnState{
218-
ResolverState: xdsclient.SetClient(resolver.State{}, xdsC),
219-
BalancerConfig: newLBConfigWithOneEDS(testEDSService),
220-
}); err != nil {
221-
t.Fatalf("edsB.UpdateClientConnState() failed: %v", err)
222-
}
223-
224-
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
225-
defer cancel()
226-
if _, err := xdsC.WaitForWatchEDS(ctx); err != nil {
227-
t.Fatalf("xdsClient.WatchEndpoints failed with error: %v", err)
228-
}
229-
xdsC.InvokeWatchEDSCallback("", defaultEndpointsUpdate, nil)
230-
edsLB, err := waitForNewChildLB(ctx, edsLBCh)
231-
if err != nil {
232-
t.Fatal(err)
233-
}
234-
235-
fsc := &fakeSubConn{}
236-
state := balancer.SubConnState{ConnectivityState: connectivity.Ready}
237-
edsB.UpdateSubConnState(fsc, state)
238-
if err := edsLB.waitForSubConnStateChange(ctx, &scStateChange{sc: fsc, state: state}); err != nil {
239-
t.Fatal(err)
240-
}
241-
}
242-
243-
func newLBConfigWithOneEDS(edsServiceName string) *LBConfig {
244-
return &LBConfig{
245-
DiscoveryMechanisms: []DiscoveryMechanism{{
246-
Cluster: testClusterName,
247-
Type: DiscoveryMechanismTypeEDS,
248-
EDSServiceName: edsServiceName,
249-
}},
250-
xdsLBPolicy: iserviceconfig.BalancerConfig{
251-
Name: "ROUND_ROBIN",
252-
Config: nil,
253-
},
254-
}
255-
}
256-
257-
func newLBConfigWithOneEDSAndOutlierDetection(edsServiceName string, odCfg outlierdetection.LBConfig) *LBConfig {
258-
lbCfg := newLBConfigWithOneEDS(edsServiceName)
259-
lbCfg.DiscoveryMechanisms[0].outlierDetection = odCfg
260-
return lbCfg
261-
}
262-
263-
// TestOutlierDetection tests the Balancer Config sent down to the child
264-
// priority balancer when Outlier Detection is turned on. The Priority
265-
// Configuration sent downward should have a top level Outlier Detection Policy
266-
// for each priority.
267-
func (s) TestOutlierDetection(t *testing.T) {
268-
edsLBCh := testutils.NewChannel()
269-
xdsC, cleanup := setup(edsLBCh)
270-
defer cleanup()
271-
builder := balancer.Get(Name)
272-
edsB := builder.Build(newNoopTestClientConn(), balancer.BuildOptions{})
273-
if edsB == nil {
274-
t.Fatalf("builder.Build(%s) failed and returned nil", Name)
275-
}
276-
defer edsB.Close()
277-
278-
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
279-
defer cancel()
280-
281-
// Update Cluster Resolver with Client Conn State with Outlier Detection
282-
// configuration present. This is what will be passed down to this balancer,
283-
// as CDS Balancer gets the Cluster Update and converts the Outlier
284-
// Detection data to an Outlier Detection configuration and sends it to this
285-
// level.
286-
if err := edsB.UpdateClientConnState(balancer.ClientConnState{
287-
ResolverState: xdsclient.SetClient(resolver.State{}, xdsC),
288-
BalancerConfig: newLBConfigWithOneEDSAndOutlierDetection(testEDSService, noopODCfg),
289-
}); err != nil {
290-
t.Fatal(err)
291-
}
292-
if _, err := xdsC.WaitForWatchEDS(ctx); err != nil {
293-
t.Fatalf("xdsClient.WatchEndpoints failed with error: %v", err)
294-
}
295-
296-
// Invoke EDS Callback - causes child balancer to be built and then
297-
// UpdateClientConnState called on it with Outlier Detection as a direct
298-
// child.
299-
xdsC.InvokeWatchEDSCallback("", defaultEndpointsUpdate, nil)
300-
edsLB, err := waitForNewChildLB(ctx, edsLBCh)
301-
if err != nil {
302-
t.Fatal(err)
303-
}
304-
305-
// The priority configuration generated should have Outlier Detection as a
306-
// direct child due to Outlier Detection being turned on.
307-
pCfgWant := &priority.LBConfig{
308-
Children: map[string]*priority.Child{
309-
"priority-0-0": {
310-
Config: &iserviceconfig.BalancerConfig{
311-
Name: outlierdetection.Name,
312-
Config: &outlierdetection.LBConfig{
313-
Interval: iserviceconfig.Duration(10 * time.Second), // default interval
314-
BaseEjectionTime: iserviceconfig.Duration(30 * time.Second),
315-
MaxEjectionTime: iserviceconfig.Duration(300 * time.Second),
316-
MaxEjectionPercent: 10,
317-
ChildPolicy: &iserviceconfig.BalancerConfig{
318-
Name: clusterimpl.Name,
319-
Config: &clusterimpl.LBConfig{
320-
Cluster: testClusterName,
321-
EDSServiceName: "test-eds-service-name",
322-
ChildPolicy: &iserviceconfig.BalancerConfig{
323-
Name: "ROUND_ROBIN",
324-
Config: nil,
325-
},
326-
},
327-
},
328-
},
329-
},
330-
IgnoreReresolutionRequests: true,
331-
},
332-
},
333-
Priorities: []string{"priority-0-0"},
334-
}
335-
336-
if err := edsLB.waitForClientConnStateChangeVerifyBalancerConfig(ctx, balancer.ClientConnState{
337-
BalancerConfig: pCfgWant,
338-
}); err != nil {
339-
t.Fatalf("EDS impl got unexpected update: %v", err)
340-
}
341-
}

0 commit comments

Comments
 (0)