From 8e0c43d095d3596ce309ad962e4e52bb6263bc91 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Fri, 9 Dec 2022 13:26:56 -0800 Subject: [PATCH] [chore] Remove telemetryInitializer from CollectorSettings This will allow to move deprecated Collector to otelcol. Signed-off-by: Bogdan Drutu --- service/collector.go | 27 +--- service/collector_test.go | 258 +------------------------------------ service/service.go | 12 ++ service/service_test.go | 262 ++++++++++++++++++++++++++++++++++++++ service/settings.go | 3 - 5 files changed, 281 insertions(+), 281 deletions(-) diff --git a/service/collector.go b/service/collector.go index ee1fad762dc..eab9630c1ed 100644 --- a/service/collector.go +++ b/service/collector.go @@ -28,7 +28,6 @@ import ( "go.uber.org/multierr" "go.uber.org/zap" - "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/service/internal/grpclog" ) @@ -76,17 +75,16 @@ func (s State) String() string { // Collector represents a server providing the OpenTelemetry Collector service. // Deprecated: [v0.67.0] use otelcol.Collector type Collector struct { - set CollectorSettings + set CollectorSettings + telemetry *telemetryInitializer service *service state *atomic.Int32 // shutdownChan is used to terminate the collector. shutdownChan chan struct{} - // signalsChannel is used to receive termination signals from the OS. signalsChannel chan os.Signal - // asyncErrorChannel is used to signal a fatal error from any component. asyncErrorChannel chan error } @@ -98,12 +96,9 @@ func New(set CollectorSettings) (*Collector, error) { return nil, errors.New("invalid nil config provider") } - if set.telemetry == nil { - set.telemetry = newColTelemetry(featuregate.GetRegistry()) - } - return &Collector{ set: set, + telemetry: newColTelemetry(featuregate.GetRegistry()), state: atomic.NewInt32(int32(StateStarting)), shutdownChan: make(chan struct{}), // Per signal.Notify documentation, a size of the channel equaled with @@ -150,7 +145,7 @@ func (col *Collector) setupConfigurationComponents(ctx context.Context) error { Config: cfg, AsyncErrorChannel: col.asyncErrorChannel, LoggingOptions: col.set.LoggingOptions, - telemetry: col.set.telemetry, + telemetry: col.telemetry, }) if err != nil { return err @@ -262,7 +257,7 @@ func (col *Collector) shutdownServiceAndTelemetry(ctx context.Context) error { // TODO: Move this as part of the service shutdown. // shutdown telemetryInitializer - if err := col.service.telemetryInitializer.shutdown(); err != nil { + if err := col.telemetry.shutdown(); err != nil { errs = multierr.Append(errs, fmt.Errorf("failed to shutdown collector telemetry: %w", err)) } return errs @@ -272,15 +267,3 @@ func (col *Collector) shutdownServiceAndTelemetry(ctx context.Context) error { func (col *Collector) setCollectorState(state State) { col.state.Store(int32(state)) } - -func getBallastSize(host component.Host) uint64 { - var ballastSize uint64 - extensions := host.GetExtensions() - for _, extension := range extensions { - if ext, ok := extension.(interface{ GetBallastSize() uint64 }); ok { - ballastSize = ext.GetBallastSize() - break - } - } - return ballastSize -} diff --git a/service/collector_test.go b/service/collector_test.go index 36e9dce4b6a..11ca02502e8 100644 --- a/service/collector_test.go +++ b/service/collector_test.go @@ -16,30 +16,21 @@ package service import ( - "bufio" "context" "errors" - "net/http" "path/filepath" - "strings" "sync" "syscall" "testing" "time" - "github.com/prometheus/common/expfmt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" - "go.opentelemetry.io/collector/confmap" - "go.opentelemetry.io/collector/extension/zpagesextension" "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/internal/obsreportconfig" - "go.opentelemetry.io/collector/internal/testutil" ) func TestStateString(t *testing.T) { @@ -61,7 +52,6 @@ func TestCollectorStartAsGoRoutine(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: cfgProvider, - telemetry: newColTelemetry(featuregate.NewRegistry()), } col, err := New(set) require.NoError(t, err) @@ -89,7 +79,6 @@ func TestCollectorCancelContext(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: cfgProvider, - telemetry: newColTelemetry(featuregate.NewRegistry()), } col, err := New(set) require.NoError(t, err) @@ -127,7 +116,6 @@ func TestCollectorStateAfterConfigChange(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: &mockCfgProvider{ConfigProvider: provider, watcher: watcher}, - telemetry: newColTelemetry(featuregate.NewRegistry()), }) require.NoError(t, err) @@ -160,7 +148,6 @@ func TestCollectorReportError(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: cfgProvider, - telemetry: newColTelemetry(featuregate.NewRegistry()), }) require.NoError(t, err) @@ -187,7 +174,6 @@ func TestCollectorSendSignal(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: cfgProvider, - telemetry: newColTelemetry(featuregate.NewRegistry()), }) require.NoError(t, err) @@ -221,7 +207,6 @@ func TestCollectorFailedShutdown(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: cfgProvider, - telemetry: newColTelemetry(featuregate.NewRegistry()), }) require.NoError(t, err) @@ -253,178 +238,13 @@ func TestCollectorStartInvalidConfig(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: cfgProvider, - telemetry: newColTelemetry(featuregate.NewRegistry()), }) require.NoError(t, err) assert.Error(t, col.Run(context.Background())) } -// mapConverter applies extraMap of config settings. Useful for overriding the config -// for testing purposes. Keys must use "::" delimiter between levels. -type mapConverter struct { - extraMap map[string]interface{} -} - -func (m mapConverter) Convert(ctx context.Context, conf *confmap.Conf) error { - return conf.Merge(confmap.NewFromStringMap(m.extraMap)) -} - -type labelState int - -const ( - labelNotPresent labelState = iota - labelSpecificValue - labelAnyValue -) - -type labelValue struct { - label string - state labelState -} - -type ownMetricsTestCase struct { - name string - userDefinedResource map[string]*string - expectedLabels map[string]labelValue -} - -var testResourceAttrValue = "resource_attr_test_value" -var testInstanceID = "test_instance_id" -var testServiceVersion = "2022-05-20" - -func ownMetricsTestCases(version string) []ownMetricsTestCase { - return []ownMetricsTestCase{{ - name: "no resource", - userDefinedResource: nil, - // All labels added to all collector metrics by default are listed below. - // These labels are hard coded here in order to avoid inadvertent changes: - // at this point changing labels should be treated as a breaking changing - // and requires a good justification. The reason is that changes to metric - // names or labels can break alerting, dashboards, etc that are used to - // monitor the Collector in production deployments. - expectedLabels: map[string]labelValue{ - "service_instance_id": {state: labelAnyValue}, - "service_version": {label: version, state: labelSpecificValue}, - }, - }, - { - name: "resource with custom attr", - userDefinedResource: map[string]*string{ - "custom_resource_attr": &testResourceAttrValue, - }, - expectedLabels: map[string]labelValue{ - "service_instance_id": {state: labelAnyValue}, - "service_version": {label: version, state: labelSpecificValue}, - "custom_resource_attr": {label: "resource_attr_test_value", state: labelSpecificValue}, - }, - }, - { - name: "override service.instance.id", - userDefinedResource: map[string]*string{ - "service.instance.id": &testInstanceID, - }, - expectedLabels: map[string]labelValue{ - "service_instance_id": {label: "test_instance_id", state: labelSpecificValue}, - "service_version": {label: version, state: labelSpecificValue}, - }, - }, - { - name: "suppress service.instance.id", - userDefinedResource: map[string]*string{ - "service.instance.id": nil, // nil value in config is used to suppress attributes. - }, - expectedLabels: map[string]labelValue{ - "service_instance_id": {state: labelNotPresent}, - "service_version": {label: version, state: labelSpecificValue}, - }, - }, - { - name: "override service.version", - userDefinedResource: map[string]*string{ - "service.version": &testServiceVersion, - }, - expectedLabels: map[string]labelValue{ - "service_instance_id": {state: labelAnyValue}, - "service_version": {label: "2022-05-20", state: labelSpecificValue}, - }, - }, - { - name: "suppress service.version", - userDefinedResource: map[string]*string{ - "service.version": nil, // nil value in config is used to suppress attributes. - }, - expectedLabels: map[string]labelValue{ - "service_instance_id": {state: labelAnyValue}, - "service_version": {state: labelNotPresent}, - }, - }} -} - -func testCollectorStartHelper(t *testing.T, telemetry *telemetryInitializer, tc ownMetricsTestCase) { - factories, err := componenttest.NopFactories() - zpagesExt := zpagesextension.NewFactory() - factories.Extensions[zpagesExt.Type()] = zpagesExt - require.NoError(t, err) - var once sync.Once - loggingHookCalled := false - hook := func(entry zapcore.Entry) error { - once.Do(func() { - loggingHookCalled = true - }) - return nil - } - - metricsAddr := testutil.GetAvailableLocalAddress(t) - zpagesAddr := testutil.GetAvailableLocalAddress(t) - // Prepare config properties to be merged with the main config. - extraCfgAsProps := map[string]interface{}{ - // Setup the zpages extension. - "extensions::zpages::endpoint": zpagesAddr, - "service::extensions": "nop, zpages", - // Set the metrics address to expose own metrics on. - "service::telemetry::metrics::address": metricsAddr, - } - // Also include resource attributes under the service::telemetry::resource key. - for k, v := range tc.userDefinedResource { - extraCfgAsProps["service::telemetry::resource::"+k] = v - } - - cfgSet := newDefaultConfigProviderSettings([]string{filepath.Join("testdata", "otelcol-nop.yaml")}) - cfgSet.ResolverSettings.Converters = append([]confmap.Converter{ - mapConverter{extraCfgAsProps}}, - cfgSet.ResolverSettings.Converters..., - ) - cfgProvider, err := NewConfigProvider(cfgSet) - require.NoError(t, err) - - col, err := New(CollectorSettings{ - BuildInfo: component.BuildInfo{Version: "test version"}, - Factories: factories, - ConfigProvider: cfgProvider, - LoggingOptions: []zap.Option{zap.Hooks(hook)}, - telemetry: telemetry, - }) - require.NoError(t, err) - - wg := startCollector(context.Background(), t, col) - - assert.Eventually(t, func() bool { - return StateRunning == col.GetState() - }, 2*time.Second, 200*time.Millisecond) - assert.True(t, loggingHookCalled) - - assertMetrics(t, metricsAddr, tc.expectedLabels) - - assertZPages(t, zpagesAddr) - - col.Shutdown() - - wg.Wait() - assert.Equal(t, StateClosed, col.GetState()) -} - func TestCollectorStartWithOpenCensusMetrics(t *testing.T) { - for _, tc := range ownMetricsTestCases("test version") { + for _, tc := range ownMetricsTestCases() { t.Run(tc.name, func(t *testing.T) { testCollectorStartHelper(t, newColTelemetry(featuregate.NewRegistry()), tc) }) @@ -432,7 +252,7 @@ func TestCollectorStartWithOpenCensusMetrics(t *testing.T) { } func TestCollectorStartWithOpenTelemetryMetrics(t *testing.T) { - for _, tc := range ownMetricsTestCases("test version") { + for _, tc := range ownMetricsTestCases() { t.Run(tc.name, func(t *testing.T) { registry := featuregate.NewRegistry() obsreportconfig.RegisterInternalMetricFeatureGate(registry) @@ -465,7 +285,6 @@ func TestCollectorStartWithTraceContextPropagation(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: cfgProvider, - telemetry: newColTelemetry(featuregate.NewRegistry()), } col, err := New(set) @@ -504,7 +323,6 @@ func TestCollectorRun(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: cfgProvider, - telemetry: newColTelemetry(featuregate.NewRegistry()), } col, err := New(set) require.NoError(t, err) @@ -529,7 +347,6 @@ func TestCollectorShutdownBeforeRun(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: cfgProvider, - telemetry: newColTelemetry(featuregate.NewRegistry()), } col, err := New(set) require.NoError(t, err) @@ -556,7 +373,6 @@ func TestCollectorClosedStateOnStartUpError(t *testing.T) { BuildInfo: component.NewDefaultBuildInfo(), Factories: factories, ConfigProvider: cfgProvider, - telemetry: newColTelemetry(featuregate.NewRegistry()), } col, err := New(set) require.NoError(t, err) @@ -568,76 +384,6 @@ func TestCollectorClosedStateOnStartUpError(t *testing.T) { assert.Equal(t, StateClosed, col.GetState()) } -func assertMetrics(t *testing.T, metricsAddr string, expectedLabels map[string]labelValue) { - client := &http.Client{} - resp, err := client.Get("http://" + metricsAddr + "/metrics") - require.NoError(t, err) - - t.Cleanup(func() { - assert.NoError(t, resp.Body.Close()) - }) - reader := bufio.NewReader(resp.Body) - - var parser expfmt.TextParser - parsed, err := parser.TextToMetricFamilies(reader) - require.NoError(t, err) - - prefix := "otelcol" - for metricName, metricFamily := range parsed { - // require is used here so test fails with a single message. - require.True( - t, - strings.HasPrefix(metricName, prefix), - "expected prefix %q but string starts with %q", - prefix, - metricName[:len(prefix)+1]+"...") - - for _, metric := range metricFamily.Metric { - labelMap := map[string]string{} - for _, labelPair := range metric.Label { - labelMap[*labelPair.Name] = *labelPair.Value - } - - for k, v := range expectedLabels { - switch v.state { - case labelNotPresent: - _, present := labelMap[k] - assert.Falsef(t, present, "label %q must not be present", k) - case labelSpecificValue: - require.Equalf(t, v.label, labelMap[k], "mandatory label %q value mismatch", k) - case labelAnyValue: - assert.NotEmptyf(t, labelMap[k], "mandatory label %q not present", k) - } - } - } - } -} - -func assertZPages(t *testing.T, zpagesAddr string) { - paths := []string{ - "/debug/tracez", - // TODO: enable this when otel-metrics is used and this page is available. - // "/debug/rpcz", - "/debug/pipelinez", - "/debug/servicez", - "/debug/extensionz", - } - - testZPagePathFn := func(t *testing.T, path string) { - client := &http.Client{} - resp, err := client.Get("http://" + zpagesAddr + path) - if !assert.NoError(t, err, "error retrieving zpage at %q", path) { - return - } - assert.Equal(t, http.StatusOK, resp.StatusCode, "unsuccessful zpage %q GET", path) - assert.NoError(t, resp.Body.Close()) - } - - for _, path := range paths { - testZPagePathFn(t, path) - } -} - func startCollector(ctx context.Context, t *testing.T, col *Collector) *sync.WaitGroup { wg := &sync.WaitGroup{} wg.Add(1) diff --git a/service/service.go b/service/service.go index 92b42dd536e..5e87429d1cd 100644 --- a/service/service.go +++ b/service/service.go @@ -171,3 +171,15 @@ func (srv *service) initExtensionsAndPipeline(set *settings) error { return nil } + +func getBallastSize(host component.Host) uint64 { + var ballastSize uint64 + extensions := host.GetExtensions() + for _, extension := range extensions { + if ext, ok := extension.(interface{ GetBallastSize() uint64 }); ok { + ballastSize = ext.GetBallastSize() + break + } + } + return ballastSize +} diff --git a/service/service_test.go b/service/service_test.go index c65d322a80b..d8105d1a7f3 100644 --- a/service/service_test.go +++ b/service/service_test.go @@ -15,20 +15,124 @@ package service import ( + "bufio" "context" "fmt" "net/http" "path/filepath" + "strings" + "sync" "testing" + "time" + "github.com/prometheus/common/expfmt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/extension/zpagesextension" "go.opentelemetry.io/collector/featuregate" + "go.opentelemetry.io/collector/internal/obsreportconfig" + "go.opentelemetry.io/collector/internal/testutil" ) +type labelState int + +const ( + labelNotPresent labelState = iota + labelSpecificValue + labelAnyValue +) + +type labelValue struct { + label string + state labelState +} + +type ownMetricsTestCase struct { + name string + userDefinedResource map[string]*string + expectedLabels map[string]labelValue +} + +var testResourceAttrValue = "resource_attr_test_value" +var testInstanceID = "test_instance_id" +var testServiceVersion = "2022-05-20" + +const metricsVersion = "test version" + +func ownMetricsTestCases() []ownMetricsTestCase { + return []ownMetricsTestCase{{ + name: "no resource", + userDefinedResource: nil, + // All labels added to all collector metrics by default are listed below. + // These labels are hard coded here in order to avoid inadvertent changes: + // at this point changing labels should be treated as a breaking changing + // and requires a good justification. The reason is that changes to metric + // names or labels can break alerting, dashboards, etc that are used to + // monitor the Collector in production deployments. + expectedLabels: map[string]labelValue{ + "service_instance_id": {state: labelAnyValue}, + "service_version": {label: metricsVersion, state: labelSpecificValue}, + }, + }, + { + name: "resource with custom attr", + userDefinedResource: map[string]*string{ + "custom_resource_attr": &testResourceAttrValue, + }, + expectedLabels: map[string]labelValue{ + "service_instance_id": {state: labelAnyValue}, + "service_version": {label: metricsVersion, state: labelSpecificValue}, + "custom_resource_attr": {label: "resource_attr_test_value", state: labelSpecificValue}, + }, + }, + { + name: "override service.instance.id", + userDefinedResource: map[string]*string{ + "service.instance.id": &testInstanceID, + }, + expectedLabels: map[string]labelValue{ + "service_instance_id": {label: "test_instance_id", state: labelSpecificValue}, + "service_version": {label: metricsVersion, state: labelSpecificValue}, + }, + }, + { + name: "suppress service.instance.id", + userDefinedResource: map[string]*string{ + "service.instance.id": nil, // nil value in config is used to suppress attributes. + }, + expectedLabels: map[string]labelValue{ + "service_instance_id": {state: labelNotPresent}, + "service_version": {label: metricsVersion, state: labelSpecificValue}, + }, + }, + { + name: "override service.version", + userDefinedResource: map[string]*string{ + "service.version": &testServiceVersion, + }, + expectedLabels: map[string]labelValue{ + "service_instance_id": {state: labelAnyValue}, + "service_version": {label: "2022-05-20", state: labelSpecificValue}, + }, + }, + { + name: "suppress service.version", + userDefinedResource: map[string]*string{ + "service.version": nil, // nil value in config is used to suppress attributes. + }, + expectedLabels: map[string]labelValue{ + "service_instance_id": {state: labelAnyValue}, + "service_version": {state: labelNotPresent}, + }, + }} +} + func TestService_GetFactory(t *testing.T) { factories, err := componenttest.NopFactories() require.NoError(t, err) @@ -135,7 +239,85 @@ func TestServiceTelemetryCleanupOnError(t *testing.T) { assert.NoError(t, telemetryTwo.shutdown()) assert.NoError(t, srv.Shutdown(context.Background())) }) +} +func TestServiceTelemetryWithOpenCensusMetrics(t *testing.T) { + for _, tc := range ownMetricsTestCases() { + t.Run(tc.name, func(t *testing.T) { + testCollectorStartHelper(t, newColTelemetry(featuregate.NewRegistry()), tc) + }) + } +} + +func TestServiceTelemetryWithOpenTelemetryMetrics(t *testing.T) { + for _, tc := range ownMetricsTestCases() { + t.Run(tc.name, func(t *testing.T) { + registry := featuregate.NewRegistry() + obsreportconfig.RegisterInternalMetricFeatureGate(registry) + colTel := newColTelemetry(registry) + require.NoError(t, colTel.registry.Apply(map[string]bool{obsreportconfig.UseOtelForInternalMetricsfeatureGateID: true})) + testCollectorStartHelper(t, colTel, tc) + }) + } +} + +func testCollectorStartHelper(t *testing.T, telemetry *telemetryInitializer, tc ownMetricsTestCase) { + factories, err := componenttest.NopFactories() + zpagesExt := zpagesextension.NewFactory() + factories.Extensions[zpagesExt.Type()] = zpagesExt + require.NoError(t, err) + var once sync.Once + loggingHookCalled := false + hook := func(entry zapcore.Entry) error { + once.Do(func() { + loggingHookCalled = true + }) + return nil + } + + metricsAddr := testutil.GetAvailableLocalAddress(t) + zpagesAddr := testutil.GetAvailableLocalAddress(t) + // Prepare config properties to be merged with the main config. + extraCfgAsProps := map[string]interface{}{ + // Setup the zpages extension. + "extensions::zpages::endpoint": zpagesAddr, + "service::extensions": "nop, zpages", + // Set the metrics address to expose own metrics on. + "service::telemetry::metrics::address": metricsAddr, + } + // Also include resource attributes under the service::telemetry::resource key. + for k, v := range tc.userDefinedResource { + extraCfgAsProps["service::telemetry::resource::"+k] = v + } + + cfgSet := newDefaultConfigProviderSettings([]string{filepath.Join("testdata", "otelcol-nop.yaml")}) + cfgSet.ResolverSettings.Converters = append([]confmap.Converter{ + mapConverter{extraCfgAsProps}}, + cfgSet.ResolverSettings.Converters..., + ) + cfgProvider, err := NewConfigProvider(cfgSet) + require.NoError(t, err) + + cfg, err := cfgProvider.Get(context.Background(), factories) + require.NoError(t, err) + + srv, err := newService(&settings{ + BuildInfo: component.BuildInfo{Version: "test version"}, + Factories: factories, + Config: cfg, + LoggingOptions: []zap.Option{zap.Hooks(hook)}, + telemetry: telemetry, + }) + require.NoError(t, err) + + require.NoError(t, srv.Start(context.Background())) + // Sleep for 1 second to ensure the http server is started. + time.Sleep(1 * time.Second) + assert.True(t, loggingHookCalled) + assertMetrics(t, metricsAddr, tc.expectedLabels) + assertZPages(t, zpagesAddr) + require.NoError(t, srv.Shutdown(context.Background())) + require.NoError(t, telemetry.shutdown()) } // TestServiceTelemetryReusable tests that a single telemetryInitializer can be reused in multiple services @@ -223,3 +405,83 @@ func createExampleService(t *testing.T, factories component.Factories) *service }) return srv } + +func assertMetrics(t *testing.T, metricsAddr string, expectedLabels map[string]labelValue) { + client := &http.Client{} + resp, err := client.Get("http://" + metricsAddr + "/metrics") + require.NoError(t, err) + + t.Cleanup(func() { + assert.NoError(t, resp.Body.Close()) + }) + reader := bufio.NewReader(resp.Body) + + var parser expfmt.TextParser + parsed, err := parser.TextToMetricFamilies(reader) + require.NoError(t, err) + + prefix := "otelcol" + for metricName, metricFamily := range parsed { + // require is used here so test fails with a single message. + require.True( + t, + strings.HasPrefix(metricName, prefix), + "expected prefix %q but string starts with %q", + prefix, + metricName[:len(prefix)+1]+"...") + + for _, metric := range metricFamily.Metric { + labelMap := map[string]string{} + for _, labelPair := range metric.Label { + labelMap[*labelPair.Name] = *labelPair.Value + } + + for k, v := range expectedLabels { + switch v.state { + case labelNotPresent: + _, present := labelMap[k] + assert.Falsef(t, present, "label %q must not be present", k) + case labelSpecificValue: + require.Equalf(t, v.label, labelMap[k], "mandatory label %q value mismatch", k) + case labelAnyValue: + assert.NotEmptyf(t, labelMap[k], "mandatory label %q not present", k) + } + } + } + } +} + +func assertZPages(t *testing.T, zpagesAddr string) { + paths := []string{ + "/debug/tracez", + // TODO: enable this when otel-metrics is used and this page is available. + // "/debug/rpcz", + "/debug/pipelinez", + "/debug/servicez", + "/debug/extensionz", + } + + testZPagePathFn := func(t *testing.T, path string) { + client := &http.Client{} + resp, err := client.Get("http://" + zpagesAddr + path) + if !assert.NoError(t, err, "error retrieving zpage at %q", path) { + return + } + assert.Equal(t, http.StatusOK, resp.StatusCode, "unsuccessful zpage %q GET", path) + assert.NoError(t, resp.Body.Close()) + } + + for _, path := range paths { + testZPagePathFn(t, path) + } +} + +// mapConverter applies extraMap of config settings. Useful for overriding the config +// for testing purposes. Keys must use "::" delimiter between levels. +type mapConverter struct { + extraMap map[string]interface{} +} + +func (m mapConverter) Convert(ctx context.Context, conf *confmap.Conf) error { + return conf.Merge(confmap.NewFromStringMap(m.extraMap)) +} diff --git a/service/settings.go b/service/settings.go index 0301a4cb056..e77a14cb47c 100644 --- a/service/settings.go +++ b/service/settings.go @@ -65,7 +65,4 @@ type CollectorSettings struct { // SkipSettingGRPCLogger avoids setting the grpc logger SkipSettingGRPCLogger bool - - // For testing purpose only. - telemetry *telemetryInitializer }