Skip to content

Commit fb5dff6

Browse files
authored
Merge pull request #4 from Charlie-lizhihan/dev-bugfix
Dev bugfix
2 parents ba22b16 + 5a8179e commit fb5dff6

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
- Fix RandomIdGenerator can generate invalid Span/Trace Ids
11+
([#3949](https://github.com/open-telemetry/opentelemetry-python/pull/3949))
1012
- Add Python 3.12 to tox
1113
([#3616](https://github.com/open-telemetry/opentelemetry-python/pull/3616))
1214

opentelemetry-sdk/src/opentelemetry/sdk/trace/id_generator.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import abc
1616
import random
1717

18+
from opentelemetry.trace.span import INVALID_SPAN_ID, INVALID_TRACE_ID
19+
1820

1921
class IdGenerator(abc.ABC):
2022
@abc.abstractmethod
@@ -46,7 +48,13 @@ class RandomIdGenerator(IdGenerator):
4648
"""
4749

4850
def generate_span_id(self) -> int:
49-
return random.getrandbits(64)
51+
span_id = random.getrandbits(64)
52+
while span_id == INVALID_SPAN_ID:
53+
span_id = random.getrandbits(64)
54+
return span_id
5055

5156
def generate_trace_id(self) -> int:
52-
return random.getrandbits(128)
57+
trace_id = random.getrandbits(128)
58+
while trace_id == INVALID_TRACE_ID:
59+
trace_id = random.getrandbits(128)
60+
return trace_id

opentelemetry-sdk/tests/trace/test_trace.py

+39
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
StatusCode,
6363
get_tracer,
6464
set_tracer_provider,
65+
span,
6566
)
6667

6768

@@ -2061,3 +2062,41 @@ def test_tracer_provider_init_default(self, resource_patch, sample_patch):
20612062
sample_patch.assert_called_once()
20622063
self.assertIsNotNone(tracer_provider._span_limits)
20632064
self.assertIsNotNone(tracer_provider._atexit_handler)
2065+
2066+
2067+
class TestRandomIdGenerator(unittest.TestCase):
2068+
_TRACE_ID_MAX_VALUE = 2**128 - 1
2069+
_SPAN_ID_MAX_VALUE = 2**64 - 1
2070+
2071+
@patch(
2072+
"random.getrandbits",
2073+
side_effect=[span.INVALID_SPAN_ID, 0x00000000DEADBEF0],
2074+
)
2075+
def test_generate_span_id_avoids_invalid(self, mock_getrandbits):
2076+
generator = RandomIdGenerator()
2077+
span_id = generator.generate_span_id()
2078+
2079+
self.assertNotEqual(span_id, span.INVALID_SPAN_ID)
2080+
self.assertGreater(span_id, span.INVALID_SPAN_ID)
2081+
self.assertLessEqual(span_id, self._SPAN_ID_MAX_VALUE)
2082+
self.assertEqual(
2083+
mock_getrandbits.call_count, 2
2084+
) # Ensure exactly two calls
2085+
2086+
@patch(
2087+
"random.getrandbits",
2088+
side_effect=[
2089+
span.INVALID_TRACE_ID,
2090+
0x000000000000000000000000DEADBEEF,
2091+
],
2092+
)
2093+
def test_generate_trace_id_avoids_invalid(self, mock_getrandbits):
2094+
generator = RandomIdGenerator()
2095+
trace_id = generator.generate_trace_id()
2096+
2097+
self.assertNotEqual(trace_id, span.INVALID_TRACE_ID)
2098+
self.assertGreater(trace_id, span.INVALID_TRACE_ID)
2099+
self.assertLessEqual(trace_id, self._TRACE_ID_MAX_VALUE)
2100+
self.assertEqual(
2101+
mock_getrandbits.call_count, 2
2102+
) # Ensure exactly two calls

0 commit comments

Comments
 (0)