12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
14
# type: ignore
15
+ # pylint: skip-file
15
16
16
17
import logging
17
18
from os import environ
19
+ from typing import Dict , Iterable , Optional
18
20
from unittest import TestCase
19
21
from unittest .mock import patch
20
22
28
30
_import_exporters ,
29
31
_import_id_generator ,
30
32
_init_logging ,
33
+ _init_metrics ,
31
34
_init_tracing ,
32
35
_initialize_components ,
33
36
)
34
37
from opentelemetry .sdk ._logs import LoggingHandler
35
38
from opentelemetry .sdk ._logs .export import ConsoleLogExporter
36
- from opentelemetry .sdk .metrics .export import ConsoleMetricExporter
39
+ from opentelemetry .sdk .metrics import MeterProvider
40
+ from opentelemetry .sdk .metrics .export import (
41
+ AggregationTemporality ,
42
+ ConsoleMetricExporter ,
43
+ Metric ,
44
+ MetricExporter ,
45
+ MetricReader ,
46
+ )
47
+ from opentelemetry .sdk .metrics .view import Aggregation
37
48
from opentelemetry .sdk .resources import SERVICE_NAME , Resource
38
49
from opentelemetry .sdk .trace .export import ConsoleSpanExporter
39
50
from opentelemetry .sdk .trace .id_generator import IdGenerator , RandomIdGenerator
@@ -61,6 +72,10 @@ def get_log_emitter(self, name):
61
72
return DummyLogEmitter (name , self .resource , self .processor )
62
73
63
74
75
+ class DummyMeterProvider (MeterProvider ):
76
+ pass
77
+
78
+
64
79
class DummyLogEmitter :
65
80
def __init__ (self , name , resource , processor ):
66
81
self .name = name
@@ -93,6 +108,44 @@ def __init__(self, exporter):
93
108
self .exporter = exporter
94
109
95
110
111
+ class DummyMetricReader (MetricReader ):
112
+ def __init__ (
113
+ self ,
114
+ exporter : MetricExporter ,
115
+ preferred_temporality : Dict [type , AggregationTemporality ] = None ,
116
+ preferred_aggregation : Dict [type , Aggregation ] = None ,
117
+ export_interval_millis : Optional [float ] = None ,
118
+ export_timeout_millis : Optional [float ] = None ,
119
+ ) -> None :
120
+ super ().__init__ (
121
+ preferred_temporality = preferred_temporality ,
122
+ preferred_aggregation = preferred_aggregation ,
123
+ )
124
+ self .exporter = exporter
125
+
126
+ def _receive_metrics (
127
+ self ,
128
+ metrics : Iterable [Metric ],
129
+ timeout_millis : float = 10_000 ,
130
+ ** kwargs ,
131
+ ) -> None :
132
+ self .exporter .export (None )
133
+
134
+ def shutdown (self , timeout_millis : float = 30_000 , ** kwargs ) -> None :
135
+ return True
136
+
137
+
138
+ class DummyOTLPMetricExporter :
139
+ def __init__ (self , * args , ** kwargs ):
140
+ self .export_called = False
141
+
142
+ def export (self , batch ):
143
+ self .export_called = True
144
+
145
+ def shutdown (self ):
146
+ pass
147
+
148
+
96
149
class Exporter :
97
150
def __init__ (self ):
98
151
tracer_provider = trace .get_tracer_provider ()
@@ -148,7 +201,7 @@ def setUp(self):
148
201
"opentelemetry.sdk._configuration.BatchSpanProcessor" , Processor
149
202
)
150
203
self .set_provider_patcher = patch (
151
- "opentelemetry.trace .set_tracer_provider"
204
+ "opentelemetry.sdk._configuration .set_tracer_provider"
152
205
)
153
206
154
207
self .get_provider_mock = self .get_provider_patcher .start ()
@@ -304,6 +357,61 @@ def test_logging_init_enable_env(self, logging_mock, tracing_mock):
304
357
self .assertEqual (tracing_mock .call_count , 1 )
305
358
306
359
360
+ class TestMetricsInit (TestCase ):
361
+ def setUp (self ):
362
+ self .metric_reader_patch = patch (
363
+ "opentelemetry.sdk._configuration.PeriodicExportingMetricReader" ,
364
+ DummyMetricReader ,
365
+ )
366
+ self .provider_patch = patch (
367
+ "opentelemetry.sdk._configuration.MeterProvider" ,
368
+ DummyMeterProvider ,
369
+ )
370
+ self .set_provider_patch = patch (
371
+ "opentelemetry.sdk._configuration.set_meter_provider"
372
+ )
373
+
374
+ self .metric_reader_mock = self .metric_reader_patch .start ()
375
+ self .provider_mock = self .provider_patch .start ()
376
+ self .set_provider_mock = self .set_provider_patch .start ()
377
+
378
+ def tearDown (self ):
379
+ self .metric_reader_patch .stop ()
380
+ self .set_provider_patch .stop ()
381
+ self .provider_patch .stop ()
382
+
383
+ def test_metrics_init_empty (self ):
384
+ _init_metrics ({}, "auto-version" )
385
+ self .assertEqual (self .set_provider_mock .call_count , 1 )
386
+ provider = self .set_provider_mock .call_args [0 ][0 ]
387
+ self .assertIsInstance (provider , DummyMeterProvider )
388
+ self .assertIsInstance (provider ._sdk_config .resource , Resource )
389
+ self .assertEqual (
390
+ provider ._sdk_config .resource .attributes .get (
391
+ "telemetry.auto.version"
392
+ ),
393
+ "auto-version" ,
394
+ )
395
+
396
+ @patch .dict (
397
+ environ ,
398
+ {"OTEL_RESOURCE_ATTRIBUTES" : "service.name=otlp-service" },
399
+ )
400
+ def test_metrics_init_exporter (self ):
401
+ _init_metrics ({"otlp" : DummyOTLPMetricExporter })
402
+ self .assertEqual (self .set_provider_mock .call_count , 1 )
403
+ provider = self .set_provider_mock .call_args [0 ][0 ]
404
+ self .assertIsInstance (provider , DummyMeterProvider )
405
+ self .assertIsInstance (provider ._sdk_config .resource , Resource )
406
+ self .assertEqual (
407
+ provider ._sdk_config .resource .attributes .get ("service.name" ),
408
+ "otlp-service" ,
409
+ )
410
+ reader = provider ._sdk_config .metric_readers [0 ]
411
+ self .assertIsInstance (reader , DummyMetricReader )
412
+ self .assertIsInstance (reader .exporter , DummyOTLPMetricExporter )
413
+
414
+
307
415
class TestExporterNames (TestCase ):
308
416
def test_otlp_exporter_overwrite (self ):
309
417
for exporter in [_EXPORTER_OTLP , _EXPORTER_OTLP_PROTO_GRPC ]:
@@ -328,8 +436,8 @@ def test_empty_exporters(self):
328
436
329
437
class TestImportExporters (TestCase ):
330
438
def test_console_exporters (self ):
331
- trace_exporters , logs_exporters = _import_exporters (
332
- ["console" ], ["console" ]
439
+ trace_exporters , metric_exporterts , logs_exporters = _import_exporters (
440
+ ["console" ], ["console" ], [ "console" ]
333
441
)
334
442
self .assertEqual (
335
443
trace_exporters ["console" ].__class__ , ConsoleSpanExporter .__class__
@@ -338,6 +446,6 @@ def test_console_exporters(self):
338
446
logs_exporters ["console" ].__class__ , ConsoleLogExporter .__class__
339
447
)
340
448
self .assertEqual (
341
- logs_exporters ["console" ].__class__ ,
449
+ metric_exporterts ["console" ].__class__ ,
342
450
ConsoleMetricExporter .__class__ ,
343
451
)
0 commit comments