github.com/kjdelisle/consul@v1.4.5/api/agent_test.go (about)

     1  package api
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/hashicorp/consul/testutil"
    13  	"github.com/hashicorp/consul/testutil/retry"
    14  	"github.com/hashicorp/serf/serf"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestAPI_AgentSelf(t *testing.T) {
    19  	t.Parallel()
    20  	c, s := makeClient(t)
    21  	defer s.Stop()
    22  
    23  	agent := c.Agent()
    24  
    25  	info, err := agent.Self()
    26  	if err != nil {
    27  		t.Fatalf("err: %v", err)
    28  	}
    29  
    30  	name := info["Config"]["NodeName"].(string)
    31  	if name == "" {
    32  		t.Fatalf("bad: %v", info)
    33  	}
    34  }
    35  
    36  func TestAPI_AgentMetrics(t *testing.T) {
    37  	t.Parallel()
    38  	c, s := makeClient(t)
    39  	defer s.Stop()
    40  
    41  	agent := c.Agent()
    42  	timer := &retry.Timer{Timeout: 10 * time.Second, Wait: 500 * time.Millisecond}
    43  	retry.RunWith(timer, t, func(r *retry.R) {
    44  		metrics, err := agent.Metrics()
    45  		if err != nil {
    46  			r.Fatalf("err: %v", err)
    47  		}
    48  		for _, g := range metrics.Gauges {
    49  			if g.Name == "consul.runtime.alloc_bytes" {
    50  				return
    51  			}
    52  		}
    53  		r.Fatalf("missing runtime metrics")
    54  	})
    55  }
    56  
    57  func TestAPI_AgentHost(t *testing.T) {
    58  	t.Parallel()
    59  	c, s := makeClient(t)
    60  	defer s.Stop()
    61  
    62  	agent := c.Agent()
    63  	timer := &retry.Timer{}
    64  	retry.RunWith(timer, t, func(r *retry.R) {
    65  		host, err := agent.Host()
    66  		if err != nil {
    67  			r.Fatalf("err: %v", err)
    68  		}
    69  
    70  		// CollectionTime should exist on all responses
    71  		if host["CollectionTime"] == nil {
    72  			r.Fatalf("missing host response")
    73  		}
    74  	})
    75  }
    76  
    77  func TestAPI_AgentReload(t *testing.T) {
    78  	t.Parallel()
    79  
    80  	// Create our initial empty config file, to be overwritten later
    81  	cfgDir := testutil.TempDir(t, "consul-config")
    82  	defer os.RemoveAll(cfgDir)
    83  
    84  	cfgFilePath := filepath.Join(cfgDir, "reload.json")
    85  	configFile, err := os.Create(cfgFilePath)
    86  	if err != nil {
    87  		t.Fatalf("Unable to create file %v, got error:%v", cfgFilePath, err)
    88  	}
    89  
    90  	c, s := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) {
    91  		conf.Args = []string{"-config-file", configFile.Name()}
    92  	})
    93  	defer s.Stop()
    94  
    95  	agent := c.Agent()
    96  
    97  	// Update the config file with a service definition
    98  	config := `{"service":{"name":"redis", "port":1234, "Meta": {"some": "meta"}}}`
    99  	err = ioutil.WriteFile(configFile.Name(), []byte(config), 0644)
   100  	if err != nil {
   101  		t.Fatalf("err: %v", err)
   102  	}
   103  
   104  	if err = agent.Reload(); err != nil {
   105  		t.Fatalf("err: %v", err)
   106  	}
   107  
   108  	services, err := agent.Services()
   109  	if err != nil {
   110  		t.Fatalf("err: %v", err)
   111  	}
   112  
   113  	service, ok := services["redis"]
   114  	if !ok {
   115  		t.Fatalf("bad: %v", ok)
   116  	}
   117  	if service.Port != 1234 {
   118  		t.Fatalf("bad: %v", service.Port)
   119  	}
   120  	if service.Meta["some"] != "meta" {
   121  		t.Fatalf("Missing metadata some:=meta in %v", service)
   122  	}
   123  }
   124  
   125  func TestAPI_AgentMembersOpts(t *testing.T) {
   126  	t.Parallel()
   127  	c, s1 := makeClient(t)
   128  	_, s2 := makeClientWithConfig(t, nil, func(c *testutil.TestServerConfig) {
   129  		c.Datacenter = "dc2"
   130  	})
   131  	defer s1.Stop()
   132  	defer s2.Stop()
   133  
   134  	agent := c.Agent()
   135  
   136  	s2.JoinWAN(t, s1.WANAddr)
   137  
   138  	members, err := agent.MembersOpts(MembersOpts{WAN: true})
   139  	if err != nil {
   140  		t.Fatalf("err: %v", err)
   141  	}
   142  
   143  	if len(members) != 2 {
   144  		t.Fatalf("bad: %v", members)
   145  	}
   146  }
   147  
   148  func TestAPI_AgentMembers(t *testing.T) {
   149  	t.Parallel()
   150  	c, s := makeClient(t)
   151  	defer s.Stop()
   152  
   153  	agent := c.Agent()
   154  
   155  	members, err := agent.Members(false)
   156  	if err != nil {
   157  		t.Fatalf("err: %v", err)
   158  	}
   159  
   160  	if len(members) != 1 {
   161  		t.Fatalf("bad: %v", members)
   162  	}
   163  }
   164  
   165  func TestAPI_AgentServices(t *testing.T) {
   166  	t.Parallel()
   167  	c, s := makeClient(t)
   168  	defer s.Stop()
   169  
   170  	agent := c.Agent()
   171  
   172  	reg := &AgentServiceRegistration{
   173  		Name: "foo",
   174  		ID:   "foo",
   175  		Tags: []string{"bar", "baz"},
   176  		Port: 8000,
   177  		Check: &AgentServiceCheck{
   178  			TTL: "15s",
   179  		},
   180  	}
   181  	if err := agent.ServiceRegister(reg); err != nil {
   182  		t.Fatalf("err: %v", err)
   183  	}
   184  
   185  	services, err := agent.Services()
   186  	if err != nil {
   187  		t.Fatalf("err: %v", err)
   188  	}
   189  	if _, ok := services["foo"]; !ok {
   190  		t.Fatalf("missing service: %#v", services)
   191  	}
   192  	checks, err := agent.Checks()
   193  	if err != nil {
   194  		t.Fatalf("err: %v", err)
   195  	}
   196  	chk, ok := checks["service:foo"]
   197  	if !ok {
   198  		t.Fatalf("missing check: %v", checks)
   199  	}
   200  
   201  	// Checks should default to critical
   202  	if chk.Status != HealthCritical {
   203  		t.Fatalf("Bad: %#v", chk)
   204  	}
   205  
   206  	state, out, err := agent.AgentHealthServiceByID("foo2")
   207  	require.Nil(t, err)
   208  	require.Nil(t, out)
   209  	require.Equal(t, HealthCritical, state)
   210  
   211  	state, out, err = agent.AgentHealthServiceByID("foo")
   212  	require.Nil(t, err)
   213  	require.NotNil(t, out)
   214  	require.Equal(t, HealthCritical, state)
   215  	require.Equal(t, 8000, out.Service.Port)
   216  
   217  	state, outs, err := agent.AgentHealthServiceByName("foo")
   218  	require.Nil(t, err)
   219  	require.NotNil(t, outs)
   220  	require.Equal(t, HealthCritical, state)
   221  	require.Equal(t, 8000, out.Service.Port)
   222  
   223  	if err := agent.ServiceDeregister("foo"); err != nil {
   224  		t.Fatalf("err: %v", err)
   225  	}
   226  }
   227  
   228  func TestAPI_AgentServices_ManagedConnectProxy(t *testing.T) {
   229  	t.Parallel()
   230  	c, s := makeClient(t)
   231  	defer s.Stop()
   232  
   233  	agent := c.Agent()
   234  
   235  	reg := &AgentServiceRegistration{
   236  		Name: "foo",
   237  		Tags: []string{"bar", "baz"},
   238  		Port: 8000,
   239  		Check: &AgentServiceCheck{
   240  			TTL: "15s",
   241  		},
   242  		Connect: &AgentServiceConnect{
   243  			Proxy: &AgentServiceConnectProxy{
   244  				ExecMode: ProxyExecModeScript,
   245  				Command:  []string{"foo.rb"},
   246  				Config: map[string]interface{}{
   247  					"foo": "bar",
   248  				},
   249  				Upstreams: []Upstream{{
   250  					DestinationType: "prepared_query",
   251  					DestinationName: "bar",
   252  					LocalBindPort:   9191,
   253  				}},
   254  			},
   255  		},
   256  	}
   257  	if err := agent.ServiceRegister(reg); err != nil {
   258  		t.Fatalf("err: %v", err)
   259  	}
   260  
   261  	services, err := agent.Services()
   262  	if err != nil {
   263  		t.Fatalf("err: %v", err)
   264  	}
   265  	if _, ok := services["foo"]; !ok {
   266  		t.Fatalf("missing service: %v", services)
   267  	}
   268  	checks, err := agent.Checks()
   269  	if err != nil {
   270  		t.Fatalf("err: %v", err)
   271  	}
   272  	chk, ok := checks["service:foo"]
   273  	if !ok {
   274  		t.Fatalf("missing check: %v", checks)
   275  	}
   276  
   277  	// Checks should default to critical
   278  	if chk.Status != HealthCritical {
   279  		t.Fatalf("Bad: %#v", chk)
   280  	}
   281  
   282  	// Proxy config should be correct
   283  	require.Equal(t, reg.Connect, services["foo"].Connect)
   284  
   285  	if err := agent.ServiceDeregister("foo"); err != nil {
   286  		t.Fatalf("err: %v", err)
   287  	}
   288  }
   289  
   290  func TestAPI_AgentServices_ManagedConnectProxyDeprecatedUpstreams(t *testing.T) {
   291  	t.Parallel()
   292  	c, s := makeClient(t)
   293  	defer s.Stop()
   294  
   295  	agent := c.Agent()
   296  
   297  	reg := &AgentServiceRegistration{
   298  		Name: "foo",
   299  		Tags: []string{"bar", "baz"},
   300  		Port: 8000,
   301  		Check: &AgentServiceCheck{
   302  			TTL: "15s",
   303  		},
   304  		Connect: &AgentServiceConnect{
   305  			Proxy: &AgentServiceConnectProxy{
   306  				ExecMode: ProxyExecModeScript,
   307  				Command:  []string{"foo.rb"},
   308  				Config: map[string]interface{}{
   309  					"foo": "bar",
   310  					"upstreams": []interface{}{
   311  						map[string]interface{}{
   312  							"destination_type":   "prepared_query",
   313  							"destination_name":   "bar",
   314  							"local_bind_port":    9191,
   315  							"connect_timeout_ms": 1000,
   316  						},
   317  					},
   318  				},
   319  			},
   320  		},
   321  	}
   322  	if err := agent.ServiceRegister(reg); err != nil {
   323  		t.Fatalf("err: %v", err)
   324  	}
   325  
   326  	services, err := agent.Services()
   327  	if err != nil {
   328  		t.Fatalf("err: %v", err)
   329  	}
   330  	if _, ok := services["foo"]; !ok {
   331  		t.Fatalf("missing service: %v", services)
   332  	}
   333  	checks, err := agent.Checks()
   334  	if err != nil {
   335  		t.Fatalf("err: %v", err)
   336  	}
   337  	chk, ok := checks["service:foo"]
   338  	if !ok {
   339  		t.Fatalf("missing check: %v", checks)
   340  	}
   341  
   342  	// Checks should default to critical
   343  	if chk.Status != HealthCritical {
   344  		t.Fatalf("Bad: %#v", chk)
   345  	}
   346  
   347  	// Proxy config should be present in response, minus the upstreams
   348  	delete(reg.Connect.Proxy.Config, "upstreams")
   349  	// Upstreams should be translated into proper field
   350  	reg.Connect.Proxy.Upstreams = []Upstream{{
   351  		DestinationType: "prepared_query",
   352  		DestinationName: "bar",
   353  		LocalBindPort:   9191,
   354  		Config: map[string]interface{}{
   355  			"connect_timeout_ms": float64(1000),
   356  		},
   357  	}}
   358  	require.Equal(t, reg.Connect, services["foo"].Connect)
   359  
   360  	if err := agent.ServiceDeregister("foo"); err != nil {
   361  		t.Fatalf("err: %v", err)
   362  	}
   363  }
   364  
   365  func TestAPI_AgentServices_SidecarService(t *testing.T) {
   366  	t.Parallel()
   367  	c, s := makeClient(t)
   368  	defer s.Stop()
   369  
   370  	agent := c.Agent()
   371  
   372  	// Register service
   373  	reg := &AgentServiceRegistration{
   374  		Name: "foo",
   375  		Port: 8000,
   376  		Connect: &AgentServiceConnect{
   377  			SidecarService: &AgentServiceRegistration{},
   378  		},
   379  	}
   380  	if err := agent.ServiceRegister(reg); err != nil {
   381  		t.Fatalf("err: %v", err)
   382  	}
   383  
   384  	services, err := agent.Services()
   385  	if err != nil {
   386  		t.Fatalf("err: %v", err)
   387  	}
   388  	if _, ok := services["foo"]; !ok {
   389  		t.Fatalf("missing service: %v", services)
   390  	}
   391  	if _, ok := services["foo-sidecar-proxy"]; !ok {
   392  		t.Fatalf("missing sidecar service: %v", services)
   393  	}
   394  
   395  	if err := agent.ServiceDeregister("foo"); err != nil {
   396  		t.Fatalf("err: %v", err)
   397  	}
   398  
   399  	// Deregister should have removed both service and it's sidecar
   400  	services, err = agent.Services()
   401  	require.NoError(t, err)
   402  
   403  	if _, ok := services["foo"]; ok {
   404  		t.Fatalf("didn't remove service: %v", services)
   405  	}
   406  	if _, ok := services["foo-sidecar-proxy"]; ok {
   407  		t.Fatalf("didn't remove sidecar service: %v", services)
   408  	}
   409  }
   410  
   411  func TestAPI_AgentServices_ExternalConnectProxy(t *testing.T) {
   412  	t.Parallel()
   413  	c, s := makeClient(t)
   414  	defer s.Stop()
   415  
   416  	agent := c.Agent()
   417  
   418  	// Register service
   419  	reg := &AgentServiceRegistration{
   420  		Name: "foo",
   421  		Port: 8000,
   422  	}
   423  	if err := agent.ServiceRegister(reg); err != nil {
   424  		t.Fatalf("err: %v", err)
   425  	}
   426  	// Register proxy
   427  	reg = &AgentServiceRegistration{
   428  		Kind: ServiceKindConnectProxy,
   429  		Name: "foo-proxy",
   430  		Port: 8001,
   431  		Proxy: &AgentServiceConnectProxyConfig{
   432  			DestinationServiceName: "foo",
   433  		},
   434  	}
   435  	if err := agent.ServiceRegister(reg); err != nil {
   436  		t.Fatalf("err: %v", err)
   437  	}
   438  
   439  	services, err := agent.Services()
   440  	if err != nil {
   441  		t.Fatalf("err: %v", err)
   442  	}
   443  	if _, ok := services["foo"]; !ok {
   444  		t.Fatalf("missing service: %v", services)
   445  	}
   446  	if _, ok := services["foo-proxy"]; !ok {
   447  		t.Fatalf("missing proxy service: %v", services)
   448  	}
   449  
   450  	if err := agent.ServiceDeregister("foo"); err != nil {
   451  		t.Fatalf("err: %v", err)
   452  	}
   453  	if err := agent.ServiceDeregister("foo-proxy"); err != nil {
   454  		t.Fatalf("err: %v", err)
   455  	}
   456  }
   457  
   458  func TestAPI_AgentServices_CheckPassing(t *testing.T) {
   459  	t.Parallel()
   460  	c, s := makeClient(t)
   461  	defer s.Stop()
   462  
   463  	agent := c.Agent()
   464  	reg := &AgentServiceRegistration{
   465  		Name: "foo",
   466  		Tags: []string{"bar", "baz"},
   467  		Port: 8000,
   468  		Check: &AgentServiceCheck{
   469  			TTL:    "15s",
   470  			Status: HealthPassing,
   471  		},
   472  	}
   473  	if err := agent.ServiceRegister(reg); err != nil {
   474  		t.Fatalf("err: %v", err)
   475  	}
   476  
   477  	services, err := agent.Services()
   478  	if err != nil {
   479  		t.Fatalf("err: %v", err)
   480  	}
   481  	if _, ok := services["foo"]; !ok {
   482  		t.Fatalf("missing service: %v", services)
   483  	}
   484  
   485  	checks, err := agent.Checks()
   486  	if err != nil {
   487  		t.Fatalf("err: %v", err)
   488  	}
   489  	chk, ok := checks["service:foo"]
   490  	if !ok {
   491  		t.Fatalf("missing check: %v", checks)
   492  	}
   493  
   494  	if chk.Status != HealthPassing {
   495  		t.Fatalf("Bad: %#v", chk)
   496  	}
   497  	if err := agent.ServiceDeregister("foo"); err != nil {
   498  		t.Fatalf("err: %v", err)
   499  	}
   500  }
   501  
   502  func TestAPI_AgentServices_CheckBadStatus(t *testing.T) {
   503  	t.Parallel()
   504  	c, s := makeClient(t)
   505  	defer s.Stop()
   506  
   507  	agent := c.Agent()
   508  	reg := &AgentServiceRegistration{
   509  		Name: "foo",
   510  		Tags: []string{"bar", "baz"},
   511  		Port: 8000,
   512  		Check: &AgentServiceCheck{
   513  			TTL:    "15s",
   514  			Status: "fluffy",
   515  		},
   516  	}
   517  	if err := agent.ServiceRegister(reg); err == nil {
   518  		t.Fatalf("bad status accepted")
   519  	}
   520  }
   521  
   522  func TestAPI_AgentServices_CheckID(t *testing.T) {
   523  	t.Parallel()
   524  	c, s := makeClient(t)
   525  	defer s.Stop()
   526  
   527  	agent := c.Agent()
   528  	reg := &AgentServiceRegistration{
   529  		Name: "foo",
   530  		Tags: []string{"bar", "baz"},
   531  		Port: 8000,
   532  		Check: &AgentServiceCheck{
   533  			CheckID: "foo-ttl",
   534  			TTL:     "15s",
   535  		},
   536  	}
   537  	if err := agent.ServiceRegister(reg); err != nil {
   538  		t.Fatalf("err: %v", err)
   539  	}
   540  
   541  	checks, err := agent.Checks()
   542  	if err != nil {
   543  		t.Fatalf("err: %v", err)
   544  	}
   545  	if _, ok := checks["foo-ttl"]; !ok {
   546  		t.Fatalf("missing check: %v", checks)
   547  	}
   548  }
   549  
   550  func TestAPI_AgentServiceAddress(t *testing.T) {
   551  	t.Parallel()
   552  	c, s := makeClient(t)
   553  	defer s.Stop()
   554  
   555  	agent := c.Agent()
   556  
   557  	reg1 := &AgentServiceRegistration{
   558  		Name:    "foo1",
   559  		Port:    8000,
   560  		Address: "192.168.0.42",
   561  	}
   562  	reg2 := &AgentServiceRegistration{
   563  		Name: "foo2",
   564  		Port: 8000,
   565  	}
   566  	if err := agent.ServiceRegister(reg1); err != nil {
   567  		t.Fatalf("err: %v", err)
   568  	}
   569  	if err := agent.ServiceRegister(reg2); err != nil {
   570  		t.Fatalf("err: %v", err)
   571  	}
   572  
   573  	services, err := agent.Services()
   574  	if err != nil {
   575  		t.Fatalf("err: %v", err)
   576  	}
   577  
   578  	if _, ok := services["foo1"]; !ok {
   579  		t.Fatalf("missing service: %v", services)
   580  	}
   581  	if _, ok := services["foo2"]; !ok {
   582  		t.Fatalf("missing service: %v", services)
   583  	}
   584  
   585  	if services["foo1"].Address != "192.168.0.42" {
   586  		t.Fatalf("missing Address field in service foo1: %v", services)
   587  	}
   588  	if services["foo2"].Address != "" {
   589  		t.Fatalf("missing Address field in service foo2: %v", services)
   590  	}
   591  
   592  	if err := agent.ServiceDeregister("foo"); err != nil {
   593  		t.Fatalf("err: %v", err)
   594  	}
   595  }
   596  
   597  func TestAPI_AgentEnableTagOverride(t *testing.T) {
   598  	t.Parallel()
   599  	c, s := makeClient(t)
   600  	defer s.Stop()
   601  
   602  	agent := c.Agent()
   603  
   604  	reg1 := &AgentServiceRegistration{
   605  		Name:              "foo1",
   606  		Port:              8000,
   607  		Address:           "192.168.0.42",
   608  		EnableTagOverride: true,
   609  	}
   610  	reg2 := &AgentServiceRegistration{
   611  		Name: "foo2",
   612  		Port: 8000,
   613  	}
   614  	if err := agent.ServiceRegister(reg1); err != nil {
   615  		t.Fatalf("err: %v", err)
   616  	}
   617  	if err := agent.ServiceRegister(reg2); err != nil {
   618  		t.Fatalf("err: %v", err)
   619  	}
   620  
   621  	services, err := agent.Services()
   622  	if err != nil {
   623  		t.Fatalf("err: %v", err)
   624  	}
   625  
   626  	if _, ok := services["foo1"]; !ok {
   627  		t.Fatalf("missing service: %v", services)
   628  	}
   629  	if services["foo1"].EnableTagOverride != true {
   630  		t.Fatalf("tag override not set on service foo1: %v", services)
   631  	}
   632  	if _, ok := services["foo2"]; !ok {
   633  		t.Fatalf("missing service: %v", services)
   634  	}
   635  	if services["foo2"].EnableTagOverride != false {
   636  		t.Fatalf("tag override set on service foo2: %v", services)
   637  	}
   638  }
   639  
   640  func TestAPI_AgentServices_MultipleChecks(t *testing.T) {
   641  	t.Parallel()
   642  	c, s := makeClient(t)
   643  	defer s.Stop()
   644  
   645  	agent := c.Agent()
   646  
   647  	reg := &AgentServiceRegistration{
   648  		Name: "foo",
   649  		Tags: []string{"bar", "baz"},
   650  		Port: 8000,
   651  		Checks: AgentServiceChecks{
   652  			&AgentServiceCheck{
   653  				TTL: "15s",
   654  			},
   655  			&AgentServiceCheck{
   656  				TTL: "30s",
   657  			},
   658  		},
   659  	}
   660  	if err := agent.ServiceRegister(reg); err != nil {
   661  		t.Fatalf("err: %v", err)
   662  	}
   663  
   664  	services, err := agent.Services()
   665  	if err != nil {
   666  		t.Fatalf("err: %v", err)
   667  	}
   668  	if _, ok := services["foo"]; !ok {
   669  		t.Fatalf("missing service: %v", services)
   670  	}
   671  
   672  	checks, err := agent.Checks()
   673  	if err != nil {
   674  		t.Fatalf("err: %v", err)
   675  	}
   676  	if _, ok := checks["service:foo:1"]; !ok {
   677  		t.Fatalf("missing check: %v", checks)
   678  	}
   679  	if _, ok := checks["service:foo:2"]; !ok {
   680  		t.Fatalf("missing check: %v", checks)
   681  	}
   682  }
   683  
   684  func TestAPI_AgentService(t *testing.T) {
   685  	t.Parallel()
   686  	c, s := makeClient(t)
   687  	defer s.Stop()
   688  
   689  	agent := c.Agent()
   690  
   691  	require := require.New(t)
   692  
   693  	reg := &AgentServiceRegistration{
   694  		Name: "foo",
   695  		Tags: []string{"bar", "baz"},
   696  		Port: 8000,
   697  		Checks: AgentServiceChecks{
   698  			&AgentServiceCheck{
   699  				TTL: "15s",
   700  			},
   701  			&AgentServiceCheck{
   702  				TTL: "30s",
   703  			},
   704  		},
   705  	}
   706  	require.NoError(agent.ServiceRegister(reg))
   707  
   708  	got, qm, err := agent.Service("foo", nil)
   709  	require.NoError(err)
   710  
   711  	expect := &AgentService{
   712  		ID:          "foo",
   713  		Service:     "foo",
   714  		Tags:        []string{"bar", "baz"},
   715  		ContentHash: "ad8c7a278470d1e8",
   716  		Port:        8000,
   717  		Weights: AgentWeights{
   718  			Passing: 1,
   719  			Warning: 1,
   720  		},
   721  	}
   722  	require.Equal(expect, got)
   723  	require.Equal(expect.ContentHash, qm.LastContentHash)
   724  
   725  	// Sanity check blocking behavior - this is more thoroughly tested in the
   726  	// agent endpoint tests but this ensures that the API package is at least
   727  	// passing the hash param properly.
   728  	opts := QueryOptions{
   729  		WaitHash: qm.LastContentHash,
   730  		WaitTime: 100 * time.Millisecond, // Just long enough to be reliably measurable
   731  	}
   732  	start := time.Now()
   733  	got, qm, err = agent.Service("foo", &opts)
   734  	elapsed := time.Since(start)
   735  	require.NoError(err)
   736  	require.True(elapsed >= opts.WaitTime)
   737  }
   738  
   739  func TestAPI_AgentSetTTLStatus(t *testing.T) {
   740  	t.Parallel()
   741  	c, s := makeClient(t)
   742  	defer s.Stop()
   743  
   744  	agent := c.Agent()
   745  
   746  	reg := &AgentServiceRegistration{
   747  		Name: "foo",
   748  		Check: &AgentServiceCheck{
   749  			TTL: "15s",
   750  		},
   751  	}
   752  	if err := agent.ServiceRegister(reg); err != nil {
   753  		t.Fatalf("err: %v", err)
   754  	}
   755  
   756  	verify := func(status, output string) {
   757  		checks, err := agent.Checks()
   758  		if err != nil {
   759  			t.Fatalf("err: %v", err)
   760  		}
   761  		chk, ok := checks["service:foo"]
   762  		if !ok {
   763  			t.Fatalf("missing check: %v", checks)
   764  		}
   765  		if chk.Status != status {
   766  			t.Fatalf("Bad: %#v", chk)
   767  		}
   768  		if chk.Output != output {
   769  			t.Fatalf("Bad: %#v", chk)
   770  		}
   771  	}
   772  
   773  	if err := agent.WarnTTL("service:foo", "foo"); err != nil {
   774  		t.Fatalf("err: %v", err)
   775  	}
   776  	verify(HealthWarning, "foo")
   777  
   778  	if err := agent.PassTTL("service:foo", "bar"); err != nil {
   779  		t.Fatalf("err: %v", err)
   780  	}
   781  	verify(HealthPassing, "bar")
   782  
   783  	if err := agent.FailTTL("service:foo", "baz"); err != nil {
   784  		t.Fatalf("err: %v", err)
   785  	}
   786  	verify(HealthCritical, "baz")
   787  
   788  	if err := agent.UpdateTTL("service:foo", "foo", "warn"); err != nil {
   789  		t.Fatalf("err: %v", err)
   790  	}
   791  	verify(HealthWarning, "foo")
   792  
   793  	if err := agent.UpdateTTL("service:foo", "bar", "pass"); err != nil {
   794  		t.Fatalf("err: %v", err)
   795  	}
   796  	verify(HealthPassing, "bar")
   797  
   798  	if err := agent.UpdateTTL("service:foo", "baz", "fail"); err != nil {
   799  		t.Fatalf("err: %v", err)
   800  	}
   801  	verify(HealthCritical, "baz")
   802  
   803  	if err := agent.UpdateTTL("service:foo", "foo", HealthWarning); err != nil {
   804  		t.Fatalf("err: %v", err)
   805  	}
   806  	verify(HealthWarning, "foo")
   807  
   808  	if err := agent.UpdateTTL("service:foo", "bar", HealthPassing); err != nil {
   809  		t.Fatalf("err: %v", err)
   810  	}
   811  	verify(HealthPassing, "bar")
   812  
   813  	if err := agent.UpdateTTL("service:foo", "baz", HealthCritical); err != nil {
   814  		t.Fatalf("err: %v", err)
   815  	}
   816  	verify(HealthCritical, "baz")
   817  
   818  	if err := agent.ServiceDeregister("foo"); err != nil {
   819  		t.Fatalf("err: %v", err)
   820  	}
   821  }
   822  
   823  func TestAPI_AgentChecks(t *testing.T) {
   824  	t.Parallel()
   825  	c, s := makeClient(t)
   826  	defer s.Stop()
   827  
   828  	agent := c.Agent()
   829  
   830  	reg := &AgentCheckRegistration{
   831  		Name: "foo",
   832  	}
   833  	reg.TTL = "15s"
   834  	if err := agent.CheckRegister(reg); err != nil {
   835  		t.Fatalf("err: %v", err)
   836  	}
   837  
   838  	checks, err := agent.Checks()
   839  	if err != nil {
   840  		t.Fatalf("err: %v", err)
   841  	}
   842  	chk, ok := checks["foo"]
   843  	if !ok {
   844  		t.Fatalf("missing check: %v", checks)
   845  	}
   846  	if chk.Status != HealthCritical {
   847  		t.Fatalf("check not critical: %v", chk)
   848  	}
   849  
   850  	if err := agent.CheckDeregister("foo"); err != nil {
   851  		t.Fatalf("err: %v", err)
   852  	}
   853  }
   854  
   855  func TestAPI_AgentScriptCheck(t *testing.T) {
   856  	t.Parallel()
   857  	c, s := makeClientWithConfig(t, nil, func(c *testutil.TestServerConfig) {
   858  		c.EnableScriptChecks = true
   859  	})
   860  	defer s.Stop()
   861  
   862  	agent := c.Agent()
   863  
   864  	t.Run("node script check", func(t *testing.T) {
   865  		reg := &AgentCheckRegistration{
   866  			Name: "foo",
   867  			AgentServiceCheck: AgentServiceCheck{
   868  				Interval: "10s",
   869  				Args:     []string{"sh", "-c", "false"},
   870  			},
   871  		}
   872  		if err := agent.CheckRegister(reg); err != nil {
   873  			t.Fatalf("err: %v", err)
   874  		}
   875  
   876  		checks, err := agent.Checks()
   877  		if err != nil {
   878  			t.Fatalf("err: %v", err)
   879  		}
   880  		if _, ok := checks["foo"]; !ok {
   881  			t.Fatalf("missing check: %v", checks)
   882  		}
   883  	})
   884  
   885  	t.Run("service script check", func(t *testing.T) {
   886  		reg := &AgentServiceRegistration{
   887  			Name: "bar",
   888  			Port: 1234,
   889  			Checks: AgentServiceChecks{
   890  				&AgentServiceCheck{
   891  					Interval: "10s",
   892  					Args:     []string{"sh", "-c", "false"},
   893  				},
   894  			},
   895  		}
   896  		if err := agent.ServiceRegister(reg); err != nil {
   897  			t.Fatalf("err: %v", err)
   898  		}
   899  
   900  		services, err := agent.Services()
   901  		if err != nil {
   902  			t.Fatalf("err: %v", err)
   903  		}
   904  		if _, ok := services["bar"]; !ok {
   905  			t.Fatalf("missing service: %v", services)
   906  		}
   907  
   908  		checks, err := agent.Checks()
   909  		if err != nil {
   910  			t.Fatalf("err: %v", err)
   911  		}
   912  		if _, ok := checks["service:bar"]; !ok {
   913  			t.Fatalf("missing check: %v", checks)
   914  		}
   915  	})
   916  }
   917  
   918  func TestAPI_AgentCheckStartPassing(t *testing.T) {
   919  	t.Parallel()
   920  	c, s := makeClient(t)
   921  	defer s.Stop()
   922  
   923  	agent := c.Agent()
   924  
   925  	reg := &AgentCheckRegistration{
   926  		Name: "foo",
   927  		AgentServiceCheck: AgentServiceCheck{
   928  			Status: HealthPassing,
   929  		},
   930  	}
   931  	reg.TTL = "15s"
   932  	if err := agent.CheckRegister(reg); err != nil {
   933  		t.Fatalf("err: %v", err)
   934  	}
   935  
   936  	checks, err := agent.Checks()
   937  	if err != nil {
   938  		t.Fatalf("err: %v", err)
   939  	}
   940  	chk, ok := checks["foo"]
   941  	if !ok {
   942  		t.Fatalf("missing check: %v", checks)
   943  	}
   944  	if chk.Status != HealthPassing {
   945  		t.Fatalf("check not passing: %v", chk)
   946  	}
   947  
   948  	if err := agent.CheckDeregister("foo"); err != nil {
   949  		t.Fatalf("err: %v", err)
   950  	}
   951  }
   952  
   953  func TestAPI_AgentChecks_serviceBound(t *testing.T) {
   954  	t.Parallel()
   955  	c, s := makeClient(t)
   956  	defer s.Stop()
   957  
   958  	agent := c.Agent()
   959  
   960  	// First register a service
   961  	serviceReg := &AgentServiceRegistration{
   962  		Name: "redis",
   963  	}
   964  	if err := agent.ServiceRegister(serviceReg); err != nil {
   965  		t.Fatalf("err: %v", err)
   966  	}
   967  
   968  	// Register a check bound to the service
   969  	reg := &AgentCheckRegistration{
   970  		Name:      "redischeck",
   971  		ServiceID: "redis",
   972  	}
   973  	reg.TTL = "15s"
   974  	reg.DeregisterCriticalServiceAfter = "nope"
   975  	err := agent.CheckRegister(reg)
   976  	if err == nil || !strings.Contains(err.Error(), "invalid duration") {
   977  		t.Fatalf("err: %v", err)
   978  	}
   979  
   980  	reg.DeregisterCriticalServiceAfter = "90m"
   981  	if err := agent.CheckRegister(reg); err != nil {
   982  		t.Fatalf("err: %v", err)
   983  	}
   984  
   985  	checks, err := agent.Checks()
   986  	if err != nil {
   987  		t.Fatalf("err: %v", err)
   988  	}
   989  
   990  	check, ok := checks["redischeck"]
   991  	if !ok {
   992  		t.Fatalf("missing check: %v", checks)
   993  	}
   994  	if check.ServiceID != "redis" {
   995  		t.Fatalf("missing service association for check: %v", check)
   996  	}
   997  }
   998  
   999  func TestAPI_AgentChecks_Docker(t *testing.T) {
  1000  	t.Parallel()
  1001  	c, s := makeClientWithConfig(t, nil, func(c *testutil.TestServerConfig) {
  1002  		c.EnableScriptChecks = true
  1003  	})
  1004  	defer s.Stop()
  1005  
  1006  	agent := c.Agent()
  1007  
  1008  	// First register a service
  1009  	serviceReg := &AgentServiceRegistration{
  1010  		Name: "redis",
  1011  	}
  1012  	if err := agent.ServiceRegister(serviceReg); err != nil {
  1013  		t.Fatalf("err: %v", err)
  1014  	}
  1015  
  1016  	// Register a check bound to the service
  1017  	reg := &AgentCheckRegistration{
  1018  		Name:      "redischeck",
  1019  		ServiceID: "redis",
  1020  		AgentServiceCheck: AgentServiceCheck{
  1021  			DockerContainerID: "f972c95ebf0e",
  1022  			Args:              []string{"/bin/true"},
  1023  			Shell:             "/bin/bash",
  1024  			Interval:          "10s",
  1025  		},
  1026  	}
  1027  	if err := agent.CheckRegister(reg); err != nil {
  1028  		t.Fatalf("err: %v", err)
  1029  	}
  1030  
  1031  	checks, err := agent.Checks()
  1032  	if err != nil {
  1033  		t.Fatalf("err: %v", err)
  1034  	}
  1035  
  1036  	check, ok := checks["redischeck"]
  1037  	if !ok {
  1038  		t.Fatalf("missing check: %v", checks)
  1039  	}
  1040  	if check.ServiceID != "redis" {
  1041  		t.Fatalf("missing service association for check: %v", check)
  1042  	}
  1043  }
  1044  
  1045  func TestAPI_AgentJoin(t *testing.T) {
  1046  	t.Parallel()
  1047  	c, s := makeClient(t)
  1048  	defer s.Stop()
  1049  
  1050  	agent := c.Agent()
  1051  
  1052  	info, err := agent.Self()
  1053  	if err != nil {
  1054  		t.Fatalf("err: %v", err)
  1055  	}
  1056  
  1057  	// Join ourself
  1058  	addr := info["DebugConfig"]["SerfAdvertiseAddrLAN"].(string)
  1059  	// strip off 'tcp://'
  1060  	addr = addr[len("tcp://"):]
  1061  	err = agent.Join(addr, false)
  1062  	if err != nil {
  1063  		t.Fatalf("err: %v", err)
  1064  	}
  1065  }
  1066  
  1067  func TestAPI_AgentLeave(t *testing.T) {
  1068  	t.Parallel()
  1069  	c1, s1 := makeClient(t)
  1070  	defer s1.Stop()
  1071  
  1072  	c2, s2 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) {
  1073  		conf.Server = false
  1074  		conf.Bootstrap = false
  1075  	})
  1076  	defer s2.Stop()
  1077  
  1078  	if err := c2.Agent().Join(s1.LANAddr, false); err != nil {
  1079  		t.Fatalf("err: %v", err)
  1080  	}
  1081  
  1082  	// We sometimes see an EOF response to this one, depending on timing.
  1083  	err := c2.Agent().Leave()
  1084  	if err != nil && !strings.Contains(err.Error(), "EOF") {
  1085  		t.Fatalf("err: %v", err)
  1086  	}
  1087  
  1088  	// Make sure the second agent's status is 'Left'
  1089  	members, err := c1.Agent().Members(false)
  1090  	if err != nil {
  1091  		t.Fatalf("err: %v", err)
  1092  	}
  1093  	member := members[0]
  1094  	if member.Name == s1.Config.NodeName {
  1095  		member = members[1]
  1096  	}
  1097  	if member.Status != int(serf.StatusLeft) {
  1098  		t.Fatalf("bad: %v", *member)
  1099  	}
  1100  }
  1101  
  1102  func TestAPI_AgentForceLeave(t *testing.T) {
  1103  	t.Parallel()
  1104  	c, s := makeClient(t)
  1105  	defer s.Stop()
  1106  
  1107  	agent := c.Agent()
  1108  
  1109  	// Eject somebody
  1110  	err := agent.ForceLeave("foo")
  1111  	if err != nil {
  1112  		t.Fatalf("err: %v", err)
  1113  	}
  1114  }
  1115  
  1116  func TestAPI_AgentMonitor(t *testing.T) {
  1117  	t.Parallel()
  1118  	c, s := makeClient(t)
  1119  	defer s.Stop()
  1120  
  1121  	agent := c.Agent()
  1122  
  1123  	logCh, err := agent.Monitor("info", nil, nil)
  1124  	if err != nil {
  1125  		t.Fatalf("err: %v", err)
  1126  	}
  1127  
  1128  	// Wait for the first log message and validate it
  1129  	select {
  1130  	case log := <-logCh:
  1131  		if !strings.Contains(log, "[INFO]") {
  1132  			t.Fatalf("bad: %q", log)
  1133  		}
  1134  	case <-time.After(10 * time.Second):
  1135  		t.Fatalf("failed to get a log message")
  1136  	}
  1137  }
  1138  
  1139  func TestAPI_ServiceMaintenance(t *testing.T) {
  1140  	t.Parallel()
  1141  	c, s := makeClient(t)
  1142  	defer s.Stop()
  1143  
  1144  	agent := c.Agent()
  1145  
  1146  	// First register a service
  1147  	serviceReg := &AgentServiceRegistration{
  1148  		Name: "redis",
  1149  	}
  1150  	if err := agent.ServiceRegister(serviceReg); err != nil {
  1151  		t.Fatalf("err: %v", err)
  1152  	}
  1153  
  1154  	// Enable maintenance mode
  1155  	if err := agent.EnableServiceMaintenance("redis", "broken"); err != nil {
  1156  		t.Fatalf("err: %s", err)
  1157  	}
  1158  
  1159  	// Ensure a critical check was added
  1160  	checks, err := agent.Checks()
  1161  	if err != nil {
  1162  		t.Fatalf("err: %v", err)
  1163  	}
  1164  	found := false
  1165  	for _, check := range checks {
  1166  		if strings.Contains(check.CheckID, "maintenance") {
  1167  			found = true
  1168  			if check.Status != HealthCritical || check.Notes != "broken" {
  1169  				t.Fatalf("bad: %#v", checks)
  1170  			}
  1171  		}
  1172  	}
  1173  	if !found {
  1174  		t.Fatalf("bad: %#v", checks)
  1175  	}
  1176  
  1177  	// Disable maintenance mode
  1178  	if err := agent.DisableServiceMaintenance("redis"); err != nil {
  1179  		t.Fatalf("err: %s", err)
  1180  	}
  1181  
  1182  	// Ensure the critical health check was removed
  1183  	checks, err = agent.Checks()
  1184  	if err != nil {
  1185  		t.Fatalf("err: %s", err)
  1186  	}
  1187  	for _, check := range checks {
  1188  		if strings.Contains(check.CheckID, "maintenance") {
  1189  			t.Fatalf("should have removed health check")
  1190  		}
  1191  	}
  1192  }
  1193  
  1194  func TestAPI_NodeMaintenance(t *testing.T) {
  1195  	t.Parallel()
  1196  	c, s := makeClient(t)
  1197  	defer s.Stop()
  1198  
  1199  	agent := c.Agent()
  1200  
  1201  	// Enable maintenance mode
  1202  	if err := agent.EnableNodeMaintenance("broken"); err != nil {
  1203  		t.Fatalf("err: %s", err)
  1204  	}
  1205  
  1206  	// Check that a critical check was added
  1207  	checks, err := agent.Checks()
  1208  	if err != nil {
  1209  		t.Fatalf("err: %s", err)
  1210  	}
  1211  	found := false
  1212  	for _, check := range checks {
  1213  		if strings.Contains(check.CheckID, "maintenance") {
  1214  			found = true
  1215  			if check.Status != HealthCritical || check.Notes != "broken" {
  1216  				t.Fatalf("bad: %#v", checks)
  1217  			}
  1218  		}
  1219  	}
  1220  	if !found {
  1221  		t.Fatalf("bad: %#v", checks)
  1222  	}
  1223  
  1224  	// Disable maintenance mode
  1225  	if err := agent.DisableNodeMaintenance(); err != nil {
  1226  		t.Fatalf("err: %s", err)
  1227  	}
  1228  
  1229  	// Ensure the check was removed
  1230  	checks, err = agent.Checks()
  1231  	if err != nil {
  1232  		t.Fatalf("err: %s", err)
  1233  	}
  1234  	for _, check := range checks {
  1235  		if strings.Contains(check.CheckID, "maintenance") {
  1236  			t.Fatalf("should have removed health check")
  1237  		}
  1238  	}
  1239  }
  1240  
  1241  func TestAPI_AgentUpdateToken(t *testing.T) {
  1242  	t.Parallel()
  1243  	c, s := makeACLClient(t)
  1244  	defer s.Stop()
  1245  
  1246  	agent := c.Agent()
  1247  
  1248  	if _, err := agent.UpdateACLToken("root", nil); err != nil {
  1249  		t.Fatalf("err: %v", err)
  1250  	}
  1251  
  1252  	if _, err := agent.UpdateACLAgentToken("root", nil); err != nil {
  1253  		t.Fatalf("err: %v", err)
  1254  	}
  1255  
  1256  	if _, err := agent.UpdateACLAgentMasterToken("root", nil); err != nil {
  1257  		t.Fatalf("err: %v", err)
  1258  	}
  1259  
  1260  	if _, err := agent.UpdateACLReplicationToken("root", nil); err != nil {
  1261  		t.Fatalf("err: %v", err)
  1262  	}
  1263  
  1264  	if _, err := agent.UpdateDefaultACLToken("root", nil); err != nil {
  1265  		t.Fatalf("err: %v", err)
  1266  	}
  1267  
  1268  	if _, err := agent.UpdateAgentACLToken("root", nil); err != nil {
  1269  		t.Fatalf("err: %v", err)
  1270  	}
  1271  
  1272  	if _, err := agent.UpdateAgentMasterACLToken("root", nil); err != nil {
  1273  		t.Fatalf("err: %v", err)
  1274  	}
  1275  
  1276  	if _, err := agent.UpdateReplicationACLToken("root", nil); err != nil {
  1277  		t.Fatalf("err: %v", err)
  1278  	}
  1279  }
  1280  
  1281  func TestAPI_AgentConnectCARoots_empty(t *testing.T) {
  1282  	t.Parallel()
  1283  
  1284  	require := require.New(t)
  1285  	c, s := makeClientWithConfig(t, nil, func(c *testutil.TestServerConfig) {
  1286  		c.Connect = nil // disable connect to prevent CA being bootstrapped
  1287  	})
  1288  	defer s.Stop()
  1289  
  1290  	agent := c.Agent()
  1291  	_, _, err := agent.ConnectCARoots(nil)
  1292  	require.Error(err)
  1293  	require.Contains(err.Error(), "Connect must be enabled")
  1294  }
  1295  
  1296  func TestAPI_AgentConnectCARoots_list(t *testing.T) {
  1297  	t.Parallel()
  1298  
  1299  	require := require.New(t)
  1300  	c, s := makeClient(t)
  1301  	defer s.Stop()
  1302  
  1303  	agent := c.Agent()
  1304  	s.WaitForSerfCheck(t)
  1305  	list, meta, err := agent.ConnectCARoots(nil)
  1306  	require.NoError(err)
  1307  	require.True(meta.LastIndex > 0)
  1308  	require.Len(list.Roots, 1)
  1309  }
  1310  
  1311  func TestAPI_AgentConnectCALeaf(t *testing.T) {
  1312  	t.Parallel()
  1313  
  1314  	require := require.New(t)
  1315  	c, s := makeClient(t)
  1316  	defer s.Stop()
  1317  
  1318  	agent := c.Agent()
  1319  	// Setup service
  1320  	reg := &AgentServiceRegistration{
  1321  		Name: "foo",
  1322  		Tags: []string{"bar", "baz"},
  1323  		Port: 8000,
  1324  	}
  1325  	require.NoError(agent.ServiceRegister(reg))
  1326  
  1327  	leaf, meta, err := agent.ConnectCALeaf("foo", nil)
  1328  	require.NoError(err)
  1329  	require.True(meta.LastIndex > 0)
  1330  	// Sanity checks here as we have actual certificate validation checks at many
  1331  	// other levels.
  1332  	require.NotEmpty(leaf.SerialNumber)
  1333  	require.NotEmpty(leaf.CertPEM)
  1334  	require.NotEmpty(leaf.PrivateKeyPEM)
  1335  	require.Equal("foo", leaf.Service)
  1336  	require.True(strings.HasSuffix(leaf.ServiceURI, "/svc/foo"))
  1337  	require.True(leaf.ModifyIndex > 0)
  1338  	require.True(leaf.ValidAfter.Before(time.Now()))
  1339  	require.True(leaf.ValidBefore.After(time.Now()))
  1340  }
  1341  
  1342  func TestAPI_AgentConnectAuthorize(t *testing.T) {
  1343  	t.Parallel()
  1344  	require := require.New(t)
  1345  	c, s := makeClient(t)
  1346  	defer s.Stop()
  1347  
  1348  	agent := c.Agent()
  1349  	s.WaitForSerfCheck(t)
  1350  	params := &AgentAuthorizeParams{
  1351  		Target:           "foo",
  1352  		ClientCertSerial: "fake",
  1353  		// Importing connect.TestSpiffeIDService creates an import cycle
  1354  		ClientCertURI: "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/ny1/svc/web",
  1355  	}
  1356  	auth, err := agent.ConnectAuthorize(params)
  1357  	require.Nil(err)
  1358  	require.True(auth.Authorized)
  1359  	require.Equal(auth.Reason, "ACLs disabled, access is allowed by default")
  1360  }
  1361  
  1362  func TestAPI_AgentConnectProxyConfig(t *testing.T) {
  1363  	t.Parallel()
  1364  	c, s := makeClientWithConfig(t, nil, func(c *testutil.TestServerConfig) {
  1365  		// Force auto port range to 1 port so we have deterministic response.
  1366  		c.Ports.ProxyMinPort = 20000
  1367  		c.Ports.ProxyMaxPort = 20000
  1368  	})
  1369  	defer s.Stop()
  1370  
  1371  	agent := c.Agent()
  1372  	reg := &AgentServiceRegistration{
  1373  		Name: "foo",
  1374  		Tags: []string{"bar", "baz"},
  1375  		Port: 8000,
  1376  		Connect: &AgentServiceConnect{
  1377  			Proxy: &AgentServiceConnectProxy{
  1378  				Command: []string{"consul", "connect", "proxy"},
  1379  				Config: map[string]interface{}{
  1380  					"foo": "bar",
  1381  				},
  1382  				Upstreams: testUpstreams(t),
  1383  			},
  1384  		},
  1385  	}
  1386  	if err := agent.ServiceRegister(reg); err != nil {
  1387  		t.Fatalf("err: %v", err)
  1388  	}
  1389  
  1390  	config, qm, err := agent.ConnectProxyConfig("foo-proxy", nil)
  1391  	require.NoError(t, err)
  1392  	expectConfig := &ConnectProxyConfig{
  1393  		ProxyServiceID:    "foo-proxy",
  1394  		TargetServiceID:   "foo",
  1395  		TargetServiceName: "foo",
  1396  		ContentHash:       "acdf5eb6f5794a14",
  1397  		ExecMode:          "daemon",
  1398  		Command:           []string{"consul", "connect", "proxy"},
  1399  		Config: map[string]interface{}{
  1400  			"bind_address":          "127.0.0.1",
  1401  			"bind_port":             float64(20000),
  1402  			"foo":                   "bar",
  1403  			"local_service_address": "127.0.0.1:8000",
  1404  		},
  1405  		Upstreams: testExpectUpstreamsWithDefaults(t, reg.Connect.Proxy.Upstreams),
  1406  	}
  1407  	require.Equal(t, expectConfig, config)
  1408  	require.Equal(t, expectConfig.ContentHash, qm.LastContentHash)
  1409  }
  1410  
  1411  func TestAPI_AgentHealthService(t *testing.T) {
  1412  	t.Parallel()
  1413  	c, s := makeClient(t)
  1414  	defer s.Stop()
  1415  
  1416  	agent := c.Agent()
  1417  
  1418  	requireServiceHealthID := func(t *testing.T, serviceID, expected string, shouldExist bool) {
  1419  		msg := fmt.Sprintf("service id:%s, shouldExist:%v, expectedStatus:%s : bad %%s", serviceID, shouldExist, expected)
  1420  
  1421  		state, out, err := agent.AgentHealthServiceByID(serviceID)
  1422  		require.Nil(t, err, msg, "err")
  1423  		require.Equal(t, expected, state, msg, "state")
  1424  		if !shouldExist {
  1425  			require.Nil(t, out, msg, "shouldExist")
  1426  		} else {
  1427  			require.NotNil(t, out, msg, "output")
  1428  			require.Equal(t, serviceID, out.Service.ID, msg, "output")
  1429  		}
  1430  	}
  1431  	requireServiceHealthName := func(t *testing.T, serviceName, expected string, shouldExist bool) {
  1432  		msg := fmt.Sprintf("service name:%s, shouldExist:%v, expectedStatus:%s : bad %%s", serviceName, shouldExist, expected)
  1433  
  1434  		state, outs, err := agent.AgentHealthServiceByName(serviceName)
  1435  		require.Nil(t, err, msg, "err")
  1436  		require.Equal(t, expected, state, msg, "state")
  1437  		if !shouldExist {
  1438  			require.Equal(t, 0, len(outs), msg, "output")
  1439  		} else {
  1440  			require.True(t, len(outs) > 0, msg, "output")
  1441  			for _, o := range outs {
  1442  				require.Equal(t, serviceName, o.Service.Service, msg, "output")
  1443  			}
  1444  		}
  1445  	}
  1446  
  1447  	requireServiceHealthID(t, "_i_do_not_exist_", HealthCritical, false)
  1448  	requireServiceHealthName(t, "_i_do_not_exist_", HealthCritical, false)
  1449  
  1450  	testServiceID1 := "foo"
  1451  	testServiceID2 := "foofoo"
  1452  	testServiceName := "bar"
  1453  
  1454  	// register service
  1455  	reg := &AgentServiceRegistration{
  1456  		Name: testServiceName,
  1457  		ID:   testServiceID1,
  1458  		Port: 8000,
  1459  		Check: &AgentServiceCheck{
  1460  			TTL: "15s",
  1461  		},
  1462  	}
  1463  	err := agent.ServiceRegister(reg)
  1464  	require.Nil(t, err)
  1465  	requireServiceHealthID(t, testServiceID1, HealthCritical, true)
  1466  	requireServiceHealthName(t, testServiceName, HealthCritical, true)
  1467  
  1468  	err = agent.WarnTTL(fmt.Sprintf("service:%s", testServiceID1), "I am warn")
  1469  	require.Nil(t, err)
  1470  	requireServiceHealthName(t, testServiceName, HealthWarning, true)
  1471  	requireServiceHealthID(t, testServiceID1, HealthWarning, true)
  1472  
  1473  	err = agent.PassTTL(fmt.Sprintf("service:%s", testServiceID1), "I am good :)")
  1474  	require.Nil(t, err)
  1475  	requireServiceHealthName(t, testServiceName, HealthPassing, true)
  1476  	requireServiceHealthID(t, testServiceID1, HealthPassing, true)
  1477  
  1478  	err = agent.FailTTL(fmt.Sprintf("service:%s", testServiceID1), "I am dead.")
  1479  	require.Nil(t, err)
  1480  	requireServiceHealthName(t, testServiceName, HealthCritical, true)
  1481  	requireServiceHealthID(t, testServiceID1, HealthCritical, true)
  1482  
  1483  	// register another service
  1484  	reg = &AgentServiceRegistration{
  1485  		Name: testServiceName,
  1486  		ID:   testServiceID2,
  1487  		Port: 8000,
  1488  		Check: &AgentServiceCheck{
  1489  			TTL: "15s",
  1490  		},
  1491  	}
  1492  	err = agent.ServiceRegister(reg)
  1493  	require.Nil(t, err)
  1494  	requireServiceHealthName(t, testServiceName, HealthCritical, true)
  1495  
  1496  	err = agent.PassTTL(fmt.Sprintf("service:%s", testServiceID1), "I am good :)")
  1497  	require.Nil(t, err)
  1498  	requireServiceHealthName(t, testServiceName, HealthCritical, true)
  1499  
  1500  	err = agent.WarnTTL(fmt.Sprintf("service:%s", testServiceID2), "I am warn")
  1501  	require.Nil(t, err)
  1502  	requireServiceHealthName(t, testServiceName, HealthWarning, true)
  1503  
  1504  	err = agent.PassTTL(fmt.Sprintf("service:%s", testServiceID2), "I am good :)")
  1505  	require.Nil(t, err)
  1506  	requireServiceHealthName(t, testServiceName, HealthPassing, true)
  1507  }