diff --git a/tests/test_the_test/test_ci_orchestrator.py b/tests/test_the_test/test_ci_orchestrator.py index 269e5e1d7db..7f1b2fc7644 100644 --- a/tests/test_the_test/test_ci_orchestrator.py +++ b/tests/test_the_test/test_ci_orchestrator.py @@ -1,11 +1,12 @@ from functools import lru_cache +from pathlib import Path -from utils import scenarios +from utils import scenarios, logger +from utils.const import COMPONENT_GROUPS from utils._context.weblog_metadata import WeblogMetaData - +from utils._context._scenarios import get_all_scenarios, Scenario from utils.scripts.ci_orchestrators.workflow_data import ( _get_endtoend_weblogs, - _is_supported, get_endtoend_definitions, ) @@ -42,9 +43,12 @@ def test_get_endtoend_definitions(): @scenarios.test_the_test def test_ipv6_is_not_supported_for_uds_weblogs(): - assert not _is_supported(get_weblog("dotnet", "uds"), scenarios.ipv6, "dev") - assert not _is_supported(get_weblog("python", "uds-flask"), scenarios.ipv6, "dev") - assert _is_supported(get_weblog("python", "flask-poc"), scenarios.ipv6, "dev") + def _is_supported(weblog: WeblogMetaData, scenario: Scenario) -> bool: + return weblog.support_scenario(scenario.name, scenario.weblog_categories) + + assert not _is_supported(get_weblog("dotnet", "uds"), scenarios.ipv6) + assert not _is_supported(get_weblog("python", "uds-flask"), scenarios.ipv6) + assert _is_supported(get_weblog("python", "flask-poc"), scenarios.ipv6) @scenarios.test_the_test @@ -139,3 +143,155 @@ def test_otel_collector(): "weblog_instance": 1, } ] + + +@scenarios.test_the_test +def test_legacy_scenario_matrix(): + has_error = False + + for library in sorted(COMPONENT_GROUPS.all): + for weblog in sorted(WeblogMetaData.load(library), key=lambda w: w.name): + for scenario in get_all_scenarios(): + legacy = _is_supported_legacy(weblog, scenario, "") + new_value = weblog.support_scenario(scenario.name, scenario.weblog_categories) + if legacy is not new_value: + has_error = True + logger.error((library, legacy, new_value, weblog.name, scenario.name, scenario.weblog_categories)) + + assert not has_error + + +@scenarios.test_the_test +def test_weblog_metadata_scenario_names_are_valid(): + valid_names = {scenario.name for scenario in get_all_scenarios()} + + for library in sorted(COMPONENT_GROUPS.all): + for weblog in WeblogMetaData.load(library): + for scenario_name in weblog.supported_scenarios + weblog.excluded_scenarios: + assert scenario_name in valid_names, ( + f"{library}/{weblog.name}: '{scenario_name}' is not a known scenario name " + f"(check utils/build/docker/{library}/weblog_metadata.yml)" + ) + + +@scenarios.test_the_test +def test_all_weblog_has_metadata(): + for library in sorted(COMPONENT_GROUPS.all): + folder = Path(f"utils/build/docker/{library}") + if folder.exists(): # some lib does not have any weblog + names = [ + f.name.replace(".Dockerfile", "") + for f in folder.iterdir() + if f.suffix == ".Dockerfile" and ".base." not in f.name and f.is_file() + ] + + known_weblog_names = {w.name.split("@")[0] for w in WeblogMetaData.load(library)} + + for name in names: + assert name in known_weblog_names, ( + f"Please add {name} in utils/build/docker/{library}/weblog_metadata.yml" + ) + + +# copy of the old function to test compatibility. To be removed once all good +def _is_supported_legacy(weblog: WeblogMetaData, scenario: Scenario, _ci_environment: str) -> bool: + # this function will remove some couple scenarios/weblog that are not supported + + def _is_uds_weblog(weblog: str) -> bool: + return weblog == "uds" or weblog.startswith("uds-") + + if scenario.github_workflow != "endtoend": + return False + + library = weblog.library + weblog_name = weblog.name + + # Only Allow Lambda scenarios for the lambda libraries + is_lambda_library = library in ( + "python_lambda", + "java_lambda", + "nodejs_lambda", + "ruby_lambda", + ) + is_lambda_scenario = scenario.name in ( + "APPSEC_LAMBDA_DEFAULT", + "APPSEC_LAMBDA_BLOCKING", + "APPSEC_LAMBDA_API_SECURITY", + "APPSEC_LAMBDA_RASP", + "APPSEC_LAMBDA_INFERRED_SPANS", + ) + if is_lambda_library != is_lambda_scenario: + return False + + # open-telemetry-automatic + if scenario.name == "OTEL_INTEGRATIONS": + possible_values: tuple = ( + ("java_otel", "spring-boot-otel"), + ("nodejs_otel", "express4-otel"), + ("python_otel", "flask-poc-otel"), + ) + if (library, weblog_name) not in possible_values: + return False + + # open-telemetry-manual + if scenario.name in ("OTEL_LOG_E2E", "OTEL_METRIC_E2E", "OTEL_TRACING_E2E"): + if (library, weblog_name) != ("java_otel", "spring-boot-native"): + return False + + if scenario.name in ("GRAPHQL_APPSEC", "GRAPHQL_ERROR_TRACKING"): + possible_values: tuple = ( + ("golang", "gqlgen"), + ("golang", "graph-gophers"), + ("golang", "graphql-go"), + ("ruby", "graphql23"), + ("nodejs", "express4"), + ("nodejs", "uds-express4"), + ("nodejs", "express4-typescript"), + ("nodejs", "express5"), + ) + if (library, weblog_name) not in possible_values: + return False + + if scenario.name in ("PERFORMANCES",): + return False + + if scenario.name == "IPV6": + if library == "ruby" or _is_uds_weblog(weblog_name): + return False + + if scenario.name in ("CROSSED_TRACING_LIBRARIES",): + if weblog_name in ("python3.12", "django-py3.13", "spring-boot-payara"): + # python 3.13 issue : APMAPI-1096 + return False + + if scenario.name in ("APPSEC_MISSING_RULES", "APPSEC_CORRUPTED_RULES") and library in ("cpp_nginx", "cpp_httpd"): + # C++ 1.2.0 freeze when the rules file is missing + return False + + if weblog_name in ["gqlgen", "graph-gophers", "graphql-go", "graphql23"]: + if scenario.name not in ("GRAPHQL_APPSEC",): + return False + + # open-telemetry-manual + if weblog_name == "spring-boot-native": + if scenario.name not in ("OTEL_LOG_E2E", "OTEL_METRIC_E2E", "OTEL_TRACING_E2E"): + return False + + # open-telemetry-automatic + if weblog_name in ["express4-otel", "flask-poc-otel", "spring-boot-otel"]: + if scenario.name not in ("OTEL_INTEGRATIONS",): + return False + + # Go proxies + if weblog.name in ("envoy", "haproxy"): + if scenario.name not in ("DEFAULT", "APPSEC_BLOCKING"): + return False + + # otel collector + if weblog_name == "otel_collector" or scenario.name in ("OTEL_COLLECTOR", "OTEL_COLLECTOR_E2E"): + return weblog_name == "otel_collector" and scenario.name in ("OTEL_COLLECTOR", "OTEL_COLLECTOR_E2E") + + if "@" in weblog_name or scenario.name == "INTEGRATION_FRAMEWORKS": + return "@" in weblog_name and scenario.name == "INTEGRATION_FRAMEWORKS" + + return True diff --git a/tests/test_the_test/test_minimal_number_of_scenarios.py b/tests/test_the_test/test_minimal_number_of_scenarios.py index 045896b5f37..748619e4b17 100644 --- a/tests/test_the_test/test_minimal_number_of_scenarios.py +++ b/tests/test_the_test/test_minimal_number_of_scenarios.py @@ -4,7 +4,9 @@ import pytest -from utils._context._scenarios import get_all_scenarios, EndToEndScenario, scenarios +from utils._context._scenarios import get_all_scenarios, scenarios +from utils._context._scenarios.endtoend import EndToEndScenario +from utils._context._scenarios.debugger import DebuggerScenario from utils import logger # Map of scenario pairs that cannot be merged and their specific reasons @@ -58,9 +60,11 @@ def test_minimal_number_of_scenarios(): - LEVEL 1 + LEVEL 3: scenarios_are_equivalent == True AND one_env_can_be_included_in_other == True """ - # Filter only scenarios that are exactly EndToEndScenario class (not subclasses) + # Filter scenarios that are EndToEndScenario or one of its subclasses endtoend_scenarios: list[EndToEndScenario] = [ - scenario for scenario in get_all_scenarios() if type(scenario) is EndToEndScenario + scenario + for scenario in get_all_scenarios() + if isinstance(scenario, EndToEndScenario) and not isinstance(scenario, DebuggerScenario) ] # sort keys in SKIP_MERGE_SCENARIOS diff --git a/utils/_context/_scenarios/__init__.py b/utils/_context/_scenarios/__init__.py index 8f34e1c92c9..885fbb06ded 100644 --- a/utils/_context/_scenarios/__init__.py +++ b/utils/_context/_scenarios/__init__.py @@ -7,7 +7,7 @@ from .aws_lambda import LambdaScenario from .core import Scenario, scenario_groups from .default import DefaultScenario -from .endtoend import DockerScenario, EndToEndScenario +from .endtoend import DockerScenario, DdTraceEndToEndScenario, GraphQlEndToEndScenario from .integrations import ( CrossedTracingLibraryScenario, DbmDynamicServiceScenario, @@ -86,7 +86,7 @@ class _Scenarios: profiling = ProfilingScenario("PROFILING") - trace_stats_computation = EndToEndScenario( + trace_stats_computation = DdTraceEndToEndScenario( name="TRACE_STATS_COMPUTATION", # feature consistency is poorly respected here ... weblog_env={ @@ -103,7 +103,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - trace_stats_computation_client_drop_p0s_false = EndToEndScenario( + trace_stats_computation_client_drop_p0s_false = DdTraceEndToEndScenario( name="TRACE_STATS_COMPUTATION_CLIENT_DROP_P0S_FALSE", # Same as trace_stats_computation but with client_drop_p0s set to false # to test tracer behavior when agent doesn't support client-side P0 dropping @@ -122,7 +122,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - trace_stats_computation_future_obfuscation_version = EndToEndScenario( + trace_stats_computation_future_obfuscation_version = DdTraceEndToEndScenario( name="TRACE_STATS_COMPUTATION_FUTURE_OBFUSCATION_VERSION", # Same as trace_stats_computation but with the agent advertising an obfuscation_version # higher than what any current SDK supports (99), to test that the SDK correctly falls @@ -143,7 +143,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - trace_stats_computation_missing_obfuscation_version = EndToEndScenario( + trace_stats_computation_missing_obfuscation_version = DdTraceEndToEndScenario( name="TRACE_STATS_COMPUTATION_MISSING_OBFUSCATION_VERSION", # Same as trace_stats_computation but with the agent not advertising obfuscation_version # in /info, to test that the SDK correctly falls back to no client-side obfuscation. @@ -163,7 +163,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - trace_stats_computation_obfuscation_version_zero = EndToEndScenario( + trace_stats_computation_obfuscation_version_zero = DdTraceEndToEndScenario( name="TRACE_STATS_COMPUTATION_OBFUSCATION_VERSION_ZERO", # Same as trace_stats_computation but with the agent advertising obfuscation_version=0, # to test that the SDK treats version 0 as "not supported" and skips client-side obfuscation. @@ -183,7 +183,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - trace_stats_computation_obfuscation_disabled = EndToEndScenario( + trace_stats_computation_obfuscation_disabled = DdTraceEndToEndScenario( name="TRACE_STATS_COMPUTATION_OBFUSCATION_DISABLED", # Same as trace_stats_computation but with the agent being configured with obfuscation disabled, to test that # the SDK correctly reads the obfuscation config from agent's /info and respects it. @@ -201,7 +201,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - trace_stats_computation_error_sampler = EndToEndScenario( + trace_stats_computation_error_sampler = DdTraceEndToEndScenario( name="TRACE_STATS_COMPUTATION_ERROR_SAMPLER", # Same as trace_stats_computation but with the trace sample rate set to 0, so that all traces # are P0 and would normally be dropped by the tracer. Error traces must still be sent to the @@ -220,7 +220,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - sampling = EndToEndScenario( + sampling = DdTraceEndToEndScenario( "SAMPLING", tracer_sampling_rate=0.5, weblog_env={"DD_TRACE_RATE_LIMIT": "10000000", "DD_TRACE_STATS_COMPUTATION_ENABLED": "false"}, @@ -228,14 +228,14 @@ class _Scenarios: scenario_groups=[scenario_groups.sampling], ) - sampling_rate_capping = EndToEndScenario( + sampling_rate_capping = DdTraceEndToEndScenario( "SAMPLING_RATE_CAPPING", weblog_env={"DD_TRACE_RATE_LIMIT": "10000000", "DD_TRACE_STATS_COMPUTATION_ENABLED": "false"}, doc="Test that tracers cap sampling rate increases to 2x per interval when agent restarts", scenario_groups=[scenario_groups.sampling], ) - trace_propagation_style_w3c = EndToEndScenario( + trace_propagation_style_w3c = DdTraceEndToEndScenario( "TRACE_PROPAGATION_STYLE_W3C", weblog_env={ "DD_TRACE_PROPAGATION_STYLE_INJECT": "tracecontext", @@ -245,14 +245,14 @@ class _Scenarios: ) # Telemetry scenarios - telemetry_dependency_loaded_test_for_dependency_collection_disabled = EndToEndScenario( + telemetry_dependency_loaded_test_for_dependency_collection_disabled = DdTraceEndToEndScenario( "TELEMETRY_DEPENDENCY_LOADED_TEST_FOR_DEPENDENCY_COLLECTION_DISABLED", weblog_env={"DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED": "false"}, doc="Test DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED=false effect on tracers", scenario_groups=[scenario_groups.telemetry], ) - telemetry_app_started_products_disabled = EndToEndScenario( + telemetry_app_started_products_disabled = DdTraceEndToEndScenario( "TELEMETRY_APP_STARTED_PRODUCTS_DISABLED", weblog_env={ "DD_APPSEC_ENABLED": "false", @@ -264,7 +264,7 @@ class _Scenarios: scenario_groups=[scenario_groups.telemetry], ) - telemetry_enhanced_config_reporting = EndToEndScenario( + telemetry_enhanced_config_reporting = DdTraceEndToEndScenario( "TELEMETRY_ENHANCED_CONFIG_REPORTING", weblog_env={ "DD_LOGS_INJECTION": "false", @@ -275,19 +275,19 @@ class _Scenarios: scenario_groups=[scenario_groups.telemetry], ) - telemetry_log_generation_disabled = EndToEndScenario( + telemetry_log_generation_disabled = DdTraceEndToEndScenario( "TELEMETRY_LOG_GENERATION_DISABLED", weblog_env={"DD_TELEMETRY_LOG_COLLECTION_ENABLED": "false"}, doc="Test env var `DD_TELEMETRY_LOG_COLLECTION_ENABLED=false`", scenario_groups=[scenario_groups.telemetry], ) - telemetry_metric_generation_disabled = EndToEndScenario( + telemetry_metric_generation_disabled = DdTraceEndToEndScenario( "TELEMETRY_METRIC_GENERATION_DISABLED", weblog_env={"DD_TELEMETRY_METRICS_ENABLED": "false"}, doc="Test env var `DD_TELEMETRY_METRICS_ENABLED=false`", scenario_groups=[scenario_groups.telemetry], ) - telemetry_extended_heartbeat = EndToEndScenario( + telemetry_extended_heartbeat = DdTraceEndToEndScenario( "TELEMETRY_EXTENDED_HEARTBEAT", weblog_env={ "DD_TELEMETRY_HEARTBEAT_INTERVAL": "1", @@ -299,13 +299,13 @@ class _Scenarios: ) # ASM scenarios - appsec_missing_rules = EndToEndScenario( + appsec_missing_rules = DdTraceEndToEndScenario( "APPSEC_MISSING_RULES", weblog_env={"DD_APPSEC_RULES": "/donotexists"}, doc="Test missing appsec rules file", scenario_groups=[scenario_groups.appsec], ) - appsec_corrupted_rules = EndToEndScenario( + appsec_corrupted_rules = DdTraceEndToEndScenario( "APPSEC_CORRUPTED_RULES", weblog_env={"DD_APPSEC_RULES": "/appsec_corrupted_rules.json"}, weblog_volumes={ @@ -314,14 +314,14 @@ class _Scenarios: doc="Test corrupted appsec rules file", scenario_groups=[scenario_groups.appsec], ) - appsec_custom_rules = EndToEndScenario( + appsec_custom_rules = DdTraceEndToEndScenario( "APPSEC_CUSTOM_RULES", weblog_env={"DD_APPSEC_RULES": "/appsec_custom_rules.json"}, weblog_volumes={"./tests/appsec/custom_rules.json": {"bind": "/appsec_custom_rules.json", "mode": "ro"}}, doc="Test custom appsec rules file", scenario_groups=[scenario_groups.appsec], ) - appsec_blocking = EndToEndScenario( + appsec_blocking = DdTraceEndToEndScenario( "APPSEC_BLOCKING", weblog_env={ "DD_APPSEC_RULES": "/appsec_blocking_rule.json", @@ -336,7 +336,7 @@ class _Scenarios: ) # This GraphQL scenario can be used for any GraphQL testing, not just AppSec - graphql_appsec = EndToEndScenario( + graphql_appsec = GraphQlEndToEndScenario( "GRAPHQL_APPSEC", weblog_env={ "DD_APPSEC_RULES": "/appsec_blocking_rule.json", @@ -344,11 +344,10 @@ class _Scenarios: }, weblog_volumes={"./tests/appsec/blocking_rule.json": {"bind": "/appsec_blocking_rule.json", "mode": "ro"}}, doc="AppSec tests for GraphQL integrations", - github_workflow="endtoend", scenario_groups=[scenario_groups.appsec, scenario_groups.graphql], ) # This GraphQL scenario can be used for any GraphQL testing, not just AppSec - graphql_error_tracking = EndToEndScenario( + graphql_error_tracking = GraphQlEndToEndScenario( "GRAPHQL_ERROR_TRACKING", weblog_env={ "DD_TRACE_GRAPHQL_ERROR_EXTENSIONS": "int,float,str,bool,other", @@ -356,10 +355,9 @@ class _Scenarios: }, weblog_volumes={"./tests/appsec/blocking_rule.json": {"bind": "/appsec_blocking_rule.json", "mode": "ro"}}, doc="GraphQL error tracking tests with OpenTelemetry semantics", - github_workflow="endtoend", scenario_groups=[scenario_groups.appsec, scenario_groups.graphql], ) - appsec_rules_monitoring_with_errors = EndToEndScenario( + appsec_rules_monitoring_with_errors = DdTraceEndToEndScenario( "APPSEC_RULES_MONITORING_WITH_ERRORS", weblog_env={"DD_APPSEC_RULES": "/appsec_custom_rules_with_errors.json"}, weblog_volumes={ @@ -371,7 +369,7 @@ class _Scenarios: doc="Appsec rule file with some errors", scenario_groups=[scenario_groups.appsec], ) - everything_disabled = EndToEndScenario( + everything_disabled = DdTraceEndToEndScenario( "EVERYTHING_DISABLED", weblog_env={"DD_APPSEC_ENABLED": "false", "DD_DBM_PROPAGATION_MODE": "disabled"}, appsec_enabled=False, @@ -382,7 +380,7 @@ class _Scenarios: appsec_low_waf_timeout = AppsecLowWafTimeout("APPSEC_LOW_WAF_TIMEOUT") - appsec_custom_obfuscation = EndToEndScenario( + appsec_custom_obfuscation = DdTraceEndToEndScenario( "APPSEC_CUSTOM_OBFUSCATION", weblog_env={ "DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP": "hide-key", @@ -391,13 +389,13 @@ class _Scenarios: doc="Test custom appsec obfuscation parameters", scenario_groups=[scenario_groups.appsec], ) - appsec_rate_limiter = EndToEndScenario( + appsec_rate_limiter = DdTraceEndToEndScenario( "APPSEC_RATE_LIMITER", weblog_env={"DD_APPSEC_TRACE_RATE_LIMIT": "1", "RAILS_MAX_THREADS": "1"}, doc="Tests with a low rate trace limit for Appsec", scenario_groups=[scenario_groups.appsec], ) - appsec_waf_telemetry = EndToEndScenario( + appsec_waf_telemetry = DdTraceEndToEndScenario( "APPSEC_WAF_TELEMETRY", weblog_env={ "DD_INSTRUMENTATION_TELEMETRY_ENABLED": "true", @@ -408,7 +406,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - appsec_blocking_full_denylist = EndToEndScenario( + appsec_blocking_full_denylist = DdTraceEndToEndScenario( "APPSEC_BLOCKING_FULL_DENYLIST", rc_api_enabled=True, weblog_env={"DD_APPSEC_RULES": None}, @@ -423,7 +421,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - appsec_runtime_activation = EndToEndScenario( + appsec_runtime_activation = DdTraceEndToEndScenario( "APPSEC_RUNTIME_ACTIVATION", rc_api_enabled=True, appsec_enabled=False, @@ -433,7 +431,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec, scenario_groups.appsec_rasp], ) - appsec_api_security = EndToEndScenario( + appsec_api_security = DdTraceEndToEndScenario( "APPSEC_API_SECURITY", appsec_enabled=True, weblog_env={ @@ -452,7 +450,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - appsec_api_security_rc = EndToEndScenario( + appsec_api_security_rc = DdTraceEndToEndScenario( "APPSEC_API_SECURITY_RC", weblog_env={ "DD_EXPERIMENTAL_API_SECURITY_ENABLED": "true", @@ -469,7 +467,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec, scenario_groups.remote_config, scenario_groups.essentials], ) - appsec_api_security_no_response_body = EndToEndScenario( + appsec_api_security_no_response_body = DdTraceEndToEndScenario( "APPSEC_API_SECURITY_NO_RESPONSE_BODY", appsec_enabled=True, weblog_env={ @@ -486,7 +484,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - appsec_api_security_with_sampling = EndToEndScenario( + appsec_api_security_with_sampling = DdTraceEndToEndScenario( "APPSEC_API_SECURITY_WITH_SAMPLING", appsec_enabled=True, weblog_env={ @@ -501,7 +499,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec, scenario_groups.essentials], ) - appsec_auto_events_extended = EndToEndScenario( + appsec_auto_events_extended = DdTraceEndToEndScenario( "APPSEC_AUTO_EVENTS_EXTENDED", weblog_env={ "DD_APPSEC_ENABLED": "true", @@ -513,7 +511,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - appsec_auto_events_rc = EndToEndScenario( + appsec_auto_events_rc = DdTraceEndToEndScenario( "APPSEC_AUTO_EVENTS_RC", weblog_env={"DD_APPSEC_ENABLED": "true", "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": "0.5"}, rc_api_enabled=True, @@ -524,7 +522,7 @@ class _Scenarios: other_weblog_containers=(InternalServerContainer,), ) - runtime_sca_reachability = EndToEndScenario( + runtime_sca_reachability = DdTraceEndToEndScenario( "RUNTIME_SCA_REACHABILITY", weblog_env={ "DD_APPSEC_SCA_ENABLED": "true", @@ -535,7 +533,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - appsec_standalone = EndToEndScenario( + appsec_standalone = DdTraceEndToEndScenario( "APPSEC_STANDALONE", weblog_env={ "DD_APPSEC_ENABLED": "true", @@ -551,7 +549,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - appsec_apm_standalone = EndToEndScenario( + appsec_apm_standalone = DdTraceEndToEndScenario( "APPSEC_APM_STANDALONE", rc_api_enabled=True, weblog_env={ @@ -568,7 +566,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - appsec_standalone_apm_standalone = EndToEndScenario( + appsec_standalone_apm_standalone = DdTraceEndToEndScenario( "APPSEC_STANDALONE_APM_STANDALONE", rc_api_enabled=True, weblog_env={ @@ -586,7 +584,7 @@ class _Scenarios: ) # Combined scenario for API Security in standalone mode - appsec_standalone_api_security = EndToEndScenario( + appsec_standalone_api_security = DdTraceEndToEndScenario( "APPSEC_STANDALONE_API_SECURITY", appsec_enabled=True, weblog_env={ @@ -601,7 +599,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec, scenario_groups.essentials], ) - iast_standalone = EndToEndScenario( + iast_standalone = DdTraceEndToEndScenario( "IAST_STANDALONE", weblog_env={ "DD_APPSEC_ENABLED": "false", @@ -617,7 +615,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - sca_standalone = EndToEndScenario( + sca_standalone = DdTraceEndToEndScenario( "SCA_STANDALONE", weblog_env={ "DD_APPSEC_ENABLED": "false", @@ -631,7 +629,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - iast_deduplication = EndToEndScenario( + iast_deduplication = DdTraceEndToEndScenario( "IAST_DEDUPLICATION", weblog_env={ "DD_IAST_ENABLED": "true", @@ -644,7 +642,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - appsec_meta_struct_disabled = EndToEndScenario( + appsec_meta_struct_disabled = DdTraceEndToEndScenario( "APPSEC_META_STRUCT_DISABLED", weblog_env={"DD_APPSEC_ENABLED": "true", "DD_IAST_ENABLED": "true"}, meta_structs_disabled=True, @@ -652,7 +650,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec], ) - remote_config_mocked_backend_asm_features = EndToEndScenario( + remote_config_mocked_backend_asm_features = DdTraceEndToEndScenario( "REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES", rc_api_enabled=True, appsec_enabled=False, @@ -666,7 +664,7 @@ class _Scenarios: scenario_groups=[scenario_groups.appsec, scenario_groups.remote_config, scenario_groups.essentials], ) - remote_config_mocked_backend_live_debugging = EndToEndScenario( + remote_config_mocked_backend_live_debugging = DdTraceEndToEndScenario( "REMOTE_CONFIG_MOCKED_BACKEND_LIVE_DEBUGGING", rc_api_enabled=True, weblog_env={ @@ -679,7 +677,7 @@ class _Scenarios: scenario_groups=[scenario_groups.remote_config, scenario_groups.essentials], ) - remote_config_mocked_backend_asm_dd = EndToEndScenario( + remote_config_mocked_backend_asm_dd = DdTraceEndToEndScenario( "REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD", rc_api_enabled=True, weblog_env={"DD_APPSEC_RULES": None}, @@ -699,7 +697,7 @@ class _Scenarios: ], ) - feature_flagging_and_experimentation = EndToEndScenario( + feature_flagging_and_experimentation = DdTraceEndToEndScenario( "FEATURE_FLAGGING_AND_EXPERIMENTATION", rc_api_enabled=True, weblog_env={ @@ -723,7 +721,7 @@ class _Scenarios: scenario_groups=[scenario_groups.ffe], ) - remote_config_mocked_backend_asm_features_nocache = EndToEndScenario( + remote_config_mocked_backend_asm_features_nocache = DdTraceEndToEndScenario( "REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES_NOCACHE", rc_api_enabled=True, weblog_env={"DD_APPSEC_ENABLED": "false", "DD_REMOTE_CONFIGURATION_ENABLED": "true"}, @@ -732,14 +730,14 @@ class _Scenarios: ) # APM tracing end-to-end scenarios - apm_tracing_e2e_otel = EndToEndScenario( + apm_tracing_e2e_otel = DdTraceEndToEndScenario( "APM_TRACING_E2E_OTEL", weblog_env={"DD_TRACE_OTEL_ENABLED": "true"}, backend_interface_timeout=5, require_api_key=True, doc="", ) - apm_tracing_e2e_single_span = EndToEndScenario( + apm_tracing_e2e_single_span = DdTraceEndToEndScenario( "APM_TRACING_E2E_SINGLE_SPAN", weblog_env={ "DD_SPAN_SAMPLING_RULES": json.dumps( @@ -751,7 +749,7 @@ class _Scenarios: require_api_key=True, doc="", ) - apm_tracing_otlp = EndToEndScenario( + apm_tracing_otlp = DdTraceEndToEndScenario( "APM_TRACING_OTLP", weblog_env={ "OTEL_TRACES_EXPORTER": "otlp", @@ -764,7 +762,7 @@ class _Scenarios: doc="", ) - apm_tracing_efficient_payload = EndToEndScenario( + apm_tracing_efficient_payload = DdTraceEndToEndScenario( "APM_TRACING_EFFICIENT_PAYLOAD", weblog_env={ "DD_TRACE_SAMPLE_RATE": "1.0", @@ -781,19 +779,19 @@ class _Scenarios: otel_metric_e2e = OpenTelemetryScenario("OTEL_METRIC_E2E", require_api_key=True, mocked_backend=False, doc="") otel_log_e2e = OpenTelemetryScenario("OTEL_LOG_E2E", require_api_key=True, doc="") - library_conf_custom_header_tags = EndToEndScenario( + library_conf_custom_header_tags = DdTraceEndToEndScenario( "LIBRARY_CONF_CUSTOM_HEADER_TAGS", additional_trace_header_tags=(VALID_CONFIGS), rc_api_enabled=True, doc="Scenario with custom headers to be used with DD_TRACE_HEADER_TAGS", ) - library_conf_custom_header_tags_invalid = EndToEndScenario( + library_conf_custom_header_tags_invalid = DdTraceEndToEndScenario( "LIBRARY_CONF_CUSTOM_HEADER_TAGS_INVALID", additional_trace_header_tags=(INVALID_CONFIGS), doc="Scenario with custom headers for DD_TRACE_HEADER_TAGS that libraries should reject", ) - tracing_config_empty = EndToEndScenario( + tracing_config_empty = DdTraceEndToEndScenario( "TRACING_CONFIG_EMPTY", weblog_env={ # This scenario should be empty but enabling logs injection allows us to reuse this scenario for the @@ -803,7 +801,7 @@ class _Scenarios: doc="", ) - tracing_config_nondefault = EndToEndScenario( + tracing_config_nondefault = DdTraceEndToEndScenario( "TRACING_CONFIG_NONDEFAULT", additional_trace_header_tags=tuple(CONFIG_WILDCARD), weblog_env={ @@ -827,7 +825,7 @@ class _Scenarios: scenario_groups=[scenario_groups.tracing_config, scenario_groups.essentials], ) - tracing_config_nondefault_2 = EndToEndScenario( + tracing_config_nondefault_2 = DdTraceEndToEndScenario( "TRACING_CONFIG_NONDEFAULT_2", weblog_env={ "DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP": "", @@ -843,7 +841,7 @@ class _Scenarios: doc="Test tracer configuration when a collection of non-default settings are applied", scenario_groups=[scenario_groups.tracing_config], ) - tracing_config_nondefault_3 = EndToEndScenario( + tracing_config_nondefault_3 = DdTraceEndToEndScenario( "TRACING_CONFIG_NONDEFAULT_3", weblog_env={ "DD_TRACE_HTTP_CLIENT_TAG_QUERY_STRING": "false", @@ -862,7 +860,7 @@ class _Scenarios: scenario_groups=[scenario_groups.tracing_config], ) - tracing_config_nondefault_4 = EndToEndScenario( + tracing_config_nondefault_4 = DdTraceEndToEndScenario( "TRACING_CONFIG_NONDEFAULT_4", weblog_env={ # Required by Node.js to ensure the snapshot isn't truncated due to a timeout @@ -952,7 +950,7 @@ class _Scenarios: doc="Test scenario for checking symdb.", ) - debugger_inproduct_enablement = EndToEndScenario( + debugger_inproduct_enablement = DdTraceEndToEndScenario( "DEBUGGER_INPRODUCT_ENABLEMENT", rc_api_enabled=True, rc_backend_enabled=False, @@ -965,7 +963,7 @@ class _Scenarios: scenario_groups=[scenario_groups.debugger], ) - debugger_telemetry = EndToEndScenario( + debugger_telemetry = DdTraceEndToEndScenario( "DEBUGGER_TELEMETRY", rc_api_enabled=True, rc_backend_enabled=True, @@ -1266,7 +1264,7 @@ class _Scenarios: }, ) - appsec_ato_sdk = EndToEndScenario( + appsec_ato_sdk = DdTraceEndToEndScenario( "APPSEC_ATO_SDK", weblog_env={"DD_APPSEC_ENABLED": "true", "DD_APPSEC_RULES": "/appsec_ato_sdk.json"}, weblog_volumes={ @@ -1276,11 +1274,10 @@ class _Scenarios: } }, doc="Rules file with unsafe login and user id", - github_workflow="endtoend", scenario_groups=[scenario_groups.appsec], ) - agent_supporting_span_events = EndToEndScenario( + agent_supporting_span_events = DdTraceEndToEndScenario( "AGENT_SUPPORTING_SPAN_EVENTS", weblog_env={"DD_TRACE_NATIVE_SPAN_EVENTS": "1", "DD_TELEMETRY_METRICS_ENABLED": "true"}, span_events=True, @@ -1288,7 +1285,7 @@ class _Scenarios: scenario_groups=[scenario_groups.integrations, scenario_groups.telemetry], ) - agent_not_supporting_span_events = EndToEndScenario( + agent_not_supporting_span_events = DdTraceEndToEndScenario( "AGENT_NOT_SUPPORTING_SPAN_EVENTS", weblog_env={"DD_TRACE_NATIVE_SPAN_EVENTS": "0"}, span_events=False, @@ -1298,7 +1295,7 @@ class _Scenarios: ipv6 = IPV6Scenario("IPV6") - runtime_metrics_enabled = EndToEndScenario( + runtime_metrics_enabled = DdTraceEndToEndScenario( "RUNTIME_METRICS_ENABLED", # Add environment variable DD_DOGSTATSD_START_DELAY=0 to avoid the default 30s startup delay in the Java tracer. # That delay is used in production to reduce the impact on startup and other side-effects on various application @@ -1309,7 +1306,7 @@ class _Scenarios: doc="Test runtime metrics", ) - otlp_runtime_metrics = EndToEndScenario( + otlp_runtime_metrics = DdTraceEndToEndScenario( "OTLP_RUNTIME_METRICS", weblog_env={ "DD_METRICS_OTEL_ENABLED": "true", @@ -1322,7 +1319,7 @@ class _Scenarios: runtime_metrics_enabled=True, include_opentelemetry=True, library_interface_timeout=20, - doc="Test runtime metrics exported via OTLP with OTel semantic convention names", + doc="Test ddtrace runtime metrics exported via OTLP with OTel semantic convention names", ) # Appsec Lambda Scenarios diff --git a/utils/_context/_scenarios/_docker_fixtures.py b/utils/_context/_scenarios/_docker_fixtures.py index e1b8389fc6d..136a730edd4 100644 --- a/utils/_context/_scenarios/_docker_fixtures.py +++ b/utils/_context/_scenarios/_docker_fixtures.py @@ -8,6 +8,7 @@ from utils.docker_fixtures._test_agent import TestAgentFactory, TestAgentAPI from docker.errors import DockerException from utils._context.docker import get_docker_client +from utils._context.constants import WeblogCategory from utils._logger import logger from .core import Scenario, ScenarioGroup, scenario_groups as groups @@ -22,6 +23,7 @@ def __init__( github_workflow: str, doc: str, agent_image: str, + weblog_categories: list[WeblogCategory], scenario_groups: tuple[ScenarioGroup, ...] = (), ) -> None: super().__init__( @@ -29,6 +31,7 @@ def __init__( doc=doc, github_workflow=github_workflow, scenario_groups=[*scenario_groups, groups.all, groups.tracer_release, groups.docker_fixtures], + weblog_categories=weblog_categories, ) self._test_agent_factory = TestAgentFactory(agent_image) diff --git a/utils/_context/_scenarios/ai_guard.py b/utils/_context/_scenarios/ai_guard.py index f42f7594ca3..cd13d043c3b 100644 --- a/utils/_context/_scenarios/ai_guard.py +++ b/utils/_context/_scenarios/ai_guard.py @@ -6,6 +6,7 @@ import pytest from utils._context.containers import VCRCassettesContainer +from utils._context.constants import WeblogCategory from utils._logger import logger from .endtoend import EndToEndScenario @@ -20,7 +21,7 @@ class AIGuardScenario(EndToEndScenario): """ def __init__(self, name: str, **kwargs): # noqa: ANN003 - super().__init__(name, **kwargs) + super().__init__(name, weblog_categories=[WeblogCategory.dd_trace], **kwargs) self._generate_cassettes = False def configure(self, config: pytest.Config): diff --git a/utils/_context/_scenarios/appsec_low_waf_timeout.py b/utils/_context/_scenarios/appsec_low_waf_timeout.py index 48d20c8341e..6accfeb5095 100644 --- a/utils/_context/_scenarios/appsec_low_waf_timeout.py +++ b/utils/_context/_scenarios/appsec_low_waf_timeout.py @@ -1,5 +1,6 @@ import pytest +from utils._context.constants import WeblogCategory from .core import scenario_groups from .endtoend import EndToEndScenario @@ -10,6 +11,7 @@ def __init__(self, name: str): name, doc="Appsec with a very low WAF timeout", scenario_groups=[scenario_groups.appsec, scenario_groups.appsec_low_waf_timeout], + weblog_categories=[WeblogCategory.dd_trace], ) def configure(self, config: pytest.Config): diff --git a/utils/_context/_scenarios/appsec_rasp.py b/utils/_context/_scenarios/appsec_rasp.py index 200bb3413f8..1e0a5a49c36 100644 --- a/utils/_context/_scenarios/appsec_rasp.py +++ b/utils/_context/_scenarios/appsec_rasp.py @@ -4,6 +4,7 @@ from utils._context._scenarios.endtoend import EndToEndScenario from utils._context._scenarios.core import scenario_groups from utils._context.containers import InternalServerContainer +from utils._context.constants import WeblogCategory class AppsecRaspScenario(EndToEndScenario): @@ -39,6 +40,7 @@ def __init__( doc="Enable APPSEC RASP", github_workflow="endtoend", scenario_groups=[scenario_groups.appsec, scenario_groups.appsec_rasp, scenario_groups.appsec_rasp_scenario], + weblog_categories=[WeblogCategory.dd_trace], other_weblog_containers=(InternalServerContainer,), ) diff --git a/utils/_context/_scenarios/aws_lambda.py b/utils/_context/_scenarios/aws_lambda.py index e75149cafa7..0291f9f5368 100644 --- a/utils/_context/_scenarios/aws_lambda.py +++ b/utils/_context/_scenarios/aws_lambda.py @@ -1,6 +1,7 @@ import pytest from utils import interfaces from utils._context._scenarios.core import ScenarioGroup +from utils._context.constants import WeblogCategory from utils._context.containers import LambdaProxyContainer, LambdaWeblogContainer from utils._logger import logger from .endtoend import DockerScenario, ProxyBasedInterfaceValidator @@ -36,7 +37,13 @@ def __init__( all_scenario_groups.all, ] + (scenario_groups or []) - super().__init__(name, github_workflow=github_workflow, doc=doc, scenario_groups=scenario_groups) + super().__init__( + name, + github_workflow=github_workflow, + doc=doc, + scenario_groups=scenario_groups, + weblog_categories=[WeblogCategory.dd_trace_lambda], + ) self.lambda_weblog = LambdaWeblogContainer( environment=weblog_env or {}, volumes=weblog_volumes or {}, trace_managed_services=trace_managed_services diff --git a/utils/_context/_scenarios/core.py b/utils/_context/_scenarios/core.py index 3459ebed521..ad8656b0aa9 100644 --- a/utils/_context/_scenarios/core.py +++ b/utils/_context/_scenarios/core.py @@ -11,6 +11,7 @@ import pytest from utils._logger import logger, get_log_formatter +from utils._context.constants import WeblogCategory class ScenarioGroup: @@ -106,7 +107,12 @@ def __getitem__(self, key: str) -> ScenarioGroup: class Scenario: def __init__( - self, name: str, github_workflow: str | None, doc: str, scenario_groups: list[ScenarioGroup] | None = None + self, + name: str, + github_workflow: str | None, + doc: str, + weblog_categories: list[WeblogCategory] | None = None, + scenario_groups: list[ScenarioGroup] | None = None, ) -> None: self.name = name self.replay = False @@ -118,11 +124,14 @@ def __init__( self.scenario_groups = list(set(self.scenario_groups)) # removes duplicates - # key value pair of what is actually tested + self.weblog_categories: list[WeblogCategory] = weblog_categories or [] + """ Which weblog categories should this scenario applies """ + self.components: dict[str, Version] = {} + """ Key-value pair of what is actually tested """ - # if xdist is used, this property will be set to false for sub workers self.is_main_worker: bool = True + """ if xdist is used, this property will be set to false for sub workers """ assert self.github_workflow in VALID_CI_WORKFLOWS, ( f"Invalid github_workflow {self.github_workflow} for {self.name}" diff --git a/utils/_context/_scenarios/debugger.py b/utils/_context/_scenarios/debugger.py index ce7eb51c7c7..15a59b36f61 100644 --- a/utils/_context/_scenarios/debugger.py +++ b/utils/_context/_scenarios/debugger.py @@ -1,6 +1,7 @@ import pytest from utils._logger import logger +from utils._context.constants import WeblogCategory from .core import scenario_groups from .endtoend import EndToEndScenario @@ -25,6 +26,7 @@ def __init__(self, name: str, doc: str, weblog_env: dict[str, str | None]) -> No library_interface_timeout=5, weblog_env=base_weblog_env, scenario_groups=[scenario_groups.debugger], + weblog_categories=[WeblogCategory.dd_trace], ) def configure(self, config: pytest.Config): diff --git a/utils/_context/_scenarios/default.py b/utils/_context/_scenarios/default.py index 4d6730c734a..8ae73cd699b 100644 --- a/utils/_context/_scenarios/default.py +++ b/utils/_context/_scenarios/default.py @@ -1,8 +1,8 @@ import pytest from .core import scenario_groups from .endtoend import EndToEndScenario -from utils._context.containers import InternalServerContainer -from utils._context.containers import PostgresContainer +from utils._context.containers import InternalServerContainer, PostgresContainer +from utils._context.constants import WeblogCategory # When Security Controls configuration is set, tracers must instrument all the designated methods in the @@ -77,6 +77,7 @@ def __init__(self, name: str): agent_env={"SOME_SECRET_ENV": "leaked-env-var"}, other_weblog_containers=(PostgresContainer,), scenario_groups=[scenario_groups.essentials, scenario_groups.telemetry], + weblog_categories=[WeblogCategory.dd_trace], doc="Default scenario, spawn tracer, the Postgres databases and agent, and run most of exisiting tests", ) diff --git a/utils/_context/_scenarios/endtoend.py b/utils/_context/_scenarios/endtoend.py index 4c3fb3d2a23..bda32d3c44f 100644 --- a/utils/_context/_scenarios/endtoend.py +++ b/utils/_context/_scenarios/endtoend.py @@ -21,7 +21,7 @@ TestedContainer, ) from utils._context.weblog_infrastructure import EndToEndWeblogInfra - +from utils._context.constants import WeblogCategory from utils._logger import logger from .core import Scenario, ScenarioGroup, scenario_groups as all_scenario_groups @@ -38,6 +38,7 @@ def __init__( *, github_workflow: str | None, doc: str, + weblog_categories: list[WeblogCategory] | None = None, scenario_groups: list[ScenarioGroup] | None = None, enable_ipv6: bool = False, use_proxy: bool = True, @@ -50,7 +51,13 @@ def __init__( obfuscation_version: int | None | Literal["MISSING"] = None, extra_containers: tuple[type[TestedContainer], ...] = (), ) -> None: - super().__init__(name, doc=doc, github_workflow=github_workflow, scenario_groups=scenario_groups) + super().__init__( + name, + doc=doc, + github_workflow=github_workflow, + scenario_groups=scenario_groups, + weblog_categories=weblog_categories, + ) self.use_proxy = use_proxy self.enable_ipv6 = enable_ipv6 @@ -187,6 +194,7 @@ def __init__( *, doc: str, github_workflow: str = "endtoend", + weblog_categories: list[WeblogCategory], scenario_groups: list[ScenarioGroup] | None = None, weblog_env: dict[str, str | None] | None = None, weblog_volumes: dict | None = None, @@ -224,6 +232,7 @@ def __init__( doc=doc, github_workflow=github_workflow, scenario_groups=scenario_groups, + weblog_categories=weblog_categories, enable_ipv6=enable_ipv6, use_proxy=use_proxy_for_agent or use_proxy_for_weblog, rc_api_enabled=rc_api_enabled, @@ -517,3 +526,83 @@ def get_junit_properties(self) -> dict[str, str]: @property def appsec_rules_file(self) -> str | None: return self.weblog_infra.appsec_rules_file + + +class DdTraceEndToEndScenario(EndToEndScenario): + """Scenario targeting basic feature of a dd-trace library (not SSI or lambda)""" + + def __init__( + self, + name: str, + *, + doc: str, + additional_trace_header_tags: tuple[str, ...] = (), + agent_env: dict[str, str | None] | None = None, + appsec_enabled: bool = True, + backend_interface_timeout: int = 0, + client_drop_p0s: bool | None = None, + iast_enabled: bool = True, + include_opentelemetry: bool = False, + library_interface_timeout: int | None = None, + meta_structs_disabled: bool = False, + obfuscation_version: int | None | Literal["MISSING"] = None, + other_weblog_containers: tuple[type[TestedContainer], ...] = (), + rc_api_enabled: bool = False, + rc_backend_enabled: bool = False, + require_api_key: bool = False, + runtime_metrics_enabled: bool = False, + scenario_groups: list[ScenarioGroup] | None = None, + span_events: bool = True, + tracer_sampling_rate: float | None = None, + weblog_env: dict[str, str | None] | None = None, + weblog_volumes: dict | None = None, + ) -> None: + super().__init__( + name, + additional_trace_header_tags=additional_trace_header_tags, + agent_env=agent_env, + appsec_enabled=appsec_enabled, + backend_interface_timeout=backend_interface_timeout, + client_drop_p0s=client_drop_p0s, + doc=doc, + iast_enabled=iast_enabled, + include_opentelemetry=include_opentelemetry, + library_interface_timeout=library_interface_timeout, + meta_structs_disabled=meta_structs_disabled, + obfuscation_version=obfuscation_version, + other_weblog_containers=other_weblog_containers, + rc_api_enabled=rc_api_enabled, + rc_backend_enabled=rc_backend_enabled, + require_api_key=require_api_key, + runtime_metrics_enabled=runtime_metrics_enabled, + scenario_groups=scenario_groups, + span_events=span_events, + tracer_sampling_rate=tracer_sampling_rate, + weblog_categories=[WeblogCategory.dd_trace], + weblog_env=weblog_env, + weblog_volumes=weblog_volumes, + ) + + +class GraphQlEndToEndScenario(EndToEndScenario): + """Scenario targeting GraphQl feature of a dd-trace library""" + + def __init__( + self, + name: str, + *, + doc: str, + agent_env: dict[str, str | None] | None = None, + scenario_groups: list[ScenarioGroup] | None = None, + weblog_env: dict[str, str | None] | None = None, + weblog_volumes: dict | None = None, + ) -> None: + super().__init__( + name, + agent_env=agent_env, + doc=doc, + scenario_groups=scenario_groups, + weblog_categories=[WeblogCategory.dd_trace_graphql], + weblog_env=weblog_env, + weblog_volumes=weblog_volumes, + ) diff --git a/utils/_context/_scenarios/integration_frameworks.py b/utils/_context/_scenarios/integration_frameworks.py index a2c40a1343d..6783a6b672e 100644 --- a/utils/_context/_scenarios/integration_frameworks.py +++ b/utils/_context/_scenarios/integration_frameworks.py @@ -12,6 +12,7 @@ ) from utils._logger import logger from utils._context.component_version import ComponentVersion +from utils._context.constants import WeblogCategory from utils._context.docker import get_docker_client from ._docker_fixtures import DockerFixturesScenario from .core import scenario_groups as groups @@ -32,6 +33,7 @@ def __init__(self, name: str, doc: str) -> None: github_workflow="endtoend", agent_image="ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent:v1.63.0", scenario_groups=(groups.integration_frameworks,), + weblog_categories=[WeblogCategory.dd_trace_frameworks], ) self.environment: dict[str, str] = {} diff --git a/utils/_context/_scenarios/integrations.py b/utils/_context/_scenarios/integrations.py index 8369dc045aa..dead83fcf71 100644 --- a/utils/_context/_scenarios/integrations.py +++ b/utils/_context/_scenarios/integrations.py @@ -14,6 +14,7 @@ MsSqlServerContainer, MySqlContainer, ) +from utils._context.constants import WeblogCategory from .core import scenario_groups from .endtoend import EndToEndScenario @@ -68,6 +69,7 @@ def __init__(self) -> None: "Test the integrations of those databases with tracers" ), scenario_groups=[scenario_groups.integrations, scenario_groups.appsec, scenario_groups.essentials], + weblog_categories=[WeblogCategory.dd_trace], ) def configure(self, config: pytest.Config): @@ -88,6 +90,7 @@ def __init__(self) -> None: "and sets _dd.propagated_hash on SQL spans with the same value." ), scenario_groups=[scenario_groups.integrations], + weblog_categories=[WeblogCategory.dd_trace], ) @@ -112,6 +115,7 @@ def __init__( doc=doc, other_weblog_containers=(ElasticMQContainer, LocalstackContainer), scenario_groups=[scenario_groups.integrations, scenario_groups.essentials], + weblog_categories=[WeblogCategory.dd_trace], ) def configure(self, config: pytest.Config): @@ -138,6 +142,7 @@ def __init__(self) -> None: KafkaContainer, ), scenario_groups=[scenario_groups.integrations, scenario_groups.essentials], + weblog_categories=[WeblogCategory.dd_trace], ) def configure(self, config: pytest.Config): diff --git a/utils/_context/_scenarios/ipv6.py b/utils/_context/_scenarios/ipv6.py index 1073c7486fd..f7cf5b22ff1 100644 --- a/utils/_context/_scenarios/ipv6.py +++ b/utils/_context/_scenarios/ipv6.py @@ -1,5 +1,6 @@ from utils._logger import logger +from utils._context.constants import WeblogCategory from .core import scenario_groups from .endtoend import EndToEndScenario @@ -10,6 +11,7 @@ def __init__(self, name: str) -> None: name, enable_ipv6=True, scenario_groups=[scenario_groups.ipv6], + weblog_categories=[WeblogCategory.dd_trace], use_proxy_for_agent=True, use_proxy_for_weblog=False, doc=( diff --git a/utils/_context/_scenarios/open_telemetry.py b/utils/_context/_scenarios/open_telemetry.py index 3c0f9407a7f..5f683569ff0 100644 --- a/utils/_context/_scenarios/open_telemetry.py +++ b/utils/_context/_scenarios/open_telemetry.py @@ -9,6 +9,7 @@ from utils import interfaces from utils.interfaces._core import ProxyBasedInterfaceValidator from utils._context.component_version import Version +from utils._context.constants import WeblogCategory from utils._context.containers import ( AgentContainer, @@ -44,6 +45,7 @@ def __init__( doc=doc, github_workflow="endtoend", scenario_groups=[scenario_groups.all, scenario_groups.open_telemetry], + weblog_categories=[WeblogCategory.open_telemetry], use_proxy=True, mocked_backend=mocked_backend, extra_containers=extra_containers, diff --git a/utils/_context/_scenarios/parametric.py b/utils/_context/_scenarios/parametric.py index 4c194c2acf2..0e11cb8ed9c 100644 --- a/utils/_context/_scenarios/parametric.py +++ b/utils/_context/_scenarios/parametric.py @@ -8,6 +8,7 @@ import pytest from utils._context.component_version import ComponentVersion +from utils._context.constants import WeblogCategory from utils._context.docker import get_docker_client from utils._logger import logger from utils.docker_fixtures import ( @@ -64,6 +65,7 @@ def __init__(self, name: str, doc: str) -> None: doc=doc, github_workflow="parametric", agent_image="ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent:v1.63.0", + weblog_categories=[WeblogCategory.parametric], ) self._parametric_tests_confs = ParametricScenario.PersistentParametricTestConf(self) diff --git a/utils/_context/_scenarios/profiling.py b/utils/_context/_scenarios/profiling.py index 17ae0ed4f53..60f67510c3a 100644 --- a/utils/_context/_scenarios/profiling.py +++ b/utils/_context/_scenarios/profiling.py @@ -1,5 +1,6 @@ import pytest +from utils._context.constants import WeblogCategory from .core import scenario_groups from .endtoend import EndToEndScenario @@ -21,6 +22,7 @@ def __init__(self, name: str) -> None: }, doc="Test profiling feature. Not included in default scenario because is quite slow", scenario_groups=[scenario_groups.profiling], + weblog_categories=[WeblogCategory.dd_trace], ) def configure(self, config: pytest.Config): diff --git a/utils/_context/constants.py b/utils/_context/constants.py index fcf234124f5..b5e17af00e8 100644 --- a/utils/_context/constants.py +++ b/utils/_context/constants.py @@ -15,6 +15,28 @@ class WeblogBuildMode(StrEnum): """ The weblog will be built in a dedicated job in the CI """ +class WeblogCategory(StrEnum): + """Used to connect scenario and weblogs""" + + dd_trace = "dd_trace" + """ Basic dd-trace instrumentation of an HTTP app """ + + dd_trace_graphql = "dd_trace_graphql" + """ dd-trace instrumentation of an GraphQL app """ + + dd_trace_lambda = "dd_trace_lambda" + """ dd-trace inside a lambda function """ + + dd_trace_frameworks = "dd_trace_frameworks" + """ dd-trace instrumentation of multi-language frameworks (mostly AI) """ + + open_telemetry = "open_telemetry" + """ Open Telemetry library """ + + parametric = "parametric" + """ Weblog shipping a dd-trace library with an interface dedicated to PARAMETRIC scenario """ + + class ContainerPorts(IntEnum): """Host ports used by tested containers""" diff --git a/utils/_context/weblog_metadata.py b/utils/_context/weblog_metadata.py index b21342b97f2..a18968fd3a9 100644 --- a/utils/_context/weblog_metadata.py +++ b/utils/_context/weblog_metadata.py @@ -1,8 +1,8 @@ -from dataclasses import dataclass, replace +from dataclasses import dataclass, replace, field from pathlib import Path import yaml -from .constants import WeblogBuildMode +from .constants import WeblogBuildMode, WeblogCategory @dataclass @@ -14,8 +14,15 @@ class WeblogMetaData: artifact_name: str = "" """ not declared in the yml file, but populated later """ + supported_scenarios: list[str] = field(default_factory=list) + excluded_scenarios: list[str] = field(default_factory=list) + + categories: list[WeblogCategory] = field(default_factory=list) + def __post_init__(self): + # cast enums self.build_mode = WeblogBuildMode(self.build_mode) + self.categories = [WeblogCategory[category] for category in self.categories] @property def require_build(self) -> bool: @@ -88,9 +95,11 @@ def load(library: str) -> list["WeblogMetaData"]: return result + def support_scenario(self, scenario_name: str, weblog_categories: list[WeblogCategory]) -> bool: + if scenario_name in self.excluded_scenarios: + return False -if __name__ == "__main__": - x = WeblogMetaData.load("python") - from pprint import pprint + if scenario_name in self.supported_scenarios: + return True - pprint(x) # noqa: T203 + return any(category in self.categories for category in weblog_categories) diff --git a/utils/build/docker/cpp_httpd/weblog_metadata.yml b/utils/build/docker/cpp_httpd/weblog_metadata.yml new file mode 100644 index 00000000000..7259a74df62 --- /dev/null +++ b/utils/build/docker/cpp_httpd/weblog_metadata.yml @@ -0,0 +1,5 @@ +# docs/understand/weblogs/weblog-metadata.md + +httpd: + categories: [dd_trace] + excluded_scenarios: [APPSEC_MISSING_RULES, APPSEC_CORRUPTED_RULES] # C++ 1.2.0 freeze when the rules file is missing \ No newline at end of file diff --git a/utils/build/docker/cpp_kong/weblog_metadata.yml b/utils/build/docker/cpp_kong/weblog_metadata.yml new file mode 100644 index 00000000000..89045df789d --- /dev/null +++ b/utils/build/docker/cpp_kong/weblog_metadata.yml @@ -0,0 +1,4 @@ +# docs/understand/weblogs/weblog-metadata.md + +kong: + categories: [dd_trace] \ No newline at end of file diff --git a/utils/build/docker/cpp_nginx/weblog_metadata.yml b/utils/build/docker/cpp_nginx/weblog_metadata.yml new file mode 100644 index 00000000000..dced372ed6a --- /dev/null +++ b/utils/build/docker/cpp_nginx/weblog_metadata.yml @@ -0,0 +1,5 @@ +# docs/understand/weblogs/weblog-metadata.md + +nginx: + categories: [dd_trace] + excluded_scenarios: [APPSEC_MISSING_RULES, APPSEC_CORRUPTED_RULES] # C++ 1.2.0 freeze when the rules file is missing \ No newline at end of file diff --git a/utils/build/docker/dotnet/weblog_metadata.yml b/utils/build/docker/dotnet/weblog_metadata.yml new file mode 100644 index 00000000000..db4db189587 --- /dev/null +++ b/utils/build/docker/dotnet/weblog_metadata.yml @@ -0,0 +1,7 @@ +# docs/understand/weblogs/weblog-metadata.md + +poc: + categories: [dd_trace] +uds: + categories: [dd_trace] + excluded_scenarios: [IPV6] \ No newline at end of file diff --git a/utils/build/docker/golang/weblog_metadata.yml b/utils/build/docker/golang/weblog_metadata.yml index c09bcc8256f..52cf8e9b07b 100644 --- a/utils/build/docker/golang/weblog_metadata.yml +++ b/utils/build/docker/golang/weblog_metadata.yml @@ -2,5 +2,29 @@ haproxy: build_mode: none + supported_scenarios: [APPSEC_BLOCKING, DEFAULT] envoy: - build_mode: none \ No newline at end of file + build_mode: none + supported_scenarios: [APPSEC_BLOCKING, DEFAULT] +graphql-go: + categories: [dd_trace_graphql] + excluded_scenarios: [GRAPHQL_ERROR_TRACKING] # why ??? +gqlgen: + categories: [dd_trace_graphql] + excluded_scenarios: [GRAPHQL_ERROR_TRACKING] # why ??? +graph-gophers: + categories: [dd_trace_graphql] + excluded_scenarios: [GRAPHQL_ERROR_TRACKING] # why ??? +echo: + categories: [dd_trace] +gin: + categories: [dd_trace] +uds-echo: + categories: [dd_trace] + excluded_scenarios: [IPV6] +net-http: + categories: [dd_trace] +chi: + categories: [dd_trace] +net-http-orchestrion: + categories: [dd_trace] \ No newline at end of file diff --git a/utils/build/docker/java/weblog_metadata.yml b/utils/build/docker/java/weblog_metadata.yml index 62cbf1d96ed..06f2ce335e0 100644 --- a/utils/build/docker/java/weblog_metadata.yml +++ b/utils/build/docker/java/weblog_metadata.yml @@ -1,5 +1,38 @@ # docs/understand/weblogs/weblog-metadata.md +akka-http: + categories: [dd_trace] +jersey-grizzly2: + categories: [dd_trace] openai-java: build_mode: none framework_versions: ["4.29.0"] + categories: [dd_trace_frameworks] +play: + categories: [dd_trace] +ratpack: + categories: [dd_trace] +resteasy-netty3: + categories: [dd_trace] +spring-boot: + categories: [dd_trace] +spring-boot-3-native: + categories: [dd_trace] +spring-boot-jetty: + categories: [dd_trace] +spring-boot-openliberty: + categories: [dd_trace] +spring-boot-payara: + categories: [dd_trace] + excluded_scenarios: [CROSSED_TRACING_LIBRARIES] # probably because of a crash, but no history +spring-boot-undertow: + categories: [dd_trace] +spring-boot-wildfly: + categories: [dd_trace] +uds-spring-boot: + categories: [dd_trace] + excluded_scenarios: [IPV6] +vertx3: + categories: [dd_trace] +vertx4: + categories: [dd_trace] \ No newline at end of file diff --git a/utils/build/docker/java_lambda/weblog_metadata.yml b/utils/build/docker/java_lambda/weblog_metadata.yml new file mode 100644 index 00000000000..64e09342acb --- /dev/null +++ b/utils/build/docker/java_lambda/weblog_metadata.yml @@ -0,0 +1,10 @@ +java-alb: + categories: [dd_trace_lambda] +java-alb-multi: + categories: [dd_trace_lambda] +java-apigw-http: + categories: [dd_trace_lambda] +java-apigw-rest: + categories: [dd_trace_lambda] +java-function-url: + categories: [dd_trace_lambda] \ No newline at end of file diff --git a/utils/build/docker/java_otel/weblog_metadata.yml b/utils/build/docker/java_otel/weblog_metadata.yml new file mode 100644 index 00000000000..c25febb947a --- /dev/null +++ b/utils/build/docker/java_otel/weblog_metadata.yml @@ -0,0 +1,7 @@ + +spring-boot-native: + categories: [open_telemetry] + excluded_scenarios: [OTEL_INTEGRATIONS] +spring-boot-otel: + categories: [open_telemetry] + excluded_scenarios: [OTEL_LOG_E2E, OTEL_METRIC_E2E, OTEL_TRACING_E2E] \ No newline at end of file diff --git a/utils/build/docker/nodejs/weblog_metadata.yml b/utils/build/docker/nodejs/weblog_metadata.yml index 802e518616e..dc27e51aba8 100644 --- a/utils/build/docker/nodejs/weblog_metadata.yml +++ b/utils/build/docker/nodejs/weblog_metadata.yml @@ -2,22 +2,32 @@ express4: build_mode: local + categories: [dd_trace, dd_trace_graphql] express4-typescript: build_mode: local + categories: [dd_trace, dd_trace_graphql] express5: build_mode: local + categories: [dd_trace, dd_trace_graphql] fastify: build_mode: local + categories: [dd_trace] nextjs: build_mode: local + categories: [dd_trace] uds-express4: build_mode: local + categories: [dd_trace, dd_trace_graphql] + excluded_scenarios: [IPV6] openai-js: build_mode: none framework_versions: ["6.0.0"] + categories: [dd_trace_frameworks] anthropic-js: build_mode: none framework_versions: ["0.71.0"] + categories: [dd_trace_frameworks] google_genai-js: build_mode: none framework_versions: ["1.34.0"] + categories: [dd_trace_frameworks] diff --git a/utils/build/docker/nodejs_lambda/weblog_metadata.yml b/utils/build/docker/nodejs_lambda/weblog_metadata.yml new file mode 100644 index 00000000000..b8ee96bacb2 --- /dev/null +++ b/utils/build/docker/nodejs_lambda/weblog_metadata.yml @@ -0,0 +1,10 @@ +nodejs-alb: + categories: [dd_trace_lambda] +nodejs-alb-multi: + categories: [dd_trace_lambda] +nodejs-apigw-http: + categories: [dd_trace_lambda] +nodejs-apigw-rest: + categories: [dd_trace_lambda] +nodejs-function-url: + categories: [dd_trace_lambda] \ No newline at end of file diff --git a/utils/build/docker/nodejs_otel/weblog_metadata.yml b/utils/build/docker/nodejs_otel/weblog_metadata.yml new file mode 100644 index 00000000000..c266bcc3858 --- /dev/null +++ b/utils/build/docker/nodejs_otel/weblog_metadata.yml @@ -0,0 +1,3 @@ +express4-otel: + categories: [open_telemetry] + excluded_scenarios: [OTEL_LOG_E2E, OTEL_METRIC_E2E, OTEL_TRACING_E2E] \ No newline at end of file diff --git a/utils/build/docker/otel_collector/weblog_metadata.yml b/utils/build/docker/otel_collector/weblog_metadata.yml index 3873e9082cb..39a1eb07ce6 100644 --- a/utils/build/docker/otel_collector/weblog_metadata.yml +++ b/utils/build/docker/otel_collector/weblog_metadata.yml @@ -2,3 +2,5 @@ otel_collector: build_mode: none + supported_scenarios: [OTEL_COLLECTOR, OTEL_COLLECTOR_E2E] + diff --git a/utils/build/docker/php/weblog_metadata.yml b/utils/build/docker/php/weblog_metadata.yml new file mode 100644 index 00000000000..2588be8c23f --- /dev/null +++ b/utils/build/docker/php/weblog_metadata.yml @@ -0,0 +1,54 @@ +# docs/understand/weblogs/weblog-metadata.md + +apache-mod-7.0: + categories: [dd_trace] +apache-mod-7.1: + categories: [dd_trace] +apache-mod-7.2: + categories: [dd_trace] +apache-mod-7.3: + categories: [dd_trace] +apache-mod-7.4: + categories: [dd_trace] +apache-mod-8.0: + categories: [dd_trace] +apache-mod-8.1: + categories: [dd_trace] +apache-mod-8.2: + categories: [dd_trace] +apache-mod-7.0-zts: + categories: [dd_trace] +apache-mod-7.1-zts: + categories: [dd_trace] +apache-mod-7.2-zts: + categories: [dd_trace] +apache-mod-7.3-zts: + categories: [dd_trace] +apache-mod-7.4-zts: + categories: [dd_trace] +apache-mod-8.0-zts: + categories: [dd_trace] +apache-mod-8.1-zts: + categories: [dd_trace] +apache-mod-8.2-zts: + categories: [dd_trace] +php-fpm-7.0: + categories: [dd_trace] +php-fpm-7.1: + categories: [dd_trace] +php-fpm-7.2: + categories: [dd_trace] +php-fpm-7.3: + categories: [dd_trace] +php-fpm-7.4: + categories: [dd_trace] +php-fpm-8.0: + categories: [dd_trace] +php-fpm-8.1: + categories: [dd_trace] +php-fpm-8.2: + categories: [dd_trace] +php-fpm-8.5: + categories: [dd_trace] +laravel11x: + categories: [dd_trace] diff --git a/utils/build/docker/python/weblog_metadata.yml b/utils/build/docker/python/weblog_metadata.yml index c0b67e68fa7..d868fe1b318 100644 --- a/utils/build/docker/python/weblog_metadata.yml +++ b/utils/build/docker/python/weblog_metadata.yml @@ -3,9 +3,31 @@ openai-py: build_mode: none framework_versions: ["2.0.0"] + categories : [dd_trace_frameworks] anthropic-py: build_mode: none framework_versions: ["0.75.0"] + categories : [dd_trace_frameworks] google_genai-py: build_mode: none framework_versions: ["1.55.0"] + categories : [dd_trace_frameworks] +tornado: + categories: [dd_trace] +django-poc: + categories: [dd_trace] +django-py3.13: + categories: [dd_trace] + excluded_scenarios: [CROSSED_TRACING_LIBRARIES] # APMAPI-1096 +python3.12: + categories: [dd_trace] + excluded_scenarios: [CROSSED_TRACING_LIBRARIES] # APMAPI-1096 +uwsgi-poc: + categories: [dd_trace] +uds-flask: + categories: [dd_trace] + excluded_scenarios: [IPV6] +flask-poc: + categories: [dd_trace] +fastapi: + categories: [dd_trace] \ No newline at end of file diff --git a/utils/build/docker/python_lambda/weblog_metadata.yml b/utils/build/docker/python_lambda/weblog_metadata.yml new file mode 100644 index 00000000000..47e16f32849 --- /dev/null +++ b/utils/build/docker/python_lambda/weblog_metadata.yml @@ -0,0 +1,10 @@ +alb: + categories: [dd_trace_lambda] +alb-multi: + categories: [dd_trace_lambda] +apigw-http: + categories: [dd_trace_lambda] +apigw-rest: + categories: [dd_trace_lambda] +function-url: + categories: [dd_trace_lambda] \ No newline at end of file diff --git a/utils/build/docker/python_otel/weblog_metadata.yml b/utils/build/docker/python_otel/weblog_metadata.yml new file mode 100644 index 00000000000..a3f8712d0f1 --- /dev/null +++ b/utils/build/docker/python_otel/weblog_metadata.yml @@ -0,0 +1,3 @@ +flask-poc-otel: + categories: [open_telemetry] + excluded_scenarios: [OTEL_LOG_E2E, OTEL_METRIC_E2E, OTEL_TRACING_E2E] \ No newline at end of file diff --git a/utils/build/docker/ruby/weblog_metadata.yml b/utils/build/docker/ruby/weblog_metadata.yml new file mode 100644 index 00000000000..96368c17818 --- /dev/null +++ b/utils/build/docker/ruby/weblog_metadata.yml @@ -0,0 +1,39 @@ +graphql23: + categories: [dd_trace_graphql] + excluded_scenarios: [GRAPHQL_ERROR_TRACKING] # why ? +rack: + categories: [dd_trace] + excluded_scenarios: [IPV6] +rails42: + categories: [dd_trace] + excluded_scenarios: [IPV6] +rails52: + categories: [dd_trace] + excluded_scenarios: [IPV6] +rails61: + categories: [dd_trace] + excluded_scenarios: [IPV6] +rails72: + categories: [dd_trace] + excluded_scenarios: [IPV6] +rails80: + categories: [dd_trace] + excluded_scenarios: [IPV6] +sinatra14: + categories: [dd_trace] + excluded_scenarios: [IPV6] +sinatra22: + categories: [dd_trace] + excluded_scenarios: [IPV6] +sinatra32: + categories: [dd_trace] + excluded_scenarios: [IPV6] +sinatra41: + categories: [dd_trace] + excluded_scenarios: [IPV6] +uds-rails: + categories: [dd_trace] + excluded_scenarios: [IPV6] +uds-sinatra: + categories: [dd_trace] + excluded_scenarios: [IPV6] \ No newline at end of file diff --git a/utils/build/docker/ruby_lambda/weblog_metadata.yml b/utils/build/docker/ruby_lambda/weblog_metadata.yml new file mode 100644 index 00000000000..17734f551bc --- /dev/null +++ b/utils/build/docker/ruby_lambda/weblog_metadata.yml @@ -0,0 +1,5 @@ + +ruby-apigw-http: + categories: [dd_trace_lambda] +ruby-apigw-rest: + categories: [dd_trace_lambda] \ No newline at end of file diff --git a/utils/scripts/ci_orchestrators/workflow_data.py b/utils/scripts/ci_orchestrators/workflow_data.py index 4d976aa0fe8..89a2bf8996a 100644 --- a/utils/scripts/ci_orchestrators/workflow_data.py +++ b/utils/scripts/ci_orchestrators/workflow_data.py @@ -322,7 +322,7 @@ def get_endtoend_definitions( *, build_base_images: bool = False, ) -> dict: - scenarios = scenario_map.get("endtoend", []) + scenarios: list[Scenario] = scenario_map.get("endtoend", []) # get time stats with open("utils/scripts/ci_orchestrators/time-stats.json", "r") as file: @@ -343,7 +343,7 @@ def get_endtoend_definitions( # build a list of {weblog, scenarios} for each weblog, and assign it to a Job jobs: list[Job] = [] for weblog in weblogs: - supported_scenarios = _filter_scenarios(scenarios, weblog, ci_environment) + supported_scenarios = _filter_scenarios(scenarios, weblog) if len(supported_scenarios) > 0: # remove weblogs with no scenarios scenarios_times = { @@ -484,111 +484,13 @@ def _get_execution_time(library: str, weblog: str, scenario: str, run_stats: dic return run_stats[scenario][library][weblog] -def _filter_scenarios(scenarios: list[Scenario], weblog: Weblog, ci_environment: str) -> list[Scenario]: +def _filter_scenarios(scenarios: list[Scenario], weblog: Weblog) -> list[Scenario]: return sorted( - [scenario for scenario in set(scenarios) if _is_supported(weblog, scenario, ci_environment)], + [scenario for scenario in set(scenarios) if weblog.support_scenario(scenario.name, scenario.weblog_categories)], key=lambda scenario: scenario.name, ) -def _is_uds_weblog(weblog: str) -> bool: - return weblog == "uds" or weblog.startswith("uds-") - - -def _is_supported(weblog: Weblog, scenario: Scenario, _ci_environment: str) -> bool: - # this function will remove some couple scenarios/weblog that are not supported - - library = weblog.library - weblog_name = weblog.name - - # Only Allow Lambda scenarios for the lambda libraries - is_lambda_library = library in ( - "python_lambda", - "java_lambda", - "nodejs_lambda", - "ruby_lambda", - ) - is_lambda_scenario = scenario.name in ( - "APPSEC_LAMBDA_DEFAULT", - "APPSEC_LAMBDA_BLOCKING", - "APPSEC_LAMBDA_API_SECURITY", - "APPSEC_LAMBDA_RASP", - "APPSEC_LAMBDA_INFERRED_SPANS", - ) - if is_lambda_library != is_lambda_scenario: - return False - - # open-telemetry-automatic - if scenario.name == "OTEL_INTEGRATIONS": - possible_values: tuple = ( - ("java_otel", "spring-boot-otel"), - ("nodejs_otel", "express4-otel"), - ("python_otel", "flask-poc-otel"), - ) - if (library, weblog_name) not in possible_values: - return False - - # open-telemetry-manual - if scenario.name in ("OTEL_LOG_E2E", "OTEL_METRIC_E2E", "OTEL_TRACING_E2E"): - if (library, weblog_name) != ("java_otel", "spring-boot-native"): - return False - - if scenario.name in ("GRAPHQL_APPSEC", "GRAPHQL_ERROR_TRACKING"): - possible_values: tuple = ( - ("golang", "gqlgen"), - ("golang", "graph-gophers"), - ("golang", "graphql-go"), - ("ruby", "graphql23"), - ("nodejs", "express4"), - ("nodejs", "uds-express4"), - ("nodejs", "express4-typescript"), - ("nodejs", "express5"), - ) - if (library, weblog_name) not in possible_values: - return False - - if scenario.name == "IPV6": - if library == "ruby" or _is_uds_weblog(weblog_name): - return False - - if scenario.name in ("CROSSED_TRACING_LIBRARIES",): - if weblog_name in ("python3.12", "django-py3.13", "spring-boot-payara"): - # python 3.13 issue : APMAPI-1096 - return False - - if scenario.name in ("APPSEC_MISSING_RULES", "APPSEC_CORRUPTED_RULES") and library in ("cpp_nginx", "cpp_httpd"): - # C++ 1.2.0 freeze when the rules file is missing - return False - - if weblog_name in ["gqlgen", "graph-gophers", "graphql-go", "graphql23"]: - if scenario.name not in ("GRAPHQL_APPSEC",): - return False - - # open-telemetry-manual - if weblog_name == "spring-boot-native": - if scenario.name not in ("OTEL_LOG_E2E", "OTEL_METRIC_E2E", "OTEL_TRACING_E2E"): - return False - - # open-telemetry-automatic - if weblog_name in ["express4-otel", "flask-poc-otel", "spring-boot-otel"]: - if scenario.name not in ("OTEL_INTEGRATIONS",): - return False - - # Go proxies - if weblog.name in ("envoy", "haproxy"): - if scenario.name not in ("DEFAULT", "APPSEC_BLOCKING"): - return False - - # otel collector - if weblog_name == "otel_collector" or scenario.name in ("OTEL_COLLECTOR", "OTEL_COLLECTOR_E2E"): - return weblog_name == "otel_collector" and scenario.name in ("OTEL_COLLECTOR", "OTEL_COLLECTOR_E2E") - - if "@" in weblog_name or scenario.name == "INTEGRATION_FRAMEWORKS": - return "@" in weblog_name and scenario.name == "INTEGRATION_FRAMEWORKS" - - return True - - if __name__ == "__main__": from utils._context._scenarios import scenarios @@ -628,17 +530,3 @@ def _is_supported(weblog: Weblog, scenario: Scenario, _ci_environment: str) -> b binaries_artifact="", unique_id="000", ) - -# if __name__ == "__main__": -# from utils._context._scenarios import get_all_scenarios - -# library = "python" -# for weblog in Weblog.load(library): -# for scenario in get_all_scenarios(): -# if scenario.github_workflow != "endtoend": -# continue -# groups = [group.name for group in scenario.scenario_groups] -# legacy = _is_supported(weblog, scenario, "") -# new_value = weblog.support_scenario(scenario.name, groups) -# if legacy is not new_value: -# print((legacy, new_value, weblog.name, scenario.name, groups))