/* * * 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" channelzgrpc "google.golang.org/grpc/channelz/grpc_channelz_v1" 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{ 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 := channelzgrpc.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 }