github.com/uchennaokeke444/nomad@v0.11.8/command/agent/agent_test.go (about)

     1  package agent
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	cstructs "github.com/hashicorp/nomad/client/structs"
    12  	"github.com/hashicorp/nomad/helper"
    13  	"github.com/hashicorp/nomad/helper/testlog"
    14  	"github.com/hashicorp/nomad/nomad/structs"
    15  	"github.com/hashicorp/nomad/nomad/structs/config"
    16  	sconfig "github.com/hashicorp/nomad/nomad/structs/config"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func tmpDir(t testing.TB) string {
    22  	dir, err := ioutil.TempDir("", "nomad")
    23  	if err != nil {
    24  		t.Fatalf("err: %v", err)
    25  	}
    26  	return dir
    27  }
    28  
    29  func TestAgent_RPC_Ping(t *testing.T) {
    30  	t.Parallel()
    31  	agent := NewTestAgent(t, t.Name(), nil)
    32  	defer agent.Shutdown()
    33  
    34  	var out struct{}
    35  	if err := agent.RPC("Status.Ping", struct{}{}, &out); err != nil {
    36  		t.Fatalf("err: %v", err)
    37  	}
    38  }
    39  
    40  func TestAgent_ServerConfig(t *testing.T) {
    41  	t.Parallel()
    42  	conf := DefaultConfig()
    43  	conf.DevMode = true // allow localhost for advertise addrs
    44  	conf.Server.Enabled = true
    45  	a := &Agent{config: conf}
    46  
    47  	conf.AdvertiseAddrs.Serf = "127.0.0.1:4000"
    48  	conf.AdvertiseAddrs.RPC = "127.0.0.1:4001"
    49  	conf.AdvertiseAddrs.HTTP = "10.10.11.1:4005"
    50  	conf.ACL.Enabled = true
    51  
    52  	// Parses the advertise addrs correctly
    53  	if err := conf.normalizeAddrs(); err != nil {
    54  		t.Fatalf("error normalizing config: %v", err)
    55  	}
    56  	out, err := a.serverConfig()
    57  	require.NoError(t, err)
    58  
    59  	serfAddr := out.SerfConfig.MemberlistConfig.AdvertiseAddr
    60  	require.Equal(t, "127.0.0.1", serfAddr)
    61  
    62  	serfPort := out.SerfConfig.MemberlistConfig.AdvertisePort
    63  	require.Equal(t, 4000, serfPort)
    64  
    65  	require.Equal(t, "global", out.AuthoritativeRegion)
    66  	require.True(t, out.ACLEnabled)
    67  
    68  	// Assert addresses weren't changed
    69  	require.Equal(t, "127.0.0.1:4001", conf.AdvertiseAddrs.RPC)
    70  	require.Equal(t, "10.10.11.1:4005", conf.AdvertiseAddrs.HTTP)
    71  	require.Equal(t, "0.0.0.0", conf.Addresses.RPC)
    72  
    73  	// Sets up the ports properly
    74  	conf.Addresses.RPC = ""
    75  	conf.Addresses.Serf = ""
    76  	conf.Ports.RPC = 4003
    77  	conf.Ports.Serf = 4004
    78  
    79  	require.NoError(t, conf.normalizeAddrs())
    80  
    81  	out, err = a.serverConfig()
    82  	require.NoError(t, err)
    83  	require.Equal(t, 4003, out.RPCAddr.Port)
    84  	require.Equal(t, 4004, out.SerfConfig.MemberlistConfig.BindPort)
    85  
    86  	// Prefers advertise over bind addr
    87  	conf.BindAddr = "127.0.0.3"
    88  	conf.Addresses.HTTP = "127.0.0.2"
    89  	conf.Addresses.RPC = "127.0.0.2"
    90  	conf.Addresses.Serf = "127.0.0.2"
    91  	conf.AdvertiseAddrs.HTTP = "10.0.0.10"
    92  	conf.AdvertiseAddrs.RPC = ""
    93  	conf.AdvertiseAddrs.Serf = "10.0.0.12:4004"
    94  
    95  	require.NoError(t, conf.normalizeAddrs())
    96  
    97  	out, err = a.serverConfig()
    98  	require.Equal(t, "127.0.0.2", out.RPCAddr.IP.String())
    99  	require.Equal(t, 4003, out.RPCAddr.Port)
   100  	require.Equal(t, "127.0.0.2", out.SerfConfig.MemberlistConfig.BindAddr)
   101  	require.Equal(t, 4004, out.SerfConfig.MemberlistConfig.BindPort)
   102  	require.Equal(t, "127.0.0.2", conf.Addresses.HTTP)
   103  	require.Equal(t, "127.0.0.2", conf.Addresses.RPC)
   104  	require.Equal(t, "127.0.0.2", conf.Addresses.Serf)
   105  	require.Equal(t, "127.0.0.2:4646", conf.normalizedAddrs.HTTP)
   106  	require.Equal(t, "127.0.0.2:4003", conf.normalizedAddrs.RPC)
   107  	require.Equal(t, "127.0.0.2:4004", conf.normalizedAddrs.Serf)
   108  	require.Equal(t, "10.0.0.10:4646", conf.AdvertiseAddrs.HTTP)
   109  	require.Equal(t, "127.0.0.2:4003", conf.AdvertiseAddrs.RPC)
   110  	require.Equal(t, "10.0.0.12:4004", conf.AdvertiseAddrs.Serf)
   111  
   112  	conf.Server.NodeGCThreshold = "42g"
   113  	require.NoError(t, conf.normalizeAddrs())
   114  
   115  	_, err = a.serverConfig()
   116  	if err == nil || !strings.Contains(err.Error(), "unknown unit") {
   117  		t.Fatalf("expected unknown unit error, got: %#v", err)
   118  	}
   119  
   120  	conf.Server.NodeGCThreshold = "10s"
   121  	require.NoError(t, conf.normalizeAddrs())
   122  	out, err = a.serverConfig()
   123  	require.NoError(t, err)
   124  	require.Equal(t, 10*time.Second, out.NodeGCThreshold)
   125  
   126  	conf.Server.HeartbeatGrace = 37 * time.Second
   127  	out, err = a.serverConfig()
   128  	require.NoError(t, err)
   129  	require.Equal(t, 37*time.Second, out.HeartbeatGrace)
   130  
   131  	conf.Server.MinHeartbeatTTL = 37 * time.Second
   132  	out, err = a.serverConfig()
   133  	require.NoError(t, err)
   134  	require.Equal(t, 37*time.Second, out.MinHeartbeatTTL)
   135  
   136  	conf.Server.MaxHeartbeatsPerSecond = 11.0
   137  	out, err = a.serverConfig()
   138  	require.NoError(t, err)
   139  	require.Equal(t, float64(11.0), out.MaxHeartbeatsPerSecond)
   140  
   141  	// Defaults to the global bind addr
   142  	conf.Addresses.RPC = ""
   143  	conf.Addresses.Serf = ""
   144  	conf.Addresses.HTTP = ""
   145  	conf.AdvertiseAddrs.RPC = ""
   146  	conf.AdvertiseAddrs.HTTP = ""
   147  	conf.AdvertiseAddrs.Serf = ""
   148  	conf.Ports.HTTP = 4646
   149  	conf.Ports.RPC = 4647
   150  	conf.Ports.Serf = 4648
   151  	require.NoError(t, conf.normalizeAddrs())
   152  
   153  	out, err = a.serverConfig()
   154  	require.NoError(t, err)
   155  
   156  	require.Equal(t, "127.0.0.3", out.RPCAddr.IP.String())
   157  	require.Equal(t, "127.0.0.3", out.SerfConfig.MemberlistConfig.BindAddr)
   158  	require.Equal(t, "127.0.0.3", conf.Addresses.HTTP)
   159  	require.Equal(t, "127.0.0.3", conf.Addresses.RPC)
   160  	require.Equal(t, "127.0.0.3", conf.Addresses.Serf)
   161  	require.Equal(t, "127.0.0.3:4646", conf.normalizedAddrs.HTTP)
   162  	require.Equal(t, "127.0.0.3:4647", conf.normalizedAddrs.RPC)
   163  	require.Equal(t, "127.0.0.3:4648", conf.normalizedAddrs.Serf)
   164  
   165  	// Properly handles the bootstrap flags
   166  	conf.Server.BootstrapExpect = 1
   167  	out, err = a.serverConfig()
   168  	require.NoError(t, err)
   169  	require.Equal(t, 1, out.BootstrapExpect)
   170  
   171  	conf.Server.BootstrapExpect = 3
   172  	out, err = a.serverConfig()
   173  	require.NoError(t, err)
   174  	require.Equal(t, 3, out.BootstrapExpect)
   175  }
   176  
   177  func TestAgent_ServerConfig_SchedulerFlags(t *testing.T) {
   178  	cases := []struct {
   179  		name     string
   180  		input    *structs.SchedulerConfiguration
   181  		expected structs.SchedulerConfiguration
   182  	}{
   183  		{
   184  			"default case",
   185  			nil,
   186  			structs.SchedulerConfiguration{
   187  				SchedulerAlgorithm: "binpack",
   188  				PreemptionConfig: structs.PreemptionConfig{
   189  					SystemSchedulerEnabled: true,
   190  				},
   191  			},
   192  		},
   193  		{
   194  			"empty value: preemption is disabled",
   195  			&structs.SchedulerConfiguration{},
   196  			structs.SchedulerConfiguration{
   197  				PreemptionConfig: structs.PreemptionConfig{
   198  					SystemSchedulerEnabled: false,
   199  				},
   200  			},
   201  		},
   202  		{
   203  			"all explicitly set",
   204  			&structs.SchedulerConfiguration{
   205  				PreemptionConfig: structs.PreemptionConfig{
   206  					SystemSchedulerEnabled:  true,
   207  					BatchSchedulerEnabled:   true,
   208  					ServiceSchedulerEnabled: true,
   209  				},
   210  			},
   211  			structs.SchedulerConfiguration{
   212  				PreemptionConfig: structs.PreemptionConfig{
   213  					SystemSchedulerEnabled:  true,
   214  					BatchSchedulerEnabled:   true,
   215  					ServiceSchedulerEnabled: true,
   216  				},
   217  			},
   218  		},
   219  	}
   220  
   221  	for _, c := range cases {
   222  		t.Run(c.name, func(t *testing.T) {
   223  			conf := DefaultConfig()
   224  			conf.Server.DefaultSchedulerConfig = c.input
   225  
   226  			a := &Agent{config: conf}
   227  			conf.AdvertiseAddrs.Serf = "127.0.0.1:4000"
   228  			conf.AdvertiseAddrs.RPC = "127.0.0.1:4001"
   229  			conf.AdvertiseAddrs.HTTP = "10.10.11.1:4005"
   230  			conf.ACL.Enabled = true
   231  			require.NoError(t, conf.normalizeAddrs())
   232  
   233  			out, err := a.serverConfig()
   234  			require.NoError(t, err)
   235  			require.Equal(t, c.expected, out.DefaultSchedulerConfig)
   236  		})
   237  	}
   238  }
   239  
   240  // TestAgent_ServerConfig_Limits_Errors asserts invalid Limits configurations
   241  // cause errors. This is the server-only (RPC) counterpart to
   242  // TestHTTPServer_Limits_Error.
   243  func TestAgent_ServerConfig_Limits_Error(t *testing.T) {
   244  	t.Parallel()
   245  
   246  	cases := []struct {
   247  		name        string
   248  		expectedErr string
   249  		limits      sconfig.Limits
   250  	}{
   251  		{
   252  			name:        "Negative Timeout",
   253  			expectedErr: "rpc_handshake_timeout must be >= 0",
   254  			limits: sconfig.Limits{
   255  				RPCHandshakeTimeout:  "-5s",
   256  				RPCMaxConnsPerClient: helper.IntToPtr(100),
   257  			},
   258  		},
   259  		{
   260  			name:        "Invalid Timeout",
   261  			expectedErr: "error parsing rpc_handshake_timeout",
   262  			limits: sconfig.Limits{
   263  				RPCHandshakeTimeout:  "s",
   264  				RPCMaxConnsPerClient: helper.IntToPtr(100),
   265  			},
   266  		},
   267  		{
   268  			name:        "Missing Timeout",
   269  			expectedErr: "error parsing rpc_handshake_timeout",
   270  			limits: sconfig.Limits{
   271  				RPCHandshakeTimeout:  "",
   272  				RPCMaxConnsPerClient: helper.IntToPtr(100),
   273  			},
   274  		},
   275  		{
   276  			name:        "Negative Connection Limit",
   277  			expectedErr: "rpc_max_conns_per_client must be > 25; found: -100",
   278  			limits: sconfig.Limits{
   279  				RPCHandshakeTimeout:  "5s",
   280  				RPCMaxConnsPerClient: helper.IntToPtr(-100),
   281  			},
   282  		},
   283  		{
   284  			name:        "Low Connection Limit",
   285  			expectedErr: "rpc_max_conns_per_client must be > 25; found: 20",
   286  			limits: sconfig.Limits{
   287  				RPCHandshakeTimeout:  "5s",
   288  				RPCMaxConnsPerClient: helper.IntToPtr(sconfig.LimitsNonStreamingConnsPerClient),
   289  			},
   290  		},
   291  	}
   292  
   293  	for i := range cases {
   294  		tc := cases[i]
   295  		t.Run(tc.name, func(t *testing.T) {
   296  			conf := DevConfig(nil)
   297  			require.NoError(t, conf.normalizeAddrs())
   298  
   299  			conf.Limits = tc.limits
   300  			serverConf, err := convertServerConfig(conf)
   301  			assert.Nil(t, serverConf)
   302  			require.Contains(t, err.Error(), tc.expectedErr)
   303  		})
   304  	}
   305  }
   306  
   307  // TestAgent_ServerConfig_Limits_OK asserts valid Limits configurations do not
   308  // cause errors. This is the server-only (RPC) counterpart to
   309  // TestHTTPServer_Limits_OK.
   310  func TestAgent_ServerConfig_Limits_OK(t *testing.T) {
   311  	t.Parallel()
   312  
   313  	cases := []struct {
   314  		name   string
   315  		limits sconfig.Limits
   316  	}{
   317  		{
   318  			name:   "Default",
   319  			limits: config.DefaultLimits(),
   320  		},
   321  		{
   322  			name: "Zero+nil is valid to disable",
   323  			limits: sconfig.Limits{
   324  				RPCHandshakeTimeout:  "0",
   325  				RPCMaxConnsPerClient: nil,
   326  			},
   327  		},
   328  		{
   329  			name: "Zeros are valid",
   330  			limits: sconfig.Limits{
   331  				RPCHandshakeTimeout:  "0s",
   332  				RPCMaxConnsPerClient: helper.IntToPtr(0),
   333  			},
   334  		},
   335  		{
   336  			name: "Low limits are valid",
   337  			limits: sconfig.Limits{
   338  				RPCHandshakeTimeout:  "1ms",
   339  				RPCMaxConnsPerClient: helper.IntToPtr(26),
   340  			},
   341  		},
   342  		{
   343  			name: "High limits are valid",
   344  			limits: sconfig.Limits{
   345  				RPCHandshakeTimeout:  "5h",
   346  				RPCMaxConnsPerClient: helper.IntToPtr(100000),
   347  			},
   348  		},
   349  	}
   350  
   351  	for i := range cases {
   352  		tc := cases[i]
   353  		t.Run(tc.name, func(t *testing.T) {
   354  			conf := DevConfig(nil)
   355  			require.NoError(t, conf.normalizeAddrs())
   356  
   357  			conf.Limits = tc.limits
   358  			serverConf, err := convertServerConfig(conf)
   359  			assert.NoError(t, err)
   360  			require.NotNil(t, serverConf)
   361  		})
   362  	}
   363  }
   364  
   365  func TestAgent_ClientConfig(t *testing.T) {
   366  	t.Parallel()
   367  	conf := DefaultConfig()
   368  	conf.Client.Enabled = true
   369  
   370  	// For Clients HTTP and RPC must be set (Serf can be skipped)
   371  	conf.Addresses.HTTP = "169.254.0.1"
   372  	conf.Addresses.RPC = "169.254.0.1"
   373  	conf.Ports.HTTP = 5678
   374  	a := &Agent{config: conf}
   375  
   376  	if err := conf.normalizeAddrs(); err != nil {
   377  		t.Fatalf("error normalizing config: %v", err)
   378  	}
   379  	c, err := a.clientConfig()
   380  	if err != nil {
   381  		t.Fatalf("got err: %v", err)
   382  	}
   383  
   384  	expectedHttpAddr := "169.254.0.1:5678"
   385  	if c.Node.HTTPAddr != expectedHttpAddr {
   386  		t.Fatalf("Expected http addr: %v, got: %v", expectedHttpAddr, c.Node.HTTPAddr)
   387  	}
   388  
   389  	conf = DefaultConfig()
   390  	conf.DevMode = true
   391  	a = &Agent{config: conf}
   392  	conf.Client.Enabled = true
   393  	conf.Addresses.HTTP = "169.254.0.1"
   394  
   395  	if err := conf.normalizeAddrs(); err != nil {
   396  		t.Fatalf("error normalizing config: %v", err)
   397  	}
   398  	c, err = a.clientConfig()
   399  	if err != nil {
   400  		t.Fatalf("got err: %v", err)
   401  	}
   402  
   403  	expectedHttpAddr = "169.254.0.1:4646"
   404  	if c.Node.HTTPAddr != expectedHttpAddr {
   405  		t.Fatalf("Expected http addr: %v, got: %v", expectedHttpAddr, c.Node.HTTPAddr)
   406  	}
   407  }
   408  
   409  // Clients should inherit telemetry configuration
   410  func TestAgent_Client_TelemetryConfiguration(t *testing.T) {
   411  	assert := assert.New(t)
   412  
   413  	conf := DefaultConfig()
   414  	conf.DevMode = true
   415  	conf.Telemetry.DisableTaggedMetrics = true
   416  	conf.Telemetry.BackwardsCompatibleMetrics = true
   417  
   418  	a := &Agent{config: conf}
   419  
   420  	c, err := a.clientConfig()
   421  	assert.Nil(err)
   422  
   423  	telemetry := conf.Telemetry
   424  
   425  	assert.Equal(c.StatsCollectionInterval, telemetry.collectionInterval)
   426  	assert.Equal(c.PublishNodeMetrics, telemetry.PublishNodeMetrics)
   427  	assert.Equal(c.PublishAllocationMetrics, telemetry.PublishAllocationMetrics)
   428  	assert.Equal(c.DisableTaggedMetrics, telemetry.DisableTaggedMetrics)
   429  	assert.Equal(c.BackwardsCompatibleMetrics, telemetry.BackwardsCompatibleMetrics)
   430  }
   431  
   432  // TestAgent_HTTPCheck asserts Agent.agentHTTPCheck properly alters the HTTP
   433  // API health check depending on configuration.
   434  func TestAgent_HTTPCheck(t *testing.T) {
   435  	t.Parallel()
   436  	logger := testlog.HCLogger(t)
   437  	agent := func() *Agent {
   438  		return &Agent{
   439  			logger: logger,
   440  			config: &Config{
   441  				AdvertiseAddrs:  &AdvertiseAddrs{HTTP: "advertise:4646"},
   442  				normalizedAddrs: &Addresses{HTTP: "normalized:4646"},
   443  				Consul: &sconfig.ConsulConfig{
   444  					ChecksUseAdvertise: helper.BoolToPtr(false),
   445  				},
   446  				TLSConfig: &sconfig.TLSConfig{EnableHTTP: false},
   447  			},
   448  		}
   449  	}
   450  
   451  	t.Run("Plain HTTP Check", func(t *testing.T) {
   452  		a := agent()
   453  		check := a.agentHTTPCheck(false)
   454  		if check == nil {
   455  			t.Fatalf("expected non-nil check")
   456  		}
   457  		if check.Type != "http" {
   458  			t.Errorf("expected http check not: %q", check.Type)
   459  		}
   460  		if expected := "/v1/agent/health?type=client"; check.Path != expected {
   461  			t.Errorf("expected %q path not: %q", expected, check.Path)
   462  		}
   463  		if check.Protocol != "http" {
   464  			t.Errorf("expected http proto not: %q", check.Protocol)
   465  		}
   466  		if expected := a.config.normalizedAddrs.HTTP; check.PortLabel != expected {
   467  			t.Errorf("expected normalized addr not %q", check.PortLabel)
   468  		}
   469  	})
   470  
   471  	t.Run("Plain HTTP + ChecksUseAdvertise", func(t *testing.T) {
   472  		a := agent()
   473  		a.config.Consul.ChecksUseAdvertise = helper.BoolToPtr(true)
   474  		check := a.agentHTTPCheck(false)
   475  		if check == nil {
   476  			t.Fatalf("expected non-nil check")
   477  		}
   478  		if expected := a.config.AdvertiseAddrs.HTTP; check.PortLabel != expected {
   479  			t.Errorf("expected advertise addr not %q", check.PortLabel)
   480  		}
   481  	})
   482  
   483  	t.Run("HTTPS", func(t *testing.T) {
   484  		a := agent()
   485  		a.config.TLSConfig.EnableHTTP = true
   486  
   487  		check := a.agentHTTPCheck(false)
   488  		if check == nil {
   489  			t.Fatalf("expected non-nil check")
   490  		}
   491  		if !check.TLSSkipVerify {
   492  			t.Errorf("expected tls skip verify")
   493  		}
   494  		if check.Protocol != "https" {
   495  			t.Errorf("expected https not: %q", check.Protocol)
   496  		}
   497  	})
   498  
   499  	t.Run("HTTPS + VerifyHTTPSClient", func(t *testing.T) {
   500  		a := agent()
   501  		a.config.TLSConfig.EnableHTTP = true
   502  		a.config.TLSConfig.VerifyHTTPSClient = true
   503  
   504  		if check := a.agentHTTPCheck(false); check != nil {
   505  			t.Fatalf("expected nil check not: %#v", check)
   506  		}
   507  	})
   508  }
   509  
   510  // TestAgent_HTTPCheckPath asserts clients and servers use different endpoints
   511  // for healthchecks.
   512  func TestAgent_HTTPCheckPath(t *testing.T) {
   513  	t.Parallel()
   514  	// Agent.agentHTTPCheck only needs a config and logger
   515  	a := &Agent{
   516  		config: DevConfig(nil),
   517  		logger: testlog.HCLogger(t),
   518  	}
   519  	if err := a.config.normalizeAddrs(); err != nil {
   520  		t.Fatalf("error normalizing config: %v", err)
   521  	}
   522  
   523  	// Assert server check uses /v1/agent/health?type=server
   524  	isServer := true
   525  	check := a.agentHTTPCheck(isServer)
   526  	if expected := "Nomad Server HTTP Check"; check.Name != expected {
   527  		t.Errorf("expected server check name to be %q but found %q", expected, check.Name)
   528  	}
   529  	if expected := "/v1/agent/health?type=server"; check.Path != expected {
   530  		t.Errorf("expected server check path to be %q but found %q", expected, check.Path)
   531  	}
   532  
   533  	// Assert client check uses /v1/agent/health?type=client
   534  	isServer = false
   535  	check = a.agentHTTPCheck(isServer)
   536  	if expected := "Nomad Client HTTP Check"; check.Name != expected {
   537  		t.Errorf("expected client check name to be %q but found %q", expected, check.Name)
   538  	}
   539  	if expected := "/v1/agent/health?type=client"; check.Path != expected {
   540  		t.Errorf("expected client check path to be %q but found %q", expected, check.Path)
   541  	}
   542  }
   543  
   544  // Here we validate that log levels get updated when the configuration is
   545  // reloaded. I can't find a good way to fetch this from the logger itself, so
   546  // we pull it only from the agents configuration struct, not the logger.
   547  func TestAgent_Reload_LogLevel(t *testing.T) {
   548  	t.Parallel()
   549  	assert := assert.New(t)
   550  
   551  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   552  		c.LogLevel = "INFO"
   553  	})
   554  	defer agent.Shutdown()
   555  
   556  	assert.Equal("INFO", agent.GetConfig().LogLevel)
   557  
   558  	newConfig := &Config{
   559  		LogLevel: "TRACE",
   560  	}
   561  
   562  	assert.Nil(agent.Reload(newConfig))
   563  	assert.Equal("TRACE", agent.GetConfig().LogLevel)
   564  }
   565  
   566  // This test asserts that the keyloader embedded in the TLS config is shared
   567  // across the Agent, Server, and Client. This is essential for certificate
   568  // reloading to work.
   569  func TestServer_Reload_TLS_Shared_Keyloader(t *testing.T) {
   570  	t.Parallel()
   571  	assert := assert.New(t)
   572  
   573  	// We will start out with a bad cert and then reload with a good one.
   574  	const (
   575  		cafile   = "../../helper/tlsutil/testdata/ca.pem"
   576  		foocert  = "../../helper/tlsutil/testdata/nomad-bad.pem"
   577  		fookey   = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
   578  		foocert2 = "../../helper/tlsutil/testdata/nomad-foo.pem"
   579  		fookey2  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   580  	)
   581  
   582  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   583  		c.TLSConfig = &sconfig.TLSConfig{
   584  			EnableHTTP:           true,
   585  			EnableRPC:            true,
   586  			VerifyServerHostname: true,
   587  			CAFile:               cafile,
   588  			CertFile:             foocert,
   589  			KeyFile:              fookey,
   590  		}
   591  	})
   592  	defer agent.Shutdown()
   593  
   594  	originalKeyloader := agent.Config.TLSConfig.GetKeyLoader()
   595  	originalCert, err := originalKeyloader.GetOutgoingCertificate(nil)
   596  	assert.NotNil(originalKeyloader)
   597  	if assert.Nil(err) {
   598  		assert.NotNil(originalCert)
   599  	}
   600  
   601  	// Switch to the correct certificates and reload
   602  	newConfig := &Config{
   603  		TLSConfig: &sconfig.TLSConfig{
   604  			EnableHTTP:           true,
   605  			EnableRPC:            true,
   606  			VerifyServerHostname: true,
   607  			CAFile:               cafile,
   608  			CertFile:             foocert2,
   609  			KeyFile:              fookey2,
   610  		},
   611  	}
   612  
   613  	assert.Nil(agent.Reload(newConfig))
   614  	assert.Equal(agent.Config.TLSConfig.CertFile, newConfig.TLSConfig.CertFile)
   615  	assert.Equal(agent.Config.TLSConfig.KeyFile, newConfig.TLSConfig.KeyFile)
   616  	assert.Equal(agent.Config.TLSConfig.GetKeyLoader(), originalKeyloader)
   617  
   618  	// Assert is passed through on the server correctly
   619  	if assert.NotNil(agent.server.GetConfig().TLSConfig) {
   620  		serverKeyloader := agent.server.GetConfig().TLSConfig.GetKeyLoader()
   621  		assert.Equal(serverKeyloader, originalKeyloader)
   622  		newCert, err := serverKeyloader.GetOutgoingCertificate(nil)
   623  		assert.Nil(err)
   624  		assert.NotEqual(originalCert, newCert)
   625  	}
   626  
   627  	// Assert is passed through on the client correctly
   628  	if assert.NotNil(agent.client.GetConfig().TLSConfig) {
   629  		clientKeyloader := agent.client.GetConfig().TLSConfig.GetKeyLoader()
   630  		assert.Equal(clientKeyloader, originalKeyloader)
   631  		newCert, err := clientKeyloader.GetOutgoingCertificate(nil)
   632  		assert.Nil(err)
   633  		assert.NotEqual(originalCert, newCert)
   634  	}
   635  }
   636  
   637  func TestServer_Reload_TLS_Certificate(t *testing.T) {
   638  	t.Parallel()
   639  	assert := assert.New(t)
   640  
   641  	const (
   642  		cafile   = "../../helper/tlsutil/testdata/ca.pem"
   643  		foocert  = "../../helper/tlsutil/testdata/nomad-bad.pem"
   644  		fookey   = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
   645  		foocert2 = "../../helper/tlsutil/testdata/nomad-foo.pem"
   646  		fookey2  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   647  	)
   648  
   649  	agentConfig := &Config{
   650  		TLSConfig: &sconfig.TLSConfig{
   651  			EnableHTTP:           true,
   652  			EnableRPC:            true,
   653  			VerifyServerHostname: true,
   654  			CAFile:               cafile,
   655  			CertFile:             foocert,
   656  			KeyFile:              fookey,
   657  		},
   658  	}
   659  
   660  	agent := &Agent{
   661  		auditor: &noOpAuditor{},
   662  		config:  agentConfig,
   663  	}
   664  
   665  	newConfig := &Config{
   666  		TLSConfig: &sconfig.TLSConfig{
   667  			EnableHTTP:           true,
   668  			EnableRPC:            true,
   669  			VerifyServerHostname: true,
   670  			CAFile:               cafile,
   671  			CertFile:             foocert2,
   672  			KeyFile:              fookey2,
   673  		},
   674  	}
   675  
   676  	originalKeyloader := agentConfig.TLSConfig.GetKeyLoader()
   677  	assert.NotNil(originalKeyloader)
   678  
   679  	err := agent.Reload(newConfig)
   680  	assert.Nil(err)
   681  	assert.Equal(agent.config.TLSConfig.CertFile, newConfig.TLSConfig.CertFile)
   682  	assert.Equal(agent.config.TLSConfig.KeyFile, newConfig.TLSConfig.KeyFile)
   683  	assert.Equal(agent.config.TLSConfig.GetKeyLoader(), originalKeyloader)
   684  }
   685  
   686  func TestServer_Reload_TLS_Certificate_Invalid(t *testing.T) {
   687  	t.Parallel()
   688  	assert := assert.New(t)
   689  
   690  	const (
   691  		cafile   = "../../helper/tlsutil/testdata/ca.pem"
   692  		foocert  = "../../helper/tlsutil/testdata/nomad-bad.pem"
   693  		fookey   = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
   694  		foocert2 = "invalid_cert_path"
   695  		fookey2  = "invalid_key_path"
   696  	)
   697  
   698  	agentConfig := &Config{
   699  		TLSConfig: &sconfig.TLSConfig{
   700  			EnableHTTP:           true,
   701  			EnableRPC:            true,
   702  			VerifyServerHostname: true,
   703  			CAFile:               cafile,
   704  			CertFile:             foocert,
   705  			KeyFile:              fookey,
   706  		},
   707  	}
   708  
   709  	agent := &Agent{
   710  		auditor: &noOpAuditor{},
   711  		config:  agentConfig,
   712  	}
   713  
   714  	newConfig := &Config{
   715  		TLSConfig: &sconfig.TLSConfig{
   716  			EnableHTTP:           true,
   717  			EnableRPC:            true,
   718  			VerifyServerHostname: true,
   719  			CAFile:               cafile,
   720  			CertFile:             foocert2,
   721  			KeyFile:              fookey2,
   722  		},
   723  	}
   724  
   725  	err := agent.Reload(newConfig)
   726  	assert.NotNil(err)
   727  	assert.NotEqual(agent.config.TLSConfig.CertFile, newConfig.TLSConfig.CertFile)
   728  	assert.NotEqual(agent.config.TLSConfig.KeyFile, newConfig.TLSConfig.KeyFile)
   729  }
   730  
   731  func Test_GetConfig(t *testing.T) {
   732  	assert := assert.New(t)
   733  
   734  	agentConfig := &Config{
   735  		Telemetry:      &Telemetry{},
   736  		Client:         &ClientConfig{},
   737  		Server:         &ServerConfig{},
   738  		ACL:            &ACLConfig{},
   739  		Ports:          &Ports{},
   740  		Addresses:      &Addresses{},
   741  		AdvertiseAddrs: &AdvertiseAddrs{},
   742  		Vault:          &sconfig.VaultConfig{},
   743  		Consul:         &sconfig.ConsulConfig{},
   744  		Sentinel:       &sconfig.SentinelConfig{},
   745  	}
   746  
   747  	agent := &Agent{
   748  		config: agentConfig,
   749  	}
   750  
   751  	actualAgentConfig := agent.GetConfig()
   752  	assert.Equal(actualAgentConfig, agentConfig)
   753  }
   754  
   755  func TestServer_Reload_TLS_WithNilConfiguration(t *testing.T) {
   756  	t.Parallel()
   757  	assert := assert.New(t)
   758  
   759  	logger := testlog.HCLogger(t)
   760  
   761  	agent := &Agent{
   762  		logger: logger,
   763  		config: &Config{},
   764  	}
   765  
   766  	err := agent.Reload(nil)
   767  	assert.NotNil(err)
   768  	assert.Equal(err.Error(), "cannot reload agent with nil configuration")
   769  }
   770  
   771  func TestServer_Reload_TLS_UpgradeToTLS(t *testing.T) {
   772  	t.Parallel()
   773  	assert := assert.New(t)
   774  
   775  	const (
   776  		cafile  = "../../helper/tlsutil/testdata/ca.pem"
   777  		foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
   778  		fookey  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   779  	)
   780  	dir := tmpDir(t)
   781  	defer os.RemoveAll(dir)
   782  
   783  	logger := testlog.HCLogger(t)
   784  
   785  	agentConfig := &Config{
   786  		TLSConfig: &sconfig.TLSConfig{},
   787  	}
   788  
   789  	agent := &Agent{
   790  		auditor: &noOpAuditor{},
   791  		logger:  logger,
   792  		config:  agentConfig,
   793  	}
   794  
   795  	newConfig := &Config{
   796  		TLSConfig: &sconfig.TLSConfig{
   797  			EnableHTTP:           true,
   798  			EnableRPC:            true,
   799  			VerifyServerHostname: true,
   800  			CAFile:               cafile,
   801  			CertFile:             foocert,
   802  			KeyFile:              fookey,
   803  		},
   804  	}
   805  
   806  	err := agent.Reload(newConfig)
   807  	assert.Nil(err)
   808  
   809  	assert.Equal(agent.config.TLSConfig.CAFile, newConfig.TLSConfig.CAFile)
   810  	assert.Equal(agent.config.TLSConfig.CertFile, newConfig.TLSConfig.CertFile)
   811  	assert.Equal(agent.config.TLSConfig.KeyFile, newConfig.TLSConfig.KeyFile)
   812  }
   813  
   814  func TestServer_Reload_TLS_DowngradeFromTLS(t *testing.T) {
   815  	t.Parallel()
   816  	assert := assert.New(t)
   817  
   818  	const (
   819  		cafile  = "../../helper/tlsutil/testdata/ca.pem"
   820  		foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
   821  		fookey  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   822  	)
   823  	dir := tmpDir(t)
   824  	defer os.RemoveAll(dir)
   825  
   826  	logger := testlog.HCLogger(t)
   827  
   828  	agentConfig := &Config{
   829  		TLSConfig: &sconfig.TLSConfig{
   830  			EnableHTTP:           true,
   831  			EnableRPC:            true,
   832  			VerifyServerHostname: true,
   833  			CAFile:               cafile,
   834  			CertFile:             foocert,
   835  			KeyFile:              fookey,
   836  		},
   837  	}
   838  
   839  	agent := &Agent{
   840  		logger:  logger,
   841  		config:  agentConfig,
   842  		auditor: &noOpAuditor{},
   843  	}
   844  
   845  	newConfig := &Config{
   846  		TLSConfig: &sconfig.TLSConfig{},
   847  	}
   848  
   849  	assert.False(agentConfig.TLSConfig.IsEmpty())
   850  
   851  	err := agent.Reload(newConfig)
   852  	assert.Nil(err)
   853  
   854  	assert.True(agentConfig.TLSConfig.IsEmpty())
   855  }
   856  
   857  func TestServer_ShouldReload_ReturnFalseForNoChanges(t *testing.T) {
   858  	t.Parallel()
   859  	assert := assert.New(t)
   860  
   861  	const (
   862  		cafile  = "../../helper/tlsutil/testdata/ca.pem"
   863  		foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
   864  		fookey  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   865  	)
   866  	dir := tmpDir(t)
   867  	defer os.RemoveAll(dir)
   868  
   869  	sameAgentConfig := &Config{
   870  		TLSConfig: &sconfig.TLSConfig{
   871  			EnableHTTP:           true,
   872  			EnableRPC:            true,
   873  			VerifyServerHostname: true,
   874  			CAFile:               cafile,
   875  			CertFile:             foocert,
   876  			KeyFile:              fookey,
   877  		},
   878  	}
   879  
   880  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   881  		c.TLSConfig = &sconfig.TLSConfig{
   882  			EnableHTTP:           true,
   883  			EnableRPC:            true,
   884  			VerifyServerHostname: true,
   885  			CAFile:               cafile,
   886  			CertFile:             foocert,
   887  			KeyFile:              fookey,
   888  		}
   889  	})
   890  	defer agent.Shutdown()
   891  
   892  	shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(sameAgentConfig)
   893  	assert.False(shouldReloadAgent)
   894  	assert.False(shouldReloadHTTP)
   895  }
   896  
   897  func TestServer_ShouldReload_ReturnTrueForOnlyHTTPChanges(t *testing.T) {
   898  	t.Parallel()
   899  	require := require.New(t)
   900  
   901  	const (
   902  		cafile  = "../../helper/tlsutil/testdata/ca.pem"
   903  		foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
   904  		fookey  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   905  	)
   906  	dir := tmpDir(t)
   907  	defer os.RemoveAll(dir)
   908  
   909  	sameAgentConfig := &Config{
   910  		TLSConfig: &sconfig.TLSConfig{
   911  			EnableHTTP:           false,
   912  			EnableRPC:            true,
   913  			VerifyServerHostname: true,
   914  			CAFile:               cafile,
   915  			CertFile:             foocert,
   916  			KeyFile:              fookey,
   917  		},
   918  	}
   919  
   920  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   921  		c.TLSConfig = &sconfig.TLSConfig{
   922  			EnableHTTP:           true,
   923  			EnableRPC:            true,
   924  			VerifyServerHostname: true,
   925  			CAFile:               cafile,
   926  			CertFile:             foocert,
   927  			KeyFile:              fookey,
   928  		}
   929  	})
   930  	defer agent.Shutdown()
   931  
   932  	shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(sameAgentConfig)
   933  	require.True(shouldReloadAgent)
   934  	require.True(shouldReloadHTTP)
   935  }
   936  
   937  func TestServer_ShouldReload_ReturnTrueForOnlyRPCChanges(t *testing.T) {
   938  	t.Parallel()
   939  	assert := assert.New(t)
   940  
   941  	const (
   942  		cafile  = "../../helper/tlsutil/testdata/ca.pem"
   943  		foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
   944  		fookey  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   945  	)
   946  	dir := tmpDir(t)
   947  	defer os.RemoveAll(dir)
   948  
   949  	sameAgentConfig := &Config{
   950  		TLSConfig: &sconfig.TLSConfig{
   951  			EnableHTTP:           true,
   952  			EnableRPC:            true,
   953  			VerifyServerHostname: true,
   954  			CAFile:               cafile,
   955  			CertFile:             foocert,
   956  			KeyFile:              fookey,
   957  		},
   958  	}
   959  
   960  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   961  		c.TLSConfig = &sconfig.TLSConfig{
   962  			EnableHTTP:           true,
   963  			EnableRPC:            false,
   964  			VerifyServerHostname: true,
   965  			CAFile:               cafile,
   966  			CertFile:             foocert,
   967  			KeyFile:              fookey,
   968  		}
   969  	})
   970  	defer agent.Shutdown()
   971  
   972  	shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(sameAgentConfig)
   973  	assert.True(shouldReloadAgent)
   974  	assert.False(shouldReloadHTTP)
   975  }
   976  
   977  func TestServer_ShouldReload_ReturnTrueForConfigChanges(t *testing.T) {
   978  	t.Parallel()
   979  	assert := assert.New(t)
   980  
   981  	const (
   982  		cafile   = "../../helper/tlsutil/testdata/ca.pem"
   983  		foocert  = "../../helper/tlsutil/testdata/nomad-foo.pem"
   984  		fookey   = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   985  		foocert2 = "../../helper/tlsutil/testdata/nomad-bad.pem"
   986  		fookey2  = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
   987  	)
   988  	dir := tmpDir(t)
   989  	defer os.RemoveAll(dir)
   990  
   991  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   992  		c.TLSConfig = &sconfig.TLSConfig{
   993  			EnableHTTP:           true,
   994  			EnableRPC:            true,
   995  			VerifyServerHostname: true,
   996  			CAFile:               cafile,
   997  			CertFile:             foocert,
   998  			KeyFile:              fookey,
   999  		}
  1000  	})
  1001  	defer agent.Shutdown()
  1002  
  1003  	newConfig := &Config{
  1004  		TLSConfig: &sconfig.TLSConfig{
  1005  			EnableHTTP:           true,
  1006  			EnableRPC:            true,
  1007  			VerifyServerHostname: true,
  1008  			CAFile:               cafile,
  1009  			CertFile:             foocert2,
  1010  			KeyFile:              fookey2,
  1011  		},
  1012  	}
  1013  
  1014  	shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(newConfig)
  1015  	assert.True(shouldReloadAgent)
  1016  	assert.True(shouldReloadHTTP)
  1017  }
  1018  
  1019  func TestServer_ShouldReload_ReturnTrueForFileChanges(t *testing.T) {
  1020  	t.Parallel()
  1021  	require := require.New(t)
  1022  
  1023  	oldCertificate := `
  1024  	-----BEGIN CERTIFICATE-----
  1025  	MIICrzCCAlagAwIBAgIUN+4rYZ6wqQCIBzYYd0sfX2e8hDowCgYIKoZIzj0EAwIw
  1026  	eDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh
  1027  	biBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMFTm9tYWQx
  1028  	GDAWBgNVBAMTD25vbWFkLmhhc2hpY29ycDAgFw0xNjExMTAxOTU2MDBaGA8yMTE2
  1029  	MTAxNzE5NTYwMFoweDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx
  1030  	FjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwG
  1031  	A1UECxMFTm9tYWQxGDAWBgNVBAMTD3JlZ2lvbkZvby5ub21hZDBZMBMGByqGSM49
  1032  	AgEGCCqGSM49AwEHA0IABOqGSFNjm+EBlLYlxmIP6SQTdX8U/6hbPWObB0ffkEO/
  1033  	CFweeYIVWb3FKNPqYAlhMqg1K0ileD0FbhEzarP0sL6jgbswgbgwDgYDVR0PAQH/
  1034  	BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8E
  1035  	AjAAMB0GA1UdDgQWBBQnMcjU4yI3k0AoMtapACpO+w9QMTAfBgNVHSMEGDAWgBQ6
  1036  	NWr8F5y2eFwqfoQdQPg0kWb9QDA5BgNVHREEMjAwghZzZXJ2ZXIucmVnaW9uRm9v
  1037  	Lm5vbWFkghZjbGllbnQucmVnaW9uRm9vLm5vbWFkMAoGCCqGSM49BAMCA0cAMEQC
  1038  	ICrvzc5NzqhdT/HkazAx5OOUU8hqoptnmhRmwn6X+0y9AiA8bNvMUxHz3ZLjGBiw
  1039  	PLBDC2UaSDqJqiiYpYegLhbQtw==
  1040  	-----END CERTIFICATE-----
  1041  	`
  1042  
  1043  	content := []byte(oldCertificate)
  1044  	dir, err := ioutil.TempDir("", "certificate")
  1045  	if err != nil {
  1046  		t.Fatal(err)
  1047  	}
  1048  	defer os.RemoveAll(dir) // clean up
  1049  
  1050  	tmpfn := filepath.Join(dir, "testcert")
  1051  	err = ioutil.WriteFile(tmpfn, content, 0666)
  1052  	require.Nil(err)
  1053  
  1054  	const (
  1055  		cafile = "../../helper/tlsutil/testdata/ca.pem"
  1056  		key    = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
  1057  	)
  1058  
  1059  	logger := testlog.HCLogger(t)
  1060  
  1061  	agentConfig := &Config{
  1062  		TLSConfig: &sconfig.TLSConfig{
  1063  			EnableHTTP:           true,
  1064  			EnableRPC:            true,
  1065  			VerifyServerHostname: true,
  1066  			CAFile:               cafile,
  1067  			CertFile:             tmpfn,
  1068  			KeyFile:              key,
  1069  		},
  1070  	}
  1071  
  1072  	agent := &Agent{
  1073  		logger: logger,
  1074  		config: agentConfig,
  1075  	}
  1076  	agent.config.TLSConfig.SetChecksum()
  1077  
  1078  	shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(agentConfig)
  1079  	require.False(shouldReloadAgent)
  1080  	require.False(shouldReloadHTTP)
  1081  
  1082  	newCertificate := `
  1083  	-----BEGIN CERTIFICATE-----
  1084  	MIICtTCCAlqgAwIBAgIUQp/L2szbgE4b1ASlPOZMReFE27owCgYIKoZIzj0EAwIw
  1085  	fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh
  1086  	biBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMFTm9tYWQx
  1087  	HDAaBgNVBAMTE2JhZC5ub21hZC5oYXNoaWNvcnAwIBcNMTYxMTEwMjAxMDAwWhgP
  1088  	MjExNjEwMTcyMDEwMDBaMHgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
  1089  	bmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKEwlIYXNoaUNvcnAx
  1090  	DjAMBgNVBAsTBU5vbWFkMRgwFgYDVQQDEw9yZWdpb25CYWQubm9tYWQwWTATBgcq
  1091  	hkjOPQIBBggqhkjOPQMBBwNCAAQk6oXJwlxNrKvl6kpeeR4NJc5EYFI2b3y7odjY
  1092  	u55Jp4sI91JVDqnpyatkyGmavdAWa4t0U6HkeaWqKk16/ZcYo4G7MIG4MA4GA1Ud
  1093  	DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T
  1094  	AQH/BAIwADAdBgNVHQ4EFgQUxhzOftFR2L0QAPx8LOuP99WPbpgwHwYDVR0jBBgw
  1095  	FoAUHPDLSgzlHqBEh+c4A7HeT0GWygIwOQYDVR0RBDIwMIIWc2VydmVyLnJlZ2lv
  1096  	bkJhZC5ub21hZIIWY2xpZW50LnJlZ2lvbkJhZC5ub21hZDAKBggqhkjOPQQDAgNJ
  1097  	ADBGAiEAq2rnBeX/St/8i9Cab7Yw0C7pjcaE+mrFYeQByng1Uc0CIQD/o4BrZdkX
  1098  	Nm7QGTRZbUFZTHYZr0ULz08Iaz2aHQ6Mcw==
  1099  	-----END CERTIFICATE-----
  1100  	`
  1101  
  1102  	os.Remove(tmpfn)
  1103  	err = ioutil.WriteFile(tmpfn, []byte(newCertificate), 0666)
  1104  	require.Nil(err)
  1105  
  1106  	newAgentConfig := &Config{
  1107  		TLSConfig: &sconfig.TLSConfig{
  1108  			EnableHTTP:           true,
  1109  			EnableRPC:            true,
  1110  			VerifyServerHostname: true,
  1111  			CAFile:               cafile,
  1112  			CertFile:             tmpfn,
  1113  			KeyFile:              key,
  1114  		},
  1115  	}
  1116  
  1117  	shouldReloadAgent, shouldReloadHTTP = agent.ShouldReload(newAgentConfig)
  1118  	require.True(shouldReloadAgent)
  1119  	require.True(shouldReloadHTTP)
  1120  }
  1121  
  1122  func TestServer_ShouldReload_ShouldHandleMultipleChanges(t *testing.T) {
  1123  	t.Parallel()
  1124  	require := require.New(t)
  1125  
  1126  	const (
  1127  		cafile   = "../../helper/tlsutil/testdata/ca.pem"
  1128  		foocert  = "../../helper/tlsutil/testdata/nomad-foo.pem"
  1129  		fookey   = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
  1130  		foocert2 = "../../helper/tlsutil/testdata/nomad-bad.pem"
  1131  		fookey2  = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
  1132  	)
  1133  	dir := tmpDir(t)
  1134  	defer os.RemoveAll(dir)
  1135  
  1136  	sameAgentConfig := &Config{
  1137  		TLSConfig: &sconfig.TLSConfig{
  1138  			EnableHTTP:           true,
  1139  			EnableRPC:            true,
  1140  			VerifyServerHostname: true,
  1141  			CAFile:               cafile,
  1142  			CertFile:             foocert,
  1143  			KeyFile:              fookey,
  1144  		},
  1145  	}
  1146  
  1147  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
  1148  		c.TLSConfig = &sconfig.TLSConfig{
  1149  			EnableHTTP:           true,
  1150  			EnableRPC:            true,
  1151  			VerifyServerHostname: true,
  1152  			CAFile:               cafile,
  1153  			CertFile:             foocert2,
  1154  			KeyFile:              fookey2,
  1155  		}
  1156  	})
  1157  	defer agent.Shutdown()
  1158  
  1159  	{
  1160  		shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(sameAgentConfig)
  1161  		require.True(shouldReloadAgent)
  1162  		require.True(shouldReloadHTTP)
  1163  	}
  1164  
  1165  	err := agent.Reload(sameAgentConfig)
  1166  	require.Nil(err)
  1167  
  1168  	{
  1169  		shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(sameAgentConfig)
  1170  		require.False(shouldReloadAgent)
  1171  		require.False(shouldReloadHTTP)
  1172  	}
  1173  }
  1174  
  1175  func TestAgent_ProxyRPC_Dev(t *testing.T) {
  1176  	t.Parallel()
  1177  	agent := NewTestAgent(t, t.Name(), nil)
  1178  	defer agent.Shutdown()
  1179  
  1180  	id := agent.client.NodeID()
  1181  	req := &structs.NodeSpecificRequest{
  1182  		NodeID: id,
  1183  		QueryOptions: structs.QueryOptions{
  1184  			Region: agent.server.Region(),
  1185  		},
  1186  	}
  1187  
  1188  	time.Sleep(100 * time.Millisecond)
  1189  
  1190  	var resp cstructs.ClientStatsResponse
  1191  	if err := agent.RPC("ClientStats.Stats", req, &resp); err != nil {
  1192  		t.Fatalf("err: %v", err)
  1193  	}
  1194  }