From eda1132955d52d0c4fdac6d45118715c634167b3 Mon Sep 17 00:00:00 2001 From: Dmitrii Anoshin <anoshindx@gmail.com> Date: Thu, 29 Feb 2024 13:46:33 -0800 Subject: [PATCH] [chore] [cmd/mdatagen] Move sample-metadata.yaml to a separate package (#31503) Create a separate internal sample receiver to generate and validate code with mdatagen, including lifecycle tests. --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/feature_request.yaml | 1 + .github/ISSUE_TEMPLATE/other.yaml | 1 + cmd/mdatagen/go.mod | 2 +- .../{ => internal/samplereceiver}/doc.go | 5 +- .../samplereceiver}/documentation.md | 2 +- .../internal/samplereceiver/factory.go | 43 +++++++++ .../generated_component_test.go | 87 +++++++++++++++++++ .../internal}/metadata/generated_config.go | 6 +- .../metadata/generated_config_test.go | 0 .../internal}/metadata/generated_metrics.go | 2 +- .../metadata/generated_metrics_test.go | 0 .../internal}/metadata/generated_resource.go | 0 .../metadata/generated_resource_test.go | 0 .../internal}/metadata/generated_status.go | 6 +- .../internal}/metadata/testdata/config.yaml | 0 .../samplereceiver/metadata.yaml} | 11 ++- .../internal/samplereceiver/metrics_test.go | 20 +++++ cmd/mdatagen/loader_test.go | 16 ++-- cmd/mdatagen/main_test.go | 10 --- .../{internal/metadata => }/package_test.go | 2 +- 21 files changed, 184 insertions(+), 31 deletions(-) rename cmd/mdatagen/{ => internal/samplereceiver}/doc.go (74%) rename cmd/mdatagen/{ => internal/samplereceiver}/documentation.md (99%) create mode 100644 cmd/mdatagen/internal/samplereceiver/factory.go create mode 100644 cmd/mdatagen/internal/samplereceiver/generated_component_test.go rename cmd/mdatagen/internal/{ => samplereceiver/internal}/metadata/generated_config.go (94%) rename cmd/mdatagen/internal/{ => samplereceiver/internal}/metadata/generated_config_test.go (100%) rename cmd/mdatagen/internal/{ => samplereceiver/internal}/metadata/generated_metrics.go (99%) rename cmd/mdatagen/internal/{ => samplereceiver/internal}/metadata/generated_metrics_test.go (100%) rename cmd/mdatagen/internal/{ => samplereceiver/internal}/metadata/generated_resource.go (100%) rename cmd/mdatagen/internal/{ => samplereceiver/internal}/metadata/generated_resource_test.go (100%) rename cmd/mdatagen/internal/{ => samplereceiver/internal}/metadata/generated_status.go (74%) rename cmd/mdatagen/internal/{ => samplereceiver/internal}/metadata/testdata/config.yaml (100%) rename cmd/mdatagen/{metadata-sample.yaml => internal/samplereceiver/metadata.yaml} (95%) create mode 100644 cmd/mdatagen/internal/samplereceiver/metrics_test.go rename cmd/mdatagen/{internal/metadata => }/package_test.go (91%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 075fdb8db139..3e0845764b2c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -21,6 +21,7 @@ body: - cmd/configschema - cmd/githubgen - cmd/mdatagen + - cmd/mdatagen/internal/samplereceiver - cmd/opampsupervisor - cmd/otelcontribcol - cmd/oteltestbedcol diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index 289ab9cf4893..7162377a6777 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -15,6 +15,7 @@ body: - cmd/configschema - cmd/githubgen - cmd/mdatagen + - cmd/mdatagen/internal/samplereceiver - cmd/opampsupervisor - cmd/otelcontribcol - cmd/oteltestbedcol diff --git a/.github/ISSUE_TEMPLATE/other.yaml b/.github/ISSUE_TEMPLATE/other.yaml index 36e090859fa0..e0eb9a0d1c42 100644 --- a/.github/ISSUE_TEMPLATE/other.yaml +++ b/.github/ISSUE_TEMPLATE/other.yaml @@ -15,6 +15,7 @@ body: - cmd/configschema - cmd/githubgen - cmd/mdatagen + - cmd/mdatagen/internal/samplereceiver - cmd/opampsupervisor - cmd/otelcontribcol - cmd/oteltestbedcol diff --git a/cmd/mdatagen/go.mod b/cmd/mdatagen/go.mod index b78c74f2f423..e5a75faa0f69 100644 --- a/cmd/mdatagen/go.mod +++ b/cmd/mdatagen/go.mod @@ -9,6 +9,7 @@ require ( go.opentelemetry.io/collector/component v0.95.0 go.opentelemetry.io/collector/confmap v0.95.0 go.opentelemetry.io/collector/confmap/provider/fileprovider v0.95.0 + go.opentelemetry.io/collector/consumer v0.95.0 go.opentelemetry.io/collector/pdata v1.2.0 go.opentelemetry.io/collector/receiver v0.95.0 go.opentelemetry.io/collector/semconv v0.95.0 @@ -44,7 +45,6 @@ require ( github.com/prometheus/common v0.46.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect go.opentelemetry.io/collector/config/configtelemetry v0.95.0 // indirect - go.opentelemetry.io/collector/consumer v0.95.0 // indirect go.opentelemetry.io/otel v1.23.1 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.45.2 // indirect go.opentelemetry.io/otel/sdk v1.23.1 // indirect diff --git a/cmd/mdatagen/doc.go b/cmd/mdatagen/internal/samplereceiver/doc.go similarity index 74% rename from cmd/mdatagen/doc.go rename to cmd/mdatagen/internal/samplereceiver/doc.go index 61e6ac8f7d59..12febf6e4aa2 100644 --- a/cmd/mdatagen/doc.go +++ b/cmd/mdatagen/internal/samplereceiver/doc.go @@ -2,8 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 // Generate a test metrics builder from a sample metrics set covering all configuration options. -//go:generate mdatagen metadata-sample.yaml +//go:generate mdatagen metadata.yaml // Deprecated: This package is moving to https://github.com/open-telemetry/opentelemetry-collector and will eventually be removed. // Please see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/30497 -package main +// This is a sample receiver package used to showcase how mdatagen is applied. +package samplereceiver diff --git a/cmd/mdatagen/documentation.md b/cmd/mdatagen/internal/samplereceiver/documentation.md similarity index 99% rename from cmd/mdatagen/documentation.md rename to cmd/mdatagen/internal/samplereceiver/documentation.md index 1955e0815351..0e29d896d669 100644 --- a/cmd/mdatagen/documentation.md +++ b/cmd/mdatagen/internal/samplereceiver/documentation.md @@ -1,6 +1,6 @@ [comment]: <> (Code generated by mdatagen. DO NOT EDIT.) -# file +# sample ## Default Metrics diff --git a/cmd/mdatagen/internal/samplereceiver/factory.go b/cmd/mdatagen/internal/samplereceiver/factory.go new file mode 100644 index 000000000000..375010bf3f24 --- /dev/null +++ b/cmd/mdatagen/internal/samplereceiver/factory.go @@ -0,0 +1,43 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package samplereceiver + +import ( + "context" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/receiver" + + "github.com/open-telemetry/opentelemetry-collector-contrib/cmd/mdatagen/internal/samplereceiver/internal/metadata" +) + +// NewFactory returns a receiver.Factory for sample receiver. +func NewFactory() receiver.Factory { + return receiver.NewFactory( + metadata.Type, + func() component.Config { return &struct{}{} }, + receiver.WithTraces(createTraces, metadata.TracesStability), + receiver.WithMetrics(createMetrics, metadata.MetricsStability), + receiver.WithLogs(createLogs, metadata.LogsStability)) +} + +func createTraces(context.Context, receiver.CreateSettings, component.Config, consumer.Traces) (receiver.Traces, error) { + return nopInstance, nil +} + +func createMetrics(context.Context, receiver.CreateSettings, component.Config, consumer.Metrics) (receiver.Metrics, error) { + return nopInstance, nil +} + +func createLogs(context.Context, receiver.CreateSettings, component.Config, consumer.Logs) (receiver.Logs, error) { + return nopInstance, nil +} + +var nopInstance = &nopReceiver{} + +type nopReceiver struct { + component.StartFunc + component.ShutdownFunc +} diff --git a/cmd/mdatagen/internal/samplereceiver/generated_component_test.go b/cmd/mdatagen/internal/samplereceiver/generated_component_test.go new file mode 100644 index 000000000000..07ab63c3b46a --- /dev/null +++ b/cmd/mdatagen/internal/samplereceiver/generated_component_test.go @@ -0,0 +1,87 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package samplereceiver + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" + + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/receiver" + "go.opentelemetry.io/collector/receiver/receivertest" + + "go.opentelemetry.io/collector/confmap/confmaptest" +) + +// assertNoErrorHost implements a component.Host that asserts that there were no errors. +type assertNoErrorHost struct { + component.Host + *testing.T +} + +var _ component.Host = (*assertNoErrorHost)(nil) + +func TestComponentLifecycle(t *testing.T) { + factory := NewFactory() + + tests := []struct { + name string + createFn func(ctx context.Context, set receiver.CreateSettings, cfg component.Config) (component.Component, error) + }{ + + { + name: "logs", + createFn: func(ctx context.Context, set receiver.CreateSettings, cfg component.Config) (component.Component, error) { + return factory.CreateLogsReceiver(ctx, set, cfg, consumertest.NewNop()) + }, + }, + + { + name: "metrics", + createFn: func(ctx context.Context, set receiver.CreateSettings, cfg component.Config) (component.Component, error) { + return factory.CreateMetricsReceiver(ctx, set, cfg, consumertest.NewNop()) + }, + }, + + { + name: "traces", + createFn: func(ctx context.Context, set receiver.CreateSettings, cfg component.Config) (component.Component, error) { + return factory.CreateTracesReceiver(ctx, set, cfg, consumertest.NewNop()) + }, + }, + } + + cm, err := confmaptest.LoadConf("metadata.yaml") + require.NoError(t, err) + cfg := factory.CreateDefaultConfig() + sub, err := cm.Sub("tests::config") + require.NoError(t, err) + require.NoError(t, component.UnmarshalConfig(sub, cfg)) + + for _, test := range tests { + t.Run(test.name+"-shutdown", func(t *testing.T) { + c, err := test.createFn(context.Background(), receivertest.NewNopCreateSettings(), cfg) + require.NoError(t, err) + err = c.Shutdown(context.Background()) + require.NoError(t, err) + }) + + t.Run(test.name+"-lifecycle", func(t *testing.T) { + + firstRcvr, err := test.createFn(context.Background(), receivertest.NewNopCreateSettings(), cfg) + require.NoError(t, err) + host := componenttest.NewNopHost() + require.NoError(t, err) + require.NoError(t, firstRcvr.Start(context.Background(), host)) + require.NoError(t, firstRcvr.Shutdown(context.Background())) + secondRcvr, err := test.createFn(context.Background(), receivertest.NewNopCreateSettings(), cfg) + require.NoError(t, err) + require.NoError(t, secondRcvr.Start(context.Background(), host)) + require.NoError(t, secondRcvr.Shutdown(context.Background())) + }) + } +} diff --git a/cmd/mdatagen/internal/metadata/generated_config.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config.go similarity index 94% rename from cmd/mdatagen/internal/metadata/generated_config.go rename to cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config.go index 92937f48dbfd..eb00e302065c 100644 --- a/cmd/mdatagen/internal/metadata/generated_config.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config.go @@ -23,7 +23,7 @@ func (ms *MetricConfig) Unmarshal(parser *confmap.Conf) error { return nil } -// MetricsConfig provides config for file metrics. +// MetricsConfig provides config for sample metrics. type MetricsConfig struct { DefaultMetric MetricConfig `mapstructure:"default.metric"` DefaultMetricToBeRemoved MetricConfig `mapstructure:"default.metric.to_be_removed"` @@ -67,7 +67,7 @@ func (rac *ResourceAttributeConfig) Unmarshal(parser *confmap.Conf) error { return nil } -// ResourceAttributesConfig provides config for file resource attributes. +// ResourceAttributesConfig provides config for sample resource attributes. type ResourceAttributesConfig struct { MapResourceAttr ResourceAttributeConfig `mapstructure:"map.resource.attr"` OptionalResourceAttr ResourceAttributeConfig `mapstructure:"optional.resource.attr"` @@ -108,7 +108,7 @@ func DefaultResourceAttributesConfig() ResourceAttributesConfig { } } -// MetricsBuilderConfig is a configuration for file metrics builder. +// MetricsBuilderConfig is a configuration for sample metrics builder. type MetricsBuilderConfig struct { Metrics MetricsConfig `mapstructure:"metrics"` ResourceAttributes ResourceAttributesConfig `mapstructure:"resource_attributes"` diff --git a/cmd/mdatagen/internal/metadata/generated_config_test.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config_test.go similarity index 100% rename from cmd/mdatagen/internal/metadata/generated_config_test.go rename to cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_config_test.go diff --git a/cmd/mdatagen/internal/metadata/generated_metrics.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics.go similarity index 99% rename from cmd/mdatagen/internal/metadata/generated_metrics.go rename to cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics.go index a52195c69df9..b9b9c65da0bb 100644 --- a/cmd/mdatagen/internal/metadata/generated_metrics.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics.go @@ -368,7 +368,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) ils := rm.ScopeMetrics().AppendEmpty() - ils.Scope().SetName("otelcol") + ils.Scope().SetName("otelcol/samplereceiver") ils.Scope().SetVersion(mb.buildInfo.Version) ils.Metrics().EnsureCapacity(mb.metricsCapacity) mb.metricDefaultMetric.emit(ils.Metrics()) diff --git a/cmd/mdatagen/internal/metadata/generated_metrics_test.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics_test.go similarity index 100% rename from cmd/mdatagen/internal/metadata/generated_metrics_test.go rename to cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_metrics_test.go diff --git a/cmd/mdatagen/internal/metadata/generated_resource.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_resource.go similarity index 100% rename from cmd/mdatagen/internal/metadata/generated_resource.go rename to cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_resource.go diff --git a/cmd/mdatagen/internal/metadata/generated_resource_test.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_resource_test.go similarity index 100% rename from cmd/mdatagen/internal/metadata/generated_resource_test.go rename to cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_resource_test.go diff --git a/cmd/mdatagen/internal/metadata/generated_status.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_status.go similarity index 74% rename from cmd/mdatagen/internal/metadata/generated_status.go rename to cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_status.go index 429ff354c01b..27982a5943fe 100644 --- a/cmd/mdatagen/internal/metadata/generated_status.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_status.go @@ -9,7 +9,7 @@ import ( ) var ( - Type = component.MustNewType("file") + Type = component.MustNewType("sample") ) const ( @@ -19,9 +19,9 @@ const ( ) func Meter(settings component.TelemetrySettings) metric.Meter { - return settings.MeterProvider.Meter("otelcol") + return settings.MeterProvider.Meter("otelcol/samplereceiver") } func Tracer(settings component.TelemetrySettings) trace.Tracer { - return settings.TracerProvider.Tracer("otelcol") + return settings.TracerProvider.Tracer("otelcol/samplereceiver") } diff --git a/cmd/mdatagen/internal/metadata/testdata/config.yaml b/cmd/mdatagen/internal/samplereceiver/internal/metadata/testdata/config.yaml similarity index 100% rename from cmd/mdatagen/internal/metadata/testdata/config.yaml rename to cmd/mdatagen/internal/samplereceiver/internal/metadata/testdata/config.yaml diff --git a/cmd/mdatagen/metadata-sample.yaml b/cmd/mdatagen/internal/samplereceiver/metadata.yaml similarity index 95% rename from cmd/mdatagen/metadata-sample.yaml rename to cmd/mdatagen/internal/samplereceiver/metadata.yaml index b9a5f8f6c908..8c32d9f382b8 100644 --- a/cmd/mdatagen/metadata-sample.yaml +++ b/cmd/mdatagen/internal/samplereceiver/metadata.yaml @@ -1,6 +1,6 @@ -# Sample metric metadata file with all available configurations. +# Sample metadata file with all available configurations for a receiver. -type: file +type: sample sem_conv_version: 1.9.0 @@ -10,7 +10,9 @@ status: development: [logs] beta: [traces] stable: [metrics] - distributions: [contrib] + distributions: [] + codeowners: + active: [dmitryax] warnings: - Any additional information that should be brought to the consumer's attention @@ -134,3 +136,6 @@ metrics: aggregation_temporality: delta warnings: if_enabled: This metric is deprecated and will be removed soon. + +tests: + config: diff --git a/cmd/mdatagen/internal/samplereceiver/metrics_test.go b/cmd/mdatagen/internal/samplereceiver/metrics_test.go new file mode 100644 index 000000000000..668e493a9f39 --- /dev/null +++ b/cmd/mdatagen/internal/samplereceiver/metrics_test.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package samplereceiver + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/receiver/receivertest" + + "github.com/open-telemetry/opentelemetry-collector-contrib/cmd/mdatagen/internal/samplereceiver/internal/metadata" +) + +// TestGeneratedMetrics verifies that the internal/metadata API is generated correctly. +func TestGeneratedMetrics(t *testing.T) { + mb := metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()) + m := mb.Emit() + require.Equal(t, 0, m.ResourceMetrics().Len()) +} diff --git a/cmd/mdatagen/loader_test.go b/cmd/mdatagen/loader_test.go index 4ebedb44c156..9b6cad69f258 100644 --- a/cmd/mdatagen/loader_test.go +++ b/cmd/mdatagen/loader_test.go @@ -18,9 +18,9 @@ func TestLoadMetadata(t *testing.T) { wantErr string }{ { - name: "metadata-sample.yaml", + name: "internal/samplereceiver/metadata.yaml", want: metadata{ - Type: "file", + Type: "sample", SemConvVersion: "1.9.0", Status: &Status{ Class: "receiver", @@ -29,8 +29,11 @@ func TestLoadMetadata(t *testing.T) { "beta": {"traces"}, "stable": {"metrics"}, }, - Distributions: []string{"contrib"}, - Warnings: []string{"Any additional information that should be brought to the consumer's attention"}, + Distributions: []string{}, + Codeowners: &Codeowners{ + Active: []string{"dmitryax"}, + }, + Warnings: []string{"Any additional information that should be brought to the consumer's attention"}, }, ResourceAttributes: map[attributeName]attribute{ "string.resource.attr": { @@ -213,8 +216,9 @@ func TestLoadMetadata(t *testing.T) { }, }, }, - ScopeName: "otelcol", - ShortFolderName: ".", + ScopeName: "otelcol/samplereceiver", + ShortFolderName: "sample", + Tests: &tests{}, }, }, { diff --git a/cmd/mdatagen/main_test.go b/cmd/mdatagen/main_test.go index 03d56343a231..1211212e64c1 100644 --- a/cmd/mdatagen/main_test.go +++ b/cmd/mdatagen/main_test.go @@ -11,9 +11,6 @@ import ( "testing" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/receiver/receivertest" - - md "github.com/open-telemetry/opentelemetry-collector-contrib/cmd/mdatagen/internal/metadata" ) func TestRunContents(t *testing.T) { @@ -413,10 +410,3 @@ func Tracer(settings component.TelemetrySettings) trace.Tracer { }) } } - -// TestGenerated verifies that the internal/metadata API is generated correctly. -func TestGenerated(t *testing.T) { - mb := md.NewMetricsBuilder(md.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()) - m := mb.Emit() - require.Equal(t, 0, m.ResourceMetrics().Len()) -} diff --git a/cmd/mdatagen/internal/metadata/package_test.go b/cmd/mdatagen/package_test.go similarity index 91% rename from cmd/mdatagen/internal/metadata/package_test.go rename to cmd/mdatagen/package_test.go index 1aba5ec4bb0b..5cd502ca564b 100644 --- a/cmd/mdatagen/internal/metadata/package_test.go +++ b/cmd/mdatagen/package_test.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metadata +package main import ( "testing"