Skip to content

Commit

Permalink
Attributes returned from SamplingResult must be immutable (#1066)
Browse files Browse the repository at this point in the history
  • Loading branch information
lzchen authored Sep 3, 2020
1 parent e45354c commit 3bbab02
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ package_dir=
packages=find_namespace:
install_requires =
opentelemetry-api == 0.13dev0
opentelemetry-sdk == 0.13dev0
psutil ~= 5.7.0

[options.extras_require]
Expand Down
2 changes: 1 addition & 1 deletion opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ def start_span( # pylint: disable=too-many-locals
parent=parent_context,
sampler=self.source.sampler,
resource=self.source.resource,
attributes=sampling_result.attributes,
attributes=sampling_result.attributes.copy(),
span_processor=self.source._active_span_processor,
kind=kind,
links=links,
Expand Down
6 changes: 3 additions & 3 deletions opentelemetry-sdk/src/opentelemetry/sdk/trace/sampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"""
import abc
import enum
from types import MappingProxyType
from typing import Optional, Sequence

# pylint: disable=unused-import
Expand Down Expand Up @@ -102,11 +103,10 @@ def __init__(
self, decision: Decision, attributes: Attributes = None,
) -> None:
self.decision = decision
# TODO: attributes must be immutable
if attributes is None:
self.attributes = {}
self.attributes = MappingProxyType({})
else:
self.attributes = attributes
self.attributes = MappingProxyType(attributes)


class Sampler(abc.ABC):
Expand Down
37 changes: 37 additions & 0 deletions opentelemetry-sdk/tests/trace/test_sampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,43 @@
TO_SAMPLED = trace.TraceFlags(trace.TraceFlags.SAMPLED)


class TestDecision(unittest.TestCase):
def test_is_recording(self):
self.assertTrue(
sampling.Decision.is_recording(sampling.Decision.RECORD)
)
self.assertTrue(
sampling.Decision.is_recording(
sampling.Decision.RECORD_AND_SAMPLED
)
)
self.assertFalse(
sampling.Decision.is_recording(sampling.Decision.NOT_RECORD)
)

def test_is_sampled(self):
self.assertFalse(
sampling.Decision.is_sampled(sampling.Decision.RECORD)
)
self.assertTrue(
sampling.Decision.is_sampled(sampling.Decision.RECORD_AND_SAMPLED)
)
self.assertFalse(
sampling.Decision.is_sampled(sampling.Decision.NOT_RECORD)
)


class TestSamplingResult(unittest.TestCase):
def test_ctr(self):
attributes = {"asd": "test"}
result = sampling.SamplingResult(sampling.Decision.RECORD, attributes)
self.assertIs(result.decision, sampling.Decision.RECORD)
with self.assertRaises(TypeError):
result.attributes["test"] = "mess-this-up"
self.assertTrue(len(result.attributes), 1)
self.assertEqual(result.attributes["asd"], "test")


class TestSampler(unittest.TestCase):
def test_always_on(self):
no_record_always_on = sampling.ALWAYS_ON.should_sample(
Expand Down

0 comments on commit 3bbab02

Please sign in to comment.