1package proxy
2
3import (
4	"testing"
5	"time"
6
7	"github.com/hashicorp/consul/agent"
8	"github.com/hashicorp/consul/api"
9	"github.com/hashicorp/consul/testrpc"
10	"github.com/hashicorp/consul/testutil/retry"
11	"github.com/stretchr/testify/require"
12)
13
14func TestRegisterMonitor_good(t *testing.T) {
15	t.Parallel()
16	require := require.New(t)
17
18	a := agent.NewTestAgent(t.Name(), ``)
19	defer a.Shutdown()
20	client := a.Client()
21
22	m, service := testMonitor(t, client)
23	defer m.Close()
24
25	// Verify the settings
26	require.Equal(api.ServiceKindConnectProxy, service.Kind)
27	require.Equal("foo", service.Proxy.DestinationServiceName)
28	require.Equal("127.0.0.1", service.Address)
29	require.Equal(1234, service.Port)
30
31	// Stop should deregister the service
32	require.NoError(m.Close())
33	services, err := client.Agent().Services()
34	require.NoError(err)
35	require.NotContains(services, m.serviceID())
36}
37
38func TestRegisterMonitor_heartbeat(t *testing.T) {
39	t.Parallel()
40	require := require.New(t)
41
42	a := agent.NewTestAgent(t.Name(), ``)
43	defer a.Shutdown()
44	client := a.Client()
45
46	testrpc.WaitForTestAgent(t, a.RPC, "dc1")
47	m, _ := testMonitor(t, client)
48	defer m.Close()
49	retry.Run(t, func(r *retry.R) {
50		// Get the check and verify that it is passing
51		checks, err := client.Agent().Checks()
52		require.NoError(err)
53		require.Contains(checks, m.checkID())
54		require.Equal("passing", checks[m.checkID()].Status)
55		// Purposely fail the TTL check, verify it becomes healthy again
56		require.NoError(client.Agent().FailTTL(m.checkID(), ""))
57	})
58
59	retry.Run(t, func(r *retry.R) {
60
61		checks, err := client.Agent().Checks()
62		if err != nil {
63			r.Fatalf("err: %s", err)
64		}
65
66		check, ok := checks[m.checkID()]
67		if !ok {
68			r.Fatal("check not found")
69		}
70
71		if check.Status != "passing" {
72			r.Fatalf("check status is bad: %s", check.Status)
73		}
74	})
75}
76
77// testMonitor creates a RegisterMonitor, configures it, and starts it.
78// It waits until the service appears in the catalog and then returns.
79func testMonitor(t *testing.T, client *api.Client) (*RegisterMonitor, *api.AgentService) {
80	// Setup the monitor
81	m := NewRegisterMonitor()
82	m.Client = client
83	m.Service = "foo"
84	m.LocalAddress = "127.0.0.1"
85	m.LocalPort = 1234
86
87	// We want shorter periods so we can test things
88	m.ReconcilePeriod = 400 * time.Millisecond
89	m.TTLPeriod = 200 * time.Millisecond
90
91	// Start the monitor
92	go m.Run()
93
94	// The service should be registered
95	var service *api.AgentService
96	retry.Run(t, func(r *retry.R) {
97		services, err := client.Agent().Services()
98		if err != nil {
99			r.Fatalf("err: %s", err)
100		}
101
102		var ok bool
103		service, ok = services[m.serviceID()]
104		if !ok {
105			r.Fatal("service not found")
106		}
107	})
108
109	return m, service
110}
111