github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/go-control-plane/pkg/integration/ttl_integration_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/golang/protobuf/ptypes"
    10  	"github.com/hxx258456/ccgo/grpc"
    11  	"github.com/stretchr/testify/assert"
    12  
    13  	envoy_config_core_v3 "github.com/hxx258456/ccgo/go-control-plane/envoy/config/core/v3"
    14  	envoy_config_endpoint_v3 "github.com/hxx258456/ccgo/go-control-plane/envoy/config/endpoint/v3"
    15  	envoy_service_discovery_v3 "github.com/hxx258456/ccgo/go-control-plane/envoy/service/discovery/v3"
    16  	endpointservice "github.com/hxx258456/ccgo/go-control-plane/envoy/service/endpoint/v3"
    17  	"github.com/hxx258456/ccgo/go-control-plane/pkg/cache/types"
    18  	"github.com/hxx258456/ccgo/go-control-plane/pkg/cache/v3"
    19  	"github.com/hxx258456/ccgo/go-control-plane/pkg/resource/v3"
    20  	"github.com/hxx258456/ccgo/go-control-plane/pkg/server/v3"
    21  )
    22  
    23  type logger struct {
    24  	t *testing.T
    25  }
    26  
    27  func (log logger) Debugf(format string, args ...interface{}) { log.t.Logf(format, args...) }
    28  func (log logger) Infof(format string, args ...interface{})  { log.t.Logf(format, args...) }
    29  func (log logger) Warnf(format string, args ...interface{})  { log.t.Logf(format, args...) }
    30  func (log logger) Errorf(format string, args ...interface{}) { log.t.Logf(format, args...) }
    31  
    32  func TestTTLResponse(t *testing.T) {
    33  
    34  	ctx, cancel := context.WithCancel(context.Background())
    35  	defer cancel()
    36  
    37  	snapshotCache := cache.NewSnapshotCacheWithHeartbeating(ctx, false, cache.IDHash{}, logger{t: t}, time.Second)
    38  
    39  	server := server.NewServer(ctx, snapshotCache, nil)
    40  
    41  	grpcServer := grpc.NewServer()
    42  	endpointservice.RegisterEndpointDiscoveryServiceServer(grpcServer, server)
    43  
    44  	l, err := net.Listen("tcp", ":9999") // nolint:gosec
    45  	assert.NoError(t, err)
    46  
    47  	go func() {
    48  		assert.NoError(t, grpcServer.Serve(l))
    49  	}()
    50  	defer grpcServer.Stop()
    51  
    52  	conn, err := grpc.Dial(":9999", grpc.WithInsecure())
    53  	assert.NoError(t, err)
    54  	client := endpointservice.NewEndpointDiscoveryServiceClient(conn)
    55  
    56  	sclient, err := client.StreamEndpoints(ctx)
    57  	assert.NoError(t, err)
    58  
    59  	err = sclient.Send(&envoy_service_discovery_v3.DiscoveryRequest{
    60  		Node: &envoy_config_core_v3.Node{
    61  			Id: "test",
    62  		},
    63  		ResourceNames: []string{"resource"},
    64  		TypeUrl:       resource.EndpointType,
    65  	})
    66  	assert.NoError(t, err)
    67  
    68  	oneSecond := time.Second
    69  	cla := &envoy_config_endpoint_v3.ClusterLoadAssignment{ClusterName: "resource"}
    70  	snap, _ := cache.NewSnapshotWithTTLs("1", map[resource.Type][]types.ResourceWithTTL{
    71  		resource.EndpointType: {{
    72  			Resource: cla,
    73  			TTL:      &oneSecond,
    74  		}},
    75  	})
    76  	err = snapshotCache.SetSnapshot(context.Background(), "test", snap)
    77  	assert.NoError(t, err)
    78  
    79  	timeout := time.NewTimer(5 * time.Second)
    80  
    81  	awaitResponse := func() *envoy_service_discovery_v3.DiscoveryResponse {
    82  		t.Helper()
    83  		doneCh := make(chan *envoy_service_discovery_v3.DiscoveryResponse)
    84  		go func() {
    85  
    86  			r, err := sclient.Recv()
    87  			assert.NoError(t, err)
    88  
    89  			doneCh <- r
    90  		}()
    91  
    92  		select {
    93  		case <-timeout.C:
    94  			assert.Fail(t, "timed out")
    95  			return nil
    96  		case r := <-doneCh:
    97  			return r
    98  		}
    99  	}
   100  
   101  	response := awaitResponse()
   102  	isFullResponseWithTTL(t, response)
   103  
   104  	err = sclient.Send(&envoy_service_discovery_v3.DiscoveryRequest{
   105  		Node: &envoy_config_core_v3.Node{
   106  			Id: "test",
   107  		},
   108  		ResourceNames: []string{"resource"},
   109  		TypeUrl:       resource.EndpointType,
   110  		VersionInfo:   "1",
   111  		ResponseNonce: response.Nonce,
   112  	})
   113  	assert.NoError(t, err)
   114  
   115  	response = awaitResponse()
   116  	isHeartbeatResponseWithTTL(t, response)
   117  }
   118  
   119  func isFullResponseWithTTL(t *testing.T, response *envoy_service_discovery_v3.DiscoveryResponse) {
   120  	t.Helper()
   121  
   122  	assert.Len(t, response.Resources, 1)
   123  	r := response.Resources[0]
   124  	resource := &envoy_service_discovery_v3.Resource{}
   125  	err := ptypes.UnmarshalAny(r, resource)
   126  	assert.NoError(t, err)
   127  
   128  	assert.NotNil(t, resource.Ttl)
   129  	assert.NotNil(t, resource.Resource)
   130  }
   131  
   132  func isHeartbeatResponseWithTTL(t *testing.T, response *envoy_service_discovery_v3.DiscoveryResponse) {
   133  	t.Helper()
   134  
   135  	assert.Len(t, response.Resources, 1)
   136  	r := response.Resources[0]
   137  	resource := &envoy_service_discovery_v3.Resource{}
   138  	err := ptypes.UnmarshalAny(r, resource)
   139  	assert.NoError(t, err)
   140  
   141  	assert.NotNil(t, resource.Ttl)
   142  	assert.Nil(t, resource.Resource)
   143  }