testing: disable global metrics sink in tests

This might be better handled by allowing configuration for the InMemSink interval and retail, and disabling
the global. For now this is a smaller change to remove the goroutine leak caused by tests because go-metrics
does not provide any way of shutting down the global goroutine.
This commit is contained in:
Daniel Nephin 2020-08-17 14:12:04 -04:00
parent 84642486b9
commit a520cf3ea7
6 changed files with 32 additions and 11 deletions

View File

@ -42,12 +42,16 @@ func NewTestACLAgent(t *testing.T, name string, hcl string, resolveAuthz authzRe
dataDir := testutil.TempDir(t, "acl-agent") dataDir := testutil.TempDir(t, "acl-agent")
logBuffer := testutil.NewLogBuffer(t) logBuffer := testutil.NewLogBuffer(t)
loader := func(source config.Source) (cfg *config.RuntimeConfig, warnings []string, err error) { loader := func(source config.Source) (*config.RuntimeConfig, []string, error) {
dataDir := fmt.Sprintf(`data_dir = "%s"`, dataDir) dataDir := fmt.Sprintf(`data_dir = "%s"`, dataDir)
opts := config.BuilderOpts{ opts := config.BuilderOpts{
HCL: []string{TestConfigHCL(NodeID()), hcl, dataDir}, HCL: []string{TestConfigHCL(NodeID()), hcl, dataDir},
} }
return config.Load(opts, source) cfg, warnings, err := config.Load(opts, source)
if cfg != nil {
cfg.Telemetry.Disable = true
}
return cfg, warnings, err
} }
bd, err := NewBaseDeps(loader, logBuffer) bd, err := NewBaseDeps(loader, logBuffer)
require.NoError(t, err) require.NoError(t, err)
@ -58,7 +62,7 @@ func NewTestACLAgent(t *testing.T, name string, hcl string, resolveAuthz authzRe
Output: logBuffer, Output: logBuffer,
TimeFormat: "04:05.000", TimeFormat: "04:05.000",
}) })
bd.TelemetrySink = metrics.NewInmemSink(1*time.Second, time.Minute) bd.MetricsHandler = metrics.NewInmemSink(1*time.Second, time.Minute)
agent, err := New(bd) agent, err := New(bd)
require.NoError(t, err) require.NoError(t, err)

View File

@ -171,7 +171,7 @@ type Agent struct {
logger hclog.InterceptLogger logger hclog.InterceptLogger
// In-memory sink used for collecting metrics // In-memory sink used for collecting metrics
MemSink *metrics.InmemSink MemSink MetricsHandler
// delegate is either a *consul.Server or *consul.Client // delegate is either a *consul.Server or *consul.Client
// depending on the configuration // depending on the configuration
@ -349,7 +349,7 @@ func New(bd BaseDeps) (*Agent, error) {
tlsConfigurator: bd.TLSConfigurator, tlsConfigurator: bd.TLSConfigurator,
config: bd.RuntimeConfig, config: bd.RuntimeConfig,
cache: bd.Cache, cache: bd.Cache,
MemSink: bd.TelemetrySink, MemSink: bd.MetricsHandler,
connPool: bd.ConnPool, connPool: bd.ConnPool,
autoConf: bd.AutoConfig, autoConf: bd.AutoConfig,
} }

View File

@ -7100,6 +7100,7 @@ func TestSanitize(t *testing.T) {
"CirconusCheckTags": "", "CirconusCheckTags": "",
"CirconusSubmissionInterval": "", "CirconusSubmissionInterval": "",
"CirconusSubmissionURL": "", "CirconusSubmissionURL": "",
"Disable": false,
"DisableHostname": false, "DisableHostname": false,
"DogstatsdAddr": "", "DogstatsdAddr": "",
"DogstatsdTags": [], "DogstatsdTags": [],

View File

@ -5,9 +5,9 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"net/http"
"time" "time"
"github.com/armon/go-metrics"
autoconf "github.com/hashicorp/consul/agent/auto-config" autoconf "github.com/hashicorp/consul/agent/auto-config"
"github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/agent/cache"
certmon "github.com/hashicorp/consul/agent/cert-monitor" certmon "github.com/hashicorp/consul/agent/cert-monitor"
@ -28,7 +28,7 @@ import (
type BaseDeps struct { type BaseDeps struct {
Logger hclog.InterceptLogger Logger hclog.InterceptLogger
TLSConfigurator *tlsutil.Configurator // TODO: use an interface TLSConfigurator *tlsutil.Configurator // TODO: use an interface
TelemetrySink *metrics.InmemSink // TODO: use an interface MetricsHandler MetricsHandler
RuntimeConfig *config.RuntimeConfig RuntimeConfig *config.RuntimeConfig
Tokens *token.Store Tokens *token.Store
Cache *cache.Cache Cache *cache.Cache
@ -36,6 +36,11 @@ type BaseDeps struct {
ConnPool *pool.ConnPool // TODO: use an interface ConnPool *pool.ConnPool // TODO: use an interface
} }
// MetricsHandler provides an http.Handler for displaying metrics.
type MetricsHandler interface {
DisplayMetrics(resp http.ResponseWriter, req *http.Request) (interface{}, error)
}
type ConfigLoader func(source config.Source) (cfg *config.RuntimeConfig, warnings []string, err error) type ConfigLoader func(source config.Source) (cfg *config.RuntimeConfig, warnings []string, err error)
func NewBaseDeps(configLoader ConfigLoader, logOut io.Writer) (BaseDeps, error) { func NewBaseDeps(configLoader ConfigLoader, logOut io.Writer) (BaseDeps, error) {
@ -71,7 +76,7 @@ func NewBaseDeps(configLoader ConfigLoader, logOut io.Writer) (BaseDeps, error)
return d, fmt.Errorf("failed to setup node ID: %w", err) return d, fmt.Errorf("failed to setup node ID: %w", err)
} }
d.TelemetrySink, err = lib.InitTelemetry(cfg.Telemetry) d.MetricsHandler, err = lib.InitTelemetry(cfg.Telemetry)
if err != nil { if err != nil {
return d, fmt.Errorf("failed to initialize telemetry: %w", err) return d, fmt.Errorf("failed to initialize telemetry: %w", err)
} }

View File

@ -170,7 +170,7 @@ func (a *TestAgent) Start(t *testing.T) (err error) {
// Create NodeID outside the closure, so that it does not change // Create NodeID outside the closure, so that it does not change
testHCLConfig := TestConfigHCL(NodeID()) testHCLConfig := TestConfigHCL(NodeID())
loader := func(source config.Source) (cfg *config.RuntimeConfig, warnings []string, err error) { loader := func(source config.Source) (*config.RuntimeConfig, []string, error) {
opts := config.BuilderOpts{ opts := config.BuilderOpts{
HCL: []string{testHCLConfig, portsConfig, a.HCL, hclDataDir}, HCL: []string{testHCLConfig, portsConfig, a.HCL, hclDataDir},
} }
@ -182,13 +182,17 @@ func (a *TestAgent) Start(t *testing.T) (err error) {
config.DefaultConsulSource(), config.DefaultConsulSource(),
config.DevConsulSource(), config.DevConsulSource(),
} }
return config.Load(opts, source, overrides...) cfg, warnings, err := config.Load(opts, source, overrides...)
if cfg != nil {
cfg.Telemetry.Disable = true
}
return cfg, warnings, err
} }
bd, err := NewBaseDeps(loader, logOutput) bd, err := NewBaseDeps(loader, logOutput)
require.NoError(t, err) require.NoError(t, err)
bd.Logger = logger bd.Logger = logger
bd.TelemetrySink = metrics.NewInmemSink(1*time.Second, time.Minute) bd.MetricsHandler = metrics.NewInmemSink(1*time.Second, time.Minute)
a.Config = bd.RuntimeConfig a.Config = bd.RuntimeConfig
agent, err := New(bd) agent, err := New(bd)

View File

@ -19,6 +19,10 @@ import (
// the shared InitTelemetry functions below, but we can't import agent/config // the shared InitTelemetry functions below, but we can't import agent/config
// due to a dependency cycle. // due to a dependency cycle.
type TelemetryConfig struct { type TelemetryConfig struct {
// Disable may be set to true to have InitTelemetry to skip initialization
// and return a nil MetricsSink.
Disable bool
// Circonus*: see https://github.com/circonus-labs/circonus-gometrics // Circonus*: see https://github.com/circonus-labs/circonus-gometrics
// for more details on the various configuration options. // for more details on the various configuration options.
// Valid configuration combinations: // Valid configuration combinations:
@ -326,6 +330,9 @@ func circonusSink(cfg TelemetryConfig, hostname string) (metrics.MetricSink, err
// InitTelemetry configures go-metrics based on map of telemetry config // InitTelemetry configures go-metrics based on map of telemetry config
// values as returned by Runtimecfg.Config(). // values as returned by Runtimecfg.Config().
func InitTelemetry(cfg TelemetryConfig) (*metrics.InmemSink, error) { func InitTelemetry(cfg TelemetryConfig) (*metrics.InmemSink, error) {
if cfg.Disable {
return nil, nil
}
// Setup telemetry // Setup telemetry
// Aggregate on 10 second intervals for 1 minute. Expose the // Aggregate on 10 second intervals for 1 minute. Expose the
// metrics over stderr when there is a SIGUSR1 received. // metrics over stderr when there is a SIGUSR1 received.