e8c91d9d70
[HCP Telemetry] Periodic Refresh for Dynamic Telemetry Configuration (#18168) * OTElExporter now uses an EndpointProvider to discover the endpoint * OTELSink uses a ConfigProvider to obtain filters and labels configuration * improve tests for otel_sink * Regex logic is moved into client for a method on the TelemetryConfig object * Create a telemetry_config_provider and update deps to use it * Fix conversion * fix import newline * Add logger to hcp client and move telemetry_config out of the client.go file * Add a telemetry_config.go to refactor client.go * Update deps * update hcp deps test * Modify telemetry_config_providers * Check for nil filters * PR review updates * Fix comments and move around pieces * Fix comments * Remove context from client struct * Moved ctx out of sink struct and fixed filters, added a test * Remove named imports, use errors.New if not fformatting * Remove HCP dependencies in telemetry package * Add success metric and move lock only to grab the t.cfgHahs * Update hash * fix nits * Create an equals method and add tests * Improve telemetry_config_provider.go tests * Add race test * Add missing godoc * Remove mock for MetricsClient * Avoid goroutine test panics * trying to kick CI lint issues by upgrading mod * imprve test code and add hasher for testing * Use structure logging for filters, fix error constants, and default to allow all regex * removed hashin and modify logic to simplify * Improve race test and fix PR feedback by removing hash equals and avoid testing the timer.Ticker logic, and instead unit test * Ran make go-mod-tidy * Use errtypes in the test * Add changelog * add safety check for exporter endpoint * remove require.Contains by using error types, fix structure logging, and fix success metric typo in exporter * Fixed race test to have changing config values * Send success metric before modifying config * Avoid the defer and move the success metric under
100 lines
2.5 KiB
Go
100 lines
2.5 KiB
Go
package hcp
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/url"
|
|
"regexp"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/mock"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/hashicorp/consul/agent/hcp/client"
|
|
"github.com/hashicorp/consul/agent/hcp/telemetry"
|
|
)
|
|
|
|
type mockMetricsClient struct {
|
|
telemetry.MetricsClient
|
|
}
|
|
|
|
func TestSink(t *testing.T) {
|
|
t.Parallel()
|
|
for name, test := range map[string]struct {
|
|
expect func(*client.MockClient)
|
|
wantErr string
|
|
expectedSink bool
|
|
}{
|
|
"success": {
|
|
expect: func(mockClient *client.MockClient) {
|
|
u, _ := url.Parse("https://test.com/v1/metrics")
|
|
filters, _ := regexp.Compile("test")
|
|
mt := mockTelemetryConfig(1*time.Second, u, filters)
|
|
mockClient.EXPECT().FetchTelemetryConfig(mock.Anything).Return(mt, nil)
|
|
},
|
|
expectedSink: true,
|
|
},
|
|
"noSinkWhenFetchTelemetryConfigFails": {
|
|
expect: func(mockClient *client.MockClient) {
|
|
mockClient.EXPECT().FetchTelemetryConfig(mock.Anything).Return(nil, fmt.Errorf("fetch failed"))
|
|
},
|
|
wantErr: "failed to fetch telemetry config",
|
|
},
|
|
"noSinkWhenServerNotRegisteredWithCCM": {
|
|
expect: func(mockClient *client.MockClient) {
|
|
mt := mockTelemetryConfig(1*time.Second, nil, nil)
|
|
mockClient.EXPECT().FetchTelemetryConfig(mock.Anything).Return(mt, nil)
|
|
},
|
|
},
|
|
"noSinkWhenTelemetryConfigProviderInitFails": {
|
|
expect: func(mockClient *client.MockClient) {
|
|
u, _ := url.Parse("https://test.com/v1/metrics")
|
|
// Bad refresh interval forces ConfigProvider creation failure.
|
|
mt := mockTelemetryConfig(0*time.Second, u, nil)
|
|
mockClient.EXPECT().FetchTelemetryConfig(mock.Anything).Return(mt, nil)
|
|
},
|
|
wantErr: "failed to init config provider",
|
|
},
|
|
} {
|
|
test := test
|
|
t.Run(name, func(t *testing.T) {
|
|
t.Parallel()
|
|
c := client.NewMockClient(t)
|
|
mc := mockMetricsClient{}
|
|
|
|
test.expect(c)
|
|
ctx := context.Background()
|
|
|
|
s, err := sink(ctx, c, mc)
|
|
|
|
if test.wantErr != "" {
|
|
require.NotNil(t, err)
|
|
require.Contains(t, err.Error(), test.wantErr)
|
|
require.Nil(t, s)
|
|
return
|
|
}
|
|
|
|
if !test.expectedSink {
|
|
require.Nil(t, s)
|
|
require.Nil(t, err)
|
|
return
|
|
}
|
|
|
|
require.NotNil(t, s)
|
|
})
|
|
}
|
|
}
|
|
|
|
func mockTelemetryConfig(refreshInterval time.Duration, metricsEndpoint *url.URL, filters *regexp.Regexp) *client.TelemetryConfig {
|
|
return &client.TelemetryConfig{
|
|
MetricsConfig: &client.MetricsConfig{
|
|
Endpoint: metricsEndpoint,
|
|
Filters: filters,
|
|
},
|
|
RefreshConfig: &client.RefreshConfig{
|
|
RefreshInterval: refreshInterval,
|
|
},
|
|
}
|
|
}
|