gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/grpc/xds/internal/test/e2e/e2e.go (about)

     1  /*
     2   *
     3   * Copyright 2021 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  // Package e2e implements xds e2e tests using go-control-plane.
    19  package e2e
    20  
    21  import (
    22  	"context"
    23  	"fmt"
    24  	"io"
    25  	"os"
    26  	"os/exec"
    27  
    28  	grpc "gitee.com/zhaochuninhefei/gmgo/grpc"
    29  	channelzgrpc "gitee.com/zhaochuninhefei/gmgo/grpc/channelz/grpc_channelz_v1"
    30  	channelzpb "gitee.com/zhaochuninhefei/gmgo/grpc/channelz/grpc_channelz_v1"
    31  	testgrpc "gitee.com/zhaochuninhefei/gmgo/grpc/interop/grpc_testing"
    32  	testpb "gitee.com/zhaochuninhefei/gmgo/grpc/interop/grpc_testing"
    33  )
    34  
    35  func cmd(path string, logger io.Writer, args []string, env []string) *exec.Cmd {
    36  	cmd := exec.Command(path, args...)
    37  	cmd.Env = append(os.Environ(), env...)
    38  	cmd.Stdout = logger
    39  	cmd.Stderr = logger
    40  	return cmd
    41  }
    42  
    43  const (
    44  	clientStatsPort = 60363 // TODO: make this different per-test, only needed for parallel tests.
    45  )
    46  
    47  type client struct {
    48  	cmd *exec.Cmd
    49  
    50  	target  string
    51  	statsCC *grpc.ClientConn
    52  }
    53  
    54  // newClient create a client with the given target and bootstrap content.
    55  func newClient(target, binaryPath, bootstrap string, logger io.Writer, flags ...string) (*client, error) {
    56  	cmd := cmd(
    57  		binaryPath,
    58  		logger,
    59  		append([]string{
    60  			"--server=" + target,
    61  			"--print_response=true",
    62  			"--qps=100",
    63  			fmt.Sprintf("--stats_port=%d", clientStatsPort),
    64  		}, flags...), // Append any flags from caller.
    65  		[]string{
    66  			"GRPC_GO_LOG_VERBOSITY_LEVEL=99",
    67  			"GRPC_GO_LOG_SEVERITY_LEVEL=info",
    68  			"GRPC_XDS_BOOTSTRAP_CONFIG=" + bootstrap, // The bootstrap content doesn't need to be quoted.
    69  		},
    70  	)
    71  	cmd.Start()
    72  
    73  	cc, err := grpc.Dial(fmt.Sprintf("localhost:%d", clientStatsPort), grpc.WithInsecure(), grpc.WithDefaultCallOptions(grpc.WaitForReady(true)))
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	return &client{
    78  		cmd:     cmd,
    79  		target:  target,
    80  		statsCC: cc,
    81  	}, nil
    82  }
    83  
    84  func (c *client) clientStats(ctx context.Context) (*testpb.LoadBalancerStatsResponse, error) {
    85  	ccc := testgrpc.NewLoadBalancerStatsServiceClient(c.statsCC)
    86  	return ccc.GetClientStats(ctx, &testpb.LoadBalancerStatsRequest{
    87  		NumRpcs:    100,
    88  		TimeoutSec: 10,
    89  	})
    90  }
    91  
    92  func (c *client) configRPCs(ctx context.Context, req *testpb.ClientConfigureRequest) error {
    93  	ccc := testgrpc.NewXdsUpdateClientConfigureServiceClient(c.statsCC)
    94  	_, err := ccc.Configure(ctx, req)
    95  	return err
    96  }
    97  
    98  func (c *client) channelzSubChannels(ctx context.Context) ([]*channelzpb.Subchannel, error) {
    99  	ccc := channelzgrpc.NewChannelzClient(c.statsCC)
   100  	r, err := ccc.GetTopChannels(ctx, &channelzpb.GetTopChannelsRequest{})
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  
   105  	var ret []*channelzpb.Subchannel
   106  	for _, cc := range r.Channel {
   107  		if cc.Data.Target != c.target {
   108  			continue
   109  		}
   110  		for _, sc := range cc.SubchannelRef {
   111  			rr, err := ccc.GetSubchannel(ctx, &channelzpb.GetSubchannelRequest{SubchannelId: sc.SubchannelId})
   112  			if err != nil {
   113  				return nil, err
   114  			}
   115  			ret = append(ret, rr.Subchannel)
   116  		}
   117  	}
   118  	return ret, nil
   119  }
   120  
   121  func (c *client) stop() {
   122  	c.cmd.Process.Kill()
   123  	c.cmd.Wait()
   124  }
   125  
   126  const (
   127  	serverPort = 50051 // TODO: make this different per-test, only needed for parallel tests.
   128  )
   129  
   130  type server struct {
   131  	cmd  *exec.Cmd
   132  	port int
   133  }
   134  
   135  // newServer creates multiple servers with the given bootstrap content.
   136  //
   137  // Each server gets a different hostname, in the format of
   138  // <hostnamePrefix>-<index>.
   139  func newServers(hostnamePrefix, binaryPath, bootstrap string, logger io.Writer, count int) (_ []*server, err error) {
   140  	var ret []*server
   141  	defer func() {
   142  		if err != nil {
   143  			for _, s := range ret {
   144  				s.stop()
   145  			}
   146  		}
   147  	}()
   148  	for i := 0; i < count; i++ {
   149  		port := serverPort + i
   150  		cmd := cmd(
   151  			binaryPath,
   152  			logger,
   153  			[]string{
   154  				fmt.Sprintf("--port=%d", port),
   155  				fmt.Sprintf("--host_name_override=%s-%d", hostnamePrefix, i),
   156  			},
   157  			[]string{
   158  				"GRPC_GO_LOG_VERBOSITY_LEVEL=99",
   159  				"GRPC_GO_LOG_SEVERITY_LEVEL=info",
   160  				"GRPC_XDS_BOOTSTRAP_CONFIG=" + bootstrap, // The bootstrap content doesn't need to be quoted.,
   161  			},
   162  		)
   163  		cmd.Start()
   164  		ret = append(ret, &server{cmd: cmd, port: port})
   165  	}
   166  	return ret, nil
   167  }
   168  
   169  func (s *server) stop() {
   170  	s.cmd.Process.Kill()
   171  	s.cmd.Wait()
   172  }