Skip to content

Commit dfeb67b

Browse files
committed
test(http_exporter): add test case for connection errors while exporting
1 parent 41870e1 commit dfeb67b

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 (
@@ -556,6 +558,48 @@ def test_retry_timeout(self, mock_post):
556558
warning.records[0].message,
557559
)
558560

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

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

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

0 commit comments

Comments
 (0)