diff --git a/sentry_sdk/integrations/redis/_async_common.py b/sentry_sdk/integrations/redis/_async_common.py index cc3baa374d..b560962875 100644 --- a/sentry_sdk/integrations/redis/_async_common.py +++ b/sentry_sdk/integrations/redis/_async_common.py @@ -14,10 +14,7 @@ _extract_key, _get_safe_command, _set_client_data, - _set_pipeline_data, ) -from sentry_sdk.tracing import Span -from sentry_sdk.tracing_utils import has_span_streaming_enabled from sentry_sdk.utils import capture_internal_exceptions if TYPE_CHECKING: @@ -34,7 +31,7 @@ def patch_redis_async_pipeline( pipeline_cls: "Union[type[Pipeline[Any]], type[ClusterPipeline[Any]]]", is_cluster: bool, get_command_args_fn: "Any", - set_db_data_fn: "Callable[[Union[Span, StreamedSpan], Any], None]", + set_db_data_fn: "Callable[[StreamedSpan, Any], None]", ) -> None: old_execute = pipeline_cls.execute @@ -55,44 +52,20 @@ async def _sentry_execute(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": }, ) - span_streaming = has_span_streaming_enabled(client.options) + if sentry_sdk.traces.get_current_span() is None: + return await old_execute(self, *args, **kwargs) - span: "Union[Span, StreamedSpan]" - if span_streaming: - if sentry_sdk.traces.get_current_span() is None: - return await old_execute(self, *args, **kwargs) - span = sentry_sdk.traces.start_span( - name="redis.pipeline.execute", - attributes={ - "sentry.origin": SPAN_ORIGIN, - "sentry.op": OP.DB_REDIS, - }, - ) - else: - span = sentry_sdk.start_span( - op=OP.DB_REDIS, - name="redis.pipeline.execute", - origin=SPAN_ORIGIN, - ) + span = sentry_sdk.traces.start_span( + name="redis.pipeline.execute", + attributes={ + "sentry.origin": SPAN_ORIGIN, + "sentry.op": OP.DB_REDIS, + }, + ) with span: with capture_internal_exceptions(): - try: - command_seq = self._execution_strategy._command_queue - except AttributeError: - if is_cluster: - command_seq = self._command_stack - else: - command_seq = self.command_stack - set_db_data_fn(span, self) - _set_pipeline_data( - span, - is_cluster, - get_command_args_fn, - False if is_cluster else self.is_transaction, - command_seq, - ) return await old_execute(self, *args, **kwargs) @@ -102,7 +75,7 @@ async def _sentry_execute(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": def patch_redis_async_client( cls: "Union[type[Redis[Any]], type[RedisCluster[Any]]]", is_cluster: bool, - set_db_data_fn: "Callable[[Union[Span, StreamedSpan], Any], None]", + set_db_data_fn: "Callable[[StreamedSpan, Any], None]", ) -> None: old_execute_command = cls.execute_command @@ -134,9 +107,7 @@ async def _sentry_execute_command( data=breadcrumb_data, ) - span_streaming = has_span_streaming_enabled(client.options) - - if span_streaming and sentry_sdk.traces.get_current_span() is None: + if sentry_sdk.traces.get_current_span() is None: return await old_execute_command(self, name, *args, **kwargs) cache_properties = _compile_cache_span_properties( @@ -152,24 +123,16 @@ async def _sentry_execute_command( _get_safe_command(name, args) ) - cache_span: "Optional[Union[Span, StreamedSpan]]" = None + cache_span: "Optional[StreamedSpan]" = None if cache_properties["is_cache_key"] and cache_properties["op"] is not None: - if span_streaming: - cache_span = sentry_sdk.traces.start_span( - name=cache_properties["description"], - attributes={ - "sentry.op": cache_properties["op"], - "sentry.origin": SPAN_ORIGIN, - **additional_cache_span_attributes, - }, - ) - else: - cache_span = sentry_sdk.start_span( - op=cache_properties["op"], - name=cache_properties["description"], - origin=SPAN_ORIGIN, - ) - cache_span.__enter__() + cache_span = sentry_sdk.traces.start_span( + name=cache_properties["description"], + attributes={ + "sentry.op": cache_properties["op"], + "sentry.origin": SPAN_ORIGIN, + **additional_cache_span_attributes, + }, + ) additional_db_span_attributes = {} with capture_internal_exceptions(): @@ -177,34 +140,25 @@ async def _sentry_execute_command( name, args ) - db_span: "Union[Span, StreamedSpan]" - if span_streaming: - db_span = sentry_sdk.traces.start_span( - name=db_properties["description"], - attributes={ - "sentry.op": db_properties["op"], - "sentry.origin": SPAN_ORIGIN, - **additional_db_span_attributes, - }, - ) - else: - db_span = sentry_sdk.start_span( - op=db_properties["op"], - name=db_properties["description"], - origin=SPAN_ORIGIN, - ) - db_span.__enter__() + db_span = sentry_sdk.traces.start_span( + name=db_properties["description"], + attributes={ + "sentry.op": db_properties["op"], + "sentry.origin": SPAN_ORIGIN, + **additional_db_span_attributes, + }, + ) set_db_data_fn(db_span, self) _set_client_data(db_span, is_cluster, name, *args) value = await old_execute_command(self, name, *args, **kwargs) - db_span.__exit__(None, None, None) + db_span.end() if cache_span: _set_cache_data(cache_span, self, cache_properties, value) - cache_span.__exit__(None, None, None) + cache_span.end() return value diff --git a/sentry_sdk/integrations/redis/_sync_common.py b/sentry_sdk/integrations/redis/_sync_common.py index fcb1822094..d6a649cad2 100644 --- a/sentry_sdk/integrations/redis/_sync_common.py +++ b/sentry_sdk/integrations/redis/_sync_common.py @@ -14,15 +14,12 @@ _extract_key, _get_safe_command, _set_client_data, - _set_pipeline_data, ) -from sentry_sdk.tracing import Span -from sentry_sdk.tracing_utils import has_span_streaming_enabled from sentry_sdk.utils import capture_internal_exceptions if TYPE_CHECKING: from collections.abc import Callable - from typing import Any, Optional, Union + from typing import Any, Optional from sentry_sdk.traces import StreamedSpan @@ -31,7 +28,7 @@ def patch_redis_pipeline( pipeline_cls: "Any", is_cluster: bool, get_command_args_fn: "Any", - set_db_data_fn: "Callable[[Union[Span, StreamedSpan], Any], None]", + set_db_data_fn: "Callable[[StreamedSpan, Any], None]", ) -> None: old_execute = pipeline_cls.execute @@ -52,41 +49,20 @@ def sentry_patched_execute(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": }, ) - span_streaming = has_span_streaming_enabled(client.options) - span: "Union[Span, StreamedSpan]" - if span_streaming: - if sentry_sdk.traces.get_current_span() is None: - return old_execute(self, *args, **kwargs) - span = sentry_sdk.traces.start_span( - name="redis.pipeline.execute", - attributes={ - "sentry.origin": SPAN_ORIGIN, - "sentry.op": OP.DB_REDIS, - }, - ) - else: - span = sentry_sdk.start_span( - op=OP.DB_REDIS, - name="redis.pipeline.execute", - origin=SPAN_ORIGIN, - ) + if sentry_sdk.traces.get_current_span() is None: + return old_execute(self, *args, **kwargs) + + span = sentry_sdk.traces.start_span( + name="redis.pipeline.execute", + attributes={ + "sentry.origin": SPAN_ORIGIN, + "sentry.op": OP.DB_REDIS, + }, + ) with span: with capture_internal_exceptions(): - command_seq = None - try: - command_seq = self._execution_strategy.command_queue - except AttributeError: - command_seq = self.command_stack - set_db_data_fn(span, self) - _set_pipeline_data( - span, - is_cluster, - get_command_args_fn, - False if is_cluster else self.transaction, - command_seq, - ) return old_execute(self, *args, **kwargs) @@ -96,7 +72,7 @@ def sentry_patched_execute(self: "Any", *args: "Any", **kwargs: "Any") -> "Any": def patch_redis_client( cls: "Any", is_cluster: bool, - set_db_data_fn: "Callable[[Union[Span, StreamedSpan], Any], None]", + set_db_data_fn: "Callable[[StreamedSpan, Any], None]", ) -> None: """ This function can be used to instrument custom redis client classes or @@ -132,9 +108,7 @@ def sentry_patched_execute_command( data=breadcrumb_data, ) - span_streaming = has_span_streaming_enabled(client.options) - - if span_streaming and sentry_sdk.traces.get_current_span() is None: + if sentry_sdk.traces.get_current_span() is None: return old_execute_command(self, name, *args, **kwargs) cache_properties = _compile_cache_span_properties( @@ -150,24 +124,16 @@ def sentry_patched_execute_command( _get_safe_command(name, args) ) - cache_span: "Optional[Union[Span, StreamedSpan]]" = None + cache_span: "Optional[StreamedSpan]" = None if cache_properties["is_cache_key"] and cache_properties["op"] is not None: - if span_streaming: - cache_span = sentry_sdk.traces.start_span( - name=cache_properties["description"], - attributes={ - "sentry.op": cache_properties["op"], - "sentry.origin": SPAN_ORIGIN, - **additional_cache_span_attributes, - }, - ) - else: - cache_span = sentry_sdk.start_span( - op=cache_properties["op"], - name=cache_properties["description"], - origin=SPAN_ORIGIN, - ) - cache_span.__enter__() + cache_span = sentry_sdk.traces.start_span( + name=cache_properties["description"], + attributes={ + "sentry.op": cache_properties["op"], + "sentry.origin": SPAN_ORIGIN, + **additional_cache_span_attributes, + }, + ) additional_db_span_attributes = {} with capture_internal_exceptions(): @@ -175,34 +141,25 @@ def sentry_patched_execute_command( name, args ) - db_span: "Union[Span, StreamedSpan]" - if span_streaming: - db_span = sentry_sdk.traces.start_span( - name=db_properties["description"], - attributes={ - "sentry.op": db_properties["op"], - "sentry.origin": SPAN_ORIGIN, - **additional_db_span_attributes, - }, - ) - else: - db_span = sentry_sdk.start_span( - op=db_properties["op"], - name=db_properties["description"], - origin=SPAN_ORIGIN, - ) - db_span.__enter__() + db_span = sentry_sdk.traces.start_span( + name=db_properties["description"], + attributes={ + "sentry.op": db_properties["op"], + "sentry.origin": SPAN_ORIGIN, + **additional_db_span_attributes, + }, + ) set_db_data_fn(db_span, self) _set_client_data(db_span, is_cluster, name, *args) value = old_execute_command(self, name, *args, **kwargs) - db_span.__exit__(None, None, None) + db_span.end() if cache_span: _set_cache_data(cache_span, self, cache_properties, value) - cache_span.__exit__(None, None, None) + cache_span.end() return value diff --git a/sentry_sdk/integrations/redis/consts.py b/sentry_sdk/integrations/redis/consts.py index 579bdd4f15..60e1220650 100644 --- a/sentry_sdk/integrations/redis/consts.py +++ b/sentry_sdk/integrations/redis/consts.py @@ -15,4 +15,3 @@ "auth", ] _MAX_NUM_ARGS = 10 # Trim argument lists to this many values -_MAX_NUM_COMMANDS = 10 # Trim command lists to this many values diff --git a/sentry_sdk/integrations/redis/modules/queries.py b/sentry_sdk/integrations/redis/modules/queries.py index 968e3dcec0..3b41cfd69e 100644 --- a/sentry_sdk/integrations/redis/modules/queries.py +++ b/sentry_sdk/integrations/redis/modules/queries.py @@ -6,16 +6,15 @@ from sentry_sdk.consts import OP, SPANDATA from sentry_sdk.integrations.redis.utils import _get_safe_command -from sentry_sdk.traces import StreamedSpan from sentry_sdk.utils import capture_internal_exceptions if TYPE_CHECKING: - from typing import Any, Union + from typing import Any from redis import Redis from sentry_sdk.integrations.redis import RedisIntegration - from sentry_sdk.tracing import Span + from sentry_sdk.traces import StreamedSpan def _compile_db_span_properties( @@ -43,42 +42,26 @@ def _get_db_span_description( def _set_db_data_on_span( - span: "Union[Span, StreamedSpan]", connection_params: "dict[str, Any]" + span: "StreamedSpan", connection_params: "dict[str, Any]" ) -> None: db = connection_params.get("db") host = connection_params.get("host") port = connection_params.get("port") - if isinstance(span, StreamedSpan): - span.set_attribute(SPANDATA.DB_SYSTEM_NAME, "redis") - span.set_attribute(SPANDATA.DB_DRIVER_NAME, "redis-py") + span.set_attribute(SPANDATA.DB_SYSTEM_NAME, "redis") + span.set_attribute(SPANDATA.DB_DRIVER_NAME, "redis-py") - if db is not None: - span.set_attribute(SPANDATA.DB_NAMESPACE, str(db)) + if db is not None: + span.set_attribute(SPANDATA.DB_NAMESPACE, str(db)) - if host is not None: - span.set_attribute(SPANDATA.SERVER_ADDRESS, host) + if host is not None: + span.set_attribute(SPANDATA.SERVER_ADDRESS, host) - if port is not None: - span.set_attribute(SPANDATA.SERVER_PORT, port) + if port is not None: + span.set_attribute(SPANDATA.SERVER_PORT, port) - else: - span.set_data(SPANDATA.DB_SYSTEM, "redis") - span.set_data(SPANDATA.DB_DRIVER_NAME, "redis-py") - if db is not None: - span.set_data(SPANDATA.DB_NAME, str(db)) - - if host is not None: - span.set_data(SPANDATA.SERVER_ADDRESS, host) - - if port is not None: - span.set_data(SPANDATA.SERVER_PORT, port) - - -def _set_db_data( - span: "Union[Span, StreamedSpan]", redis_instance: "Redis[Any]" -) -> None: +def _set_db_data(span: "StreamedSpan", redis_instance: "Redis[Any]") -> None: try: _set_db_data_on_span(span, redis_instance.connection_pool.connection_kwargs) except AttributeError: diff --git a/sentry_sdk/integrations/redis/redis_cluster.py b/sentry_sdk/integrations/redis/redis_cluster.py index b6c95e6abd..74cd12cab7 100644 --- a/sentry_sdk/integrations/redis/redis_cluster.py +++ b/sentry_sdk/integrations/redis/redis_cluster.py @@ -16,7 +16,7 @@ from sentry_sdk.utils import capture_internal_exceptions if TYPE_CHECKING: - from typing import Any, Union + from typing import Any from redis import RedisCluster from redis.asyncio.cluster import ( @@ -27,11 +27,10 @@ ) from sentry_sdk.traces import StreamedSpan - from sentry_sdk.tracing import Span def _set_async_cluster_db_data( - span: "Union[Span, StreamedSpan]", + span: "StreamedSpan", async_redis_cluster_instance: "AsyncRedisCluster[Any]", ) -> None: default_node = async_redis_cluster_instance.get_default_node() @@ -40,7 +39,7 @@ def _set_async_cluster_db_data( def _set_async_cluster_pipeline_db_data( - span: "Union[Span, StreamedSpan]", + span: "StreamedSpan", async_redis_cluster_pipeline_instance: "AsyncClusterPipeline[Any]", ) -> None: with capture_internal_exceptions(): @@ -61,7 +60,7 @@ def _set_async_cluster_pipeline_db_data( def _set_cluster_db_data( - span: "Union[Span, StreamedSpan]", redis_cluster_instance: "RedisCluster[Any]" + span: "StreamedSpan", redis_cluster_instance: "RedisCluster[Any]" ) -> None: default_node = redis_cluster_instance.get_default_node() diff --git a/sentry_sdk/integrations/redis/utils.py b/sentry_sdk/integrations/redis/utils.py index d7def5edf9..b14626a62d 100644 --- a/sentry_sdk/integrations/redis/utils.py +++ b/sentry_sdk/integrations/redis/utils.py @@ -5,17 +5,15 @@ from sentry_sdk.integrations.redis.consts import ( _COMMANDS_INCLUDING_SENSITIVE_DATA, _MAX_NUM_ARGS, - _MAX_NUM_COMMANDS, _MULTI_KEY_COMMANDS, _SINGLE_KEY_COMMANDS, ) from sentry_sdk.scope import should_send_default_pii from sentry_sdk.traces import StreamedSpan -from sentry_sdk.tracing import Span from sentry_sdk.utils import SENSITIVE_DATA_SUBSTITUTE, has_data_collection_enabled if TYPE_CHECKING: - from typing import Any, Optional, Sequence, Union + from typing import Any, Optional, Sequence def _get_safe_command(name: str, args: "Sequence[Any]") -> str: @@ -110,45 +108,15 @@ def _parse_rediscluster_command(command: "Any") -> "Sequence[Any]": return command.args -def _set_pipeline_data( - span: "Union[Span, StreamedSpan]", - is_cluster: bool, - get_command_args_fn: "Any", - is_transaction: bool, - commands_seq: "Sequence[Any]", -) -> None: - # TODO: Remove this whole function when removing transaction based tracing - if isinstance(span, StreamedSpan): - return - - commands = [] - for i, arg in enumerate(commands_seq): - if i >= _MAX_NUM_COMMANDS: - break - - command = get_command_args_fn(arg) - commands.append(_get_safe_command(command[0], command[1:])) - - span.set_data( - "redis.commands", - { - "count": len(commands_seq), - "first_ten": commands, - }, - ) - - def _set_client_data( - span: "Union[Span, StreamedSpan]", is_cluster: bool, name: str, *args: "Any" + span: "StreamedSpan", is_cluster: bool, name: str, *args: "Any" ) -> None: - if isinstance(span, StreamedSpan): - if name: - span.set_attribute(SPANDATA.DB_OPERATION_NAME, name) + if name: + span.set_attribute(SPANDATA.DB_OPERATION_NAME, name) key = _extract_key(name, args) if key is not None: - if isinstance(span, StreamedSpan): - span.set_attribute("db.redis.key", key) + span.set_attribute("db.redis.key", key) def _extract_key(name: str, args: "Any") -> "Optional[str]": diff --git a/tests/integrations/redis/asyncio/test_redis_asyncio.py b/tests/integrations/redis/asyncio/test_redis_asyncio.py index 6bf6d78ed9..1716bad85c 100644 --- a/tests/integrations/redis/asyncio/test_redis_asyncio.py +++ b/tests/integrations/redis/asyncio/test_redis_asyncio.py @@ -2,10 +2,9 @@ from fakeredis.aioredis import FakeRedis import sentry_sdk -from sentry_sdk import capture_message, start_transaction +from sentry_sdk import capture_message from sentry_sdk.consts import SPANDATA from sentry_sdk.integrations.redis import RedisIntegration -from tests.conftest import ApproxDict @pytest.mark.asyncio @@ -35,7 +34,6 @@ async def test_async_basic(sentry_init, capture_events): } -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.parametrize( "is_transaction, send_default_pii, expected_first_ten", [ @@ -51,118 +49,69 @@ async def test_async_redis_pipeline( is_transaction, send_default_pii, expected_first_ten, - span_streaming, ): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, send_default_pii=send_default_pii, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - pipeline = connection.pipeline(transaction=is_transaction) - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - await pipeline.execute() - sentry_sdk.flush() - - assert len(items) == 2 - pipeline_span, parent_span = items[0].payload, items[1].payload - - assert parent_span["name"] == "custom parent" - assert pipeline_span["name"] == "redis.pipeline.execute" - attrs = pipeline_span["attributes"] - assert attrs["sentry.op"] == "db.redis" - assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" - assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" - assert attrs[SPANDATA.DB_NAMESPACE] == "0" - assert attrs[SPANDATA.SERVER_ADDRESS] == ( - connection.connection_pool.connection_kwargs.get("host") - ) - assert attrs[SPANDATA.SERVER_PORT] == 6379 - else: - events = capture_events() - with start_transaction(): - pipeline = connection.pipeline(transaction=is_transaction) - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - await pipeline.execute() - - (event,) = events - (span,) = event["spans"] - assert span["op"] == "db.redis" - assert span["description"] == "redis.pipeline.execute" - assert span["data"] == ApproxDict( - { - "redis.commands": { - "count": 3, - "first_ten": expected_first_ten, - }, - SPANDATA.DB_SYSTEM: "redis", - SPANDATA.DB_NAME: "0", - SPANDATA.SERVER_ADDRESS: connection.connection_pool.connection_kwargs.get( - "host" - ), - SPANDATA.SERVER_PORT: 6379, - } - ) - - -@pytest.mark.parametrize("span_streaming", [True, False]) + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + pipeline = connection.pipeline(transaction=is_transaction) + pipeline.get("foo") + pipeline.set("bar", 1) + pipeline.set("baz", 2) + await pipeline.execute() + + sentry_sdk.flush() + + assert len(items) == 2 + pipeline_span, parent_span = items[0].payload, items[1].payload + + assert parent_span["name"] == "custom parent" + assert pipeline_span["name"] == "redis.pipeline.execute" + attrs = pipeline_span["attributes"] + assert attrs["sentry.op"] == "db.redis" + assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" + assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" + assert attrs[SPANDATA.DB_NAMESPACE] == "0" + assert attrs[SPANDATA.SERVER_ADDRESS] == ( + connection.connection_pool.connection_kwargs.get("host") + ) + assert attrs[SPANDATA.SERVER_PORT] == 6379 + + @pytest.mark.asyncio -async def test_async_span_origin( - sentry_init, capture_events, capture_items, span_streaming -): +async def test_async_span_origin(sentry_init, capture_events, capture_items): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - # default case - await connection.set("somekey", "somevalue") - - # pipeline - pipeline = connection.pipeline(transaction=False) - pipeline.get("somekey") - pipeline.set("anotherkey", 1) - await pipeline.execute() - sentry_sdk.flush() - - assert len(items) == 3 - set_span, pipeline_span, parent_span = [item.payload for item in items] - - assert parent_span["name"] == "custom parent" - assert parent_span["attributes"]["sentry.origin"] == "manual" - assert set_span["attributes"]["sentry.origin"] == "auto.db.redis" - assert pipeline_span["attributes"]["sentry.origin"] == "auto.db.redis" - else: - events = capture_events() - with start_transaction(name="custom_transaction"): - # default case - await connection.set("somekey", "somevalue") - - # pipeline - pipeline = connection.pipeline(transaction=False) - pipeline.get("somekey") - pipeline.set("anotherkey", 1) - await pipeline.execute() - - (event,) = events - - assert event["contexts"]["trace"]["origin"] == "manual" - - for span in event["spans"]: - assert span["origin"] == "auto.db.redis" + items = capture_items("span") + with sentry_sdk.traces.start_span(name="custom parent"): + # default case + await connection.set("somekey", "somevalue") + + # pipeline + pipeline = connection.pipeline(transaction=False) + pipeline.get("somekey") + pipeline.set("anotherkey", 1) + await pipeline.execute() + sentry_sdk.flush() + + assert len(items) == 3 + set_span, pipeline_span, parent_span = [item.payload for item in items] + + assert parent_span["name"] == "custom parent" + assert parent_span["attributes"]["sentry.origin"] == "manual" + assert set_span["attributes"]["sentry.origin"] == "auto.db.redis" + assert pipeline_span["attributes"]["sentry.origin"] == "auto.db.redis" diff --git a/tests/integrations/redis/cluster/test_redis_cluster.py b/tests/integrations/redis/cluster/test_redis_cluster.py index d4e45d3d7d..dadfe7cd41 100644 --- a/tests/integrations/redis/cluster/test_redis_cluster.py +++ b/tests/integrations/redis/cluster/test_redis_cluster.py @@ -5,10 +5,8 @@ import sentry_sdk from sentry_sdk import capture_message -from sentry_sdk.api import start_transaction from sentry_sdk.consts import SPANDATA from sentry_sdk.integrations.redis import RedisIntegration -from tests.conftest import ApproxDict @pytest.fixture(autouse=True) @@ -58,7 +56,6 @@ def test_rediscluster_breadcrumb(sentry_init, capture_events): } -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.parametrize( "send_default_pii, description", [ @@ -72,69 +69,43 @@ def test_rediscluster_basic( capture_items, send_default_pii, description, - span_streaming, ): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, send_default_pii=send_default_pii, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - rc = redis.RedisCluster(host="localhost", port=6379) - rc.set("bar", 1) - sentry_sdk.flush() - - # on initializing a RedisCluster, a COMMAND call may be emitted - payloads = [item.payload for item in items] - parent_span = payloads[-1] - redis_spans = payloads[:-1] - assert parent_span["name"] == "custom parent" - assert len(redis_spans) in (1, 2) - assert len(redis_spans) == 1 or redis_spans[0]["name"] == "COMMAND" - - span = redis_spans[-1] - assert span["name"] == description - attrs = span["attributes"] - assert attrs["sentry.op"] == "db.redis" - assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" - assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" - # ClusterNode converts localhost to 127.0.0.1 - assert attrs[SPANDATA.SERVER_ADDRESS] == "127.0.0.1" - assert attrs[SPANDATA.SERVER_PORT] == 6379 - assert attrs[SPANDATA.DB_OPERATION_NAME] == "SET" - assert attrs["db.redis.key"] == "bar" - else: - events = capture_events() - with start_transaction(): - rc = redis.RedisCluster(host="localhost", port=6379) - rc.set("bar", 1) - - (event,) = events - spans = event["spans"] - - # on initializing a RedisCluster, a COMMAND call is made - this is not important for the test - # but must be accounted for - assert len(spans) in (1, 2) - assert len(spans) == 1 or spans[0]["description"] == "COMMAND" - - span = spans[-1] - assert span["op"] == "db.redis" - assert span["description"] == description - assert span["data"] == ApproxDict( - { - SPANDATA.DB_SYSTEM: "redis", - # ClusterNode converts localhost to 127.0.0.1 - SPANDATA.SERVER_ADDRESS: "127.0.0.1", - SPANDATA.SERVER_PORT: 6379, - } - ) - - -@pytest.mark.parametrize("span_streaming", [True, False]) + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + rc = redis.RedisCluster(host="localhost", port=6379) + rc.set("bar", 1) + + sentry_sdk.flush() + + # on initializing a RedisCluster, a COMMAND call may be emitted + payloads = [item.payload for item in items] + parent_span = payloads[-1] + redis_spans = payloads[:-1] + assert parent_span["name"] == "custom parent" + assert len(redis_spans) in (1, 2) + assert len(redis_spans) == 1 or redis_spans[0]["name"] == "COMMAND" + + span = redis_spans[-1] + assert span["name"] == description + attrs = span["attributes"] + assert attrs["sentry.op"] == "db.redis" + assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" + assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" + # ClusterNode converts localhost to 127.0.0.1 + assert attrs[SPANDATA.SERVER_ADDRESS] == "127.0.0.1" + assert attrs[SPANDATA.SERVER_PORT] == 6379 + assert attrs[SPANDATA.DB_OPERATION_NAME] == "SET" + assert attrs["db.redis.key"] == "bar" + + @pytest.mark.parametrize( "send_default_pii, expected_first_ten", [ @@ -148,120 +119,78 @@ def test_rediscluster_pipeline( capture_items, send_default_pii, expected_first_ten, - span_streaming, ): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, send_default_pii=send_default_pii, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) rc = redis.RedisCluster(host="localhost", port=6379) - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - pipeline = rc.pipeline() - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - pipeline.execute() - sentry_sdk.flush() - - # on initializing a RedisCluster, a COMMAND call may be emitted - payloads = [item.payload for item in items] - parent_span = payloads[-1] - redis_spans = payloads[:-1] - assert parent_span["name"] == "custom parent" - assert len(redis_spans) in (1, 2) - assert len(redis_spans) == 1 or redis_spans[0]["name"] == "COMMAND" - - pipeline_span = redis_spans[-1] - assert pipeline_span["name"] == "redis.pipeline.execute" - attrs = pipeline_span["attributes"] - assert attrs["sentry.op"] == "db.redis" - assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" - assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" - # ClusterNode converts localhost to 127.0.0.1 - assert attrs[SPANDATA.SERVER_ADDRESS] == "127.0.0.1" - assert attrs[SPANDATA.SERVER_PORT] == 6379 - else: - events = capture_events() - with start_transaction(): - pipeline = rc.pipeline() - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - pipeline.execute() - - (event,) = events - (span,) = event["spans"] - assert span["op"] == "db.redis" - assert span["description"] == "redis.pipeline.execute" - assert span["data"] == ApproxDict( - { - "redis.commands": { - "count": 3, - "first_ten": expected_first_ten, - }, - SPANDATA.DB_SYSTEM: "redis", - # ClusterNode converts localhost to 127.0.0.1 - SPANDATA.SERVER_ADDRESS: "127.0.0.1", - SPANDATA.SERVER_PORT: 6379, - } - ) - - -@pytest.mark.parametrize("span_streaming", [True, False]) + items = capture_items("span") + with sentry_sdk.traces.start_span(name="custom parent"): + pipeline = rc.pipeline() + pipeline.get("foo") + pipeline.set("bar", 1) + pipeline.set("baz", 2) + pipeline.execute() + sentry_sdk.flush() + + # on initializing a RedisCluster, a COMMAND call may be emitted + payloads = [item.payload for item in items] + parent_span = payloads[-1] + redis_spans = payloads[:-1] + assert parent_span["name"] == "custom parent" + assert len(redis_spans) in (1, 2) + assert len(redis_spans) == 1 or redis_spans[0]["name"] == "COMMAND" + + pipeline_span = redis_spans[-1] + assert pipeline_span["name"] == "redis.pipeline.execute" + attrs = pipeline_span["attributes"] + assert attrs["sentry.op"] == "db.redis" + assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" + assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" + # ClusterNode converts localhost to 127.0.0.1 + assert attrs[SPANDATA.SERVER_ADDRESS] == "127.0.0.1" + assert attrs[SPANDATA.SERVER_PORT] == 6379 + + def test_rediscluster_span_origin( - sentry_init, capture_events, capture_items, span_streaming + sentry_init, + capture_events, + capture_items, ): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) rc = redis.RedisCluster(host="localhost", port=6379) - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - # default case - rc.set("somekey", "somevalue") - - # pipeline - pipeline = rc.pipeline(transaction=False) - pipeline.get("somekey") - pipeline.set("anotherkey", 1) - pipeline.execute() - sentry_sdk.flush() - - payloads = [item.payload for item in items] - parent_span = payloads[-1] - redis_spans = payloads[:-1] - - assert parent_span["name"] == "custom parent" - assert parent_span["attributes"]["sentry.origin"] == "manual" - assert len(redis_spans) >= 2 - for span in redis_spans: - assert span["attributes"]["sentry.origin"] == "auto.db.redis" - else: - events = capture_events() - with start_transaction(name="custom_transaction"): - # default case - rc.set("somekey", "somevalue") - - # pipeline - pipeline = rc.pipeline(transaction=False) - pipeline.get("somekey") - pipeline.set("anotherkey", 1) - pipeline.execute() - - (event,) = events - - assert event["contexts"]["trace"]["origin"] == "manual" - - for span in event["spans"]: - assert span["origin"] == "auto.db.redis" + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + # default case + rc.set("somekey", "somevalue") + + # pipeline + pipeline = rc.pipeline(transaction=False) + pipeline.get("somekey") + pipeline.set("anotherkey", 1) + pipeline.execute() + + sentry_sdk.flush() + + payloads = [item.payload for item in items] + parent_span = payloads[-1] + redis_spans = payloads[:-1] + + assert parent_span["name"] == "custom parent" + assert parent_span["attributes"]["sentry.origin"] == "manual" + assert len(redis_spans) >= 2 + + for span in redis_spans: + assert span["attributes"]["sentry.origin"] == "auto.db.redis" diff --git a/tests/integrations/redis/cluster_asyncio/test_redis_cluster_asyncio.py b/tests/integrations/redis/cluster_asyncio/test_redis_cluster_asyncio.py index c9c82b0ff8..97abfa617e 100644 --- a/tests/integrations/redis/cluster_asyncio/test_redis_cluster_asyncio.py +++ b/tests/integrations/redis/cluster_asyncio/test_redis_cluster_asyncio.py @@ -2,7 +2,7 @@ from redis.asyncio import cluster import sentry_sdk -from sentry_sdk import capture_message, start_transaction +from sentry_sdk import capture_message from sentry_sdk.consts import SPANDATA from sentry_sdk.integrations.redis import RedisIntegration from tests.conftest import ApproxDict @@ -61,7 +61,6 @@ async def test_async_breadcrumb(sentry_init, capture_events): } -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.parametrize( "send_default_pii, description", [ @@ -76,56 +75,38 @@ async def test_async_basic( capture_items, send_default_pii, description, - span_streaming, ): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, send_default_pii=send_default_pii, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = cluster.RedisCluster(host="localhost", port=6379) - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - await connection.set("bar", 1) - sentry_sdk.flush() - - assert len(items) == 2 - redis_span, parent_span = items[0].payload, items[1].payload - - assert parent_span["name"] == "custom parent" - assert redis_span["name"] == description - attrs = redis_span["attributes"] - assert attrs["sentry.op"] == "db.redis" - assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" - assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" - assert attrs[SPANDATA.SERVER_ADDRESS] == "127.0.0.1" - assert attrs[SPANDATA.SERVER_PORT] == 6379 - assert attrs[SPANDATA.DB_OPERATION_NAME] == "SET" - assert attrs["db.redis.key"] == "bar" - else: - events = capture_events() - with start_transaction(): - await connection.set("bar", 1) - - (event,) = events - (span,) = event["spans"] - assert span["op"] == "db.redis" - assert span["description"] == description - assert span["data"] == ApproxDict( - { - SPANDATA.DB_SYSTEM: "redis", - # ClusterNode converts localhost to 127.0.0.1 - SPANDATA.SERVER_ADDRESS: "127.0.0.1", - SPANDATA.SERVER_PORT: 6379, - } - ) + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + await connection.set("bar", 1) + + sentry_sdk.flush() + + assert len(items) == 2 + redis_span, parent_span = items[0].payload, items[1].payload + + assert parent_span["name"] == "custom parent" + assert redis_span["name"] == description + attrs = redis_span["attributes"] + assert attrs["sentry.op"] == "db.redis" + assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" + assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" + assert attrs[SPANDATA.SERVER_ADDRESS] == "127.0.0.1" + assert attrs[SPANDATA.SERVER_PORT] == 6379 + assert attrs[SPANDATA.DB_OPERATION_NAME] == "SET" + assert attrs["db.redis.key"] == "bar" -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.parametrize( "send_default_pii, expected_first_ten", [ @@ -136,117 +117,71 @@ async def test_async_basic( @pytest.mark.asyncio async def test_async_redis_pipeline( sentry_init, - capture_events, capture_items, send_default_pii, expected_first_ten, - span_streaming, ): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, send_default_pii=send_default_pii, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = cluster.RedisCluster(host="localhost", port=6379) - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - pipeline = connection.pipeline() - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - await pipeline.execute() - sentry_sdk.flush() - - assert len(items) == 2 - pipeline_span, parent_span = items[0].payload, items[1].payload - - assert parent_span["name"] == "custom parent" - assert pipeline_span["name"] == "redis.pipeline.execute" - attrs = pipeline_span["attributes"] - assert attrs["sentry.op"] == "db.redis" - assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" - assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" - assert attrs[SPANDATA.SERVER_ADDRESS] == "127.0.0.1" - assert attrs[SPANDATA.SERVER_PORT] == 6379 - else: - events = capture_events() - with start_transaction(): - pipeline = connection.pipeline() - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - await pipeline.execute() - - (event,) = events - (span,) = event["spans"] - assert span["op"] == "db.redis" - assert span["description"] == "redis.pipeline.execute" - assert span["data"] == ApproxDict( - { - "redis.commands": { - "count": 3, - "first_ten": expected_first_ten, - }, - SPANDATA.DB_SYSTEM: "redis", - # ClusterNode converts localhost to 127.0.0.1 - SPANDATA.SERVER_ADDRESS: "127.0.0.1", - SPANDATA.SERVER_PORT: 6379, - } - ) + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + pipeline = connection.pipeline() + pipeline.get("foo") + pipeline.set("bar", 1) + pipeline.set("baz", 2) + await pipeline.execute() + + sentry_sdk.flush() + + assert len(items) == 2 + pipeline_span, parent_span = items[0].payload, items[1].payload + + assert parent_span["name"] == "custom parent" + assert pipeline_span["name"] == "redis.pipeline.execute" + attrs = pipeline_span["attributes"] + assert attrs["sentry.op"] == "db.redis" + assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" + assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" + assert attrs[SPANDATA.SERVER_ADDRESS] == "127.0.0.1" + assert attrs[SPANDATA.SERVER_PORT] == 6379 -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.asyncio -async def test_async_span_origin( - sentry_init, capture_events, capture_items, span_streaming -): +async def test_async_span_origin(sentry_init, capture_items): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = cluster.RedisCluster(host="localhost", port=6379) - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - # default case - await connection.set("somekey", "somevalue") - - # pipeline - pipeline = connection.pipeline(transaction=False) - pipeline.get("somekey") - pipeline.set("anotherkey", 1) - await pipeline.execute() - sentry_sdk.flush() - - assert len(items) == 3 - set_span, pipeline_span, parent_span = [item.payload for item in items] - - assert parent_span["name"] == "custom parent" - assert parent_span["attributes"]["sentry.origin"] == "manual" - assert set_span["attributes"]["sentry.origin"] == "auto.db.redis" - assert pipeline_span["attributes"]["sentry.origin"] == "auto.db.redis" - else: - events = capture_events() - with start_transaction(name="custom_transaction"): - # default case - await connection.set("somekey", "somevalue") - - # pipeline - pipeline = connection.pipeline(transaction=False) - pipeline.get("somekey") - pipeline.set("anotherkey", 1) - await pipeline.execute() - - (event,) = events - - assert event["contexts"]["trace"]["origin"] == "manual" - - for span in event["spans"]: - assert span["origin"] == "auto.db.redis" + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + # default case + await connection.set("somekey", "somevalue") + + # pipeline + pipeline = connection.pipeline(transaction=False) + pipeline.get("somekey") + pipeline.set("anotherkey", 1) + await pipeline.execute() + + sentry_sdk.flush() + + assert len(items) == 3 + set_span, pipeline_span, parent_span = [item.payload for item in items] + + assert parent_span["name"] == "custom parent" + assert parent_span["attributes"]["sentry.origin"] == "manual" + assert set_span["attributes"]["sentry.origin"] == "auto.db.redis" + assert pipeline_span["attributes"]["sentry.origin"] == "auto.db.redis" diff --git a/tests/integrations/redis/test_redis.py b/tests/integrations/redis/test_redis.py index 0f212bd03b..abc6a0d86e 100644 --- a/tests/integrations/redis/test_redis.py +++ b/tests/integrations/redis/test_redis.py @@ -4,7 +4,7 @@ from fakeredis import FakeRedis import sentry_sdk -from sentry_sdk import capture_message, start_transaction +from sentry_sdk import capture_message from sentry_sdk.consts import SPANDATA from sentry_sdk.integrations.redis import RedisIntegration @@ -42,7 +42,6 @@ def test_basic(sentry_init, capture_events): } -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.parametrize( "is_transaction, send_default_pii, expected_first_ten", [ @@ -57,58 +56,39 @@ def test_redis_pipeline( is_transaction, send_default_pii, expected_first_ten, - span_streaming, ): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, send_default_pii=send_default_pii, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - pipeline = connection.pipeline(transaction=is_transaction) - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - pipeline.execute() - sentry_sdk.flush() + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + pipeline = connection.pipeline(transaction=is_transaction) + pipeline.get("foo") + pipeline.set("bar", 1) + pipeline.set("baz", 2) + pipeline.execute() + + sentry_sdk.flush() + + assert len(items) == 2 + pipeline_span, parent_span = items[0].payload, items[1].payload + + assert parent_span["name"] == "custom parent" + assert parent_span["is_segment"] is True + + assert pipeline_span["name"] == "redis.pipeline.execute" + assert pipeline_span["attributes"]["sentry.op"] == "db.redis" + assert pipeline_span["attributes"]["sentry.origin"] == "auto.db.redis" + assert pipeline_span["attributes"][SPANDATA.DB_SYSTEM_NAME] == "redis" - assert len(items) == 2 - pipeline_span, parent_span = items[0].payload, items[1].payload - assert parent_span["name"] == "custom parent" - assert parent_span["is_segment"] is True - - assert pipeline_span["name"] == "redis.pipeline.execute" - assert pipeline_span["attributes"]["sentry.op"] == "db.redis" - assert pipeline_span["attributes"]["sentry.origin"] == "auto.db.redis" - assert pipeline_span["attributes"][SPANDATA.DB_SYSTEM_NAME] == "redis" - else: - events = capture_events() - with start_transaction(): - pipeline = connection.pipeline(transaction=is_transaction) - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - pipeline.execute() - - (event,) = events - (span,) = event["spans"] - assert span["op"] == "db.redis" - assert span["description"] == "redis.pipeline.execute" - assert span["data"][SPANDATA.DB_SYSTEM] == "redis" - assert span["data"]["redis.commands"] == { - "count": 3, - "first_ten": expected_first_ten, - } - - -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.parametrize( "data_collection, expected_first_ten", [ @@ -128,54 +108,40 @@ def test_redis_pipeline_data_collection( capture_items, data_collection, expected_first_ten, - span_streaming, ): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", _experiments={"data_collection": data_collection}, ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - pipeline = connection.pipeline(transaction=False) - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - pipeline.execute() - sentry_sdk.flush() + items = capture_items("span") - assert len(items) == 2 - pipeline_span, parent_span = items[0].payload, items[1].payload + with sentry_sdk.traces.start_span(name="custom parent"): + pipeline = connection.pipeline(transaction=False) + pipeline.get("foo") + pipeline.set("bar", 1) + pipeline.set("baz", 2) + pipeline.execute() - assert parent_span["name"] == "custom parent" - assert pipeline_span["name"] == "redis.pipeline.execute" - assert pipeline_span["attributes"]["sentry.op"] == "db.redis" - else: - events = capture_events() - with start_transaction(): - pipeline = connection.pipeline(transaction=False) - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - pipeline.execute() - - (event,) = events - (span,) = event["spans"] - assert span["op"] == "db.redis" - assert span["description"] == "redis.pipeline.execute" - assert span["data"]["redis.commands"] == { - "count": 3, - "first_ten": expected_first_ten, - } - - -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_sensitive_data(sentry_init, capture_events, capture_items, span_streaming): + sentry_sdk.flush() + + assert len(items) == 2 + pipeline_span, parent_span = items[0].payload, items[1].payload + + assert parent_span["name"] == "custom parent" + assert pipeline_span["name"] == "redis.pipeline.execute" + assert pipeline_span["attributes"]["sentry.op"] == "db.redis" + + +def test_sensitive_data( + sentry_init, + capture_events, + capture_items, +): # fakeredis does not support the AUTH command, so we need to mock it with mock.patch( "sentry_sdk.integrations.redis.utils._COMMANDS_INCLUDING_SENSITIVE_DATA", @@ -185,85 +151,61 @@ def test_sensitive_data(sentry_init, capture_events, capture_items, span_streami integrations=[RedisIntegration()], traces_sample_rate=1.0, send_default_pii=True, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.get("this is super secret") - sentry_sdk.flush() - - assert len(items) == 2 - redis_span, parent_span = items[0].payload, items[1].payload - - assert parent_span["name"] == "custom parent" - assert redis_span["name"] == "GET [Filtered]" - assert redis_span["attributes"][SPANDATA.DB_QUERY_TEXT] == "GET [Filtered]" - assert redis_span["attributes"]["sentry.op"] == "db.redis" - else: - events = capture_events() - with start_transaction(): - connection.get( - "this is super secret" - ) # because fakeredis does not support AUTH we use GET instead - - (event,) = events - spans = event["spans"] - assert spans[0]["op"] == "db.redis" - assert spans[0]["description"] == "GET [Filtered]" - - -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_pii_data_redacted(sentry_init, capture_events, capture_items, span_streaming): + items = capture_items("span") + with sentry_sdk.traces.start_span(name="custom parent"): + connection.get("this is super secret") + sentry_sdk.flush() + + assert len(items) == 2 + redis_span, parent_span = items[0].payload, items[1].payload + + assert parent_span["name"] == "custom parent" + assert redis_span["name"] == "GET [Filtered]" + assert redis_span["attributes"][SPANDATA.DB_QUERY_TEXT] == "GET [Filtered]" + assert redis_span["attributes"]["sentry.op"] == "db.redis" + + +def test_pii_data_redacted( + sentry_init, + capture_events, + capture_items, +): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.set("somekey1", "my secret string1") - connection.set("somekey2", "my secret string2") - connection.get("somekey2") - connection.delete("somekey1", "somekey2") - sentry_sdk.flush() + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + connection.set("somekey1", "my secret string1") + connection.set("somekey2", "my secret string2") + connection.get("somekey2") + connection.delete("somekey1", "somekey2") + + sentry_sdk.flush() + + assert len(items) == 5 + set1, set2, get, delete, parent = [item.payload for item in items] + + assert parent["name"] == "custom parent" + assert set1["name"] == "SET 'somekey1' [Filtered]" + assert set1["attributes"][SPANDATA.DB_QUERY_TEXT] == "SET 'somekey1' [Filtered]" + assert set1["attributes"]["sentry.op"] == "db.redis" + assert set2["name"] == "SET 'somekey2' [Filtered]" + assert set2["attributes"][SPANDATA.DB_QUERY_TEXT] == "SET 'somekey2' [Filtered]" + assert get["name"] == "GET 'somekey2'" + assert delete["name"] == "DEL 'somekey1' [Filtered]" + - assert len(items) == 5 - set1, set2, get, delete, parent = [item.payload for item in items] - - assert parent["name"] == "custom parent" - assert set1["name"] == "SET 'somekey1' [Filtered]" - assert set1["attributes"][SPANDATA.DB_QUERY_TEXT] == "SET 'somekey1' [Filtered]" - assert set1["attributes"]["sentry.op"] == "db.redis" - assert set2["name"] == "SET 'somekey2' [Filtered]" - assert set2["attributes"][SPANDATA.DB_QUERY_TEXT] == "SET 'somekey2' [Filtered]" - assert get["name"] == "GET 'somekey2'" - assert delete["name"] == "DEL 'somekey1' [Filtered]" - else: - events = capture_events() - with start_transaction(): - connection.set("somekey1", "my secret string1") - connection.set("somekey2", "my secret string2") - connection.get("somekey2") - connection.delete("somekey1", "somekey2") - - (event,) = events - spans = event["spans"] - assert spans[0]["op"] == "db.redis" - assert spans[0]["description"] == "SET 'somekey1' [Filtered]" - assert spans[1]["description"] == "SET 'somekey2' [Filtered]" - assert spans[2]["description"] == "GET 'somekey2'" - assert spans[3]["description"] == "DEL 'somekey1' [Filtered]" - - -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.parametrize( "data_collection, expected_description", [ @@ -281,44 +223,34 @@ def test_data_collection_database_query_data( sentry_init, capture_events, capture_items, - span_streaming, data_collection, expected_description, ): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", _experiments={"data_collection": data_collection}, ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.set("somekey1", "my secret string1") - sentry_sdk.flush() + items = capture_items("span") - assert len(items) == 2 - set_span, parent = [item.payload for item in items] + with sentry_sdk.traces.start_span(name="custom parent"): + connection.set("somekey1", "my secret string1") + + sentry_sdk.flush() - assert parent["name"] == "custom parent" - assert set_span["name"] == expected_description - assert set_span["attributes"][SPANDATA.DB_QUERY_TEXT] == expected_description - assert set_span["attributes"]["sentry.op"] == "db.redis" - else: - events = capture_events() - with start_transaction(): - connection.set("somekey1", "my secret string1") + assert len(items) == 2 + set_span, parent = [item.payload for item in items] - (event,) = events - spans = event["spans"] - assert spans[0]["op"] == "db.redis" - assert spans[0]["description"] == expected_description + assert parent["name"] == "custom parent" + assert set_span["name"] == expected_description + assert set_span["attributes"][SPANDATA.DB_QUERY_TEXT] == expected_description + assert set_span["attributes"]["sentry.op"] == "db.redis" -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.parametrize( "data_collection, send_default_pii, expected_description", [ @@ -335,7 +267,6 @@ def test_database_query_data_takes_precedence_over_send_default_pii( sentry_init, capture_events, capture_items, - span_streaming, data_collection, send_default_pii, expected_description, @@ -344,138 +275,100 @@ def test_database_query_data_takes_precedence_over_send_default_pii( integrations=[RedisIntegration()], traces_sample_rate=1.0, send_default_pii=send_default_pii, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", _experiments={"data_collection": data_collection}, ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.set("somekey1", "my secret string1") - sentry_sdk.flush() + items = capture_items("span") - assert len(items) == 2 - set_span, parent = [item.payload for item in items] + with sentry_sdk.traces.start_span(name="custom parent"): + connection.set("somekey1", "my secret string1") + + sentry_sdk.flush() - assert parent["name"] == "custom parent" - assert set_span["name"] == expected_description - assert set_span["attributes"][SPANDATA.DB_QUERY_TEXT] == expected_description - assert set_span["attributes"]["sentry.op"] == "db.redis" - else: - events = capture_events() - with start_transaction(): - connection.set("somekey1", "my secret string1") + assert len(items) == 2 + set_span, parent = [item.payload for item in items] - (event,) = events - spans = event["spans"] - assert spans[0]["op"] == "db.redis" - assert spans[0]["description"] == expected_description + assert parent["name"] == "custom parent" + assert set_span["name"] == expected_description + assert set_span["attributes"][SPANDATA.DB_QUERY_TEXT] == expected_description + assert set_span["attributes"]["sentry.op"] == "db.redis" -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_pii_data_sent(sentry_init, capture_events, capture_items, span_streaming): +def test_pii_data_sent(sentry_init, capture_items): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, send_default_pii=True, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.set("somekey1", "my secret string1") - connection.set("somekey2", "my secret string2") - connection.get("somekey2") - connection.delete("somekey1", "somekey2") - sentry_sdk.flush() + items = capture_items("span") - assert len(items) == 5 - set1, set2, get, delete, parent = [item.payload for item in items] + with sentry_sdk.traces.start_span(name="custom parent"): + connection.set("somekey1", "my secret string1") + connection.set("somekey2", "my secret string2") + connection.get("somekey2") + connection.delete("somekey1", "somekey2") - assert parent["name"] == "custom parent" - assert set1["name"] == "SET 'somekey1' 'my secret string1'" - assert ( - set1["attributes"][SPANDATA.DB_QUERY_TEXT] - == "SET 'somekey1' 'my secret string1'" - ) - assert set1["attributes"]["sentry.op"] == "db.redis" - assert set2["name"] == "SET 'somekey2' 'my secret string2'" - assert ( - set2["attributes"][SPANDATA.DB_QUERY_TEXT] - == "SET 'somekey2' 'my secret string2'" - ) - assert get["name"] == "GET 'somekey2'" - assert delete["name"] == "DEL 'somekey1' 'somekey2'" - else: - events = capture_events() - with start_transaction(): - connection.set("somekey1", "my secret string1") - connection.set("somekey2", "my secret string2") - connection.get("somekey2") - connection.delete("somekey1", "somekey2") - - (event,) = events - spans = event["spans"] - assert spans[0]["op"] == "db.redis" - assert spans[0]["description"] == "SET 'somekey1' 'my secret string1'" - assert spans[1]["description"] == "SET 'somekey2' 'my secret string2'" - assert spans[2]["description"] == "GET 'somekey2'" - assert spans[3]["description"] == "DEL 'somekey1' 'somekey2'" - - -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_no_data_truncation_by_default( - sentry_init, capture_events, capture_items, span_streaming -): + sentry_sdk.flush() + + assert len(items) == 5 + set1, set2, get, delete, parent = [item.payload for item in items] + + assert parent["name"] == "custom parent" + assert set1["name"] == "SET 'somekey1' 'my secret string1'" + assert ( + set1["attributes"][SPANDATA.DB_QUERY_TEXT] + == "SET 'somekey1' 'my secret string1'" + ) + assert set1["attributes"]["sentry.op"] == "db.redis" + assert set2["name"] == "SET 'somekey2' 'my secret string2'" + assert ( + set2["attributes"][SPANDATA.DB_QUERY_TEXT] + == "SET 'somekey2' 'my secret string2'" + ) + assert get["name"] == "GET 'somekey2'" + assert delete["name"] == "DEL 'somekey1' 'somekey2'" + + +def test_no_data_truncation_by_default(sentry_init, capture_items): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, send_default_pii=True, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() long_string = "a" * 100000 short_string = "b" * 10 - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.set("somekey1", long_string) - connection.set("somekey2", short_string) - sentry_sdk.flush() + items = capture_items("span") - assert len(items) == 3 - set1, set2, parent = [item.payload for item in items] + with sentry_sdk.traces.start_span(name="custom parent"): + connection.set("somekey1", long_string) + connection.set("somekey2", short_string) - assert parent["name"] == "custom parent" - assert set1["name"] == f"SET 'somekey1' '{long_string}'" - assert ( - set1["attributes"][SPANDATA.DB_QUERY_TEXT] - == f"SET 'somekey1' '{long_string}'" - ) - assert set1["attributes"]["sentry.op"] == "db.redis" - assert set2["name"] == f"SET 'somekey2' '{short_string}'" - assert ( - set2["attributes"][SPANDATA.DB_QUERY_TEXT] - == f"SET 'somekey2' '{short_string}'" - ) - else: - events = capture_events() - with start_transaction(): - connection.set("somekey1", long_string) - connection.set("somekey2", short_string) + sentry_sdk.flush() + + assert len(items) == 3 + set1, set2, parent = [item.payload for item in items] - (event,) = events - spans = event["spans"] - assert spans[0]["op"] == "db.redis" - assert spans[0]["description"] == f"SET 'somekey1' '{long_string}'" - assert spans[1]["description"] == f"SET 'somekey2' '{short_string}'" + assert parent["name"] == "custom parent" + assert set1["name"] == f"SET 'somekey1' '{long_string}'" + assert ( + set1["attributes"][SPANDATA.DB_QUERY_TEXT] == f"SET 'somekey1' '{long_string}'" + ) + assert set1["attributes"]["sentry.op"] == "db.redis" + assert set2["name"] == f"SET 'somekey2' '{short_string}'" + assert ( + set2["attributes"][SPANDATA.DB_QUERY_TEXT] == f"SET 'somekey2' '{short_string}'" + ) def test_breadcrumbs(sentry_init, capture_events): @@ -523,157 +416,97 @@ def test_breadcrumbs(sentry_init, capture_events): } -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_db_connection_attributes_client( - sentry_init, capture_events, capture_items, span_streaming -): +def test_db_connection_attributes_client(sentry_init, capture_items): sentry_init( traces_sample_rate=1.0, integrations=[RedisIntegration()], - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection = FakeRedis(connection_pool=MOCK_CONNECTION_POOL) - connection.get("foobar") - sentry_sdk.flush() + items = capture_items("span") - assert len(items) == 2 - redis_span, parent_span = items[0].payload, items[1].payload + with sentry_sdk.traces.start_span(name="custom parent"): + connection = FakeRedis(connection_pool=MOCK_CONNECTION_POOL) + connection.get("foobar") - assert parent_span["name"] == "custom parent" - assert redis_span["name"] == "GET 'foobar'" - attrs = redis_span["attributes"] - assert attrs["sentry.op"] == "db.redis" - assert attrs[SPANDATA.DB_QUERY_TEXT] == "GET 'foobar'" - assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" - assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" - assert attrs[SPANDATA.DB_NAMESPACE] == "1" - assert attrs[SPANDATA.SERVER_ADDRESS] == "localhost" - assert attrs[SPANDATA.SERVER_PORT] == 63791 - else: - events = capture_events() - with start_transaction(): - connection = FakeRedis(connection_pool=MOCK_CONNECTION_POOL) - connection.get("foobar") - - (event,) = events - (span,) = event["spans"] - - assert span["op"] == "db.redis" - assert span["description"] == "GET 'foobar'" - assert span["data"][SPANDATA.DB_SYSTEM] == "redis" - assert span["data"][SPANDATA.DB_DRIVER_NAME] == "redis-py" - assert span["data"][SPANDATA.DB_NAME] == "1" - assert span["data"][SPANDATA.SERVER_ADDRESS] == "localhost" - assert span["data"][SPANDATA.SERVER_PORT] == 63791 - - -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_db_connection_attributes_pipeline( - sentry_init, capture_events, capture_items, span_streaming -): + sentry_sdk.flush() + + assert len(items) == 2 + redis_span, parent_span = items[0].payload, items[1].payload + + assert parent_span["name"] == "custom parent" + assert redis_span["name"] == "GET 'foobar'" + attrs = redis_span["attributes"] + assert attrs["sentry.op"] == "db.redis" + assert attrs[SPANDATA.DB_QUERY_TEXT] == "GET 'foobar'" + assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" + assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" + assert attrs[SPANDATA.DB_NAMESPACE] == "1" + assert attrs[SPANDATA.SERVER_ADDRESS] == "localhost" + assert attrs[SPANDATA.SERVER_PORT] == 63791 + + +def test_db_connection_attributes_pipeline(sentry_init, capture_items): sentry_init( traces_sample_rate=1.0, integrations=[RedisIntegration()], - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection = FakeRedis(connection_pool=MOCK_CONNECTION_POOL) - pipeline = connection.pipeline(transaction=False) - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - pipeline.execute() - sentry_sdk.flush() + items = capture_items("span") - assert len(items) == 2 - pipeline_span, parent_span = items[0].payload, items[1].payload + with sentry_sdk.traces.start_span(name="custom parent"): + connection = FakeRedis(connection_pool=MOCK_CONNECTION_POOL) + pipeline = connection.pipeline(transaction=False) + pipeline.get("foo") + pipeline.set("bar", 1) + pipeline.set("baz", 2) + pipeline.execute() - assert parent_span["name"] == "custom parent" - assert pipeline_span["name"] == "redis.pipeline.execute" - attrs = pipeline_span["attributes"] - assert attrs["sentry.op"] == "db.redis" - assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" - assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" - assert attrs[SPANDATA.DB_NAMESPACE] == "1" - assert attrs[SPANDATA.SERVER_ADDRESS] == "localhost" - assert attrs[SPANDATA.SERVER_PORT] == 63791 - else: - events = capture_events() - with start_transaction(): - connection = FakeRedis(connection_pool=MOCK_CONNECTION_POOL) - pipeline = connection.pipeline(transaction=False) - pipeline.get("foo") - pipeline.set("bar", 1) - pipeline.set("baz", 2) - pipeline.execute() - - (event,) = events - (span,) = event["spans"] - - assert span["op"] == "db.redis" - assert span["description"] == "redis.pipeline.execute" - assert span["data"][SPANDATA.DB_SYSTEM] == "redis" - assert span["data"][SPANDATA.DB_DRIVER_NAME] == "redis-py" - assert span["data"][SPANDATA.DB_NAME] == "1" - assert span["data"][SPANDATA.SERVER_ADDRESS] == "localhost" - assert span["data"][SPANDATA.SERVER_PORT] == 63791 - - -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_span_origin(sentry_init, capture_events, capture_items, span_streaming): + sentry_sdk.flush() + + assert len(items) == 2 + pipeline_span, parent_span = items[0].payload, items[1].payload + + assert parent_span["name"] == "custom parent" + assert pipeline_span["name"] == "redis.pipeline.execute" + attrs = pipeline_span["attributes"] + assert attrs["sentry.op"] == "db.redis" + assert attrs[SPANDATA.DB_SYSTEM_NAME] == "redis" + assert attrs[SPANDATA.DB_DRIVER_NAME] == "redis-py" + assert attrs[SPANDATA.DB_NAMESPACE] == "1" + assert attrs[SPANDATA.SERVER_ADDRESS] == "localhost" + assert attrs[SPANDATA.SERVER_PORT] == 63791 + + +def test_span_origin(sentry_init, capture_items): sentry_init( integrations=[RedisIntegration()], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - # default case - connection.set("somekey", "somevalue") - - # pipeline - pipeline = connection.pipeline(transaction=False) - pipeline.get("somekey") - pipeline.set("anotherkey", 1) - pipeline.execute() - sentry_sdk.flush() + items = capture_items("span") - assert len(items) == 3 - set_span, pipeline_span, parent_span = [item.payload for item in items] - - assert parent_span["name"] == "custom parent" - assert parent_span["attributes"]["sentry.origin"] == "manual" - assert set_span["attributes"]["sentry.origin"] == "auto.db.redis" - assert ( - set_span["attributes"][SPANDATA.DB_QUERY_TEXT] == "SET 'somekey' [Filtered]" - ) - assert pipeline_span["attributes"]["sentry.origin"] == "auto.db.redis" - else: - events = capture_events() - with start_transaction(name="custom_transaction"): - # default case - connection.set("somekey", "somevalue") + with sentry_sdk.traces.start_span(name="custom parent"): + # default case + connection.set("somekey", "somevalue") - # pipeline - pipeline = connection.pipeline(transaction=False) - pipeline.get("somekey") - pipeline.set("anotherkey", 1) - pipeline.execute() + # pipeline + pipeline = connection.pipeline(transaction=False) + pipeline.get("somekey") + pipeline.set("anotherkey", 1) + pipeline.execute() - (event,) = events + sentry_sdk.flush() - assert event["contexts"]["trace"]["origin"] == "manual" + assert len(items) == 3 + set_span, pipeline_span, parent_span = [item.payload for item in items] - for span in event["spans"]: - assert span["origin"] == "auto.db.redis" + assert parent_span["name"] == "custom parent" + assert parent_span["attributes"]["sentry.origin"] == "manual" + assert set_span["attributes"]["sentry.origin"] == "auto.db.redis" + assert set_span["attributes"][SPANDATA.DB_QUERY_TEXT] == "SET 'somekey' [Filtered]" + assert pipeline_span["attributes"]["sentry.origin"] == "auto.db.redis" diff --git a/tests/integrations/redis/test_redis_cache_module.py b/tests/integrations/redis/test_redis_cache_module.py index 9fbb17ec37..f8beae5da5 100644 --- a/tests/integrations/redis/test_redis_cache_module.py +++ b/tests/integrations/redis/test_redis_cache_module.py @@ -13,41 +13,31 @@ FAKEREDIS_VERSION = parse_version(fakeredis.__version__) -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_no_cache_basic(sentry_init, capture_events, capture_items, span_streaming): +def test_no_cache_basic(sentry_init, capture_events, capture_items): sentry_init( integrations=[ RedisIntegration(), ], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.get("mycachekey") - sentry_sdk.flush() + items = capture_items("span") - assert len(items) == 2 - db_span, parent_span = items[0].payload, items[1].payload - assert parent_span["name"] == "custom parent" - assert db_span["attributes"]["sentry.op"] == "db.redis" - else: - events = capture_events() - with sentry_sdk.start_transaction(): - connection.get("mycachekey") + with sentry_sdk.traces.start_span(name="custom parent"): + connection.get("mycachekey") + + sentry_sdk.flush() - (event,) = events - spans = event["spans"] - assert len(spans) == 1 - assert spans[0]["op"] == "db.redis" + assert len(items) == 2 + db_span, parent_span = items[0].payload, items[1].payload + assert parent_span["name"] == "custom parent" + assert db_span["attributes"]["sentry.op"] == "db.redis" -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_cache_basic(sentry_init, capture_events, capture_items, span_streaming): +def test_cache_basic(sentry_init, capture_events, capture_items): sentry_init( integrations=[ RedisIntegration( @@ -55,95 +45,68 @@ def test_cache_basic(sentry_init, capture_events, capture_items, span_streaming) ), ], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.hget("mycachekey", "myfield") - connection.get("mycachekey") - connection.set("mycachekey1", "bla") - connection.setex("mycachekey2", 10, "blub") - connection.mget("mycachekey1", "mycachekey2") - sentry_sdk.flush() - - # Close order: db spans close before their wrapping cache span, - # and the "custom parent" segment closes last. - assert len(items) == 10 - payloads = [item.payload for item in items] - - # hget: db only (HGET is not a cache command) - assert payloads[0]["attributes"]["sentry.op"] == "db.redis" - assert payloads[0]["attributes"][SPANDATA.DB_OPERATION_NAME] == "HGET" - - # get: db then cache.get - assert payloads[1]["attributes"]["sentry.op"] == "db.redis" - assert payloads[1]["attributes"][SPANDATA.DB_OPERATION_NAME] == "GET" - assert payloads[2]["attributes"]["sentry.op"] == "cache.get" - assert payloads[2]["attributes"][SPANDATA.DB_QUERY_TEXT] == "GET 'mycachekey'" - - # set: db then cache.put - assert payloads[3]["attributes"]["sentry.op"] == "db.redis" - assert payloads[3]["attributes"][SPANDATA.DB_OPERATION_NAME] == "SET" - assert payloads[4]["attributes"]["sentry.op"] == "cache.put" - assert ( - payloads[4]["attributes"][SPANDATA.DB_QUERY_TEXT] - == "SET 'mycachekey1' [Filtered]" - ) - - # setex: db then cache.put - assert payloads[5]["attributes"]["sentry.op"] == "db.redis" - assert payloads[5]["attributes"][SPANDATA.DB_OPERATION_NAME] == "SETEX" - assert payloads[6]["attributes"]["sentry.op"] == "cache.put" - assert ( - payloads[6]["attributes"][SPANDATA.DB_QUERY_TEXT] - == "SETEX 'mycachekey2' [Filtered] [Filtered]" - ) - - # mget: db then cache.get - assert payloads[7]["attributes"]["sentry.op"] == "db.redis" - assert payloads[7]["attributes"][SPANDATA.DB_OPERATION_NAME] == "MGET" - assert payloads[8]["attributes"]["sentry.op"] == "cache.get" - assert ( - payloads[8]["attributes"][SPANDATA.DB_QUERY_TEXT] - == "MGET 'mycachekey1' [Filtered]" - ) - - assert payloads[9]["name"] == "custom parent" - else: - events = capture_events() - with sentry_sdk.start_transaction(): - connection.hget("mycachekey", "myfield") - connection.get("mycachekey") - connection.set("mycachekey1", "bla") - connection.setex("mycachekey2", 10, "blub") - connection.mget("mycachekey1", "mycachekey2") - - (event,) = events - spans = event["spans"] - assert len(spans) == 9 - - # no cache support for hget command - assert spans[0]["op"] == "db.redis" - - assert spans[1]["op"] == "cache.get" - assert spans[2]["op"] == "db.redis" + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + connection.hget("mycachekey", "myfield") + connection.get("mycachekey") + connection.set("mycachekey1", "bla") + connection.setex("mycachekey2", 10, "blub") + connection.mget("mycachekey1", "mycachekey2") + + sentry_sdk.flush() + + # Close order: db spans close before their wrapping cache span, + # and the "custom parent" segment closes last. + assert len(items) == 10 + payloads = [item.payload for item in items] + + # hget: db only (HGET is not a cache command) + assert payloads[0]["attributes"]["sentry.op"] == "db.redis" + assert payloads[0]["attributes"][SPANDATA.DB_OPERATION_NAME] == "HGET" + + # get: db then cache.get + assert payloads[1]["attributes"]["sentry.op"] == "db.redis" + assert payloads[1]["attributes"][SPANDATA.DB_OPERATION_NAME] == "GET" + assert payloads[2]["attributes"]["sentry.op"] == "cache.get" + assert payloads[2]["attributes"][SPANDATA.DB_QUERY_TEXT] == "GET 'mycachekey'" + + # set: db then cache.put + assert payloads[3]["attributes"]["sentry.op"] == "db.redis" + assert payloads[3]["attributes"][SPANDATA.DB_OPERATION_NAME] == "SET" + assert payloads[4]["attributes"]["sentry.op"] == "cache.put" + assert ( + payloads[4]["attributes"][SPANDATA.DB_QUERY_TEXT] + == "SET 'mycachekey1' [Filtered]" + ) - assert spans[3]["op"] == "cache.put" - assert spans[4]["op"] == "db.redis" + # setex: db then cache.put + assert payloads[5]["attributes"]["sentry.op"] == "db.redis" + assert payloads[5]["attributes"][SPANDATA.DB_OPERATION_NAME] == "SETEX" + assert payloads[6]["attributes"]["sentry.op"] == "cache.put" + assert ( + payloads[6]["attributes"][SPANDATA.DB_QUERY_TEXT] + == "SETEX 'mycachekey2' [Filtered] [Filtered]" + ) - assert spans[5]["op"] == "cache.put" - assert spans[6]["op"] == "db.redis" + # mget: db then cache.get + assert payloads[7]["attributes"]["sentry.op"] == "db.redis" + assert payloads[7]["attributes"][SPANDATA.DB_OPERATION_NAME] == "MGET" + assert payloads[8]["attributes"]["sentry.op"] == "cache.get" + assert ( + payloads[8]["attributes"][SPANDATA.DB_QUERY_TEXT] + == "MGET 'mycachekey1' [Filtered]" + ) - assert spans[7]["op"] == "cache.get" - assert spans[8]["op"] == "db.redis" + assert payloads[9]["name"] == "custom parent" -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_cache_keys(sentry_init, capture_events, capture_items, span_streaming): +def test_cache_keys(sentry_init, capture_events, capture_items): sentry_init( integrations=[ RedisIntegration( @@ -151,76 +114,50 @@ def test_cache_keys(sentry_init, capture_events, capture_items, span_streaming): ), ], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.get("somethingelse") - connection.get("blub") - connection.get("blubkeything") - connection.get("bl") - sentry_sdk.flush() - - assert len(items) == 7 - payloads = [item.payload for item in items] - - # somethingelse: db only - assert payloads[0]["attributes"]["sentry.op"] == "db.redis" - assert payloads[0]["name"] == "GET 'somethingelse'" - - # blub: db then cache.get - assert payloads[1]["attributes"]["sentry.op"] == "db.redis" - assert payloads[1]["name"] == "GET 'blub'" - assert payloads[2]["attributes"]["sentry.op"] == "cache.get" - assert payloads[2]["name"] == "blub" - assert payloads[2]["attributes"][SPANDATA.DB_QUERY_TEXT] == "GET 'blub'" - - # blubkeything: db then cache.get - assert payloads[3]["attributes"]["sentry.op"] == "db.redis" - assert payloads[3]["name"] == "GET 'blubkeything'" - assert payloads[4]["attributes"]["sentry.op"] == "cache.get" - assert payloads[4]["name"] == "blubkeything" - assert payloads[4]["attributes"][SPANDATA.DB_QUERY_TEXT] == "GET 'blubkeything'" - - # bl: db only (no prefix match) - assert payloads[5]["attributes"]["sentry.op"] == "db.redis" - assert payloads[5]["name"] == "GET 'bl'" - - assert payloads[6]["name"] == "custom parent" - else: - events = capture_events() - with sentry_sdk.start_transaction(): - connection.get("somethingelse") - connection.get("blub") - connection.get("blubkeything") - connection.get("bl") - - (event,) = events - spans = event["spans"] - assert len(spans) == 6 - assert spans[0]["op"] == "db.redis" - assert spans[0]["description"] == "GET 'somethingelse'" - - assert spans[1]["op"] == "cache.get" - assert spans[1]["description"] == "blub" - assert spans[2]["op"] == "db.redis" - assert spans[2]["description"] == "GET 'blub'" - - assert spans[3]["op"] == "cache.get" - assert spans[3]["description"] == "blubkeything" - assert spans[4]["op"] == "db.redis" - assert spans[4]["description"] == "GET 'blubkeything'" - - assert spans[5]["op"] == "db.redis" - assert spans[5]["description"] == "GET 'bl'" - - -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_cache_data(sentry_init, capture_events, capture_items, span_streaming): + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + connection.get("somethingelse") + connection.get("blub") + connection.get("blubkeything") + connection.get("bl") + + sentry_sdk.flush() + + assert len(items) == 7 + payloads = [item.payload for item in items] + + # somethingelse: db only + assert payloads[0]["attributes"]["sentry.op"] == "db.redis" + assert payloads[0]["name"] == "GET 'somethingelse'" + + # blub: db then cache.get + assert payloads[1]["attributes"]["sentry.op"] == "db.redis" + assert payloads[1]["name"] == "GET 'blub'" + assert payloads[2]["attributes"]["sentry.op"] == "cache.get" + assert payloads[2]["name"] == "blub" + assert payloads[2]["attributes"][SPANDATA.DB_QUERY_TEXT] == "GET 'blub'" + + # blubkeything: db then cache.get + assert payloads[3]["attributes"]["sentry.op"] == "db.redis" + assert payloads[3]["name"] == "GET 'blubkeything'" + assert payloads[4]["attributes"]["sentry.op"] == "cache.get" + assert payloads[4]["name"] == "blubkeything" + assert payloads[4]["attributes"][SPANDATA.DB_QUERY_TEXT] == "GET 'blubkeything'" + + # bl: db only (no prefix match) + assert payloads[5]["attributes"]["sentry.op"] == "db.redis" + assert payloads[5]["name"] == "GET 'bl'" + + assert payloads[6]["name"] == "custom parent" + + +def test_cache_data(sentry_init, capture_events, capture_items): sentry_init( integrations=[ RedisIntegration( @@ -228,7 +165,7 @@ def test_cache_data(sentry_init, capture_events, capture_items, span_streaming): ), ], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) # Use a unique host per parametrized run so fakeredis (which shares state @@ -236,144 +173,73 @@ def test_cache_data(sentry_init, capture_events, capture_items, span_streaming): host = f"mycacheserver-{uuid.uuid4().hex}.io" connection = FakeRedis(host=host, port=6378) - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.get("mycachekey") - connection.set("mycachekey", "事实胜于雄辩") - connection.get("mycachekey") - sentry_sdk.flush() - - # Close order: db then cache for each command, then parent - assert len(items) == 7 - payloads = [item.payload for item in items] - - # First get (miss) - assert payloads[0]["attributes"]["sentry.op"] == "db.redis" - cache_get_miss = payloads[1] - assert cache_get_miss["attributes"]["sentry.op"] == "cache.get" - assert cache_get_miss["name"] == "mycachekey" - assert cache_get_miss["attributes"]["cache.key"] == ["mycachekey"] - assert cache_get_miss["attributes"]["cache.hit"] is False - assert "cache.item_size" not in cache_get_miss["attributes"] - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in cache_get_miss["attributes"] - else: - assert cache_get_miss["attributes"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in cache_get_miss["attributes"] - else: - assert cache_get_miss["attributes"]["network.peer.address"] == host - - # Set - assert payloads[2]["attributes"]["sentry.op"] == "db.redis" - cache_put = payloads[3] - assert cache_put["attributes"]["sentry.op"] == "cache.put" - assert cache_put["name"] == "mycachekey" - assert cache_put["attributes"]["cache.key"] == ["mycachekey"] - assert "cache.hit" not in cache_put["attributes"] - assert cache_put["attributes"]["cache.item_size"] == 18 - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in cache_put["attributes"] - else: - assert cache_put["attributes"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in cache_put["attributes"] - else: - assert cache_put["attributes"]["network.peer.address"] == host - - # Second get (hit) - assert payloads[4]["attributes"]["sentry.op"] == "db.redis" - cache_get_hit = payloads[5] - assert cache_get_hit["attributes"]["sentry.op"] == "cache.get" - assert cache_get_hit["attributes"]["cache.key"] == ["mycachekey"] - assert cache_get_hit["attributes"]["cache.hit"] is True - assert cache_get_hit["attributes"]["cache.item_size"] == 18 - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in cache_get_hit["attributes"] - else: - assert cache_get_hit["attributes"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in cache_get_hit["attributes"] - else: - assert cache_get_hit["attributes"]["network.peer.address"] == host - - assert payloads[6]["name"] == "custom parent" + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + connection.get("mycachekey") + connection.set("mycachekey", "事实胜于雄辩") + connection.get("mycachekey") + + sentry_sdk.flush() + + # Close order: db then cache for each command, then parent + assert len(items) == 7 + payloads = [item.payload for item in items] + + # First get (miss) + assert payloads[0]["attributes"]["sentry.op"] == "db.redis" + cache_get_miss = payloads[1] + assert cache_get_miss["attributes"]["sentry.op"] == "cache.get" + assert cache_get_miss["name"] == "mycachekey" + assert cache_get_miss["attributes"]["cache.key"] == ["mycachekey"] + assert cache_get_miss["attributes"]["cache.hit"] is False + assert "cache.item_size" not in cache_get_miss["attributes"] + if FAKEREDIS_VERSION <= (2, 7, 1): + assert "network.peer.port" not in cache_get_miss["attributes"] + else: + assert cache_get_miss["attributes"]["network.peer.port"] == 6378 + if FAKEREDIS_VERSION <= (1, 7, 1): + assert "network.peer.address" not in cache_get_miss["attributes"] + else: + assert cache_get_miss["attributes"]["network.peer.address"] == host + + # Set + assert payloads[2]["attributes"]["sentry.op"] == "db.redis" + cache_put = payloads[3] + assert cache_put["attributes"]["sentry.op"] == "cache.put" + assert cache_put["name"] == "mycachekey" + assert cache_put["attributes"]["cache.key"] == ["mycachekey"] + assert "cache.hit" not in cache_put["attributes"] + assert cache_put["attributes"]["cache.item_size"] == 18 + if FAKEREDIS_VERSION <= (2, 7, 1): + assert "network.peer.port" not in cache_put["attributes"] else: - events = capture_events() - with sentry_sdk.start_transaction(): - connection.get("mycachekey") - connection.set("mycachekey", "事实胜于雄辩") - connection.get("mycachekey") - - (event,) = events - spans = event["spans"] - - assert len(spans) == 6 - - assert spans[0]["op"] == "cache.get" - assert spans[0]["description"] == "mycachekey" - assert spans[0]["data"]["cache.key"] == [ - "mycachekey", - ] - assert spans[0]["data"]["cache.hit"] == False # noqa: E712 - assert "cache.item_size" not in spans[0]["data"] - # very old fakeredis can not handle port and/or host. - # only applicable for Redis v3 - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in spans[0]["data"] - else: - assert spans[0]["data"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in spans[0]["data"] - else: - assert spans[0]["data"]["network.peer.address"] == host - - assert spans[1]["op"] == "db.redis" # we ignore db spans in this test. - - assert spans[2]["op"] == "cache.put" - assert spans[2]["description"] == "mycachekey" - assert spans[2]["data"]["cache.key"] == [ - "mycachekey", - ] - assert "cache.hit" not in spans[1]["data"] - assert spans[2]["data"]["cache.item_size"] == 18 - # very old fakeredis can not handle port. - # only used with redis v3 - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in spans[2]["data"] - else: - assert spans[2]["data"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in spans[2]["data"] - else: - assert spans[2]["data"]["network.peer.address"] == host - - assert spans[3]["op"] == "db.redis" # we ignore db spans in this test. - - assert spans[4]["op"] == "cache.get" - assert spans[4]["description"] == "mycachekey" - assert spans[4]["data"]["cache.key"] == [ - "mycachekey", - ] - assert spans[4]["data"]["cache.hit"] == True # noqa: E712 - assert spans[4]["data"]["cache.item_size"] == 18 - # very old fakeredis can not handle port. - # only used with redis v3 - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in spans[4]["data"] - else: - assert spans[4]["data"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in spans[4]["data"] - else: - assert spans[4]["data"]["network.peer.address"] == host - - assert spans[5]["op"] == "db.redis" # we ignore db spans in this test. - - -@pytest.mark.parametrize("span_streaming", [True, False]) -def test_cache_prefixes(sentry_init, capture_events, capture_items, span_streaming): + assert cache_put["attributes"]["network.peer.port"] == 6378 + if FAKEREDIS_VERSION <= (1, 7, 1): + assert "network.peer.address" not in cache_put["attributes"] + else: + assert cache_put["attributes"]["network.peer.address"] == host + + # Second get (hit) + assert payloads[4]["attributes"]["sentry.op"] == "db.redis" + cache_get_hit = payloads[5] + assert cache_get_hit["attributes"]["sentry.op"] == "cache.get" + assert cache_get_hit["attributes"]["cache.key"] == ["mycachekey"] + assert cache_get_hit["attributes"]["cache.hit"] is True + assert cache_get_hit["attributes"]["cache.item_size"] == 18 + if FAKEREDIS_VERSION <= (2, 7, 1): + assert "network.peer.port" not in cache_get_hit["attributes"] + else: + assert cache_get_hit["attributes"]["network.peer.port"] == 6378 + if FAKEREDIS_VERSION <= (1, 7, 1): + assert "network.peer.address" not in cache_get_hit["attributes"] + else: + assert cache_get_hit["attributes"]["network.peer.address"] == host + + assert payloads[6]["name"] == "custom parent" + + +def test_cache_prefixes(sentry_init, capture_events, capture_items): sentry_init( integrations=[ RedisIntegration( @@ -381,64 +247,40 @@ def test_cache_prefixes(sentry_init, capture_events, capture_items, span_streami ), ], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedis() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - connection.mget("yes", "no") - connection.mget("no", 1, "yes") - connection.mget("no", "yes.1", "yes.2") - connection.mget("no.1", "no.2", "no.3") - connection.mget("no.1", "no.2", "no.actually.yes") - connection.mget(b"no.3", b"yes.5") - connection.mget(uuid.uuid4().bytes) - connection.mget(uuid.uuid4().bytes, "yes") - sentry_sdk.flush() - - # 8 db spans + 5 cache spans + 1 parent - assert len(items) == 14 - payloads = [item.payload for item in items] - assert payloads[-1]["name"] == "custom parent" - - cache_spans = [ - p for p in payloads if p["attributes"].get("sentry.op") == "cache.get" - ] - assert len(cache_spans) == 5 - - assert cache_spans[0]["name"] == "yes, no" - assert cache_spans[1]["name"] == "no, 1, yes" - assert cache_spans[2]["name"] == "no, yes.1, yes.2" - assert cache_spans[3]["name"] == "no.3, yes.5" - assert cache_spans[4]["name"] == ", yes" - else: - events = capture_events() - with sentry_sdk.start_transaction(): - connection.mget("yes", "no") - connection.mget("no", 1, "yes") - connection.mget("no", "yes.1", "yes.2") - connection.mget("no.1", "no.2", "no.3") - connection.mget("no.1", "no.2", "no.actually.yes") - connection.mget(b"no.3", b"yes.5") - connection.mget(uuid.uuid4().bytes) - connection.mget(uuid.uuid4().bytes, "yes") - - (event,) = events - - spans = event["spans"] - assert len(spans) == 13 # 8 db spans + 5 cache spans - - cache_spans = [span for span in spans if span["op"] == "cache.get"] - assert len(cache_spans) == 5 - - assert cache_spans[0]["description"] == "yes, no" - assert cache_spans[1]["description"] == "no, 1, yes" - assert cache_spans[2]["description"] == "no, yes.1, yes.2" - assert cache_spans[3]["description"] == "no.3, yes.5" - assert cache_spans[4]["description"] == ", yes" + items = capture_items("span") + + with sentry_sdk.traces.start_span(name="custom parent"): + connection.mget("yes", "no") + connection.mget("no", 1, "yes") + connection.mget("no", "yes.1", "yes.2") + connection.mget("no.1", "no.2", "no.3") + connection.mget("no.1", "no.2", "no.actually.yes") + connection.mget(b"no.3", b"yes.5") + connection.mget(uuid.uuid4().bytes) + connection.mget(uuid.uuid4().bytes, "yes") + + sentry_sdk.flush() + + # 8 db spans + 5 cache spans + 1 parent + assert len(items) == 14 + payloads = [item.payload for item in items] + assert payloads[-1]["name"] == "custom parent" + + cache_spans = [ + p for p in payloads if p["attributes"].get("sentry.op") == "cache.get" + ] + assert len(cache_spans) == 5 + + assert cache_spans[0]["name"] == "yes, no" + assert cache_spans[1]["name"] == "no, 1, yes" + assert cache_spans[2]["name"] == "no, yes.1, yes.2" + assert cache_spans[3]["name"] == "no.3, yes.5" + assert cache_spans[4]["name"] == ", yes" @pytest.mark.parametrize( diff --git a/tests/integrations/redis/test_redis_cache_module_async.py b/tests/integrations/redis/test_redis_cache_module_async.py index 96e486fd55..b56eb9478d 100644 --- a/tests/integrations/redis/test_redis_cache_module_async.py +++ b/tests/integrations/redis/test_redis_cache_module_async.py @@ -22,45 +22,31 @@ FAKEREDIS_VERSION = parse_version(fakeredis.__version__) -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.asyncio -async def test_no_cache_basic( - sentry_init, capture_events, capture_items, span_streaming -): +async def test_no_cache_basic(sentry_init, capture_events, capture_items): sentry_init( integrations=[ RedisIntegration(), ], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedisAsync() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - await connection.get("myasynccachekey") - sentry_sdk.flush() + items = capture_items("span") + with sentry_sdk.traces.start_span(name="custom parent"): + await connection.get("myasynccachekey") + sentry_sdk.flush() - assert len(items) == 2 - db_span, parent_span = items[0].payload, items[1].payload - assert parent_span["name"] == "custom parent" - assert db_span["attributes"]["sentry.op"] == "db.redis" - else: - events = capture_events() - with sentry_sdk.start_transaction(): - await connection.get("myasynccachekey") - - (event,) = events - spans = event["spans"] - assert len(spans) == 1 - assert spans[0]["op"] == "db.redis" + assert len(items) == 2 + db_span, parent_span = items[0].payload, items[1].payload + assert parent_span["name"] == "custom parent" + assert db_span["attributes"]["sentry.op"] == "db.redis" -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.asyncio -async def test_cache_basic(sentry_init, capture_events, capture_items, span_streaming): +async def test_cache_basic(sentry_init, capture_events, capture_items): sentry_init( integrations=[ RedisIntegration( @@ -68,39 +54,26 @@ async def test_cache_basic(sentry_init, capture_events, capture_items, span_stre ), ], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedisAsync() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - await connection.get("myasynccachekey") - sentry_sdk.flush() - - assert len(items) == 3 - db_span, cache_span, parent_span = [item.payload for item in items] - assert parent_span["name"] == "custom parent" - assert db_span["attributes"]["sentry.op"] == "db.redis" - assert cache_span["attributes"]["sentry.op"] == "cache.get" - assert cache_span["attributes"][SPANDATA.CACHE_KEY] == ["myasynccachekey"] - else: - events = capture_events() - with sentry_sdk.start_transaction(): - await connection.get("myasynccachekey") + items = capture_items("span") + with sentry_sdk.traces.start_span(name="custom parent"): + await connection.get("myasynccachekey") + sentry_sdk.flush() - (event,) = events - spans = event["spans"] - assert len(spans) == 2 + assert len(items) == 3 + db_span, cache_span, parent_span = [item.payload for item in items] + assert parent_span["name"] == "custom parent" + assert db_span["attributes"]["sentry.op"] == "db.redis" + assert cache_span["attributes"]["sentry.op"] == "cache.get" + assert cache_span["attributes"][SPANDATA.CACHE_KEY] == ["myasynccachekey"] - assert spans[0]["op"] == "cache.get" - assert spans[1]["op"] == "db.redis" - -@pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.asyncio -async def test_cache_keys(sentry_init, capture_events, capture_items, span_streaming): +async def test_cache_keys(sentry_init, capture_events, capture_items): sentry_init( integrations=[ RedisIntegration( @@ -108,77 +81,49 @@ async def test_cache_keys(sentry_init, capture_events, capture_items, span_strea ), ], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) connection = FakeRedisAsync() - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - await connection.get("asomethingelse") - await connection.get("ablub") - await connection.get("ablubkeything") - await connection.get("abl") - sentry_sdk.flush() - - assert len(items) == 7 - payloads = [item.payload for item in items] - - # asomethingelse: db only - assert payloads[0]["attributes"]["sentry.op"] == "db.redis" - assert payloads[0]["name"] == "GET 'asomethingelse'" - - # ablub: db then cache.get - assert payloads[1]["attributes"]["sentry.op"] == "db.redis" - assert payloads[1]["name"] == "GET 'ablub'" - assert payloads[2]["attributes"]["sentry.op"] == "cache.get" - assert payloads[2]["name"] == "ablub" - assert payloads[2]["attributes"][SPANDATA.CACHE_KEY] == ["ablub"] - - # ablubkeything: db then cache.get - assert payloads[3]["attributes"]["sentry.op"] == "db.redis" - assert payloads[3]["name"] == "GET 'ablubkeything'" - assert payloads[4]["attributes"]["sentry.op"] == "cache.get" - assert payloads[4]["name"] == "ablubkeything" - assert payloads[4]["attributes"][SPANDATA.CACHE_KEY] == ["ablubkeything"] - - # abl: db only (no prefix match) - assert payloads[5]["attributes"]["sentry.op"] == "db.redis" - assert payloads[5]["name"] == "GET 'abl'" - - assert payloads[6]["name"] == "custom parent" - else: - events = capture_events() - with sentry_sdk.start_transaction(): - await connection.get("asomethingelse") - await connection.get("ablub") - await connection.get("ablubkeything") - await connection.get("abl") - - (event,) = events - spans = event["spans"] - assert len(spans) == 6 - assert spans[0]["op"] == "db.redis" - assert spans[0]["description"] == "GET 'asomethingelse'" - - assert spans[1]["op"] == "cache.get" - assert spans[1]["description"] == "ablub" - assert spans[2]["op"] == "db.redis" - assert spans[2]["description"] == "GET 'ablub'" - - assert spans[3]["op"] == "cache.get" - assert spans[3]["description"] == "ablubkeything" - assert spans[4]["op"] == "db.redis" - assert spans[4]["description"] == "GET 'ablubkeything'" - - assert spans[5]["op"] == "db.redis" - assert spans[5]["description"] == "GET 'abl'" - - -@pytest.mark.parametrize("span_streaming", [True, False]) + items = capture_items("span") + with sentry_sdk.traces.start_span(name="custom parent"): + await connection.get("asomethingelse") + await connection.get("ablub") + await connection.get("ablubkeything") + await connection.get("abl") + sentry_sdk.flush() + + assert len(items) == 7 + payloads = [item.payload for item in items] + + # asomethingelse: db only + assert payloads[0]["attributes"]["sentry.op"] == "db.redis" + assert payloads[0]["name"] == "GET 'asomethingelse'" + + # ablub: db then cache.get + assert payloads[1]["attributes"]["sentry.op"] == "db.redis" + assert payloads[1]["name"] == "GET 'ablub'" + assert payloads[2]["attributes"]["sentry.op"] == "cache.get" + assert payloads[2]["name"] == "ablub" + assert payloads[2]["attributes"][SPANDATA.CACHE_KEY] == ["ablub"] + + # ablubkeything: db then cache.get + assert payloads[3]["attributes"]["sentry.op"] == "db.redis" + assert payloads[3]["name"] == "GET 'ablubkeything'" + assert payloads[4]["attributes"]["sentry.op"] == "cache.get" + assert payloads[4]["name"] == "ablubkeything" + assert payloads[4]["attributes"][SPANDATA.CACHE_KEY] == ["ablubkeything"] + + # abl: db only (no prefix match) + assert payloads[5]["attributes"]["sentry.op"] == "db.redis" + assert payloads[5]["name"] == "GET 'abl'" + + assert payloads[6]["name"] == "custom parent" + + @pytest.mark.asyncio -async def test_cache_data(sentry_init, capture_events, capture_items, span_streaming): +async def test_cache_data(sentry_init, capture_events, capture_items): sentry_init( integrations=[ RedisIntegration( @@ -186,7 +131,7 @@ async def test_cache_data(sentry_init, capture_events, capture_items, span_strea ), ], traces_sample_rate=1.0, - trace_lifecycle="stream" if span_streaming else "static", + trace_lifecycle="stream", ) # Use a unique host per parametrized run so fakeredis (which shares state @@ -194,136 +139,64 @@ async def test_cache_data(sentry_init, capture_events, capture_items, span_strea host = f"mycacheserver-{uuid.uuid4().hex}.io" connection = FakeRedisAsync(host=host, port=6378) - if span_streaming: - items = capture_items("span") - with sentry_sdk.traces.start_span(name="custom parent"): - await connection.get("myasynccachekey") - await connection.set("myasynccachekey", "事实胜于雄辩") - await connection.get("myasynccachekey") - sentry_sdk.flush() - - assert len(items) == 7 - payloads = [item.payload for item in items] - - # First get (miss) - assert payloads[0]["attributes"]["sentry.op"] == "db.redis" - cache_get_miss = payloads[1] - assert cache_get_miss["attributes"]["sentry.op"] == "cache.get" - assert cache_get_miss["name"] == "myasynccachekey" - assert cache_get_miss["attributes"]["cache.key"] == ["myasynccachekey"] - assert cache_get_miss["attributes"]["cache.hit"] is False - assert "cache.item_size" not in cache_get_miss["attributes"] - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in cache_get_miss["attributes"] - else: - assert cache_get_miss["attributes"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in cache_get_miss["attributes"] - else: - assert cache_get_miss["attributes"]["network.peer.address"] == host - - # Set - assert payloads[2]["attributes"]["sentry.op"] == "db.redis" - cache_put = payloads[3] - assert cache_put["attributes"]["sentry.op"] == "cache.put" - assert cache_put["name"] == "myasynccachekey" - assert cache_put["attributes"]["cache.key"] == ["myasynccachekey"] - assert "cache.hit" not in cache_put["attributes"] - assert cache_put["attributes"]["cache.item_size"] == 18 - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in cache_put["attributes"] - else: - assert cache_put["attributes"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in cache_put["attributes"] - else: - assert cache_put["attributes"]["network.peer.address"] == host - - # Second get (hit) - assert payloads[4]["attributes"]["sentry.op"] == "db.redis" - cache_get_hit = payloads[5] - assert cache_get_hit["attributes"]["sentry.op"] == "cache.get" - assert cache_get_hit["attributes"]["cache.key"] == ["myasynccachekey"] - assert cache_get_hit["attributes"]["cache.hit"] is True - assert cache_get_hit["attributes"]["cache.item_size"] == 18 - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in cache_get_hit["attributes"] - else: - assert cache_get_hit["attributes"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in cache_get_hit["attributes"] - else: - assert cache_get_hit["attributes"]["network.peer.address"] == host - - assert payloads[6]["name"] == "custom parent" + items = capture_items("span") + with sentry_sdk.traces.start_span(name="custom parent"): + await connection.get("myasynccachekey") + await connection.set("myasynccachekey", "事实胜于雄辩") + await connection.get("myasynccachekey") + sentry_sdk.flush() + + assert len(items) == 7 + payloads = [item.payload for item in items] + + # First get (miss) + assert payloads[0]["attributes"]["sentry.op"] == "db.redis" + cache_get_miss = payloads[1] + assert cache_get_miss["attributes"]["sentry.op"] == "cache.get" + assert cache_get_miss["name"] == "myasynccachekey" + assert cache_get_miss["attributes"]["cache.key"] == ["myasynccachekey"] + assert cache_get_miss["attributes"]["cache.hit"] is False + assert "cache.item_size" not in cache_get_miss["attributes"] + if FAKEREDIS_VERSION <= (2, 7, 1): + assert "network.peer.port" not in cache_get_miss["attributes"] + else: + assert cache_get_miss["attributes"]["network.peer.port"] == 6378 + if FAKEREDIS_VERSION <= (1, 7, 1): + assert "network.peer.address" not in cache_get_miss["attributes"] + else: + assert cache_get_miss["attributes"]["network.peer.address"] == host + + # Set + assert payloads[2]["attributes"]["sentry.op"] == "db.redis" + cache_put = payloads[3] + assert cache_put["attributes"]["sentry.op"] == "cache.put" + assert cache_put["name"] == "myasynccachekey" + assert cache_put["attributes"]["cache.key"] == ["myasynccachekey"] + assert "cache.hit" not in cache_put["attributes"] + assert cache_put["attributes"]["cache.item_size"] == 18 + if FAKEREDIS_VERSION <= (2, 7, 1): + assert "network.peer.port" not in cache_put["attributes"] else: - events = capture_events() - with sentry_sdk.start_transaction(): - await connection.get("myasynccachekey") - await connection.set("myasynccachekey", "事实胜于雄辩") - await connection.get("myasynccachekey") - - (event,) = events - spans = event["spans"] - - assert len(spans) == 6 - - assert spans[0]["op"] == "cache.get" - assert spans[0]["description"] == "myasynccachekey" - assert spans[0]["data"]["cache.key"] == [ - "myasynccachekey", - ] - assert spans[0]["data"]["cache.hit"] == False # noqa: E712 - assert "cache.item_size" not in spans[0]["data"] - # very old fakeredis can not handle port and/or host. - # only applicable for Redis v3 - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in spans[0]["data"] - else: - assert spans[0]["data"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in spans[0]["data"] - else: - assert spans[0]["data"]["network.peer.address"] == host - - assert spans[1]["op"] == "db.redis" # we ignore db spans in this test. - - assert spans[2]["op"] == "cache.put" - assert spans[2]["description"] == "myasynccachekey" - assert spans[2]["data"]["cache.key"] == [ - "myasynccachekey", - ] - assert "cache.hit" not in spans[1]["data"] - assert spans[2]["data"]["cache.item_size"] == 18 - # very old fakeredis can not handle port. - # only used with redis v3 - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in spans[2]["data"] - else: - assert spans[2]["data"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in spans[2]["data"] - else: - assert spans[2]["data"]["network.peer.address"] == host - - assert spans[3]["op"] == "db.redis" # we ignore db spans in this test. - - assert spans[4]["op"] == "cache.get" - assert spans[4]["description"] == "myasynccachekey" - assert spans[4]["data"]["cache.key"] == [ - "myasynccachekey", - ] - assert spans[4]["data"]["cache.hit"] == True # noqa: E712 - assert spans[4]["data"]["cache.item_size"] == 18 - # very old fakeredis can not handle port. - # only used with redis v3 - if FAKEREDIS_VERSION <= (2, 7, 1): - assert "network.peer.port" not in spans[4]["data"] - else: - assert spans[4]["data"]["network.peer.port"] == 6378 - if FAKEREDIS_VERSION <= (1, 7, 1): - assert "network.peer.address" not in spans[4]["data"] - else: - assert spans[4]["data"]["network.peer.address"] == host - - assert spans[5]["op"] == "db.redis" # we ignore db spans in this test. + assert cache_put["attributes"]["network.peer.port"] == 6378 + if FAKEREDIS_VERSION <= (1, 7, 1): + assert "network.peer.address" not in cache_put["attributes"] + else: + assert cache_put["attributes"]["network.peer.address"] == host + + # Second get (hit) + assert payloads[4]["attributes"]["sentry.op"] == "db.redis" + cache_get_hit = payloads[5] + assert cache_get_hit["attributes"]["sentry.op"] == "cache.get" + assert cache_get_hit["attributes"]["cache.key"] == ["myasynccachekey"] + assert cache_get_hit["attributes"]["cache.hit"] is True + assert cache_get_hit["attributes"]["cache.item_size"] == 18 + if FAKEREDIS_VERSION <= (2, 7, 1): + assert "network.peer.port" not in cache_get_hit["attributes"] + else: + assert cache_get_hit["attributes"]["network.peer.port"] == 6378 + if FAKEREDIS_VERSION <= (1, 7, 1): + assert "network.peer.address" not in cache_get_hit["attributes"] + else: + assert cache_get_hit["attributes"]["network.peer.address"] == host + + assert payloads[6]["name"] == "custom parent"