diff --git a/tests/parametric/test_otel_span_methods.py b/tests/parametric/test_otel_span_methods.py index 71fd786023a..5837fddff8a 100644 --- a/tests/parametric/test_otel_span_methods.py +++ b/tests/parametric/test_otel_span_methods.py @@ -12,6 +12,7 @@ from utils.docker_fixtures.spec.trace import retrieve_span_links from utils.docker_fixtures.spec.trace import find_first_span_in_trace_payload from utils.docker_fixtures import TestAgentAPI +from utils.dd_types import is_same_boolean from utils import features, context, scenarios from .conftest import APMLibrary @@ -191,9 +192,14 @@ def test_otel_set_attributes_different_types_with_array_encoding( assert root_span["name"] == "producer" assert root_span["resource"] == "operation" + # v0.4 stores booleans as strings in meta. With v1.0, tracers can send typed booleans; + # dd-apm-test-agent converts them to numeric 1/0 while normalizing the payload. + # Since numeric values belong in metrics, accept boolean attributes from either map. + meta_or_metrics = {**root_span["meta"], **root_span["metrics"]} + assert root_span["meta"]["str_val"] == "val" assert root_span["meta"]["str_val_empty"] == "" - assert root_span["meta"]["bool_val"] == "true" + assert is_same_boolean(actual=meta_or_metrics.get("bool_val"), expected="true") assert root_span["metrics"]["int_val"] == 1 assert root_span["metrics"]["int_val_zero"] == 0 assert root_span["metrics"]["double_val"] == 4.2 @@ -204,14 +210,14 @@ def test_otel_set_attributes_different_types_with_array_encoding( assert root_span["metrics"]["array_val_int.0"] == 10 assert root_span["metrics"]["array_val_int.1"] == 20 - assert root_span["meta"]["array_val_bool.0"] == "true" - assert root_span["meta"]["array_val_bool.1"] == "false" + assert is_same_boolean(actual=meta_or_metrics.get("array_val_bool.0"), expected="true") + assert is_same_boolean(actual=meta_or_metrics.get("array_val_bool.1"), expected="false") assert root_span["metrics"]["array_val_double.0"] == 10.1 assert root_span["metrics"]["array_val_double.1"] == 20.2 assert root_span["meta"]["d_str_val"] == "bye" - assert root_span["meta"]["d_bool_val"] == "false" + assert is_same_boolean(actual=meta_or_metrics.get("d_bool_val"), expected="false") assert root_span["metrics"]["d_int_val"] == 2 assert root_span["metrics"]["d_double_val"] == 3.14 diff --git a/utils/dd_types/_utils.py b/utils/dd_types/_utils.py index 0918ef3f4ee..ec12582df1d 100644 --- a/utils/dd_types/_utils.py +++ b/utils/dd_types/_utils.py @@ -31,14 +31,15 @@ def get_rid_from_span_data(span_type: str, meta: dict, metrics: dict) -> str | N return get_rid_from_user_agent(user_agent) -# Protocol v1.0 may deserialize meta booleans as True/False; older formats use "true"/"false". -def _normalize_for_compare(*, value: bool | str | None) -> str | None: - if value is True: +# Protocol v1.0 may deserialize meta booleans as True/False; older formats use "true"/"false"; OTel can use 1/0. +def _normalize_for_compare(*, value: bool | int | str | None) -> bool | int | str | None: + if value in (True, 1): return "true" - if value is False: + if value in (False, 0): return "false" + # compare by value as last resort return value -def is_same_boolean(*, actual: bool | str | None, expected: bool | str | None) -> bool: +def is_same_boolean(*, actual: bool | int | str | None, expected: bool | int | str | None) -> bool: return _normalize_for_compare(value=actual) == _normalize_for_compare(value=expected)