| /* |
| * |
| * Copyright 2021 gRPC authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| // Package test contains test only functions for package admin. It's used by |
| // admin/admin_test.go and admin/test/admin_test.go. |
| package test |
| |
| import ( |
| "context" |
| "net" |
| "testing" |
| "time" |
| |
| "github.com/google/uuid" |
| "google.golang.org/grpc" |
| "google.golang.org/grpc/admin" |
| "google.golang.org/grpc/codes" |
| "google.golang.org/grpc/credentials/insecure" |
| "google.golang.org/grpc/internal/testutils/xds/bootstrap" |
| "google.golang.org/grpc/status" |
| |
| v3statusgrpc "github.com/envoyproxy/go-control-plane/envoy/service/status/v3" |
| v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3" |
| channelzpb "google.golang.org/grpc/channelz/grpc_channelz_v1" |
| ) |
| |
| const ( |
| defaultTestTimeout = 10 * time.Second |
| ) |
| |
| // ExpectedStatusCodes contains the expected status code for each RPC (can be |
| // OK). |
| type ExpectedStatusCodes struct { |
| ChannelzCode codes.Code |
| CSDSCode codes.Code |
| } |
| |
| // RunRegisterTests makes a client, runs the RPCs, and compares the status |
| // codes. |
| func RunRegisterTests(t *testing.T, ec ExpectedStatusCodes) { |
| nodeID := uuid.New().String() |
| bootstrapCleanup, err := bootstrap.CreateFile(bootstrap.Options{ |
| Version: bootstrap.TransportV3, |
| NodeID: nodeID, |
| ServerURI: "no.need.for.a.server", |
| }) |
| if err != nil { |
| t.Fatal(err) |
| } |
| defer bootstrapCleanup() |
| |
| lis, err := net.Listen("tcp", "localhost:0") |
| if err != nil { |
| t.Fatalf("cannot create listener: %v", err) |
| } |
| |
| server := grpc.NewServer() |
| defer server.Stop() |
| cleanup, err := admin.Register(server) |
| if err != nil { |
| t.Fatalf("failed to register admin: %v", err) |
| } |
| defer cleanup() |
| go func() { |
| server.Serve(lis) |
| }() |
| |
| conn, err := grpc.Dial(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) |
| if err != nil { |
| t.Fatalf("cannot connect to server: %v", err) |
| } |
| |
| t.Run("channelz", func(t *testing.T) { |
| if err := RunChannelz(conn); status.Code(err) != ec.ChannelzCode { |
| t.Fatalf("%s RPC failed with error %v, want code %v", "channelz", err, ec.ChannelzCode) |
| } |
| }) |
| t.Run("csds", func(t *testing.T) { |
| if err := RunCSDS(conn); status.Code(err) != ec.CSDSCode { |
| t.Fatalf("%s RPC failed with error %v, want code %v", "CSDS", err, ec.CSDSCode) |
| } |
| }) |
| } |
| |
| // RunChannelz makes a channelz RPC. |
| func RunChannelz(conn *grpc.ClientConn) error { |
| c := channelzpb.NewChannelzClient(conn) |
| ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| defer cancel() |
| _, err := c.GetTopChannels(ctx, &channelzpb.GetTopChannelsRequest{}, grpc.WaitForReady(true)) |
| return err |
| } |
| |
| // RunCSDS makes a CSDS RPC. |
| func RunCSDS(conn *grpc.ClientConn) error { |
| c := v3statusgrpc.NewClientStatusDiscoveryServiceClient(conn) |
| ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| defer cancel() |
| _, err := c.FetchClientStatus(ctx, &v3statuspb.ClientStatusRequest{}, grpc.WaitForReady(true)) |
| return err |
| } |