github.com/cdmixer/woolloomooloo@v0.1.0/grpc-go/xds/internal/xdsclient/loadreport_test.go (about) 1 // +build go1.12 2 3 /* 4 * 5 * Copyright 2020 gRPC authors. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ 20 21 package xdsclient_test 22 23 import ( 24 "context" 25 "testing" 26 "time" 27 28 v2corepb "github.com/envoyproxy/go-control-plane/envoy/api/v2/core" 29 endpointpb "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint" 30 lrspb "github.com/envoyproxy/go-control-plane/envoy/service/load_stats/v2" 31 durationpb "github.com/golang/protobuf/ptypes/duration" 32 "github.com/google/go-cmp/cmp" 33 "google.golang.org/grpc" 34 "google.golang.org/grpc/codes" 35 "google.golang.org/grpc/credentials/insecure" 36 "google.golang.org/grpc/status" 37 "google.golang.org/grpc/xds/internal/testutils/fakeserver" 38 "google.golang.org/grpc/xds/internal/version" 39 "google.golang.org/grpc/xds/internal/xdsclient" 40 "google.golang.org/grpc/xds/internal/xdsclient/bootstrap" 41 "google.golang.org/protobuf/testing/protocmp" 42 43 _ "google.golang.org/grpc/xds/internal/xdsclient/v2" // Register the v2 xDS API client. 44 ) 45 46 const ( 47 defaultTestTimeout = 5 * time.Second 48 defaultTestShortTimeout = 10 * time.Millisecond // For events expected to *not* happen. 49 defaultClientWatchExpiryTimeout = 15 * time.Second 50 ) 51 52 func (s) TestLRSClient(t *testing.T) { 53 fs, sCleanup, err := fakeserver.StartServer() 54 if err != nil { 55 t.Fatalf("failed to start fake xDS server: %v", err) 56 } 57 defer sCleanup() 58 59 xdsC, err := xdsclient.NewWithConfigForTesting(&bootstrap.Config{ 60 BalancerName: fs.Address, 61 Creds: grpc.WithTransportCredentials(insecure.NewCredentials()), 62 NodeProto: &v2corepb.Node{}, 63 TransportAPI: version.TransportV2, 64 }, defaultClientWatchExpiryTimeout) 65 if err != nil { 66 t.Fatalf("failed to create xds client: %v", err) 67 } 68 defer xdsC.Close() 69 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 70 defer cancel() 71 if u, err := fs.NewConnChan.Receive(ctx); err != nil { 72 t.Errorf("unexpected timeout: %v, %v, want NewConn", u, err) 73 } 74 75 // Report to the same address should not create new ClientConn. 76 store1, lrsCancel1 := xdsC.ReportLoad(fs.Address) 77 defer lrsCancel1() 78 sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout) 79 defer sCancel() 80 if u, err := fs.NewConnChan.Receive(sCtx); err != context.DeadlineExceeded { 81 t.Errorf("unexpected NewConn: %v, %v, want channel recv timeout", u, err) 82 } 83 84 fs2, sCleanup2, err := fakeserver.StartServer() 85 if err != nil { 86 t.Fatalf("failed to start fake xDS server: %v", err) 87 } 88 defer sCleanup2() 89 90 // Report to a different address should create new ClientConn. 91 store2, lrsCancel2 := xdsC.ReportLoad(fs2.Address) 92 defer lrsCancel2() 93 if u, err := fs2.NewConnChan.Receive(ctx); err != nil { 94 t.Errorf("unexpected timeout: %v, %v, want NewConn", u, err) 95 } 96 97 if store1 == store2 { 98 t.Fatalf("got same store for different servers, want different") 99 } 100 101 if u, err := fs2.LRSRequestChan.Receive(ctx); err != nil { 102 t.Errorf("unexpected timeout: %v, %v, want NewConn", u, err) 103 } 104 store2.PerCluster("cluster", "eds").CallDropped("test") 105 106 // Send one resp to the client. 107 fs2.LRSResponseChan <- &fakeserver.Response{ 108 Resp: &lrspb.LoadStatsResponse{ 109 SendAllClusters: true, 110 LoadReportingInterval: &durationpb.Duration{Nanos: 50000000}, 111 }, 112 } 113 114 // Server should receive a req with the loads. 115 u, err := fs2.LRSRequestChan.Receive(ctx) 116 if err != nil { 117 t.Fatalf("unexpected LRS request: %v, %v, want error canceled", u, err) 118 } 119 receivedLoad := u.(*fakeserver.Request).Req.(*lrspb.LoadStatsRequest).ClusterStats 120 if len(receivedLoad) <= 0 { 121 t.Fatalf("unexpected load received, want load for cluster, eds, dropped for test") 122 } 123 receivedLoad[0].LoadReportInterval = nil 124 want := &endpointpb.ClusterStats{ 125 ClusterName: "cluster", 126 ClusterServiceName: "eds", 127 TotalDroppedRequests: 1, 128 DroppedRequests: []*endpointpb.ClusterStats_DroppedRequests{{Category: "test", DroppedCount: 1}}, 129 } 130 if d := cmp.Diff(want, receivedLoad[0], protocmp.Transform()); d != "" { 131 t.Fatalf("unexpected load received, want load for cluster, eds, dropped for test, diff (-want +got):\n%s", d) 132 } 133 134 // Cancel this load reporting stream, server should see error canceled. 135 lrsCancel2() 136 137 // Server should receive a stream canceled error. 138 if u, err := fs2.LRSRequestChan.Receive(ctx); err != nil || status.Code(u.(*fakeserver.Request).Err) != codes.Canceled { 139 t.Errorf("unexpected LRS request: %v, %v, want error canceled", u, err) 140 } 141 }