github.com/manicqin/nomad@v0.9.5/command/agent/consul/group_test.go (about)

     1  package consul
     2  
     3  import (
     4  	"io/ioutil"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/hashicorp/consul/api"
     9  	consulapi "github.com/hashicorp/consul/api"
    10  	"github.com/hashicorp/consul/testutil"
    11  	"github.com/hashicorp/nomad/helper/testlog"
    12  	"github.com/hashicorp/nomad/nomad/mock"
    13  	"github.com/hashicorp/nomad/nomad/structs"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestConsul_Connect(t *testing.T) {
    18  	// Create an embedded Consul server
    19  	testconsul, err := testutil.NewTestServerConfig(func(c *testutil.TestServerConfig) {
    20  		// If -v wasn't specified squelch consul logging
    21  		if !testing.Verbose() {
    22  			c.Stdout = ioutil.Discard
    23  			c.Stderr = ioutil.Discard
    24  		}
    25  	})
    26  	if err != nil {
    27  		t.Fatalf("error starting test consul server: %v", err)
    28  	}
    29  	defer testconsul.Stop()
    30  
    31  	consulConfig := consulapi.DefaultConfig()
    32  	consulConfig.Address = testconsul.HTTPAddr
    33  	consulClient, err := consulapi.NewClient(consulConfig)
    34  	require.NoError(t, err)
    35  	serviceClient := NewServiceClient(consulClient.Agent(), testlog.HCLogger(t), true)
    36  
    37  	// Lower periodicInterval to ensure periodic syncing doesn't improperly
    38  	// remove Connect services.
    39  	const interval = 50 * time.Millisecond
    40  	serviceClient.periodicInterval = interval
    41  
    42  	// Disable deregistration probation to test syncing
    43  	serviceClient.deregisterProbationExpiry = time.Time{}
    44  
    45  	go serviceClient.Run()
    46  	defer serviceClient.Shutdown()
    47  
    48  	alloc := mock.Alloc()
    49  	alloc.AllocatedResources.Shared.Networks = []*structs.NetworkResource{
    50  		{
    51  			Mode: "bridge",
    52  			IP:   "10.0.0.1",
    53  			DynamicPorts: []structs.Port{
    54  				{
    55  					Label: "connect-proxy-testconnect",
    56  					Value: 9999,
    57  					To:    9998,
    58  				},
    59  			},
    60  		},
    61  	}
    62  	tg := alloc.Job.LookupTaskGroup(alloc.TaskGroup)
    63  	tg.Services = []*structs.Service{
    64  		{
    65  			Name:      "testconnect",
    66  			PortLabel: "9999",
    67  			Meta: map[string]string{
    68  				"alloc_id": "${NOMAD_ALLOC_ID}",
    69  			},
    70  			Connect: &structs.ConsulConnect{
    71  				SidecarService: &structs.ConsulSidecarService{
    72  					Proxy: &structs.ConsulProxy{
    73  						LocalServicePort: 9000,
    74  					},
    75  				},
    76  			},
    77  		},
    78  	}
    79  
    80  	// required by isNomadSidecar assertion below
    81  	serviceRegMap := map[string]*api.AgentServiceRegistration{
    82  		MakeAllocServiceID(alloc.ID, "group-"+alloc.TaskGroup, tg.Services[0]): nil,
    83  	}
    84  
    85  	require.NoError(t, serviceClient.RegisterWorkload(BuildAllocServices(mock.Node(), alloc, NoopRestarter())))
    86  
    87  	require.Eventually(t, func() bool {
    88  		services, err := consulClient.Agent().Services()
    89  		require.NoError(t, err)
    90  		return len(services) == 2
    91  	}, 3*time.Second, 100*time.Millisecond)
    92  
    93  	// Test a few times to ensure Nomad doesn't improperly deregister
    94  	// Connect services.
    95  	for i := 10; i > 0; i-- {
    96  		services, err := consulClient.Agent().Services()
    97  		require.NoError(t, err)
    98  		require.Len(t, services, 2)
    99  
   100  		serviceID := MakeAllocServiceID(alloc.ID, "group-"+alloc.TaskGroup, tg.Services[0])
   101  		connectID := serviceID + "-sidecar-proxy"
   102  
   103  		require.Contains(t, services, serviceID)
   104  		require.True(t, isNomadService(serviceID))
   105  		require.False(t, isNomadSidecar(serviceID, serviceRegMap))
   106  		agentService := services[serviceID]
   107  		require.Equal(t, agentService.Service, "testconnect")
   108  		require.Equal(t, agentService.Address, "10.0.0.1")
   109  		require.Equal(t, agentService.Port, 9999)
   110  		require.Nil(t, agentService.Connect)
   111  		require.Nil(t, agentService.Proxy)
   112  
   113  		require.Contains(t, services, connectID)
   114  		require.True(t, isNomadService(connectID))
   115  		require.True(t, isNomadSidecar(connectID, serviceRegMap))
   116  		connectService := services[connectID]
   117  		require.Equal(t, connectService.Service, "testconnect-sidecar-proxy")
   118  		require.Equal(t, connectService.Address, "10.0.0.1")
   119  		require.Equal(t, connectService.Port, 9999)
   120  		require.Nil(t, connectService.Connect)
   121  		require.Equal(t, connectService.Proxy.DestinationServiceName, "testconnect")
   122  		require.Equal(t, connectService.Proxy.DestinationServiceID, serviceID)
   123  		require.Equal(t, connectService.Proxy.LocalServiceAddress, "127.0.0.1")
   124  		require.Equal(t, connectService.Proxy.LocalServicePort, 9000)
   125  		require.Equal(t, connectService.Proxy.Config, map[string]interface{}{
   126  			"bind_address": "0.0.0.0",
   127  			"bind_port":    float64(9998),
   128  		})
   129  		require.Equal(t, alloc.ID, agentService.Meta["alloc_id"])
   130  
   131  		time.Sleep(interval >> 2)
   132  	}
   133  }