Skip to content

Add metrics base tests #3182

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 5 commits into from
Feb 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 120 additions & 2 deletions tests/opentelemetry-test-utils/src/opentelemetry/test/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,19 @@
import logging
import unittest
from contextlib import contextmanager
from typing import Tuple
from typing import Optional, Sequence, Tuple

from opentelemetry import metrics as metrics_api
from opentelemetry import trace as trace_api
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import InMemoryMetricReader, MetricReader
from opentelemetry.sdk.metrics._internal.point import Metric
from opentelemetry.sdk.metrics.export import (
DataPointT,
HistogramDataPoint,
InMemoryMetricReader,
MetricReader,
NumberDataPoint,
)
from opentelemetry.sdk.trace import TracerProvider, export
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
InMemorySpanExporter,
Expand Down Expand Up @@ -130,6 +137,117 @@ def disable_logging(highest_level=logging.CRITICAL):
finally:
logging.disable(logging.NOTSET)

def get_sorted_metrics(self):
resource_metrics = (
self.memory_metrics_reader.get_metrics_data().resource_metrics
)

all_metrics = []
for metrics in resource_metrics:
for scope_metrics in metrics.scope_metrics:
all_metrics.extend(scope_metrics.metrics)

return self.sorted_metrics(all_metrics)

@staticmethod
def sorted_metrics(metrics):
"""
Sorts metrics by metric name.
"""
return sorted(
metrics,
key=lambda m: m.name,
)

def assert_metric_expected(
self,
metric: Metric,
expected_data_points: Sequence[DataPointT],
est_value_delta: Optional[float] = 0,
):
self.assertEqual(
len(expected_data_points), len(metric.data.data_points)
)
for expected_data_point in expected_data_points:
self.assert_data_point_expected(
expected_data_point, metric.data.data_points, est_value_delta
)

# pylint: disable=unidiomatic-typecheck
@staticmethod
def is_data_points_equal(
expected_data_point: DataPointT,
data_point: DataPointT,
est_value_delta: Optional[float] = 0,
):
if type(expected_data_point) != type(data_point) or not isinstance(
expected_data_point, (HistogramDataPoint, NumberDataPoint)
):
return False

values_diff = None
if isinstance(data_point, NumberDataPoint):
values_diff = abs(expected_data_point.value - data_point.value)
elif isinstance(data_point, HistogramDataPoint):
values_diff = abs(expected_data_point.sum - data_point.sum)
if expected_data_point.count != data_point.count or (
est_value_delta == 0
and (
expected_data_point.min != data_point.min
or expected_data_point.max != data_point.max
)
):
return False

return (
values_diff <= est_value_delta
and expected_data_point.attributes == dict(data_point.attributes)
)

def assert_data_point_expected(
self,
expected_data_point: DataPointT,
data_points: Sequence[DataPointT],
est_value_delta: Optional[float] = 0,
):
is_data_point_exist = False
for data_point in data_points:
if self.is_data_points_equal(
expected_data_point, data_point, est_value_delta
):
is_data_point_exist = True
break

self.assertTrue(
is_data_point_exist,
msg=f"Data point {expected_data_point} does not exist",
)

@staticmethod
def create_number_data_point(value, attributes):
return NumberDataPoint(
value=value,
attributes=attributes,
start_time_unix_nano=0,
time_unix_nano=0,
)

@staticmethod
def create_histogram_data_point(
sum_data_point, count, max_data_point, min_data_point, attributes
):
return HistogramDataPoint(
count=count,
sum=sum_data_point,
min=min_data_point,
max=max_data_point,
attributes=attributes,
start_time_unix_nano=0,
time_unix_nano=0,
bucket_counts=[],
explicit_bounds=[],
)


class FinishedTestSpans(list):
def __init__(self, test, spans):
Expand Down