Skip to content

Commit b03bb04

Browse files
Add unit test for http metricexporter batching
1 parent 4165741 commit b03bb04

File tree

1 file changed

+319
-0
lines changed

1 file changed

+319
-0
lines changed

exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from logging import WARNING
1616
from os import environ
17+
from typing import List
1718
from unittest import TestCase
1819
from unittest.mock import MagicMock, Mock, call, patch
1920

@@ -33,6 +34,11 @@
3334
OTLPMetricExporter,
3435
)
3536
from opentelemetry.exporter.otlp.proto.http.version import __version__
37+
from opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2
38+
from opentelemetry.proto.common.v1.common_pb2 import (
39+
InstrumentationScope,
40+
KeyValue,
41+
)
3642
from opentelemetry.sdk.environment_variables import (
3743
OTEL_EXPORTER_OTLP_CERTIFICATE,
3844
OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE,
@@ -331,6 +337,273 @@ def test_serialization(self, mock_post):
331337
cert=exporter._client_cert,
332338
)
333339

340+
def test_split_metrics_data_many_data_points(self):
341+
metrics_data = pb2.MetricsData(
342+
resource_metrics=[
343+
_resource_metrics(
344+
index=1,
345+
scope_metrics=[
346+
_scope_metrics(
347+
index=1,
348+
metrics=[
349+
_gauge(
350+
index=1,
351+
data_points=[
352+
_number_data_point(11),
353+
_number_data_point(12),
354+
_number_data_point(13),
355+
],
356+
),
357+
],
358+
),
359+
],
360+
),
361+
]
362+
)
363+
split_metrics_data: List[MetricsData] = list(
364+
# pylint: disable=protected-access
365+
OTLPMetricExporter(max_export_batch_size=2)._split_metrics_data(
366+
metrics_data=metrics_data,
367+
)
368+
)
369+
370+
self.assertEqual(
371+
[
372+
MetricsData(
373+
resource_metrics=[
374+
_resource_metrics(
375+
index=1,
376+
scope_metrics=[
377+
_scope_metrics(
378+
index=1,
379+
metrics=[
380+
_gauge(
381+
index=1,
382+
data_points=[
383+
_number_data_point(11),
384+
_number_data_point(12),
385+
],
386+
),
387+
],
388+
),
389+
],
390+
),
391+
]
392+
),
393+
MetricsData(
394+
resource_metrics=[
395+
_resource_metrics(
396+
index=1,
397+
scope_metrics=[
398+
_scope_metrics(
399+
index=1,
400+
metrics=[
401+
_gauge(
402+
index=1,
403+
data_points=[
404+
_number_data_point(13),
405+
],
406+
),
407+
],
408+
),
409+
],
410+
),
411+
]
412+
),
413+
],
414+
split_metrics_data,
415+
)
416+
417+
def test_split_metrics_data_nb_data_points_equal_batch_size(self):
418+
metrics_data = MetricsData(
419+
resource_metrics=[
420+
_resource_metrics(
421+
index=1,
422+
scope_metrics=[
423+
_scope_metrics(
424+
index=1,
425+
metrics=[
426+
_gauge(
427+
index=1,
428+
data_points=[
429+
_number_data_point(11),
430+
_number_data_point(12),
431+
_number_data_point(13),
432+
],
433+
),
434+
],
435+
),
436+
],
437+
),
438+
]
439+
)
440+
441+
split_metrics_data: List[MetricsData] = list(
442+
# pylint: disable=protected-access
443+
OTLPMetricExporter(max_export_batch_size=3)._split_metrics_data(
444+
metrics_data=metrics_data,
445+
)
446+
)
447+
448+
self.assertEqual(
449+
[
450+
MetricsData(
451+
resource_metrics=[
452+
_resource_metrics(
453+
index=1,
454+
scope_metrics=[
455+
_scope_metrics(
456+
index=1,
457+
metrics=[
458+
_gauge(
459+
index=1,
460+
data_points=[
461+
_number_data_point(11),
462+
_number_data_point(12),
463+
_number_data_point(13),
464+
],
465+
),
466+
],
467+
),
468+
],
469+
),
470+
]
471+
),
472+
],
473+
split_metrics_data,
474+
)
475+
476+
def test_split_metrics_data_many_resources_scopes_metrics(self):
477+
# GIVEN
478+
metrics_data = MetricsData(
479+
resource_metrics=[
480+
_resource_metrics(
481+
index=1,
482+
scope_metrics=[
483+
_scope_metrics(
484+
index=1,
485+
metrics=[
486+
_gauge(
487+
index=1,
488+
data_points=[
489+
_number_data_point(11),
490+
],
491+
),
492+
_gauge(
493+
index=2,
494+
data_points=[
495+
_number_data_point(12),
496+
],
497+
),
498+
],
499+
),
500+
_scope_metrics(
501+
index=2,
502+
metrics=[
503+
_gauge(
504+
index=3,
505+
data_points=[
506+
_number_data_point(13),
507+
],
508+
),
509+
],
510+
),
511+
],
512+
),
513+
_resource_metrics(
514+
index=2,
515+
scope_metrics=[
516+
_scope_metrics(
517+
index=3,
518+
metrics=[
519+
_gauge(
520+
index=4,
521+
data_points=[
522+
_number_data_point(14),
523+
],
524+
),
525+
],
526+
),
527+
],
528+
),
529+
]
530+
)
531+
532+
split_metrics_data: List[MetricsData] = list(
533+
# pylint: disable=protected-access
534+
OTLPMetricExporter(max_export_batch_size=2)._split_metrics_data(
535+
metrics_data=metrics_data,
536+
)
537+
)
538+
539+
self.assertEqual(
540+
[
541+
MetricsData(
542+
resource_metrics=[
543+
_resource_metrics(
544+
index=1,
545+
scope_metrics=[
546+
_scope_metrics(
547+
index=1,
548+
metrics=[
549+
_gauge(
550+
index=1,
551+
data_points=[
552+
_number_data_point(11),
553+
],
554+
),
555+
_gauge(
556+
index=2,
557+
data_points=[
558+
_number_data_point(12),
559+
],
560+
),
561+
],
562+
),
563+
],
564+
),
565+
]
566+
),
567+
MetricsData(
568+
resource_metrics=[
569+
_resource_metrics(
570+
index=1,
571+
scope_metrics=[
572+
_scope_metrics(
573+
index=2,
574+
metrics=[
575+
_gauge(
576+
index=3,
577+
data_points=[
578+
_number_data_point(13),
579+
],
580+
),
581+
],
582+
),
583+
],
584+
),
585+
_resource_metrics(
586+
index=2,
587+
scope_metrics=[
588+
_scope_metrics(
589+
index=3,
590+
metrics=[
591+
_gauge(
592+
index=4,
593+
data_points=[
594+
_number_data_point(14),
595+
],
596+
),
597+
],
598+
),
599+
],
600+
),
601+
]
602+
),
603+
],
604+
split_metrics_data,
605+
)
606+
334607
@activate
335608
@patch("opentelemetry.exporter.otlp.proto.http.metric_exporter.sleep")
336609
def test_exponential_backoff(self, mock_sleep):
@@ -523,3 +796,49 @@ def test_preferred_aggregation_override(self):
523796
self.assertEqual(
524797
exporter._preferred_aggregation[Histogram], histogram_aggregation
525798
)
799+
800+
801+
802+
def _resource_metrics(
803+
index: int, scope_metrics: List[pb2.ScopeMetrics]
804+
) -> pb2.ResourceMetrics:
805+
return pb2.ResourceMetrics(
806+
resource={
807+
"attributes": [
808+
KeyValue(key="a", value={"int_value": index})
809+
],
810+
},
811+
schema_url=f"resource_url_{index}",
812+
scope_metrics=scope_metrics,
813+
)
814+
815+
816+
def _scope_metrics(index: int, metrics: List[pb2.Metric]) -> pb2.ScopeMetrics:
817+
return pb2.ScopeMetrics(
818+
scope=InstrumentationScope(name=f"scope_{index}"),
819+
schema_url=f"scope_url_{index}",
820+
metrics=metrics,
821+
)
822+
823+
824+
def _gauge(index: int, data_points: List[pb2.NumberDataPoint]) -> pb2.Metric:
825+
return pb2.Metric(
826+
name=f"gauge_{index}",
827+
description="description",
828+
unit="unit",
829+
gauge=pb2.Gauge(
830+
data_points=data_points
831+
),
832+
)
833+
834+
835+
def _number_data_point(value: int) -> pb2.NumberDataPoint:
836+
return pb2.NumberDataPoint(
837+
attributes=[
838+
KeyValue(key="a", value={"int_value": 1}),
839+
KeyValue(key="b", value={"bool_value": True}),
840+
],
841+
start_time_unix_nano=1641946015139533244,
842+
time_unix_nano=1641946016139533244,
843+
as_int=value,
844+
)

0 commit comments

Comments
 (0)