diff --git a/pyproject.toml b/pyproject.toml index fad1b990731..83c771ceca8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,18 +34,6 @@ markers =[ python_files = "test_*.py *utils.py" -# migration tooling: list of folders where feature declarations are mandatory -# once every test class got its feature declaration, we can remove this -allow_no_feature_nodes = [ - "tests/apm_tracing_e2e/test_single_span.py", - "tests/apm_tracing_e2e/test_smoke.py", - "tests/otel_tracing_e2e/test_e2e.py", - "tests/parametric/test_span_links.py", - "tests/parametric/test_tracer.py", - "tests/perfs/test_performances.py", # exotic scenario, not really used - "tests/test_the_test/", # Not a real test -] - [tool.mypy] files = [ "utils/", diff --git a/tests/apm_tracing_e2e/test_single_span.py b/tests/apm_tracing_e2e/test_single_span.py index cf975363f9b..1732ac7cd2b 100644 --- a/tests/apm_tracing_e2e/test_single_span.py +++ b/tests/apm_tracing_e2e/test_single_span.py @@ -1,4 +1,4 @@ -from utils import context, weblog, interfaces, rfc, scenarios, missing_feature +from utils import context, weblog, interfaces, rfc, scenarios, missing_feature, features from utils.dd_constants import ( SAMPLING_PRIORITY_KEY, SINGLE_SPAN_SAMPLING_MECHANISM, @@ -11,6 +11,7 @@ @rfc("ATI-2419") @missing_feature(context.agent_version < "7.40", reason="Single Spans is not available in agents pre 7.40.") @scenarios.apm_tracing_e2e_single_span +@features.single_span_ingestion_control class Test_SingleSpan: """This is a test that exercises the Single Span Ingestion Control feature. Read more about Single Span at https://docs.datadoghq.com/tracing/trace_pipeline/ingestion_mechanisms/?tab=java#single-spans diff --git a/tests/apm_tracing_e2e/test_smoke.py b/tests/apm_tracing_e2e/test_smoke.py index cdd5d30de23..7177af3be3d 100644 --- a/tests/apm_tracing_e2e/test_smoke.py +++ b/tests/apm_tracing_e2e/test_smoke.py @@ -1,8 +1,9 @@ -from utils import weblog, interfaces, rfc, scenarios +from utils import weblog, interfaces, rfc, scenarios, features @rfc("https://docs.google.com/document/d/1MtSlvPCKWM4x4amOYAvlKVbJjd0b0oUXxxlX-lo8KN8/edit#") @scenarios.apm_tracing_e2e +@features.not_reported # the scenario is not executed class Test_Backend: """This is a smoke test that exercises the full flow of APM Tracing. It includes trace submission, the trace flowing through the backend processing, diff --git a/tests/otel_tracing_e2e/test_e2e.py b/tests/otel_tracing_e2e/test_e2e.py index f5c31b4b1ff..620d885f76e 100644 --- a/tests/otel_tracing_e2e/test_e2e.py +++ b/tests/otel_tracing_e2e/test_e2e.py @@ -2,7 +2,7 @@ import os import time -from utils import context, weblog, interfaces, scenarios, irrelevant +from utils import context, weblog, interfaces, scenarios, irrelevant, features from utils.tools import logger, get_rid_from_request from utils.otel_validators.validator_trace import validate_all_traces from utils.otel_validators.validator_log import validate_log, validate_log_trace_correlation @@ -18,6 +18,7 @@ def _get_dd_trace_id(otel_trace_id: str, use_128_bits_trace_id: bool) -> int: @scenarios.otel_tracing_e2e @irrelevant(context.library != "java_otel") +@features.not_reported # FPD does not support otel libs class Test_OTelTracingE2E: def setup_main(self): self.use_128_bits_trace_id = False @@ -73,6 +74,7 @@ def test_main(self): @scenarios.otel_metric_e2e @irrelevant(context.library != "java_otel") +@features.not_reported # FPD does not support otel libs class Test_OTelMetricE2E: def setup_main(self): self.start = int(time.time()) @@ -139,6 +141,7 @@ def test_main(self): @scenarios.otel_log_e2e @irrelevant(context.library != "java_otel") +@features.not_reported # FPD does not support otel libs class Test_OTelLogE2E: def setup_main(self): self.r = weblog.get(path="/basic/log") diff --git a/tests/parametric/test_span_links.py b/tests/parametric/test_span_links.py index 975947b6543..07073edfdfd 100644 --- a/tests/parametric/test_span_links.py +++ b/tests/parametric/test_span_links.py @@ -6,11 +6,12 @@ from utils.parametric.spec.trace import AUTO_DROP_KEY from utils.parametric.spec.trace import span_has_no_parent from utils.parametric.spec.tracecontext import TRACECONTEXT_FLAGS_SET -from utils import scenarios, missing_feature +from utils import scenarios, missing_feature, features from utils.parametric.spec.trace import retrieve_span_links, find_span, find_trace, find_span_in_traces @scenarios.parametric +@features.span_links class Test_Span_Links: @pytest.mark.parametrize("library_env", [{"DD_TRACE_API_VERSION": "v0.4"}]) @missing_feature(library="nodejs", reason="only supports span links encoding through _dd.span_links tag") diff --git a/tests/parametric/test_tracer.py b/tests/parametric/test_tracer.py index 8c4c7389b84..c71da9533cd 100644 --- a/tests/parametric/test_tracer.py +++ b/tests/parametric/test_tracer.py @@ -14,6 +14,7 @@ @scenarios.parametric +@features.trace_annotation class Test_Tracer: @missing_feature(context.library == "cpp", reason="metrics cannot be set manually") @missing_feature(context.library == "nodejs", reason="nodejs overrides the manually set service name") @@ -152,6 +153,7 @@ def test_tracer_repository_url_strip_credentials( @scenarios.parametric +@features.dd_service_mapping class Test_TracerUniversalServiceTagging: @missing_feature(reason="FIXME: library test client sets empty string as the service name") @parametrize("library_env", [{"DD_SERVICE": "service1"}]) diff --git a/tests/perfs/test_performances.py b/tests/perfs/test_performances.py index 974b7b26b8d..91d45ad8e64 100644 --- a/tests/perfs/test_performances.py +++ b/tests/perfs/test_performances.py @@ -6,7 +6,7 @@ import requests import docker -from utils import scenarios +from utils import scenarios, features MAX_CONCURRENT_REQUEST = 5 @@ -21,6 +21,7 @@ # WARMUP_LAST_SLEEP_DURATION = 1 # WEBLOG_URL="http://localhost:7777" @scenarios.performances +@features.not_reported class Test_Performances: def setup_main(self) -> None: self.requests: list = [] diff --git a/tests/test_the_test/test_features.py b/tests/test_the_test/test_features.py index 0bb94d0ae32..a307b0eb2fa 100644 --- a/tests/test_the_test/test_features.py +++ b/tests/test_the_test/test_features.py @@ -26,7 +26,6 @@ def test_not_reported(): @scenarios.test_the_test def test_all_class_has_feature_decorator(session, deselected_items): - allow_no_feature_nodes = session.config.inicfg["allow_no_feature_nodes"] processed_nodes = set() shouldfail = False @@ -38,14 +37,8 @@ def test_all_class_has_feature_decorator(session, deselected_items): processed_nodes.add(reported_node_id) - allow_missing_declaration = False - - for node in allow_no_feature_nodes: - if item.nodeid.startswith(node): - allow_missing_declaration = True - break - - if allow_missing_declaration: + if item.nodeid.startswith("tests/test_the_test/"): + # special use case of test the test folder continue declared_features = [marker.kwargs["feature_id"] for marker in item.iter_markers("features")] diff --git a/utils/_features.py b/utils/_features.py index baf77fddf4d..a8a766cb057 100644 --- a/utils/_features.py +++ b/utils/_features.py @@ -2399,5 +2399,14 @@ def stable_configuration_support(test_object): pytest.mark.features(feature_id=365)(test_object) return test_object + @staticmethod + def single_span_ingestion_control(test_object): + """Enforces that basic stable configuration support exists + + https://feature-parity.us1.prod.dog/#/?feature=366 + """ + pytest.mark.features(feature_id=366)(test_object) + return test_object + features = _Features()