diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index ff91e45d7e0..1104c48ad76 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -23,7 +23,7 @@ This project has custom skills that provide specialized workflows. **Always chec **Use whenever:** Formatting code, validating style/types/security, or before committing changes. **Purpose:** Runs targeted linting and code quality checks using `hatch run lint:*`: -- Formats code with Black and Ruff auto-fixes +- Formats code with `ruff check` and `ruff format` - Validates style, types, and security - Checks spelling and documentation - Validates test infrastructure (suitespec, riotfile, etc.) diff --git a/.claude/skills/lint/SKILL.md b/.claude/skills/lint/SKILL.md index 19fe201113e..78834862993 100644 --- a/.claude/skills/lint/SKILL.md +++ b/.claude/skills/lint/SKILL.md @@ -48,7 +48,7 @@ hatch run lint:typing -- path/to/file.py ### Code Formatting #### `fmt` - Format code (recommended for most edits) -Formats and validates code style using Black and Ruff. +Formats and validates code style using Ruff. **Usage:** ```bash @@ -63,7 +63,7 @@ hatch run lint:fmt -- ddtrace/contrib/flask/ ``` **What it does:** -1. Runs Black formatter +1. Runs the Ruff formatter 2. Runs Ruff with --fix to auto-fix issues 3. Re-validates with style checks @@ -94,7 +94,7 @@ hatch run lint:style -- ddtrace/ ``` **What it validates:** -- Black formatting +- Ruff formatting - Ruff linting rules - Cython linting - C code formatting @@ -102,12 +102,13 @@ hatch run lint:style -- ddtrace/ **When to use:** To verify style compliance before committing without auto-fixes. -#### `black_check` - Check Black formatting -Validates Python code formatting with Black (no auto-fix). +#### `format_check` - Check formatting + +Validates Python code formatting with `ruff format` (no auto-fix). **Usage:** ```bash -hatch run lint:black_check -- ddtrace/tracer.py +hatch run lint:format_check -- ddtrace/tracer.py ``` **When to use:** Quick check of Python formatting before committing. diff --git a/benchmarks/bm/iast_fixtures/str_methods.py b/benchmarks/bm/iast_fixtures/str_methods.py index e2a859bf3f4..f0366ba6937 100644 --- a/benchmarks/bm/iast_fixtures/str_methods.py +++ b/benchmarks/bm/iast_fixtures/str_methods.py @@ -832,7 +832,7 @@ def get_random_string_join(mystring: str) -> Text: def get_random_string_seed( length=12, - allowed_chars="abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", + allowed_chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", ): # type: (int, str) -> str """ Returns a securely generated random string. @@ -1180,13 +1180,13 @@ def do_add_re_compile(): import re invalid_unicode_no_surrogate = ( - "[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF" - "\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF" - "\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF" - "\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF" - "\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF" - "\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF" - "\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]" + "[\u0001-\u0008\u000b\u000e-\u001f\u007f-\u009f\ufdd0-\ufdef" + "\ufffe\uffff\U0001fffe\U0001ffff\U0002fffe\U0002ffff" + "\U0003fffe\U0003ffff\U0004fffe\U0004ffff\U0005fffe\U0005ffff" + "\U0006fffe\U0006ffff\U0007fffe\U0007ffff\U0008fffe\U0008ffff" + "\U0009fffe\U0009ffff\U000afffe\U000affff\U000bfffe\U000bffff" + "\U000cfffe\U000cffff\U000dfffe\U000dffff\U000efffe\U000effff" + "\U000ffffe\U000fffff\U0010fffe\U0010ffff]" ) # noqa:F401 _ = re.compile(invalid_unicode_no_surrogate[:-1] + eval('"\\uD800-\\uDFFF"') + "]") # pylint:disable=eval-used diff --git a/conftest.py b/conftest.py index d35199f2b09..b1fc2733be1 100644 --- a/conftest.py +++ b/conftest.py @@ -5,6 +5,7 @@ Local plugins: https://docs.pytest.org/en/3.10.1/writing_plugins.html#local-conftest-plugins Hook reference: https://docs.pytest.org/en/3.10.1/reference.html#hook-reference """ + import os import re import sys diff --git a/ddtrace/_trace/sampler.py b/ddtrace/_trace/sampler.py index 8bd6e0a089c..fd9a9bd9ec6 100644 --- a/ddtrace/_trace/sampler.py +++ b/ddtrace/_trace/sampler.py @@ -2,6 +2,7 @@ Any `sampled = False` trace won't be written, and can be ignored by the instrumentation. """ + import json from json.decoder import JSONDecodeError from typing import Dict diff --git a/ddtrace/_trace/utils_valkey.py b/ddtrace/_trace/utils_valkey.py index ae66b45a82a..b232db69fd7 100644 --- a/ddtrace/_trace/utils_valkey.py +++ b/ddtrace/_trace/utils_valkey.py @@ -50,14 +50,17 @@ def _set_span_tags( @contextmanager def _instrument_valkey_cmd(pin, config_integration, instance, args): query = stringify_cache_args(args, cmd_max_len=config_integration.cmd_max_length) - with core.context_with_data( - "valkey.command", - span_name=schematize_cache_operation(valkeyx.CMD, cache_provider=valkeyx.APP), - pin=pin, - service=trace_utils.ext_service(pin, config_integration), - span_type=SpanTypes.VALKEY, - resource=query.split(" ")[0] if config_integration.resource_only_command else query, - ) as ctx, ctx.span as span: + with ( + core.context_with_data( + "valkey.command", + span_name=schematize_cache_operation(valkeyx.CMD, cache_provider=valkeyx.APP), + pin=pin, + service=trace_utils.ext_service(pin, config_integration), + span_type=SpanTypes.VALKEY, + resource=query.split(" ")[0] if config_integration.resource_only_command else query, + ) as ctx, + ctx.span as span, + ): _set_span_tags(span, pin, config_integration, args, instance, query) yield ctx diff --git a/ddtrace/appsec/_constants.py b/ddtrace/appsec/_constants.py index aedc7db5b99..b75d760e28d 100644 --- a/ddtrace/appsec/_constants.py +++ b/ddtrace/appsec/_constants.py @@ -81,43 +81,43 @@ class APPSEC(metaclass=Constant_Class): USER_LOGIN_EVENT_PREFIX_PUBLIC: Literal["appsec.events.users.login"] = "appsec.events.users.login" USER_LOGIN_USERID: Literal["_dd.appsec.usr.id"] = "_dd.appsec.usr.id" USER_LOGIN_USERNAME: Literal["_dd.appsec.usr.login"] = "_dd.appsec.usr.login" - USER_LOGIN_EVENT_SUCCESS_TRACK: Literal[ + USER_LOGIN_EVENT_SUCCESS_TRACK: Literal["appsec.events.users.login.success.track"] = ( "appsec.events.users.login.success.track" - ] = "appsec.events.users.login.success.track" - USER_LOGIN_EVENT_FAILURE_TRACK: Literal[ + ) + USER_LOGIN_EVENT_FAILURE_TRACK: Literal["appsec.events.users.login.failure.track"] = ( "appsec.events.users.login.failure.track" - ] = "appsec.events.users.login.failure.track" + ) USER_SIGNUP_EVENT: Literal["appsec.events.users.signup.track"] = "appsec.events.users.signup.track" USER_SIGNUP_EVENT_USERNAME: Literal["appsec.events.users.signup.usr.login"] = "appsec.events.users.signup.usr.login" USER_SIGNUP_EVENT_USERID: Literal["appsec.events.users.signup.usr.id"] = "appsec.events.users.signup.usr.id" - USER_SIGNUP_EVENT_MODE: Literal[ + USER_SIGNUP_EVENT_MODE: Literal["_dd.appsec.events.users.signup.auto.mode"] = ( "_dd.appsec.events.users.signup.auto.mode" - ] = "_dd.appsec.events.users.signup.auto.mode" - AUTO_LOGIN_EVENTS_SUCCESS_MODE: Literal[ + ) + AUTO_LOGIN_EVENTS_SUCCESS_MODE: Literal["_dd.appsec.events.users.login.success.auto.mode"] = ( "_dd.appsec.events.users.login.success.auto.mode" - ] = "_dd.appsec.events.users.login.success.auto.mode" - AUTO_LOGIN_EVENTS_FAILURE_MODE: Literal[ + ) + AUTO_LOGIN_EVENTS_FAILURE_MODE: Literal["_dd.appsec.events.users.login.failure.auto.mode"] = ( "_dd.appsec.events.users.login.failure.auto.mode" - ] = "_dd.appsec.events.users.login.failure.auto.mode" + ) AUTO_LOGIN_EVENTS_COLLECTION_MODE: Literal["_dd.appsec.user.collection_mode"] = "_dd.appsec.user.collection_mode" BLOCKED: Literal["appsec.blocked"] = "appsec.blocked" EVENT: Literal["appsec.event"] = "appsec.event" - AUTO_USER_INSTRUMENTATION_MODE: Literal[ + AUTO_USER_INSTRUMENTATION_MODE: Literal["DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE"] = ( "DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE" - ] = "DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE" - AUTO_USER_INSTRUMENTATION_MODE_ENABLED: Literal[ + ) + AUTO_USER_INSTRUMENTATION_MODE_ENABLED: Literal["DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED"] = ( "DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED" - ] = "DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED" + ) USER_MODEL_LOGIN_FIELD: Literal["DD_USER_MODEL_LOGIN_FIELD"] = "DD_USER_MODEL_LOGIN_FIELD" USER_MODEL_EMAIL_FIELD: Literal["DD_USER_MODEL_EMAIL_FIELD"] = "DD_USER_MODEL_EMAIL_FIELD" USER_MODEL_NAME_FIELD: Literal["DD_USER_MODEL_NAME_FIELD"] = "DD_USER_MODEL_NAME_FIELD" PROPAGATION_HEADER: Literal["_dd.p.ts"] = "_dd.p.ts" - OBFUSCATION_PARAMETER_KEY_REGEXP: Literal[ + OBFUSCATION_PARAMETER_KEY_REGEXP: Literal["DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP"] = ( "DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP" - ] = "DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP" - OBFUSCATION_PARAMETER_VALUE_REGEXP: Literal[ + ) + OBFUSCATION_PARAMETER_VALUE_REGEXP: Literal["DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP"] = ( "DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP" - ] = "DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP" + ) RC_CLIENT_ID: Literal["_dd.rc.client_id"] = "_dd.rc.client_id" WAF_ERROR: Literal["_dd.appsec.waf.error"] = "_dd.appsec.waf.error" RASP_ERROR: Literal["_dd.appsec.rasp.error"] = "_dd.appsec.rasp.error" @@ -148,9 +148,9 @@ class IAST(metaclass=Constant_Class): ENV_SINK_POINTS_ENABLED: Literal["DD_IAST_SINK_POINTS_ENABLED"] = "DD_IAST_SINK_POINTS_ENABLED" ENV_PROPAGATION_DEBUG: Literal["DD_IAST_PROPAGATION_DEBUG"] = "DD_IAST_PROPAGATION_DEBUG" ENV_REQUEST_SAMPLING: Literal["DD_IAST_REQUEST_SAMPLING"] = "DD_IAST_REQUEST_SAMPLING" - DD_IAST_VULNERABILITIES_PER_REQUEST: Literal[ + DD_IAST_VULNERABILITIES_PER_REQUEST: Literal["DD_IAST_VULNERABILITIES_PER_REQUEST"] = ( "DD_IAST_VULNERABILITIES_PER_REQUEST" - ] = "DD_IAST_VULNERABILITIES_PER_REQUEST" + ) DD_IAST_MAX_CONCURRENT_REQUESTS: Literal["DD_IAST_MAX_CONCURRENT_REQUESTS"] = "DD_IAST_MAX_CONCURRENT_REQUESTS" ENV_TELEMETRY_REPORT_LVL: Literal["DD_IAST_TELEMETRY_VERBOSITY"] = "DD_IAST_TELEMETRY_VERBOSITY" LAZY_TAINT: Literal["_DD_IAST_LAZY_TAINT"] = "_DD_IAST_LAZY_TAINT" @@ -185,9 +185,9 @@ class IAST_SPAN_TAGS(metaclass=Constant_Class): TELEMETRY_REQUEST_TAINTED: Literal["_dd.iast.telemetry.request.tainted"] = "_dd.iast.telemetry.request.tainted" TELEMETRY_EXECUTED_SINK: Literal["_dd.iast.telemetry.executed.sink"] = "_dd.iast.telemetry.executed.sink" - TELEMETRY_SUPPRESSED_VULNERABILITY: Literal[ + TELEMETRY_SUPPRESSED_VULNERABILITY: Literal["_dd.iast.telemetry.suppressed.vulnerabilities"] = ( "_dd.iast.telemetry.suppressed.vulnerabilities" - ] = "_dd.iast.telemetry.suppressed.vulnerabilities" + ) TELEMETRY_EXECUTED_SOURCE: Literal["_dd.iast.telemetry.executed.source"] = "_dd.iast.telemetry.executed.source" @@ -252,9 +252,9 @@ class SPAN_DATA_NAMES(metaclass=Constant_Class): REQUEST_BODY: Literal["http.request.body"] = "http.request.body" REQUEST_QUERY: Literal["http.request.query"] = "http.request.query" REQUEST_HEADERS_NO_COOKIES: Literal["http.request.headers"] = "http.request.headers" - REQUEST_HEADERS_NO_COOKIES_CASE: Literal[ + REQUEST_HEADERS_NO_COOKIES_CASE: Literal["http.request.headers_case_sensitive"] = ( "http.request.headers_case_sensitive" - ] = "http.request.headers_case_sensitive" + ) REQUEST_URI_RAW: Literal["http.request.uri"] = "http.request.uri" REQUEST_ROUTE: Literal["http.request.route"] = "http.request.route" REQUEST_METHOD: Literal["http.request.method"] = "http.request.method" @@ -287,12 +287,12 @@ class API_SECURITY(metaclass=Constant_Class): SAMPLE_RATE: Literal["DD_API_SECURITY_REQUEST_SAMPLE_RATE"] = "DD_API_SECURITY_REQUEST_SAMPLE_RATE" SAMPLE_DELAY: Literal["DD_API_SECURITY_SAMPLE_DELAY"] = "DD_API_SECURITY_SAMPLE_DELAY" MAX_PAYLOAD_SIZE: Literal[0x1000000] = 0x1000000 # 16MB maximum size - ENDPOINT_COLLECTION: Literal[ + ENDPOINT_COLLECTION: Literal["DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED"] = ( "DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED" - ] = "DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED" - ENDPOINT_COLLECTION_LIMIT: Literal[ + ) + ENDPOINT_COLLECTION_LIMIT: Literal["DD_API_SECURITY_ENDPOINT_COLLECTION_MESSAGE_LIMIT"] = ( "DD_API_SECURITY_ENDPOINT_COLLECTION_MESSAGE_LIMIT" - ] = "DD_API_SECURITY_ENDPOINT_COLLECTION_MESSAGE_LIMIT" + ) class WAF_CONTEXT_NAMES(metaclass=Constant_Class): @@ -376,9 +376,9 @@ class EXPLOIT_PREVENTION(metaclass=Constant_Class): STACK_TRACE_ENABLED: Literal["DD_APPSEC_STACK_TRACE_ENABLED"] = "DD_APPSEC_STACK_TRACE_ENABLED" MAX_STACK_TRACES: Literal["DD_APPSEC_MAX_STACK_TRACES"] = "DD_APPSEC_MAX_STACK_TRACES" MAX_STACK_TRACE_DEPTH: Literal["DD_APPSEC_MAX_STACK_TRACE_DEPTH"] = "DD_APPSEC_MAX_STACK_TRACE_DEPTH" - STACK_TOP_PERCENT: Literal[ + STACK_TOP_PERCENT: Literal["DD_APPSEC_MAX_STACK_TRACE_DEPTH_TOP_PERCENT"] = ( "DD_APPSEC_MAX_STACK_TRACE_DEPTH_TOP_PERCENT" - ] = "DD_APPSEC_MAX_STACK_TRACE_DEPTH_TOP_PERCENT" + ) class TYPE(metaclass=Constant_Class): CMDI: Literal["command_injection"] = "command_injection" diff --git a/ddtrace/appsec/_iast/_overhead_control_engine.py b/ddtrace/appsec/_iast/_overhead_control_engine.py index bd2a1ddca9b..cdff23d7a37 100644 --- a/ddtrace/appsec/_iast/_overhead_control_engine.py +++ b/ddtrace/appsec/_iast/_overhead_control_engine.py @@ -3,6 +3,7 @@ limit. It will measure operations being executed in a request and it will deactivate detection (and therefore reduce the overhead to nearly 0) if a certain threshold is reached. """ + from ddtrace._trace.sampler import RateSampler from ddtrace._trace.span import Span from ddtrace.appsec._iast._utils import _is_iast_debug_enabled diff --git a/ddtrace/appsec/_iast/_patch_modules.py b/ddtrace/appsec/_iast/_patch_modules.py index 4b66bc3a27c..f9d15c4a3e2 100644 --- a/ddtrace/appsec/_iast/_patch_modules.py +++ b/ddtrace/appsec/_iast/_patch_modules.py @@ -10,6 +10,7 @@ The module uses wrapt's function wrapping capabilities to intercept calls to security-sensitive functions and enable taint tracking and vulnerability detection. """ + import functools from typing import Callable from typing import Optional @@ -110,12 +111,7 @@ def unpatch(self): def __repr__(self): """Return a string representation of the IASTFunction instance.""" - return ( - f"IASTFunction(name={self.name}, " - f"function={self.function}, " - f"hook={self.hook}, " - f"force={self.force})" - ) + return f"IASTFunction(name={self.name}, function={self.function}, hook={self.hook}, force={self.force})" class WrapFunctonsForIAST: diff --git a/ddtrace/appsec/_iast/taint_sinks/header_injection.py b/ddtrace/appsec/_iast/taint_sinks/header_injection.py index 30987773555..cdd4d08947f 100644 --- a/ddtrace/appsec/_iast/taint_sinks/header_injection.py +++ b/ddtrace/appsec/_iast/taint_sinks/header_injection.py @@ -54,6 +54,7 @@ This module implements taint sink detection to track and block cases where tainted data is passed to header-setting APIs without proper sanitization. """ # noqa: D301 + import typing from typing import Text diff --git a/ddtrace/appsec/trace_utils/__init__.py b/ddtrace/appsec/trace_utils/__init__.py index 2acc862729b..80804ed6938 100644 --- a/ddtrace/appsec/trace_utils/__init__.py +++ b/ddtrace/appsec/trace_utils/__init__.py @@ -1,4 +1,5 @@ """Public API for User events""" + from functools import wraps from ddtrace.appsec import _metrics diff --git a/ddtrace/auto.py b/ddtrace/auto.py index 27f80866f8f..944a9b6b057 100644 --- a/ddtrace/auto.py +++ b/ddtrace/auto.py @@ -18,4 +18,5 @@ def main(): If you'd like more granular control over instrumentation setup, you can call the `patch*` functions directly. """ + import ddtrace.bootstrap.sitecustomize # noqa:F401 diff --git a/ddtrace/contrib/aiohttp.py b/ddtrace/contrib/aiohttp.py index d001139dde8..06d70713b8c 100644 --- a/ddtrace/contrib/aiohttp.py +++ b/ddtrace/contrib/aiohttp.py @@ -91,6 +91,7 @@ async def home_handler(request): :ref:`All HTTP tags ` are supported for this integration. """ + from ddtrace.contrib.internal.aiohttp.middlewares import trace_app diff --git a/ddtrace/contrib/asgi.py b/ddtrace/contrib/asgi.py index cb77f34e958..08d6073200b 100644 --- a/ddtrace/contrib/asgi.py +++ b/ddtrace/contrib/asgi.py @@ -89,7 +89,6 @@ def handle_request(scope, send): .. __: https://asgi.readthedocs.io/ """ - from ddtrace.contrib.internal.asgi.middleware import TraceMiddleware from ddtrace.contrib.internal.asgi.middleware import span_from_scope diff --git a/ddtrace/contrib/bottle.py b/ddtrace/contrib/bottle.py index 84f7c3a7d7d..7b5ee0c4515 100644 --- a/ddtrace/contrib/bottle.py +++ b/ddtrace/contrib/bottle.py @@ -32,6 +32,7 @@ config.bottle['distributed_tracing'] = True """ + from ddtrace.contrib.internal.bottle.trace import TracePlugin diff --git a/ddtrace/contrib/celery.py b/ddtrace/contrib/celery.py index f727e53c0e3..9cdfe40b773 100644 --- a/ddtrace/contrib/celery.py +++ b/ddtrace/contrib/celery.py @@ -51,6 +51,7 @@ def run(self): Default: ``'celery-worker'`` """ + from ddtrace.contrib.internal.celery.app import patch_app from ddtrace.contrib.internal.celery.app import unpatch_app diff --git a/ddtrace/contrib/cherrypy.py b/ddtrace/contrib/cherrypy.py index b217d16b440..6825716339a 100644 --- a/ddtrace/contrib/cherrypy.py +++ b/ddtrace/contrib/cherrypy.py @@ -52,6 +52,7 @@ def index(self): cherrypy.quickstart(HelloWorld()) """ + from ddtrace.contrib.internal.cherrypy.patch import TraceMiddleware diff --git a/ddtrace/contrib/dbapi.py b/ddtrace/contrib/dbapi.py index 595a2c1f7fb..8d98e1c92d1 100644 --- a/ddtrace/contrib/dbapi.py +++ b/ddtrace/contrib/dbapi.py @@ -1,6 +1,7 @@ """ Generic dbapi tracing code. """ + import wrapt from ddtrace import config diff --git a/ddtrace/contrib/falcon.py b/ddtrace/contrib/falcon.py index a80d298d09b..c0b09c94e01 100644 --- a/ddtrace/contrib/falcon.py +++ b/ddtrace/contrib/falcon.py @@ -44,6 +44,7 @@ def on_falcon_request(span, request, response): :ref:`Headers tracing ` is supported for this integration. """ + from ddtrace.contrib.internal.falcon.middleware import TraceMiddleware diff --git a/ddtrace/contrib/flask_cache.py b/ddtrace/contrib/flask_cache.py index 35cae2fb164..37af13bfc48 100644 --- a/ddtrace/contrib/flask_cache.py +++ b/ddtrace/contrib/flask_cache.py @@ -43,6 +43,7 @@ def counter(): Cache = get_traced_cache(tracer, service='my-flask-cache-app', cache_cls=Cache) """ + from ddtrace.contrib.internal.flask_cache.patch import get_traced_cache diff --git a/ddtrace/contrib/internal/asgi/middleware.py b/ddtrace/contrib/internal/asgi/middleware.py index 2bb6179fd8c..202999e426e 100644 --- a/ddtrace/contrib/internal/asgi/middleware.py +++ b/ddtrace/contrib/internal/asgi/middleware.py @@ -209,22 +209,25 @@ async def __call__(self, scope: Mapping[str, Any], receive: Callable, send: Call if scope["type"] == "http": operation_name = schematize_url_operation(operation_name, direction=SpanDirection.INBOUND, protocol="http") - with core.context_with_data( - "asgi.request", - remote_addr=scope.get("REMOTE_ADDR"), - headers=headers, - headers_case_sensitive=True, - environ=scope, - middleware=self, - span_name=operation_name, - resource=resource, - span_type=SpanTypes.WEB, - service=trace_utils.int_service(None, self.integration_config), - distributed_headers=headers, - activate_distributed_headers=True, - scope=scope, - integration_config=self.integration_config, - ) as ctx, ctx.span as span: + with ( + core.context_with_data( + "asgi.request", + remote_addr=scope.get("REMOTE_ADDR"), + headers=headers, + headers_case_sensitive=True, + environ=scope, + middleware=self, + span_name=operation_name, + resource=resource, + span_type=SpanTypes.WEB, + service=trace_utils.int_service(None, self.integration_config), + distributed_headers=headers, + activate_distributed_headers=True, + scope=scope, + integration_config=self.integration_config, + ) as ctx, + ctx.span as span, + ): if self.span_modifier: self.span_modifier(span, scope) diff --git a/ddtrace/contrib/internal/asgi/utils.py b/ddtrace/contrib/internal/asgi/utils.py index 73f5d176ccc..8f0c2758415 100644 --- a/ddtrace/contrib/internal/asgi/utils.py +++ b/ddtrace/contrib/internal/asgi/utils.py @@ -33,6 +33,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ + import asyncio import inspect diff --git a/ddtrace/contrib/internal/botocore/patch.py b/ddtrace/contrib/internal/botocore/patch.py index a3528d726ea..473e1510995 100644 --- a/ddtrace/contrib/internal/botocore/patch.py +++ b/ddtrace/contrib/internal/botocore/patch.py @@ -176,12 +176,15 @@ def patched_lib_fn(original_func, instance, args, kwargs): pin = Pin.get_from(instance) if not pin or not pin.enabled() or not config.botocore["instrument_internals"]: return original_func(*args, **kwargs) - with core.context_with_data( - "botocore.instrumented_lib_function", - span_name="{}.{}".format(original_func.__module__, original_func.__name__), - tags={COMPONENT: config.botocore.integration_name, SPAN_KIND: SpanKind.CLIENT}, - pin=pin, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "botocore.instrumented_lib_function", + span_name="{}.{}".format(original_func.__module__, original_func.__name__), + tags={COMPONENT: config.botocore.integration_name, SPAN_KIND: SpanKind.CLIENT}, + pin=pin, + ) as ctx, + ctx.span, + ): return original_func(*args, **kwargs) @@ -260,19 +263,24 @@ def patched_api_call_fallback(original_func, instance, args, kwargs, function_va endpoint_name = function_vars.get("endpoint_name") operation = function_vars.get("operation") - with core.context_with_data( - "botocore.instrumented_api_call", - instance=instance, - args=args, - params=params, - endpoint_name=endpoint_name, - operation=operation, - service=schematize_service_name("{}.{}".format(ext_service(pin, int_config=config.botocore), endpoint_name)), - pin=pin, - span_name=function_vars.get("trace_operation"), - span_type=SpanTypes.HTTP, - span_key="instrumented_api_call", - ) as ctx, ctx.span: + with ( + core.context_with_data( + "botocore.instrumented_api_call", + instance=instance, + args=args, + params=params, + endpoint_name=endpoint_name, + operation=operation, + service=schematize_service_name( + "{}.{}".format(ext_service(pin, int_config=config.botocore), endpoint_name) + ), + pin=pin, + span_name=function_vars.get("trace_operation"), + span_type=SpanTypes.HTTP, + span_key="instrumented_api_call", + ) as ctx, + ctx.span, + ): core.dispatch("botocore.patched_api_call.started", [ctx]) if args and config.botocore["distributed_tracing"]: prep_context_injection(ctx, endpoint_name, operation, trace_operation, params) diff --git a/ddtrace/contrib/internal/botocore/services/kinesis.py b/ddtrace/contrib/internal/botocore/services/kinesis.py index ce7d79ccc9d..ab14b88d9f9 100644 --- a/ddtrace/contrib/internal/botocore/services/kinesis.py +++ b/ddtrace/contrib/internal/botocore/services/kinesis.py @@ -134,26 +134,29 @@ def _patched_kinesis_api_call(parent_ctx, original_func, instance, args, kwargs, child_of = parent_ctx.get_item("distributed_context") if should_instrument: - with core.context_with_data( - "botocore.patched_kinesis_api_call", - parent=parent_ctx, - instance=instance, - args=args, - params=params, - endpoint_name=endpoint_name, - child_of=child_of if child_of is not None else pin.tracer.context_provider.active(), - operation=operation, - service=schematize_service_name( - "{}.{}".format(ext_service(pin, int_config=config.botocore), endpoint_name) - ), - call_trace=False, - pin=pin, - span_name=span_name, - span_type=SpanTypes.HTTP, - activate=True, - func_run=is_getrecords_call, - start_ns=start_ns, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "botocore.patched_kinesis_api_call", + parent=parent_ctx, + instance=instance, + args=args, + params=params, + endpoint_name=endpoint_name, + child_of=child_of if child_of is not None else pin.tracer.context_provider.active(), + operation=operation, + service=schematize_service_name( + "{}.{}".format(ext_service(pin, int_config=config.botocore), endpoint_name) + ), + call_trace=False, + pin=pin, + span_name=span_name, + span_type=SpanTypes.HTTP, + activate=True, + func_run=is_getrecords_call, + start_ns=start_ns, + ) as ctx, + ctx.span, + ): core.dispatch("botocore.patched_kinesis_api_call.started", [ctx]) if is_kinesis_put_operation: diff --git a/ddtrace/contrib/internal/botocore/services/sqs.py b/ddtrace/contrib/internal/botocore/services/sqs.py index 19062ae8b63..72c005c93f6 100644 --- a/ddtrace/contrib/internal/botocore/services/sqs.py +++ b/ddtrace/contrib/internal/botocore/services/sqs.py @@ -139,24 +139,27 @@ def _patched_sqs_api_call(parent_ctx, original_func, instance, args, kwargs, fun child_of = parent_ctx.get_item("distributed_context") if should_instrument: - with core.context_with_data( - "botocore.patched_sqs_api_call", - parent=parent_ctx, - span_name=call_name, - service=schematize_service_name( - "{}.{}".format(ext_service(pin, int_config=config.botocore), endpoint_name) - ), - span_type=SpanTypes.HTTP, - child_of=child_of if child_of is not None else pin.tracer.context_provider.active(), - activate=True, - instance=instance, - args=args, - params=params, - endpoint_name=endpoint_name, - operation=operation, - call_trace=False, - pin=pin, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "botocore.patched_sqs_api_call", + parent=parent_ctx, + span_name=call_name, + service=schematize_service_name( + "{}.{}".format(ext_service(pin, int_config=config.botocore), endpoint_name) + ), + span_type=SpanTypes.HTTP, + child_of=child_of if child_of is not None else pin.tracer.context_provider.active(), + activate=True, + instance=instance, + args=args, + params=params, + endpoint_name=endpoint_name, + operation=operation, + call_trace=False, + pin=pin, + ) as ctx, + ctx.span, + ): core.dispatch("botocore.patched_sqs_api_call.started", [ctx]) if should_update_messages: diff --git a/ddtrace/contrib/internal/botocore/services/stepfunctions.py b/ddtrace/contrib/internal/botocore/services/stepfunctions.py index 72db8dbd119..ef2a7439050 100644 --- a/ddtrace/contrib/internal/botocore/services/stepfunctions.py +++ b/ddtrace/contrib/internal/botocore/services/stepfunctions.py @@ -61,19 +61,24 @@ def patched_stepfunction_api_call(original_func, instance, args, kwargs: Dict, f else: call_name = trace_operation - with core.context_with_data( - "botocore.patched_stepfunctions_api_call", - span_name=call_name, - service=schematize_service_name("{}.{}".format(ext_service(pin, int_config=config.botocore), endpoint_name)), - span_type=SpanTypes.HTTP, - span_key="patched_stepfunctions_api_call", - instance=instance, - args=args, - params=params, - endpoint_name=endpoint_name, - operation=operation, - pin=pin, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "botocore.patched_stepfunctions_api_call", + span_name=call_name, + service=schematize_service_name( + "{}.{}".format(ext_service(pin, int_config=config.botocore), endpoint_name) + ), + span_type=SpanTypes.HTTP, + span_key="patched_stepfunctions_api_call", + instance=instance, + args=args, + params=params, + endpoint_name=endpoint_name, + operation=operation, + pin=pin, + ) as ctx, + ctx.span, + ): core.dispatch("botocore.patched_stepfunctions_api_call.started", [ctx]) if should_update_input: diff --git a/ddtrace/contrib/internal/botocore/utils.py b/ddtrace/contrib/internal/botocore/utils.py index 664bc5d7741..50491076141 100644 --- a/ddtrace/contrib/internal/botocore/utils.py +++ b/ddtrace/contrib/internal/botocore/utils.py @@ -1,6 +1,7 @@ """ Trace queries monitoring to aws api done via botocore client """ + import base64 import json from typing import Any diff --git a/ddtrace/contrib/internal/bottle/trace.py b/ddtrace/contrib/internal/bottle/trace.py index 80ad18263df..cefb238574c 100644 --- a/ddtrace/contrib/internal/bottle/trace.py +++ b/ddtrace/contrib/internal/bottle/trace.py @@ -37,19 +37,24 @@ def wrapped(*args, **kwargs): resource = "{} {}".format(request.method, route.rule) - with core.context_with_data( - "bottle.request", - span_name=schematize_url_operation("bottle.request", protocol="http", direction=SpanDirection.INBOUND), - span_type=SpanTypes.WEB, - service=self.service, - resource=resource, - tags={}, - tracer=self.tracer, - distributed_headers=request.headers, - integration_config=config.bottle, - headers_case_sensitive=True, - activate_distributed_headers=True, - ) as ctx, ctx.span as req_span: + with ( + core.context_with_data( + "bottle.request", + span_name=schematize_url_operation( + "bottle.request", protocol="http", direction=SpanDirection.INBOUND + ), + span_type=SpanTypes.WEB, + service=self.service, + resource=resource, + tags={}, + tracer=self.tracer, + distributed_headers=request.headers, + integration_config=config.bottle, + headers_case_sensitive=True, + activate_distributed_headers=True, + ) as ctx, + ctx.span as req_span, + ): ctx.set_item("req_span", req_span) core.dispatch("web.request.start", (ctx, config.bottle)) diff --git a/ddtrace/contrib/internal/cherrypy/patch.py b/ddtrace/contrib/internal/cherrypy/patch.py index b657192a4f4..512dd0399c3 100644 --- a/ddtrace/contrib/internal/cherrypy/patch.py +++ b/ddtrace/contrib/internal/cherrypy/patch.py @@ -1,6 +1,7 @@ """ Datadog trace code for cherrypy. """ + import logging import os from typing import Dict diff --git a/ddtrace/contrib/internal/django/patch.py b/ddtrace/contrib/internal/django/patch.py index 8b6d613f1ba..3c2558ff12e 100644 --- a/ddtrace/contrib/internal/django/patch.py +++ b/ddtrace/contrib/internal/django/patch.py @@ -162,9 +162,10 @@ def traced_populate(django, pin, func, instance, args, kwargs): def traced_func(django, name, resource=None, ignored_excs=None): def wrapped(django, pin, func, instance, args, kwargs): tags = {COMPONENT: config_django.integration_name} - with core.context_with_data( - "django.func.wrapped", span_name=name, resource=resource, tags=tags, pin=pin - ) as ctx, ctx.span: + with ( + core.context_with_data("django.func.wrapped", span_name=name, resource=resource, tags=tags, pin=pin) as ctx, + ctx.span, + ): core.dispatch( "django.func.wrapped", ( diff --git a/ddtrace/contrib/internal/flask/patch.py b/ddtrace/contrib/internal/flask/patch.py index 3e9aee5850d..b4b6cb5c64e 100644 --- a/ddtrace/contrib/internal/flask/patch.py +++ b/ddtrace/contrib/internal/flask/patch.py @@ -503,14 +503,17 @@ def traced_render(wrapped, instance, args, kwargs): pin = Pin._find(wrapped, instance, get_current_app()) if not pin or not pin.enabled(): return wrapped(*args, **kwargs) - with core.context_with_data( - "flask.render_template", - span_name=name, - pin=pin, - flask_config=config.flask, - tags={COMPONENT: config.flask.integration_name}, - span_type=SpanTypes.TEMPLATE, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "flask.render_template", + span_name=name, + pin=pin, + flask_config=config.flask, + tags={COMPONENT: config.flask.integration_name}, + span_type=SpanTypes.TEMPLATE, + ) as ctx, + ctx.span, + ): return wrapped(*args, **kwargs) return traced_render @@ -555,17 +558,20 @@ def _block_request_callable(call): def request_patcher(name): @with_instance_pin def _patched_request(pin, wrapped, instance, args, kwargs): - with core.context_with_data( - "flask._patched_request", - span_name=".".join(("flask", name)), - pin=pin, - service=trace_utils.int_service(pin, config.flask, pin), - flask_config=config.flask, - flask_request=flask.request, - block_request_callable=_block_request_callable, - ignored_exception_type=NotFound, - tags={COMPONENT: config.flask.integration_name}, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "flask._patched_request", + span_name=".".join(("flask", name)), + pin=pin, + service=trace_utils.int_service(pin, config.flask, pin), + flask_config=config.flask, + flask_request=flask.request, + block_request_callable=_block_request_callable, + ignored_exception_type=NotFound, + tags={COMPONENT: config.flask.integration_name}, + ) as ctx, + ctx.span, + ): core.dispatch("flask._patched_request", (ctx,)) return wrapped(*args, **kwargs) @@ -590,11 +596,14 @@ def patched_jsonify(wrapped, instance, args, kwargs): if not pin or not pin.enabled(): return wrapped(*args, **kwargs) - with core.context_with_data( - "flask.jsonify", - span_name="flask.jsonify", - flask_config=config.flask, - tags={COMPONENT: config.flask.integration_name}, - pin=pin, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "flask.jsonify", + span_name="flask.jsonify", + flask_config=config.flask, + tags={COMPONENT: config.flask.integration_name}, + pin=pin, + ) as ctx, + ctx.span, + ): return wrapped(*args, **kwargs) diff --git a/ddtrace/contrib/internal/flask/wrappers.py b/ddtrace/contrib/internal/flask/wrappers.py index 1d4c7e07e26..6b072619084 100644 --- a/ddtrace/contrib/internal/flask/wrappers.py +++ b/ddtrace/contrib/internal/flask/wrappers.py @@ -35,15 +35,18 @@ def _wrap_call( tags = {COMPONENT: config.flask.integration_name} if signal: tags["flask.signal"] = signal - with core.context_with_data( - "flask.call", - span_name=name, - pin=pin, - resource=resource, - service=trace_utils.int_service(pin, config.flask), - span_type=span_type, - tags=tags, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "flask.call", + span_name=name, + pin=pin, + resource=resource, + service=trace_utils.int_service(pin, config.flask), + span_type=span_type, + tags=tags, + ) as ctx, + ctx.span, + ): if do_dispatch: dispatch = core.dispatch_with_results( # ast-grep-ignore: core-dispatch-with-results "flask.wrapped_view", (kwargs,) diff --git a/ddtrace/contrib/internal/kombu/utils.py b/ddtrace/contrib/internal/kombu/utils.py index 96acd6795cc..503a0d40dea 100644 --- a/ddtrace/contrib/internal/kombu/utils.py +++ b/ddtrace/contrib/internal/kombu/utils.py @@ -1,6 +1,7 @@ """ Some utils used by the dogtrace kombu integration """ + from ddtrace.ext import kombu as kombux from ddtrace.ext import net diff --git a/ddtrace/contrib/internal/molten/patch.py b/ddtrace/contrib/internal/molten/patch.py index 3591631021d..ce3dfe4d11c 100644 --- a/ddtrace/contrib/internal/molten/patch.py +++ b/ddtrace/contrib/internal/molten/patch.py @@ -79,20 +79,23 @@ def patch_app_call(wrapped, instance, args, kwargs): request = molten.http.Request.from_environ(environ) resource = func_name(wrapped) - with core.context_with_data( - "molten.request", - span_name=schematize_url_operation("molten.request", protocol="http", direction=SpanDirection.INBOUND), - span_type=SpanTypes.WEB, - service=trace_utils.int_service(pin, config.molten), - resource=resource, - tags={}, - tracer=pin.tracer, - distributed_headers=dict(request.headers), # request.headers is type Iterable[Tuple[str, str]] - integration_config=config.molten, - allow_default_resource=True, - activate_distributed_headers=True, - headers_case_sensitive=True, - ) as ctx, ctx.span as req_span: + with ( + core.context_with_data( + "molten.request", + span_name=schematize_url_operation("molten.request", protocol="http", direction=SpanDirection.INBOUND), + span_type=SpanTypes.WEB, + service=trace_utils.int_service(pin, config.molten), + resource=resource, + tags={}, + tracer=pin.tracer, + distributed_headers=dict(request.headers), # request.headers is type Iterable[Tuple[str, str]] + integration_config=config.molten, + allow_default_resource=True, + activate_distributed_headers=True, + headers_case_sensitive=True, + ) as ctx, + ctx.span as req_span, + ): ctx.set_item("req_span", req_span) core.dispatch("web.request.start", (ctx, config.molten)) diff --git a/ddtrace/contrib/internal/pymongo/parse.py b/ddtrace/contrib/internal/pymongo/parse.py index af5197b5285..1dc751ec6b6 100644 --- a/ddtrace/contrib/internal/pymongo/parse.py +++ b/ddtrace/contrib/internal/pymongo/parse.py @@ -51,7 +51,7 @@ def __init__(self, name, db, coll): self.query = None def __repr__(self): - return ("Command(" "name=%s," "db=%s," "coll=%s)") % (self.name, self.db, self.coll) + return ("Command(name=%s,db=%s,coll=%s)") % (self.name, self.db, self.coll) def parse_msg(msg_bytes): diff --git a/ddtrace/contrib/internal/pyramid/trace.py b/ddtrace/contrib/internal/pyramid/trace.py index bf4e274032f..99d3d3deff1 100644 --- a/ddtrace/contrib/internal/pyramid/trace.py +++ b/ddtrace/contrib/internal/pyramid/trace.py @@ -69,19 +69,24 @@ def trace_tween_factory(handler, registry): if enabled: # make a request tracing function def trace_tween(request): - with core.context_with_data( - "pyramid.request", - span_name=schematize_url_operation("pyramid.request", protocol="http", direction=SpanDirection.INBOUND), - span_type=SpanTypes.WEB, - service=service, - resource="404", - tags={}, - tracer=tracer, - distributed_headers=request.headers, - integration_config=config.pyramid, - activate_distributed_headers=True, - headers_case_sensitive=True, - ) as ctx, ctx.span as req_span: + with ( + core.context_with_data( + "pyramid.request", + span_name=schematize_url_operation( + "pyramid.request", protocol="http", direction=SpanDirection.INBOUND + ), + span_type=SpanTypes.WEB, + service=service, + resource="404", + tags={}, + tracer=tracer, + distributed_headers=request.headers, + integration_config=config.pyramid, + activate_distributed_headers=True, + headers_case_sensitive=True, + ) as ctx, + ctx.span as req_span, + ): ctx.set_item("req_span", req_span) core.dispatch("web.request.start", (ctx, config.pyramid)) diff --git a/ddtrace/contrib/internal/pytest/plugin.py b/ddtrace/contrib/internal/pytest/plugin.py index fc64e9c3f45..53f8b34bba0 100644 --- a/ddtrace/contrib/internal/pytest/plugin.py +++ b/ddtrace/contrib/internal/pytest/plugin.py @@ -11,6 +11,7 @@ expected failures. """ + import os from typing import Dict # noqa:F401 diff --git a/ddtrace/contrib/internal/rq/patch.py b/ddtrace/contrib/internal/rq/patch.py index d66876630d7..723a99dd5a1 100644 --- a/ddtrace/contrib/internal/rq/patch.py +++ b/ddtrace/contrib/internal/rq/patch.py @@ -62,24 +62,27 @@ def traced_queue_enqueue_job(rq, pin, func, instance, args, kwargs): else: resource = func_name - with core.context_with_data( - "rq.queue.enqueue_job", - span_name=schematize_messaging_operation( - "rq.queue.enqueue_job", provider="rq", direction=SpanDirection.OUTBOUND - ), - pin=pin, - service=trace_utils.int_service(pin, config.rq), - resource=resource, - span_type=SpanTypes.WORKER, - integration_config=config.rq_worker, - tags={ - COMPONENT: config.rq.integration_name, - SPAN_KIND: SpanKind.PRODUCER, - QUEUE_NAME: instance.name, - JOB_ID: job.get_id(), - JOB_FUNC_NAME: job.func_name, - }, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "rq.queue.enqueue_job", + span_name=schematize_messaging_operation( + "rq.queue.enqueue_job", provider="rq", direction=SpanDirection.OUTBOUND + ), + pin=pin, + service=trace_utils.int_service(pin, config.rq), + resource=resource, + span_type=SpanTypes.WORKER, + integration_config=config.rq_worker, + tags={ + COMPONENT: config.rq.integration_name, + SPAN_KIND: SpanKind.PRODUCER, + QUEUE_NAME: instance.name, + JOB_ID: job.get_id(), + JOB_FUNC_NAME: job.func_name, + }, + ) as ctx, + ctx.span, + ): # If the queue is_async then add distributed tracing headers to the job if instance.is_async: core.dispatch("rq.queue.enqueue_job", [ctx, job.meta]) @@ -89,15 +92,18 @@ def traced_queue_enqueue_job(rq, pin, func, instance, args, kwargs): @trace_utils.with_traced_module def traced_queue_fetch_job(rq, pin, func, instance, args, kwargs): job_id = get_argument_value(args, kwargs, 0, "job_id") - with core.context_with_data( - "rq.traced_queue_fetch_job", - span_name=schematize_messaging_operation( - "rq.queue.fetch_job", provider="rq", direction=SpanDirection.PROCESSING - ), - pin=pin, - service=trace_utils.int_service(pin, config.rq), - tags={COMPONENT: config.rq.integration_name, JOB_ID: job_id}, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "rq.traced_queue_fetch_job", + span_name=schematize_messaging_operation( + "rq.queue.fetch_job", provider="rq", direction=SpanDirection.PROCESSING + ), + pin=pin, + service=trace_utils.int_service(pin, config.rq), + tags={COMPONENT: config.rq.integration_name, JOB_ID: job_id}, + ) as ctx, + ctx.span, + ): return func(*args, **kwargs) @@ -108,18 +114,21 @@ def traced_perform_job(rq, pin, func, instance, args, kwargs): job = get_argument_value(args, kwargs, 0, "job") try: - with core.context_with_data( - "rq.worker.perform_job", - span_name="rq.worker.perform_job", - service=trace_utils.int_service(pin, config.rq_worker), - pin=pin, - span_type=SpanTypes.WORKER, - resource=job.func_name, - integration_config=config.rq_worker, - distributed_headers=job.meta, - activate_distributed_headers=True, - tags={COMPONENT: config.rq.integration_name, SPAN_KIND: SpanKind.CONSUMER, JOB_ID: job.get_id()}, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "rq.worker.perform_job", + span_name="rq.worker.perform_job", + service=trace_utils.int_service(pin, config.rq_worker), + pin=pin, + span_type=SpanTypes.WORKER, + resource=job.func_name, + integration_config=config.rq_worker, + distributed_headers=job.meta, + activate_distributed_headers=True, + tags={COMPONENT: config.rq.integration_name, SPAN_KIND: SpanKind.CONSUMER, JOB_ID: job.get_id()}, + ) as ctx, + ctx.span, + ): try: return func(*args, **kwargs) finally: @@ -142,13 +151,16 @@ def traced_job_perform(rq, pin, func, instance, args, kwargs): # Inherit the service name from whatever parent exists. # eg. in a worker, a perform_job parent span will exist with the worker # service. - with core.context_with_data( - "rq.job.perform", - span_name="rq.job.perform", - resource=job.func_name, - pin=pin, - tags={COMPONENT: config.rq.integration_name, JOB_ID: job.get_id()}, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "rq.job.perform", + span_name="rq.job.perform", + resource=job.func_name, + pin=pin, + tags={COMPONENT: config.rq.integration_name, JOB_ID: job.get_id()}, + ) as ctx, + ctx.span, + ): return func(*args, **kwargs) @@ -156,15 +168,18 @@ def traced_job_perform(rq, pin, func, instance, args, kwargs): def traced_job_fetch_many(rq, pin, func, instance, args, kwargs): """Trace rq.Job.fetch_many(...)""" job_ids = get_argument_value(args, kwargs, 0, "job_ids") - with core.context_with_data( - "rq.job.fetch_many", - span_name=schematize_messaging_operation( - "rq.job.fetch_many", provider="rq", direction=SpanDirection.PROCESSING - ), - service=trace_utils.ext_service(pin, config.rq_worker), - pin=pin, - tags={COMPONENT: config.rq.integration_name, JOB_ID: job_ids}, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "rq.job.fetch_many", + span_name=schematize_messaging_operation( + "rq.job.fetch_many", provider="rq", direction=SpanDirection.PROCESSING + ), + service=trace_utils.ext_service(pin, config.rq_worker), + pin=pin, + tags={COMPONENT: config.rq.integration_name, JOB_ID: job_ids}, + ) as ctx, + ctx.span, + ): return func(*args, **kwargs) diff --git a/ddtrace/contrib/internal/sqlalchemy/engine.py b/ddtrace/contrib/internal/sqlalchemy/engine.py index f9912cec2c8..195af1ef413 100644 --- a/ddtrace/contrib/internal/sqlalchemy/engine.py +++ b/ddtrace/contrib/internal/sqlalchemy/engine.py @@ -11,6 +11,7 @@ engine.connect().execute('select count(*) from users') """ + # 3p import sqlalchemy from sqlalchemy.event import listen diff --git a/ddtrace/contrib/internal/tornado/constants.py b/ddtrace/contrib/internal/tornado/constants.py index 18a3a6eb5a1..e4af68bda97 100644 --- a/ddtrace/contrib/internal/tornado/constants.py +++ b/ddtrace/contrib/internal/tornado/constants.py @@ -2,6 +2,7 @@ This module defines Tornado settings that are shared between integration modules. """ + CONFIG_KEY = "datadog_trace" REQUEST_SPAN_KEY = "__datadog_request_span" FUTURE_SPAN_KEY = "__datadog_future_span" diff --git a/ddtrace/contrib/internal/tornado/stack_context.py b/ddtrace/contrib/internal/tornado/stack_context.py index a6978c7f25c..0c976d7071f 100644 --- a/ddtrace/contrib/internal/tornado/stack_context.py +++ b/ddtrace/contrib/internal/tornado/stack_context.py @@ -61,7 +61,7 @@ def __exit__(self, type, value, traceback): # noqa: A002 if final_contexts is not self.new_contexts: raise StackContextInconsistentError( - "stack_context inconsistency (may be caused by yield " 'within a "with TracerStackContext" block)' + 'stack_context inconsistency (may be caused by yield within a "with TracerStackContext" block)' ) # break the reference to allow faster GC on CPython diff --git a/ddtrace/contrib/internal/trace_utils_async.py b/ddtrace/contrib/internal/trace_utils_async.py index 910d2c9049c..fbdc45d35f8 100644 --- a/ddtrace/contrib/internal/trace_utils_async.py +++ b/ddtrace/contrib/internal/trace_utils_async.py @@ -3,6 +3,7 @@ Note that this module should only be imported in Python 3.5+. """ + from ddtrace._trace.pin import Pin from ddtrace.internal.logger import get_logger diff --git a/ddtrace/contrib/internal/valkey/patch.py b/ddtrace/contrib/internal/valkey/patch.py index ba8b794962b..dec3646cea0 100644 --- a/ddtrace/contrib/internal/valkey/patch.py +++ b/ddtrace/contrib/internal/valkey/patch.py @@ -66,6 +66,7 @@ # as the service name. client.get("my-key") """ + import os from typing import Dict diff --git a/ddtrace/contrib/internal/wsgi/wsgi.py b/ddtrace/contrib/internal/wsgi/wsgi.py index e977789108a..2938b28c95f 100644 --- a/ddtrace/contrib/internal/wsgi/wsgi.py +++ b/ddtrace/contrib/internal/wsgi/wsgi.py @@ -288,19 +288,22 @@ def __init__(self, application, tracer=None, span_modifier=default_wsgi_span_mod self.span_modifier = span_modifier def _traced_start_response(self, start_response, request_span, app_span, status, environ, exc_info=None): - with core.context_with_data( - "wsgi.response", - middleware=self, - request_span=request_span, - parent_call=app_span, - status=status, - environ=environ, - span_type=SpanTypes.WEB, - span_name="wsgi.start_response", - service=trace_utils.int_service(None, self._config), - start_span=True, - tags={COMPONENT: self._config.integration_name, SPAN_KIND: SpanKind.SERVER}, - ) as ctx, ctx.span: + with ( + core.context_with_data( + "wsgi.response", + middleware=self, + request_span=request_span, + parent_call=app_span, + status=status, + environ=environ, + span_type=SpanTypes.WEB, + span_name="wsgi.start_response", + service=trace_utils.int_service(None, self._config), + start_span=True, + tags={COMPONENT: self._config.integration_name, SPAN_KIND: SpanKind.SERVER}, + ) as ctx, + ctx.span, + ): return start_response(status, environ, exc_info) def _request_span_modifier(self, req_span, environ, parsed_headers=None): diff --git a/ddtrace/contrib/pyramid.py b/ddtrace/contrib/pyramid.py index d608a83fc3e..578cd264a47 100644 --- a/ddtrace/contrib/pyramid.py +++ b/ddtrace/contrib/pyramid.py @@ -39,6 +39,7 @@ :ref:`All HTTP tags ` are supported for this integration. """ + from ddtrace.contrib.internal.pyramid.trace import includeme from ddtrace.contrib.internal.pyramid.trace import trace_pyramid from ddtrace.contrib.internal.pyramid.trace import trace_tween_factory diff --git a/ddtrace/contrib/requests.py b/ddtrace/contrib/requests.py index 747facfe98e..e2dbabc84bb 100644 --- a/ddtrace/contrib/requests.py +++ b/ddtrace/contrib/requests.py @@ -71,6 +71,7 @@ session = Session() Pin.override(session, service='auth-api') """ + from ddtrace.contrib.internal.requests.patch import TracedSession diff --git a/ddtrace/contrib/sqlalchemy.py b/ddtrace/contrib/sqlalchemy.py index e69e6b9c0a8..d06556ce56f 100644 --- a/ddtrace/contrib/sqlalchemy.py +++ b/ddtrace/contrib/sqlalchemy.py @@ -20,6 +20,7 @@ # Use a PIN to specify metadata related to this engine Pin.override(engine, service='replica-db') """ + from ddtrace.contrib.internal.sqlalchemy.engine import trace_engine diff --git a/ddtrace/contrib/tornado.py b/ddtrace/contrib/tornado.py index f460d350886..ad29c6492ac 100644 --- a/ddtrace/contrib/tornado.py +++ b/ddtrace/contrib/tornado.py @@ -97,6 +97,7 @@ def log_exception(self, typ, value, tb): * ``agent_port`` (default: `8126`): define the port of the APM agent. * ``settings`` (default: ``{}``): Tracer extra settings used to change, for instance, the filtering behavior. """ + from ddtrace.contrib.internal.tornado.stack_context import TracerStackContext from ddtrace.contrib.internal.tornado.stack_context import context_provider from ddtrace.contrib.internal.tornado.stack_context import run_with_trace_context diff --git a/ddtrace/contrib/wsgi.py b/ddtrace/contrib/wsgi.py index 94f44fbb9df..9ea04ef5db3 100644 --- a/ddtrace/contrib/wsgi.py +++ b/ddtrace/contrib/wsgi.py @@ -36,6 +36,7 @@ :ref:`All HTTP tags ` are supported for this integration. """ + from ddtrace.contrib.internal.wsgi.wsgi import DDWSGIMiddleware diff --git a/ddtrace/debugging/_probe/model.py b/ddtrace/debugging/_probe/model.py index e5700ad324e..ad503028272 100644 --- a/ddtrace/debugging/_probe/model.py +++ b/ddtrace/debugging/_probe/model.py @@ -99,8 +99,7 @@ def __hash__(self): class AbstractProbeMixIn(abc.ABC): - def __post_init__(self): - ... + def __post_init__(self): ... @dataclass diff --git a/ddtrace/debugging/_session.py b/ddtrace/debugging/_session.py index f6c37bae2f6..1f3e796f90e 100644 --- a/ddtrace/debugging/_session.py +++ b/ddtrace/debugging/_session.py @@ -88,9 +88,9 @@ def is_active(cls, ident: SessionId) -> bool: class SessionManager: - _sessions_trace_map: t.MutableMapping[ - t.Any, t.Dict[SessionId, Session] - ] = wkdict() # Trace context to Sessions mapping + _sessions_trace_map: t.MutableMapping[t.Any, t.Dict[SessionId, Session]] = ( + wkdict() + ) # Trace context to Sessions mapping @classmethod def link_session_to_trace(cls, session: Session, trace_context: t.Optional[t.Any] = None) -> None: diff --git a/ddtrace/errortracking/product.py b/ddtrace/errortracking/product.py index 71f8372b5c5..3540143e0f0 100644 --- a/ddtrace/errortracking/product.py +++ b/ddtrace/errortracking/product.py @@ -1,6 +1,7 @@ """ This is the entry point for the Error Tracking automatic reporting of handled exception. """ + from ddtrace.internal.settings.errortracking import config diff --git a/ddtrace/ext/ci.py b/ddtrace/ext/ci.py index 26ae22f44ca..f1263d7bd0f 100644 --- a/ddtrace/ext/ci.py +++ b/ddtrace/ext/ci.py @@ -1,6 +1,7 @@ """ Tags for common CI attributes """ + import json import logging import os @@ -164,9 +165,7 @@ def extract_appveyor(env): if env.get("APPVEYOR_REPO_PROVIDER") == "github": repository = "https://github.com/{0}.git".format(env.get("APPVEYOR_REPO_NAME")) # type: Optional[str] commit = env.get("APPVEYOR_REPO_COMMIT") # type: Optional[str] - branch = env.get("APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH") or env.get( - "APPVEYOR_REPO_BRANCH" - ) # type: Optional[str] + branch = env.get("APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH") or env.get("APPVEYOR_REPO_BRANCH") # type: Optional[str] tag = env.get("APPVEYOR_REPO_TAG_NAME") # type: Optional[str] else: repository = commit = branch = tag = None @@ -203,9 +202,7 @@ def extract_azure_pipelines(env): env.get("SYSTEM_TEAMFOUNDATIONSERVERURI"), env.get("SYSTEM_TEAMPROJECTID"), env.get("BUILD_BUILDID") ) pipeline_url = base_url # type: Optional[str] - job_url = base_url + "&view=logs&j={0}&t={1}".format( - env.get("SYSTEM_JOBID"), env.get("SYSTEM_TASKINSTANCEID") - ) # type: Optional[str] + job_url = base_url + "&view=logs&j={0}&t={1}".format(env.get("SYSTEM_JOBID"), env.get("SYSTEM_TASKINSTANCEID")) # type: Optional[str] else: pipeline_url = job_url = None diff --git a/ddtrace/ext/http.py b/ddtrace/ext/http.py index 4c47d918add..012f8755f0b 100644 --- a/ddtrace/ext/http.py +++ b/ddtrace/ext/http.py @@ -6,6 +6,7 @@ span.set_tag(URL, '/user/home') span.set_tag(STATUS_CODE, 404) """ + # tags URL = "http.url" METHOD = "http.method" diff --git a/ddtrace/ext/test_visibility/api.py b/ddtrace/ext/test_visibility/api.py index 93fbfbe19d3..69f7657e127 100644 --- a/ddtrace/ext/test_visibility/api.py +++ b/ddtrace/ext/test_visibility/api.py @@ -12,6 +12,7 @@ All types and methods for interacting with the API are provided and documented in this file. """ + from enum import Enum from pathlib import Path from typing import Any diff --git a/ddtrace/internal/_encoding.pyi b/ddtrace/internal/_encoding.pyi index 73cba3d6f28..604e6742208 100644 --- a/ddtrace/internal/_encoding.pyi +++ b/ddtrace/internal/_encoding.pyi @@ -1,8 +1,8 @@ from typing import Any from typing import List from typing import Optional -from typing import Union from typing import Tuple +from typing import Union from ddtrace._trace.span import Span diff --git a/ddtrace/internal/agent.py b/ddtrace/internal/agent.py index d2b43078f9f..7c424c4657f 100644 --- a/ddtrace/internal/agent.py +++ b/ddtrace/internal/agent.py @@ -41,8 +41,7 @@ def __init__(self, interval: float = 0.0): self._state = self._agent_check @abc.abstractmethod - def info_check(self, agent_info: t.Optional[dict]) -> bool: - ... + def info_check(self, agent_info: t.Optional[dict]) -> bool: ... def _agent_check(self) -> None: try: @@ -62,8 +61,7 @@ def _online(self) -> None: log.debug("Error during online operation, reverting to agent check", exc_info=True) @abc.abstractmethod - def online(self) -> None: - ... + def online(self) -> None: ... def periodic(self) -> None: return self._state() diff --git a/ddtrace/internal/appsec/prototypes.py b/ddtrace/internal/appsec/prototypes.py index bd346545d09..f05fba102f0 100644 --- a/ddtrace/internal/appsec/prototypes.py +++ b/ddtrace/internal/appsec/prototypes.py @@ -6,14 +6,10 @@ def _update_rules( self, removals: t.Sequence[t.Tuple[str, str]], updates: t.Sequence[t.Tuple[str, str, t.Optional[t.Dict[str, t.Any]]]], - ) -> bool: - ... + ) -> bool: ... - def on_span_start(self, span: t.Any) -> None: - ... + def on_span_start(self, span: t.Any) -> None: ... - def on_span_finish(self, span: t.Any) -> None: - ... + def on_span_finish(self, span: t.Any) -> None: ... - def shutdown(self, timeout: t.Optional[float]) -> None: - ... + def shutdown(self, timeout: t.Optional[float]) -> None: ... diff --git a/ddtrace/internal/atexit.py b/ddtrace/internal/atexit.py index c85bd450f27..6e70c08c8fe 100644 --- a/ddtrace/internal/atexit.py +++ b/ddtrace/internal/atexit.py @@ -2,6 +2,7 @@ """ An API to provide atexit functionalities """ + from __future__ import absolute_import import atexit diff --git a/ddtrace/internal/ci_visibility/service_registry.py b/ddtrace/internal/ci_visibility/service_registry.py index dcf64c5be42..d1cc221c8a8 100644 --- a/ddtrace/internal/ci_visibility/service_registry.py +++ b/ddtrace/internal/ci_visibility/service_registry.py @@ -1,4 +1,5 @@ """Service registry to avoid circular imports in CI Visibility system.""" + import typing as t diff --git a/ddtrace/internal/ci_visibility/writer.py b/ddtrace/internal/ci_visibility/writer.py index a3a0ba9d217..e6181c58ac9 100644 --- a/ddtrace/internal/ci_visibility/writer.py +++ b/ddtrace/internal/ci_visibility/writer.py @@ -130,9 +130,7 @@ def __init__( intake_url = "%s.%s" % (AGENTLESS_BASE_URL, os.getenv("DD_SITE", AGENTLESS_DEFAULT_SITE)) self._use_evp = use_evp - clients = ( - [CIVisibilityProxiedEventClient()] if self._use_evp else [CIVisibilityAgentlessEventClient()] - ) # type: List[WriterClientBase] + clients = [CIVisibilityProxiedEventClient()] if self._use_evp else [CIVisibilityAgentlessEventClient()] # type: List[WriterClientBase] self._coverage_enabled = coverage_enabled self._itr_suite_skipping_mode = itr_suite_skipping_mode if self._coverage_enabled: diff --git a/ddtrace/internal/coverage/threading_coverage.py b/ddtrace/internal/coverage/threading_coverage.py index e257c6cd0e6..25cda4166e6 100644 --- a/ddtrace/internal/coverage/threading_coverage.py +++ b/ddtrace/internal/coverage/threading_coverage.py @@ -12,6 +12,7 @@ Session-level coverage does not need special-casing since the ModuleCodeCollector behavior is process-wide and thread-safe. """ + import pickle # nosec: B403 -- pickle is only used to serialize coverage data from a spawned thread to the main thread from queue import Queue import threading diff --git a/ddtrace/internal/datadog/profiling/ddup/_ddup.pyi b/ddtrace/internal/datadog/profiling/ddup/_ddup.pyi index 00cfcbfc613..de9fbbd4965 100644 --- a/ddtrace/internal/datadog/profiling/ddup/_ddup.pyi +++ b/ddtrace/internal/datadog/profiling/ddup/_ddup.pyi @@ -1,10 +1,12 @@ from typing import Dict from typing import Optional from typing import Union -from .._types import StringType + +import ddtrace from ddtrace._trace.span import Span from ddtrace._trace.tracer import Tracer -import ddtrace + +from .._types import StringType def config( env: StringType = None, diff --git a/ddtrace/internal/datadog/profiling/stack_v2/__init__.pyi b/ddtrace/internal/datadog/profiling/stack_v2/__init__.pyi index 32c415a5eec..72654f5bd42 100644 --- a/ddtrace/internal/datadog/profiling/stack_v2/__init__.pyi +++ b/ddtrace/internal/datadog/profiling/stack_v2/__init__.pyi @@ -1,6 +1,8 @@ import asyncio from types import FrameType -from typing import Optional, Sequence, Union +from typing import Optional +from typing import Sequence +from typing import Union from ddtrace._trace import context from ddtrace._trace import span as ddspan diff --git a/ddtrace/internal/datastreams/fnv.py b/ddtrace/internal/datastreams/fnv.py index ee200af557e..11d6fb4cc05 100644 --- a/ddtrace/internal/datastreams/fnv.py +++ b/ddtrace/internal/datastreams/fnv.py @@ -2,6 +2,7 @@ Implementation of Fowler/Noll/Vo hash algorithm in pure Python. See http://isthe.com/chongo/tech/comp/fnv/ """ + import sys diff --git a/ddtrace/internal/datastreams/processor.py b/ddtrace/internal/datastreams/processor.py index e9b8a874259..a229f48387b 100644 --- a/ddtrace/internal/datastreams/processor.py +++ b/ddtrace/internal/datastreams/processor.py @@ -112,9 +112,7 @@ def __init__( self._timeout = timeout # Have the bucket size match the interval in which flushes occur. self._bucket_size_ns = int(interval * 1e9) # type: int - self._buckets = defaultdict( - lambda: Bucket(defaultdict(PathwayStats), defaultdict(int), defaultdict(int)) - ) # type: DefaultDict[int, Bucket] + self._buckets = defaultdict(lambda: Bucket(defaultdict(PathwayStats), defaultdict(int), defaultdict(int))) # type: DefaultDict[int, Bucket] self._version = get_version() self._headers = { "Datadog-Meta-Lang": "python", diff --git a/ddtrace/internal/ipc.py b/ddtrace/internal/ipc.py index f17e08788ca..5b9166648f8 100644 --- a/ddtrace/internal/ipc.py +++ b/ddtrace/internal/ipc.py @@ -19,11 +19,9 @@ class BaseLock: def __init__(self, file: typing.IO[typing.Any]): self.file = file - def acquire(self): - ... + def acquire(self): ... - def release(self): - ... + def release(self): ... def __enter__(self): self.acquire() diff --git a/ddtrace/internal/native/_native.pyi b/ddtrace/internal/native/_native.pyi index b6d66f81e68..c515aec12f7 100644 --- a/ddtrace/internal/native/_native.pyi +++ b/ddtrace/internal/native/_native.pyi @@ -1,5 +1,9 @@ -from typing import Dict, List, Literal, Optional, Any from enum import Enum +from typing import Any +from typing import Dict +from typing import List +from typing import Literal +from typing import Optional class DDSketch: def __init__(self): ... diff --git a/ddtrace/internal/openfeature/_provider.py b/ddtrace/internal/openfeature/_provider.py index 157985af930..5a2a9265e6f 100644 --- a/ddtrace/internal/openfeature/_provider.py +++ b/ddtrace/internal/openfeature/_provider.py @@ -4,6 +4,7 @@ This module handles Feature Flag configuration rules from Remote Configuration and forwards the raw bytes to the native FFE processor. """ + from importlib.metadata import version import typing diff --git a/ddtrace/internal/openfeature/_remoteconfiguration.py b/ddtrace/internal/openfeature/_remoteconfiguration.py index 152b789945a..d06df14ba92 100644 --- a/ddtrace/internal/openfeature/_remoteconfiguration.py +++ b/ddtrace/internal/openfeature/_remoteconfiguration.py @@ -4,6 +4,7 @@ This product receives feature flag configuration rules from Remote Configuration and processes them through the native FFE processor. """ + import enum import os import typing as t diff --git a/ddtrace/internal/opentelemetry/logs.py b/ddtrace/internal/opentelemetry/logs.py index a3175abeaaa..81fdc9a38bf 100644 --- a/ddtrace/internal/opentelemetry/logs.py +++ b/ddtrace/internal/opentelemetry/logs.py @@ -142,7 +142,7 @@ def _import_exporter(protocol): from opentelemetry.exporter.otlp.proto.http.version import __version__ as exporter_version else: log.warning( - "OpenTelemetry Logs exporter protocol '%s' is not supported. " "Use 'grpc' or 'http/protobuf'.", + "OpenTelemetry Logs exporter protocol '%s' is not supported. Use 'grpc' or 'http/protobuf'.", protocol, ) return None diff --git a/ddtrace/internal/opentelemetry/metrics.py b/ddtrace/internal/opentelemetry/metrics.py index db59d13ca91..dc90258a821 100644 --- a/ddtrace/internal/opentelemetry/metrics.py +++ b/ddtrace/internal/opentelemetry/metrics.py @@ -150,7 +150,7 @@ def _import_exporter(protocol): from opentelemetry.exporter.otlp.proto.http.version import __version__ as exporter_version else: log.warning( - "OpenTelemetry Metrics exporter protocol '%s' is not supported. " "Use 'grpc' or 'http/protobuf'.", + "OpenTelemetry Metrics exporter protocol '%s' is not supported. Use 'grpc' or 'http/protobuf'.", protocol, ) return None @@ -187,9 +187,9 @@ def _initialize_metrics(exporter_class, protocol, resource): # Ensure metrics exporter is configured to send payloads to a Datadog Agent. if "OTEL_EXPORTER_OTLP_ENDPOINT" not in os.environ and "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT" not in os.environ: os.environ["OTEL_EXPORTER_OTLP_METRICS_ENDPOINT"] = otel_config.exporter.METRICS_ENDPOINT - os.environ[ - "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE" - ] = otel_config.exporter.METRICS_TEMPORALITY_PREFERENCE + os.environ["OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE"] = ( + otel_config.exporter.METRICS_TEMPORALITY_PREFERENCE + ) os.environ["OTEL_METRIC_EXPORT_INTERVAL"] = str(otel_config.exporter.METRICS_METRIC_READER_EXPORT_INTERVAL) os.environ["OTEL_METRIC_EXPORT_TIMEOUT"] = str(otel_config.exporter.METRICS_METRIC_READER_EXPORT_TIMEOUT) _init_metrics({protocol: exporter_class}, resource=resource) diff --git a/ddtrace/internal/packages.py b/ddtrace/internal/packages.py index d402e4d962e..48ef62b2426 100644 --- a/ddtrace/internal/packages.py +++ b/ddtrace/internal/packages.py @@ -358,8 +358,7 @@ def _get_toplevel_name(name) -> str: """ return _topmost(name) or ( # python/typeshed#10328 - inspect.getmodulename(name) - or str(name) + inspect.getmodulename(name) or str(name) ) diff --git a/ddtrace/internal/products.py b/ddtrace/internal/products.py index e9992410cba..2d5f5734c5c 100644 --- a/ddtrace/internal/products.py +++ b/ddtrace/internal/products.py @@ -35,20 +35,15 @@ def get_product_entry_points() -> t.List[t.Any]: class Product(Protocol): requires: t.List[str] - def post_preload(self) -> None: - ... + def post_preload(self) -> None: ... - def start(self) -> None: - ... + def start(self) -> None: ... - def restart(self, join: bool = False) -> None: - ... + def restart(self, join: bool = False) -> None: ... - def stop(self, join: bool = False) -> None: - ... + def stop(self, join: bool = False) -> None: ... - def at_exit(self, join: bool = False) -> None: - ... + def at_exit(self, join: bool = False) -> None: ... class ProductManager: diff --git a/ddtrace/internal/settings/endpoint_config.py b/ddtrace/internal/settings/endpoint_config.py index bd1115848de..57e51a03459 100644 --- a/ddtrace/internal/settings/endpoint_config.py +++ b/ddtrace/internal/settings/endpoint_config.py @@ -3,6 +3,7 @@ The configuration endpoint is a URL that returns a JSON object with the configuration for the products. It takes precedence over environment variables and configuration files. """ + import os from ddtrace.constants import _CONFIG_ENDPOINT_ENV diff --git a/ddtrace/internal/test_visibility/_itr_mixins.py b/ddtrace/internal/test_visibility/_itr_mixins.py index 5d2f7756a49..a99c7a5503a 100644 --- a/ddtrace/internal/test_visibility/_itr_mixins.py +++ b/ddtrace/internal/test_visibility/_itr_mixins.py @@ -93,7 +93,7 @@ def add_coverage_data(item_id, coverage_data) -> None: @staticmethod @_catch_and_log_exceptions def get_coverage_data( - item_id: t.Union[ext_api.TestSuiteId, ext_api.TestId] + item_id: t.Union[ext_api.TestSuiteId, ext_api.TestId], ) -> t.Optional[t.Dict[Path, CoverageLines]]: log.debug("Getting coverage data for item %s", item_id) diff --git a/ddtrace/internal/test_visibility/coverage_lines.py b/ddtrace/internal/test_visibility/coverage_lines.py index 7a200b36299..2a79a9b1aee 100644 --- a/ddtrace/internal/test_visibility/coverage_lines.py +++ b/ddtrace/internal/test_visibility/coverage_lines.py @@ -1,6 +1,7 @@ """ NOTE: BETA - this API is currently in development and is subject to change. """ + import typing as t diff --git a/ddtrace/llmobs/_evaluators/ragas/context_precision.py b/ddtrace/llmobs/_evaluators/ragas/context_precision.py index 13ccb1d593a..f5ec8bc4c33 100644 --- a/ddtrace/llmobs/_evaluators/ragas/context_precision.py +++ b/ddtrace/llmobs/_evaluators/ragas/context_precision.py @@ -90,8 +90,7 @@ def evaluate(self, span_event: dict) -> Tuple[Union[float, str], Optional[dict]] ctx_precision_inputs = self._extract_evaluation_inputs_from_span(span_event) if ctx_precision_inputs is None: logger.debug( - "Failed to extract evaluation inputs from " - "span sampled for `ragas_context_precision` evaluation" + "Failed to extract evaluation inputs from span sampled for `ragas_context_precision` evaluation" ) return "fail_extract_context_precision_inputs", evaluation_metadata diff --git a/ddtrace/llmobs/_experiment.py b/ddtrace/llmobs/_experiment.py index 5e9795ff446..3ea2bb3ec00 100644 --- a/ddtrace/llmobs/_experiment.py +++ b/ddtrace/llmobs/_experiment.py @@ -269,12 +269,10 @@ def _estimate_delta_size(self) -> int: return size @overload - def __getitem__(self, index: int) -> DatasetRecord: - ... + def __getitem__(self, index: int) -> DatasetRecord: ... @overload - def __getitem__(self, index: slice) -> List[DatasetRecord]: - ... + def __getitem__(self, index: slice) -> List[DatasetRecord]: ... def __getitem__(self, index: Union[int, slice]) -> Union[DatasetRecord, List[DatasetRecord]]: return self._records.__getitem__(index) diff --git a/ddtrace/llmobs/_integrations/base_stream_handler.py b/ddtrace/llmobs/_integrations/base_stream_handler.py index 96208234c32..d3d031a1df0 100644 --- a/ddtrace/llmobs/_integrations/base_stream_handler.py +++ b/ddtrace/llmobs/_integrations/base_stream_handler.py @@ -3,6 +3,7 @@ implement a StreamHandler and / or AsyncStreamHandler subclass to be passed into the make_traced_stream factory function along with the stream to wrap. """ + from abc import ABC from abc import abstractmethod import sys diff --git a/ddtrace/llmobs/_integrations/bedrock.py b/ddtrace/llmobs/_integrations/bedrock.py index 592fb31145b..0e7aca6ade4 100644 --- a/ddtrace/llmobs/_integrations/bedrock.py +++ b/ddtrace/llmobs/_integrations/bedrock.py @@ -238,13 +238,11 @@ def _extract_output_message_for_converse(response: Dict[str, Any]): return get_messages_from_converse_content(role, content) @staticmethod - def _converse_output_stream_processor() -> ( - Generator[ - None, - Dict[str, Any], - Tuple[List[Message], Dict[str, str], Dict[str, int]], - ] - ): + def _converse_output_stream_processor() -> Generator[ + None, + Dict[str, Any], + Tuple[List[Message], Dict[str, str], Dict[str, int]], + ]: """ Listens for output chunks from a converse streamed response and builds a list of output messages, usage metrics, and metadata. diff --git a/ddtrace/llmobs/_integrations/langgraph.py b/ddtrace/llmobs/_integrations/langgraph.py index 97c7b3a0a77..230a4a31f70 100644 --- a/ddtrace/llmobs/_integrations/langgraph.py +++ b/ddtrace/llmobs/_integrations/langgraph.py @@ -501,7 +501,7 @@ def _find_pregel_push_index(task, pregel_pushes: List[Tuple[str, str]]) -> int: def _map_channel_writes_to_finished_tasks_ids( - finished_tasks: Dict[str, Any] + finished_tasks: Dict[str, Any], ) -> Dict[str, List[Union[str, Tuple[str, str]]]]: """ Maps channel writes for finished tasks to the list of finished tasks ids that wrote to that channel. diff --git a/ddtrace/profiling/auto.py b/ddtrace/profiling/auto.py index 98016081be7..c9da54cdaee 100644 --- a/ddtrace/profiling/auto.py +++ b/ddtrace/profiling/auto.py @@ -1,4 +1,5 @@ """Automatically starts a collector when imported.""" + from ddtrace.internal.logger import get_logger from ddtrace.profiling.bootstrap import sitecustomize # noqa:F401 diff --git a/ddtrace/profiling/collector/_lock.py b/ddtrace/profiling/collector/_lock.py index 998908e4673..30543d1ceeb 100644 --- a/ddtrace/profiling/collector/_lock.py +++ b/ddtrace/profiling/collector/_lock.py @@ -276,12 +276,10 @@ def __init__( self._original_lock: Any = None @abc.abstractmethod - def _get_patch_target(self) -> Callable[..., Any]: - ... + def _get_patch_target(self) -> Callable[..., Any]: ... @abc.abstractmethod - def _set_patch_target(self, value: Any) -> None: - ... + def _set_patch_target(self, value: Any) -> None: ... def _start_service(self) -> None: """Start collecting lock usage.""" diff --git a/ddtrace/profiling/profiler.py b/ddtrace/profiling/profiler.py index 4fe470f54d9..d8695aa2ae6 100644 --- a/ddtrace/profiling/profiler.py +++ b/ddtrace/profiling/profiler.py @@ -258,9 +258,7 @@ def start_collector(collector_class: Type) -> None: self._build_default_exporters() - scheduler_class = ( - scheduler.ServerlessScheduler if self._lambda_function_name else scheduler.Scheduler - ) # type: (Type[Union[scheduler.Scheduler, scheduler.ServerlessScheduler]]) + scheduler_class = scheduler.ServerlessScheduler if self._lambda_function_name else scheduler.Scheduler # type: (Type[Union[scheduler.Scheduler, scheduler.ServerlessScheduler]]) self._scheduler = scheduler_class( before_flush=self._collectors_snapshot, diff --git a/docs/contributing.rst b/docs/contributing.rst index 143b6e082ae..106ede49ef9 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -35,7 +35,7 @@ suite passes. Within a few business days, one of the maintainers will respond with a code review. The review will primarily focus on idiomatic Python usage, efficiency, testing, and adherence to the versioning policy. Correctness and code style are automatically checked in continuous integration, with style linting managed by -various tools including Flake8, Black, and MyPy. This means that code reviews don't need to worry about style +various tools including Flake8, Ruff, and MyPy. This means that code reviews don't need to worry about style and can focus on substance. Pull Request Requirements diff --git a/hatch.toml b/hatch.toml index 3a7815ce8b8..5c2aea3d94d 100644 --- a/hatch.toml +++ b/hatch.toml @@ -2,7 +2,6 @@ detached = true python = "3.10" dependencies = [ - "black==23.10.1", "click==8.1.7", "cython-lint==0.15.0", "codespell==2.4.1", @@ -26,8 +25,8 @@ dependencies = [ ] [envs.lint.scripts] -black_check = [ - "black --check {args:.}", +format_check = [ + "ruff format --check {args:.}", ] cmakeformat_check = [ "bash scripts/cmake-format.sh" @@ -36,14 +35,14 @@ cformat_check = [ "bash scripts/cformat.sh" ] style = [ - "black_check", + "format_check", "ruff check {args:.}", "cython-lint {args:.}", "cformat_check", "cmakeformat_check", ] fmt = [ - "black {args:.}", + "ruff format {args:.}", "ruff check --fix {args:.}", "style", ] diff --git a/hooks/scripts/run-black.sh b/hooks/scripts/run-python-format.sh similarity index 81% rename from hooks/scripts/run-black.sh rename to hooks/scripts/run-python-format.sh index 0311a036abf..206a1b88731 100755 --- a/hooks/scripts/run-black.sh +++ b/hooks/scripts/run-python-format.sh @@ -1,7 +1,8 @@ #!/bin/sh + staged_files=$(git diff --staged --name-only HEAD --diff-filter=ACMR | grep -E '\.py$') if [ -n "$staged_files" ]; then - hatch -v run lint:black_check $staged_files + hatch -v run lint:format_check $staged_files else echo 'hatch style check skipped: No Python files were found in `git diff --staged`' fi diff --git a/pyproject.toml b/pyproject.toml index 4f6f85edc87..0d96d70749f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -100,46 +100,6 @@ exclude = ''' ) ''' -[tool.black] -line-length = 120 -target_version = ['py39', 'py310', 'py311', 'py312'] -include = '''\.py[ix]?$''' -exclude = ''' -( - \.worktrees/ - | .venv* - | \.sg - | \.riot/ - | ddtrace/appsec/_ddwaf.pyx$ - | ddtrace/internal/_encoding.pyx$ - | ddtrace/internal/_rand.pyx$ - | ddtrace/internal/_tagset.pyx$ - | ddtrace/internal/telemetry/metrics_namespaces.pyx$ - | ddtrace/profiling/collector/_traceback.pyx$ - | ddtrace/profiling/collector/_task.pyx$ - | ddtrace/profiling/_threading.pyx$ - | ddtrace/profiling/exporter/pprof.pyx$ - | ddtrace/internal/datadog/profiling/ddup/_ddup.pyx$ - | ddtrace/vendor/ - | ddtrace/appsec/_iast/_taint_tracking/_vendor/ - | ddtrace/appsec/_iast/_taint_tracking/cmake-build-debug/ - | ddtrace/_version.py - | \.eggs - | \.git - | \.hg - | \.mypy_cache - | \.nox - | \.tox - | \.venv - | _build/ - | buck-out/ - | build/ - | dist/ - | tests/lib-injection/dd-lib-python-init-test-protobuf-old/addressbook_pb2.py$ - | tests/profiling/collector/pprof_.*_pb2.py$ -) -''' - [tool.pyright] exclude = [ "**/__pycache__", @@ -172,6 +132,7 @@ exclude_dirs = [ ] [tool.ruff] +# This exclude list applies to both linting and formatting exclude = [ ".riot", ".ddriot", @@ -242,6 +203,16 @@ lint.unfixable =[ "F401", ] + +[tool.ruff.format] +# Formatter-specific settings +# The exclude list from [tool.ruff] is inherited automatically +# Additional formatter options can be added here if needed +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" + [tool.ruff.lint.pydocstyle] convention = "pep257" @@ -251,8 +222,3 @@ lines-after-imports = 2 force-sort-within-sections = true known-first-party = [ "ddtrace" ] relative-imports-order = "furthest-to-closest" - -[tool.ruff.lint.per-file-ignores] -# Exclude typing stubs as vertical line spacing incompatibility with black -# See: https://github.com/astral-sh/ruff/pull/6501 -"*.pyi" = ["I001"] diff --git a/scripts/check_constant_log_message.py b/scripts/check_constant_log_message.py index 5f12a86bd00..300d5c90289 100644 --- a/scripts/check_constant_log_message.py +++ b/scripts/check_constant_log_message.py @@ -108,7 +108,7 @@ def main() -> int: for filepath in python_files: errors = check_file(filepath) for line_no, col_no in errors: - print(f"{filepath}:{line_no}:{col_no}: " "LOG001 first argument to logging call must be a constant string") + print(f"{filepath}:{line_no}:{col_no}: LOG001 first argument to logging call must be a constant string") total_errors += 1 if total_errors > 0: diff --git a/scripts/extract_debug_symbols.py b/scripts/extract_debug_symbols.py index 77cdccbaa65..8c7530ef578 100644 --- a/scripts/extract_debug_symbols.py +++ b/scripts/extract_debug_symbols.py @@ -353,9 +353,10 @@ def update_wheel_with_stripped_dynamic_libraries(wheel_path: str, temp_dir: str) temp_wheel_path = f"{wheel_path}.tmp" # Create new wheel with stripped dynamic library files - with zipfile.ZipFile(wheel_path, "r") as source_wheel, zipfile.ZipFile( - temp_wheel_path, "w", zipfile.ZIP_DEFLATED - ) as temp_wheel: + with ( + zipfile.ZipFile(wheel_path, "r") as source_wheel, + zipfile.ZipFile(temp_wheel_path, "w", zipfile.ZIP_DEFLATED) as temp_wheel, + ): for file_info in source_wheel.infolist(): if file_info.filename.endswith(".so") or file_info.filename.endswith(".dylib"): # Replace with stripped version, preserving directory structure diff --git a/scripts/freshvenvs.py b/scripts/freshvenvs.py index 9e5e749df18..f3bf30af528 100644 --- a/scripts/freshvenvs.py +++ b/scripts/freshvenvs.py @@ -103,6 +103,7 @@ def _get_updatable_packages_implementing(contrib_modules: typing.Set[str]) -> ty all_venvs = _propagate_venv_names_to_child_venvs(all_venvs) packages_setting_latest = set() + def recurse_venvs(venvs: typing.List[riotfile.Venv]): for venv in venvs: # split venv name by ":" since some venvs are named after the integration:subintegration @@ -130,6 +131,7 @@ def _propagate_venv_names_to_child_venvs(all_venvs: typing.List[riotfile.Venv]) venvs are nested within each other, we will get a consistent integration name for each venv / child venv. Also lowercase the package names to ensure consistent lookups. """ + def _lower_pkg_names(venv: riotfile.Venv): venv.pkgs = {k.lower(): v for k, v in venv.pkgs.items()} @@ -199,7 +201,7 @@ def _get_riot_hash_to_venv_name() -> typing.Dict[str, str]: hash_to_name = {} for line in output.splitlines(): - match = re.match(r'\[#\d+\]\s+([a-f0-9]+)\s+(\S+)', line) + match = re.match(r"\[#\d+\]\s+([a-f0-9]+)\s+(\S+)", line) if match: venv_hash, venv_name = match.groups() hash_to_name[venv_hash] = venv_name.lower() @@ -228,11 +230,12 @@ def get_integration_and_dependencies(venv_name: str) -> typing.Tuple[str, typing return integration, dependencies else: return None, [] + integration, dependencies = get_integration_and_dependencies(venv_name) for line in lockfile_content: package, _, versions = line.partition("==") - package = package.split("[")[0] # strip optional package installs like flask[async] + package = package.split("[")[0] # strip optional package installs like flask[async] if package in dependencies or package == integration: lock_packages.append((package, versions)) return lock_packages diff --git a/scripts/update-system-tests-version.py b/scripts/update-system-tests-version.py index ca50d2e0d71..44cbf322734 100755 --- a/scripts/update-system-tests-version.py +++ b/scripts/update-system-tests-version.py @@ -61,7 +61,7 @@ def update_system_tests_version(latest_version: str): if lines[i].strip().startswith("SYSTEM_TESTS_REF:"): # Replace the entire line with the new commit hash indent = len(lines[i]) - len(lines[i].lstrip()) - lines[i] = f"{' ' * indent}SYSTEM_TESTS_REF: \"{latest_version}\"" + lines[i] = f'{" " * indent}SYSTEM_TESTS_REF: "{latest_version}"' break if lines and lines[-1]: diff --git a/scripts/zip_filter.py b/scripts/zip_filter.py index 0c9f8568460..5f9d9730d8e 100644 --- a/scripts/zip_filter.py +++ b/scripts/zip_filter.py @@ -41,9 +41,10 @@ def remove_from_zip(zip_filename, patterns): break # Second pass: create new zip without removed files and with updated RECORD - with zipfile.ZipFile(zip_filename, "r") as source_zip, zipfile.ZipFile( - temp_zip_filename, "w", zipfile.ZIP_DEFLATED - ) as temp_zip: + with ( + zipfile.ZipFile(zip_filename, "r") as source_zip, + zipfile.ZipFile(temp_zip_filename, "w", zipfile.ZIP_DEFLATED) as temp_zip, + ): # DEV: Use ZipInfo objects to ensure original file attributes are preserved for file in source_zip.infolist(): if any(fnmatch.fnmatch(file.filename, pattern) for pattern in patterns): diff --git a/tests/appsec/app.py b/tests/appsec/app.py index c5ff1a81e73..dd1bb3b8275 100644 --- a/tests/appsec/app.py +++ b/tests/appsec/app.py @@ -1,4 +1,5 @@ """This Flask application is imported on tests.appsec.appsec_utils.gunicorn_flask_server""" + import os diff --git a/tests/appsec/appsec/test_appsec_trace_utils.py b/tests/appsec/appsec/test_appsec_trace_utils.py index 31f61db842b..f1b1bb31b5a 100644 --- a/tests/appsec/appsec/test_appsec_trace_utils.py +++ b/tests/appsec/appsec/test_appsec_trace_utils.py @@ -145,9 +145,10 @@ def test_track_user_login_event_success_auto_mode_extended(self): assert entry_span.get_tag(APPSEC.AUTO_LOGIN_EVENTS_SUCCESS_MODE) == str(LOGIN_EVENTS_MODE.IDENT) def test_track_user_login_event_success_with_metadata(self): - with mock_patch.object( - ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock() - ) as telemetry_mock, asm_context(tracer=self.tracer, span_name="test_success2", config=config_asm) as span: + with ( + mock_patch.object(ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock()) as telemetry_mock, + asm_context(tracer=self.tracer, span_name="test_success2", config=config_asm) as span, + ): track_user_login_success_event(self.tracer, "1234", metadata={"foo": "bar"}) entry_span = span._service_entry_span assert entry_span.get_tag("appsec.events.users.login.success.track") == "true" @@ -210,9 +211,10 @@ def test_track_user_login_event_failure_user_exists(self): assert not entry_span.get_tag(user.SESSION_ID) def test_track_user_login_event_failure_user_doesnt_exists(self): - with mock_patch.object( - ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock() - ) as telemetry_mock, self.trace("test_failure") as span: + with ( + mock_patch.object(ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock()) as telemetry_mock, + self.trace("test_failure") as span, + ): track_user_login_failure_event( self.tracer, "john", @@ -228,9 +230,10 @@ def test_track_user_login_event_failure_user_doesnt_exists(self): ] def test_track_user_signup_event_exists(self): - with mock_patch.object( - ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock() - ) as telemetry_mock, self.trace("test_signup_exists") as span: + with ( + mock_patch.object(ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock()) as telemetry_mock, + self.trace("test_signup_exists") as span, + ): track_user_signup_event(self.tracer, "john", True) entry_span = span._service_entry_span assert entry_span.get_tag(APPSEC.USER_SIGNUP_EVENT) == "true" @@ -239,9 +242,10 @@ def test_track_user_signup_event_exists(self): assert metrics == [("count", "appsec", "sdk.event", 1, (("event_type", "signup"), ("sdk_version", "v1")))] def test_custom_event(self): - with mock_patch.object( - ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock() - ) as telemetry_mock, self.trace("test_custom") as span: + with ( + mock_patch.object(ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock()) as telemetry_mock, + self.trace("test_custom") as span, + ): event = "some_event" track_custom_event(self.tracer, event, {"foo": "bar"}) entry_span = span._service_entry_span diff --git a/tests/appsec/appsec/test_processor.py b/tests/appsec/appsec/test_processor.py index 1c9fa71fff7..27e830b0294 100644 --- a/tests/appsec/appsec/test_processor.py +++ b/tests/appsec/appsec/test_processor.py @@ -591,8 +591,9 @@ def test_ddwaf_run_contained_typeerror(tracer, caplog): config = rules.Config() config.http_tag_query_string = True - with caplog.at_level(logging.DEBUG), mock.patch( - "ddtrace.appsec._ddwaf.waf.ddwaf_run", side_effect=TypeError("expected c_long instead of int") + with ( + caplog.at_level(logging.DEBUG), + mock.patch("ddtrace.appsec._ddwaf.waf.ddwaf_run", side_effect=TypeError("expected c_long instead of int")), ): with asm_context(tracer=tracer, config=config_asm) as span: set_http_meta( @@ -627,8 +628,9 @@ def test_ddwaf_run_contained_oserror(tracer, caplog): config = rules.Config() config.http_tag_query_string = True - with caplog.at_level(logging.DEBUG), mock.patch( - "ddtrace.appsec._ddwaf.waf.ddwaf_run", side_effect=OSError("ddwaf run failed") + with ( + caplog.at_level(logging.DEBUG), + mock.patch("ddtrace.appsec._ddwaf.waf.ddwaf_run", side_effect=OSError("ddwaf run failed")), ): with asm_context(tracer=tracer, config=config_asm) as span: set_http_meta( diff --git a/tests/appsec/appsec/test_remoteconfiguration.py b/tests/appsec/appsec/test_remoteconfiguration.py index e134b7d0118..8a4ee112c3e 100644 --- a/tests/appsec/appsec/test_remoteconfiguration.py +++ b/tests/appsec/appsec/test_remoteconfiguration.py @@ -83,8 +83,9 @@ def test_rc_activate_is_active_and_get_processor_tags(tracer, remote_config_work ], ) def test_rc_activation_states_on(tracer, appsec_enabled, rc_value, remote_config_worker): - with override_env({APPSEC.ENV: appsec_enabled} if appsec_enabled else {}), override_global_config( - dict(_asm_enabled=asbool(appsec_enabled), _remote_config_enabled=True) + with ( + override_env({APPSEC.ENV: appsec_enabled} if appsec_enabled else {}), + override_global_config(dict(_asm_enabled=asbool(appsec_enabled), _remote_config_enabled=True)), ): if appsec_enabled: tracer.configure(appsec_enabled=asbool(appsec_enabled)) @@ -251,13 +252,16 @@ def test_rc_activation_check_asm_features_product_disables_rest_of_products( @pytest.mark.parametrize("auto_user", [True, False]) def test_rc_activation_with_auto_user_appsec_fixed(tracer, remote_config_worker, auto_user): - with override_env({APPSEC.ENV: "true"}), override_global_config( - dict( - _remote_config_enabled=True, - _asm_enabled=True, - _auto_user_instrumentation_enabled=auto_user, - api_version="v0.4", - ) + with ( + override_env({APPSEC.ENV: "true"}), + override_global_config( + dict( + _remote_config_enabled=True, + _asm_enabled=True, + _auto_user_instrumentation_enabled=auto_user, + api_version="v0.4", + ) + ), ): tracer.configure(appsec_enabled=True) enable_appsec_rc(tracer) diff --git a/tests/appsec/appsec/test_telemetry.py b/tests/appsec/appsec/test_telemetry.py index a07a0b8e06d..fcc2a601797 100644 --- a/tests/appsec/appsec/test_telemetry.py +++ b/tests/appsec/appsec/test_telemetry.py @@ -40,9 +40,9 @@ def _assert_generate_metrics(metrics_result, is_rule_triggered=False, is_blocked for m in metrics_result[TELEMETRY_EVENT_TYPE.METRICS][TELEMETRY_NAMESPACE.APPSEC.value] if m["metric"] != "enabled" ] - assert ( - len(generate_metrics) == 3 + is_updated - ), f"Expected {3 + is_updated} generate_metrics, got {[m['metric'] for m in generate_metrics]}" + assert len(generate_metrics) == 3 + is_updated, ( + f"Expected {3 + is_updated} generate_metrics, got {[m['metric'] for m in generate_metrics]}" + ) for metric in generate_metrics: metric_name = metric["metric"] if metric_name == "waf.requests": @@ -303,8 +303,11 @@ def test_appsec_enabled_metric( telemetry_writer._report_configurations() # Start the test - with override_env(environment), override_global_config( - dict(_asm_enabled=appsec_enabled, _remote_config_enabled=rc_enabled, _lib_was_injected=ssi_enabled) + with ( + override_env(environment), + override_global_config( + dict(_asm_enabled=appsec_enabled, _remote_config_enabled=rc_enabled, _lib_was_injected=ssi_enabled) + ), ): tracer.configure(appsec_enabled=appsec_enabled) if rc_enabled: diff --git a/tests/appsec/contrib_appsec/utils.py b/tests/appsec/contrib_appsec/utils.py index 2c0da84a486..1b6d405d5c5 100644 --- a/tests/appsec/contrib_appsec/utils.py +++ b/tests/appsec/contrib_appsec/utils.py @@ -169,11 +169,14 @@ def test_simple_attack_timeout(self, interface: Interface, entry_span, get_entry import ddtrace.internal.telemetry - with override_global_config(dict(_asm_enabled=True, _waf_timeout=0.001)), mock_patch.object( - ddtrace.internal.telemetry.telemetry_writer, - "_namespace", - MagicMock(), - ) as mocked: + with ( + override_global_config(dict(_asm_enabled=True, _waf_timeout=0.001)), + mock_patch.object( + ddtrace.internal.telemetry.telemetry_writer, + "_namespace", + MagicMock(), + ) as mocked, + ): self.update_tracer(interface) query_params = urlencode({"q": "1"}) url = f"/?{query_params}" @@ -303,11 +306,14 @@ def test_truncation_telemetry(self, interface: Interface, get_entry_span_metric) import ddtrace.internal.telemetry - with override_global_config(dict(_asm_enabled=True)), mock_patch.object( - ddtrace.internal.telemetry.telemetry_writer, - "_namespace", - MagicMock(), - ) as mocked: + with ( + override_global_config(dict(_asm_enabled=True)), + mock_patch.object( + ddtrace.internal.telemetry.telemetry_writer, + "_namespace", + MagicMock(), + ) as mocked, + ): self.update_tracer(interface) body: Dict[str, Any] = {"val": "x" * 5000} body.update({f"a_{i}": i for i in range(517)}) @@ -432,8 +438,9 @@ def test_request_body_bad(self, caplog, interface: Interface, entry_span, get_en # Ensure no crash when body is not parsable import logging - with caplog.at_level(logging.DEBUG), override_global_config( - dict(_asm_enabled=True, _asm_static_rule_file=rules.RULES_GOOD_PATH) + with ( + caplog.at_level(logging.DEBUG), + override_global_config(dict(_asm_enabled=True, _asm_static_rule_file=rules.RULES_GOOD_PATH)), ): self.update_tracer(interface) payload = '{"attack": "bad_payload",}&=' @@ -590,17 +597,17 @@ def test_request_ipmonitor( code = 403 if not bypassed and not monitored and asm_enabled and blocked else 200 rule = "tst-421-001" if blocked else "tst-421-002" assert self.status(response) == code, f"status={self.status(response)}, expected={code}" - assert get_entry_span_tag(http.STATUS_CODE) == str( - code - ), f"status_code={get_entry_span_tag(http.STATUS_CODE)}, expected={code}" + assert get_entry_span_tag(http.STATUS_CODE) == str(code), ( + f"status_code={get_entry_span_tag(http.STATUS_CODE)}, expected={code}" + ) if asm_enabled and not bypassed: assert get_entry_span_tag(http.URL) == f"http://localhost:8000/{query}" - assert ( - get_entry_span_tag(http.METHOD) == "GET" - ), f"method={get_entry_span_tag(http.METHOD)}, expected=GET" - assert ( - get_entry_span_tag("actor.ip") == headers["X-Real-Ip"] - ), f"actor.ip={get_entry_span_tag('actor.ip')}, expected={headers['X-Real-Ip']}" + assert get_entry_span_tag(http.METHOD) == "GET", ( + f"method={get_entry_span_tag(http.METHOD)}, expected=GET" + ) + assert get_entry_span_tag("actor.ip") == headers["X-Real-Ip"], ( + f"actor.ip={get_entry_span_tag('actor.ip')}, expected={headers['X-Real-Ip']}" + ) if monitored: self.check_rules_triggered(["blk-001-010", rule], entry_span) else: @@ -644,9 +651,9 @@ def test_request_suspicious_attacker_blocking( if event and ip == self.SUSPICIOUS_IP: status = 402 assert self.status(response) == status, f"status={self.status(response)}, expected={status}" - assert get_entry_span_tag(http.STATUS_CODE) == str( - status - ), f"status_code={self.status(response)}, expected={status}" + assert get_entry_span_tag(http.STATUS_CODE) == str(status), ( + f"status_code={self.status(response)}, expected={status}" + ) if event: self.check_single_rule_triggered( "ua0-600-56x" if agent == "dd-test-scanner-log-block" else "ua0-600-12x", entry_span @@ -1121,17 +1128,20 @@ def test_request_suspicious_request_block_custom_actions( http_cache._JSON_BLOCKED_TEMPLATE_CACHE = None try: uri = f"/?param={query}" - with override_global_config( - dict( - _asm_enabled=asm_enabled, - _use_metastruct_for_triggers=metastruct, - _asm_static_rule_file=rules.RULES_SRBCA, - ) - ), override_env( - dict( - DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON=rules.RESPONSE_CUSTOM_JSON, - DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML=rules.RESPONSE_CUSTOM_HTML, - ) + with ( + override_global_config( + dict( + _asm_enabled=asm_enabled, + _use_metastruct_for_triggers=metastruct, + _asm_static_rule_file=rules.RULES_SRBCA, + ) + ), + override_env( + dict( + DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON=rules.RESPONSE_CUSTOM_JSON, + DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML=rules.RESPONSE_CUSTOM_HTML, + ) + ), ): self.update_tracer(interface) response = interface.client.get(uri, headers=headers) @@ -1281,13 +1291,16 @@ def test_api_security_schemas( from ddtrace.ext import http import ddtrace.internal.telemetry - with override_global_config( - dict(_asm_enabled=True, _api_security_enabled=apisec_enabled, _apm_tracing_enabled=apm_tracing_enabled) - ), mock_patch.object( - ddtrace.internal.telemetry.telemetry_writer, - "_namespace", - MagicMock(), - ) as mocked: + with ( + override_global_config( + dict(_asm_enabled=True, _api_security_enabled=apisec_enabled, _apm_tracing_enabled=apm_tracing_enabled) + ), + mock_patch.object( + ddtrace.internal.telemetry.telemetry_writer, + "_namespace", + MagicMock(), + ) as mocked, + ): self.update_tracer(interface) response = interface.client.post( "/asm/324/huj/?x=1&y=2", @@ -1331,12 +1344,12 @@ def test_api_security_schemas( if not apm_tracing_enabled: span_sampling_priority = entry_span()._span.context.sampling_priority sampling_decision = get_entry_span_tag(constants.SAMPLING_DECISION_TRACE_TAG_KEY) - assert ( - span_sampling_priority == constants.USER_KEEP - ), f"Expected 2 (USER_KEEP), got {span_sampling_priority}" - assert ( - sampling_decision == f"-{constants.SamplingMechanism.APPSEC}" - ), f"Expected '-5' (APPSEC), got {sampling_decision}" + assert span_sampling_priority == constants.USER_KEEP, ( + f"Expected 2 (USER_KEEP), got {span_sampling_priority}" + ) + assert sampling_decision == f"-{constants.SamplingMechanism.APPSEC}", ( + f"Expected '-5' (APPSEC), got {sampling_decision}" + ) else: assert value is None, name @@ -1664,9 +1677,12 @@ def validate_top_function(trace): asm_config._iast_enabled and top_function.endswith("ast_function") ) - with override_global_config( - dict(_asm_enabled=asm_enabled, _ep_enabled=ep_enabled, _asm_static_rule_file=rule_file) - ), mock_patch.object(ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock()) as mocked: + with ( + override_global_config( + dict(_asm_enabled=asm_enabled, _ep_enabled=ep_enabled, _asm_static_rule_file=rule_file) + ), + mock_patch.object(ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock()) as mocked, + ): self.update_tracer(interface) assert asm_config._asm_enabled == asm_enabled response = interface.client.get(f"/rasp/{endpoint}/?{parameters}") @@ -1683,9 +1699,9 @@ def validate_top_function(trace): assert self.check_for_stack_trace(entry_span) for trace in self.check_for_stack_trace(entry_span): assert "frames" in trace - assert validate_top_function( - trace - ), f"unknown top function {trace['frames'][0]} {[t['function'] for t in trace['frames'][:4]]}" + assert validate_top_function(trace), ( + f"unknown top function {trace['frames'][0]} {[t['function'] for t in trace['frames'][:4]]}" + ) # assert mocked.call_args_list == [] expected_rule_type = "command_injection" if endpoint == "shell_injection" else endpoint expected_variant = ( @@ -1862,14 +1878,17 @@ def test_auto_user_events_sdk_v2( if not USER_SDK_V2: raise pytest.skip("SDK v2 not available") - with override_global_config( - dict( - _asm_enabled=asm_enabled, - _auto_user_instrumentation_local_mode=local_mode, - _auto_user_instrumentation_rc_mode=rc_mode, - _auto_user_instrumentation_enabled=auto_events_enabled, - ) - ), mock_patch.object(ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock()) as telemetry_mock: + with ( + override_global_config( + dict( + _asm_enabled=asm_enabled, + _auto_user_instrumentation_local_mode=local_mode, + _auto_user_instrumentation_rc_mode=rc_mode, + _auto_user_instrumentation_enabled=auto_events_enabled, + ) + ), + mock_patch.object(ddtrace.internal.telemetry.telemetry_writer, "_namespace", MagicMock()) as telemetry_mock, + ): self.update_tracer(interface) metadata = json.dumps( { @@ -1943,9 +1962,9 @@ def test_auto_user_events_sdk_v2( assert get_entry_span_tag(f"appsec.events.users.login.{success}.a") == "a", entry_span()._meta assert get_entry_span_tag(f"appsec.events.users.login.{success}.load_a.b") == "true", entry_span()._meta assert get_entry_span_tag(f"appsec.events.users.login.{success}.load_a.load_b.c") == "3", entry_span()._meta - assert ( - get_entry_span_tag(f"appsec.events.users.login.{success}.load_a.load_b.load_c.load_d.e") == "1.32" - ), entry_span()._meta + assert get_entry_span_tag(f"appsec.events.users.login.{success}.load_a.load_b.load_c.load_d.e") == "1.32", ( + entry_span()._meta + ) assert ( get_entry_span_tag(f"appsec.events.users.login.{success}.load_a.load_b.load_c.load_d.load_e.f") is None ), entry_span()._meta diff --git a/tests/appsec/iast/aspects/test_common_aspects.py b/tests/appsec/iast/aspects/test_common_aspects.py index d626ee7862f..02fd0d03695 100644 --- a/tests/appsec/iast/aspects/test_common_aspects.py +++ b/tests/appsec/iast/aspects/test_common_aspects.py @@ -2,6 +2,7 @@ """ Common tests to aspects, like ensuring that they don't break when receiving extra arguments. """ + import os import pytest diff --git a/tests/appsec/iast/aspects/test_common_aspects_generator.py b/tests/appsec/iast/aspects/test_common_aspects_generator.py index a85d608afe4..a1b253a806d 100644 --- a/tests/appsec/iast/aspects/test_common_aspects_generator.py +++ b/tests/appsec/iast/aspects/test_common_aspects_generator.py @@ -2,6 +2,7 @@ """ Common tests to aspects, like ensuring that they don't break when receiving extra arguments. """ + import os import pytest diff --git a/tests/appsec/iast/aspects/test_empty_arg_aspects.py b/tests/appsec/iast/aspects/test_empty_arg_aspects.py index b73c313bbb4..214853e8bd2 100644 --- a/tests/appsec/iast/aspects/test_empty_arg_aspects.py +++ b/tests/appsec/iast/aspects/test_empty_arg_aspects.py @@ -2,6 +2,7 @@ """ Common tests to aspects, ensuring that they don't break when receiving empty arguments. """ + import os import pytest diff --git a/tests/appsec/iast/aspects/test_format_map_aspect_fixtures.py b/tests/appsec/iast/aspects/test_format_map_aspect_fixtures.py index 5865d69c97f..ef08915bb7e 100644 --- a/tests/appsec/iast/aspects/test_format_map_aspect_fixtures.py +++ b/tests/appsec/iast/aspects/test_format_map_aspect_fixtures.py @@ -77,7 +77,7 @@ def test_format_map_when_tainted_template_range_no_brackets_and_tainted_param_th taint_escaped_template=":+-template-+: {key}", taint_escaped_mapping={"key": ":+-parameter-+:"}, expected_result="template parameter", - escaped_expected_result=":+-template-+: " ":+-parameter-+:", + escaped_expected_result=":+-template-+: :+-parameter-+:", ) def test_format_map_when_tainted_template_range_with_brackets_and_tainted_param_then_tainted( @@ -87,7 +87,7 @@ def test_format_map_when_tainted_template_range_with_brackets_and_tainted_param_ taint_escaped_template=":+-template {key}-+:", taint_escaped_mapping={"key": ":+-parameter-+:"}, expected_result="template parameter", - escaped_expected_result=":+-template -+:" ":+-parameter-+:", + escaped_expected_result=":+-template -+::+-parameter-+:", ) def test_format_map_when_ranges_overlap_then_give_preference_to_ranges_from_parameter(self): # type: () -> None @@ -105,7 +105,7 @@ def test_format_map_when_tainted_str_emoji_strings_then_tainted_result(self): # taint_escaped_template=":+-template⚠️-+: {key}", taint_escaped_mapping={"key": ":+-parameter⚠️-+:"}, expected_result="template⚠️ parameter⚠️", - escaped_expected_result=":+-template⚠️-+: " ":+-parameter⚠️-+:", + escaped_expected_result=":+-template⚠️-+: :+-parameter⚠️-+:", ) def test_format_map_when_tainted_template_range_no_brackets_and_param_not_str_then_tainted( @@ -132,9 +132,9 @@ def test_format_map_when_texts_tainted_and_contain_escape_sequences_then_result_ self, ): # type: () -> None self._assert_format_map_result( - taint_escaped_template=":+-template ::++--<0>my_code<0>--++::" "-+: {key}", - taint_escaped_mapping={"key": ":+-parameter-+: " "::++--<0>my_code<0>--++::"}, - expected_result="template :+-<0>my_code<0>-+: parameter " ":+-<0>my_code<0>-+:", + taint_escaped_template=":+-template ::++--<0>my_code<0>--++::-+: {key}", + taint_escaped_mapping={"key": ":+-parameter-+: ::++--<0>my_code<0>--++::"}, + expected_result="template :+-<0>my_code<0>-+: parameter :+-<0>my_code<0>-+:", escaped_expected_result=":+-template :+-<0>my_code<0>-+:-+: " ":+-parameter-+: " ":+-<0>my_code<0>-+:", diff --git a/tests/appsec/iast/aspects/test_slice_aspect_fixtures.py b/tests/appsec/iast/aspects/test_slice_aspect_fixtures.py index 956ff716ecf..2c906773cb2 100644 --- a/tests/appsec/iast/aspects/test_slice_aspect_fixtures.py +++ b/tests/appsec/iast/aspects/test_slice_aspect_fixtures.py @@ -110,9 +110,7 @@ def test_string_slice_2(input_str, start_pos, end_pos, step, expected_result, ta def test_string_slice_2_and_two_strings( input_str_not_tainted, input_str_tainted, start_pos, end_pos, step, expected_result ): - result = mod.do_slice_2_and_two_strings( - input_str_not_tainted, input_str_tainted, start_pos + 5, end_pos + 5, step - ) # pylint: disable=no-member + result = mod.do_slice_2_and_two_strings(input_str_not_tainted, input_str_tainted, start_pos + 5, end_pos + 5, step) # pylint: disable=no-member assert result == expected_result tainted_input = taint_pyobject( @@ -121,9 +119,7 @@ def test_string_slice_2_and_two_strings( source_value="foo", source_origin=OriginType.PARAMETER, ) - result = mod.do_slice_2_and_two_strings( - input_str_not_tainted, tainted_input, start_pos + 5, end_pos + 5, step - ) # pylint: disable=no-member + result = mod.do_slice_2_and_two_strings(input_str_not_tainted, tainted_input, start_pos + 5, end_pos + 5, step) # pylint: disable=no-member assert result == expected_result tainted_ranges = get_tainted_ranges(result) assert len(tainted_ranges) == 1 @@ -162,9 +158,7 @@ def test_string_slice_2_and_two_strings( def test_string_slice_2_and_two_strings_two_tainted( input_str_tainted1, input_str_tainted2, start_pos, end_pos, step, expected_result ): - result = mod.do_slice_2_and_two_strings( - input_str_tainted1, input_str_tainted2, start_pos + 5, end_pos + 5, step - ) # pylint: disable=no-member + result = mod.do_slice_2_and_two_strings(input_str_tainted1, input_str_tainted2, start_pos + 5, end_pos + 5, step) # pylint: disable=no-member assert result == expected_result tainted_input1 = taint_pyobject( @@ -181,9 +175,7 @@ def test_string_slice_2_and_two_strings_two_tainted( source_origin=OriginType.PARAMETER, ) - result = mod.do_slice_2_and_two_strings( - tainted_input1, tainted_input2, start_pos + 5, end_pos + 5, step - ) # pylint: disable=no-member + result = mod.do_slice_2_and_two_strings(tainted_input1, tainted_input2, start_pos + 5, end_pos + 5, step) # pylint: disable=no-member assert result == expected_result tainted_ranges = get_tainted_ranges(result) assert len(tainted_ranges) == 1 @@ -201,9 +193,7 @@ def test_string_slice_2_and_two_strings_two_tainted( def test_string_slice_2_and_two_strings_two_tainted_overlap_tained( input_str_tainted1, input_str_tainted2, start_pos, end_pos, step, expected_result ): - result = mod.do_slice_2_and_two_strings( - input_str_tainted1, input_str_tainted2, start_pos, end_pos, step - ) # pylint: disable=no-member + result = mod.do_slice_2_and_two_strings(input_str_tainted1, input_str_tainted2, start_pos, end_pos, step) # pylint: disable=no-member assert result == expected_result tainted_input1 = taint_pyobject( @@ -220,9 +210,7 @@ def test_string_slice_2_and_two_strings_two_tainted_overlap_tained( source_origin=OriginType.PARAMETER, ) - result = mod.do_slice_2_and_two_strings( - tainted_input1, tainted_input2, start_pos, end_pos, step - ) # pylint: disable=no-member + result = mod.do_slice_2_and_two_strings(tainted_input1, tainted_input2, start_pos, end_pos, step) # pylint: disable=no-member assert result == expected_result tainted_ranges = get_tainted_ranges(result) assert len(tainted_ranges) == 2 diff --git a/tests/appsec/iast/conftest.py b/tests/appsec/iast/conftest.py index 900b8d5fbb1..21c423821a1 100644 --- a/tests/appsec/iast/conftest.py +++ b/tests/appsec/iast/conftest.py @@ -49,16 +49,19 @@ class MockSpan: env.update({"DD_IAST_DEDUPLICATION_ENABLED": str(deduplication)}) # env.update({"DD_IAST_MAX_CONCURRENT_REQUESTS": "100"}) - with override_global_config( - dict( - _asm_enabled=asm_enabled, - _iast_enabled=True, - _iast_is_testing=True, - _iast_deduplication_enabled=deduplication, - _iast_max_vulnerabilities_per_requests=vulnerabilities_per_requests, - _iast_request_sampling=request_sampling, - ) - ), override_env(env): + with ( + override_global_config( + dict( + _asm_enabled=asm_enabled, + _iast_enabled=True, + _iast_is_testing=True, + _iast_deduplication_enabled=deduplication, + _iast_max_vulnerabilities_per_requests=vulnerabilities_per_requests, + _iast_request_sampling=request_sampling, + ) + ), + override_env(env), + ): assert debug_context_array_size() == 2 assert debug_context_array_free_slots_number() > 0 span = MockSpan() diff --git a/tests/appsec/iast/fixtures/aspects/str/future_import_class_str.py b/tests/appsec/iast/fixtures/aspects/str/future_import_class_str.py index 7f22fc12fe2..badfffca908 100644 --- a/tests/appsec/iast/fixtures/aspects/str/future_import_class_str.py +++ b/tests/appsec/iast/fixtures/aspects/str/future_import_class_str.py @@ -5,6 +5,7 @@ docstring here """ + from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/tests/appsec/iast/fixtures/aspects/str/future_import_function_str.py b/tests/appsec/iast/fixtures/aspects/str/future_import_function_str.py index f3d0f990160..a1d1f800d48 100644 --- a/tests/appsec/iast/fixtures/aspects/str/future_import_function_str.py +++ b/tests/appsec/iast/fixtures/aspects/str/future_import_function_str.py @@ -6,6 +6,7 @@ docstring here """ + from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/tests/appsec/iast/fixtures/ast/str/future_import_class_str.py b/tests/appsec/iast/fixtures/ast/str/future_import_class_str.py index 7f22fc12fe2..badfffca908 100644 --- a/tests/appsec/iast/fixtures/ast/str/future_import_class_str.py +++ b/tests/appsec/iast/fixtures/ast/str/future_import_class_str.py @@ -5,6 +5,7 @@ docstring here """ + from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/tests/appsec/iast/fixtures/ast/str/future_import_function_str.py b/tests/appsec/iast/fixtures/ast/str/future_import_function_str.py index f3d0f990160..a1d1f800d48 100644 --- a/tests/appsec/iast/fixtures/ast/str/future_import_function_str.py +++ b/tests/appsec/iast/fixtures/ast/str/future_import_function_str.py @@ -6,6 +6,7 @@ docstring here """ + from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/tests/appsec/iast/fixtures/propagation_path.py b/tests/appsec/iast/fixtures/propagation_path.py index 4148521939f..4a9eab63211 100644 --- a/tests/appsec/iast/fixtures/propagation_path.py +++ b/tests/appsec/iast/fixtures/propagation_path.py @@ -2,6 +2,7 @@ CAVEAT: the line number is important to some IAST tests, be careful to modify this file and update the tests if you make some changes """ + import _io import asyncio import os diff --git a/tests/appsec/iast/fixtures/taint_sinks/code_injection.py b/tests/appsec/iast/fixtures/taint_sinks/code_injection.py index 4909ecb8c21..03dc34f415e 100644 --- a/tests/appsec/iast/fixtures/taint_sinks/code_injection.py +++ b/tests/appsec/iast/fixtures/taint_sinks/code_injection.py @@ -2,6 +2,7 @@ CAVEAT: the line number is important to some IAST tests, be careful to modify this file and update the tests if you make some changes """ + from ast import literal_eval diff --git a/tests/appsec/iast/fixtures/taint_sinks/command_injection.py b/tests/appsec/iast/fixtures/taint_sinks/command_injection.py index 59dca198a7c..c48eca39acf 100644 --- a/tests/appsec/iast/fixtures/taint_sinks/command_injection.py +++ b/tests/appsec/iast/fixtures/taint_sinks/command_injection.py @@ -2,6 +2,7 @@ CAVEAT: the line number is important to some IAST tests, be careful to modify this file and update the tests if you make some changes """ + import os import subprocess diff --git a/tests/appsec/iast/fixtures/taint_sinks/path_traversal.py b/tests/appsec/iast/fixtures/taint_sinks/path_traversal.py index 48768f6a6cb..1420b47d0e3 100644 --- a/tests/appsec/iast/fixtures/taint_sinks/path_traversal.py +++ b/tests/appsec/iast/fixtures/taint_sinks/path_traversal.py @@ -2,6 +2,7 @@ CAVEAT: the line number is important to some IAST tests, be careful to modify this file and update the tests if you make some changes """ + import glob import os import pickle diff --git a/tests/appsec/iast/fixtures/taint_sinks/weak_algorithms.py b/tests/appsec/iast/fixtures/taint_sinks/weak_algorithms.py index 696cb7706e0..bff11e39cc2 100644 --- a/tests/appsec/iast/fixtures/taint_sinks/weak_algorithms.py +++ b/tests/appsec/iast/fixtures/taint_sinks/weak_algorithms.py @@ -2,6 +2,7 @@ CAVEAT: the line number is important to some IAST tests, be careful to modify this file and update the tests if you make some changes """ + import os diff --git a/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random.py b/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random.py index b8c180870da..9c42d07dced 100644 --- a/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random.py +++ b/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random.py @@ -2,6 +2,7 @@ CAVEAT: the line number is important to some IAST tests, be careful to modify this file and update the tests if you make some changes """ + import random as random_module from random import betavariate from random import choice diff --git a/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random_module.py b/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random_module.py index f0e0eb3eaa9..4686ab96151 100644 --- a/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random_module.py +++ b/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random_module.py @@ -2,6 +2,7 @@ CAVEAT: the line number is important to some IAST tests, be careful to modify this file and update the tests if you make some changes """ + import random as random_2 diff --git a/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random_secure_module.py b/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random_secure_module.py index 073e295da4b..765dc2d240f 100644 --- a/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random_secure_module.py +++ b/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_random_secure_module.py @@ -2,6 +2,7 @@ CAVEAT: the line number is important to some IAST tests, be careful to modify this file and update the tests if you make some changes """ + import random as random_module diff --git a/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_secrets.py b/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_secrets.py index d329bfb9ba1..3453563b9d2 100644 --- a/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_secrets.py +++ b/tests/appsec/iast/fixtures/taint_sinks/weak_randomness_secrets.py @@ -2,6 +2,7 @@ CAVEAT: the line number is important to some IAST tests, be careful to modify this file and update the tests if you make some changes """ + from secrets import choice diff --git a/tests/appsec/iast/secure_marks/test_sanitizers.py b/tests/appsec/iast/secure_marks/test_sanitizers.py index dfa0f37c7f4..b7cae9cb84f 100644 --- a/tests/appsec/iast/secure_marks/test_sanitizers.py +++ b/tests/appsec/iast/secure_marks/test_sanitizers.py @@ -1,4 +1,5 @@ """Tests for IAST secure marks sanitizers.""" + from unittest import mock from ddtrace.appsec._iast._taint_tracking import OriginType diff --git a/tests/appsec/iast/secure_marks/test_security_controls_configuration.py b/tests/appsec/iast/secure_marks/test_security_controls_configuration.py index d5653320940..229fdf92f02 100644 --- a/tests/appsec/iast/secure_marks/test_security_controls_configuration.py +++ b/tests/appsec/iast/secure_marks/test_security_controls_configuration.py @@ -1,4 +1,5 @@ """Tests for DD_IAST_SECURITY_CONTROLS_CONFIGURATION environment variable functionality.""" + import functools import os from unittest.mock import patch @@ -147,7 +148,7 @@ def test_parse_security_controls_config_single(): def test_parse_security_controls_config_multiple(): """Test parsing multiple security control configurations.""" - config = "INPUT_VALIDATOR:COMMAND_INJECTION:shlex:quote;" "SANITIZER:XSS,SQLI:html:escape" + config = "INPUT_VALIDATOR:COMMAND_INJECTION:shlex:quote;SANITIZER:XSS,SQLI:html:escape" result = parse_security_controls_config(config) assert len(result) == 2 diff --git a/tests/appsec/iast/taint_sinks/test_code_injection_inspect_regression.py b/tests/appsec/iast/taint_sinks/test_code_injection_inspect_regression.py index 1412bb2b40f..5c0add1107d 100644 --- a/tests/appsec/iast/taint_sinks/test_code_injection_inspect_regression.py +++ b/tests/appsec/iast/taint_sinks/test_code_injection_inspect_regression.py @@ -5,6 +5,7 @@ inspect.currentframe() returns None, preventing AttributeError when accessing f_back and other crashes. """ + import sys from unittest import mock diff --git a/tests/appsec/iast/taint_sinks/test_sql_injection.py b/tests/appsec/iast/taint_sinks/test_sql_injection.py index acfc060a822..0b689258507 100644 --- a/tests/appsec/iast/taint_sinks/test_sql_injection.py +++ b/tests/appsec/iast/taint_sinks/test_sql_injection.py @@ -89,11 +89,10 @@ def test_check_and_report_sqli_metrics(args, integration_name, expected_result, args[0], source_name="request_body", source_value=args[0], source_origin=OriginType.PARAMETER ) - with mock.patch( - "ddtrace.appsec._iast.taint_sinks.sql_injection.increment_iast_span_metric" - ) as mock_increment, mock.patch( - "ddtrace.appsec._iast.taint_sinks.sql_injection._set_metric_iast_executed_sink" - ) as mock_set_metric: + with ( + mock.patch("ddtrace.appsec._iast.taint_sinks.sql_injection.increment_iast_span_metric") as mock_increment, + mock.patch("ddtrace.appsec._iast.taint_sinks.sql_injection._set_metric_iast_executed_sink") as mock_set_metric, + ): # Call with tainted argument that should trigger metrics result = _on_report_sqli(args, {}, integration_name, cursor.execute) @@ -127,11 +126,10 @@ def test_check_and_report_sqli_no_metrics(args, integration_name, iast_context_d cursor = mock.Mock() cursor.execute.__name__ = "execute" - with mock.patch( - "ddtrace.appsec._iast.taint_sinks.sql_injection.increment_iast_span_metric" - ) as mock_increment, mock.patch( - "ddtrace.appsec._iast.taint_sinks.sql_injection._set_metric_iast_executed_sink" - ) as mock_set_metric: + with ( + mock.patch("ddtrace.appsec._iast.taint_sinks.sql_injection.increment_iast_span_metric") as mock_increment, + mock.patch("ddtrace.appsec._iast.taint_sinks.sql_injection._set_metric_iast_executed_sink") as mock_set_metric, + ): # Call with untainted argument that should not trigger metrics result = _on_report_sqli(args, {}, integration_name, cursor.execute) diff --git a/tests/appsec/iast/taint_sinks/test_sql_injection_dbapi.py b/tests/appsec/iast/taint_sinks/test_sql_injection_dbapi.py index 7721beecaf6..633d4d17c36 100644 --- a/tests/appsec/iast/taint_sinks/test_sql_injection_dbapi.py +++ b/tests/appsec/iast/taint_sinks/test_sql_injection_dbapi.py @@ -41,13 +41,16 @@ def test_tainted_query(self): from ddtrace.appsec._iast._taint_tracking import OriginType from ddtrace.appsec._iast._taint_tracking._taint_objects import taint_pyobject - with override_global_config( - dict( - _iast_enabled=True, - ) - ), mock.patch( - "ddtrace.appsec._iast.taint_sinks.sql_injection.SqlInjection.report" - ) as mock_sql_injection_report: + with ( + override_global_config( + dict( + _iast_enabled=True, + ) + ), + mock.patch( + "ddtrace.appsec._iast.taint_sinks.sql_injection.SqlInjection.report" + ) as mock_sql_injection_report, + ): query = "SELECT * FROM db;" query = taint_pyobject(query, source_name="query", source_value=query, source_origin=OriginType.PARAMETER) diff --git a/tests/appsec/iast/taint_sinks/test_text_type_validation.py b/tests/appsec/iast/taint_sinks/test_text_type_validation.py index 94bfb26e01b..233646df3b4 100644 --- a/tests/appsec/iast/taint_sinks/test_text_type_validation.py +++ b/tests/appsec/iast/taint_sinks/test_text_type_validation.py @@ -69,9 +69,9 @@ def test_text_types_still_trigger_vulnerabilities(iast_context_defaults): _iast_report_unvalidated_redirect(tainted_obj) span_report = get_iast_reporter() assert span_report is not None, f"No unvalidated redirect vulnerability reported for {text_type.__name__}" - assert ( - len(span_report.vulnerabilities) > 0 - ), f"No unvalidated redirect vulnerabilities found for {text_type.__name__}" + assert len(span_report.vulnerabilities) > 0, ( + f"No unvalidated redirect vulnerabilities found for {text_type.__name__}" + ) # Clear vulnerabilities for next test span_report.vulnerabilities.clear() diff --git a/tests/appsec/iast/taint_tracking/test_anyio_thread_safety.py b/tests/appsec/iast/taint_tracking/test_anyio_thread_safety.py index 44310e2bc51..e4a248d901d 100644 --- a/tests/appsec/iast/taint_tracking/test_anyio_thread_safety.py +++ b/tests/appsec/iast/taint_tracking/test_anyio_thread_safety.py @@ -7,6 +7,7 @@ This test verifies the fix by simulating anyio-like concurrent access patterns. """ + import pytest diff --git a/tests/appsec/iast/taint_tracking/test_initializer_thread_safety.py b/tests/appsec/iast/taint_tracking/test_initializer_thread_safety.py index 6b1e3e67f20..d478bac3944 100644 --- a/tests/appsec/iast/taint_tracking/test_initializer_thread_safety.py +++ b/tests/appsec/iast/taint_tracking/test_initializer_thread_safety.py @@ -6,6 +6,7 @@ 1. Concurrent access from multiple threads doesn't cause issues 2. IAST is properly disabled in forked child processes to prevent segfaults """ + import os import sys import threading diff --git a/tests/appsec/iast/test_fork_handler_regression.py b/tests/appsec/iast/test_fork_handler_regression.py index 40a51cd7a0e..dbd6942f4bc 100644 --- a/tests/appsec/iast/test_fork_handler_regression.py +++ b/tests/appsec/iast/test_fork_handler_regression.py @@ -13,6 +13,7 @@ The fork handler detects which type of fork occurred by checking for active contexts. """ + from multiprocessing import Process from multiprocessing import Queue import os @@ -108,9 +109,7 @@ def child_process_work(queue): # Parent setup - IAST works normally _start_iast_context_and_oce() - _ = taint_pyobject( - "parent_data", source_name="parent", source_value="value", source_origin=OriginType.HEADER_NAME - ) # noqa: F841 + _ = taint_pyobject("parent_data", source_name="parent", source_value="value", source_origin=OriginType.HEADER_NAME) # noqa: F841 # Fork a child process queue = Queue() diff --git a/tests/appsec/iast/test_grpc_iast.py b/tests/appsec/iast/test_grpc_iast.py index b8f7ade95ba..9d225585129 100644 --- a/tests/appsec/iast/test_grpc_iast.py +++ b/tests/appsec/iast/test_grpc_iast.py @@ -147,8 +147,9 @@ class MyUserDict(UserDict): @pytest.mark.skip def test_address_server_data(self): - with override_config("grpc", dict(service_name="myclientsvc")), override_config( - "grpc_server", dict(service_name="myserversvc") + with ( + override_config("grpc", dict(service_name="myclientsvc")), + override_config("grpc_server", dict(service_name="myserversvc")), ): with mock.patch("ddtrace.appsec._asm_request_context.set_waf_address") as mock_set_waf_addr: channel1 = grpc.insecure_channel("localhost:%d" % (_GRPC_PORT)) diff --git a/tests/appsec/iast/test_multiprocessing_eval_integration.py b/tests/appsec/iast/test_multiprocessing_eval_integration.py index baaea671643..ecc0379811a 100644 --- a/tests/appsec/iast/test_multiprocessing_eval_integration.py +++ b/tests/appsec/iast/test_multiprocessing_eval_integration.py @@ -5,6 +5,7 @@ segmentation faults: a web server using multiprocessing workers with IAST enabled performing code evaluation. """ + from multiprocessing import Process from multiprocessing import Queue import os diff --git a/tests/appsec/iast/test_overhead_control_engine.py b/tests/appsec/iast/test_overhead_control_engine.py index 0b970cfc8f8..db3cd521646 100644 --- a/tests/appsec/iast/test_overhead_control_engine.py +++ b/tests/appsec/iast/test_overhead_control_engine.py @@ -112,9 +112,10 @@ def test_oce_reset_vulnerabilities_report(iast_context_deduplication_enabled): f"DEBUG: vulnerability_budget={env.vulnerability_budget}, " f"vulnerabilities_request_limit={env.vulnerabilities_request_limit}" ) - assert ( - False - ), f"IAST reporter should exist before reset. IAST enabled: {is_iast_request_enabled()}, env: {env is not None}" + assert False, ( + f"IAST reporter should exist before reset. IAST enabled: {is_iast_request_enabled()}, " + "env: {env is not None}" + ) initial_count = len(span_report.vulnerabilities) assert initial_count == asm_config._iast_max_vulnerabilities_per_requests diff --git a/tests/appsec/iast/test_patch_modules.py b/tests/appsec/iast/test_patch_modules.py index cdb7ea665bd..6d1254c6235 100644 --- a/tests/appsec/iast/test_patch_modules.py +++ b/tests/appsec/iast/test_patch_modules.py @@ -3,6 +3,7 @@ This module contains tests for the IAST module patching system, including tests for IASTFunction and WrapFunctonsForIAST classes. """ + from unittest.mock import MagicMock from unittest.mock import patch diff --git a/tests/appsec/iast/test_product_inspect_regression.py b/tests/appsec/iast/test_product_inspect_regression.py index 61a7df4dae1..ddc6d480795 100644 --- a/tests/appsec/iast/test_product_inspect_regression.py +++ b/tests/appsec/iast/test_product_inspect_regression.py @@ -14,6 +14,7 @@ 3. pytest tries to use the old Signature objects with a fresh inspect module 4. The mismatch causes type/identity checks to fail """ + import sys from tests.utils import override_env diff --git a/tests/appsec/iast_packages/inside_env_runner.py b/tests/appsec/iast_packages/inside_env_runner.py index 77f7c52c0e5..92bc138254a 100644 --- a/tests/appsec/iast_packages/inside_env_runner.py +++ b/tests/appsec/iast_packages/inside_env_runner.py @@ -39,15 +39,15 @@ def try_patched(module_name, expect_no_change=False): module, patched_module = _iast_patched_module_and_patched_source(module_name) if expect_no_change: assert module, "Module is not OK after patching" - assert ( - not patched_module - ), "Patched source is None after patching: Expected to be the same as the original source" + assert not patched_module, ( + "Patched source is None after patching: Expected to be the same as the original source" + ) return 0 assert module, "Module is None after patching: Maybe not an error, but something fishy is going on" - assert ( - patched_module - ), "Patched source is None after patching: Maybe not an error, but something fishy is going on" + assert patched_module, ( + "Patched source is None after patching: Maybe not an error, but something fishy is going on" + ) new_code = unparse(patched_module) assert ( "import ddtrace.appsec._iast.taint_sinks as _ddtrace_taint_sinks" diff --git a/tests/appsec/iast_packages/packages/pkg_aiohttp.py b/tests/appsec/iast_packages/packages/pkg_aiohttp.py index 7d05a5eab31..45fe24a8e39 100644 --- a/tests/appsec/iast_packages/packages/pkg_aiohttp.py +++ b/tests/appsec/iast_packages/packages/pkg_aiohttp.py @@ -3,6 +3,7 @@ https://pypi.org/project/aiohttp/ """ + from flask import Blueprint from flask import jsonify from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_aiosignal.py b/tests/appsec/iast_packages/packages/pkg_aiosignal.py index b07f66163d7..84e5a45cd67 100644 --- a/tests/appsec/iast_packages/packages/pkg_aiosignal.py +++ b/tests/appsec/iast_packages/packages/pkg_aiosignal.py @@ -3,6 +3,7 @@ https://pypi.org/project/aiosignal/ """ + import asyncio from flask import Blueprint diff --git a/tests/appsec/iast_packages/packages/pkg_asn1crypto.py b/tests/appsec/iast_packages/packages/pkg_asn1crypto.py index f8fd06c6056..2b9a731f066 100644 --- a/tests/appsec/iast_packages/packages/pkg_asn1crypto.py +++ b/tests/appsec/iast_packages/packages/pkg_asn1crypto.py @@ -3,6 +3,7 @@ https://pypi.org/project/asn1crypto/ """ + from flask import Blueprint from flask import Flask from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_certifi.py b/tests/appsec/iast_packages/packages/pkg_certifi.py index b83adfa8098..9ffb0066f3a 100644 --- a/tests/appsec/iast_packages/packages/pkg_certifi.py +++ b/tests/appsec/iast_packages/packages/pkg_certifi.py @@ -3,6 +3,7 @@ https://pypi.org/project/certifi/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_cffi.py b/tests/appsec/iast_packages/packages/pkg_cffi.py index 0d4bb0d1cd4..fa202615e4a 100644 --- a/tests/appsec/iast_packages/packages/pkg_cffi.py +++ b/tests/appsec/iast_packages/packages/pkg_cffi.py @@ -3,6 +3,7 @@ https://pypi.org/project/cffi/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_click.py b/tests/appsec/iast_packages/packages/pkg_click.py index 7b3a6df91cf..791e326a80b 100644 --- a/tests/appsec/iast_packages/packages/pkg_click.py +++ b/tests/appsec/iast_packages/packages/pkg_click.py @@ -3,6 +3,7 @@ https://pypi.org/project/click/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_decorator.py b/tests/appsec/iast_packages/packages/pkg_decorator.py index f8ec0686d16..0fbd9e9e292 100644 --- a/tests/appsec/iast_packages/packages/pkg_decorator.py +++ b/tests/appsec/iast_packages/packages/pkg_decorator.py @@ -3,6 +3,7 @@ https://pypi.org/project/decorator/ """ + from flask import Blueprint from flask import jsonify from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_distlib.py b/tests/appsec/iast_packages/packages/pkg_distlib.py index 9f4fa69e5fc..92b1c47b2e0 100644 --- a/tests/appsec/iast_packages/packages/pkg_distlib.py +++ b/tests/appsec/iast_packages/packages/pkg_distlib.py @@ -3,6 +3,7 @@ https://pypi.org/project/distlib/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_filelock.py b/tests/appsec/iast_packages/packages/pkg_filelock.py index 835e385f106..51cf1143819 100644 --- a/tests/appsec/iast_packages/packages/pkg_filelock.py +++ b/tests/appsec/iast_packages/packages/pkg_filelock.py @@ -3,6 +3,7 @@ https://pypi.org/project/filelock/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_frozenlist.py b/tests/appsec/iast_packages/packages/pkg_frozenlist.py index 8ff892a8e60..f6d81451c59 100644 --- a/tests/appsec/iast_packages/packages/pkg_frozenlist.py +++ b/tests/appsec/iast_packages/packages/pkg_frozenlist.py @@ -3,6 +3,7 @@ https://pypi.org/project/frozenlist/ """ + from flask import Blueprint from flask import jsonify from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_fsspec.py b/tests/appsec/iast_packages/packages/pkg_fsspec.py index f7e342970d9..27efdf73665 100644 --- a/tests/appsec/iast_packages/packages/pkg_fsspec.py +++ b/tests/appsec/iast_packages/packages/pkg_fsspec.py @@ -2,6 +2,7 @@ fsspec==2024.5.0 https://pypi.org/project/fsspec/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_google_api_core.py b/tests/appsec/iast_packages/packages/pkg_google_api_core.py index a87e0ae3456..b2deba7567d 100644 --- a/tests/appsec/iast_packages/packages/pkg_google_api_core.py +++ b/tests/appsec/iast_packages/packages/pkg_google_api_core.py @@ -3,6 +3,7 @@ https://pypi.org/project/google-api-core/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_importlib_resources.py b/tests/appsec/iast_packages/packages/pkg_importlib_resources.py index 96d0abb5f29..95580983b6c 100644 --- a/tests/appsec/iast_packages/packages/pkg_importlib_resources.py +++ b/tests/appsec/iast_packages/packages/pkg_importlib_resources.py @@ -3,6 +3,7 @@ https://pypi.org/project/importlib-resources/ """ + import os import shutil diff --git a/tests/appsec/iast_packages/packages/pkg_itsdangerous.py b/tests/appsec/iast_packages/packages/pkg_itsdangerous.py index fb2bee1603a..c99f413d316 100644 --- a/tests/appsec/iast_packages/packages/pkg_itsdangerous.py +++ b/tests/appsec/iast_packages/packages/pkg_itsdangerous.py @@ -3,6 +3,7 @@ https://pypi.org/project/itsdangerous/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_jmespath.py b/tests/appsec/iast_packages/packages/pkg_jmespath.py index 34598feacf2..e026bace4c7 100644 --- a/tests/appsec/iast_packages/packages/pkg_jmespath.py +++ b/tests/appsec/iast_packages/packages/pkg_jmespath.py @@ -2,6 +2,7 @@ jmespath==1.0.1 https://pypi.org/project/jmespath/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_jsonschema.py b/tests/appsec/iast_packages/packages/pkg_jsonschema.py index 6297dca6ca5..a6af90a3c96 100644 --- a/tests/appsec/iast_packages/packages/pkg_jsonschema.py +++ b/tests/appsec/iast_packages/packages/pkg_jsonschema.py @@ -2,6 +2,7 @@ jsonschema==4.22.0 https://pypi.org/project/jsonschema/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_markupsafe.py b/tests/appsec/iast_packages/packages/pkg_markupsafe.py index 26a78a3b953..3efcb34b2d1 100644 --- a/tests/appsec/iast_packages/packages/pkg_markupsafe.py +++ b/tests/appsec/iast_packages/packages/pkg_markupsafe.py @@ -3,6 +3,7 @@ https://pypi.org/project/markupsafe/ """ + from flask import Blueprint from flask import request from jinja2 import Template diff --git a/tests/appsec/iast_packages/packages/pkg_more_itertools.py b/tests/appsec/iast_packages/packages/pkg_more_itertools.py index 3aed8fe8be2..224ef40d450 100644 --- a/tests/appsec/iast_packages/packages/pkg_more_itertools.py +++ b/tests/appsec/iast_packages/packages/pkg_more_itertools.py @@ -3,6 +3,7 @@ https://pypi.org/project/more-itertools/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_numpy.py b/tests/appsec/iast_packages/packages/pkg_numpy.py index b9383ac108e..00c2c9958b7 100644 --- a/tests/appsec/iast_packages/packages/pkg_numpy.py +++ b/tests/appsec/iast_packages/packages/pkg_numpy.py @@ -3,6 +3,7 @@ https://pypi.org/project/numpy/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_oauthlib.py b/tests/appsec/iast_packages/packages/pkg_oauthlib.py index f0867b6c85a..eddd80453f0 100644 --- a/tests/appsec/iast_packages/packages/pkg_oauthlib.py +++ b/tests/appsec/iast_packages/packages/pkg_oauthlib.py @@ -3,6 +3,7 @@ https://pypi.org/project/oauthlib/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_openpyxl.py b/tests/appsec/iast_packages/packages/pkg_openpyxl.py index 3c87d732554..c6f1f4a138f 100644 --- a/tests/appsec/iast_packages/packages/pkg_openpyxl.py +++ b/tests/appsec/iast_packages/packages/pkg_openpyxl.py @@ -3,6 +3,7 @@ https://pypi.org/project/openpyxl/ """ + import os from flask import Blueprint diff --git a/tests/appsec/iast_packages/packages/pkg_packaging.py b/tests/appsec/iast_packages/packages/pkg_packaging.py index 4800c4ca2a2..d01adcfe160 100644 --- a/tests/appsec/iast_packages/packages/pkg_packaging.py +++ b/tests/appsec/iast_packages/packages/pkg_packaging.py @@ -2,6 +2,7 @@ packaging==24.0 https://pypi.org/project/packaging/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_pandas.py b/tests/appsec/iast_packages/packages/pkg_pandas.py index 441ba96159c..97a899ae75c 100644 --- a/tests/appsec/iast_packages/packages/pkg_pandas.py +++ b/tests/appsec/iast_packages/packages/pkg_pandas.py @@ -3,6 +3,7 @@ https://pypi.org/project/pandas/ """ + import os from flask import Blueprint diff --git a/tests/appsec/iast_packages/packages/pkg_pillow.py b/tests/appsec/iast_packages/packages/pkg_pillow.py index 2f6f02aa413..9f8530bbf58 100644 --- a/tests/appsec/iast_packages/packages/pkg_pillow.py +++ b/tests/appsec/iast_packages/packages/pkg_pillow.py @@ -3,6 +3,7 @@ https://pypi.org/project/Pillow/ """ + import os from flask import Blueprint diff --git a/tests/appsec/iast_packages/packages/pkg_pluggy.py b/tests/appsec/iast_packages/packages/pkg_pluggy.py index 303fad64a32..f6a51c65105 100644 --- a/tests/appsec/iast_packages/packages/pkg_pluggy.py +++ b/tests/appsec/iast_packages/packages/pkg_pluggy.py @@ -3,6 +3,7 @@ https://pypi.org/project/pluggy/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_psutil.py b/tests/appsec/iast_packages/packages/pkg_psutil.py index bb97e567846..fe80f21f78d 100644 --- a/tests/appsec/iast_packages/packages/pkg_psutil.py +++ b/tests/appsec/iast_packages/packages/pkg_psutil.py @@ -3,6 +3,7 @@ https://pypi.org/project/psutil/ """ + from flask import Blueprint from flask import jsonify from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_pyarrow.py b/tests/appsec/iast_packages/packages/pkg_pyarrow.py index 880d6c01207..fca395faaca 100644 --- a/tests/appsec/iast_packages/packages/pkg_pyarrow.py +++ b/tests/appsec/iast_packages/packages/pkg_pyarrow.py @@ -3,6 +3,7 @@ https://pypi.org/project/pyarrow/ """ + import os from flask import Blueprint diff --git a/tests/appsec/iast_packages/packages/pkg_pycparser.py b/tests/appsec/iast_packages/packages/pkg_pycparser.py index 4e80e46c681..e7ed045cf20 100644 --- a/tests/appsec/iast_packages/packages/pkg_pycparser.py +++ b/tests/appsec/iast_packages/packages/pkg_pycparser.py @@ -2,6 +2,7 @@ pycparser==2.22 https://pypi.org/project/pycparser/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_pydantic.py b/tests/appsec/iast_packages/packages/pkg_pydantic.py index a33eea5fd29..596656c22c0 100644 --- a/tests/appsec/iast_packages/packages/pkg_pydantic.py +++ b/tests/appsec/iast_packages/packages/pkg_pydantic.py @@ -3,6 +3,7 @@ https://pypi.org/project/pydantic/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_pyopenssl.py b/tests/appsec/iast_packages/packages/pkg_pyopenssl.py index 919fc750c11..a312cc79171 100644 --- a/tests/appsec/iast_packages/packages/pkg_pyopenssl.py +++ b/tests/appsec/iast_packages/packages/pkg_pyopenssl.py @@ -3,6 +3,7 @@ https://pypi.org/project/pyOpenSSL/ """ + from flask import Blueprint from flask import jsonify from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_python_dateutil.py b/tests/appsec/iast_packages/packages/pkg_python_dateutil.py index 2b7b65d670a..aa9415e3d27 100644 --- a/tests/appsec/iast_packages/packages/pkg_python_dateutil.py +++ b/tests/appsec/iast_packages/packages/pkg_python_dateutil.py @@ -3,6 +3,7 @@ https://pypi.org/project/python-dateutil/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_pytz.py b/tests/appsec/iast_packages/packages/pkg_pytz.py index cad43b45d14..4b9a37a6db3 100644 --- a/tests/appsec/iast_packages/packages/pkg_pytz.py +++ b/tests/appsec/iast_packages/packages/pkg_pytz.py @@ -3,6 +3,7 @@ https://pypi.org/project/pytz/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_requests.py b/tests/appsec/iast_packages/packages/pkg_requests.py index 90508460480..94e02f8b043 100644 --- a/tests/appsec/iast_packages/packages/pkg_requests.py +++ b/tests/appsec/iast_packages/packages/pkg_requests.py @@ -3,6 +3,7 @@ https://pypi.org/project/requests/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_requests_toolbelt.py b/tests/appsec/iast_packages/packages/pkg_requests_toolbelt.py index 9767892e8e4..f0f2e6070d1 100644 --- a/tests/appsec/iast_packages/packages/pkg_requests_toolbelt.py +++ b/tests/appsec/iast_packages/packages/pkg_requests_toolbelt.py @@ -3,6 +3,7 @@ https://pypi.org/project/requests-toolbelt/ """ + from flask import Blueprint from flask import jsonify from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_s3fs.py b/tests/appsec/iast_packages/packages/pkg_s3fs.py index 3f00a0c8c87..d0a3510793e 100644 --- a/tests/appsec/iast_packages/packages/pkg_s3fs.py +++ b/tests/appsec/iast_packages/packages/pkg_s3fs.py @@ -2,6 +2,7 @@ s3fs==2024.5.0 https://pypi.org/project/s3fs/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_s3transfer.py b/tests/appsec/iast_packages/packages/pkg_s3transfer.py index bab9f21fcf0..86c3516ce78 100644 --- a/tests/appsec/iast_packages/packages/pkg_s3transfer.py +++ b/tests/appsec/iast_packages/packages/pkg_s3transfer.py @@ -3,6 +3,7 @@ https://pypi.org/project/s3transfer/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_scipy.py b/tests/appsec/iast_packages/packages/pkg_scipy.py index 5bc6568b926..b5f160c86fc 100644 --- a/tests/appsec/iast_packages/packages/pkg_scipy.py +++ b/tests/appsec/iast_packages/packages/pkg_scipy.py @@ -3,6 +3,7 @@ https://pypi.org/project/scipy/ """ + from flask import Blueprint from flask import jsonify from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_setuptools.py b/tests/appsec/iast_packages/packages/pkg_setuptools.py index 9b9bc049838..3178348e04b 100644 --- a/tests/appsec/iast_packages/packages/pkg_setuptools.py +++ b/tests/appsec/iast_packages/packages/pkg_setuptools.py @@ -3,6 +3,7 @@ https://pypi.org/project/setuptools/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_tomlkit.py b/tests/appsec/iast_packages/packages/pkg_tomlkit.py index 9761e4e4e7b..ad785de2d9b 100644 --- a/tests/appsec/iast_packages/packages/pkg_tomlkit.py +++ b/tests/appsec/iast_packages/packages/pkg_tomlkit.py @@ -3,6 +3,7 @@ https://pypi.org/project/tomlkit/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_urllib3.py b/tests/appsec/iast_packages/packages/pkg_urllib3.py index a520ed749f3..d9e2fdc89b3 100644 --- a/tests/appsec/iast_packages/packages/pkg_urllib3.py +++ b/tests/appsec/iast_packages/packages/pkg_urllib3.py @@ -3,6 +3,7 @@ https://pypi.org/project/urllib3/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_virtualenv.py b/tests/appsec/iast_packages/packages/pkg_virtualenv.py index ed59730e5d3..14726284446 100644 --- a/tests/appsec/iast_packages/packages/pkg_virtualenv.py +++ b/tests/appsec/iast_packages/packages/pkg_virtualenv.py @@ -3,6 +3,7 @@ https://pypi.org/project/virtualenv/ """ + import os import shutil diff --git a/tests/appsec/iast_packages/packages/pkg_werkzeug.py b/tests/appsec/iast_packages/packages/pkg_werkzeug.py index ea94485eaac..7324c934a49 100644 --- a/tests/appsec/iast_packages/packages/pkg_werkzeug.py +++ b/tests/appsec/iast_packages/packages/pkg_werkzeug.py @@ -3,6 +3,7 @@ https://pypi.org/project/werkzeug/ """ + from flask import Blueprint from flask import request diff --git a/tests/appsec/iast_packages/packages/pkg_zipp.py b/tests/appsec/iast_packages/packages/pkg_zipp.py index 63505df7302..02f0e3b0970 100644 --- a/tests/appsec/iast_packages/packages/pkg_zipp.py +++ b/tests/appsec/iast_packages/packages/pkg_zipp.py @@ -3,6 +3,7 @@ https://pypi.org/project/zipp/ """ + import os import zipfile diff --git a/tests/appsec/integrations/django_tests/conftest.py b/tests/appsec/integrations/django_tests/conftest.py index 68843239604..244e905c73e 100644 --- a/tests/appsec/integrations/django_tests/conftest.py +++ b/tests/appsec/integrations/django_tests/conftest.py @@ -27,13 +27,16 @@ # `pytest` automatically calls this function once when tests are run. def pytest_configure(): - with override_global_config( - dict( - _iast_enabled=True, - _iast_deduplication_enabled=False, - _iast_request_sampling=100.0, - ) - ), override_env(dict(_DD_IAST_PATCH_MODULES="tests.appsec.integrations")): + with ( + override_global_config( + dict( + _iast_enabled=True, + _iast_deduplication_enabled=False, + _iast_request_sampling=100.0, + ) + ), + override_env(dict(_DD_IAST_PATCH_MODULES="tests.appsec.integrations")), + ): settings.DEBUG = False patch_iast() load_iast() diff --git a/tests/appsec/integrations/django_tests/django_app/wsgi.py b/tests/appsec/integrations/django_tests/django_app/wsgi.py index a838bc7cfcc..4990356f388 100644 --- a/tests/appsec/integrations/django_tests/django_app/wsgi.py +++ b/tests/appsec/integrations/django_tests/django_app/wsgi.py @@ -3,6 +3,7 @@ This enables running the Django test app under Gunicorn using the ``tests.appsec.integrations.django_tests.django_app.wsgi:application`` target. """ + import ddtrace.auto # noqa: F401 # isort: skip import os diff --git a/tests/appsec/integrations/django_tests/test_appsec_django.py b/tests/appsec/integrations/django_tests/test_appsec_django.py index 1786ee542a8..7ac64751864 100644 --- a/tests/appsec/integrations/django_tests/test_appsec_django.py +++ b/tests/appsec/integrations/django_tests/test_appsec_django.py @@ -179,15 +179,18 @@ def test_django_login_sucess_identification(client, test_spans, tracer, use_logi from django.contrib.auth import get_user from django.contrib.auth.models import User - with override_global_config( - dict( - _asm_enabled=True, - _auto_user_instrumentation_local_mode=LOGIN_EVENTS_MODE.IDENT, - _django_include_user_email=use_email, - _django_include_user_login=use_login, - _django_include_user_realname=use_realname, - ) - ), update_django_config(): + with ( + override_global_config( + dict( + _asm_enabled=True, + _auto_user_instrumentation_local_mode=LOGIN_EVENTS_MODE.IDENT, + _django_include_user_email=use_email, + _django_include_user_login=use_login, + _django_include_user_realname=use_realname, + ) + ), + update_django_config(), + ): # update django config for tests test_user = User.objects.create(username="fred", first_name="Fred", email="fred@test.com") test_user.set_password("secret") @@ -226,15 +229,18 @@ def test_django_login_sucess_anonymization(client, test_spans, tracer, use_login from django.contrib.auth import get_user from django.contrib.auth.models import User - with override_global_config( - dict( - _asm_enabled=True, - _auto_user_instrumentation_local_mode=LOGIN_EVENTS_MODE.ANON, - _django_include_user_email=use_email, - _django_include_user_login=use_login, - _django_include_user_realname=use_realname, - ) - ), update_django_config(): + with ( + override_global_config( + dict( + _asm_enabled=True, + _auto_user_instrumentation_local_mode=LOGIN_EVENTS_MODE.ANON, + _django_include_user_email=use_email, + _django_include_user_login=use_login, + _django_include_user_realname=use_realname, + ) + ), + update_django_config(), + ): test_user = User.objects.create(username="fred2") test_user.set_password("secret") test_user.save() diff --git a/tests/appsec/integrations/django_tests/test_iast_django.py b/tests/appsec/integrations/django_tests/test_iast_django.py index d35f91cda03..e217d22c8e6 100644 --- a/tests/appsec/integrations/django_tests/test_iast_django.py +++ b/tests/appsec/integrations/django_tests/test_iast_django.py @@ -205,9 +205,9 @@ def test_django_sqli_http_request_parameter_metrics_disabled(client, iast_spans_ url="/appsec/sqli_http_request_parameter_name_post/", headers={"HTTP_USER_AGENT": "test/1.2.3"}, ) - assert ( - root_span.get_metric(IAST.ENABLED) == 0.0 - ), f"IAST should be disabled. Metric: {root_span.get_metric(IAST.ENABLED)}" + assert root_span.get_metric(IAST.ENABLED) == 0.0, ( + f"IAST should be disabled. Metric: {root_span.get_metric(IAST.ENABLED)}" + ) assert root_span.get_metric(IAST_SPAN_TAGS.TELEMETRY_REQUEST_TAINTED) is None assert root_span.get_metric(IAST_SPAN_TAGS.TELEMETRY_EXECUTED_SINK + ".sql_injection") is None assert root_span.get_metric(IAST_SPAN_TAGS.TELEMETRY_EXECUTED_SINK + ".header_injection") is None @@ -989,14 +989,14 @@ def test_django_command_injection_subprocess(client, iast_span, tracer): line, hash_value = get_line_and_hash("iast_command_injection_subprocess", VULN_CMDI, filename=TEST_FILE) - assert loaded["sources"] == [ - {"name": "cmd", "origin": "http.request.body", "value": "ls"} - ], f'Assertion error: {loaded["sources"]}' + assert loaded["sources"] == [{"name": "cmd", "origin": "http.request.body", "value": "ls"}], ( + f"Assertion error: {loaded['sources']}" + ) assert loaded["vulnerabilities"][0]["type"] == VULN_CMDI assert loaded["vulnerabilities"][0]["hash"] == hash_value assert loaded["vulnerabilities"][0]["evidence"] == { "valueParts": [{"value": "ls", "source": 0}, {"value": " "}, {"redacted": True}] - }, f'Assertion error: {loaded["vulnerabilities"][0]["evidence"]}' + }, f"Assertion error: {loaded['vulnerabilities'][0]['evidence']}" assert loaded["vulnerabilities"][0]["location"]["line"] == line assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE @@ -1628,9 +1628,9 @@ def test_django_iast_sampling(client, test_spans_2_vuln_per_request_deduplicatio for vuln in loaded["vulnerabilities"]: assert vuln["type"] == VULN_SQL_INJECTION list_vulnerabilities.append(vuln["location"]["line"]) - assert ( - len(list_vulnerabilities) == 10 - ), f"Num vulnerabilities: ({len(list_vulnerabilities)}): {list_vulnerabilities}" + assert len(list_vulnerabilities) == 10, ( + f"Num vulnerabilities: ({len(list_vulnerabilities)}): {list_vulnerabilities}" + ) @pytest.mark.django_db() @@ -1684,9 +1684,9 @@ def test_django_iast_sampling_by_route_method(client, test_spans_2_vuln_per_requ for vuln in loaded["vulnerabilities"]: assert vuln["type"] == VULN_SQL_INJECTION list_vulnerabilities.append(vuln["location"]["line"]) - assert ( - len(list_vulnerabilities) == 16 - ), f"Num vulnerabilities: ({len(list_vulnerabilities)}): {list_vulnerabilities}" + assert len(list_vulnerabilities) == 16, ( + f"Num vulnerabilities: ({len(list_vulnerabilities)}): {list_vulnerabilities}" + ) @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") diff --git a/tests/appsec/integrations/django_tests/test_iast_django_testagent.py b/tests/appsec/integrations/django_tests/test_iast_django_testagent.py index efb068c4fab..51a8518667d 100644 --- a/tests/appsec/integrations/django_tests/test_iast_django_testagent.py +++ b/tests/appsec/integrations/django_tests/test_iast_django_testagent.py @@ -55,7 +55,7 @@ def test_iast_cmdi_bodies(body, content_type, server): token=token, env={ "_DD_IAST_PATCH_MODULES": ( - "benchmarks.," "tests.appsec.," "tests.appsec.integrations.django_tests.django_app.views." + "benchmarks.,tests.appsec.,tests.appsec.integrations.django_tests.django_app.views." ), }, ) as context: @@ -110,7 +110,7 @@ def test_iast_untrusted_serialization_yaml(server, iast_test_token): token=iast_test_token, env={ "_DD_IAST_PATCH_MODULES": ( - "benchmarks.," "tests.appsec.," "tests.appsec.integrations.django_tests.django_app.views." + "benchmarks.,tests.appsec.,tests.appsec.integrations.django_tests.django_app.views." ), }, ) as context: @@ -339,7 +339,7 @@ def test_iast_header_injection(iast_test_token): token=iast_test_token, env={ "_DD_IAST_PATCH_MODULES": ( - "benchmarks.," "tests.appsec.," "tests.appsec.integrations.django_tests.django_app.views." + "benchmarks.,tests.appsec.,tests.appsec.integrations.django_tests.django_app.views." ), }, ) as context: diff --git a/tests/appsec/integrations/fastapi_tests/mcp_app.py b/tests/appsec/integrations/fastapi_tests/mcp_app.py index 186f3ce3f6b..df14c1e21d7 100644 --- a/tests/appsec/integrations/fastapi_tests/mcp_app.py +++ b/tests/appsec/integrations/fastapi_tests/mcp_app.py @@ -3,6 +3,7 @@ This app provides both regular HTTP endpoints and MCP tools to test IAST with different communication patterns. """ + import subprocess from fastapi import FastAPI diff --git a/tests/appsec/integrations/fastapi_tests/test_fastapi_appsec_iast.py b/tests/appsec/integrations/fastapi_tests/test_fastapi_appsec_iast.py index 5d80bc11646..9c72fed6b00 100644 --- a/tests/appsec/integrations/fastapi_tests/test_fastapi_appsec_iast.py +++ b/tests/appsec/integrations/fastapi_tests/test_fastapi_appsec_iast.py @@ -1202,6 +1202,6 @@ async def test_route(request: Request, item_id): list_vulnerabilities.append(vuln["location"]["line"]) else: assert loaded is None - assert ( - len(list_vulnerabilities) == 16 - ), f"Num vulnerabilities: ({len(list_vulnerabilities)}): {list_vulnerabilities}" + assert len(list_vulnerabilities) == 16, ( + f"Num vulnerabilities: ({len(list_vulnerabilities)}): {list_vulnerabilities}" + ) diff --git a/tests/appsec/integrations/fastapi_tests/test_iast_fastapi_testagent.py b/tests/appsec/integrations/fastapi_tests/test_iast_fastapi_testagent.py index aba4a41fb5c..7cda79dd689 100644 --- a/tests/appsec/integrations/fastapi_tests/test_iast_fastapi_testagent.py +++ b/tests/appsec/integrations/fastapi_tests/test_iast_fastapi_testagent.py @@ -15,7 +15,7 @@ # Common environment configuration for IAST tests IAST_ENV = { - "_DD_IAST_PATCH_MODULES": ("benchmarks.," "tests.appsec.," "tests.appsec.integrations.fastapi_tests.app."), + "_DD_IAST_PATCH_MODULES": ("benchmarks.,tests.appsec.,tests.appsec.integrations.fastapi_tests.app."), } diff --git a/tests/appsec/integrations/fastapi_tests/test_iast_mcp_testagent.py b/tests/appsec/integrations/fastapi_tests/test_iast_mcp_testagent.py index 2c9f8e6fea4..6a25bb4a38b 100644 --- a/tests/appsec/integrations/fastapi_tests/test_iast_mcp_testagent.py +++ b/tests/appsec/integrations/fastapi_tests/test_iast_mcp_testagent.py @@ -6,6 +6,7 @@ Includes both in-memory MCP connections and HTTP/SSE-based streaming tests. """ + from contextlib import asynccontextmanager import sys @@ -26,7 +27,7 @@ # Common environment configuration for MCP IAST tests MCP_IAST_ENV = { - "_DD_IAST_PATCH_MODULES": ("benchmarks.," "tests.appsec.," "tests.appsec.integrations.fastapi_tests.mcp_app."), + "_DD_IAST_PATCH_MODULES": ("benchmarks.,tests.appsec.,tests.appsec.integrations.fastapi_tests.mcp_app."), } diff --git a/tests/appsec/integrations/flask_tests/test_iast_flask.py b/tests/appsec/integrations/flask_tests/test_iast_flask.py index f1664294412..764cf46bed3 100644 --- a/tests/appsec/integrations/flask_tests/test_iast_flask.py +++ b/tests/appsec/integrations/flask_tests/test_iast_flask.py @@ -2080,9 +2080,9 @@ def test_sqli(): list_vulnerabilities.append(vuln["location"]["line"]) else: assert loaded is None - assert ( - len(list_vulnerabilities) == 16 - ), f"Num vulnerabilities: ({len(list_vulnerabilities)}): {list_vulnerabilities}" + assert len(list_vulnerabilities) == 16, ( + f"Num vulnerabilities: ({len(list_vulnerabilities)}): {list_vulnerabilities}" + ) class FlaskAppSecIASTDisabledTestCase(BaseFlaskTestCase): diff --git a/tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py b/tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py index 12da00a402b..8da7f27b5dc 100644 --- a/tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py +++ b/tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py @@ -21,8 +21,9 @@ def test_ddtrace_iast_flask_patch(): \s*\d+ LOAD_FAST 0 \(a\) \s*\d+ LOAD_FAST 1 \(b\)""" - with override_global_config(dict(_iast_enabled=True)), override_env( - dict(DD_IAST_ENABLED="true", DD_IAST_REQUEST_SAMPLING="100") + with ( + override_global_config(dict(_iast_enabled=True)), + override_env(dict(DD_IAST_ENABLED="true", DD_IAST_REQUEST_SAMPLING="100")), ): import tests.appsec.iast.fixtures.entrypoint.app_main_patched as flask_entrypoint @@ -49,8 +50,9 @@ def test_ddtrace_iast_flask_patch_py313(): PATTERN = r"""LOAD_GLOBAL 0 \(_ddtrace_aspects\)""" - with override_global_config(dict(_iast_enabled=True)), override_env( - dict(DD_IAST_ENABLED="true", DD_IAST_REQUEST_SAMPLING="100") + with ( + override_global_config(dict(_iast_enabled=True)), + override_env(dict(DD_IAST_ENABLED="true", DD_IAST_REQUEST_SAMPLING="100")), ): import tests.appsec.iast.fixtures.entrypoint.app_main_patched as flask_entrypoint @@ -108,8 +110,9 @@ def _uninstall_watchdog_and_reload(): assert ModuleWatchdog._instance._pre_exec_module_hooks == set() _uninstall_watchdog_and_reload() - with override_global_config(dict(_iast_enabled=True)), override_env( - dict(DD_IAST_ENABLED="true", DD_IAST_REQUEST_SAMPLING="100") + with ( + override_global_config(dict(_iast_enabled=True)), + override_env(dict(DD_IAST_ENABLED="true", DD_IAST_REQUEST_SAMPLING="100")), ): import tests.appsec.iast.fixtures.entrypoint.app as flask_entrypoint diff --git a/tests/appsec/integrations/flask_tests/test_iast_flask_testagent.py b/tests/appsec/integrations/flask_tests/test_iast_flask_testagent.py index 37277065a24..ef3ce9b8d26 100644 --- a/tests/appsec/integrations/flask_tests/test_iast_flask_testagent.py +++ b/tests/appsec/integrations/flask_tests/test_iast_flask_testagent.py @@ -66,9 +66,9 @@ def test_iast_stacktrace_error(iast_test_token): "/iast-stacktrace-leak-vulnerability", headers={"X-Datadog-Test-Session-Token": iast_test_token} ) assert response.status_code == 500 - assert ( - b"ValueError: Check my stacktrace!" in response.content - ), f"Exception doesn't found in CONTENT: {response.content}" + assert b"<title>ValueError: Check my stacktrace!" in response.content, ( + f"Exception doesn't found in CONTENT: {response.content}" + ) response_tracer = _get_span(iast_test_token) spans_with_iast = [] diff --git a/tests/appsec/integrations/langchain_tests/conftest.py b/tests/appsec/integrations/langchain_tests/conftest.py index f2ed1a76c24..ced8080cc58 100644 --- a/tests/appsec/integrations/langchain_tests/conftest.py +++ b/tests/appsec/integrations/langchain_tests/conftest.py @@ -8,13 +8,16 @@ # `pytest` automatically calls this function once when tests are run. def pytest_configure(): - with override_global_config( - dict( - _iast_enabled=True, - _iast_deduplication_enabled=False, - _iast_request_sampling=100.0, - ) - ), override_env(dict(_DD_IAST_PATCH_MODULES="tests.appsec.integrations")): + with ( + override_global_config( + dict( + _iast_enabled=True, + _iast_deduplication_enabled=False, + _iast_request_sampling=100.0, + ) + ), + override_env(dict(_DD_IAST_PATCH_MODULES="tests.appsec.integrations")), + ): patch_iast() enable_iast_propagation() # load_iast needs to happen before langchain_patch call, so that diff --git a/tests/appsec/integrations/packages_tests/test_ast_patching.py b/tests/appsec/integrations/packages_tests/test_ast_patching.py index 1793c16a103..526d116e7a7 100644 --- a/tests/appsec/integrations/packages_tests/test_ast_patching.py +++ b/tests/appsec/integrations/packages_tests/test_ast_patching.py @@ -4,6 +4,7 @@ This is necessary for detection by should_iast_patch, which checks for packages in site-packages. """ + import sys import pytest diff --git a/tests/appsec/utils.py b/tests/appsec/utils.py index 9b14d13b798..7ab114d296c 100644 --- a/tests/appsec/utils.py +++ b/tests/appsec/utils.py @@ -75,14 +75,17 @@ def asm_context( processor = AppSecSpanProcessor._instance if processor: processor._update_rules([], rc_payload) - with core.context_with_data( - "test.asm", - remote_addr=ip_addr, - headers_case_sensitive=headers_case_sensitive, - headers=headers, - block_request_callable=block_request_callable, - service=service, - ), tracer.trace(span_name or "test", span_type=span_type, service=service) as span: + with ( + core.context_with_data( + "test.asm", + remote_addr=ip_addr, + headers_case_sensitive=headers_case_sensitive, + headers=headers, + block_request_callable=block_request_callable, + service=service, + ), + tracer.trace(span_name or "test", span_type=span_type, service=service) as span, + ): yield span unpatch_for_waf_addresses() diff --git a/tests/ci_visibility/api/fake_runner_atr_mix_fail.py b/tests/ci_visibility/api/fake_runner_atr_mix_fail.py index c0358d64cdd..33edcde4daf 100644 --- a/tests/ci_visibility/api/fake_runner_atr_mix_fail.py +++ b/tests/ci_visibility/api/fake_runner_atr_mix_fail.py @@ -6,6 +6,7 @@ Comment lines in the test start/finish lines are there for visual distinction. """ + import json from multiprocessing import freeze_support from pathlib import Path diff --git a/tests/ci_visibility/api/fake_runner_atr_mix_pass.py b/tests/ci_visibility/api/fake_runner_atr_mix_pass.py index bafa323c944..1a738df5d75 100644 --- a/tests/ci_visibility/api/fake_runner_atr_mix_pass.py +++ b/tests/ci_visibility/api/fake_runner_atr_mix_pass.py @@ -2,6 +2,7 @@ Comment lines in the test start/finish lines are there for visual distinction. """ + import json from multiprocessing import freeze_support from pathlib import Path diff --git a/tests/ci_visibility/api/fake_runner_efd_all_pass.py b/tests/ci_visibility/api/fake_runner_efd_all_pass.py index 241f6e5a3d6..0625072b178 100644 --- a/tests/ci_visibility/api/fake_runner_efd_all_pass.py +++ b/tests/ci_visibility/api/fake_runner_efd_all_pass.py @@ -5,6 +5,7 @@ Comment lines in the test start/finish lines are there for visual distinction. """ + import json from multiprocessing import freeze_support from pathlib import Path diff --git a/tests/ci_visibility/api/fake_runner_efd_faulty_session.py b/tests/ci_visibility/api/fake_runner_efd_faulty_session.py index 2ce6b7d5445..9ccd55b687a 100644 --- a/tests/ci_visibility/api/fake_runner_efd_faulty_session.py +++ b/tests/ci_visibility/api/fake_runner_efd_faulty_session.py @@ -4,6 +4,7 @@ Comment lines in the test start/finish lines are there for visual distinction. """ + import json from multiprocessing import freeze_support from pathlib import Path diff --git a/tests/ci_visibility/api/fake_runner_efd_mix_fail.py b/tests/ci_visibility/api/fake_runner_efd_mix_fail.py index f0a17a36f15..b8934f648a2 100644 --- a/tests/ci_visibility/api/fake_runner_efd_mix_fail.py +++ b/tests/ci_visibility/api/fake_runner_efd_mix_fail.py @@ -5,6 +5,7 @@ Comment lines in the test start/finish lines are there for visual distinction. """ + import json from multiprocessing import freeze_support from pathlib import Path diff --git a/tests/ci_visibility/api/fake_runner_efd_mix_pass.py b/tests/ci_visibility/api/fake_runner_efd_mix_pass.py index 16f97a7b4bb..77d5b1cc1c8 100644 --- a/tests/ci_visibility/api/fake_runner_efd_mix_pass.py +++ b/tests/ci_visibility/api/fake_runner_efd_mix_pass.py @@ -5,6 +5,7 @@ Comment lines in the test start/finish lines are there for visual distinction. """ + import json from multiprocessing import freeze_support from pathlib import Path diff --git a/tests/ci_visibility/api/fake_runner_mix_fail.py b/tests/ci_visibility/api/fake_runner_mix_fail.py index c16d661d911..13c503209a5 100644 --- a/tests/ci_visibility/api/fake_runner_mix_fail.py +++ b/tests/ci_visibility/api/fake_runner_mix_fail.py @@ -9,6 +9,7 @@ Comment lines in the test start/finish lines are there for visual distinction. """ + import json from multiprocessing import freeze_support from pathlib import Path diff --git a/tests/ci_visibility/api/fake_runner_mix_fail_itr_test_level.py b/tests/ci_visibility/api/fake_runner_mix_fail_itr_test_level.py index eabaa6abcb5..18e21f5a5a7 100644 --- a/tests/ci_visibility/api/fake_runner_mix_fail_itr_test_level.py +++ b/tests/ci_visibility/api/fake_runner_mix_fail_itr_test_level.py @@ -15,6 +15,7 @@ Comment lines in the test start/finish lines are there for visual distinction. """ + import json from multiprocessing import freeze_support from pathlib import Path diff --git a/tests/ci_visibility/api/fake_runner_mix_pass.py b/tests/ci_visibility/api/fake_runner_mix_pass.py index 4e008c85881..93dad89dda0 100644 --- a/tests/ci_visibility/api/fake_runner_mix_pass.py +++ b/tests/ci_visibility/api/fake_runner_mix_pass.py @@ -5,6 +5,7 @@ Comment lines in the test start/finish lines are there for visual distinction. """ + import json from multiprocessing import freeze_support from pathlib import Path diff --git a/tests/ci_visibility/api/test_api_fake_runners.py b/tests/ci_visibility/api/test_api_fake_runners.py index 40a7206470f..216e06c7e89 100644 --- a/tests/ci_visibility/api/test_api_fake_runners.py +++ b/tests/ci_visibility/api/test_api_fake_runners.py @@ -53,22 +53,24 @@ def test_manual_api_fake_runner_all_pass(self): self.testdir.makepyfile(fake_runner_all_pass=fake_runner_src) self.testdir.chdir() - with override_env( - _get_default_ci_env_vars( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED="false", - CI_PROJECT_DIR=str(self.testdir.tmpdir), - _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", + with ( + override_env( + _get_default_ci_env_vars( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED="false", + CI_PROJECT_DIR=str(self.testdir.tmpdir), + _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", + ), + mock_ci_env=True, ), - mock_ci_env=True, + replace_os_env=True, ), - replace_os_env=True, - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False, False), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False, False), + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): subprocess.run(["python", "fake_runner_all_pass.py"]) @@ -91,10 +93,13 @@ def test_manual_api_fake_runner_all_fail(self): ), replace_os_env=True, ): - with mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False, False), - ), mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()): + with ( + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False, False), + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), + ): subprocess.run(["python", "fake_runner_all_fail.py"]) @snapshot(ignores=SNAPSHOT_IGNORES) @@ -105,21 +110,23 @@ def test_manual_api_fake_runner_all_skip(self): self.testdir.makepyfile(fake_runner_all_skip=fake_runner_src) self.testdir.chdir() - with override_env( - _get_default_ci_env_vars( - dict( - DD_API_KEY="foobar.baz", - CI_PROJECT_DIR=str(self.testdir.tmpdir), - DD_CIVISIBILITY_AGENTLESS_ENABLED="false", - _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", - ) + with ( + override_env( + _get_default_ci_env_vars( + dict( + DD_API_KEY="foobar.baz", + CI_PROJECT_DIR=str(self.testdir.tmpdir), + DD_CIVISIBILITY_AGENTLESS_ENABLED="false", + _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", + ) + ), + replace_os_env=True, ), - replace_os_env=True, - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False, False), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False, False), + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): subprocess.run(["python", "fake_runner_all_skip.py"]) @@ -131,20 +138,23 @@ def test_manual_api_fake_runner_all_itr_skip_test_level(self): self.testdir.makepyfile(fake_runner_all_itr_skip_test_level=fake_runner_src) self.testdir.chdir() - with override_env( - _get_default_ci_env_vars( - dict( - DD_API_KEY="foobar.baz", - CI_PROJECT_DIR=str(self.testdir.tmpdir), - DD_CIVISIBILITY_AGENTLESS_ENABLED="false", - _DD_CIVISIBILITY_ITR_SUITE_MODE="false", - _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", - ) + with ( + override_env( + _get_default_ci_env_vars( + dict( + DD_API_KEY="foobar.baz", + CI_PROJECT_DIR=str(self.testdir.tmpdir), + DD_CIVISIBILITY_AGENTLESS_ENABLED="false", + _DD_CIVISIBILITY_ITR_SUITE_MODE="false", + _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", + ) + ), + replace_os_env=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False, False), ), - replace_os_env=True, - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False, False), ): subprocess.run(["python", "fake_runner_all_itr_skip_test_level.py"]) @@ -156,22 +166,26 @@ def test_manual_api_fake_runner_all_itr_skip_suite_level(self): self.testdir.makepyfile(fake_runner_all_itr_skip_suite_level=fake_runner_src) self.testdir.chdir() - with override_env( - _get_default_ci_env_vars( - dict( - DD_API_KEY="foobar.baz", - CI_PROJECT_DIR=str(self.testdir.tmpdir), - DD_CIVISIBILITY_AGENTLESS_ENABLED="false", - _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", - ) + with ( + override_env( + _get_default_ci_env_vars( + dict( + DD_API_KEY="foobar.baz", + CI_PROJECT_DIR=str(self.testdir.tmpdir), + DD_CIVISIBILITY_AGENTLESS_ENABLED="false", + _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", + ) + ), + replace_os_env=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False, False), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(itr_skipping_level=ITR_SKIPPING_LEVEL.SUITE), ), - replace_os_env=True, - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False, False), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(itr_skipping_level=ITR_SKIPPING_LEVEL.SUITE), ): subprocess.run(["python", "fake_runner_all_itr_skip_suite_level.py"]) @@ -183,21 +197,23 @@ def test_manual_api_fake_runner_mix_pass(self): self.testdir.makepyfile(fake_runner_mix_pass=fake_runner_src) self.testdir.chdir() - with override_env( - _get_default_ci_env_vars( - dict( - DD_API_KEY="foobar.baz", - CI_PROJECT_DIR=str(self.testdir.tmpdir), - DD_CIVISIBILITY_AGENTLESS_ENABLED="false", - _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", - ) + with ( + override_env( + _get_default_ci_env_vars( + dict( + DD_API_KEY="foobar.baz", + CI_PROJECT_DIR=str(self.testdir.tmpdir), + DD_CIVISIBILITY_AGENTLESS_ENABLED="false", + _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", + ) + ), + replace_os_env=True, ), - replace_os_env=True, - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False, False), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False, False), + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): subprocess.run(["python", "fake_runner_mix_pass.py"]) @@ -209,21 +225,23 @@ def test_manual_api_fake_runner_mix_fail(self): self.testdir.makepyfile(fake_runner_mix_fail=fake_runner_src) self.testdir.chdir() - with override_env( - _get_default_ci_env_vars( - dict( - DD_API_KEY="foobar.baz", - CI_PROJECT_DIR=str(self.testdir.tmpdir), - DD_CIVISIBILITY_AGENTLESS_ENABLED="false", - _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", - ) + with ( + override_env( + _get_default_ci_env_vars( + dict( + DD_API_KEY="foobar.baz", + CI_PROJECT_DIR=str(self.testdir.tmpdir), + DD_CIVISIBILITY_AGENTLESS_ENABLED="false", + _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", + ) + ), + replace_os_env=True, ), - replace_os_env=True, - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False, False), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False, False), + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): subprocess.run(["python", "fake_runner_mix_fail.py"]) @@ -235,21 +253,24 @@ def test_manual_api_fake_runner_mix_fail_itr_test_level(self): self.testdir.makepyfile(fake_runner_mix_fail_itr_test_level=fake_runner_src) self.testdir.chdir() - with override_env( - _get_default_ci_env_vars( - dict( - DD_API_KEY="foobar.baz", - CI_PROJECT_DIR=str(self.testdir.tmpdir), - DD_CIVISIBILITY_AGENTLESS_ENABLED="false", - _DD_CIVISIBILITY_ITR_SUITE_MODE="false", - _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", + with ( + override_env( + _get_default_ci_env_vars( + dict( + DD_API_KEY="foobar.baz", + CI_PROJECT_DIR=str(self.testdir.tmpdir), + DD_CIVISIBILITY_AGENTLESS_ENABLED="false", + _DD_CIVISIBILITY_ITR_SUITE_MODE="false", + _DD_CIVISIBILITY_DISABLE_EVP_PROXY="true", + ), + mock_ci_env=True, ), - mock_ci_env=True, + replace_os_env=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False, False), ), - replace_os_env=True, - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False, False), ): subprocess.run(["python", "fake_runner_mix_fail_itr_test_level.py"]) diff --git a/tests/ci_visibility/api_client/_util.py b/tests/ci_visibility/api_client/_util.py index a7e6d193921..b33760f09f3 100644 --- a/tests/ci_visibility/api_client/_util.py +++ b/tests/ci_visibility/api_client/_util.py @@ -338,7 +338,9 @@ def _get_mock_civisibility(requests_mode, suite_skipping_mode): @pytest.fixture(scope="function", autouse=True) def _test_context_manager(self): - with mock.patch("ddtrace.internal.ci_visibility._api_client.uuid4", return_value="checkoutmyuuid4"), mock.patch( - "ddtrace.internal.ci_visibility._api_client.DEFAULT_TIMEOUT", 12.34 - ), mock.patch("ddtrace.internal.ci_visibility._api_client.DEFAULT_ITR_SKIPPABLE_TIMEOUT", 43.21): + with ( + mock.patch("ddtrace.internal.ci_visibility._api_client.uuid4", return_value="checkoutmyuuid4"), + mock.patch("ddtrace.internal.ci_visibility._api_client.DEFAULT_TIMEOUT", 12.34), + mock.patch("ddtrace.internal.ci_visibility._api_client.DEFAULT_ITR_SKIPPABLE_TIMEOUT", 43.21), + ): yield diff --git a/tests/ci_visibility/api_client/test_ci_visibility_api_client.py b/tests/ci_visibility/api_client/test_ci_visibility_api_client.py index 170c77dfcbb..2e0c7b5ff1c 100644 --- a/tests/ci_visibility/api_client/test_ci_visibility_api_client.py +++ b/tests/ci_visibility/api_client/test_ci_visibility_api_client.py @@ -32,28 +32,32 @@ @contextmanager def _patch_env_for_testing(): """Patches a bunch of things to make the environment more predictable for testing""" - with _dummy_noop_git_client(), mock.patch( - "ddtrace.ext.ci._get_runtime_and_os_metadata", - return_value={ - "os.architecture": "testarch64", - "os.platform": "Not Actually Linux", - "os.version": "1.2.3-test", - "runtime.name": "CPythonTest", - "runtime.version": "1.2.3", - }, - ), mock.patch( - "ddtrace.ext.ci.tags", - return_value={ - "git.repository_url": "git@github.com:TestDog/dd-test-py.git", - "git.commit.sha": "mytestcommitsha1234", - "git.branch": "notmainbranch", - "git.commit.message": "message", - }, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(), - ), mock.patch( - "ddtrace.config._ci_visibility_agentless_enabled", True + with ( + _dummy_noop_git_client(), + mock.patch( + "ddtrace.ext.ci._get_runtime_and_os_metadata", + return_value={ + "os.architecture": "testarch64", + "os.platform": "Not Actually Linux", + "os.version": "1.2.3-test", + "runtime.name": "CPythonTest", + "runtime.version": "1.2.3", + }, + ), + mock.patch( + "ddtrace.ext.ci.tags", + return_value={ + "git.repository_url": "git@github.com:TestDog/dd-test-py.git", + "git.commit.sha": "mytestcommitsha1234", + "git.branch": "notmainbranch", + "git.commit.message": "message", + }, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(), + ), + mock.patch("ddtrace.config._ci_visibility_agentless_enabled", True), ): # Rebuild the config (yes, this is horrible) new_ddconfig = Config() @@ -487,14 +491,20 @@ def test_civisibility_api_client_evp_proxy_config_success(self, env_vars, expect _expected_config["dd_service"] = "dd-test-py" git_data = GitData("git@github.com:TestDog/dd-test-py.git", "notmainbranch", "mytestcommitsha1234", "message") - with _ci_override_env(_env_vars, full_clear=True), _patch_env_for_testing(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._agent_evp_proxy_base_url", - return_value=EVP_PROXY_AGENT_BASE_PATH, - ), mock.patch( - "ddtrace.internal.settings._agent.config.trace_agent_url", return_value="http://shouldntbeused:6218" - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddtrace.tracer._span_aggregator.writer.intake_url", - "http://patchedagenturl:6218", + with ( + _ci_override_env(_env_vars, full_clear=True), + _patch_env_for_testing(), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._agent_evp_proxy_base_url", + return_value=EVP_PROXY_AGENT_BASE_PATH, + ), + mock.patch( + "ddtrace.internal.settings._agent.config.trace_agent_url", return_value="http://shouldntbeused:6218" + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddtrace.tracer._span_aggregator.writer.intake_url", + "http://patchedagenturl:6218", + ), ): try: expected_client = EVPProxyTestVisibilityAPIClient( @@ -592,20 +602,23 @@ def test_civisibility_api_client_evp_respects_agent_default_config(self): } git_data = GitData("git@github.com:TestDog/dd-test-py.git", "notmainbranch", "mytestcommitsha1234", "message") - with _ci_override_env( - {"_DD_CIVISIBILITY_ITR_SUITE_MODE": "false"}, full_clear=True - ), _patch_env_for_testing(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._agent_evp_proxy_base_url", - return_value=EVP_PROXY_AGENT_BASE_PATH, - ), mock.patch( - "ddtrace.internal.agent.info", return_value=agent_info_response - ), mock.patch( - "ddtrace.internal.settings._agent.config.trace_agent_url", - new_callable=mock.PropertyMock, - return_value="http://shouldntbeused:6218", - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddtrace.tracer._span_aggregator.writer.intake_url", - "http://patchedagenturl:6218", + with ( + _ci_override_env({"_DD_CIVISIBILITY_ITR_SUITE_MODE": "false"}, full_clear=True), + _patch_env_for_testing(), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._agent_evp_proxy_base_url", + return_value=EVP_PROXY_AGENT_BASE_PATH, + ), + mock.patch("ddtrace.internal.agent.info", return_value=agent_info_response), + mock.patch( + "ddtrace.internal.settings._agent.config.trace_agent_url", + new_callable=mock.PropertyMock, + return_value="http://shouldntbeused:6218", + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddtrace.tracer._span_aggregator.writer.intake_url", + "http://patchedagenturl:6218", + ), ): try: expected_client = EVPProxyTestVisibilityAPIClient( diff --git a/tests/ci_visibility/api_client/test_ci_visibility_api_client_caching.py b/tests/ci_visibility/api_client/test_ci_visibility_api_client_caching.py index 1504c6128e0..7933e548a68 100644 --- a/tests/ci_visibility/api_client/test_ci_visibility_api_client_caching.py +++ b/tests/ci_visibility/api_client/test_ci_visibility_api_client_caching.py @@ -150,9 +150,10 @@ def test_first_request_makes_http_call_and_caches_response(self): expected_parsed_response = json.loads(api_response.body) # Mock _do_request to return the response without making actual HTTP call - with patch( - "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=True - ), patch.object(client, "_do_request", return_value=api_response) as mock_do_request: + with ( + patch("ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=True), + patch.object(client, "_do_request", return_value=api_response) as mock_do_request, + ): metric_names = APIRequestMetricNames( count="test.count", duration="test.duration", response_bytes=None, error="test.error" ) @@ -196,9 +197,10 @@ def test_second_request_uses_cached_response(self): expected_parsed_response = json.loads(api_response.body) # Mock _do_request to return the response without making actual HTTP call - with patch( - "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=True - ), patch.object(client, "_do_request", return_value=api_response) as mock_do_request: + with ( + patch("ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=True), + patch.object(client, "_do_request", return_value=api_response) as mock_do_request, + ): metric_names = APIRequestMetricNames( count="test.count", duration="test.duration", response_bytes=None, error="test.error" ) @@ -264,9 +266,10 @@ def test_different_requests_not_cached_together(self): expected_parsed_response2 = json.loads(response2.body) # Mock _do_request to return different responses based on payload - with patch( - "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=True - ), patch.object(client, "_do_request", side_effect=[response1, response2]) as mock_do_request: + with ( + patch("ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=True), + patch.object(client, "_do_request", side_effect=[response1, response2]) as mock_do_request, + ): metric_names = APIRequestMetricNames( count="test.count", duration="test.duration", response_bytes=None, error="test.error" ) diff --git a/tests/ci_visibility/api_client/test_ci_visibility_api_client_setting_responses.py b/tests/ci_visibility/api_client/test_ci_visibility_api_client_setting_responses.py index 582680d8c8b..7c7056f04dd 100644 --- a/tests/ci_visibility/api_client/test_ci_visibility_api_client_setting_responses.py +++ b/tests/ci_visibility/api_client/test_ci_visibility_api_client_setting_responses.py @@ -139,8 +139,10 @@ def test_civisibility_api_client_setting_parsed(self, setting_response, expected def test_civisibility_api_client_setting_errors(self, do_request_side_effect, expected_exception): """Tests that the client reports errors correctly based on the API response""" client = self._get_test_client() - with mock.patch.object(client, "_do_request", side_effect=[do_request_side_effect] * 5), pytest.raises( - expected_exception - ), mock.patch("ddtrace.internal.ci_visibility.utils.sleep"): + with ( + mock.patch.object(client, "_do_request", side_effect=[do_request_side_effect] * 5), + pytest.raises(expected_exception), + mock.patch("ddtrace.internal.ci_visibility.utils.sleep"), + ): settings = client.fetch_settings(read_from_cache=False) assert settings is None diff --git a/tests/ci_visibility/api_client/test_ci_visibility_api_client_skippable_responses.py b/tests/ci_visibility/api_client/test_ci_visibility_api_client_skippable_responses.py index da3130f54d7..982ea097b00 100644 --- a/tests/ci_visibility/api_client/test_ci_visibility_api_client_skippable_responses.py +++ b/tests/ci_visibility/api_client/test_ci_visibility_api_client_skippable_responses.py @@ -577,8 +577,9 @@ def test_civisibility_api_client_skippable_parsed_covered_files(self, skippable_ def test_civisibility_api_client_skippable_errors(self, do_request_side_effect): """Tests that the client reports errors correctly gives a None item without crashing""" client = self._get_test_client() - with mock.patch.object(client, "_do_request", side_effect=[do_request_side_effect] * 5), mock.patch( - "ddtrace.internal.utils.retry.sleep" + with ( + mock.patch.object(client, "_do_request", side_effect=[do_request_side_effect] * 5), + mock.patch("ddtrace.internal.utils.retry.sleep"), ): skippable_items = client.fetch_skippable_items(read_from_cache=False) assert skippable_items is None diff --git a/tests/ci_visibility/api_client/test_ci_visibility_api_client_test_management_responses.py b/tests/ci_visibility/api_client/test_ci_visibility_api_client_test_management_responses.py index 35911a5d951..ed57d60e2fc 100644 --- a/tests/ci_visibility/api_client/test_ci_visibility_api_client_test_management_responses.py +++ b/tests/ci_visibility/api_client/test_ci_visibility_api_client_test_management_responses.py @@ -119,8 +119,9 @@ def test_api_client_test_management_tests_parsed(self): def test_api_client_test_management_tests_errors(self, do_request_side_effect): """Tests that the client correctly handles errors in the Test Management test API response""" client = self._get_test_client() - with mock.patch.object(client, "_do_request", side_effect=[do_request_side_effect] * 5), mock.patch( - "ddtrace.internal.utils.retry.sleep" + with ( + mock.patch.object(client, "_do_request", side_effect=[do_request_side_effect] * 5), + mock.patch("ddtrace.internal.utils.retry.sleep"), ): settings = client.fetch_test_management_tests(read_from_cache=False) assert settings is None diff --git a/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py b/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py index bba65c12d4c..b0ccdec3ad9 100644 --- a/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py +++ b/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py @@ -102,8 +102,9 @@ def test_civisibility_api_client_known_tests_parsed(self, known_test_response, e def test_civisibility_api_client_known_tests_errors(self, do_request_side_effect): """Tests that the client correctly handles errors in the known test API response""" client = self._get_test_client() - with mock.patch.object(client, "_do_request", side_effect=[do_request_side_effect] * 5), mock.patch( - "ddtrace.internal.utils.retry.sleep" + with ( + mock.patch.object(client, "_do_request", side_effect=[do_request_side_effect] * 5), + mock.patch("ddtrace.internal.utils.retry.sleep"), ): settings = client.fetch_known_tests(read_from_cache=False) assert settings is None diff --git a/tests/ci_visibility/test_ci_visibility.py b/tests/ci_visibility/test_ci_visibility.py index 6ea211e4c54..21dd124ab17 100644 --- a/tests/ci_visibility/test_ci_visibility.py +++ b/tests/ci_visibility/test_ci_visibility.py @@ -108,14 +108,18 @@ def test_filters_non_test_spans(): def test_ci_visibility_service_enable(): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False), + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False), + ), ): with _patch_dummy_writer(): dummy_tracer = DummyTracer() @@ -136,16 +140,21 @@ def test_ci_visibility_service_enable(): def test_ci_visibility_service_enable_without_service(): """Test that enabling works and sets the right service when service isn't provided as a parameter to enable()""" - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder._extract_repository_name_from_url", return_value="test-repo" + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder._extract_repository_name_from_url", return_value="test-repo" + ), ): with _patch_dummy_writer(): dummy_tracer = DummyTracer() @@ -166,15 +175,17 @@ def test_ci_visibility_service_enable_without_service(): @mock.patch("ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase._do_request") def test_ci_visibility_service_enable_with_app_key_and_itr_disabled(_do_request): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_APP_KEY="foobar", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - DD_CIVISIBILITY_ITR_ENABLED="0", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_APP_KEY="foobar", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + DD_CIVISIBILITY_ITR_ENABLED="0", + ) + ), + _dummy_noop_git_client(), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): with _patch_dummy_writer(): _do_request.return_value = Response( @@ -193,14 +204,16 @@ def test_ci_visibility_service_enable_with_app_key_and_itr_disabled(_do_request) "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase._do_request", side_effect=TimeoutError ) def test_ci_visibility_service_settings_timeout(_do_request): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_APP_KEY="foobar", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_APP_KEY="foobar", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): CIVisibility.enable(service="test-service") assert CIVisibility._instance._api_settings.coverage_enabled is False @@ -212,14 +225,16 @@ def test_ci_visibility_service_settings_timeout(_do_request): "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase._do_request", side_effect=socket.timeout ) def test_ci_visibility_service_settings_socket_timeout(_do_request): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_APP_KEY="foobar", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_APP_KEY="foobar", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): CIVisibility.enable(service="test-service") assert CIVisibility._instance._api_settings.coverage_enabled is False @@ -235,14 +250,16 @@ def test_ci_visibility_service_settings_socket_timeout(_do_request): "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase._do_request", side_effect=TimeoutError ) def test_ci_visibility_service_skippable_timeout(_do_request, _check_enabled_features): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_APP_KEY="foobar", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_APP_KEY="foobar", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): CIVisibility.enable(service="test-service") assert CIVisibility._instance._itr_data is None @@ -257,14 +274,16 @@ def test_ci_visibility_service_skippable_timeout(_do_request, _check_enabled_fea "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase._do_request", side_effect=ValueError ) def test_ci_visibility_service_skippable_other_error(_do_request, _check_enabled_features): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_APP_KEY="foobar", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_APP_KEY="foobar", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): CIVisibility.enable(service="test-service") assert CIVisibility._instance._itr_data is None @@ -349,17 +368,19 @@ def test_civisibility_init_evp_proxy_versions( @mock.patch("ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase._do_request") def test_ci_visibility_service_enable_with_itr_enabled(_do_request): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip" - ), mock.patch( - "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=False - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + mock.patch("ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip"), + mock.patch( + "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=False + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): _do_request.return_value = Response( status=200, @@ -402,16 +423,19 @@ def test_ci_visibility_service_enable_with_itr_enabled(_do_request): @pytest.mark.parametrize("agentless_enabled", [False, True]) def test_ci_visibility_service_enable_with_itr_disabled_in_env(_do_request, agentless_enabled): agentless_enabled_str = "1" if agentless_enabled else "0" - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED=agentless_enabled_str, - DD_CIVISIBILITY_ITR_ENABLED="0", - ) - ), mock.patch( - "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=False - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED=agentless_enabled_str, + DD_CIVISIBILITY_ITR_ENABLED="0", + ) + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=False + ), + _dummy_noop_git_client(), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): CIVisibility.enable(service="test-service") assert CIVisibility._instance._api_settings.coverage_enabled is False @@ -423,13 +447,16 @@ def test_ci_visibility_service_enable_with_itr_disabled_in_env(_do_request, agen @mock.patch("ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase._do_request") def test_ci_visibility_service_enable_with_app_key_and_error_response(_do_request): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_APP_KEY="foobar", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - ) - ), _dummy_noop_git_client(): + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_APP_KEY="foobar", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + ): _do_request.return_value = Response( status=404, body='{"errors": ["Not found"]}', @@ -441,9 +468,12 @@ def test_ci_visibility_service_enable_with_app_key_and_error_response(_do_reques def test_ci_visibility_service_disable(): - with _ci_override_env( - dict(DD_API_KEY="foobar.baz"), - ), _dummy_noop_git_client(): + with ( + _ci_override_env( + dict(DD_API_KEY="foobar.baz"), + ), + _dummy_noop_git_client(), + ): with _patch_dummy_writer(): dummy_tracer = DummyTracer() CIVisibility.enable(tracer=dummy_tracer, service="test-service") @@ -541,8 +571,9 @@ def test_get_client_do_request_agentless_headers(): response = mock.MagicMock() response.status = 200 - with mock.patch("ddtrace.internal.http.HTTPConnection.request") as _request, mock.patch( - "ddtrace.internal.http.HTTPConnection.getresponse", return_value=response + with ( + mock.patch("ddtrace.internal.http.HTTPConnection.request") as _request, + mock.patch("ddtrace.internal.http.HTTPConnection.getresponse", return_value=response), ): CIVisibilityGitClient._do_request( REQUESTS_MODE.AGENTLESS_EVENTS, "http://base_url", "/endpoint", "payload", serializer, {} @@ -556,8 +587,9 @@ def test_get_client_do_request_evp_proxy_headers(): response = mock.MagicMock() response.status = 200 - with mock.patch("ddtrace.internal.http.HTTPConnection.request") as _request, mock.patch( - "ddtrace.internal.http.HTTPConnection.getresponse", return_value=response + with ( + mock.patch("ddtrace.internal.http.HTTPConnection.request") as _request, + mock.patch("ddtrace.internal.http.HTTPConnection.getresponse", return_value=response), ): CIVisibilityGitClient._do_request( REQUESTS_MODE.EVP_PROXY_EVENTS, "http://base_url", "/endpoint", "payload", serializer, {} @@ -676,8 +708,11 @@ def tearDown(self): def test_civisibilitywriter_agentless_url(self): with _ci_override_env(dict(DD_API_KEY="foobar.baz")): - with override_global_config({"_ci_visibility_agentless_url": "https://foo.bar"}), mock.patch( - "ddtrace.internal.ci_visibility.writer.config._ci_visibility_agentless_url", "https://foo.bar" + with ( + override_global_config({"_ci_visibility_agentless_url": "https://foo.bar"}), + mock.patch( + "ddtrace.internal.ci_visibility.writer.config._ci_visibility_agentless_url", "https://foo.bar" + ), ): dummy_writer = DummyCIVisibilityWriter() assert dummy_writer.intake_url == "https://foo.bar" @@ -715,24 +750,27 @@ def test_civisibilitywriter_coverage_agentless_with_intake_url_param(self): cov_client = dummy_writer._clients[1] assert cov_client._intake_url == "https://citestcov-intake.datadoghq.com" - with mock.patch("ddtrace.internal.writer.writer.get_connection") as _get_connection, mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + mock.patch("ddtrace.internal.writer.writer.get_connection") as _get_connection, + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): _get_connection.return_value.getresponse.return_value.status = 200 dummy_writer._put("", {}, cov_client, no_trace=True) _get_connection.assert_any_call("https://citestcov-intake.datadoghq.com", 2.0) def test_civisibilitywriter_coverage_evp_proxy_url(self): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - ) - ), mock.patch( - "ddtrace.internal.settings._agent.config.trace_agent_url", - new_callable=mock.PropertyMock, - return_value="http://arandomhost:9126", - ) as agent_url_mock, mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + ) + ), + mock.patch( + "ddtrace.internal.settings._agent.config.trace_agent_url", + new_callable=mock.PropertyMock, + return_value="http://arandomhost:9126", + ) as agent_url_mock, + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): dummy_writer = DummyCIVisibilityWriter(use_evp=True, coverage_enabled=True) @@ -748,19 +786,21 @@ def test_civisibilitywriter_coverage_evp_proxy_url(self): def test_civisibilitywriter_agentless_url_envvar(): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_URL="https://foo.bar", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False), - ), mock.patch( - "ddtrace.internal.ci_visibility.writer.config", Config() - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_URL="https://foo.bar", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False), + ), + mock.patch("ddtrace.internal.ci_visibility.writer.config", Config()), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): CIVisibility.enable() assert CIVisibility._instance._requests_mode == REQUESTS_MODE.AGENTLESS_EVENTS @@ -768,23 +808,26 @@ def test_civisibilitywriter_agentless_url_envvar(): CIVisibility.disable() def test_civisibilitywriter_evp_proxy_url(self): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - ) - ), mock.patch( - "ddtrace.internal.settings._agent.config.trace_agent_url", - new_callable=mock.PropertyMock, - return_value="http://evpproxy.bar:1234", - ), mock.patch("ddtrace.internal.settings._config.Config", _get_default_civisibility_ddconfig()), mock.patch( - "ddtrace.tracer", CIVisibilityTracer() - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._agent_evp_proxy_base_url", - return_value=EVP_PROXY_AGENT_BASE_PATH, - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility.writer.config", Config() - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + ) + ), + mock.patch( + "ddtrace.internal.settings._agent.config.trace_agent_url", + new_callable=mock.PropertyMock, + return_value="http://evpproxy.bar:1234", + ), + mock.patch("ddtrace.internal.settings._config.Config", _get_default_civisibility_ddconfig()), + mock.patch("ddtrace.tracer", CIVisibilityTracer()), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._agent_evp_proxy_base_url", + return_value=EVP_PROXY_AGENT_BASE_PATH, + ), + _dummy_noop_git_client(), + mock.patch("ddtrace.internal.ci_visibility.writer.config", Config()), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): CIVisibility.enable() assert CIVisibility._instance._requests_mode == REQUESTS_MODE.EVP_PROXY_EVENTS @@ -792,20 +835,23 @@ def test_civisibilitywriter_evp_proxy_url(self): CIVisibility.disable() def test_civisibilitywriter_only_traces(self): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - ) - ), mock.patch( - "ddtrace.internal.settings._agent.config.trace_agent_url", - new_callable=mock.PropertyMock, - return_value="http://onlytraces:1234", - ), mock.patch("ddtrace.tracer", CIVisibilityTracer()), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._agent_evp_proxy_base_url", return_value=None - ), mock.patch( - "ddtrace.internal.ci_visibility.writer.config", Config() - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + ) + ), + mock.patch( + "ddtrace.internal.settings._agent.config.trace_agent_url", + new_callable=mock.PropertyMock, + return_value="http://onlytraces:1234", + ), + mock.patch("ddtrace.tracer", CIVisibilityTracer()), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._agent_evp_proxy_base_url", return_value=None + ), + mock.patch("ddtrace.internal.ci_visibility.writer.config", Config()), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): CIVisibility.enable() assert CIVisibility._instance._requests_mode == REQUESTS_MODE.TRACES @@ -815,17 +861,20 @@ def test_civisibilitywriter_only_traces(self): def test_run_protocol_unshallow_git_ge_227(): with mock.patch("ddtrace.internal.ci_visibility.git_client.extract_git_version", return_value=(2, 27, 0)): - with mock.patch.multiple( - CIVisibilityGitClient, - _get_repository_url=mock.DEFAULT, - _is_shallow_repository=classmethod(lambda *args, **kwargs: True), - _get_latest_commits=classmethod(lambda *args, **kwwargs: ["latest1", "latest2"]), - _search_commits=classmethod(lambda *args: ["latest1", "searched1", "searched2"]), - _get_filtered_revisions=mock.DEFAULT, - _upload_packfiles=mock.DEFAULT, - ), mock.patch( - "ddtrace.internal.ci_visibility.git_client._build_git_packfiles_with_details" - ) as mock_build_packfiles: + with ( + mock.patch.multiple( + CIVisibilityGitClient, + _get_repository_url=mock.DEFAULT, + _is_shallow_repository=classmethod(lambda *args, **kwargs: True), + _get_latest_commits=classmethod(lambda *args, **kwwargs: ["latest1", "latest2"]), + _search_commits=classmethod(lambda *args: ["latest1", "searched1", "searched2"]), + _get_filtered_revisions=mock.DEFAULT, + _upload_packfiles=mock.DEFAULT, + ), + mock.patch( + "ddtrace.internal.ci_visibility.git_client._build_git_packfiles_with_details" + ) as mock_build_packfiles, + ): mock_build_packfiles.return_value.__enter__.return_value = "myprefix", _GitSubprocessDetails("", "", 10, 0) with mock.patch.object(CIVisibilityGitClient, "_unshallow_repository") as mock_unshallow_repository: CIVisibilityGitClient._run_protocol(None, None, None, multiprocessing.Value(c_int, 0)) @@ -835,17 +884,20 @@ def test_run_protocol_unshallow_git_ge_227(): def test_run_protocol_does_not_unshallow_git_lt_227(): with mock.patch("ddtrace.internal.ci_visibility.git_client.extract_git_version", return_value=(2, 26, 0)): - with mock.patch.multiple( - CIVisibilityGitClient, - _get_repository_url=mock.DEFAULT, - _is_shallow_repository=classmethod(lambda *args, **kwargs: True), - _get_latest_commits=classmethod(lambda *args, **kwargs: ["latest1", "latest2"]), - _search_commits=classmethod(lambda *args: ["latest1", "searched1", "searched2"]), - _get_filtered_revisions=mock.DEFAULT, - _upload_packfiles=mock.DEFAULT, - ), mock.patch( - "ddtrace.internal.ci_visibility.git_client._build_git_packfiles_with_details" - ) as mock_build_packfiles: + with ( + mock.patch.multiple( + CIVisibilityGitClient, + _get_repository_url=mock.DEFAULT, + _is_shallow_repository=classmethod(lambda *args, **kwargs: True), + _get_latest_commits=classmethod(lambda *args, **kwargs: ["latest1", "latest2"]), + _search_commits=classmethod(lambda *args: ["latest1", "searched1", "searched2"]), + _get_filtered_revisions=mock.DEFAULT, + _upload_packfiles=mock.DEFAULT, + ), + mock.patch( + "ddtrace.internal.ci_visibility.git_client._build_git_packfiles_with_details" + ) as mock_build_packfiles, + ): mock_build_packfiles.return_value.__enter__.return_value = "myprefix", _GitSubprocessDetails("", "", 10, 0) with mock.patch.object(CIVisibilityGitClient, "_unshallow_repository") as mock_unshallow_repository: CIVisibilityGitClient._run_protocol(None, None, None, multiprocessing.Value(c_int, 0)) @@ -869,20 +921,23 @@ class TestUploadGitMetadata: @pytest.fixture(scope="function", autouse=True) def mock_git_client(self): """NotImplementedError mocks should never be reached unless tests are set up improperly""" - with mock.patch.multiple( - CIVisibilityGitClient, - _is_shallow_repository=mock.Mock(return_value=True), - _get_latest_commits=mock.Mock( - side_effect=[["latest1", "latest2"], ["latest1", "latest2", "latest3", "latest4"]] + with ( + mock.patch.multiple( + CIVisibilityGitClient, + _is_shallow_repository=mock.Mock(return_value=True), + _get_latest_commits=mock.Mock( + side_effect=[["latest1", "latest2"], ["latest1", "latest2", "latest3", "latest4"]] + ), + _search_commits=mock.Mock(side_effect=[["latest1"], ["latest1", "latest2"]]), + _unshallow_repository=mock.Mock(), + _get_filtered_revisions=mock.Mock(return_value="latest3\nlatest4"), + _upload_packfiles=mock.Mock(side_effec=NotImplementedError), + _do_request=mock.Mock(side_effect=NotImplementedError), ), - _search_commits=mock.Mock(side_effect=[["latest1"], ["latest1", "latest2"]]), - _unshallow_repository=mock.Mock(), - _get_filtered_revisions=mock.Mock(return_value="latest3\nlatest4"), - _upload_packfiles=mock.Mock(side_effec=NotImplementedError), - _do_request=mock.Mock(side_effect=NotImplementedError), - ), mock.patch( - "ddtrace.internal.ci_visibility.git_client._build_git_packfiles_with_details" - ) as mock_build_packfiles: + mock.patch( + "ddtrace.internal.ci_visibility.git_client._build_git_packfiles_with_details" + ) as mock_build_packfiles, + ): mock_build_packfiles.return_value.__enter__.return_value = "myprefix", _GitSubprocessDetails("", "", 10, 0) yield @@ -956,12 +1011,16 @@ def test_upload_git_metadata_upload_timeout_raises_timeout(self, api_key, reques @pytest.mark.parametrize("api_key, requests_mode", api_key_requests_mode_parameters) def test_upload_git_metadata_upload_unnecessary(self, api_key, requests_mode): - with mock.patch.object( - CIVisibilityGitClient, "_get_latest_commits", mock.Mock(side_effect=[["latest1", "latest2"]]) - ), mock.patch( - "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=False - ), mock.patch.object( - CIVisibilityGitClient, "_search_commits", mock.Mock(side_effect=[["latest1", "latest2"]]) + with ( + mock.patch.object( + CIVisibilityGitClient, "_get_latest_commits", mock.Mock(side_effect=[["latest1", "latest2"]]) + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=False + ), + mock.patch.object( + CIVisibilityGitClient, "_search_commits", mock.Mock(side_effect=[["latest1", "latest2"]]) + ), ): git_client = CIVisibilityGitClient(api_key, requests_mode) git_client.upload_git_metadata() @@ -1113,55 +1172,63 @@ def test_encoder_pack_payload(): [("", "https://api.datadoghq.com"), ("https://mycustomurl.com:1234", "https://mycustomurl.com:1234")], ) def test_fetch_tests_to_skip_custom_configurations(dd_ci_visibility_agentless_url, expected_url_prefix): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - DD_CIVISIBILITY_AGENTLESS_URL=dd_ci_visibility_agentless_url, - DD_TAGS="test.configuration.disk:slow,test.configuration.memory:low", - DD_SERVICE="test-service", - DD_ENV="test-env", - ) - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(True, True, False, True), - ), mock.patch.multiple( - CIVisibilityGitClient, - _get_repository_url=classmethod(lambda *args, **kwargs: "git@github.com:TestDog/dd-test-py.git"), - _is_shallow_repository=classmethod(lambda *args, **kwargs: False), - _get_latest_commits=classmethod(lambda *args, **kwwargs: ["latest1", "latest2"]), - _search_commits=classmethod(lambda *args: ["latest1", "searched1", "searched2"]), - _get_filtered_revisions=classmethod(lambda *args, **kwargs: "revision1\nrevision2"), - _upload_packfiles=classmethod(lambda *args, **kwargs: None), - ), mock.patch( - "ddtrace.ext.ci._get_runtime_and_os_metadata", - return_value={ - "os.architecture": "testarch64", - "os.platform": "Not Actually Linux", - "os.version": "1.2.3-test", - "runtime.name": "CPythonTest", - "runtime.version": "1.2.3", - }, - ), mock.patch( - "ddtrace.ext.ci.tags", - return_value={ - "git.repository_url": "git@github.com:TestDog/dd-test-py.git", - "git.commit.sha": "mytestcommitsha1234", - }, - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase._do_request", - return_value=Response( - status=200, - body='{"data": []}', + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + DD_CIVISIBILITY_AGENTLESS_URL=dd_ci_visibility_agentless_url, + DD_TAGS="test.configuration.disk:slow,test.configuration.memory:low", + DD_SERVICE="test-service", + DD_ENV="test-env", + ) + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(True, True, False, True), + ), + mock.patch.multiple( + CIVisibilityGitClient, + _get_repository_url=classmethod(lambda *args, **kwargs: "git@github.com:TestDog/dd-test-py.git"), + _is_shallow_repository=classmethod(lambda *args, **kwargs: False), + _get_latest_commits=classmethod(lambda *args, **kwwargs: ["latest1", "latest2"]), + _search_commits=classmethod(lambda *args: ["latest1", "searched1", "searched2"]), + _get_filtered_revisions=classmethod(lambda *args, **kwargs: "revision1\nrevision2"), + _upload_packfiles=classmethod(lambda *args, **kwargs: None), + ), + mock.patch( + "ddtrace.ext.ci._get_runtime_and_os_metadata", + return_value={ + "os.architecture": "testarch64", + "os.platform": "Not Actually Linux", + "os.version": "1.2.3-test", + "runtime.name": "CPythonTest", + "runtime.version": "1.2.3", + }, + ), + mock.patch( + "ddtrace.ext.ci.tags", + return_value={ + "git.repository_url": "git@github.com:TestDog/dd-test-py.git", + "git.commit.sha": "mytestcommitsha1234", + }, + ), + _dummy_noop_git_client(), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase._do_request", + return_value=Response( + status=200, + body='{"data": []}', + ), + ) as mock_do_request, + mock.patch( + "ddtrace.internal.ci_visibility.git_client._build_git_packfiles_with_details" + ) as mock_build_packfiles, + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), + mock.patch("ddtrace.internal.ci_visibility._api_client.uuid4", return_value="checkoutmyuuid4"), + mock.patch( + "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=False ), - ) as mock_do_request, mock.patch( - "ddtrace.internal.ci_visibility.git_client._build_git_packfiles_with_details" - ) as mock_build_packfiles, mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.uuid4", return_value="checkoutmyuuid4" - ), mock.patch( - "ddtrace.internal.ci_visibility._api_responses_cache._is_response_cache_enabled", return_value=False ): mock_build_packfiles.return_value.__enter__.return_value = "myprefix", _GitSubprocessDetails("", "", 10, 0) CIVisibility.enable(service="test-service") @@ -1202,13 +1269,16 @@ def test_fetch_tests_to_skip_custom_configurations(dd_ci_visibility_agentless_ur def test_civisibility_enable_tracer_uses_partial_traces(): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() - ), mock.patch("ddtrace.internal.ci_visibility.writer.config", Config()): + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + ) + ), + _dummy_noop_git_client(), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), + mock.patch("ddtrace.internal.ci_visibility.writer.config", Config()), + ): CIVisibility.enable() assert CIVisibility._instance.tracer._span_aggregator.partial_flush_enabled is True assert CIVisibility._instance.tracer._span_aggregator.partial_flush_min_spans == 1 @@ -1216,13 +1286,16 @@ def test_civisibility_enable_tracer_uses_partial_traces(): def test_civisibility_enable_respects_passed_in_tracer(): - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() - ), mock.patch("ddtrace.internal.ci_visibility.writer.config", Config()): + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + ) + ), + _dummy_noop_git_client(), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), + mock.patch("ddtrace.internal.ci_visibility.writer.config", Config()), + ): tracer = CIVisibilityTracer() tracer._span_aggregator.partial_flush_enabled = False tracer._span_aggregator.partial_flush_min_spans = 100 @@ -1235,15 +1308,19 @@ def test_civisibility_enable_respects_passed_in_tracer(): def test_ci_visibility_service_disabled_by_dd_civisibility_enabled_false(): """Test that CI Visibility is disabled when DD_CIVISIBILITY_ENABLED is set to false.""" - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - DD_CIVISIBILITY_ENABLED="false", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False), + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + DD_CIVISIBILITY_ENABLED="false", + ) + ), + _dummy_noop_git_client(), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False), + ), ): with _patch_dummy_writer(): dummy_tracer = DummyTracer() @@ -1254,15 +1331,19 @@ def test_ci_visibility_service_disabled_by_dd_civisibility_enabled_false(): def test_ci_visibility_service_disabled_by_dd_civisibility_enabled_0(): """Test that CI Visibility is disabled when DD_CIVISIBILITY_ENABLED is set to 0.""" - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - DD_CIVISIBILITY_ENABLED="0", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False), + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + DD_CIVISIBILITY_ENABLED="0", + ) + ), + _dummy_noop_git_client(), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False), + ), ): with _patch_dummy_writer(): dummy_tracer = DummyTracer() @@ -1273,15 +1354,19 @@ def test_ci_visibility_service_disabled_by_dd_civisibility_enabled_0(): def test_ci_visibility_service_enabled_by_dd_civisibility_enabled_true(): """Test that CI Visibility is enabled when DD_CIVISIBILITY_ENABLED is set to true.""" - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - DD_CIVISIBILITY_ENABLED="true", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False), + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + DD_CIVISIBILITY_ENABLED="true", + ) + ), + _dummy_noop_git_client(), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False), + ), ): with _patch_dummy_writer(): dummy_tracer = DummyTracer() @@ -1295,15 +1380,19 @@ def test_ci_visibility_service_enabled_by_dd_civisibility_enabled_true(): def test_ci_visibility_service_enabled_by_dd_civisibility_enabled_1(): """Test that CI Visibility is enabled when DD_CIVISIBILITY_ENABLED is set to 1.""" - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - DD_CIVISIBILITY_ENABLED="1", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False), + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + DD_CIVISIBILITY_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False), + ), ): with _patch_dummy_writer(): dummy_tracer = DummyTracer() @@ -1317,14 +1406,18 @@ def test_ci_visibility_service_enabled_by_dd_civisibility_enabled_1(): def test_ci_visibility_service_enabled_by_default_when_dd_civisibility_enabled_not_set(): """Test that CI Visibility is enabled by default when DD_CIVISIBILITY_ENABLED is not set.""" - with _ci_override_env( - dict( - DD_API_KEY="foobar.baz", - DD_CIVISIBILITY_AGENTLESS_ENABLED="1", - ) - ), _dummy_noop_git_client(), mock.patch( - "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", - return_value=TestVisibilityAPISettings(False, False, False, False), + with ( + _ci_override_env( + dict( + DD_API_KEY="foobar.baz", + DD_CIVISIBILITY_AGENTLESS_ENABLED="1", + ) + ), + _dummy_noop_git_client(), + mock.patch( + "ddtrace.internal.ci_visibility._api_client._TestVisibilityAPIClientBase.fetch_settings", + return_value=TestVisibilityAPISettings(False, False, False, False), + ), ): with _patch_dummy_writer(): dummy_tracer = DummyTracer() @@ -1553,11 +1646,15 @@ def test_set_test_session_name_from_command(self): def test_set_test_session_name_from_dd_test_session_name_env_var(self): """When DD_TEST_SESSION_NAME is provided, the test session name should be its value.""" - with _ci_override_env( - dict( - DD_TEST_SESSION_NAME="the_name", - ) - ), set_up_mock_civisibility(), _patch_dummy_writer(): + with ( + _ci_override_env( + dict( + DD_TEST_SESSION_NAME="the_name", + ) + ), + set_up_mock_civisibility(), + _patch_dummy_writer(), + ): CIVisibility.enable() CIVisibility._instance.set_test_session_name(test_command="some_command") self.assert_test_session_name("the_name") @@ -1566,25 +1663,33 @@ def test_set_test_session_name_from_job_name_and_command(self): """When DD_TEST_SESSION_NAME is not provided, but a job id is, the test session name should be constructed from the job id and test command. """ - with _ci_override_env( - dict( - GITLAB_CI="1", - CI_JOB_NAME="the_job", - ) - ), set_up_mock_civisibility(), _patch_dummy_writer(): + with ( + _ci_override_env( + dict( + GITLAB_CI="1", + CI_JOB_NAME="the_job", + ) + ), + set_up_mock_civisibility(), + _patch_dummy_writer(), + ): CIVisibility.enable() CIVisibility._instance.set_test_session_name(test_command="some_command") self.assert_test_session_name("the_job-some_command") def test_set_test_session_name_from_dd_test_session_name_env_var_priority(self): """When both DD_TEST_SESSION_NAME and job id are provided, DD_TEST_SESSION_NAME wins.""" - with _ci_override_env( - dict( - GITLAB_CI="1", - CI_JOB_NAME="the_job", - DD_TEST_SESSION_NAME="the_name", - ) - ), set_up_mock_civisibility(), _patch_dummy_writer(): + with ( + _ci_override_env( + dict( + GITLAB_CI="1", + CI_JOB_NAME="the_job", + DD_TEST_SESSION_NAME="the_name", + ) + ), + set_up_mock_civisibility(), + _patch_dummy_writer(), + ): CIVisibility.enable() CIVisibility._instance.set_test_session_name(test_command="some_command") self.assert_test_session_name("the_name") diff --git a/tests/ci_visibility/util.py b/tests/ci_visibility/util.py index 3992597c544..6a2cc2cf99b 100644 --- a/tests/ci_visibility/util.py +++ b/tests/ci_visibility/util.py @@ -109,36 +109,43 @@ def _mock_upload_git_metadata(obj, **kwargs): if efd_settings is None: efd_settings = EarlyFlakeDetectionSettings() - with override_env(env_overrides), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig( - ITR_SKIPPING_LEVEL.SUITE if suite_skipping_mode else ITR_SKIPPING_LEVEL.TEST + with ( + override_env(env_overrides), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig( + ITR_SKIPPING_LEVEL.SUITE if suite_skipping_mode else ITR_SKIPPING_LEVEL.TEST + ), ), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - coverage_enabled=coverage_enabled, - skipping_enabled=skipping_enabled, - require_git=require_git, - itr_enabled=itr_enabled, - early_flake_detection=efd_settings, + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + coverage_enabled=coverage_enabled, + skipping_enabled=skipping_enabled, + require_git=require_git, + itr_enabled=itr_enabled, + early_flake_detection=efd_settings, + ), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fake_fetch_tests_to_skip, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_known_tests", + return_value=_fetch_known_tests_side_effect(known_test_ids), + ), + mock.patch.multiple( + CIVisibilityGitClient, + _get_repository_url=classmethod(lambda *args, **kwargs: "git@github.com:TestDog/dd-test-py.git"), + _is_shallow_repository=classmethod(lambda *args, **kwargs: False), + _get_latest_commits=classmethod(lambda *args, **kwwargs: ["latest1", "latest2"]), + _search_commits=classmethod(lambda *args: ["latest1", "searched1", "searched2"]), + _get_filtered_revisions=classmethod(lambda *args, **kwargs: "revision1\nrevision2"), + _upload_packfiles=classmethod(lambda *args, **kwargs: None), + upload_git_metadata=_mock_upload_git_metadata, + _do_request=NotImplementedError, ), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fake_fetch_tests_to_skip, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_known_tests", - return_value=_fetch_known_tests_side_effect(known_test_ids), - ), mock.patch.multiple( - CIVisibilityGitClient, - _get_repository_url=classmethod(lambda *args, **kwargs: "git@github.com:TestDog/dd-test-py.git"), - _is_shallow_repository=classmethod(lambda *args, **kwargs: False), - _get_latest_commits=classmethod(lambda *args, **kwwargs: ["latest1", "latest2"]), - _search_commits=classmethod(lambda *args: ["latest1", "searched1", "searched2"]), - _get_filtered_revisions=classmethod(lambda *args, **kwargs: "revision1\nrevision2"), - _upload_packfiles=classmethod(lambda *args, **kwargs: None), - upload_git_metadata=_mock_upload_git_metadata, - _do_request=NotImplementedError, ): yield diff --git a/tests/commands/ddtrace_run_patched_modules_overrides.py b/tests/commands/ddtrace_run_patched_modules_overrides.py index 7f31984677d..86f8cd212a1 100644 --- a/tests/commands/ddtrace_run_patched_modules_overrides.py +++ b/tests/commands/ddtrace_run_patched_modules_overrides.py @@ -1,24 +1,24 @@ if __name__ == "__main__": from ddtrace._monkey import _PATCHED_MODULES - assert ( - "flask" in _PATCHED_MODULES - ), "DD_PATCH_MODULES enables flask, this should override any value set by DD_TRACE_FLASK_ENABLED" + assert "flask" in _PATCHED_MODULES, ( + "DD_PATCH_MODULES enables flask, this should override any value set by DD_TRACE_FLASK_ENABLED" + ) - assert ( - "gevent" in _PATCHED_MODULES - ), "DD_PATCH_MODULES enables gevent, this should override any value set by DD_TRACE_GEVENT_ENABLED" + assert "gevent" in _PATCHED_MODULES, ( + "DD_PATCH_MODULES enables gevent, this should override any value set by DD_TRACE_GEVENT_ENABLED" + ) - assert ( - "django" not in _PATCHED_MODULES - ), "DD_PATCH_MODULES enables django, this setting should override all other configurations" + assert "django" not in _PATCHED_MODULES, ( + "DD_PATCH_MODULES enables django, this setting should override all other configurations" + ) - assert ( - "boto" in _PATCHED_MODULES - ), "DD_PATCH_MODULES disables boto, this setting should override all other configurations" + assert "boto" in _PATCHED_MODULES, ( + "DD_PATCH_MODULES disables boto, this setting should override all other configurations" + ) - assert ( - "falcon" not in _PATCHED_MODULES - ), "DD_PATCH_MODULES disables falcon, this setting override any value set by DD_TRACE_FALCON_ENABLED" + assert "falcon" not in _PATCHED_MODULES, ( + "DD_PATCH_MODULES disables falcon, this setting override any value set by DD_TRACE_FALCON_ENABLED" + ) print("Test success") diff --git a/tests/commands/test_runner.py b/tests/commands/test_runner.py index 71c11722905..c6a53873a86 100644 --- a/tests/commands/test_runner.py +++ b/tests/commands/test_runner.py @@ -529,12 +529,12 @@ def mock_unregister(func): raise AssertionError("Duplicate unregistered function: %s" % func) unregistered_funcs.add(func) - with patch("ddtrace.internal.atexit.register", side_effect=mock_register), patch( - "ddtrace.internal.atexit.unregister", side_effect=mock_unregister - ), patch("ddtrace.internal.atexit.register_on_exit_signal", side_effect=mock_register), patch( - "atexit.register", side_effect=mock_register - ), patch( - "atexit.unregister", side_effect=mock_unregister + with ( + patch("ddtrace.internal.atexit.register", side_effect=mock_register), + patch("ddtrace.internal.atexit.unregister", side_effect=mock_unregister), + patch("ddtrace.internal.atexit.register_on_exit_signal", side_effect=mock_register), + patch("atexit.register", side_effect=mock_register), + patch("atexit.unregister", side_effect=mock_unregister), ): # Create and shutdown a tracer import ddtrace.auto # noqa: F401 diff --git a/tests/contrib/aiobotocore/test.py b/tests/contrib/aiobotocore/test.py index 0fdf25414e8..d7c0f81c98d 100644 --- a/tests/contrib/aiobotocore/test.py +++ b/tests/contrib/aiobotocore/test.py @@ -402,9 +402,7 @@ async def async_test(tracer): if __name__ == "__main__": import sys sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service_name, expected_operation_name - ) + """.format(expected_service_name, expected_operation_name) env = os.environ.copy() if service_name: env["DD_SERVICE"] = service_name diff --git a/tests/contrib/aiohttp/test_middleware.py b/tests/contrib/aiohttp/test_middleware.py index e067c197685..0cf312f8718 100644 --- a/tests/contrib/aiohttp/test_middleware.py +++ b/tests/contrib/aiohttp/test_middleware.py @@ -97,9 +97,7 @@ async def async_test(app_tracer, aiohttp_client): if __name__ == "__main__": import sys sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service_name, expected_span_name - ) + """.format(expected_service_name, expected_span_name) env = os.environ.copy() if schema_version: env["DD_TRACE_SPAN_ATTRIBUTE_SCHEMA"] = schema_version diff --git a/tests/contrib/aiohttp/test_request_safety.py b/tests/contrib/aiohttp/test_request_safety.py index 5b44ed45048..c3e126449e2 100644 --- a/tests/contrib/aiohttp/test_request_safety.py +++ b/tests/contrib/aiohttp/test_request_safety.py @@ -3,6 +3,7 @@ bad traces are produced but the ``Context`` object will not leak memory. """ + import asyncio import threading from urllib import request diff --git a/tests/contrib/aredis/test_aredis.py b/tests/contrib/aredis/test_aredis.py index f374c67668a..a5b7f6c0fe7 100644 --- a/tests/contrib/aredis/test_aredis.py +++ b/tests/contrib/aredis/test_aredis.py @@ -171,9 +171,7 @@ async def test(tracer, test_spans): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service, expected_operation - ) + """.format(expected_service, expected_operation) env = os.environ.copy() if service: env["DD_SERVICE"] = service diff --git a/tests/contrib/asgi/test_asgi.py b/tests/contrib/asgi/test_asgi.py index 7284d0f08bf..11159233547 100644 --- a/tests/contrib/asgi/test_asgi.py +++ b/tests/contrib/asgi/test_asgi.py @@ -229,9 +229,7 @@ async def test(scope, tracer, test_spans): if __name__ == "__main__": import sys sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_span_name - ) + """.format(expected_span_name) env = os.environ.copy() if schema_version: env["DD_TRACE_SPAN_ATTRIBUTE_SCHEMA"] = schema_version @@ -288,9 +286,7 @@ async def test(scope, tracer, test_spans): if __name__ == "__main__": import sys sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service_name - ) + """.format(expected_service_name) env = os.environ.copy() if global_service_name: env["DD_SERVICE"] = global_service_name diff --git a/tests/contrib/asyncpg/test_asyncpg.py b/tests/contrib/asyncpg/test_asyncpg.py index 38fc9f15530..660b136bb04 100644 --- a/tests/contrib/asyncpg/test_asyncpg.py +++ b/tests/contrib/asyncpg/test_asyncpg.py @@ -463,9 +463,9 @@ def mock_func(args, kwargs, sql_pos, sql_kw, sql_with_dbm_tags): f"/*dddb='{db_name}',dddbs='postgres',dde='staging',ddh='127.0.0.1',ddps='orders-app'," "ddpv='v7343437-d7ac743'*/ " ) - assert ( - patched.call_args_list[0][0][4] == dbm_comment + create_table_query - ), f"Expected: {dbm_comment + create_table_query},\nActual: {patched.call_args_list[0][0][4]}" + assert patched.call_args_list[0][0][4] == dbm_comment + create_table_query, ( + f"Expected: {dbm_comment + create_table_query},\nActual: {patched.call_args_list[0][0][4]}" + ) @mark_asyncio @AsyncioTestCase.run_in_subprocess( @@ -500,9 +500,9 @@ def mock_func(args, kwargs, sql_pos, sql_kw, sql_with_dbm_tags): f"/*dddb='{db_name}',dddbs='service-name-override',dde='staging',ddh='127.0.0.1',ddps='orders-app'," "ddpv='v7343437-d7ac743'*/ " ) - assert ( - patched.call_args_list[0][0][4] == dbm_comment + create_table_query - ), f"Expected: {dbm_comment + create_table_query},\nActual: {patched.call_args_list[0][0][4]}" + assert patched.call_args_list[0][0][4] == dbm_comment + create_table_query, ( + f"Expected: {dbm_comment + create_table_query},\nActual: {patched.call_args_list[0][0][4]}" + ) @mark_asyncio @AsyncioTestCase.run_in_subprocess( @@ -539,9 +539,9 @@ def mock_func(args, kwargs, sql_pos, sql_kw, sql_with_dbm_tags): f"/*dddb='{db_name}',dddbs='pin-service-name-override',dde='staging',ddh='127.0.0.1',ddps='orders-app'," "ddpv='v7343437-d7ac743'*/ " ) - assert ( - patched.call_args_list[0][0][4] == dbm_comment + create_table_query - ), f"Expected: {dbm_comment + create_table_query},\nActual: {patched.call_args_list[0][0][4]}" + assert patched.call_args_list[0][0][4] == dbm_comment + create_table_query, ( + f"Expected: {dbm_comment + create_table_query},\nActual: {patched.call_args_list[0][0][4]}" + ) @mark_asyncio @AsyncioTestCase.run_in_subprocess( @@ -576,6 +576,6 @@ def mock_func(args, kwargs, sql_pos, sql_kw, sql_with_dbm_tags): f"/*dddb='{db_name}',dddbs='{db_name}',dde='staging',ddh='127.0.0.1',ddps='orders-app'," "ddpv='v7343437-d7ac743'*/ " ) - assert ( - patched.call_args_list[0][0][4] == dbm_comment + create_table_query - ), f"Expected: {dbm_comment + create_table_query},\nActual: {patched.call_args_list[0][0][4]}" + assert patched.call_args_list[0][0][4] == dbm_comment + create_table_query, ( + f"Expected: {dbm_comment + create_table_query},\nActual: {patched.call_args_list[0][0][4]}" + ) diff --git a/tests/contrib/botocore/test.py b/tests/contrib/botocore/test.py index 1cfdb2306fd..0f8e3007e8a 100644 --- a/tests/contrib/botocore/test.py +++ b/tests/contrib/botocore/test.py @@ -250,9 +250,9 @@ def test_schematized_unspecified_service_ec2_call_v1(self): spans = self.get_spans() span = spans[0] - assert ( - span.service == DEFAULT_SPAN_SERVICE_NAME - ), "Expected 'internal.schema.DEFAULT_SPAN_SERVICE_NAME' but got {}".format(span.service) + assert span.service == DEFAULT_SPAN_SERVICE_NAME, ( + "Expected 'internal.schema.DEFAULT_SPAN_SERVICE_NAME' but got {}".format(span.service) + ) assert span.name == "aws.ec2.request" @mock_dynamodb @@ -1425,8 +1425,11 @@ def _moto_compatible_encode(trace_data): @mock_sqs def _test_data_streams_sns_to_sqs(self, use_raw_delivery): # DEV: We want to mock time to ensure we only create a single bucket - with mock.patch("time.time") as mt, mock.patch( - "ddtrace.internal.datastreams.data_streams_processor", return_value=self.tracer.data_streams_processor + with ( + mock.patch("time.time") as mt, + mock.patch( + "ddtrace.internal.datastreams.data_streams_processor", return_value=self.tracer.data_streams_processor + ), ): mt.return_value = 1642544540 @@ -1518,8 +1521,11 @@ def _test_data_streams_sns_to_sqs(self, use_raw_delivery): @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_DATA_STREAMS_ENABLED="True")) def test_data_streams_sqs(self): # DEV: We want to mock time to ensure we only create a single bucket - with mock.patch("time.time") as mt, mock.patch( - "ddtrace.internal.datastreams.data_streams_processor", return_value=self.tracer.data_streams_processor + with ( + mock.patch("time.time") as mt, + mock.patch( + "ddtrace.internal.datastreams.data_streams_processor", return_value=self.tracer.data_streams_processor + ), ): mt.return_value = 1642544540 @@ -1579,8 +1585,11 @@ def test_data_streams_sqs(self): @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_DATA_STREAMS_ENABLED="True")) def test_data_streams_sqs_batch(self): # DEV: We want to mock time to ensure we only create a single bucket - with mock.patch("time.time") as mt, mock.patch( - "ddtrace.internal.datastreams.data_streams_processor", return_value=self.tracer.data_streams_processor + with ( + mock.patch("time.time") as mt, + mock.patch( + "ddtrace.internal.datastreams.data_streams_processor", return_value=self.tracer.data_streams_processor + ), ): mt.return_value = 1642544540 @@ -1659,8 +1668,11 @@ def test_data_streams_sqs_header_information(self): @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_DATA_STREAMS_ENABLED="True")) def test_data_streams_sqs_no_header(self): # DEV: We want to mock time to ensure we only create a single bucket - with mock.patch("time.time") as mt, mock.patch( - "ddtrace.internal.datastreams.data_streams_processor", return_value=self.tracer.data_streams_processor + with ( + mock.patch("time.time") as mt, + mock.patch( + "ddtrace.internal.datastreams.data_streams_processor", return_value=self.tracer.data_streams_processor + ), ): mt.return_value = 1642544540 diff --git a/tests/contrib/botocore/test_bedrock_llmobs.py b/tests/contrib/botocore/test_bedrock_llmobs.py index fd813a81a66..286de410c67 100644 --- a/tests/contrib/botocore/test_bedrock_llmobs.py +++ b/tests/contrib/botocore/test_bedrock_llmobs.py @@ -453,18 +453,21 @@ def test_llmobs_converse_prompt_caching(self, bedrock_client, request_vcr, mock_ {"cachePoint": {"type": "default"}}, ] with request_vcr.use_cassette("bedrock_converse_prompt_caching.yaml"): - _, _ = bedrock_client.converse( - **create_bedrock_converse_request( - system=large_system_content, - user_message="What is a service", - modelId="us.anthropic.claude-3-7-sonnet-20250219-v1:0", - ) - ), bedrock_client.converse( - **create_bedrock_converse_request( - system=large_system_content, - user_message="What is a ml app", - modelId="us.anthropic.claude-3-7-sonnet-20250219-v1:0", - ) + _, _ = ( + bedrock_client.converse( + **create_bedrock_converse_request( + system=large_system_content, + user_message="What is a service", + modelId="us.anthropic.claude-3-7-sonnet-20250219-v1:0", + ) + ), + bedrock_client.converse( + **create_bedrock_converse_request( + system=large_system_content, + user_message="What is a ml app", + modelId="us.anthropic.claude-3-7-sonnet-20250219-v1:0", + ) + ), ) assert len(llmobs_events) == 2 spans = mock_tracer.pop_traces() diff --git a/tests/contrib/cherrypy/test_middleware.py b/tests/contrib/cherrypy/test_middleware.py index a0f31a29a64..43357cf5150 100644 --- a/tests/contrib/cherrypy/test_middleware.py +++ b/tests/contrib/cherrypy/test_middleware.py @@ -651,9 +651,7 @@ def test(self): if __name__ == "__main__": import sys sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service_name - ) + """.format(expected_service_name) env = os.environ.copy() if schema_version: env["DD_TRACE_SPAN_ATTRIBUTE_SCHEMA"] = schema_version @@ -710,9 +708,7 @@ def test(self): if __name__ == "__main__": import sys sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_operation_name - ) + """.format(expected_operation_name) env = os.environ.copy() if schema_version: env["DD_TRACE_SPAN_ATTRIBUTE_SCHEMA"] = schema_version diff --git a/tests/contrib/django/test_django.py b/tests/contrib/django/test_django.py index 753eae11ac7..d9287703ad1 100644 --- a/tests/contrib/django/test_django.py +++ b/tests/contrib/django/test_django.py @@ -1664,9 +1664,7 @@ def test(client, test_spans): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service_name - ) + """.format(expected_service_name) env = os.environ.copy() if schema_version is not None: @@ -1714,9 +1712,7 @@ def test_schematized_default_db_service_name( assert span.span_type == "sql" assert span.get_tag("django.db.vendor") == "sqlite" assert span.get_tag("django.db.alias") == "default" - """.format( - expected_service_name - ) + """.format(expected_service_name) env = os.environ.copy() env["DD_DJANGO_INSTRUMENT_DATABASES"] = "true" @@ -1759,9 +1755,7 @@ def test(client, test_spans): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_operation_name - ) + """.format(expected_operation_name) env = os.environ.copy() if schema_version is not None: diff --git a/tests/contrib/django_hosts/views.py b/tests/contrib/django_hosts/views.py index 8b8c70f1405..64bbf1e02f1 100644 --- a/tests/contrib/django_hosts/views.py +++ b/tests/contrib/django_hosts/views.py @@ -1,6 +1,7 @@ """ Class based views used for Django tests. """ + from django.http import HttpResponse from django.views.generic import View diff --git a/tests/contrib/djangorestframework/app/settings.py b/tests/contrib/djangorestframework/app/settings.py index 2ee44e951f9..19b76762675 100644 --- a/tests/contrib/djangorestframework/app/settings.py +++ b/tests/contrib/djangorestframework/app/settings.py @@ -3,6 +3,7 @@ configuration if you need to change the default behavior of Django during tests """ + import os import django diff --git a/tests/contrib/djangorestframework/test_djangorestframework.py b/tests/contrib/djangorestframework/test_djangorestframework.py index dcc6ad49ca1..866327e297d 100644 --- a/tests/contrib/djangorestframework/test_djangorestframework.py +++ b/tests/contrib/djangorestframework/test_djangorestframework.py @@ -139,9 +139,7 @@ def test(client, test_spans): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service_name - ) + """.format(expected_service_name) env = os.environ.copy() if schema_version is not None: env["DD_TRACE_SPAN_ATTRIBUTE_SCHEMA"] = schema_version @@ -175,9 +173,7 @@ def test(client, test_spans): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_operation_name - ) + """.format(expected_operation_name) env = os.environ.copy() if schema_version is not None: env["DD_TRACE_SPAN_ATTRIBUTE_SCHEMA"] = schema_version diff --git a/tests/contrib/dogpile_cache/test_tracing.py b/tests/contrib/dogpile_cache/test_tracing.py index 6b83deaeeb3..6dff6cf7111 100644 --- a/tests/contrib/dogpile_cache/test_tracing.py +++ b/tests/contrib/dogpile_cache/test_tracing.py @@ -272,9 +272,7 @@ def test(tracer, single_cache, test_spans): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service, expected_operation - ) + """.format(expected_service, expected_operation) env = os.environ.copy() if service_override: env["DD_SERVICE"] = service_override diff --git a/tests/contrib/falcon/test_schematization.py b/tests/contrib/falcon/test_schematization.py index 438433b5dac..8698cee7e1c 100644 --- a/tests/contrib/falcon/test_schematization.py +++ b/tests/contrib/falcon/test_schematization.py @@ -40,9 +40,7 @@ def test(self, query_string="", trace_query_string=False): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service_name - ) + """.format(expected_service_name) env = os.environ.copy() if schema_version is not None: env["DD_TRACE_SPAN_ATTRIBUTE_SCHEMA"] = schema_version @@ -88,9 +86,7 @@ def test(self, query_string="", trace_query_string=False): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_operation_name - ) + """.format(expected_operation_name) env = os.environ.copy() if schema_version is not None: env["DD_TRACE_SPAN_ATTRIBUTE_SCHEMA"] = schema_version diff --git a/tests/contrib/flask/test_flask_pytest_iast.py b/tests/contrib/flask/test_flask_pytest_iast.py index f59e6944e95..fcacf6b36c9 100644 --- a/tests/contrib/flask/test_flask_pytest_iast.py +++ b/tests/contrib/flask/test_flask_pytest_iast.py @@ -3,6 +3,7 @@ This test suite is actually used as fixture in end-to-end test for pytest IAST integration. """ + import urllib.parse import pytest diff --git a/tests/contrib/flask/test_request.py b/tests/contrib/flask/test_request.py index d93571009ec..2b04522ba41 100644 --- a/tests/contrib/flask/test_request.py +++ b/tests/contrib/flask/test_request.py @@ -1170,9 +1170,7 @@ def index(): if __name__ == "__main__": import sys sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service_name - ) + """.format(expected_service_name) env = os.environ.copy() if schema_version: env["DD_TRACE_SPAN_ATTRIBUTE_SCHEMA"] = schema_version @@ -1214,9 +1212,7 @@ def index(): if __name__ == "__main__": import sys sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_operation_name - ) + """.format(expected_operation_name) env = os.environ.copy() if schema_version: env["DD_TRACE_SPAN_ATTRIBUTE_SCHEMA"] = schema_version diff --git a/tests/contrib/flask_cache/test.py b/tests/contrib/flask_cache/test.py index 6e23414eace..b9b885b63a7 100644 --- a/tests/contrib/flask_cache/test.py +++ b/tests/contrib/flask_cache/test.py @@ -412,9 +412,9 @@ def test_schematization_undefined_service_v1(self): spans = self.get_spans() for span in spans: - assert ( - span.service == DEFAULT_SPAN_SERVICE_NAME - ), "Expected service name to be 'internal.schema.DEFAULT_SEVICE_NAME' but was '{}'".format(span.service) + assert span.service == DEFAULT_SPAN_SERVICE_NAME, ( + "Expected service name to be 'internal.schema.DEFAULT_SEVICE_NAME' but was '{}'".format(span.service) + ) @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v0")) def test_schematization_operation_name_v0(self): @@ -442,6 +442,6 @@ def test_schematization_operation_name_v1(self): spans = self.get_spans() for span in spans: - assert ( - span.name == "flask_cache.command" - ), "Expected span name to be 'flask_cache.command' but was '{}'".format(span.name) + assert span.name == "flask_cache.command", ( + "Expected span name to be 'flask_cache.command' but was '{}'".format(span.name) + ) diff --git a/tests/contrib/google_adk/test_google_adk.py b/tests/contrib/google_adk/test_google_adk.py index 9cadc4aa87a..8abf47e3eb0 100644 --- a/tests/contrib/google_adk/test_google_adk.py +++ b/tests/contrib/google_adk/test_google_adk.py @@ -84,9 +84,9 @@ async def test_agent_with_tool_usage(test_runner, mock_tracer, request_vcr): assert len(runner_spans) >= 1, f"Expected Runner.run_async spans, got spans: {[s.resource for s in spans]}" tool_spans = [s for s in spans if "FunctionTool.__call_tool_async" in s.resource] - assert ( - len(tool_spans) >= 1 - ), f"Expected FunctionTool.__call_tool_async spans, got spans: {[s.resource for s in spans]}" + assert len(tool_spans) >= 1, ( + f"Expected FunctionTool.__call_tool_async spans, got spans: {[s.resource for s in spans]}" + ) runner_span = runner_spans[0] assert runner_span.name == "google_adk.request" @@ -147,9 +147,9 @@ async def test_agent_with_tool_calculation(test_runner, mock_tracer, request_vcr assert len(runner_spans) >= 1, f"Expected Runner.run_async spans, got spans: {[s.resource for s in spans]}" tool_spans = [s for s in spans if "FunctionTool.__call_tool_async" in s.resource] - assert ( - len(tool_spans) >= 1 - ), f"Expected FunctionTool.__call_tool_async spans, got spans: {[s.resource for s in spans]}" + assert len(tool_spans) >= 1, ( + f"Expected FunctionTool.__call_tool_async spans, got spans: {[s.resource for s in spans]}" + ) runner_span = runner_spans[0] assert runner_span.name == "google_adk.request" diff --git a/tests/contrib/google_genai/conftest.py b/tests/contrib/google_genai/conftest.py index eeac616d22c..efd41b24e48 100644 --- a/tests/contrib/google_genai/conftest.py +++ b/tests/contrib/google_genai/conftest.py @@ -233,8 +233,9 @@ def _fake_request(self, method, path, request_dict, http_options): mock_response.body = "{}" return mock_response - with mock_patch.object(genai.types.EmbedContentResponse, "_from_response", _fake_from_response), mock_patch.object( - genai._api_client.BaseApiClient, "request", _fake_request + with ( + mock_patch.object(genai.types.EmbedContentResponse, "_from_response", _fake_from_response), + mock_patch.object(genai._api_client.BaseApiClient, "request", _fake_request), ): yield @@ -250,7 +251,8 @@ async def _fake_async_request(self, method, path, request_dict, http_options): mock_response.body = "{}" return mock_response - with mock_patch.object(genai.types.EmbedContentResponse, "_from_response", _fake_from_response), mock_patch.object( - genai._api_client.BaseApiClient, "async_request", _fake_async_request + with ( + mock_patch.object(genai.types.EmbedContentResponse, "_from_response", _fake_from_response), + mock_patch.object(genai._api_client.BaseApiClient, "async_request", _fake_async_request), ): yield diff --git a/tests/contrib/google_genai/test_google_genai_llmobs.py b/tests/contrib/google_genai/test_google_genai_llmobs.py index 7fa2ec3b2eb..82fd030654d 100644 --- a/tests/contrib/google_genai/test_google_genai_llmobs.py +++ b/tests/contrib/google_genai/test_google_genai_llmobs.py @@ -518,8 +518,7 @@ def expected_llmobs_tool_response_span_event(span): output_messages=[ { "content": ( - "The weather in Boston is sunny with a light breeze and the temperature is " - "72 degrees Fahrenheit." + "The weather in Boston is sunny with a light breeze and the temperature is 72 degrees Fahrenheit." ), "role": "assistant", } diff --git a/tests/contrib/grpc_aio/hellostreamingworld_pb2.py b/tests/contrib/grpc_aio/hellostreamingworld_pb2.py index a017b55c76b..38fac9e0f95 100644 --- a/tests/contrib/grpc_aio/hellostreamingworld_pb2.py +++ b/tests/contrib/grpc_aio/hellostreamingworld_pb2.py @@ -2,6 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: hellostreamingworld.proto """Generated protocol buffer code.""" + from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database diff --git a/tests/contrib/grpc_aio/hellostreamingworld_pb2.pyi b/tests/contrib/grpc_aio/hellostreamingworld_pb2.pyi index 35d878e7a7e..1c64b971230 100644 --- a/tests/contrib/grpc_aio/hellostreamingworld_pb2.pyi +++ b/tests/contrib/grpc_aio/hellostreamingworld_pb2.pyi @@ -1,6 +1,8 @@ +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message -from typing import ClassVar as _ClassVar, Optional as _Optional DESCRIPTOR: _descriptor.FileDescriptor diff --git a/tests/contrib/grpc_aio/hellostreamingworld_pb2_grpc.py b/tests/contrib/grpc_aio/hellostreamingworld_pb2_grpc.py index b09944b790b..9f2e2ca38a7 100644 --- a/tests/contrib/grpc_aio/hellostreamingworld_pb2_grpc.py +++ b/tests/contrib/grpc_aio/hellostreamingworld_pb2_grpc.py @@ -1,5 +1,6 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" + import grpc from tests.contrib.grpc_aio import hellostreamingworld_pb2 as hellostreamingworld__pb2 diff --git a/tests/contrib/grpc_aio/test_grpc_aio.py b/tests/contrib/grpc_aio/test_grpc_aio.py index 793ed93f677..3b6fdcf7a60 100644 --- a/tests/contrib/grpc_aio/test_grpc_aio.py +++ b/tests/contrib/grpc_aio/test_grpc_aio.py @@ -924,9 +924,7 @@ async def test_client_streaming(server_info, tracer): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__, "--asyncio-mode=auto"])) - """.format( - expected_operation_name_format - ) + """.format(expected_operation_name_format) env = os.environ.copy() if service: env["DD_SERVICE"] = service @@ -1055,17 +1053,17 @@ async def test_async_streaming_generator(async_server_info, tracer): def test_parse_rpc_repr_string(case): try: code, details = _parse_rpc_repr_string(case["rpc_string"], grpc) - assert not case[ - "expect_error" - ], f"Test case with repr string: {case['rpc_string']} expected error but got result" - assert ( - code == case["expected_code"] - ), f"Test case with repr string: {case['rpc_string']} expected code {case['expected_code']} but got {code}" + assert not case["expect_error"], ( + f"Test case with repr string: {case['rpc_string']} expected error but got result" + ) + assert code == case["expected_code"], ( + f"Test case with repr string: {case['rpc_string']} expected code {case['expected_code']} but got {code}" + ) assert details == case["expected_details"], ( f"Test case with repr string: {case['rpc_string']} expected details {case['expected_details']} but" f"got {details}" ) except ValueError as e: - assert case[ - "expect_error" - ], f"Test case with repr string: {case['rpc_string']} did not expect error but got {e}" + assert case["expect_error"], ( + f"Test case with repr string: {case['rpc_string']} did not expect error but got {e}" + ) diff --git a/tests/contrib/gunicorn/wsgi_mw_app.py b/tests/contrib/gunicorn/wsgi_mw_app.py index f9d85166337..046067cee04 100644 --- a/tests/contrib/gunicorn/wsgi_mw_app.py +++ b/tests/contrib/gunicorn/wsgi_mw_app.py @@ -37,8 +37,7 @@ def simple_app(environ, start_response): "profiler": { # Once the scheduler is initialized, the last_export is set to a # timestamp using time.time_ns() - "is_active": bootstrap.profiler._scheduler._last_export - > 0, + "is_active": bootstrap.profiler._scheduler._last_export > 0, }, } data = json.dumps(payload).encode("utf-8") diff --git a/tests/contrib/integration_registry/test_external_dependencies.py b/tests/contrib/integration_registry/test_external_dependencies.py index 582dac89c85..71e5ef9ebe8 100644 --- a/tests/contrib/integration_registry/test_external_dependencies.py +++ b/tests/contrib/integration_registry/test_external_dependencies.py @@ -151,8 +151,7 @@ def test_external_dependencies_exist_on_pypi(registry_data: list[dict]): for dep_name in dependency_names: if not isinstance(dep_name, str) or not dep_name: errors.append( - f"External integration '{integration_name}' has invalid item in dependency_names list: " - f"{dep_name}" + f"External integration '{integration_name}' has invalid item in dependency_names list: {dep_name}" ) continue diff --git a/tests/contrib/kafka/test_kafka.py b/tests/contrib/kafka/test_kafka.py index 12cf343291e..5e21b10f96d 100644 --- a/tests/contrib/kafka/test_kafka.py +++ b/tests/contrib/kafka/test_kafka.py @@ -604,9 +604,7 @@ def test(): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - kafka_topic - ) + """.format(kafka_topic) env = os.environ.copy() env["DD_KAFKA_SERVICE"] = "my-custom-service-name" env["DD_KAFKA_EMPTY_POLL_ENABLED"] = "False" @@ -629,9 +627,7 @@ def test(): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - kafka_topic - ) + """.format(kafka_topic) env = os.environ.copy() if service: env["DD_SERVICE"] = service diff --git a/tests/contrib/kombu/test.py b/tests/contrib/kombu/test.py index 6972ac0619c..d156df2745d 100644 --- a/tests/contrib/kombu/test.py +++ b/tests/contrib/kombu/test.py @@ -220,9 +220,9 @@ def test_schematized_unspecified_service_name_v0(self): def test_schematized_unspecified_service_name_v1(self): spans = self._create_schematized_spans() for span in spans: - assert ( - span.service == DEFAULT_SPAN_SERVICE_NAME - ), "Expected internal.schema.DEFAULT_SPAN_SERVICE_NAME got {}".format(span.service) + assert span.service == DEFAULT_SPAN_SERVICE_NAME, ( + "Expected internal.schema.DEFAULT_SPAN_SERVICE_NAME got {}".format(span.service) + ) @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v0")) def test_schematized_operation_name_v0(self): diff --git a/tests/contrib/langchain/test_langchain_llmobs.py b/tests/contrib/langchain/test_langchain_llmobs.py index 970457d690f..f960d784bc8 100644 --- a/tests/contrib/langchain/test_langchain_llmobs.py +++ b/tests/contrib/langchain/test_langchain_llmobs.py @@ -871,9 +871,9 @@ def _assert_trace_structure_from_writer_call_args(self, span_kinds): for span_kind, call in zip(span_kinds, calls): call_args = call.args[0] - assert ( - call_args["meta"]["span"]["kind"] == span_kind - ), f"Span kind is {call_args['meta']['span']['kind']} but expected {span_kind}" + assert call_args["meta"]["span"]["kind"] == span_kind, ( + f"Span kind is {call_args['meta']['span']['kind']} but expected {span_kind}" + ) if span_kind == "workflow": assert len(call_args["meta"]["input"]["value"]) > 0 assert len(call_args["meta"]["output"]["value"]) > 0 diff --git a/tests/contrib/logging/test_logging.py b/tests/contrib/logging/test_logging.py index afb5b27e4a1..8d09dccfabb 100644 --- a/tests/contrib/logging/test_logging.py +++ b/tests/contrib/logging/test_logging.py @@ -118,8 +118,9 @@ def func(): span.finish() return span - with self.override_config("logging", dict(tracer=self.tracer)), self.override_global_config( - dict(_logs_injection=enabled) + with ( + self.override_config("logging", dict(tracer=self.tracer)), + self.override_global_config(dict(_logs_injection=enabled)), ): # with format string for trace info output, span = capture_function_log(func) @@ -241,8 +242,9 @@ def func(): return span for fmt, style in ((DEFAULT_FORMAT, None), (DEFAULT_FORMAT, "%"), (BRACE_FORMAT, "{")): - with self.override_config("logging", dict(tracer=self.tracer)), self.override_global_config( - dict(_logs_injection="true") + with ( + self.override_config("logging", dict(tracer=self.tracer)), + self.override_global_config(dict(_logs_injection="true")), ): output, span = capture_function_log(func, fmt=fmt, fmt_style=style) @@ -270,8 +272,9 @@ def func(): logger.info("Hello!") return span - with self.override_config("logging", dict(tracer=self.tracer)), self.override_global_config( - dict(_logs_injection="true") + with ( + self.override_config("logging", dict(tracer=self.tracer)), + self.override_global_config(dict(_logs_injection="true")), ): with pytest.raises(ValueError) as exc: _, _ = capture_function_log(func, fmt=DOLLAR_FORMAT, fmt_style="$") @@ -286,8 +289,9 @@ def test_log_strformat_style_format(self): ) formatter = logging.StrFormatStyle(fmt) - with self.override_config("logging", dict(tracer=self.tracer)), self.override_global_config( - dict(_logs_injection="true") + with ( + self.override_config("logging", dict(tracer=self.tracer)), + self.override_global_config(dict(_logs_injection="true")), ): with self.tracer.trace("test.logging") as span: record = logger.makeRecord("name", "INFO", "func", 534, "Manual log record", (), None) diff --git a/tests/contrib/openai/test_openai_llmobs.py b/tests/contrib/openai/test_openai_llmobs.py index b0e2ac84d7f..f3cefbdff8d 100644 --- a/tests/contrib/openai/test_openai_llmobs.py +++ b/tests/contrib/openai/test_openai_llmobs.py @@ -207,7 +207,9 @@ def test_completion_azure( self, openai, azure_openai_config, ddtrace_global_config, mock_llmobs_writer, mock_tracer ): prompt = "why do some languages have words that can't directly be translated to other languages?" - expected_output = '". The answer is that languages are not just a collection of words, but also a collection of cultural' # noqa: E501 + expected_output = ( + '". The answer is that languages are not just a collection of words, but also a collection of cultural' # noqa: E501 + ) with get_openai_vcr(subdirectory_name="v1").use_cassette("azure_completion.yaml"): azure_client = openai.AzureOpenAI( api_version=azure_openai_config["api_version"], @@ -241,7 +243,9 @@ async def test_completion_azure_async( self, openai, azure_openai_config, ddtrace_global_config, mock_llmobs_writer, mock_tracer ): prompt = "why do some languages have words that can't directly be translated to other languages?" - expected_output = '". The answer is that languages are not just a collection of words, but also a collection of cultural' # noqa: E501 + expected_output = ( + '". The answer is that languages are not just a collection of words, but also a collection of cultural' # noqa: E501 + ) with get_openai_vcr(subdirectory_name="v1").use_cassette("azure_completion.yaml"): azure_client = openai.AsyncAzureOpenAI( api_version=azure_openai_config["api_version"], diff --git a/tests/contrib/psycopg/test_psycopg_async.py b/tests/contrib/psycopg/test_psycopg_async.py index a21dc2d794c..37a8d9a3f0e 100644 --- a/tests/contrib/psycopg/test_psycopg_async.py +++ b/tests/contrib/psycopg/test_psycopg_async.py @@ -264,7 +264,7 @@ async def test_connection_context_execute(self): """Checks whether connection context manager works as normal.""" query = SQL("""select 'one' as x""") - async with (await psycopg.AsyncConnection.connect(**POSTGRES_CONFIG)) as conn: + async with await psycopg.AsyncConnection.connect(**POSTGRES_CONFIG) as conn: cur = await conn.execute(query) rows = await cur.fetchall() diff --git a/tests/contrib/pyodbc/test_pyodbc.py b/tests/contrib/pyodbc/test_pyodbc.py index 62597ea972c..e7e33aff8e7 100644 --- a/tests/contrib/pyodbc/test_pyodbc.py +++ b/tests/contrib/pyodbc/test_pyodbc.py @@ -335,9 +335,9 @@ def test_schematized_unspecified_service_name_v1(self): spans = tracer.pop() assert len(spans) == 1 span = spans[0] - assert ( - span.service == DEFAULT_SPAN_SERVICE_NAME - ), "Expected service name to be internal.schema.DEFAULT_SPAN_SERVICE_NAME but was '{}'".format(span.service) + assert span.service == DEFAULT_SPAN_SERVICE_NAME, ( + "Expected service name to be internal.schema.DEFAULT_SPAN_SERVICE_NAME but was '{}'".format(span.service) + ) @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc", DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v0")) def test_schematized_operation_name_v0(self): diff --git a/tests/contrib/pytest/test_coverage_per_suite.py b/tests/contrib/pytest/test_coverage_per_suite.py index 4247c56fb65..c947be48ec6 100644 --- a/tests/contrib/pytest/test_coverage_per_suite.py +++ b/tests/contrib/pytest/test_coverage_per_suite.py @@ -95,10 +95,14 @@ def test_second(): """ ) - with _ci_override_env({"DD_API_KEY": "foobar.baz", "_DD_CIVISIBILITY_ITR_SUITE_MODE": "True"}), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(True, False, False, True), - ), _mock_ddconfig_test_visibility(itr_skipping_level=ITR_SKIPPING_LEVEL.SUITE): + with ( + _ci_override_env({"DD_API_KEY": "foobar.baz", "_DD_CIVISIBILITY_ITR_SUITE_MODE": "True"}), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(True, False, False, True), + ), + _mock_ddconfig_test_visibility(itr_skipping_level=ITR_SKIPPING_LEVEL.SUITE), + ): self.inline_run( "-p", "no:randomly", @@ -190,21 +194,24 @@ def test_second(): ) ) - with _ci_override_env( - { - "DD_API_KEY": "foobar.baz", - "_DD_CIVISIBILITY_ITR_SUITE_MODE": "True", - "DD_APPLICATION_KEY": "not_an_app_key_at_all", - "DD_CIVISIBILITY_AGENTLESS_ENABLED": "True", - }, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(True, True, False, True), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), - ), _mock_ddconfig_test_visibility( - itr_skipping_level=ITR_SKIPPING_LEVEL.SUITE + with ( + _ci_override_env( + { + "DD_API_KEY": "foobar.baz", + "_DD_CIVISIBILITY_ITR_SUITE_MODE": "True", + "DD_APPLICATION_KEY": "not_an_app_key_at_all", + "DD_CIVISIBILITY_AGENTLESS_ENABLED": "True", + }, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(True, True, False, True), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), + _mock_ddconfig_test_visibility(itr_skipping_level=ITR_SKIPPING_LEVEL.SUITE), ): self.inline_run( "-p", diff --git a/tests/contrib/pytest/test_pytest.py b/tests/contrib/pytest/test_pytest.py index 3413ae55e2d..e6771ea87e9 100644 --- a/tests/contrib/pytest/test_pytest.py +++ b/tests/contrib/pytest/test_pytest.py @@ -837,7 +837,7 @@ def test_foo(): assert span.get_tag(test.SUITE) == file_name test_session_span = _get_spans_from_list(spans, "session")[0] assert test_session_span.get_tag("test.command") == ( - "pytest -p no:randomly --ddtrace --doctest-modules " "test_pytest_doctest_module.py" + "pytest -p no:randomly --ddtrace --doctest-modules test_pytest_doctest_module.py" ) def test_pytest_sets_sample_priority(self): @@ -1709,12 +1709,15 @@ def test_second(): """ ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(True, False, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(True, False, False, True), + ), ): self.inline_run( "--ddtrace", @@ -1801,15 +1804,19 @@ def test_second(): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(True, True, False, True), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(True, True, False, True), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), ): self.inline_run( "--ddtrace", @@ -1893,12 +1900,15 @@ def test_skipif_mark_true(): """ ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(True, False, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(True, False, False, True), + ), ): self.inline_run( "--ddtrace", @@ -1977,12 +1987,15 @@ def test_second(): """ ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(True, False, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(True, False, False, True), + ), ): self.inline_run( "--ddtrace", @@ -2041,12 +2054,15 @@ def test_cov(): """ ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(True, False, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(True, False, False, True), + ), ): self.inline_run( "--ddtrace", @@ -2180,18 +2196,23 @@ def test_inner_class_ok(self): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + ), ): self.inline_run("--ddtrace") @@ -2280,18 +2301,23 @@ def test_inner_ok(): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), ): self.inline_run("--ddtrace") @@ -2371,17 +2397,20 @@ def test_inner_ok(): ) ) self.testdir.chdir() - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip" - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip"), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + ), ): self.inline_run("--ddtrace") @@ -2438,19 +2467,21 @@ def test_inner_ok(): ) ) self.testdir.chdir() - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip" - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder._is_item_itr_skippable", return_value=True + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip"), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + ), + mock.patch("ddtrace.internal.ci_visibility.recorder._is_item_itr_skippable", return_value=True), ): self.inline_run("--ddtrace") @@ -2513,19 +2544,21 @@ def test_inner_ok(): ) ) self.testdir.chdir() - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip" - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_item_itr_skippable", return_value=True - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip"), + mock.patch("ddtrace.internal.ci_visibility.recorder.CIVisibility.is_item_itr_skippable", return_value=True), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + ), ): self.inline_run("--ddtrace") @@ -2605,19 +2638,21 @@ def test_inner_2(): ) self.testdir.chdir() - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip" - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_item_itr_skippable", return_value=True - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip"), + mock.patch("ddtrace.internal.ci_visibility.recorder.CIVisibility.is_item_itr_skippable", return_value=True), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + ), ): self.inline_run("--ddtrace") @@ -2634,9 +2669,9 @@ def test_inner_2(): # This is the regression test: should count tests (4), not suites (2) expected_test_count = 4 # 4 individual tests were skipped actual_count = session_span.get_metric("test.itr.tests_skipping.count") - assert ( - actual_count == expected_test_count - ), f"Expected {expected_test_count} tests skipped but got {actual_count}" + assert actual_count == expected_test_count, ( + f"Expected {expected_test_count} tests skipped but got {actual_count}" + ) # Verify all test spans were skipped by ITR skipped_test_spans = [x for x in spans if x.get_tag("test.status") == "skip" and x.get_tag("type") == "test"] @@ -2686,19 +2721,21 @@ def test_inner_2(): ) self.testdir.chdir() - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip" - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_item_itr_skippable", return_value=True - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip"), + mock.patch("ddtrace.internal.ci_visibility.recorder.CIVisibility.is_item_itr_skippable", return_value=True), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + ), ): self.inline_run("--ddtrace") @@ -2715,9 +2752,9 @@ def test_inner_2(): # This is the regression test: should count suites (2), not tests (4) expected_suite_count = 2 # 4 individual tests were skipped actual_count = session_span.get_metric("test.itr.tests_skipping.count") - assert ( - actual_count == expected_suite_count - ), f"Expected {expected_suite_count} suites skipped but got {actual_count}" + assert actual_count == expected_suite_count, ( + f"Expected {expected_suite_count} suites skipped but got {actual_count}" + ) # Verify all test spans were skipped by ITR skipped_test_spans = [x for x in spans if x.get_tag("test.status") == "skip" and x.get_tag("type") == "test"] @@ -2756,17 +2793,20 @@ def test_inner_ok(): ) ) self.testdir.chdir() - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip" - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch("ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip"), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + ), ): self.inline_run("--ddtrace") @@ -2886,15 +2926,19 @@ def test_inner_ok(): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + ), ): self.inline_run("--ddtrace") @@ -2959,12 +3003,15 @@ def test_inner_ok(): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), ): self.inline_run("--ddtrace") @@ -3052,18 +3099,23 @@ def test_inner_wasnot_going_to_skip_skipif(): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + ), ): self.inline_run("--ddtrace") @@ -3194,18 +3246,23 @@ def test_inner_wasnot_going_to_skip_skipif(): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + ), ): self.inline_run("--ddtrace") @@ -3332,18 +3389,23 @@ def test_inner_wasnot_going_to_skip_skipif(): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + ), ): self.inline_run("--ddtrace") @@ -3440,18 +3502,23 @@ def test_inner_wasnot_going_to_skip_skipif(): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + ), ): self.inline_run("--ddtrace") @@ -3582,18 +3649,23 @@ def test_inner_wasnot_going_to_skip_skipif(): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + ), ): self.inline_run("--ddtrace") @@ -3719,18 +3791,23 @@ def test_inner_wasnot_going_to_skip_skipif(): ) ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - side_effect=_fetch_test_to_skip_side_effect(_itr_data), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", - return_value=True, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + side_effect=_fetch_test_to_skip_side_effect(_itr_data), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.is_itr_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.SUITE), + ), ): self.inline_run("--ddtrace") @@ -4528,10 +4605,13 @@ def test_add_two_number_list(): ) self.testdir.chdir() - with mock.patch("ddtrace.ext.git._get_executable_path", return_value=None), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(), - ) as mock_ddconfig: + with ( + mock.patch("ddtrace.ext.git._get_executable_path", return_value=None), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(), + ) as mock_ddconfig, + ): mock_ddconfig._ci_visibility_agentless_enabled = True self.inline_run("--ddtrace") @@ -4705,30 +4785,35 @@ def test_coverage_target(): ) # Mock settings to enable ITR test-level + coverage + EFD - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - coverage_enabled=True, - itr_enabled=True, - skipping_enabled=True, - flaky_test_retries_enabled=False, - known_tests_enabled=True, # This is required for EFD to work - early_flake_detection=EarlyFlakeDetectionSettings( - enabled=True, - slow_test_retries_5s=3, - slow_test_retries_10s=2, - slow_test_retries_30s=1, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + coverage_enabled=True, + itr_enabled=True, + skipping_enabled=True, + flaky_test_retries_enabled=False, + known_tests_enabled=True, # This is required for EFD to work + early_flake_detection=EarlyFlakeDetectionSettings( + enabled=True, + slow_test_retries_5s=3, + slow_test_retries_10s=2, + slow_test_retries_30s=1, + ), ), ), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - return_value=ITRData(skippable_items=set()), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_known_tests", - return_value=set(), # All tests are new so EFD can retry them - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + return_value=ITRData(skippable_items=set()), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_known_tests", + return_value=set(), # All tests are new so EFD can retry them + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), + ), ): # Run with ITR test-level mode enabled rec = self.inline_run( @@ -4796,21 +4881,25 @@ def test_coverage_target(): ) # Mock settings to enable ITR test-level + coverage + ATR - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - coverage_enabled=True, - itr_enabled=True, - skipping_enabled=True, - flaky_test_retries_enabled=True, # Enable ATR - early_flake_detection=EarlyFlakeDetectionSettings(enabled=False), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + coverage_enabled=True, + itr_enabled=True, + skipping_enabled=True, + flaky_test_retries_enabled=True, # Enable ATR + early_flake_detection=EarlyFlakeDetectionSettings(enabled=False), + ), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + return_value=ITRData(skippable_items=set()), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), ), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - return_value=ITRData(skippable_items=set()), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), ): # Run with ITR test-level mode enabled self.inline_run( @@ -4881,21 +4970,25 @@ def test_simple(): ) # Mock settings to enable ITR test-level + coverage (no retry for simplicity) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - coverage_enabled=True, - itr_enabled=True, - skipping_enabled=True, - flaky_test_retries_enabled=False, - early_flake_detection=EarlyFlakeDetectionSettings(enabled=False), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + coverage_enabled=True, + itr_enabled=True, + skipping_enabled=True, + flaky_test_retries_enabled=False, + early_flake_detection=EarlyFlakeDetectionSettings(enabled=False), + ), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + return_value=ITRData(skippable_items=set()), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.ddconfig", + _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), ), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - return_value=ITRData(skippable_items=set()), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", - _get_default_civisibility_ddconfig(ITR_SKIPPING_LEVEL.TEST), ): # Run with ITR test-level mode enabled rec = self.inline_run( @@ -4933,28 +5026,33 @@ def test_pytest_coverage_data_format_handling_none_value(): ci_visibility_instance = mock.MagicMock(spec=CIVisibility) # Test case 1: coverage data is None - with mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._coverage_data", - {PCT_COVERED_KEY: None}, - ), mock.patch( - "ddtrace.ext.test_visibility.api.require_ci_visibility_service", - return_value=ci_visibility_instance, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", - return_value=True, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_patched", - return_value=True, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_invoked_by_coverage_run", - return_value=True, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.run_coverage_report" - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.set_covered_lines_pct" - ) as mock_set_covered_lines_pct, mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.log" - ) as mock_log: + with ( + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._coverage_data", + {PCT_COVERED_KEY: None}, + ), + mock.patch( + "ddtrace.ext.test_visibility.api.require_ci_visibility_service", + return_value=ci_visibility_instance, + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_patched", + return_value=True, + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_invoked_by_coverage_run", + return_value=True, + ), + mock.patch("ddtrace.contrib.internal.pytest._plugin_v2.run_coverage_report"), + mock.patch( + "ddtrace.internal.test_visibility.api.InternalTestSession.set_covered_lines_pct" + ) as mock_set_covered_lines_pct, + mock.patch("ddtrace.contrib.internal.pytest._plugin_v2.log") as mock_log, + ): _pytest_sessionfinish(mock_session, 0) mock_log.debug.assert_called_with("Unable to retrieve coverage data for the session span") @@ -4974,28 +5072,33 @@ def test_pytest_coverage_data_format_handling_invalid_type(): # Test case 2: coverage data is not a float (e.g., string) invalid_value = "not_a_float" - with mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._coverage_data", - {PCT_COVERED_KEY: invalid_value}, - ), mock.patch( - "ddtrace.ext.test_visibility.api.require_ci_visibility_service", - return_value=ci_visibility_instance, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", - return_value=True, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_patched", - return_value=True, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_invoked_by_coverage_run", - return_value=True, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.run_coverage_report" - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.set_covered_lines_pct" - ) as mock_set_covered_lines_pct, mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.log" - ) as mock_log: + with ( + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._coverage_data", + {PCT_COVERED_KEY: invalid_value}, + ), + mock.patch( + "ddtrace.ext.test_visibility.api.require_ci_visibility_service", + return_value=ci_visibility_instance, + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_patched", + return_value=True, + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_invoked_by_coverage_run", + return_value=True, + ), + mock.patch("ddtrace.contrib.internal.pytest._plugin_v2.run_coverage_report"), + mock.patch( + "ddtrace.internal.test_visibility.api.InternalTestSession.set_covered_lines_pct" + ) as mock_set_covered_lines_pct, + mock.patch("ddtrace.contrib.internal.pytest._plugin_v2.log") as mock_log, + ): _pytest_sessionfinish(mock_session, 0) mock_log.warning.assert_called_with( @@ -5019,27 +5122,30 @@ def test_pytest_coverage_data_format_handling_valid_values(valid_value): ci_visibility_instance = mock.MagicMock(spec=CIVisibility) - with mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._coverage_data", {PCT_COVERED_KEY: valid_value} - ), mock.patch( - "ddtrace.ext.test_visibility.api.require_ci_visibility_service", - return_value=ci_visibility_instance, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", - return_value=True, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_patched", - return_value=True, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_invoked_by_coverage_run", - return_value=True, - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.run_coverage_report" - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.set_covered_lines_pct" - ) as mock_set_covered_lines_pct, mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.log" - ) as mock_log: + with ( + mock.patch("ddtrace.contrib.internal.pytest._plugin_v2._coverage_data", {PCT_COVERED_KEY: valid_value}), + mock.patch( + "ddtrace.ext.test_visibility.api.require_ci_visibility_service", + return_value=ci_visibility_instance, + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", + return_value=True, + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_patched", + return_value=True, + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._is_coverage_invoked_by_coverage_run", + return_value=True, + ), + mock.patch("ddtrace.contrib.internal.pytest._plugin_v2.run_coverage_report"), + mock.patch( + "ddtrace.internal.test_visibility.api.InternalTestSession.set_covered_lines_pct" + ) as mock_set_covered_lines_pct, + mock.patch("ddtrace.contrib.internal.pytest._plugin_v2.log") as mock_log, + ): _pytest_sessionfinish(mock_session, 0) # No warning or debug should be called for valid case diff --git a/tests/contrib/pytest/test_pytest_atr.py b/tests/contrib/pytest/test_pytest_atr.py index e564c27181d..feb7090a55c 100644 --- a/tests/contrib/pytest/test_pytest_atr.py +++ b/tests/contrib/pytest/test_pytest_atr.py @@ -6,6 +6,7 @@ - The same known tests are used to override fetching of known tests. - The session object is patched to never be a faulty session, by default. """ + from unittest import mock from xml.etree import ElementTree @@ -169,11 +170,12 @@ def test_pytest_atr_env_var_does_not_override_api(self): self.testdir.makepyfile(test_errors=_TEST_ERRORS_CONTENT) self.testdir.makepyfile(test_pass_on_retries=_TEST_PASS_ON_RETRIES_CONTENT) self.testdir.makepyfile(test_skip=_TEST_SKIP_CONTENT) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(flaky_test_retries_enabled=False), + with ( + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(flaky_test_retries_enabled=False), + ), ): rec = self.inline_run("--ddtrace", extra_env={"DD_CIVISIBILITY_FLAKY_RETRY_ENABLED": "1"}) rec.assertoutcome(passed=3, failed=9, skipped=4) diff --git a/tests/contrib/pytest/test_pytest_attempt_to_fix.py b/tests/contrib/pytest/test_pytest_attempt_to_fix.py index 9fc76a4c0f0..311c45a5521 100644 --- a/tests/contrib/pytest/test_pytest_attempt_to_fix.py +++ b/tests/contrib/pytest/test_pytest_attempt_to_fix.py @@ -87,18 +87,21 @@ def test_flaky(): class PytestAttemptToFixTestCase(PytestTestCaseBase): @pytest.fixture(autouse=True, scope="function") def set_up_test_management(self): - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - test_management=TestManagementSettings( - enabled=True, - attempt_to_fix_retries=10, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + test_management=TestManagementSettings( + enabled=True, + attempt_to_fix_retries=10, + ), + flaky_test_retries_enabled=False, ), - flaky_test_retries_enabled=False, ), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_test_management_tests", - return_value=_TEST_PROPERTIES, + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_test_management_tests", + return_value=_TEST_PROPERTIES, + ), ): yield @@ -277,22 +280,26 @@ def set_up_test_management(self): def _mock_fetch_tests_to_skip(self, *_, **__): self._itr_data = ITRData(skippable_items={_make_fqdn_suite_id("", "test_skippable.py")}) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - test_management=TestManagementSettings( - enabled=True, - attempt_to_fix_retries=10, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + test_management=TestManagementSettings( + enabled=True, + attempt_to_fix_retries=10, + ), + skipping_enabled=True, + flaky_test_retries_enabled=False, ), - skipping_enabled=True, - flaky_test_retries_enabled=False, ), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_test_management_tests", - return_value=_TEST_PROPERTIES, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", - _mock_fetch_tests_to_skip, + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_test_management_tests", + return_value=_TEST_PROPERTIES, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_tests_to_skip", + _mock_fetch_tests_to_skip, + ), ): yield diff --git a/tests/contrib/pytest/test_pytest_coverage_edge_cases.py b/tests/contrib/pytest/test_pytest_coverage_edge_cases.py index 92331f99c3a..c479a85f02d 100644 --- a/tests/contrib/pytest/test_pytest_coverage_edge_cases.py +++ b/tests/contrib/pytest/test_pytest_coverage_edge_cases.py @@ -27,12 +27,15 @@ def test_another_one(): ) # Mock coverage collection to raise an exception - with mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._coverage_collector_get_covered_lines", - side_effect=Exception("Coverage collection failed"), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(coverage_enabled=True), + with ( + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._coverage_collector_get_covered_lines", + side_effect=Exception("Coverage collection failed"), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(coverage_enabled=True), + ), ): rec = self.inline_run("--ddtrace") @@ -139,21 +142,26 @@ def count_coverage_exit_calls(*args, **kwargs): nonlocal coverage_exit_call_count coverage_exit_call_count += 1 - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(coverage_enabled=True), - ), mock.patch( - # "ddtrace.internal.coverage.code.ModuleCodeCollector.CollectInContext.get_covered_lines", - "ddtrace.contrib.internal.pytest._plugin_v2._coverage_collector_enter", - side_effect=count_coverage_enter_calls, - ), mock.patch( - # "ddtrace.internal.coverage.code.ModuleCodeCollector.CollectInContext.get_covered_lines", - "ddtrace.contrib.internal.pytest._plugin_v2._coverage_collector_exit", - side_effect=count_coverage_exit_calls, - ), mock.patch( - # "ddtrace.internal.coverage.code.ModuleCodeCollector.CollectInContext.get_covered_lines", - "ddtrace.contrib.internal.pytest._plugin_v2._coverage_collector_get_covered_lines", - side_effect=count_coverage_lines_calls, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(coverage_enabled=True), + ), + mock.patch( + # "ddtrace.internal.coverage.code.ModuleCodeCollector.CollectInContext.get_covered_lines", + "ddtrace.contrib.internal.pytest._plugin_v2._coverage_collector_enter", + side_effect=count_coverage_enter_calls, + ), + mock.patch( + # "ddtrace.internal.coverage.code.ModuleCodeCollector.CollectInContext.get_covered_lines", + "ddtrace.contrib.internal.pytest._plugin_v2._coverage_collector_exit", + side_effect=count_coverage_exit_calls, + ), + mock.patch( + # "ddtrace.internal.coverage.code.ModuleCodeCollector.CollectInContext.get_covered_lines", + "ddtrace.contrib.internal.pytest._plugin_v2._coverage_collector_get_covered_lines", + side_effect=count_coverage_lines_calls, + ), ): rec = self.inline_run("--ddtrace") @@ -204,12 +212,15 @@ def thread_safe_coverage_handler(item, test_id, coverage_collector): } ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(coverage_enabled=True), - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._handle_collected_coverage", - side_effect=thread_safe_coverage_handler, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(coverage_enabled=True), + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._handle_collected_coverage", + side_effect=thread_safe_coverage_handler, + ), ): rec = self.inline_run("--ddtrace") @@ -217,9 +228,9 @@ def thread_safe_coverage_handler(item, test_id, coverage_collector): rec.assertoutcome(passed=3, failed=0) # Verify thread safety - should have collected coverage for each test - assert ( - len(collector_access_log) == 3 - ), f"Expected at least 3 coverage collections, got {len(collector_access_log)}" + assert len(collector_access_log) == 3, ( + f"Expected at least 3 coverage collections, got {len(collector_access_log)}" + ) # Each coverage collection should have had access to the correct collector for log_entry in collector_access_log: @@ -250,12 +261,15 @@ def count_coverage_calls(*args, **kwargs): nonlocal coverage_call_count coverage_call_count += 1 - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(coverage_enabled=True), - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._handle_collected_coverage", - side_effect=count_coverage_calls, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(coverage_enabled=True), + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._handle_collected_coverage", + side_effect=count_coverage_calls, + ), ): rec = self.inline_run("--ddtrace") @@ -330,12 +344,15 @@ def selective_failure_handler(*args, **kwargs): # Other tests should work fine return None - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(coverage_enabled=True), - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2._coverage_collector_get_covered_lines", - side_effect=selective_failure_handler, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(coverage_enabled=True), + ), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2._coverage_collector_get_covered_lines", + side_effect=selective_failure_handler, + ), ): rec = self.inline_run("--ddtrace") diff --git a/tests/contrib/pytest/test_pytest_disabling.py b/tests/contrib/pytest/test_pytest_disabling.py index c147836e134..e7619ef8c3f 100644 --- a/tests/contrib/pytest/test_pytest_disabling.py +++ b/tests/contrib/pytest/test_pytest_disabling.py @@ -1,4 +1,5 @@ """Tests Disabling functionality""" + from unittest import mock import pytest @@ -56,15 +57,18 @@ def test_pass(): class PytestDisablingTestCase(PytestTestCaseBase): @pytest.fixture(autouse=True, scope="function") def set_up_test_management(self): - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - test_management=TestManagementSettings(enabled=True), - flaky_test_retries_enabled=False, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + test_management=TestManagementSettings(enabled=True), + flaky_test_retries_enabled=False, + ), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_test_management_tests", + return_value=_TEST_PROPERTIES, ), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_test_management_tests", - return_value=_TEST_PROPERTIES, ): yield diff --git a/tests/contrib/pytest/test_pytest_efd.py b/tests/contrib/pytest/test_pytest_efd.py index 32d39a6d83e..88513a0b2f8 100644 --- a/tests/contrib/pytest/test_pytest_efd.py +++ b/tests/contrib/pytest/test_pytest_efd.py @@ -6,6 +6,7 @@ - The same known tests are used to override fetching of known tests. - The session object is patched to never be a faulty session, by default. """ + from unittest import mock from xml.etree import ElementTree @@ -108,14 +109,17 @@ def test_fails_teardown_01(fails_teardown): class PytestEFDTestCase(PytestTestCaseBase): @pytest.fixture(autouse=True, scope="function") def set_up_efd(self): - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_known_tests", - return_value=_KNOWN_TEST_IDS, - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - early_flake_detection=EarlyFlakeDetectionSettings(enabled=True, faulty_session_threshold=90), - known_tests_enabled=True, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_known_tests", + return_value=_KNOWN_TEST_IDS, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + early_flake_detection=EarlyFlakeDetectionSettings(enabled=True, faulty_session_threshold=90), + known_tests_enabled=True, + ), ), ): yield @@ -151,8 +155,9 @@ def test_pytest_efd_env_var_disables_retrying(self): self.testdir.makepyfile(test_new_pass=_TEST_NEW_PASS_CONTENT) self.testdir.makepyfile(test_new_fail=_TEST_NEW_FAIL_CONTENT) self.testdir.makepyfile(test_new_flaky=_TEST_NEW_FLAKY_CONTENT) - with override_env({"DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED": "0"}), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + override_env({"DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED": "0"}), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): rec = self.inline_run("--ddtrace") rec.assertoutcome(passed=4, failed=3) @@ -163,11 +168,15 @@ def test_pytest_efd_env_var_does_not_override_api(self): self.testdir.makepyfile(test_new_pass=_TEST_NEW_PASS_CONTENT) self.testdir.makepyfile(test_new_fail=_TEST_NEW_FAIL_CONTENT) self.testdir.makepyfile(test_new_flaky=_TEST_NEW_FLAKY_CONTENT) - with override_env({"DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED": "1"}), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(early_flake_detection=EarlyFlakeDetectionSettings(enabled=False)), + with ( + override_env({"DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED": "1"}), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + early_flake_detection=EarlyFlakeDetectionSettings(enabled=False) + ), + ), ): rec = self.inline_run("--ddtrace") rec.assertoutcome(passed=4, failed=3) @@ -281,13 +290,15 @@ def test_pytest_efd_env_var_disables_retrying_even_with_kte(self): self.testdir.makepyfile(test_known_pass=_TEST_KNOWN_PASS_CONTENT) self.testdir.makepyfile(test_new_pass=_TEST_NEW_PASS_CONTENT) self.testdir.makepyfile(test_new_flaky=_TEST_NEW_FLAKY_CONTENT) - with override_env({"DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED": "0"}), mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - early_flake_detection=EarlyFlakeDetectionSettings(enabled=True, faulty_session_threshold=90), - known_tests_enabled=True, + with ( + override_env({"DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED": "0"}), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + early_flake_detection=EarlyFlakeDetectionSettings(enabled=True, faulty_session_threshold=90), + known_tests_enabled=True, + ), ), ): rec = self.inline_run("--ddtrace") diff --git a/tests/contrib/pytest/test_pytest_quarantine.py b/tests/contrib/pytest/test_pytest_quarantine.py index cd62649a5ea..3f2c41b3911 100644 --- a/tests/contrib/pytest/test_pytest_quarantine.py +++ b/tests/contrib/pytest/test_pytest_quarantine.py @@ -6,6 +6,7 @@ - The same known tests are used to override fetching of known tests. - The session object is patched to never be a faulty session, by default. """ + from unittest import mock import pytest @@ -97,15 +98,18 @@ def test_fail_teardown(fail_teardown): class PytestQuarantineTestCase(PytestTestCaseBase): @pytest.fixture(autouse=True, scope="function") def set_up_quarantine(self): - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - test_management=TestManagementSettings(enabled=True), - flaky_test_retries_enabled=False, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + test_management=TestManagementSettings(enabled=True), + flaky_test_retries_enabled=False, + ), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_test_management_tests", + return_value=_TEST_PROPERTIES, ), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_test_management_tests", - return_value=_TEST_PROPERTIES, ): yield @@ -305,15 +309,18 @@ def test_quarantine_spans_with_atr(self): class PytestQuarantineSkippingTestCase(PytestTestCaseBase): @pytest.fixture(autouse=True, scope="function") def set_up_quarantine(self): - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings( - test_management=TestManagementSettings(enabled=True), - flaky_test_retries_enabled=False, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings( + test_management=TestManagementSettings(enabled=True), + flaky_test_retries_enabled=False, + ), + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_test_management_tests", + return_value=_TEST_PROPERTIES, ), - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._fetch_test_management_tests", - return_value=_TEST_PROPERTIES, ): yield diff --git a/tests/contrib/pytest/test_pytest_xdist_atr.py b/tests/contrib/pytest/test_pytest_xdist_atr.py index fcf64c3d77f..9beff45c98f 100644 --- a/tests/contrib/pytest/test_pytest_xdist_atr.py +++ b/tests/contrib/pytest/test_pytest_xdist_atr.py @@ -2,6 +2,7 @@ The tests in this module only validate the exit status from pytest-xdist. """ + import os # Just for the RIOT env var check from unittest import mock diff --git a/tests/contrib/pytest/test_pytest_xdist_itr.py b/tests/contrib/pytest/test_pytest_xdist_itr.py index 315cd2ff354..1d0a1bbb6ad 100644 --- a/tests/contrib/pytest/test_pytest_xdist_itr.py +++ b/tests/contrib/pytest/test_pytest_xdist_itr.py @@ -153,11 +153,15 @@ def patched_enable(cls, *args, **kwargs): test_management=TestManagementSettings(), ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", return_value=itr_settings - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=itr_settings, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), ): # note, passing -n 2 without --dist will fallback to dist=load # passing args via PYTEST_ADDOPTS env var @@ -272,11 +276,15 @@ def test_scope2_method1(self): test_management=TestManagementSettings(), ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", return_value=itr_settings - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=itr_settings, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), ): # Run with xdist using loadscope mode (suite-level skipping) rec = self.inline_run( @@ -374,11 +382,15 @@ def patched_enable(cls, *args, **kwargs): test_management=TestManagementSettings(), ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", return_value=itr_settings - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=itr_settings, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), ): # note, passing -n 2 without --dist will fallback to dist=load rec = self.inline_run( @@ -470,11 +482,15 @@ def patched_enable(cls, *args, **kwargs): test_management=TestManagementSettings(), ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", return_value=itr_settings - ), mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", - return_value=True, + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=itr_settings, + ), + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility.test_skipping_enabled", + return_value=True, + ), ): rec = self.inline_run( "--ddtrace", @@ -603,18 +619,17 @@ def test_handle_itr_should_skip_counts_skipped_tests_in_worker(self): mock_service = mock.MagicMock() mock_service._suite_skipping_mode = False # Use test-level skipping for worker count tests - with mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.is_test_skipping_enabled", return_value=True - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.is_itr_unskippable", return_value=False - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.is_attempt_to_fix", return_value=False - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.is_itr_skippable", return_value=True - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.mark_itr_skipped" - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.require_ci_visibility_service", return_value=mock_service + with ( + mock.patch( + "ddtrace.internal.test_visibility.api.InternalTestSession.is_test_skipping_enabled", return_value=True + ), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.is_itr_unskippable", return_value=False), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.is_attempt_to_fix", return_value=False), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.is_itr_skippable", return_value=True), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.mark_itr_skipped"), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2.require_ci_visibility_service", return_value=mock_service + ), ): result = _handle_itr_should_skip(mock_item, test_id) @@ -634,18 +649,17 @@ def test_handle_itr_should_skip_increments_existing_worker_count(self): mock_service = mock.MagicMock() mock_service._suite_skipping_mode = False # Use test-level skipping for worker count tests - with mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.is_test_skipping_enabled", return_value=True - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.is_itr_unskippable", return_value=False - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.is_attempt_to_fix", return_value=False - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.is_itr_skippable", return_value=True - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.mark_itr_skipped" - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.require_ci_visibility_service", return_value=mock_service + with ( + mock.patch( + "ddtrace.internal.test_visibility.api.InternalTestSession.is_test_skipping_enabled", return_value=True + ), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.is_itr_unskippable", return_value=False), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.is_attempt_to_fix", return_value=False), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.is_itr_skippable", return_value=True), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.mark_itr_skipped"), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2.require_ci_visibility_service", return_value=mock_service + ), ): result = _handle_itr_should_skip(mock_item, test_id) @@ -662,16 +676,16 @@ def test_handle_itr_should_skip_returns_false_when_not_skippable(self): mock_service = mock.MagicMock() mock_service._suite_skipping_mode = True - with mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.is_test_skipping_enabled", return_value=True - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSuite.is_itr_unskippable", return_value=False - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.is_attempt_to_fix", return_value=False - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSuite.is_itr_skippable", return_value=False - ), mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.require_ci_visibility_service", return_value=mock_service + with ( + mock.patch( + "ddtrace.internal.test_visibility.api.InternalTestSession.is_test_skipping_enabled", return_value=True + ), + mock.patch("ddtrace.internal.test_visibility.api.InternalTestSuite.is_itr_unskippable", return_value=False), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.is_attempt_to_fix", return_value=False), + mock.patch("ddtrace.internal.test_visibility.api.InternalTestSuite.is_itr_skippable", return_value=False), + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2.require_ci_visibility_service", return_value=mock_service + ), ): # Not skippable result = _handle_itr_should_skip(mock_item, test_id) @@ -689,18 +703,17 @@ def test_handle_itr_should_skip_unskippable_test_gets_forced_run(self): mock_service = mock.MagicMock() mock_service._suite_skipping_mode = True - with mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.is_test_skipping_enabled", return_value=True - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSuite.is_itr_unskippable", return_value=True - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.is_attempt_to_fix", return_value=False - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSuite.is_itr_skippable", return_value=True - ), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTest.mark_itr_forced_run" - ) as mock_forced_run, mock.patch( - "ddtrace.contrib.internal.pytest._plugin_v2.require_ci_visibility_service", return_value=mock_service + with ( + mock.patch( + "ddtrace.internal.test_visibility.api.InternalTestSession.is_test_skipping_enabled", return_value=True + ), + mock.patch("ddtrace.internal.test_visibility.api.InternalTestSuite.is_itr_unskippable", return_value=True), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.is_attempt_to_fix", return_value=False), + mock.patch("ddtrace.internal.test_visibility.api.InternalTestSuite.is_itr_skippable", return_value=True), + mock.patch("ddtrace.internal.test_visibility.api.InternalTest.mark_itr_forced_run") as mock_forced_run, + mock.patch( + "ddtrace.contrib.internal.pytest._plugin_v2.require_ci_visibility_service", return_value=mock_service + ), ): result = _handle_itr_should_skip(mock_item, test_id) @@ -754,9 +767,13 @@ def test_pytest_sessionfinish_no_aggregation_for_worker_process(self): mock_session_span = mock.MagicMock() - with mock.patch("ddtrace.ext.test_visibility.api.is_test_visibility_enabled", return_value=True), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.get_span", return_value=mock_session_span - ), mock.patch("ddtrace.internal.test_visibility.api.InternalTestSession.finish"): + with ( + mock.patch("ddtrace.ext.test_visibility.api.is_test_visibility_enabled", return_value=True), + mock.patch( + "ddtrace.internal.test_visibility.api.InternalTestSession.get_span", return_value=mock_session_span + ), + mock.patch("ddtrace.internal.test_visibility.api.InternalTestSession.finish"), + ): _pytest_sessionfinish(mock_session, 0) # Verify no ITR tags were set (worker shouldn't aggregate) @@ -779,9 +796,13 @@ def test_pytest_sessionfinish_no_aggregation_when_no_global_results(self): mock_session_span = mock.MagicMock() - with mock.patch("ddtrace.ext.test_visibility.api.is_test_visibility_enabled", return_value=True), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.get_span", return_value=mock_session_span - ), mock.patch("ddtrace.internal.test_visibility.api.InternalTestSession.finish"): + with ( + mock.patch("ddtrace.ext.test_visibility.api.is_test_visibility_enabled", return_value=True), + mock.patch( + "ddtrace.internal.test_visibility.api.InternalTestSession.get_span", return_value=mock_session_span + ), + mock.patch("ddtrace.internal.test_visibility.api.InternalTestSession.finish"), + ): _pytest_sessionfinish(mock_session, 0) # Verify no ITR tags were set (no global results to aggregate) @@ -800,9 +821,13 @@ def test_pytest_sessionfinish_no_aggregation_when_zero_skipped(self): mock_session_span = mock.MagicMock() - with mock.patch("ddtrace.ext.test_visibility.api.is_test_visibility_enabled", return_value=True), mock.patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.get_span", return_value=mock_session_span - ), mock.patch("ddtrace.internal.test_visibility.api.InternalTestSession.finish"): + with ( + mock.patch("ddtrace.ext.test_visibility.api.is_test_visibility_enabled", return_value=True), + mock.patch( + "ddtrace.internal.test_visibility.api.InternalTestSession.get_span", return_value=mock_session_span + ), + mock.patch("ddtrace.internal.test_visibility.api.InternalTestSession.finish"), + ): _pytest_sessionfinish(mock_session, 0) # Verify no ITR tags were set (zero tests skipped) @@ -1085,12 +1110,15 @@ def test_suite2_func1(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using loadscope mode result = self.inline_run( @@ -1133,12 +1161,15 @@ def test_func3(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using worksteal mode result = self.inline_run( @@ -1180,12 +1211,15 @@ def test_file2_func1(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using loadfile mode result = self.inline_run( @@ -1219,12 +1253,15 @@ def test_func(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run without xdist result = self.inline_run( @@ -1256,12 +1293,15 @@ def test_func(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist disabled (-n 0) result = self.inline_run( @@ -1310,12 +1350,15 @@ def test_group2_func1(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using loadgroup mode result = self.inline_run( @@ -1361,12 +1404,15 @@ def test_func4(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using load mode (default) result = self.inline_run( @@ -1406,12 +1452,15 @@ def test_func2(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using each mode result = self.inline_run( @@ -1454,12 +1503,15 @@ def test_func3(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist but no --dist parameter (defaults to load mode) result = self.inline_run( @@ -1500,12 +1552,15 @@ def test_func2(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using -n auto result = self.inline_run( @@ -1545,12 +1600,15 @@ def test_func2(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using -n logical result = self.inline_run( @@ -1600,12 +1658,15 @@ def test_scope2_method1(self): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using loadscope with maxprocesses result = self.inline_run( @@ -1649,12 +1710,15 @@ def test_func3(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using multiple workers (simplified from --tx option) result = self.inline_run( @@ -1708,12 +1772,15 @@ def test_complex2_method2(self): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using complex options combination result = self.inline_run( @@ -1756,12 +1823,15 @@ def test_func2(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using worksteal mode (removed rsync-dir for test compatibility) result = self.inline_run( @@ -1801,12 +1871,15 @@ def test_func2(): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using load mode (normally test-level) but explicitly set suite mode result = self.inline_run( @@ -1833,9 +1906,9 @@ def test_func2(): assert session_span.get_tag("test.itr.tests_skipping.type") == "suite" expected_suite_count = 0 # No suites skipped actual_count = session_span.get_metric("test.itr.tests_skipping.count") - assert ( - actual_count == expected_suite_count - ), f"Expected {expected_suite_count} suites skipped but got {actual_count}" + assert actual_count == expected_suite_count, ( + f"Expected {expected_suite_count} suites skipped but got {actual_count}" + ) def test_explicit_env_var_overrides_xdist_test_mode(self): """Test that explicit _DD_CIVISIBILITY_ITR_SUITE_MODE=False overrides xdist suite-level detection.""" @@ -1918,12 +1991,15 @@ def test_scope2_method1(self): """, ) - with mock.patch( - "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", - return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR - ), mock.patch( - "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", - return_value=TestVisibilityAPISettings(False, True, False, True), + with ( + mock.patch( + "ddtrace.internal.ci_visibility.recorder.CIVisibility._check_enabled_features", + return_value=TestVisibilityAPISettings(False, True, False, True), # Enable skipping and ITR + ), + mock.patch( + "ddtrace.internal.ci_visibility._api_client.AgentlessTestVisibilityAPIClient.fetch_settings", + return_value=TestVisibilityAPISettings(False, True, False, True), + ), ): # Run with xdist using loadscope mode (normally suite-level) but explicitly set test mode result = self.inline_run( diff --git a/tests/contrib/pytest/test_xdist_context_propagation.py b/tests/contrib/pytest/test_xdist_context_propagation.py index daa51f2ca3f..1b18b9b1aa9 100644 --- a/tests/contrib/pytest/test_xdist_context_propagation.py +++ b/tests/contrib/pytest/test_xdist_context_propagation.py @@ -4,6 +4,7 @@ These tests verifies that the XdistHooks class properly extracts and passes span IDs and that worker processes can create proper contexts from received span IDs. """ + from unittest.mock import MagicMock from unittest.mock import patch @@ -83,14 +84,13 @@ def test_pytest_sessionstart_extracts_context_from_valid_workerinput(): mock_session.config.workerinput = {"root_span": "54321"} # Mock all the dependencies - with patch("ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", return_value=True), patch( - "ddtrace.contrib.internal.pytest._utils._get_session_command", return_value="pytest" - ), patch("ddtrace.internal.test_visibility.api.InternalTestSession.discover"), patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.set_library_capabilities" - ), patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.start" - ) as mock_start, patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.efd_enabled", return_value=False + with ( + patch("ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", return_value=True), + patch("ddtrace.contrib.internal.pytest._utils._get_session_command", return_value="pytest"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.discover"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.set_library_capabilities"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.start") as mock_start, + patch("ddtrace.internal.test_visibility.api.InternalTestSession.efd_enabled", return_value=False), ): pytest_sessionstart(mock_session) @@ -113,14 +113,13 @@ def test_pytest_sessionstart_handles_invalid_span_id_gracefully(): mock_session.config.workerinput = {"root_span": "not_a_number"} # Mock all the dependencies - with patch("ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", return_value=True), patch( - "ddtrace.contrib.internal.pytest._utils._get_session_command", return_value="pytest" - ), patch("ddtrace.internal.test_visibility.api.InternalTestSession.discover"), patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.set_library_capabilities" - ), patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.start" - ) as mock_start, patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.efd_enabled", return_value=False + with ( + patch("ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", return_value=True), + patch("ddtrace.contrib.internal.pytest._utils._get_session_command", return_value="pytest"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.discover"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.set_library_capabilities"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.start") as mock_start, + patch("ddtrace.internal.test_visibility.api.InternalTestSession.efd_enabled", return_value=False), ): pytest_sessionstart(mock_session) @@ -148,16 +147,14 @@ def mock_hasattr(obj, name): return original_hasattr(obj, name) # Mock all the dependencies - with patch("ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", return_value=True), patch( - "ddtrace.contrib.internal.pytest._utils._get_session_command", return_value="pytest" - ), patch("ddtrace.internal.test_visibility.api.InternalTestSession.discover"), patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.set_library_capabilities" - ), patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.start" - ) as mock_start, patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.efd_enabled", return_value=False - ), patch( - "builtins.hasattr", side_effect=mock_hasattr + with ( + patch("ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", return_value=True), + patch("ddtrace.contrib.internal.pytest._utils._get_session_command", return_value="pytest"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.discover"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.set_library_capabilities"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.start") as mock_start, + patch("ddtrace.internal.test_visibility.api.InternalTestSession.efd_enabled", return_value=False), + patch("builtins.hasattr", side_effect=mock_hasattr), ): pytest_sessionstart(mock_session) @@ -187,16 +184,14 @@ def mock_hasattr(obj, name): return original_hasattr(obj, name) # Mock all the dependencies - with patch("ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", return_value=True), patch( - "ddtrace.contrib.internal.pytest._utils._get_session_command", return_value="pytest" - ), patch("ddtrace.internal.test_visibility.api.InternalTestSession.discover"), patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.set_library_capabilities" - ), patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.start" - ) as mock_start, patch( - "ddtrace.internal.test_visibility.api.InternalTestSession.efd_enabled", return_value=False - ), patch( - "builtins.hasattr", side_effect=mock_hasattr + with ( + patch("ddtrace.contrib.internal.pytest._plugin_v2.is_test_visibility_enabled", return_value=True), + patch("ddtrace.contrib.internal.pytest._utils._get_session_command", return_value="pytest"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.discover"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.set_library_capabilities"), + patch("ddtrace.internal.test_visibility.api.InternalTestSession.start") as mock_start, + patch("ddtrace.internal.test_visibility.api.InternalTestSession.efd_enabled", return_value=False), + patch("builtins.hasattr", side_effect=mock_hasattr), ): pytest_sessionstart(mock_session) diff --git a/tests/contrib/sanic/test_sanic.py b/tests/contrib/sanic/test_sanic.py index e8dc8cbd14b..5be8c8bb01c 100644 --- a/tests/contrib/sanic/test_sanic.py +++ b/tests/contrib/sanic/test_sanic.py @@ -463,9 +463,7 @@ async def test(client, integration_config, integration_http_config, test_spans): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_service_name - ) + """.format(expected_service_name) env = os.environ.copy() if schema_version is not None: @@ -515,9 +513,7 @@ async def test(client, integration_config, integration_http_config, test_spans): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_operation_name - ) + """.format(expected_operation_name) env = os.environ.copy() if schema_version is not None: diff --git a/tests/contrib/shared_tests_async.py b/tests/contrib/shared_tests_async.py index a5a45a38b29..39a73f1707c 100644 --- a/tests/contrib/shared_tests_async.py +++ b/tests/contrib/shared_tests_async.py @@ -89,7 +89,7 @@ async def _test_dbm_propagation_comment_peer_service_enabled(config, cursor, wra db_name = config["db"] dbm_comment = ( - f"/*dddb='{db_name}',dddbs='test',dde='staging',ddh='127.0.0.1',ddps='orders-app'," "ddpv='v7343437-d7ac743'*/ " + f"/*dddb='{db_name}',dddbs='test',dde='staging',ddh='127.0.0.1',ddps='orders-app',ddpv='v7343437-d7ac743'*/ " ) await _test_execute(dbm_comment, cursor, wrapped_instance) if execute_many: diff --git a/tests/contrib/structlog/test_structlog_logging.py b/tests/contrib/structlog/test_structlog_logging.py index b42e81a9fe0..1dde6b270ce 100644 --- a/tests/contrib/structlog/test_structlog_logging.py +++ b/tests/contrib/structlog/test_structlog_logging.py @@ -97,9 +97,9 @@ def test_log_injection_disabled(): output = gcf.logger.calls for key in json.loads(output[0].args[0]).keys(): - assert not key.startswith( - "dd." - ), f"Expected no dd.* keys in log output when DD_LOGS_INJECTION is False, key={key}" + assert not key.startswith("dd."), ( + f"Expected no dd.* keys in log output when DD_LOGS_INJECTION is False, key={key}" + ) def test_log_trace_global_values(): diff --git a/tests/contrib/vertexai/conftest.py b/tests/contrib/vertexai/conftest.py index 877e80e1e30..4f285fb51f6 100644 --- a/tests/contrib/vertexai/conftest.py +++ b/tests/contrib/vertexai/conftest.py @@ -76,11 +76,14 @@ def vertexai(ddtrace_global_config, ddtrace_config_vertexai, mock_client, mock_a import vertexai from vertexai.generative_models import GenerativeModel - with mock.patch.object( - GenerativeModel, "_prediction_client", new_callable=PropertyMock - ) as mock_client_property, mock.patch.object( - GenerativeModel, "_prediction_async_client", new_callable=PropertyMock - ) as mock_async_client_property: + with ( + mock.patch.object( + GenerativeModel, "_prediction_client", new_callable=PropertyMock + ) as mock_client_property, + mock.patch.object( + GenerativeModel, "_prediction_async_client", new_callable=PropertyMock + ) as mock_async_client_property, + ): mock_client_property.return_value = mock_client mock_async_client_property.return_value = mock_async_client yield vertexai diff --git a/tests/contrib/vertica/test_vertica.py b/tests/contrib/vertica/test_vertica.py index e9404efeda1..58d1283e918 100644 --- a/tests/contrib/vertica/test_vertica.py +++ b/tests/contrib/vertica/test_vertica.py @@ -42,9 +42,7 @@ def test_conn(request, test_tracer): a INT, b VARCHAR(32) ) - """.format( - TEST_TABLE - ) + """.format(TEST_TABLE) ) test_tracer.pop() @@ -282,9 +280,7 @@ def test_rowcount_oddity(self): SELECT 4, 'd' UNION ALL SELECT 5, 'e' - """.format( - TEST_TABLE - ) + """.format(TEST_TABLE) ) assert cur.rowcount == -1 @@ -493,9 +489,7 @@ def test_operation_name_v0(self): SELECT 4, 'd' UNION ALL SELECT 5, 'e' - """.format( - TEST_TABLE - ) + """.format(TEST_TABLE) ) assert cur.rowcount == -1 @@ -539,9 +533,7 @@ def test_operation_name_v1(self): SELECT 4, 'd' UNION ALL SELECT 5, 'e' - """.format( - TEST_TABLE - ) + """.format(TEST_TABLE) ) assert cur.rowcount == -1 diff --git a/tests/coverage/included_path/nsa/nsa_imports_parent.py b/tests/coverage/included_path/nsa/nsa_imports_parent.py index a1710ddc363..d3af3a3c28a 100644 --- a/tests/coverage/included_path/nsa/nsa_imports_parent.py +++ b/tests/coverage/included_path/nsa/nsa_imports_parent.py @@ -1,4 +1,5 @@ """This imports the parent package's constants""" + from ..normal_import_const import NORMAL diff --git a/tests/coverage/included_path/rpa/rpa_imports_parent.py b/tests/coverage/included_path/rpa/rpa_imports_parent.py index 9121aa9f987..91a95d71d8b 100644 --- a/tests/coverage/included_path/rpa/rpa_imports_parent.py +++ b/tests/coverage/included_path/rpa/rpa_imports_parent.py @@ -1,4 +1,5 @@ """This imports the parent package's constants""" + from ..normal_import_const import NORMAL diff --git a/tests/coverage/test_constants_import_tracking.py b/tests/coverage/test_constants_import_tracking.py index a68f5f93cb8..f8a336768fc 100644 --- a/tests/coverage/test_constants_import_tracking.py +++ b/tests/coverage/test_constants_import_tracking.py @@ -42,10 +42,12 @@ def test_constants_module_toplevel_import_tracked(): # Get coverage with and without imports covered = _get_relpath_dict( - cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=False) # type: ignore[union-attr] + cwd_path, + ModuleCodeCollector._instance._get_covered_lines(include_imported=False), # type: ignore[union-attr] ) covered_with_imports = _get_relpath_dict( - cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=True) # type: ignore[union-attr] + cwd_path, + ModuleCodeCollector._instance._get_covered_lines(include_imported=True), # type: ignore[union-attr] ) # Verify runtime coverage (without imports) @@ -65,8 +67,7 @@ def test_constants_module_toplevel_import_tracked(): # Verify it includes the constant declarations (lines 4, 5, 6) expected_constant_lines = {4, 5, 6} assert expected_constant_lines.issubset(constants_lines), ( - f"Expected constant declaration lines {expected_constant_lines} in coverage, " - f"but got: {sorted(constants_lines)}" + f"Expected constant declaration lines {expected_constant_lines} in coverage, but got: {sorted(constants_lines)}" ) @@ -101,10 +102,12 @@ def test_constants_module_dynamic_import_tracked(): # Get coverage with and without imports covered = _get_relpath_dict( - cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=False) # type: ignore[union-attr] + cwd_path, + ModuleCodeCollector._instance._get_covered_lines(include_imported=False), # type: ignore[union-attr] ) covered_with_imports = _get_relpath_dict( - cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=True) # type: ignore[union-attr] + cwd_path, + ModuleCodeCollector._instance._get_covered_lines(include_imported=True), # type: ignore[union-attr] ) # Verify runtime coverage (without imports) @@ -121,8 +124,7 @@ def test_constants_module_dynamic_import_tracked(): # Verify it includes the constant declarations (lines 4, 5) expected_constant_lines = {4, 5} assert expected_constant_lines.issubset(constants_lines), ( - f"Expected constant declaration lines {expected_constant_lines} in coverage, " - f"but got: {sorted(constants_lines)}" + f"Expected constant declaration lines {expected_constant_lines} in coverage, but got: {sorted(constants_lines)}" ) @@ -155,7 +157,8 @@ def test_constants_module_reinstrumentation(): ModuleCodeCollector.stop_coverage() first_covered_with_imports = _get_relpath_dict( - cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=True) # type: ignore[union-attr] + cwd_path, + ModuleCodeCollector._instance._get_covered_lines(include_imported=True), # type: ignore[union-attr] ) # Clear coverage to simulate new test @@ -167,16 +170,17 @@ def test_constants_module_reinstrumentation(): ModuleCodeCollector.stop_coverage() second_covered_with_imports = _get_relpath_dict( - cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=True) # type: ignore[union-attr] + cwd_path, + ModuleCodeCollector._instance._get_covered_lines(include_imported=True), # type: ignore[union-attr] ) # CRITICAL: Both collections should track the constants module - assert ( - "tests/coverage/included_path/constants_toplevel.py" in first_covered_with_imports - ), "First collection missing constants_toplevel.py" - assert ( - "tests/coverage/included_path/constants_toplevel.py" in second_covered_with_imports - ), "Second collection missing constants_toplevel.py - re-instrumentation failed for constant modules!" + assert "tests/coverage/included_path/constants_toplevel.py" in first_covered_with_imports, ( + "First collection missing constants_toplevel.py" + ) + assert "tests/coverage/included_path/constants_toplevel.py" in second_covered_with_imports, ( + "Second collection missing constants_toplevel.py - re-instrumentation failed for constant modules!" + ) # Both should have the same lines for the constants module first_constants = first_covered_with_imports["tests/coverage/included_path/constants_toplevel.py"] @@ -190,6 +194,6 @@ def test_constants_module_reinstrumentation(): # Verify the constants are actually tracked expected_lines = {4, 5, 6} - assert expected_lines.issubset( - second_constants - ), f"Expected constant lines {expected_lines} in second collection, got: {sorted(second_constants)}" + assert expected_lines.issubset(second_constants), ( + f"Expected constant lines {expected_lines} in second collection, got: {sorted(second_constants)}" + ) diff --git a/tests/coverage/test_coverage.py b/tests/coverage/test_coverage.py index 9e260c69771..cc05043a2f9 100644 --- a/tests/coverage/test_coverage.py +++ b/tests/coverage/test_coverage.py @@ -54,21 +54,21 @@ def test_coverage_import_time_lib(): if os.getenv("_DD_COVERAGE_FILE_LEVEL") == "true": # In file-level mode, we only track files, not specific line numbers - assert ( - executable.keys() == expected_executable.keys() - ), f"Executable files mismatch: expected={expected_executable.keys()} vs actual={executable.keys()}" - assert ( - covered.keys() == expected_covered.keys() - ), f"Covered files mismatch: expected={expected_covered.keys()} vs actual={covered.keys()}" + assert executable.keys() == expected_executable.keys(), ( + f"Executable files mismatch: expected={expected_executable.keys()} vs actual={executable.keys()}" + ) + assert covered.keys() == expected_covered.keys(), ( + f"Covered files mismatch: expected={expected_covered.keys()} vs actual={covered.keys()}" + ) assert covered_with_imports.keys() == expected_covered_with_imports.keys(), ( f"Covered files with imports mismatch: expected={expected_covered_with_imports.keys()}" f" vs actual={covered_with_imports.keys()}" ) else: # In full coverage mode, we track exact line numbers - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" assert covered_with_imports == expected_covered_with_imports, ( f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " @@ -119,12 +119,12 @@ def test_coverage_import_time_function(): if os.getenv("_DD_COVERAGE_FILE_LEVEL") == "true": # In file-level mode, we only track files, not specific line numbers - assert ( - lines.keys() == expected_lines.keys() - ), f"Executable files mismatch: expected={expected_lines.keys()} vs actual={lines.keys()}" - assert ( - covered.keys() == expected_covered.keys() - ), f"Covered files mismatch: expected={expected_covered.keys()} vs actual={covered.keys()}" + assert lines.keys() == expected_lines.keys(), ( + f"Executable files mismatch: expected={expected_lines.keys()} vs actual={lines.keys()}" + ) + assert covered.keys() == expected_covered.keys(), ( + f"Covered files mismatch: expected={expected_covered.keys()} vs actual={covered.keys()}" + ) assert covered_with_imports.keys() == expected_covered_with_imports.keys(), ( f"Covered files with imports mismatch: expected={expected_covered_with_imports.keys()} " f"vs actual={covered_with_imports.keys()}" diff --git a/tests/coverage/test_coverage_async.py b/tests/coverage/test_coverage_async.py index 059da55fc7d..51d50451850 100644 --- a/tests/coverage/test_coverage_async.py +++ b/tests/coverage/test_coverage_async.py @@ -42,11 +42,12 @@ def test_coverage_async_function(): "tests/coverage/included_path/async_code.py": {1, 2, 5, 6, 7, 8, 9, 10, 13, 14}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) assert line_number == 7 diff --git a/tests/coverage/test_coverage_context_reinstrumentation.py b/tests/coverage/test_coverage_context_reinstrumentation.py index ec90bd66937..76340f31a12 100644 --- a/tests/coverage/test_coverage_context_reinstrumentation.py +++ b/tests/coverage/test_coverage_context_reinstrumentation.py @@ -91,16 +91,16 @@ def test_sequential_contexts_with_no_overlap(): # In line-level mode, add critical re-instrumentation checks # Line 2 is the function body - it MUST be present in contexts that execute the function assert 2 in both_contexts_covered["tests/coverage/included_path/lib.py"], "Context 1 missing lib.py line 2" - assert ( - 2 in session_context_covered["tests/coverage/included_path/lib.py"] - ), "Context 3 missing lib.py line 2 - re-instrumentation failed!" + assert 2 in session_context_covered["tests/coverage/included_path/lib.py"], ( + "Context 3 missing lib.py line 2 - re-instrumentation failed!" + ) - assert ( - 2 in both_contexts_covered["tests/coverage/included_path/in_context_lib.py"] - ), "Context 1 missing in_context_lib.py line 2" - assert ( - 2 in context_context_covered["tests/coverage/included_path/in_context_lib.py"] - ), "Context 2 missing in_context_lib.py line 2 - re-instrumentation failed!" + assert 2 in both_contexts_covered["tests/coverage/included_path/in_context_lib.py"], ( + "Context 1 missing in_context_lib.py line 2" + ) + assert 2 in context_context_covered["tests/coverage/included_path/in_context_lib.py"], ( + "Context 2 missing in_context_lib.py line 2 - re-instrumentation failed!" + ) @pytest.mark.skipif(sys.version_info < (3, 12), reason="Test specific to Python 3.12+ monitoring API") @@ -254,14 +254,14 @@ def test_many_sequential_contexts_no_degradation(): else: # In line-level mode, check that runtime lines are present (may have import-time lines too) actual_callee = context_covered["tests/coverage/included_path/callee.py"] - assert expected_callee_runtime_lines.issubset( - actual_callee - ), f"Context {idx} missing expected callee lines: {expected_callee_runtime_lines}" + assert expected_callee_runtime_lines.issubset(actual_callee), ( + f"Context {idx} missing expected callee lines: {expected_callee_runtime_lines}" + ) # Check lib.py exists and has line 2 (the function body) - critical re-instrumentation check - assert ( - 2 in context_covered["tests/coverage/included_path/lib.py"] - ), f"Context {idx} missing lib.py line 2 - re-instrumentation failed!" + assert 2 in context_covered["tests/coverage/included_path/lib.py"], ( + f"Context {idx} missing lib.py line 2 - re-instrumentation failed!" + ) if not file_level_mode: # Critical: Coverage should not decrease over iterations @@ -344,31 +344,31 @@ def test_context_after_session_coverage(): # In line-level mode, check that expected runtime lines are present # Session may have import-time lines, so use subset check expected_session_runtime = expected_session["tests/coverage/included_path/callee.py"] - assert expected_session_runtime.issubset( - session_covered["tests/coverage/included_path/callee.py"] - ), f"Session missing expected lines: {expected_session_runtime}" + assert expected_session_runtime.issubset(session_covered["tests/coverage/included_path/callee.py"]), ( + f"Session missing expected lines: {expected_session_runtime}" + ) assert 2 in session_covered["tests/coverage/included_path/lib.py"], "Session missing lib.py line 2" # Contexts should have exact coverage expected_context_callee_runtime = expected_context["tests/coverage/included_path/callee.py"] - assert expected_context_callee_runtime.issubset( - context1_covered["tests/coverage/included_path/callee.py"] - ), f"Context 1 missing expected lines: {expected_context_callee_runtime}" + assert expected_context_callee_runtime.issubset(context1_covered["tests/coverage/included_path/callee.py"]), ( + f"Context 1 missing expected lines: {expected_context_callee_runtime}" + ) assert 2 in context1_covered["tests/coverage/included_path/lib.py"], "Context 1 missing lib.py line 2" - assert ( - 2 in context1_covered["tests/coverage/included_path/in_context_lib.py"] - ), "Context 1 missing in_context_lib.py line 2" + assert 2 in context1_covered["tests/coverage/included_path/in_context_lib.py"], ( + "Context 1 missing in_context_lib.py line 2" + ) # Context 2 is the critical re-instrumentation check - assert expected_context_callee_runtime.issubset( - context2_covered["tests/coverage/included_path/callee.py"] - ), f"Context 2 missing expected lines: {expected_context_callee_runtime}" - assert ( - 2 in context2_covered["tests/coverage/included_path/lib.py"] - ), "Context 2 missing lib.py line 2 - re-instrumentation failed!" - assert ( - 2 in context2_covered["tests/coverage/included_path/in_context_lib.py"] - ), "Context 2 missing in_context_lib.py line 2 - re-instrumentation failed!" + assert expected_context_callee_runtime.issubset(context2_covered["tests/coverage/included_path/callee.py"]), ( + f"Context 2 missing expected lines: {expected_context_callee_runtime}" + ) + assert 2 in context2_covered["tests/coverage/included_path/lib.py"], ( + "Context 2 missing lib.py line 2 - re-instrumentation failed!" + ) + assert 2 in context2_covered["tests/coverage/included_path/in_context_lib.py"], ( + "Context 2 missing in_context_lib.py line 2 - re-instrumentation failed!" + ) @pytest.mark.skipif(sys.version_info < (3, 12), reason="Test specific to Python 3.12+ monitoring API") diff --git a/tests/coverage/test_coverage_relative_namespace_packages.py b/tests/coverage/test_coverage_relative_namespace_packages.py index 787aa569739..9fef582d837 100644 --- a/tests/coverage/test_coverage_relative_namespace_packages.py +++ b/tests/coverage/test_coverage_relative_namespace_packages.py @@ -23,6 +23,7 @@ def test_coverage_namespace_package_import_normal(): imports_ns_dot_normal() ModuleCodeCollector.stop_coverage() + assert ModuleCodeCollector._instance is not None executable = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance.lines) covered = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=False)) covered_with_imports = _get_relpath_dict( @@ -47,13 +48,14 @@ def test_coverage_namespace_package_import_normal(): "tests/coverage/included_path/nsb/normal_import_const.py": {1}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) @pytest.mark.subprocess @@ -78,6 +80,7 @@ def test_coverage_namespace_package_import_late(): imports_ns_dot_late() ModuleCodeCollector.stop_coverage() + assert ModuleCodeCollector._instance is not None executable = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance.lines) covered = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=False)) covered_with_imports = _get_relpath_dict( @@ -117,13 +120,14 @@ def test_coverage_namespace_package_import_late(): "tests/coverage/included_path/nsb/normal_import_const.py": {1}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) @pytest.mark.subprocess @@ -148,6 +152,7 @@ def test_coverage_namespace_package_nsa_import_parent_normal(): nsa_imports_parent_normal() ModuleCodeCollector.stop_coverage() + assert ModuleCodeCollector._instance is not None executable = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance.lines) covered = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=False)) covered_with_imports = _get_relpath_dict( @@ -156,23 +161,24 @@ def test_coverage_namespace_package_nsa_import_parent_normal(): expected_executable = { "tests/coverage/included_path/normal_import_const.py": {1}, - "tests/coverage/included_path/nsa/nsa_imports_parent.py": {1, 2, 5, 6, 9, 10, 12}, + "tests/coverage/included_path/nsa/nsa_imports_parent.py": {1, 3, 6, 7, 10, 11, 13}, } expected_covered = { - "tests/coverage/included_path/nsa/nsa_imports_parent.py": {6}, + "tests/coverage/included_path/nsa/nsa_imports_parent.py": {7}, } expected_covered_with_imports = { "tests/coverage/included_path/normal_import_const.py": {1}, - "tests/coverage/included_path/nsa/nsa_imports_parent.py": {1, 2, 5, 6, 9}, + "tests/coverage/included_path/nsa/nsa_imports_parent.py": {1, 3, 6, 7, 10}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) @pytest.mark.subprocess @@ -197,6 +203,7 @@ def test_coverage_namespace_package_nsa_import_parent_late(): nsa_imports_parent_late() ModuleCodeCollector.stop_coverage() + assert ModuleCodeCollector._instance is not None executable = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance.lines) covered = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=False)) covered_with_imports = _get_relpath_dict( @@ -206,25 +213,26 @@ def test_coverage_namespace_package_nsa_import_parent_late(): expected_executable = { "tests/coverage/included_path/late_import_const.py": {1}, "tests/coverage/included_path/normal_import_const.py": {1}, - "tests/coverage/included_path/nsa/nsa_imports_parent.py": {1, 2, 5, 6, 9, 10, 12}, + "tests/coverage/included_path/nsa/nsa_imports_parent.py": {1, 3, 6, 7, 10, 11, 13}, } expected_covered = { "tests/coverage/included_path/late_import_const.py": {1}, - "tests/coverage/included_path/nsa/nsa_imports_parent.py": {10, 12}, + "tests/coverage/included_path/nsa/nsa_imports_parent.py": {11, 13}, } expected_covered_with_imports = { "tests/coverage/included_path/late_import_const.py": {1}, "tests/coverage/included_path/normal_import_const.py": {1}, - "tests/coverage/included_path/nsa/nsa_imports_parent.py": {1, 2, 5, 9, 10, 12}, + "tests/coverage/included_path/nsa/nsa_imports_parent.py": {1, 3, 6, 10, 11, 13}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) @pytest.mark.subprocess @@ -249,6 +257,7 @@ def test_coverage_namespace_package_nsa_import_dot_normal(): nsa_imports_dot_normal() ModuleCodeCollector.stop_coverage() + assert ModuleCodeCollector._instance is not None executable = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance.lines) covered = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=False)) covered_with_imports = _get_relpath_dict( @@ -271,13 +280,14 @@ def test_coverage_namespace_package_nsa_import_dot_normal(): "tests/coverage/included_path/nsa/nsb/normal_import_const.py": {1}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) @pytest.mark.subprocess @@ -302,6 +312,7 @@ def test_coverage_namespace_package_nsa_import_dot_late(): nsa_imports_dot_late() ModuleCodeCollector.stop_coverage() + assert ModuleCodeCollector._instance is not None executable = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance.lines) covered = _get_relpath_dict(cwd_path, ModuleCodeCollector._instance._get_covered_lines(include_imported=False)) covered_with_imports = _get_relpath_dict( @@ -333,10 +344,11 @@ def test_coverage_namespace_package_nsa_import_dot_late(): "tests/coverage/included_path/nsa/nsb/normal_import_const.py": {1}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) diff --git a/tests/coverage/test_coverage_relative_regular_packages.py b/tests/coverage/test_coverage_relative_regular_packages.py index cc03518baca..d977ad9e933 100644 --- a/tests/coverage/test_coverage_relative_regular_packages.py +++ b/tests/coverage/test_coverage_relative_regular_packages.py @@ -57,13 +57,14 @@ def test_coverage_regular_package_import_normal(): "tests/coverage/included_path/rpb/normal_import_const.py": {1}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) @pytest.mark.subprocess @@ -140,13 +141,14 @@ def test_coverage_regular_package_import_late(): "tests/coverage/included_path/rpb/normal_import_const.py": {1}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) @pytest.mark.subprocess @@ -184,22 +186,23 @@ def test_coverage_regular_package_rpa_import_parent_normal(): expected_executable = { "tests/coverage/included_path/normal_import_const.py": {1}, "tests/coverage/included_path/rpa/__init__.py": {_empty_init_lineno}, - "tests/coverage/included_path/rpa/rpa_imports_parent.py": {1, 2, 5, 6, 9, 10, 12}, + "tests/coverage/included_path/rpa/rpa_imports_parent.py": {1, 3, 6, 7, 10, 11, 13}, } - expected_covered = {"tests/coverage/included_path/rpa/rpa_imports_parent.py": {6}} + expected_covered = {"tests/coverage/included_path/rpa/rpa_imports_parent.py": {7}} expected_covered_with_imports = { "tests/coverage/included_path/normal_import_const.py": {1}, "tests/coverage/included_path/rpa/__init__.py": {_empty_init_lineno}, - "tests/coverage/included_path/rpa/rpa_imports_parent.py": {1, 2, 5, 6, 9}, + "tests/coverage/included_path/rpa/rpa_imports_parent.py": {1, 3, 6, 7, 10}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) @pytest.mark.subprocess @@ -238,26 +241,27 @@ def test_coverage_regular_package_rpa_import_parent_late(): "tests/coverage/included_path/late_import_const.py": {1}, "tests/coverage/included_path/normal_import_const.py": {1}, "tests/coverage/included_path/rpa/__init__.py": {_empty_init_lineno}, - "tests/coverage/included_path/rpa/rpa_imports_parent.py": {1, 2, 5, 6, 9, 10, 12}, + "tests/coverage/included_path/rpa/rpa_imports_parent.py": {1, 3, 6, 7, 10, 11, 13}, } expected_covered = { "tests/coverage/included_path/late_import_const.py": {1}, - "tests/coverage/included_path/rpa/rpa_imports_parent.py": {10, 12}, + "tests/coverage/included_path/rpa/rpa_imports_parent.py": {11, 13}, } expected_covered_with_imports = { "tests/coverage/included_path/late_import_const.py": {1}, "tests/coverage/included_path/normal_import_const.py": {1}, "tests/coverage/included_path/rpa/__init__.py": {_empty_init_lineno}, - "tests/coverage/included_path/rpa/rpa_imports_parent.py": {1, 2, 5, 9, 10, 12}, + "tests/coverage/included_path/rpa/rpa_imports_parent.py": {1, 3, 6, 10, 11, 13}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) @pytest.mark.subprocess @@ -312,13 +316,14 @@ def test_coverage_regular_package_rpa_import_dot_normal(): "tests/coverage/included_path/rpa/rpb/normal_import_const.py": {1}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) @pytest.mark.subprocess @@ -385,10 +390,11 @@ def test_coverage_regular_package_rpa_import_dot_late(): "tests/coverage/included_path/rpa/rpb/normal_import_const.py": {1}, } - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) diff --git a/tests/coverage/test_coverage_tool_clash.py b/tests/coverage/test_coverage_tool_clash.py index 5d6cbb6c5c0..4f069d4f9b6 100644 --- a/tests/coverage/test_coverage_tool_clash.py +++ b/tests/coverage/test_coverage_tool_clash.py @@ -40,11 +40,12 @@ def test_code_coverage_tool_clash(): expected_covered = {} expected_covered_with_imports = {} - assert ( - executable == expected_executable - ), f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + assert executable == expected_executable, ( + f"Executable lines mismatch: expected={expected_executable} vs actual={executable}" + ) assert covered == expected_covered, f"Covered lines mismatch: expected={expected_covered} vs actual={covered}" - assert ( - covered_with_imports == expected_covered_with_imports - ), f"Covered lines with imports mismatch: expected={expected_covered_with_imports} vs actual={covered_with_imports}" + assert covered_with_imports == expected_covered_with_imports, ( + f"Covered lines with imports mismatch: expected={expected_covered_with_imports} " + f"vs actual={covered_with_imports}" + ) assert line_number == 7 diff --git a/tests/coverage/test_import_dependency_tracking.py b/tests/coverage/test_import_dependency_tracking.py index 6a34ddcc54f..322c021df59 100644 --- a/tests/coverage/test_import_dependency_tracking.py +++ b/tests/coverage/test_import_dependency_tracking.py @@ -60,14 +60,14 @@ def test_direct_import_dependency(): ) # Verify the main file is covered - assert ( - "tests/coverage/included_path/import_time_callee.py" in covered_no_imports - ), "Main executed file should be in coverage without imports" + assert "tests/coverage/included_path/import_time_callee.py" in covered_no_imports, ( + "Main executed file should be in coverage without imports" + ) # CRITICAL: Verify dependency is only included with include_imported=True - assert ( - "tests/coverage/included_path/import_time_lib.py" in covered_with_imports - ), "Import dependency should be included when include_imported=True" + assert "tests/coverage/included_path/import_time_lib.py" in covered_with_imports, ( + "Import dependency should be included when include_imported=True" + ) # Note: import_time_lib may be in covered_no_imports if it was imported before coverage started # The key test is that it's definitely in covered_with_imports @@ -112,9 +112,9 @@ def test_transitive_import_dependency(): ] for module in expected_modules: - assert ( - module in covered_with_imports - ), f"Transitive dependency {module} should be tracked with include_imported=True" + assert module in covered_with_imports, ( + f"Transitive dependency {module} should be tracked with include_imported=True" + ) @pytest.mark.skipif(sys.version_info < (3, 12), reason="Test specific to Python 3.12+ monitoring API") @@ -151,9 +151,9 @@ def test_import_inside_function(): ) # CRITICAL: The module imported inside the function should be tracked - assert ( - "tests/coverage/included_path/imported_in_function_lib.py" in covered_with_imports - ), "Module imported inside function should be tracked with include_imported=True" + assert "tests/coverage/included_path/imported_in_function_lib.py" in covered_with_imports, ( + "Module imported inside function should be tracked with include_imported=True" + ) @pytest.mark.skipif(sys.version_info < (3, 12), reason="Test specific to Python 3.12+ monitoring API") @@ -191,9 +191,9 @@ def test_import_tracking_persists_across_contexts(): # Both contexts should have the main file (re-instrumentation test) assert "tests/coverage/included_path/import_time_callee.py" in context1_covered, "Context 1 should have main file" - assert ( - "tests/coverage/included_path/import_time_callee.py" in context2_covered - ), "Context 2 should have main file (re-instrumentation test)" + assert "tests/coverage/included_path/import_time_callee.py" in context2_covered, ( + "Context 2 should have main file (re-instrumentation test)" + ) # Import dependencies are tracked at the module level (via _import_time_covered) # Verify they're available @@ -208,9 +208,9 @@ def test_import_tracking_persists_across_contexts(): # If import-time tracking is enabled, we should have the callee file in import_time_covered if callee_path: - assert ( - len(import_time_covered[callee_path]) > 0 - ), "Import time covered should track lines for import_time_callee.py" + assert len(import_time_covered[callee_path]) > 0, ( + "Import time covered should track lines for import_time_callee.py" + ) @pytest.mark.skipif(sys.version_info < (3, 12), reason="Test specific to Python 3.12+ monitoring API") @@ -257,9 +257,9 @@ def test_import_names_by_path_populated(): # Check that the import entries reference import_time_lib import_names_str = str(import_entries) - assert ( - "import_time_lib" in import_names_str - ), f"Import entries should reference import_time_lib, got: {import_entries}" + assert "import_time_lib" in import_names_str, ( + f"Import entries should reference import_time_lib, got: {import_entries}" + ) @pytest.mark.skipif(sys.version_info < (3, 12), reason="Test specific to Python 3.12+ monitoring API") @@ -297,12 +297,12 @@ def test_no_false_dependencies(): # (it's only used in a different function that we didn't call) # Note: This may be present if module_level_constant was evaluated at import time # So we just verify the core dependencies are correct - assert ( - "tests/coverage/included_path/import_time_lib.py" in covered_with_imports - ), "Should track actual import dependency" - assert ( - "tests/coverage/included_path/nested_import_time_lib.py" in covered_with_imports - ), "Should track transitive import dependency" + assert "tests/coverage/included_path/import_time_lib.py" in covered_with_imports, ( + "Should track actual import dependency" + ) + assert "tests/coverage/included_path/nested_import_time_lib.py" in covered_with_imports, ( + "Should track transitive import dependency" + ) @pytest.mark.skipif(sys.version_info < (3, 12), reason="Test specific to Python 3.12+ monitoring API") diff --git a/tests/coverage/utils.py b/tests/coverage/utils.py index e5f962563d4..631eddb181a 100644 --- a/tests/coverage/utils.py +++ b/tests/coverage/utils.py @@ -52,15 +52,15 @@ def assert_coverage_matches(actual_coverage, expected_coverage, file_level_mode, actual_files = set(actual_coverage.keys()) - assert ( - actual_files == expected_files - ), f"{context_prefix}File coverage mismatch: expected={expected_files} vs actual={actual_files}" + assert actual_files == expected_files, ( + f"{context_prefix}File coverage mismatch: expected={expected_files} vs actual={actual_files}" + ) # Verify each file has some coverage for file_path in expected_files: assert len(actual_coverage[file_path]) > 0, f"{context_prefix}File {file_path} has no coverage data" else: # Line-level mode: compare actual line numbers - assert ( - actual_coverage == expected_coverage - ), f"{context_prefix}Line coverage mismatch: expected={expected_coverage} vs actual={actual_coverage}" + assert actual_coverage == expected_coverage, ( + f"{context_prefix}Line coverage mismatch: expected={expected_coverage} vs actual={actual_coverage}" + ) diff --git a/tests/debugging/test_debugger.py b/tests/debugging/test_debugger.py index 6ab1c33bc83..8f4e4678201 100644 --- a/tests/debugging/test_debugger.py +++ b/tests/debugging/test_debugger.py @@ -765,9 +765,9 @@ def test_debugger_condition_eval_then_rate_limit(stuff): assert d.signal_state_counter[SignalState.SKIP_COND] == 99 assert d.signal_state_counter[SignalState.DONE] == 1 - assert ( - "42" == snapshot["debugger"]["snapshot"]["captures"]["lines"]["36"]["arguments"]["bar"]["value"] - ), snapshot + assert "42" == snapshot["debugger"]["snapshot"]["captures"]["lines"]["36"]["arguments"]["bar"]["value"], ( + snapshot + ) def test_debugger_condition_eval_error_get_reported_once(stuff): diff --git a/tests/integration/test_debug.py b/tests/integration/test_debug.py index b38872b3212..ddad2b79bd0 100644 --- a/tests/integration/test_debug.py +++ b/tests/integration/test_debug.py @@ -160,9 +160,9 @@ def test_tracer_loglevel_info_connection(self): # regression: this used to cause an exception to be raised ddtrace.config.version = AgentWriter(intake_url="foobar") ddtrace.trace.tracer._generate_diagnostic_logs() - assert ( - mock.call(logging.INFO, re_matcher("- DATADOG TRACER CONFIGURATION - ")) in mock_logger.mock_calls - ), mock_logger.mock_calls + assert mock.call(logging.INFO, re_matcher("- DATADOG TRACER CONFIGURATION - ")) in mock_logger.mock_calls, ( + mock_logger.mock_calls + ) @run_in_subprocess( env_overrides=dict( diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index 2c2b9aaf034..5d5942f5aa6 100644 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -305,9 +305,10 @@ def test_single_trace_too_large(): from tests.utils import AnyStr assert t._span_aggregator.partial_flush_enabled is True - with mock.patch.object(t._span_aggregator.writer, "flush_queue", return_value=None), mock.patch( - "ddtrace.internal.writer.writer.log" - ) as log: + with ( + mock.patch.object(t._span_aggregator.writer, "flush_queue", return_value=None), + mock.patch("ddtrace.internal.writer.writer.log") as log, + ): with t.trace("huge"): for i in range(1 << 20 + 1): t.trace("operation").finish() @@ -398,9 +399,10 @@ def test_inode_entity_id_header_present(): from ddtrace import __version__ from ddtrace.trace import tracer as t - with mock.patch("ddtrace.internal.runtime.container.get_container_info") as gcimock, mock.patch( - "http.client.HTTPConnection.request" - ) as request_mock: + with ( + mock.patch("ddtrace.internal.runtime.container.get_container_info") as gcimock, + mock.patch("http.client.HTTPConnection.request") as request_mock, + ): from ddtrace.internal.runtime.container import CGroupInfo gcimock.return_value = CGroupInfo(node_inode=12345) @@ -686,9 +688,7 @@ def test_application_does_not_deadlock_when_parent_span_closes_before_child(run_ s2 = ddtrace.tracer.trace("2") s1.finish() s2.finish() -""".format( - str(patch_logging) - ) +""".format(str(patch_logging)) env = os.environ.copy() env.update( @@ -809,14 +809,14 @@ def test_logging_during_tracer_init_succeeds_when_debug_logging_and_logs_injecti assert status == 0, (out, err) assert out == b"", "an empty program should generate no logs under ddtrace-run" - assert ( - b"[dd.service=ddtrace_subprocess_dir dd.env= dd.version= dd.trace_id=0 dd.span_id=0]" not in err - ), "stderr should not contain debug output when DD_TRACE_DEBUG is set" + assert b"[dd.service=ddtrace_subprocess_dir dd.env= dd.version= dd.trace_id=0 dd.span_id=0]" not in err, ( + "stderr should not contain debug output when DD_TRACE_DEBUG is set" + ) assert b"KeyError: 'dd.service'" not in err, "stderr should not contain any exception logs" - assert ( - b"ValueError: Formatting field not found in record: 'dd.service'" not in err - ), "stderr should not contain any exception logs" + assert b"ValueError: Formatting field not found in record: 'dd.service'" not in err, ( + "stderr should not contain any exception logs" + ) @pytest.mark.skipif(PYTHON_VERSION_INFO < (3, 10), reason="ddtrace under Python 3.9 is deprecated") diff --git a/tests/integration/test_integration_civisibility.py b/tests/integration/test_integration_civisibility.py index 974b8a0f7cc..e258f64c2b8 100644 --- a/tests/integration/test_integration_civisibility.py +++ b/tests/integration/test_integration_civisibility.py @@ -33,9 +33,10 @@ def _dummy_check_enabled_features(): @pytest.mark.skipif(AGENT_VERSION == "testagent", reason="Test agent doesn't support evp proxy.") def test_civisibility_intake_with_evp_available(): - with override_env( - dict(DD_API_KEY="foobar.baz", DD_SITE="foo.bar", DD_CIVISIBILITY_AGENTLESS_ENABLED="0") - ), mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()): + with ( + override_env(dict(DD_API_KEY="foobar.baz", DD_SITE="foo.bar", DD_CIVISIBILITY_AGENTLESS_ENABLED="0")), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), + ): t = CIVisibilityTracer() CIVisibility.enable(tracer=t) assert CIVisibility._instance.tracer._span_aggregator.writer._endpoint == EVP_PROXY_AGENT_ENDPOINT @@ -50,8 +51,9 @@ def test_civisibility_intake_with_evp_available(): def test_civisibility_intake_with_missing_apikey(): with override_env(dict(DD_SITE="foobar.baz", DD_CIVISIBILITY_AGENTLESS_ENABLED="1")): with mock.patch.object(CIVisibility, "__init__", return_value=None) as mock_CIVisibility_init: - with mock.patch.object(CIVisibility, "start") as mock_CIVisibility_start, mock.patch( - "ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig() + with ( + mock.patch.object(CIVisibility, "start") as mock_CIVisibility_start, + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), ): CIVisibility.enable() assert CIVisibility.enabled is False @@ -61,9 +63,10 @@ def test_civisibility_intake_with_missing_apikey(): def test_civisibility_intake_with_apikey(): - with override_env( - dict(DD_API_KEY="foobar.baz", DD_SITE="foo.bar", DD_CIVISIBILITY_AGENTLESS_ENABLED="1") - ), mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()): + with ( + override_env(dict(DD_API_KEY="foobar.baz", DD_SITE="foo.bar", DD_CIVISIBILITY_AGENTLESS_ENABLED="1")), + mock.patch("ddtrace.internal.ci_visibility.recorder.ddconfig", _get_default_civisibility_ddconfig()), + ): t = CIVisibilityTracer() CIVisibility.enable(tracer=t) assert CIVisibility._instance.tracer._span_aggregator.writer._endpoint == AGENTLESS_ENDPOINT @@ -103,10 +106,10 @@ def test_civisibility_intake_payloads(): t.shutdown() assert 2 <= conn.request.call_count <= 3 assert conn.request.call_args_list[0].args[1] == "api/v2/citestcycle" - assert b"svc-no-cov" in gzip.decompress( - conn.request.call_args_list[0].args[2] - ), "requests to the cycle endpoint should include non-coverage spans" + assert b"svc-no-cov" in gzip.decompress(conn.request.call_args_list[0].args[2]), ( + "requests to the cycle endpoint should include non-coverage spans" + ) assert conn.request.call_args_list[1].args[1] == "api/v2/citestcov" - assert b"svc-no-cov" not in gzip.decompress( - conn.request.call_args_list[1].args[2] - ), "requests to the coverage endpoint should not include non-coverage spans" + assert b"svc-no-cov" not in gzip.decompress(conn.request.call_args_list[1].args[2]), ( + "requests to the coverage endpoint should not include non-coverage spans" + ) diff --git a/tests/integration/test_priority_sampling.py b/tests/integration/test_priority_sampling.py index d80084b8d4b..7c0b33e85db 100644 --- a/tests/integration/test_priority_sampling.py +++ b/tests/integration/test_priority_sampling.py @@ -108,9 +108,9 @@ def test_priority_sampling_response(): sampler_key = "service:{},env:".format(service) assert sampler_key not in t._span_aggregator.sampling_processor.sampler._agent_based_samplers _prime_tracer_with_priority_sample_rate_from_agent(t, service) - assert ( - sampler_key in t._span_aggregator.sampling_processor.sampler._agent_based_samplers - ), "after fetching priority sample rates from the agent, the tracer should hold those rates" + assert sampler_key in t._span_aggregator.sampling_processor.sampler._agent_based_samplers, ( + "after fetching priority sample rates from the agent, the tracer should hold those rates" + ) t.shutdown() @@ -161,9 +161,9 @@ def test_sampling_configurations_are_not_reset_on_tracer_configure(): agent_based_samplers = t._span_aggregator.sampling_processor.sampler._agent_based_samplers trace_sampling_rules = t._span_aggregator.sampling_processor.sampler.rules single_span_sampling_rules = t._span_aggregator.sampling_processor.single_span_rules - assert ( - agent_based_samplers and trace_sampling_rules and single_span_sampling_rules - ), "Expected agent sampling rules, span sampling rules, trace sampling rules to be set" + assert agent_based_samplers and trace_sampling_rules and single_span_sampling_rules, ( + "Expected agent sampling rules, span sampling rules, trace sampling rules to be set" + ) f", got {agent_based_samplers}, {trace_sampling_rules}, {single_span_sampling_rules}" class CustomFilter(TraceFilter): @@ -174,19 +174,19 @@ def process_trace(self, trace): return trace t.configure(trace_processors=[CustomFilter()]) # Triggers AgentWriter recreate - assert ( - t._span_aggregator.sampling_processor.sampler._agent_based_samplers == agent_based_samplers - ), f"Expected agent sampling rules to be set to {agent_based_samplers}, " + assert t._span_aggregator.sampling_processor.sampler._agent_based_samplers == agent_based_samplers, ( + f"Expected agent sampling rules to be set to {agent_based_samplers}, " + ) f"got {t._span_aggregator.sampling_processor.sampler._agent_based_samplers}" - assert ( - t._span_aggregator.sampling_processor.sampler.rules == trace_sampling_rules - ), f"Expected trace sampling rules to be set to {trace_sampling_rules}, " + assert t._span_aggregator.sampling_processor.sampler.rules == trace_sampling_rules, ( + f"Expected trace sampling rules to be set to {trace_sampling_rules}, " + ) f"got {t._span_aggregator.sampling_processor.sampler.rules}" - assert len(t._span_aggregator.sampling_processor.single_span_rules) == len( - single_span_sampling_rules - ), f"Expected single span sampling rules to be set to {single_span_sampling_rules}, " + assert len(t._span_aggregator.sampling_processor.single_span_rules) == len(single_span_sampling_rules), ( + f"Expected single span sampling rules to be set to {single_span_sampling_rules}, " + ) f"got {t._span_aggregator.sampling_processor.single_span_rules}" diff --git a/tests/integration/test_sampling.py b/tests/integration/test_sampling.py index 44d450c64dd..e0002c898de 100644 --- a/tests/integration/test_sampling.py +++ b/tests/integration/test_sampling.py @@ -69,9 +69,9 @@ def test_unsupported_sampling_mechanism(): meta = {SAMPLING_DECISION_TRACE_TAG_KEY: "-999999999999"} sampling_decision_validation = validate_sampling_decision(meta) decoding_error_result = {"_dd.propagation_error": "decoding_error"} - assert ( - sampling_decision_validation == decoding_error_result - ), f"Instead of getting {decoding_error_result}, received {sampling_decision_validation}" + assert sampling_decision_validation == decoding_error_result, ( + f"Instead of getting {decoding_error_result}, received {sampling_decision_validation}" + ) @pytest.mark.snapshot() diff --git a/tests/internal/bytecode_injection/test_core.py b/tests/internal/bytecode_injection/test_core.py index 69d55bcdbe4..54f4058ce5e 100644 --- a/tests/internal/bytecode_injection/test_core.py +++ b/tests/internal/bytecode_injection/test_core.py @@ -226,18 +226,18 @@ def test_exceptiontable_adjustment(): if original_co_code[original_entry.start] != injected_co_code[injected_entry.start]: partially_translated_starts.append(original_entry.start) - assert ( - original_co_code[original_entry.end - 2] == injected_co_code[injected_entry.end - 2] - ), "End (exclusive) opcode is the same" - assert ( - original_co_code[original_entry.target] == injected_co_code[injected_entry.target] - ), "Target opcode is the same" + assert original_co_code[original_entry.end - 2] == injected_co_code[injected_entry.end - 2], ( + "End (exclusive) opcode is the same" + ) + assert original_co_code[original_entry.target] == injected_co_code[injected_entry.target], ( + "Target opcode is the same" + ) assert original_entry.depth == injected_entry.depth, "Depth is the same" assert original_entry.lasti == injected_entry.lasti, "lasti is the same" - assert set(partially_translated_starts).issubset( - set(injection_offsets) - ), "All partially translated starts are in the injection offsets" + assert set(partially_translated_starts).issubset(set(injection_offsets)), ( + "All partially translated starts are in the injection offsets" + ) @skipif_bytecode_injection_not_supported diff --git a/tests/internal/remoteconfig/__init__.py b/tests/internal/remoteconfig/__init__.py index 76d0483d7a1..c83e30ae6cd 100644 --- a/tests/internal/remoteconfig/__init__.py +++ b/tests/internal/remoteconfig/__init__.py @@ -9,11 +9,15 @@ @contextmanager def rcm_endpoint(port=10126, poll_interval=0.05): - with override_env( - dict( - DD_TRACE_AGENT_URL="http://localhost:%d" % port, - ) - ), httpretty.enabled(), override_global_config(dict(_remote_config_poll_interval=poll_interval)): + with ( + override_env( + dict( + DD_TRACE_AGENT_URL="http://localhost:%d" % port, + ) + ), + httpretty.enabled(), + override_global_config(dict(_remote_config_poll_interval=poll_interval)), + ): httpretty.register_uri( httpretty.GET, "http://localhost:%d/info" % port, body='{"endpoints":["%s"]}' % REMOTE_CONFIG_AGENT_ENDPOINT ) diff --git a/tests/internal/service_name/test_inferred_base_service.py b/tests/internal/service_name/test_inferred_base_service.py index ac323223564..94ea5d9a28e 100644 --- a/tests/internal/service_name/test_inferred_base_service.py +++ b/tests/internal/service_name/test_inferred_base_service.py @@ -235,9 +235,7 @@ def test_get_service(cmd, default, expected, testdir): result = subprocess.run(command, cwd=testdir.tmpdir, capture_output=True, text=True, env=env) assert result.returncode == 0, ( - f"Command failed with return code {result.returncode}\n" - f"STDOUT:\n{result.stdout}\n" - f"STDERR:\n{result.stderr}" + f"Command failed with return code {result.returncode}\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}" ) assert "AssertionError" not in result.stderr, "AssertionError found in stderr" @@ -271,8 +269,8 @@ def test_python_detector_pattern_matching(command, should_match, expected_captur if should_match: assert match is not None, f"Expected '{command}' to match but it didn't" # The full match should contain the expected capture - assert expected_capture in match.group( - 0 - ), f"Expected capture '{expected_capture}' not found in match '{match.group(0)}'" + assert expected_capture in match.group(0), ( + f"Expected capture '{expected_capture}' not found in match '{match.group(0)}'" + ) else: assert match is None, f"Expected '{command}' not to match but it did: {match.group(0) if match else None}" diff --git a/tests/internal/service_name/test_processor.py b/tests/internal/service_name/test_processor.py index 158f5e1e621..060aa353969 100644 --- a/tests/internal/service_name/test_processor.py +++ b/tests/internal/service_name/test_processor.py @@ -62,9 +62,7 @@ def test(processor): if __name__ == "__main__": sys.exit(pytest.main(["-x", __file__])) - """.format( - expected_base_service_name - ) + """.format(expected_base_service_name) env = os.environ.copy() if schema_version is not None: diff --git a/tests/internal/test_forksafe.py b/tests/internal/test_forksafe.py index cd911c520bb..9979886cc6c 100644 --- a/tests/internal/test_forksafe.py +++ b/tests/internal/test_forksafe.py @@ -231,9 +231,9 @@ def test_lock_unpatched(): assert lock_collector is not None, "ThreadingLockCollector not found in profiler collectors" lock = forksafe.Lock() - assert ( - lock_collector._get_patch_target() is not lock._self_wrapped_class - ), "forksafe.Lock is using the same class that is patched by ThreadingLockCollector" + assert lock_collector._get_patch_target() is not lock._self_wrapped_class, ( + "forksafe.Lock is using the same class that is patched by ThreadingLockCollector" + ) def test_rlock_basic(): diff --git a/tests/internal/test_module.py b/tests/internal/test_module.py index 27de6444ef0..df29f2e7d79 100644 --- a/tests/internal/test_module.py +++ b/tests/internal/test_module.py @@ -516,9 +516,9 @@ def test_module_watchdog_does_not_rewrap_get_code(): reload(ns_module) reload(ns_module) new_get_code = ns_module.__loader__.get_code - assert ( - new_get_code is initial_get_code - ), f"module loader get_code (id: {id(new_get_code)}is not initial get_code (id: {id(initial_get_code)})" + assert new_get_code is initial_get_code, ( + f"module loader get_code (id: {id(new_get_code)}is not initial get_code (id: {id(initial_get_code)})" + ) @pytest.mark.subprocess diff --git a/tests/internal/test_serverless.py b/tests/internal/test_serverless.py index d5147b20006..ac203ee685f 100644 --- a/tests/internal/test_serverless.py +++ b/tests/internal/test_serverless.py @@ -54,10 +54,13 @@ def test_not_azure_function(): "ddtrace.internal._file_queue", "secrets", ] -expanded_blocklist = standard_blocklist + [ - # wrapt 2.0 is importing importlib.metada - # "importlib.metadata", -] +expanded_blocklist = ( + standard_blocklist + + [ + # wrapt 2.0 is importing importlib.metada + # "importlib.metadata", + ] +) @pytest.mark.parametrize( diff --git a/tests/internal/test_settings.py b/tests/internal/test_settings.py index 2e8369e1ea5..7a1020dbf02 100644 --- a/tests/internal/test_settings.py +++ b/tests/internal/test_settings.py @@ -682,6 +682,6 @@ def test_remoteconfig_debug_logging(): rc_configs, ), ] - assert sorted(mock_log.debug.call_args_list) == sorted( - expected_logs - ), f"expected: {expected_logs} got: {mock_log.debug.call_args_list}" + assert sorted(mock_log.debug.call_args_list) == sorted(expected_logs), ( + f"expected: {expected_logs} got: {mock_log.debug.call_args_list}" + ) diff --git a/tests/internal/test_tracer_flare.py b/tests/internal/test_tracer_flare.py index e9dbf851620..b5c75b42690 100644 --- a/tests/internal/test_tracer_flare.py +++ b/tests/internal/test_tracer_flare.py @@ -162,9 +162,9 @@ def test_json_logs(self): assert isinstance(data, dict), f"Log line is not a JSON object: {line}" for key, value in data.items(): assert isinstance(key, str), f"Log line has non-string key: {key} in line: {line}" - assert value is None or isinstance( - value, (str, int, float) - ), f"Log line has non-string/int/float/None value: {value} in line: {line}" + assert value is None or isinstance(value, (str, int, float)), ( + f"Log line has non-string/int/float/None value: {value} in line: {line}" + ) data = cast(Dict[str, Union[str, int, float, None]], data) @@ -183,9 +183,9 @@ def test_json_logs(self): "timestamp", } log_keys = set(data.keys()) - assert required_keys.issubset( - log_keys - ), f"Log line is missing required keys: {required_keys - log_keys}" + assert required_keys.issubset(log_keys), ( + f"Log line is missing required keys: {required_keys - log_keys}" + ) logs.append(data) assert len(logs) == 5, f"Expected 4 log lines, got {len(logs)}" @@ -791,9 +791,9 @@ def test_process_flare_request_success(self): self.generate_agent_config() mock_flare_prep.assert_called_once() - assert ( - self.tracer_flare_sub.current_request_start is not None - ), "current_request_start should be a non-None value after request is received" + assert self.tracer_flare_sub.current_request_start is not None, ( + "current_request_start should be a non-None value after request is received" + ) # Generate an AGENT_TASK product to complete the request with mock.patch("ddtrace.internal.flare.flare.Flare.send") as mock_flare_send: @@ -801,9 +801,9 @@ def test_process_flare_request_success(self): mock_flare_send.assert_called_once() # Timestamp cleared after request completed - assert ( - self.tracer_flare_sub.current_request_start is None - ), "current_request_start timestamp should have been reset after request was completed" + assert self.tracer_flare_sub.current_request_start is None, ( + "current_request_start timestamp should have been reset after request was completed" + ) def test_detect_stale_flare(self): """ @@ -847,9 +847,9 @@ def test_no_overlapping_requests(self): self.generate_agent_config() mock_flare_prep.assert_not_called() - assert ( - self.tracer_flare_sub.current_request_start == original_request_start - ), "Original request should not have been updated with newer request start time" + assert self.tracer_flare_sub.current_request_start == original_request_start, ( + "Original request should not have been updated with newer request start time" + ) def test_native_logs(tmp_path): diff --git a/tests/lib_injection/test_denylist.py b/tests/lib_injection/test_denylist.py index 0a191ee4920..a0fc356e064 100644 --- a/tests/lib_injection/test_denylist.py +++ b/tests/lib_injection/test_denylist.py @@ -215,14 +215,14 @@ def test_non_python_executable_with_m_flag_allowed(mock_sitecustomize): result = mock_sitecustomize.get_first_incompatible_sysarg() if result is not None: - assert result == executable or result == os.path.basename( - executable - ), f"Expected '{executable}' itself to be denied (if at all), not '-m py_compile'. Got: '{result}'" + assert result == executable or result == os.path.basename(executable), ( + f"Expected '{executable}' itself to be denied (if at all), not '-m py_compile'. Got: '{result}'" + ) with patch.object(sys, "argv", [executable, "-m", "some_other_module"]): result = mock_sitecustomize.get_first_incompatible_sysarg() if result is not None: - assert result == executable or result == os.path.basename( - executable - ), f"Non-Python executable '{executable}' should not be denied for -m patterns. Got: '{result}'" + assert result == executable or result == os.path.basename(executable), ( + f"Non-Python executable '{executable}' should not be denied for -m patterns. Got: '{result}'" + ) diff --git a/tests/lib_injection/test_guardrails.py b/tests/lib_injection/test_guardrails.py index 9b76d2aa9bc..6af9eb1e28c 100644 --- a/tests/lib_injection/test_guardrails.py +++ b/tests/lib_injection/test_guardrails.py @@ -28,9 +28,7 @@ def script_to_run(import_line): except ImportError: print("ddtrace not found") exit(1) -""" % ( - import_line - ) +""" % (import_line) TEST_CASES = [ @@ -131,9 +129,9 @@ def test_integration_compatibility_guardrail( expected_disabled_names = {d["name"] for d in expected_disabled_integrations} unexpectedly_disabled = all_disabled_integrations - expected_disabled_names - assert ( - not unexpectedly_disabled - ), f"Found unexpected disabled integrations: {unexpectedly_disabled}. stderr: {stderr}" + assert not unexpectedly_disabled, ( + f"Found unexpected disabled integrations: {unexpectedly_disabled}. stderr: {stderr}" + ) except subprocess.CalledProcessError as e: pytest.fail(f"Subprocess failed:\\nExit Code: {e.returncode}\\nstdout:\\n{e.stdout}\\nstderr:\\n{e.stderr}") diff --git a/tests/opentelemetry/test_logs.py b/tests/opentelemetry/test_logs.py index 88ce040ab16..ae850c1e6d5 100644 --- a/tests/opentelemetry/test_logs.py +++ b/tests/opentelemetry/test_logs.py @@ -128,9 +128,9 @@ def test_otel_logs_support_enabled(): from ddtrace.internal.opentelemetry.logs import DD_LOGS_PROVIDER_CONFIGURED logger_provider = get_logger_provider() - assert ( - DD_LOGS_PROVIDER_CONFIGURED - ), f"OpenTelemetry logs exporter should be configured automatically. {logger_provider} configured." + assert DD_LOGS_PROVIDER_CONFIGURED, ( + f"OpenTelemetry logs exporter should be configured automatically. {logger_provider} configured." + ) @pytest.mark.skipif( @@ -153,9 +153,9 @@ def test_otel_logs_exporter_configured_twice(): from ddtrace.internal.opentelemetry.logs import DD_LOGS_PROVIDER_CONFIGURED logger_provider = get_logger_provider() - assert ( - DD_LOGS_PROVIDER_CONFIGURED - ), f"OpenTelemetry logs exporter should be configured automatically. {logger_provider} configured." + assert DD_LOGS_PROVIDER_CONFIGURED, ( + f"OpenTelemetry logs exporter should be configured automatically. {logger_provider} configured." + ) @pytest.mark.skipif( @@ -170,9 +170,9 @@ def test_otel_logs_support_not_enabled(): from ddtrace.internal.opentelemetry.logs import DD_LOGS_PROVIDER_CONFIGURED logger_provider = get_logger_provider() - assert ( - not DD_LOGS_PROVIDER_CONFIGURED - ), f"OpenTelemetry logs exporter should not be configured automatically. {logger_provider} configured." + assert not DD_LOGS_PROVIDER_CONFIGURED, ( + f"OpenTelemetry logs exporter should not be configured automatically. {logger_provider} configured." + ) @pytest.mark.skipif( @@ -229,14 +229,14 @@ def test_otel_logs_exporter_auto_configured_http(): attributes = extract_log_correlation_attributes(captured_logs, "test_otel_logs_exporter_auto_configured_http") assert len(attributes) == 6, f"Expected 6 log correlation attributes but found: {attributes}" - assert ( - attributes["service"] == "ddservice" - ), f"Expected service.name to be 'ddservice' but found: {attributes['service']}" + assert attributes["service"] == "ddservice", ( + f"Expected service.name to be 'ddservice' but found: {attributes['service']}" + ) assert attributes["env"] == "ddenv", f"Expected deployment.environment to be 'ddenv' but found: {attributes['env']}" assert attributes["version"] == "ddv1", f"Expected service.version to be 'ddv1' but found: {attributes['version']}" - assert ( - attributes["host_name"] == "ddhost" - ), f"Expected host.name to be 'ddhost' but found: {attributes['host_name']}" + assert attributes["host_name"] == "ddhost", ( + f"Expected host.name to be 'ddhost' but found: {attributes['host_name']}" + ) assert attributes["trace_id"] in ( "00000000000000000000000000000000", "", @@ -303,9 +303,9 @@ def test_otel_logs_exporter_auto_configured_grpc(): for record in scope_logs.log_records ] - assert any( - b"test_otel_logs_exporter_auto_configured_grpc" in log.body.string_value.encode() for log in all_logs - ), "Expected log message not found in exported gRPC payload" + assert any(b"test_otel_logs_exporter_auto_configured_grpc" in log.body.string_value.encode() for log in all_logs), ( + "Expected log message not found in exported gRPC payload" + ) @pytest.mark.skipif( @@ -362,9 +362,9 @@ def test_ddtrace_log_injection_otlp_enabled(): if attr.key in (LOG_ATTR_ENV, LOG_ATTR_SERVICE, LOG_ATTR_VERSION, LOG_ATTR_TRACE_ID, LOG_ATTR_SPAN_ID): ddtrace_attributes[attr.key] = attr.value - assert ( - ddtrace_attributes == {} - ), f"Log Injection attributes should not be present in the log record: {ddtrace_attributes}" + assert ddtrace_attributes == {}, ( + f"Log Injection attributes should not be present in the log record: {ddtrace_attributes}" + ) @pytest.mark.skipif( @@ -397,9 +397,9 @@ def test_ddtrace_log_correlation(): from tests.opentelemetry.test_logs import extract_log_correlation_attributes otel_context = os.environ.get("OTEL_PYTHON_CONTEXT") - assert ( - otel_context == "ddcontextvars_context" - ), f"Expected OTEL_PYTHON_CONTEXT to be set to ddcontextvars_context but found: {otel_context}" + assert otel_context == "ddcontextvars_context", ( + f"Expected OTEL_PYTHON_CONTEXT to be set to ddcontextvars_context but found: {otel_context}" + ) log = getLogger() mock_service, server = create_mock_grpc_server() @@ -419,22 +419,22 @@ def test_ddtrace_log_correlation(): break assert len(attributes) == 6, f"All log correlation attributes NOT found attributes: {attributes}" - assert ( - attributes["service"] == "test_service" - ), f"Expected service.name to be 'test_service' but found: {attributes['service']}" - assert ( - attributes["env"] == "test_env" - ), f"Expected deployment.environment to be 'test_env' but found: {attributes['env']}" + assert attributes["service"] == "test_service", ( + f"Expected service.name to be 'test_service' but found: {attributes['service']}" + ) + assert attributes["env"] == "test_env", ( + f"Expected deployment.environment to be 'test_env' but found: {attributes['env']}" + ) assert attributes["version"] == "1.0", f"Expected service.version to be '1.0' but found: {attributes['version']}" - assert ( - attributes["host_name"] == "test_host2" - ), f"Expected host.name to match 'test_host2' but found: {attributes['host_name']}" - assert ( - int(attributes["trace_id"], 16) == span.trace_id - ), f"Expected trace_id_hex to be set to {attributes['trace_id']} but found: {span.trace_id}" - assert ( - int(attributes["span_id"], 16) == span.span_id - ), f"Expected span_id_hex to be set to {attributes['span_id']} but found: {span.span_id}" + assert attributes["host_name"] == "test_host2", ( + f"Expected host.name to match 'test_host2' but found: {attributes['host_name']}" + ) + assert int(attributes["trace_id"], 16) == span.trace_id, ( + f"Expected trace_id_hex to be set to {attributes['trace_id']} but found: {span.trace_id}" + ) + assert int(attributes["span_id"], 16) == span.span_id, ( + f"Expected span_id_hex to be set to {attributes['span_id']} but found: {span.span_id}" + ) @pytest.mark.skipif( @@ -462,9 +462,9 @@ def test_otel_trace_log_correlation(): from tests.opentelemetry.test_logs import extract_log_correlation_attributes otel_context = os.environ.get("OTEL_PYTHON_CONTEXT") - assert ( - otel_context == "ddcontextvars_context" - ), f"Expected OTEL_PYTHON_CONTEXT to be set to ddcontextvars_context but found: {otel_context}" + assert otel_context == "ddcontextvars_context", ( + f"Expected OTEL_PYTHON_CONTEXT to be set to ddcontextvars_context but found: {otel_context}" + ) log = getLogger() @@ -486,24 +486,24 @@ def test_otel_trace_log_correlation(): break assert len(attributes) == 6, f"All log correlation attributes NOT found attributes: {attributes}" - assert ( - attributes["service"] == "test_service" - ), f"Expected service.name to be 'test_service' but found: {attributes['service']}" - assert ( - attributes["env"] == "test_env" - ), f"Expected deployment.environment to be 'test_env' but found: {attributes['env']}" + assert attributes["service"] == "test_service", ( + f"Expected service.name to be 'test_service' but found: {attributes['service']}" + ) + assert attributes["env"] == "test_env", ( + f"Expected deployment.environment to be 'test_env' but found: {attributes['env']}" + ) assert attributes["version"] == "1.0", f"Expected service.version to be '1.0' but found: {attributes['version']}" - assert ( - attributes["host_name"] == "test_host" - ), f"Expected host.name to match 'test_host' but found: {attributes['host_name']}" + assert attributes["host_name"] == "test_host", ( + f"Expected host.name to match 'test_host' but found: {attributes['host_name']}" + ) span_context = ot_span.get_span_context() - assert ( - int(attributes["trace_id"], 16) == span_context.trace_id - ), f"Expected trace_id_hex to be set to {attributes['trace_id']} but found: {span_context.trace_id}" - assert ( - int(attributes["span_id"], 16) == span_context.span_id - ), f"Expected span_id_hex to be set to {attributes['span_id']} but found: {span_context.span_id}" + assert int(attributes["trace_id"], 16) == span_context.trace_id, ( + f"Expected trace_id_hex to be set to {attributes['trace_id']} but found: {span_context.trace_id}" + ) + assert int(attributes["span_id"], 16) == span_context.span_id, ( + f"Expected span_id_hex to be set to {attributes['span_id']} but found: {span_context.span_id}" + ) @pytest.mark.skipif( diff --git a/tests/opentelemetry/test_metrics.py b/tests/opentelemetry/test_metrics.py index a534236d579..a3038fff9d1 100644 --- a/tests/opentelemetry/test_metrics.py +++ b/tests/opentelemetry/test_metrics.py @@ -93,6 +93,6 @@ def test_otel_metrics_disabled_and_unset(): from opentelemetry.metrics import get_meter_provider meter_provider = get_meter_provider() - assert (meter_provider is None) or ( - type(meter_provider).__name__ == "_ProxyMeterProvider" - ), "OpenTelemetry mterics exporter should not be configured automatically." + assert (meter_provider is None) or (type(meter_provider).__name__ == "_ProxyMeterProvider"), ( + "OpenTelemetry mterics exporter should not be configured automatically." + ) diff --git a/tests/profiling/collector/pprof_utils.py b/tests/profiling/collector/pprof_utils.py index f6a2a4de6c4..5dfdeefe2a0 100644 --- a/tests/profiling/collector/pprof_utils.py +++ b/tests/profiling/collector/pprof_utils.py @@ -196,9 +196,9 @@ def assert_lock_events_of_type( # sort the samples and expected events by lock name, which is <filename>:<line>:<lock_name> # when the lock_name exists, otherwise <filename>:<line> - assert all( - get_label_with_key(profile.string_table, sample, "lock name") for sample in samples - ), "All samples should have the label 'lock name'" + assert all(get_label_with_key(profile.string_table, sample, "lock name") for sample in samples), ( + "All samples should have the label 'lock name'" + ) samples = { profile.string_table[get_label_with_key(profile.string_table, sample, "lock name").str]: sample for sample in samples diff --git a/tests/profiling/collector/test_sample_count.py b/tests/profiling/collector/test_sample_count.py index c2304237276..e1fcd755172 100644 --- a/tests/profiling/collector/test_sample_count.py +++ b/tests/profiling/collector/test_sample_count.py @@ -66,6 +66,6 @@ async def hello(): if internal_metadata["sample_count"] > internal_metadata["sampling_event_count"]: found_at_least_one_with_more_samples_than_sampling_events = True - assert ( - found_at_least_one_with_more_samples_than_sampling_events - ), "Expected at least one file with more samples than sampling events" + assert found_at_least_one_with_more_samples_than_sampling_events, ( + "Expected at least one file with more samples than sampling events" + ) diff --git a/tests/profiling/collector/test_stack.py b/tests/profiling/collector/test_stack.py index b70ddd773e9..4ad90aa8e9f 100644 --- a/tests/profiling/collector/test_stack.py +++ b/tests/profiling/collector/test_stack.py @@ -302,9 +302,7 @@ def test_repr(): try: raise ValueError('test') except Exception: - time.sleep(2)""".format( - MAX_FN_NUM=MAX_FN_NUM - ) + time.sleep(2)""".format(MAX_FN_NUM=MAX_FN_NUM) ) diff --git a/tests/profiling_v2/collector/test_memalloc.py b/tests/profiling_v2/collector/test_memalloc.py index 2022636f72f..1d670aa66d6 100644 --- a/tests/profiling_v2/collector/test_memalloc.py +++ b/tests/profiling_v2/collector/test_memalloc.py @@ -523,9 +523,9 @@ def test_memory_collector_allocation_tracking_across_snapshots(): samples = mc.test_snapshot() - assert all( - sample.alloc_size > 0 for sample in samples - ), "Initial snapshot should have alloc_size>0 (new allocations)" + assert all(sample.alloc_size > 0 for sample in samples), ( + "Initial snapshot should have alloc_size>0 (new allocations)" + ) freed_samples = [s for s in samples if s.in_use_size == 0] live_samples = [s for s in samples if s.in_use_size > 0] @@ -582,9 +582,9 @@ def test_memory_collector_python_interface_with_allocation_tracking(): one_samples_in_final = [sample for sample in final_samples if has_function_in_traceback(sample.frames, "one")] - assert ( - len(one_samples_in_final) == 0 - ), f"Should have no samples with 'one' in traceback in final_samples, got {len(one_samples_in_final)}" + assert len(one_samples_in_final) == 0, ( + f"Should have no samples with 'one' in traceback in final_samples, got {len(one_samples_in_final)}" + ) batch_two_live_samples = [ sample @@ -592,9 +592,9 @@ def test_memory_collector_python_interface_with_allocation_tracking(): if has_function_in_traceback(sample.frames, "two") and sample.in_use_size > 0 ] - assert ( - len(batch_two_live_samples) > 0 - ), f"Should have live samples from batch two, got {len(batch_two_live_samples)}" + assert len(batch_two_live_samples) > 0, ( + f"Should have live samples from batch two, got {len(batch_two_live_samples)}" + ) assert all(sample.in_use_size > 0 and sample.alloc_size > 0 for sample in batch_two_live_samples) del second_batch @@ -641,12 +641,12 @@ def test_memory_collector_python_interface_with_allocation_tracking_no_deletion( if has_function_in_traceback(sample.frames, "two") and sample.in_use_size > 0 ] - assert ( - len(batch_one_live_samples) > 0 - ), f"Should have live samples from batch one, got {len(batch_one_live_samples)}" - assert ( - len(batch_two_live_samples) > 0 - ), f"Should have live samples from batch two, got {len(batch_two_live_samples)}" + assert len(batch_one_live_samples) > 0, ( + f"Should have live samples from batch one, got {len(batch_one_live_samples)}" + ) + assert len(batch_two_live_samples) > 0, ( + f"Should have live samples from batch two, got {len(batch_two_live_samples)}" + ) assert all(sample.in_use_size > 0 and sample.alloc_size == 0 for sample in batch_one_live_samples) assert all(sample.in_use_size > 0 and sample.alloc_size > 0 for sample in batch_two_live_samples) @@ -749,9 +749,9 @@ def deep_alloc(depth): deep_alloc_count += 1 break - assert ( - deep_alloc_count >= 10 - ), f"Buffer pool test: Expected many allocations from concurrent threads, got {deep_alloc_count}" + assert deep_alloc_count >= 10, ( + f"Buffer pool test: Expected many allocations from concurrent threads, got {deep_alloc_count}" + ) assert max_stack_depth >= 50, ( f"Buffer pool test: Stack traces should be preserved even under stress (expecting at least 50 frames), " @@ -794,6 +794,6 @@ def worker(): worker_samples += 1 break - assert ( - worker_samples > 0 - ), "Thread lifecycle test: Should capture allocations even as threads are created/destroyed" + assert worker_samples > 0, ( + "Thread lifecycle test: Should capture allocations even as threads are created/destroyed" + ) diff --git a/tests/profiling_v2/collector/test_threading.py b/tests/profiling_v2/collector/test_threading.py index fb4e0ad71cc..c733cb174b0 100644 --- a/tests/profiling_v2/collector/test_threading.py +++ b/tests/profiling_v2/collector/test_threading.py @@ -40,8 +40,7 @@ _test_global_lock: LockClassInst -class TestBar: - ... +class TestBar: ... _test_global_bar_instance: TestBar @@ -215,9 +214,7 @@ def test_lock_gevent_tasks() -> None: test_name: str = "test_lock_gevent_tasks" pprof_prefix: str = "/tmp" + os.sep + test_name output_filename: str = pprof_prefix + "." + str(os.getpid()) - ddup.config( - env="test", service=test_name, version="my_version", output_filename=pprof_prefix - ) # pyright: ignore[reportCallIssue] + ddup.config(env="test", service=test_name, version="my_version", output_filename=pprof_prefix) # pyright: ignore[reportCallIssue] ddup.start() init_linenos(os.environ["DD_PROFILING_FILE_PATH"]) @@ -233,9 +230,7 @@ def validate_and_cleanup() -> None: expected_filename: str = "test_threading.py" linenos: LineNo = get_lock_linenos(test_name) - profile: pprof_pb2.Profile = pprof_utils.parse_newest_profile( - output_filename - ) # pyright: ignore[reportInvalidTypeForm] + profile: pprof_pb2.Profile = pprof_utils.parse_newest_profile(output_filename) # pyright: ignore[reportInvalidTypeForm] pprof_utils.assert_lock_events( profile, expected_acquire_events=[ @@ -307,9 +302,7 @@ def test_rlock_gevent_tasks() -> None: test_name: str = "test_rlock_gevent_tasks" pprof_prefix: str = "/tmp" + os.sep + test_name output_filename: str = pprof_prefix + "." + str(os.getpid()) - ddup.config( - env="test", service=test_name, version="my_version", output_filename=pprof_prefix - ) # pyright: ignore[reportCallIssue] + ddup.config(env="test", service=test_name, version="my_version", output_filename=pprof_prefix) # pyright: ignore[reportCallIssue] ddup.start() init_linenos(os.environ["DD_PROFILING_FILE_PATH"]) @@ -456,9 +449,7 @@ def setup_method(self, method: Callable[..., None]) -> None: # ddup is available when the native module is compiled assert ddup.is_available, "ddup is not available" - ddup.config( - env="test", service=self.test_name, version="my_version", output_filename=self.pprof_prefix - ) # pyright: ignore[reportCallIssue] + ddup.config(env="test", service=self.test_name, version="my_version", output_filename=self.pprof_prefix) # pyright: ignore[reportCallIssue] ddup.start() def teardown_method(self, method: Callable[..., None]) -> None: @@ -1054,9 +1045,9 @@ def test_upload_resets_profile(self) -> None: num_files_after_second_upload: int = len(glob.glob(self.output_filename + ".*.pprof")) # A new profile file should always be created (upload_seq increments) - assert ( - num_files_after_second_upload - num_files_before_second_upload == 1 - ), f"Expected 1 new file, got {num_files_after_second_upload - num_files_before_second_upload}." + assert num_files_after_second_upload - num_files_before_second_upload == 1, ( + f"Expected 1 new file, got {num_files_after_second_upload - num_files_before_second_upload}." + ) # The newest profile file should be empty (no samples), which causes an AssertionError with pytest.raises(AssertionError, match="No samples found in profile"): @@ -1162,9 +1153,10 @@ def test_lock_profiling_overhead_reasonable(self) -> None: # Allow up to 50x overhead since lock operations are extremely fast (microseconds) # and wrapper overhead is constant per call overhead_multiplier: float = profiled_time_zero / regular_time if regular_time > 0 else 1 - assert ( - overhead_multiplier < 50 - ), f"Overhead too high: {overhead_multiplier}x (regular: {regular_time:.6f}s, profiled: {profiled_time_zero:.6f}s)" # noqa: E501 + assert overhead_multiplier < 50, ( + f"Overhead too high: {overhead_multiplier}x (regular: {regular_time:.6f}s, " + f"profiled: {profiled_time_zero:.6f}s)" + ) # noqa: E501 class TestThreadingLockCollector(BaseThreadingLockCollectorTest): diff --git a/tests/profiling_v2/simple_program_gevent.py b/tests/profiling_v2/simple_program_gevent.py index f50fa3aa2e0..1cc85d2c921 100644 --- a/tests/profiling_v2/simple_program_gevent.py +++ b/tests/profiling_v2/simple_program_gevent.py @@ -4,7 +4,7 @@ import ddtrace.profiling.auto # noqa:F401 -import gevent.monkey # noqa:F402 +import gevent.monkey # noqa:F402 gevent.monkey.patch_all() diff --git a/tests/profiling_v2/test_profiler.py b/tests/profiling_v2/test_profiler.py index d4b87237f63..6ddf6c39ca6 100644 --- a/tests/profiling_v2/test_profiler.py +++ b/tests/profiling_v2/test_profiler.py @@ -184,11 +184,14 @@ def test_libdd_failure_telemetry_logging(): from unittest import mock - with mock.patch.multiple( - "ddtrace.internal.datadog.profiling.ddup", - failure_msg="mock failure message", - is_available=False, - ), mock.patch("ddtrace.internal.telemetry.telemetry_writer.add_log") as mock_add_log: + with ( + mock.patch.multiple( + "ddtrace.internal.datadog.profiling.ddup", + failure_msg="mock failure message", + is_available=False, + ), + mock.patch("ddtrace.internal.telemetry.telemetry_writer.add_log") as mock_add_log, + ): from ddtrace.internal.settings.profiling import config # noqa:F401 from ddtrace.internal.telemetry.constants import TELEMETRY_LOG_LEVEL @@ -208,11 +211,14 @@ def test_libdd_failure_telemetry_logging(): def test_libdd_failure_telemetry_logging_with_auto(): from unittest import mock - with mock.patch.multiple( - "ddtrace.internal.datadog.profiling.ddup", - failure_msg="mock failure message", - is_available=False, - ), mock.patch("ddtrace.internal.telemetry.telemetry_writer.add_log") as mock_add_log: + with ( + mock.patch.multiple( + "ddtrace.internal.datadog.profiling.ddup", + failure_msg="mock failure message", + is_available=False, + ), + mock.patch("ddtrace.internal.telemetry.telemetry_writer.add_log") as mock_add_log, + ): from ddtrace.internal.telemetry.constants import TELEMETRY_LOG_LEVEL import ddtrace.profiling.auto # noqa: F401 @@ -235,11 +241,14 @@ def test_stack_v2_failure_telemetry_logging(): from unittest import mock - with mock.patch.multiple( - "ddtrace.internal.datadog.profiling.stack_v2", - failure_msg="mock failure message", - is_available=False, - ), mock.patch("ddtrace.internal.telemetry.telemetry_writer.add_log") as mock_add_log: + with ( + mock.patch.multiple( + "ddtrace.internal.datadog.profiling.stack_v2", + failure_msg="mock failure message", + is_available=False, + ), + mock.patch("ddtrace.internal.telemetry.telemetry_writer.add_log") as mock_add_log, + ): from ddtrace.internal.settings.profiling import config # noqa: F401 from ddtrace.internal.telemetry.constants import TELEMETRY_LOG_LEVEL @@ -259,11 +268,14 @@ def test_stack_v2_failure_telemetry_logging(): def test_stack_v2_failure_telemetry_logging_with_auto(): from unittest import mock - with mock.patch.multiple( - "ddtrace.internal.datadog.profiling.stack_v2", - failure_msg="mock failure message", - is_available=False, - ), mock.patch("ddtrace.internal.telemetry.telemetry_writer.add_log") as mock_add_log: + with ( + mock.patch.multiple( + "ddtrace.internal.datadog.profiling.stack_v2", + failure_msg="mock failure message", + is_available=False, + ), + mock.patch("ddtrace.internal.telemetry.telemetry_writer.add_log") as mock_add_log, + ): from ddtrace.internal.telemetry.constants import TELEMETRY_LOG_LEVEL import ddtrace.profiling.auto # noqa: F401 diff --git a/tests/runtime/test_runtime_metrics_api.py b/tests/runtime/test_runtime_metrics_api.py index ef6487fbc27..2616bcef6b4 100644 --- a/tests/runtime/test_runtime_metrics_api.py +++ b/tests/runtime/test_runtime_metrics_api.py @@ -260,6 +260,6 @@ def test_runtime_metrics_experimental_metric_type(): if "DD_RUNTIME_METRICS_ENABLED" in os.environ["DD_TRACE_EXPERIMENTAL_FEATURES_ENABLED"]: assert worker_instance.send_metric == worker_instance._dogstatsd_client.gauge, worker_instance.send_metric else: - assert ( - worker_instance.send_metric == worker_instance._dogstatsd_client.distribution - ), worker_instance.send_metric + assert worker_instance.send_metric == worker_instance._dogstatsd_client.distribution, ( + worker_instance.send_metric + ) diff --git a/tests/subprocesstest.py b/tests/subprocesstest.py index c7cd1c39c36..862cfc60708 100644 --- a/tests/subprocesstest.py +++ b/tests/subprocesstest.py @@ -5,6 +5,7 @@ A base class SubprocessTestCase is provided that, when extended, will run test cases marked with @run_in_subprocess in a separate python interpreter. """ + import inspect import os import subprocess diff --git a/tests/tracer/test_ci.py b/tests/tracer/test_ci.py index 2bd347f221f..a320d5c63e8 100644 --- a/tests/tracer/test_ci.py +++ b/tests/tracer/test_ci.py @@ -272,11 +272,12 @@ def test_os_runtime_metadata_tagging(): def test_get_rev_list_no_args_git_ge_223(git_repo): - with mock.patch( - "ddtrace.ext.git._git_subprocess_cmd_with_details", - return_value=git._GitSubprocessDetails("commithash1\ncommithash2\n", "", 10, 0), - ) as mock_git_subprocess_cmd_with_details, mock.patch( - "ddtrace.ext.git.extract_git_version", return_value=(2, 23, 0) + with ( + mock.patch( + "ddtrace.ext.git._git_subprocess_cmd_with_details", + return_value=git._GitSubprocessDetails("commithash1\ncommithash2\n", "", 10, 0), + ) as mock_git_subprocess_cmd_with_details, + mock.patch("ddtrace.ext.git.extract_git_version", return_value=(2, 23, 0)), ): assert git._get_rev_list(cwd=git_repo) == "commithash1\ncommithash2\n" mock_git_subprocess_cmd_with_details.assert_called_once_with( @@ -291,11 +292,12 @@ def test_get_rev_list_no_args_git_ge_223(git_repo): def test_get_rev_list_git_lt_223(git_repo): - with mock.patch( - "ddtrace.ext.git._git_subprocess_cmd_with_details", - return_value=git._GitSubprocessDetails("commithash1\ncommithash2\n", "", 10, 0), - ) as mock_git_subprocess_cmd_with_details, mock.patch( - "ddtrace.ext.git.extract_git_version", return_value=(2, 22, 0) + with ( + mock.patch( + "ddtrace.ext.git._git_subprocess_cmd_with_details", + return_value=git._GitSubprocessDetails("commithash1\ncommithash2\n", "", 10, 0), + ) as mock_git_subprocess_cmd_with_details, + mock.patch("ddtrace.ext.git.extract_git_version", return_value=(2, 22, 0)), ): assert ( git._get_rev_list( @@ -517,13 +519,14 @@ def test_extract_git_head_metadata(): "committer": ("Committer", "c@committer.com", "date2"), } - with mock.patch( - "ddtrace.ext.git._is_shallow_repository_with_details", return_value=(True, 0.1, 0) - ) as mock_is_shallow, mock.patch("ddtrace.ext.git._unshallow_repository") as mock_unshallow_repository, mock.patch( - "ddtrace.ext.git.extract_user_info", return_value=fake_user_info - ), mock.patch( - "ddtrace.ext.git._git_subprocess_cmd", return_value="commit message" - ) as mock_git_subprocess_cmd: + with ( + mock.patch( + "ddtrace.ext.git._is_shallow_repository_with_details", return_value=(True, 0.1, 0) + ) as mock_is_shallow, + mock.patch("ddtrace.ext.git._unshallow_repository") as mock_unshallow_repository, + mock.patch("ddtrace.ext.git.extract_user_info", return_value=fake_user_info), + mock.patch("ddtrace.ext.git._git_subprocess_cmd", return_value="commit message") as mock_git_subprocess_cmd, + ): tags = git.extract_git_head_metadata("sha123", cwd="/repo") mock_is_shallow.assert_called_once() diff --git a/tests/tracer/test_endpoint_config.py b/tests/tracer/test_endpoint_config.py index 18194636d99..e312f2e2639 100644 --- a/tests/tracer/test_endpoint_config.py +++ b/tests/tracer/test_endpoint_config.py @@ -92,12 +92,12 @@ def test_unset_config_endpoint(caplog): def test_set_config_endpoint_enabled(caplog): - with caplog.at_level(logging.DEBUG, logger="ddtrace"), override_env( - {"_DD_CONFIG_ENDPOINT": "http://localhost:80"} - ), mock.patch.object(HTTPConnection, "connect", new=mock_pass), mock.patch.object( - HTTPConnection, "send", new=mock_pass - ), mock.patch.object( - HTTPConnection, "getresponse", new=mock_getresponse_enabled + with ( + caplog.at_level(logging.DEBUG, logger="ddtrace"), + override_env({"_DD_CONFIG_ENDPOINT": "http://localhost:80"}), + mock.patch.object(HTTPConnection, "connect", new=mock_pass), + mock.patch.object(HTTPConnection, "send", new=mock_pass), + mock.patch.object(HTTPConnection, "getresponse", new=mock_getresponse_enabled), ): assert fetch_config_from_endpoint() == {"dd_product_enabled": True} if caplog.text: @@ -106,12 +106,12 @@ def test_set_config_endpoint_enabled(caplog): def test_set_config_endpoint_500(caplog): - with caplog.at_level(logging.DEBUG, logger="ddtrace"), override_env( - {"_DD_CONFIG_ENDPOINT": "http://localhost:80"} - ), mock.patch.object(HTTPConnection, "connect", new=mock_pass), mock.patch.object( - HTTPConnection, "send", new=mock_pass - ), mock.patch.object( - HTTPConnection, "getresponse", new=mock_getresponse_500 + with ( + caplog.at_level(logging.DEBUG, logger="ddtrace"), + override_env({"_DD_CONFIG_ENDPOINT": "http://localhost:80"}), + mock.patch.object(HTTPConnection, "connect", new=mock_pass), + mock.patch.object(HTTPConnection, "send", new=mock_pass), + mock.patch.object(HTTPConnection, "getresponse", new=mock_getresponse_500), ): assert fetch_config_from_endpoint() == {} if caplog.text: @@ -120,12 +120,12 @@ def test_set_config_endpoint_500(caplog): def test_set_config_endpoint_403(caplog): - with caplog.at_level(logging.DEBUG, logger="ddtrace"), override_env( - {"_DD_CONFIG_ENDPOINT": "http://localhost:80"} - ), mock.patch.object(HTTPConnection, "connect", new=mock_pass), mock.patch.object( - HTTPConnection, "send", new=mock_pass - ), mock.patch.object( - HTTPConnection, "getresponse", new=mock_getresponse_403 + with ( + caplog.at_level(logging.DEBUG, logger="ddtrace"), + override_env({"_DD_CONFIG_ENDPOINT": "http://localhost:80"}), + mock.patch.object(HTTPConnection, "connect", new=mock_pass), + mock.patch.object(HTTPConnection, "send", new=mock_pass), + mock.patch.object(HTTPConnection, "getresponse", new=mock_getresponse_403), ): assert fetch_config_from_endpoint() == {} if caplog.text: @@ -134,12 +134,12 @@ def test_set_config_endpoint_403(caplog): def test_set_config_endpoint_malformed(caplog): - with caplog.at_level(logging.DEBUG, logger="ddtrace"), override_env( - {"_DD_CONFIG_ENDPOINT": "http://localhost:80"} - ), mock.patch.object(HTTPConnection, "connect", new=mock_pass), mock.patch.object( - HTTPConnection, "send", new=mock_pass - ), mock.patch.object( - HTTPConnection, "getresponse", new=mock_getresponse_malformed + with ( + caplog.at_level(logging.DEBUG, logger="ddtrace"), + override_env({"_DD_CONFIG_ENDPOINT": "http://localhost:80"}), + mock.patch.object(HTTPConnection, "connect", new=mock_pass), + mock.patch.object(HTTPConnection, "send", new=mock_pass), + mock.patch.object(HTTPConnection, "getresponse", new=mock_getresponse_malformed), ): assert fetch_config_from_endpoint() == {} if caplog.text: @@ -158,9 +158,11 @@ def test_set_config_endpoint_connection_refused(caplog): def test_set_config_endpoint_timeout_error(caplog): - with caplog.at_level(logging.DEBUG, logger="ddtrace"), override_env( - {"_DD_CONFIG_ENDPOINT": "http://localhost:80"} - ), mock.patch("ddtrace.internal.utils.http.get_connection", side_effect=TimeoutError): + with ( + caplog.at_level(logging.DEBUG, logger="ddtrace"), + override_env({"_DD_CONFIG_ENDPOINT": "http://localhost:80"}), + mock.patch("ddtrace.internal.utils.http.get_connection", side_effect=TimeoutError), + ): assert fetch_config_from_endpoint() == {} if caplog.text: @@ -172,13 +174,12 @@ def test_set_config_endpoint_timeout_error(caplog): def test_set_config_endpoint_retries(caplog): - with caplog.at_level(logging.DEBUG, logger="ddtrace"), override_env( - {"_DD_CONFIG_ENDPOINT": "http://localhost:80"} - ), mock.patch.object(HTTPConnection, "connect", new=mock_pass), mock.patch.object( - HTTPConnection, "send", new=mock_pass - ), mock.patch.object( - HTTPConnection, "getresponse", new=mock_getresponse_enabled_after_4_retries - ), mock.patch( - "ddtrace.internal.settings.endpoint_config._get_retries", return_value=5 + with ( + caplog.at_level(logging.DEBUG, logger="ddtrace"), + override_env({"_DD_CONFIG_ENDPOINT": "http://localhost:80"}), + mock.patch.object(HTTPConnection, "connect", new=mock_pass), + mock.patch.object(HTTPConnection, "send", new=mock_pass), + mock.patch.object(HTTPConnection, "getresponse", new=mock_getresponse_enabled_after_4_retries), + mock.patch("ddtrace.internal.settings.endpoint_config._get_retries", return_value=5), ): assert fetch_config_from_endpoint() == {"dd_product_enabled": True} diff --git a/tests/tracer/test_gitmetadata.py b/tests/tracer/test_gitmetadata.py index add4df05878..7513f5d1929 100644 --- a/tests/tracer/test_gitmetadata.py +++ b/tests/tracer/test_gitmetadata.py @@ -2,6 +2,7 @@ """ tests for git metadata embedding and processing. """ + import glob import os import subprocess diff --git a/tests/tracer/test_native_logger.py b/tests/tracer/test_native_logger.py index 525c56290ae..6a85dcdd4b4 100644 --- a/tests/tracer/test_native_logger.py +++ b/tests/tracer/test_native_logger.py @@ -87,9 +87,7 @@ def test_logger_subprocess( message_level = f"{}" logger.log(message_level, f"{}") - """.format( - message_level, message - ) + """.format(message_level, message) out, err, status, _ = ddtrace_run_python_code_in_subprocess(code, env=env) assert status == 0 diff --git a/tests/tracer/test_propagation.py b/tests/tracer/test_propagation.py index d9f93c4d490..1cf184921ac 100644 --- a/tests/tracer/test_propagation.py +++ b/tests/tracer/test_propagation.py @@ -303,7 +303,10 @@ def test_extract(tracer): # noqa: F811 @pytest.mark.parametrize("appsec_enabled", [True, False]) @pytest.mark.parametrize("iast_enabled", [True, False]) def test_asm_standalone_minimum_trace_per_minute_has_no_downstream_propagation( - tracer, sca_enabled, appsec_enabled, iast_enabled # noqa: F811 + tracer, # noqa: F811 + sca_enabled, + appsec_enabled, + iast_enabled, # noqa: F811 ): if not appsec_enabled and not iast_enabled and sca_enabled == "false": pytest.skip("SCA, AppSec or IAST must be enabled") @@ -361,7 +364,10 @@ def test_asm_standalone_minimum_trace_per_minute_has_no_downstream_propagation( @pytest.mark.parametrize("appsec_enabled", [True, False]) @pytest.mark.parametrize("iast_enabled", [True, False]) def test_asm_standalone_missing_propagation_tags_no_appsec_event_trace_dropped( - tracer, sca_enabled, appsec_enabled, iast_enabled # noqa: F811 + tracer, # noqa: F811 + sca_enabled, + appsec_enabled, + iast_enabled, # noqa: F811 ): if not appsec_enabled and not iast_enabled and sca_enabled == "false": pytest.skip("SCA, AppSec or IAST must be enabled") @@ -440,7 +446,10 @@ def test_asm_standalone_missing_propagation_tags_appsec_event_present_trace_kept @pytest.mark.parametrize("appsec_enabled", [True, False]) @pytest.mark.parametrize("iast_enabled", [True, False]) def test_asm_standalone_missing_appsec_tag_no_appsec_event_propagation_resets( - tracer, sca_enabled, appsec_enabled, iast_enabled # noqa: F811 + tracer, # noqa: F811 + sca_enabled, + appsec_enabled, + iast_enabled, # noqa: F811 ): if not appsec_enabled and not iast_enabled and sca_enabled == "false": pytest.skip("SCA, AppSec or IAST must be enabled") @@ -548,7 +557,11 @@ def test_asm_standalone_missing_appsec_tag_appsec_event_present_trace_kept( @pytest.mark.parametrize("appsec_enabled", [True, False]) @pytest.mark.parametrize("iast_enabled", [True, False]) def test_asm_standalone_present_appsec_tag_no_appsec_event_propagation_set_to_user_keep( - tracer, upstream_priority, sca_enabled, appsec_enabled, iast_enabled # noqa: F811 + tracer, # noqa: F811 + upstream_priority, + sca_enabled, + appsec_enabled, + iast_enabled, # noqa: F811 ): if not appsec_enabled and not iast_enabled and sca_enabled == "false": pytest.skip("SCA, AppSec or IAST must be enabled") @@ -616,7 +629,11 @@ def test_asm_standalone_present_appsec_tag_no_appsec_event_propagation_set_to_us @pytest.mark.parametrize("appsec_enabled", [True, False]) @pytest.mark.parametrize("iast_enabled", [True, False]) def test_asm_standalone_present_appsec_tag_appsec_event_present_propagation_force_keep( - tracer, upstream_priority, sca_enabled, appsec_enabled, iast_enabled # noqa: F811 + tracer, # noqa: F811 + upstream_priority, + sca_enabled, + appsec_enabled, + iast_enabled, # noqa: F811 ): if not appsec_enabled and not iast_enabled and sca_enabled == "false": pytest.skip("SCA, AppSec or IAST must be enabled") @@ -2568,9 +2585,7 @@ def test_DD_TRACE_PROPAGATION_STYLE_EXTRACT_overrides_DD_TRACE_PROPAGATION_STYLE "sampling_priority": context.sampling_priority, "dd_origin": context.dd_origin, }})) - """.format( - headers - ) + """.format(headers) env = os.environ.copy() if styles is not None: env["DD_TRACE_PROPAGATION_STYLE"] = ",".join(styles) @@ -3272,9 +3287,7 @@ def test_propagation_inject(name, styles, context, expected_headers, run_python_ HTTPPropagator.inject(context, headers) print(json.dumps(headers)) - """.format( - context - ) + """.format(context) env = os.environ.copy() if styles is not None: @@ -3339,9 +3352,7 @@ def test_DD_TRACE_PROPAGATION_STYLE_INJECT_overrides_DD_TRACE_PROPAGATION_STYLE( HTTPPropagator.inject(context, headers) print(json.dumps(headers)) - """.format( - context - ) + """.format(context) env = os.environ.copy() if styles is not None: @@ -3422,9 +3433,9 @@ def test_baggageheader_maxbytes_inject(): # multiple baggage items to test dropping items when the total size exceeds the limit headers = {} baggage_items = { - "key1": "a" * ((DD_TRACE_BAGGAGE_MAX_BYTES // 3)), - "key2": "b" * ((DD_TRACE_BAGGAGE_MAX_BYTES // 3)), - "key3": "c" * ((DD_TRACE_BAGGAGE_MAX_BYTES // 3)), + "key1": "a" * (DD_TRACE_BAGGAGE_MAX_BYTES // 3), + "key2": "b" * (DD_TRACE_BAGGAGE_MAX_BYTES // 3), + "key3": "c" * (DD_TRACE_BAGGAGE_MAX_BYTES // 3), "key4": "d", } span_context = Context(baggage=baggage_items) diff --git a/tests/tracer/test_sampler.py b/tests/tracer/test_sampler.py index f68fe0bad98..ba3a9a6ee0a 100644 --- a/tests/tracer/test_sampler.py +++ b/tests/tracer/test_sampler.py @@ -98,15 +98,15 @@ def test_deterministic_behavior(self): span.finish() samples = tracer.pop() - assert ( - len(samples) == 1 - ), f"DummyTracer should always store a single span, regardless of sampling decision {samples}" + assert len(samples) == 1, ( + f"DummyTracer should always store a single span, regardless of sampling decision {samples}" + ) sampled = len(samples) == 1 and samples[0].context.sampling_priority > 0 for _ in range(10): other_span = Span(str(i), trace_id=span.trace_id) - assert sampled == tracer._sampler.sample( - other_span - ), "sampling should give the same result for a given trace_id" + assert sampled == tracer._sampler.sample(other_span), ( + "sampling should give the same result for a given trace_id" + ) def test_deterministic_behavior_with_list_of_trace_ids(self): """Test that specific trace IDs are consistently kept or dropped""" @@ -144,9 +144,9 @@ def test_negative_sample_rate_raises_error(self): def test_sample_rate_0_does_not_reset_to_1(self): tracer = DummyTracer() tracer._sampler = RateSampler(sample_rate=0) - assert ( - tracer._sampler.sample_rate == 0 - ), "Setting the sample rate to zero should result in the sample rate being zero" + assert tracer._sampler.sample_rate == 0, ( + "Setting the sample rate to zero should result in the sample rate being zero" + ) # RateByServiceSamplerTest Cases @@ -155,21 +155,21 @@ def test_default_key(): def test_key(): - assert DatadogSampler._default_key == DatadogSampler._key( - None, None - ), "_key() with None arguments returns the default key" - assert "service:mcnulty,env:" == DatadogSampler._key( - service="mcnulty", env=None - ), "_key call with service name returns expected result" - assert "service:,env:test" == DatadogSampler._key( - None, env="test" - ), "_key call with env name returns expected result" - assert "service:mcnulty,env:test" == DatadogSampler._key( - service="mcnulty", env="test" - ), "_key call with service and env name returns expected result" - assert "service:mcnulty,env:test" == DatadogSampler._key( - "mcnulty", "test" - ), "_key call with service and env name as positional args returns expected result" + assert DatadogSampler._default_key == DatadogSampler._key(None, None), ( + "_key() with None arguments returns the default key" + ) + assert "service:mcnulty,env:" == DatadogSampler._key(service="mcnulty", env=None), ( + "_key call with service name returns expected result" + ) + assert "service:,env:test" == DatadogSampler._key(None, env="test"), ( + "_key call with env name returns expected result" + ) + assert "service:mcnulty,env:test" == DatadogSampler._key(service="mcnulty", env="test"), ( + "_key call with service and env name returns expected result" + ) + assert "service:mcnulty,env:test" == DatadogSampler._key("mcnulty", "test"), ( + "_key call with service and env name as positional args returns expected result" + ) @pytest.mark.parametrize( @@ -188,9 +188,9 @@ def test_key(): ) def test_sampling_rule_init_sample_rate(sample_rate, expectation): rule = SamplingRule(sample_rate=sample_rate) - assert rule.sample_rate == ( - sample_rate if expectation is True else expectation - ), "SamplingRule should store the rate it's initialized with" + assert rule.sample_rate == (sample_rate if expectation is True else expectation), ( + "SamplingRule should store the rate it's initialized with" + ) def test_sampling_rule_init_defaults(): @@ -539,18 +539,18 @@ def test_sampling_rule_sample_rate_1(): rule = SamplingRule(sample_rate=1) iterations = int(1e4) - assert all( - rule.sample(Span(name=str(i))) for i in range(iterations) - ), "SamplingRule with rate=1 should always keep samples" + assert all(rule.sample(Span(name=str(i))) for i in range(iterations)), ( + "SamplingRule with rate=1 should always keep samples" + ) def test_sampling_rule_sample_rate_0(): rule = SamplingRule(sample_rate=0) iterations = int(1e4) - assert ( - sum(rule.sample(Span(name=str(i))) for i in range(iterations)) == 0 - ), "SamplingRule with rate=0 should never keep samples" + assert sum(rule.sample(Span(name=str(i))) for i in range(iterations)) == 0, ( + "SamplingRule with rate=0 should never keep samples" + ) @pytest.mark.subprocess( @@ -600,19 +600,19 @@ def test_partial_flush_with_sampling_rules(): def test_datadog_sampler_init(): sampler = DatadogSampler() assert sampler.rules == [], "DatadogSampler initialized with no arguments should hold no rules" - assert isinstance( - sampler.limiter, RateLimiter - ), "DatadogSampler initialized with no arguments should hold a RateLimiter" - assert ( - sampler.limiter.rate_limit == DEFAULT_SAMPLING_RATE_LIMIT - ), "DatadogSampler initialized with no arguments should hold a RateLimiter with the default limit" + assert isinstance(sampler.limiter, RateLimiter), ( + "DatadogSampler initialized with no arguments should hold a RateLimiter" + ) + assert sampler.limiter.rate_limit == DEFAULT_SAMPLING_RATE_LIMIT, ( + "DatadogSampler initialized with no arguments should hold a RateLimiter with the default limit" + ) rule = SamplingRule(sample_rate=1) sampler = DatadogSampler(rules=[rule]) assert sampler.rules == [rule], "DatadogSampler initialized with a rule should hold that rule" - assert ( - sampler.limiter.rate_limit == DEFAULT_SAMPLING_RATE_LIMIT - ), "DatadogSampler initialized with a rule should hold the default rate limit" + assert sampler.limiter.rate_limit == DEFAULT_SAMPLING_RATE_LIMIT, ( + "DatadogSampler initialized with a rule should hold the default rate limit" + ) sampler = DatadogSampler(rate_limit=10) assert sampler.limiter.rate_limit == 10, "DatadogSampler initialized with a rate limit should hold that rate limit" @@ -793,9 +793,9 @@ def test_datadog_sampler_sample_rules(sampler, sampling_priority, sampling_mecha spans = dummy_tracer.pop() assert len(spans) > 0, "A tracer using DatadogSampler should always emit its spans" span = spans[0] - assert ( - span.context.sampling_priority is not None - ), "A span emitted from a tracer using DatadogSampler should always have the 'sampled' flag set" + assert span.context.sampling_priority is not None, ( + "A span emitted from a tracer using DatadogSampler should always have the 'sampled' flag set" + ) trace_tag = "-%d" % sampling_mechanism if sampling_mechanism is not None else None assert_sampling_decision_tags( span, rule=rule, limit=limit, sampling_priority=sampling_priority, trace_tag=trace_tag diff --git a/tests/tracer/test_span.py b/tests/tracer/test_span.py index b68d7e53e0c..95ddd2641ec 100644 --- a/tests/tracer/test_span.py +++ b/tests/tracer/test_span.py @@ -302,9 +302,9 @@ def wrapper(): # ZeroDivisionError: division by zero header_and_footer_lines += 1 - assert ( - len(stack.splitlines()) == tb_length_limit * multiplier + header_and_footer_lines - ), "stacktrace should contain two lines per entry" + assert len(stack.splitlines()) == tb_length_limit * multiplier + header_and_footer_lines, ( + "stacktrace should contain two lines per entry" + ) def test_ctx_mgr(self): s = Span("bar") diff --git a/tests/vendor/msgpack/test_case.py b/tests/vendor/msgpack/test_case.py index cb8b20eb546..4016fa7a332 100644 --- a/tests/vendor/msgpack/test_case.py +++ b/tests/vendor/msgpack/test_case.py @@ -100,7 +100,7 @@ def test_match(): b"\x8f\x00\x00\x01\x01\x02\x02\x03\x03\x04" b"\x04\x05\x05\x06\x06\x07\x07\x08\x08\t\t" b"\n\n\x0b\x0b\x0c\x0c\r\r\x0e\x0e" - ) + ), ), ( dict([(x, x) for x in range(16)]), @@ -108,7 +108,7 @@ def test_match(): b"\xde\x00\x10\x00\x00\x01\x01\x02\x02\x03\x03" b"\x04\x04\x05\x05\x06\x06\x07\x07\x08\x08\t\t" b"\n\n\x0b\x0b\x0c\x0c\r\r\x0e\x0e\x0f\x0f" - ) + ), ), ] diff --git a/tests/vendor/msgpack/test_limits.py b/tests/vendor/msgpack/test_limits.py index fda16e25a1c..8063759611d 100644 --- a/tests/vendor/msgpack/test_limits.py +++ b/tests/vendor/msgpack/test_limits.py @@ -17,12 +17,12 @@ def test_integer(): - x = -(2 ** 63) + x = -(2**63) assert unpackb(packb(x)) == x with pytest.raises(PackOverflowError): packb(x - 1) - x = 2 ** 64 - 1 + x = 2**64 - 1 assert unpackb(packb(x)) == x with pytest.raises(PackOverflowError): packb(x + 1) @@ -30,16 +30,16 @@ def test_integer(): def test_array_header(): packer = Packer() - packer.pack_array_header(2 ** 32 - 1) + packer.pack_array_header(2**32 - 1) with pytest.raises(PackValueError): - packer.pack_array_header(2 ** 32) + packer.pack_array_header(2**32) def test_map_header(): packer = Packer() - packer.pack_map_header(2 ** 32 - 1) + packer.pack_map_header(2**32 - 1) with pytest.raises(PackValueError): - packer.pack_array_header(2 ** 32) + packer.pack_array_header(2**32) def test_max_str_len(): diff --git a/tests/vendor/msgpack/test_newspec.py b/tests/vendor/msgpack/test_newspec.py index 7e1ba8fed7d..ada25b2d9dd 100644 --- a/tests/vendor/msgpack/test_newspec.py +++ b/tests/vendor/msgpack/test_newspec.py @@ -6,64 +6,64 @@ def test_str8(): - header = b'\xd9' - data = b'x' * 32 + header = b"\xd9" + data = b"x" * 32 b = packb(data.decode()) assert len(b) == len(data) + 2 - assert b[0:2] == header + b'\x20' + assert b[0:2] == header + b"\x20" assert b[2:] == data assert unpackb(b, raw=True) == data - data = b'x' * 255 + data = b"x" * 255 b = packb(data.decode()) assert len(b) == len(data) + 2 - assert b[0:2] == header + b'\xff' + assert b[0:2] == header + b"\xff" assert b[2:] == data assert unpackb(b, raw=True) == data def test_bin8(): - header = b'\xc4' - data = b'' + header = b"\xc4" + data = b"" b = packb(data) assert len(b) == len(data) + 2 - assert b[0:2] == header + b'\x00' + assert b[0:2] == header + b"\x00" assert b[2:] == data assert unpackb(b) == data - data = b'x' * 255 + data = b"x" * 255 b = packb(data) assert len(b) == len(data) + 2 - assert b[0:2] == header + b'\xff' + assert b[0:2] == header + b"\xff" assert b[2:] == data assert unpackb(b) == data def test_bin16(): - header = b'\xc5' - data = b'x' * 256 + header = b"\xc5" + data = b"x" * 256 b = packb(data) assert len(b) == len(data) + 3 assert b[0:1] == header - assert b[1:3] == b'\x01\x00' + assert b[1:3] == b"\x01\x00" assert b[3:] == data assert unpackb(b) == data - data = b'x' * 65535 + data = b"x" * 65535 b = packb(data) assert len(b) == len(data) + 3 assert b[0:1] == header - assert b[1:3] == b'\xff\xff' + assert b[1:3] == b"\xff\xff" assert b[3:] == data assert unpackb(b) == data def test_bin32(): - header = b'\xc6' - data = b'x' * 65536 + header = b"\xc6" + data = b"x" * 65536 b = packb(data) assert len(b) == len(data) + 5 assert b[0:1] == header - assert b[1:5] == b'\x00\x01\x00\x00' + assert b[1:5] == b"\x00\x01\x00\x00" assert b[5:] == data assert unpackb(b) == data diff --git a/tests/vendor/msgpack/test_read_size.py b/tests/vendor/msgpack/test_read_size.py index 476eef28ff5..565aefee4d9 100644 --- a/tests/vendor/msgpack/test_read_size.py +++ b/tests/vendor/msgpack/test_read_size.py @@ -1,4 +1,5 @@ """Test Unpacker's read_array_header and read_map_header methods""" + from msgpack import OutOfData from msgpack import Unpacker