129 lines
4.1 KiB
Go
129 lines
4.1 KiB
Go
|
package usagemetrics
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/armon/go-metrics"
|
||
|
"github.com/hashicorp/consul/agent/consul/state"
|
||
|
"github.com/hashicorp/consul/agent/structs"
|
||
|
"github.com/hashicorp/consul/sdk/testutil"
|
||
|
"github.com/stretchr/testify/mock"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
type mockStateProvider struct {
|
||
|
mock.Mock
|
||
|
}
|
||
|
|
||
|
func (m *mockStateProvider) State() *state.Store {
|
||
|
retValues := m.Called()
|
||
|
return retValues.Get(0).(*state.Store)
|
||
|
}
|
||
|
|
||
|
func TestUsageReporter_Run(t *testing.T) {
|
||
|
type testCase struct {
|
||
|
modfiyStateStore func(t *testing.T, s *state.Store)
|
||
|
expectedGauges map[string]metrics.GaugeValue
|
||
|
}
|
||
|
cases := map[string]testCase{
|
||
|
"empty-state": {
|
||
|
expectedGauges: map[string]metrics.GaugeValue{
|
||
|
"consul.usage.test.consul.state.nodes;datacenter=dc1": {
|
||
|
Name: "consul.usage.test.consul.state.nodes",
|
||
|
Value: 0,
|
||
|
Labels: []metrics.Label{{Name: "datacenter", Value: "dc1"}},
|
||
|
},
|
||
|
"consul.usage.test.consul.state.services;datacenter=dc1": {
|
||
|
Name: "consul.usage.test.consul.state.services",
|
||
|
Value: 0,
|
||
|
Labels: []metrics.Label{
|
||
|
{Name: "datacenter", Value: "dc1"},
|
||
|
},
|
||
|
},
|
||
|
"consul.usage.test.consul.state.service_instances;datacenter=dc1": {
|
||
|
Name: "consul.usage.test.consul.state.service_instances",
|
||
|
Value: 0,
|
||
|
Labels: []metrics.Label{
|
||
|
{Name: "datacenter", Value: "dc1"},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"nodes-and-services": {
|
||
|
modfiyStateStore: func(t *testing.T, s *state.Store) {
|
||
|
require.Nil(t, s.EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}))
|
||
|
require.Nil(t, s.EnsureNode(2, &structs.Node{Node: "bar", Address: "127.0.0.2"}))
|
||
|
require.Nil(t, s.EnsureNode(3, &structs.Node{Node: "baz", Address: "127.0.0.2"}))
|
||
|
|
||
|
// Typical services and some consul services spread across two nodes
|
||
|
require.Nil(t, s.EnsureService(4, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: nil, Address: "", Port: 5000}))
|
||
|
require.Nil(t, s.EnsureService(5, "bar", &structs.NodeService{ID: "api", Service: "api", Tags: nil, Address: "", Port: 5000}))
|
||
|
require.Nil(t, s.EnsureService(6, "foo", &structs.NodeService{ID: "consul", Service: "consul", Tags: nil}))
|
||
|
require.Nil(t, s.EnsureService(7, "bar", &structs.NodeService{ID: "consul", Service: "consul", Tags: nil}))
|
||
|
},
|
||
|
expectedGauges: map[string]metrics.GaugeValue{
|
||
|
"consul.usage.test.consul.state.nodes;datacenter=dc1": {
|
||
|
Name: "consul.usage.test.consul.state.nodes",
|
||
|
Value: 3,
|
||
|
Labels: []metrics.Label{{Name: "datacenter", Value: "dc1"}},
|
||
|
},
|
||
|
"consul.usage.test.consul.state.services;datacenter=dc1": {
|
||
|
Name: "consul.usage.test.consul.state.services",
|
||
|
Value: 3,
|
||
|
Labels: []metrics.Label{
|
||
|
{Name: "datacenter", Value: "dc1"},
|
||
|
},
|
||
|
},
|
||
|
"consul.usage.test.consul.state.service_instances;datacenter=dc1": {
|
||
|
Name: "consul.usage.test.consul.state.service_instances",
|
||
|
Value: 4,
|
||
|
Labels: []metrics.Label{
|
||
|
{Name: "datacenter", Value: "dc1"},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for name, tcase := range cases {
|
||
|
t.Run(name, func(t *testing.T) {
|
||
|
// Only have a single interval for the test
|
||
|
sink := metrics.NewInmemSink(1*time.Minute, 1*time.Minute)
|
||
|
cfg := metrics.DefaultConfig("consul.usage.test")
|
||
|
cfg.EnableHostname = false
|
||
|
metrics.NewGlobal(cfg, sink)
|
||
|
|
||
|
mockStateProvider := &mockStateProvider{}
|
||
|
s, err := newStateStore()
|
||
|
require.NoError(t, err)
|
||
|
if tcase.modfiyStateStore != nil {
|
||
|
tcase.modfiyStateStore(t, s)
|
||
|
}
|
||
|
mockStateProvider.On("State").Return(s)
|
||
|
|
||
|
reporter, err := NewUsageMetricsReporter(
|
||
|
new(Config).
|
||
|
WithStateProvider(mockStateProvider).
|
||
|
WithLogger(testutil.Logger(t)).
|
||
|
WithDatacenter("dc1"),
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
reporter.runOnce()
|
||
|
|
||
|
intervals := sink.Data()
|
||
|
require.Len(t, intervals, 1)
|
||
|
intv := intervals[0]
|
||
|
|
||
|
// Range over the expected values instead of just doing an Equal
|
||
|
// comparison on the maps because of different metrics emitted between
|
||
|
// OSS and Ent. The enterprise tests have a full equality comparison on
|
||
|
// the maps.
|
||
|
for key, expected := range tcase.expectedGauges {
|
||
|
require.Equal(t, expected, intv.Gauges[key])
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|