Skip to content

Commit

Permalink
[receivertest] add metrics support to contract_checker
Browse files Browse the repository at this point in the history
  • Loading branch information
atoulme committed Feb 11, 2024
1 parent de6287d commit fbdb26d
Show file tree
Hide file tree
Showing 3 changed files with 315 additions and 15 deletions.
25 changes: 25 additions & 0 deletions .chloggen/implement_contract_checker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: receivertest

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: add support for metrics in contract checker

# One or more tracking issues or pull requests related to the change
issues: [9551]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [api]
114 changes: 111 additions & 3 deletions receiver/receivertest/contract_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"go.opentelemetry.io/collector/consumer/consumererror"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/plog"
"go.opentelemetry.io/collector/pdata/pmetric"
"go.opentelemetry.io/collector/pdata/ptrace"
"go.opentelemetry.io/collector/receiver"
)
Expand Down Expand Up @@ -116,8 +117,7 @@ func checkConsumeContractScenario(params CheckConsumeContractParams, decisionFun
case component.DataTypeTraces:
receiver, err = params.Factory.CreateTracesReceiver(ctx, NewNopCreateSettings(), params.Config, consumer)
case component.DataTypeMetrics:
// TODO: add metrics support to mockConsumer so that this case can be also implemented.
require.FailNow(params.T, "DataTypeMetrics is not implemented")
receiver, err = params.Factory.CreateMetricsReceiver(ctx, NewNopCreateSettings(), params.Config, consumer)
default:
require.FailNow(params.T, "must specify a valid DataType to test for")
}
Expand Down Expand Up @@ -390,7 +390,76 @@ func idSetFromLogs(data plog.Logs) (idSet, error) {
return ds, nil
}

// TODO: Implement mockConsumer.ConsumeMetrics()
func (m *mockConsumer) ConsumeMetrics(_ context.Context, data pmetric.Metrics) error {
ids, err := idSetFromMetrics(data)
require.NoError(m.t, err)
return m.consume(ids)
}

// idSetFromLogs computes an idSet from given plog.Logs. The idSet will contain ids of all log records.
func idSetFromMetrics(data pmetric.Metrics) (idSet, error) {
ds := map[UniqueIDAttrVal]bool{}
rss := data.ResourceMetrics()
for i := 0; i < rss.Len(); i++ {
ils := rss.At(i).ScopeMetrics()
for j := 0; j < ils.Len(); j++ {
ss := ils.At(j).Metrics()
for k := 0; k < ss.Len(); k++ {
elem := ss.At(k)
switch elem.Type() {
case pmetric.MetricTypeGauge:
for l := 0; l < elem.Gauge().DataPoints().Len(); l++ {
dp := elem.Gauge().DataPoints().At(l)
if err := idSetFromDataPoint(ds, dp.Attributes()); err != nil {
return ds, err
}

Check warning on line 415 in receiver/receivertest/contract_checker.go

View check run for this annotation

Codecov / codecov/patch

receiver/receivertest/contract_checker.go#L414-L415

Added lines #L414 - L415 were not covered by tests
}
case pmetric.MetricTypeSum:
for l := 0; l < elem.Sum().DataPoints().Len(); l++ {
dp := elem.Sum().DataPoints().At(l)
if err := idSetFromDataPoint(ds, dp.Attributes()); err != nil {
return ds, err
}

Check warning on line 422 in receiver/receivertest/contract_checker.go

View check run for this annotation

Codecov / codecov/patch

receiver/receivertest/contract_checker.go#L421-L422

Added lines #L421 - L422 were not covered by tests
}
case pmetric.MetricTypeSummary:
for l := 0; l < elem.Summary().DataPoints().Len(); l++ {
dp := elem.Summary().DataPoints().At(l)
if err := idSetFromDataPoint(ds, dp.Attributes()); err != nil {
return ds, err
}

Check warning on line 429 in receiver/receivertest/contract_checker.go

View check run for this annotation

Codecov / codecov/patch

receiver/receivertest/contract_checker.go#L428-L429

Added lines #L428 - L429 were not covered by tests
}
case pmetric.MetricTypeHistogram:
for l := 0; l < elem.Histogram().DataPoints().Len(); l++ {
dp := elem.Histogram().DataPoints().At(l)
if err := idSetFromDataPoint(ds, dp.Attributes()); err != nil {
return ds, err
}

Check warning on line 436 in receiver/receivertest/contract_checker.go

View check run for this annotation

Codecov / codecov/patch

receiver/receivertest/contract_checker.go#L435-L436

Added lines #L435 - L436 were not covered by tests
}
case pmetric.MetricTypeExponentialHistogram:
for l := 0; l < elem.ExponentialHistogram().DataPoints().Len(); l++ {
dp := elem.ExponentialHistogram().DataPoints().At(l)
if err := idSetFromDataPoint(ds, dp.Attributes()); err != nil {
return ds, err
}

Check warning on line 443 in receiver/receivertest/contract_checker.go

View check run for this annotation

Codecov / codecov/patch

receiver/receivertest/contract_checker.go#L442-L443

Added lines #L442 - L443 were not covered by tests
}
}
}
}
}
return ds, nil
}

func idSetFromDataPoint(ds map[UniqueIDAttrVal]bool, attributes pcommon.Map) error {
key, exists := attributes.Get(UniqueIDAttrName)
if !exists {
return fmt.Errorf("invalid data element, attribute %q is missing", UniqueIDAttrName)
}

Check warning on line 456 in receiver/receivertest/contract_checker.go

View check run for this annotation

Codecov / codecov/patch

receiver/receivertest/contract_checker.go#L455-L456

Added lines #L455 - L456 were not covered by tests
if key.Type() != pcommon.ValueTypeStr {
return fmt.Errorf("invalid data element, attribute %q is wrong type %v", UniqueIDAttrName, key.Type())
}

Check warning on line 459 in receiver/receivertest/contract_checker.go

View check run for this annotation

Codecov / codecov/patch

receiver/receivertest/contract_checker.go#L458-L459

Added lines #L458 - L459 were not covered by tests
ds[UniqueIDAttrVal(key.Str())] = true
return nil
}

// consume the elements with the specified ids, regardless of the element data type.
func (m *mockConsumer) consume(ids idSet) error {
Expand Down Expand Up @@ -437,3 +506,42 @@ func CreateOneLogWithID(id UniqueIDAttrVal) plog.Logs {
)
return data
}

func CreateEveryMetricTypeWithID(id UniqueIDAttrVal) pmetric.Metrics {
data := pmetric.NewMetrics()
gauge := data.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
gauge.AppendEmpty().SetEmptyGauge().DataPoints().AppendEmpty().Attributes().PutStr(
UniqueIDAttrName,
string(id),
)
sum := data.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
sum.AppendEmpty().SetEmptySum().DataPoints().AppendEmpty().Attributes().PutStr(
UniqueIDAttrName,
string(id),
)
summary := data.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
summary.AppendEmpty().SetEmptySummary().DataPoints().AppendEmpty().Attributes().PutStr(
UniqueIDAttrName,
string(id),
)
histogram := data.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
histogram.AppendEmpty().SetEmptyHistogram().DataPoints().AppendEmpty().Attributes().PutStr(
UniqueIDAttrName,
string(id),
)
exponentialHistogram := data.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
exponentialHistogram.AppendEmpty().SetEmptyExponentialHistogram().DataPoints().AppendEmpty().Attributes().PutStr(
UniqueIDAttrName,
string(id),
)
return data
}

func CreateOneSpanWithID(id UniqueIDAttrVal) ptrace.Traces {
data := ptrace.NewTraces()
data.ResourceSpans().AppendEmpty().ScopeSpans().AppendEmpty().Spans().AppendEmpty().Attributes().PutStr(
UniqueIDAttrName,
string(id),
)
return data
}
Loading

0 comments on commit fbdb26d

Please sign in to comment.