Skip to content

Commit 1f3af45

Browse files
committed
test(http_exporter): add test case for connection errors while exporting
1 parent 89c1dc4 commit 1f3af45

File tree

3 files changed

+130
-0
lines changed

3 files changed

+130
-0
lines changed

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
from unittest import TestCase
2020
from unittest.mock import ANY, MagicMock, Mock, patch
2121

22+
import requests
2223
from requests import Session
24+
from requests.exceptions import ConnectionError
2325
from requests.models import Response
2426

2527
from opentelemetry.exporter.otlp.proto.common.metrics_encoder import (
@@ -555,6 +557,48 @@ def test_retry_timeout(self, mock_post):
555557
warning.records[0].message,
556558
)
557559

560+
@patch.object(Session, "post")
561+
def test_export_no_collector_available_retryable(self, mock_post):
562+
exporter = OTLPMetricExporter(timeout=1.5)
563+
msg = "Server not available."
564+
mock_post.side_effect = ConnectionError(msg)
565+
with self.assertLogs(level=WARNING) as warning:
566+
before = time.time()
567+
# Set timeout to 1.5 seconds
568+
self.assertEqual(
569+
exporter.export(self.metrics["sum_int"]),
570+
MetricExportResult.FAILURE,
571+
)
572+
after = time.time()
573+
# First call at time 0, second at time 1, then an early return before the second backoff sleep b/c it would exceed timeout.
574+
# Additionally every retry results in two calls, therefore 4.
575+
self.assertEqual(mock_post.call_count, 4)
576+
# There's a +/-20% jitter on each backoff.
577+
self.assertTrue(0.75 < after - before < 1.25)
578+
self.assertIn(
579+
f"Transient error {msg} encountered while exporting metrics batch, retrying in",
580+
warning.records[0].message,
581+
)
582+
583+
@patch.object(Session, "post")
584+
def test_export_no_collector_available(self, mock_post):
585+
exporter = OTLPMetricExporter(timeout=1.5)
586+
587+
mock_post.side_effect = requests.exceptions.RequestException()
588+
with self.assertLogs(level=WARNING) as warning:
589+
# Set timeout to 1.5 seconds
590+
self.assertEqual(
591+
exporter.export(self.metrics["sum_int"]),
592+
MetricExportResult.FAILURE,
593+
)
594+
# First call at time 0, second at time 1, then an early return before the second backoff sleep b/c it would exceed timeout.
595+
self.assertEqual(mock_post.call_count, 1)
596+
# There's a +/-20% jitter on each backoff.
597+
self.assertIn(
598+
"Failed to export metrics batch code",
599+
warning.records[0].message,
600+
)
601+
558602
@patch.object(Session, "post")
559603
def test_timeout_set_correctly(self, mock_post):
560604
resp = Response()

exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import requests
2525
from google.protobuf.json_format import MessageToDict
2626
from requests import Session
27+
from requests.exceptions import ConnectionError
2728
from requests.models import Response
2829

2930
from opentelemetry._logs import LogRecord, SeverityNumber
@@ -483,6 +484,48 @@ def test_retry_timeout(self, mock_post):
483484
warning.records[0].message,
484485
)
485486

487+
@patch.object(Session, "post")
488+
def test_export_no_collector_available_retryable(self, mock_post):
489+
exporter = OTLPLogExporter(timeout=1.5)
490+
msg = "Server not available."
491+
mock_post.side_effect = ConnectionError(msg)
492+
with self.assertLogs(level=WARNING) as warning:
493+
before = time.time()
494+
# Set timeout to 1.5 seconds
495+
self.assertEqual(
496+
exporter.export(self._get_sdk_log_data()),
497+
LogExportResult.FAILURE,
498+
)
499+
after = time.time()
500+
# First call at time 0, second at time 1, then an early return before the second backoff sleep b/c it would exceed timeout.
501+
# Additionally every retry results in two calls, therefore 4.
502+
self.assertEqual(mock_post.call_count, 4)
503+
# There's a +/-20% jitter on each backoff.
504+
self.assertTrue(0.75 < after - before < 1.25)
505+
self.assertIn(
506+
f"Transient error {msg} encountered while exporting logs batch, retrying in",
507+
warning.records[0].message,
508+
)
509+
510+
@patch.object(Session, "post")
511+
def test_export_no_collector_available(self, mock_post):
512+
exporter = OTLPLogExporter(timeout=1.5)
513+
514+
mock_post.side_effect = requests.exceptions.RequestException()
515+
with self.assertLogs(level=WARNING) as warning:
516+
# Set timeout to 1.5 seconds
517+
self.assertEqual(
518+
exporter.export(self._get_sdk_log_data()),
519+
LogExportResult.FAILURE,
520+
)
521+
# First call at time 0, second at time 1, then an early return before the second backoff sleep b/c it would exceed timeout.
522+
self.assertEqual(mock_post.call_count, 1)
523+
# There's a +/-20% jitter on each backoff.
524+
self.assertIn(
525+
"Failed to export logs batch code",
526+
warning.records[0].message,
527+
)
528+
486529
@patch.object(Session, "post")
487530
def test_timeout_set_correctly(self, mock_post):
488531
resp = Response()

exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import requests
2222
from requests import Session
23+
from requests.exceptions import ConnectionError
2324
from requests.models import Response
2425

2526
from opentelemetry.exporter.otlp.proto.http import Compression
@@ -303,6 +304,48 @@ def test_retry_timeout(self, mock_post):
303304
warning.records[0].message,
304305
)
305306

307+
@patch.object(Session, "post")
308+
def test_export_no_collector_available_retryable(self, mock_post):
309+
exporter = OTLPSpanExporter(timeout=1.5)
310+
msg = "Server not available."
311+
mock_post.side_effect = ConnectionError(msg)
312+
with self.assertLogs(level=WARNING) as warning:
313+
before = time.time()
314+
# Set timeout to 1.5 seconds
315+
self.assertEqual(
316+
exporter.export([BASIC_SPAN]),
317+
SpanExportResult.FAILURE,
318+
)
319+
after = time.time()
320+
# First call at time 0, second at time 1, then an early return before the second backoff sleep b/c it would exceed timeout.
321+
# Additionally every retry results in two calls, therefore 4.
322+
self.assertEqual(mock_post.call_count, 4)
323+
# There's a +/-20% jitter on each backoff.
324+
self.assertTrue(0.75 < after - before < 1.25)
325+
self.assertIn(
326+
f"Transient error {msg} encountered while exporting span batch, retrying in",
327+
warning.records[0].message,
328+
)
329+
330+
@patch.object(Session, "post")
331+
def test_export_no_collector_available(self, mock_post):
332+
exporter = OTLPSpanExporter(timeout=1.5)
333+
334+
mock_post.side_effect = requests.exceptions.RequestException()
335+
with self.assertLogs(level=WARNING) as warning:
336+
# Set timeout to 1.5 seconds
337+
self.assertEqual(
338+
exporter.export([BASIC_SPAN]),
339+
SpanExportResult.FAILURE,
340+
)
341+
# First call at time 0, second at time 1, then an early return before the second backoff sleep b/c it would exceed timeout.
342+
self.assertEqual(mock_post.call_count, 1)
343+
# There's a +/-20% jitter on each backoff.
344+
self.assertIn(
345+
"Failed to export span batch code",
346+
warning.records[0].message,
347+
)
348+
306349
@patch.object(Session, "post")
307350
def test_timeout_set_correctly(self, mock_post):
308351
resp = Response()

0 commit comments

Comments
 (0)