Skip to content

ci: dogfood ddtest across riot test suites - #19870

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 26 commits into
mainfrom
gnufede/ddtest-dogfooding
Sep 3, 2026
Merged

ci: dogfood ddtest across riot test suites#19870
gh-worker-dd-mergequeue-cf854d[bot] merged 26 commits into
mainfrom
gnufede/ddtest-dogfooding

Conversation

@gnufede

@gnufede gnufede commented Aug 26, 2026

Copy link
Copy Markdown
Member

Summary

Extend ddtest dogfooding from the standalone internal pilot to opt-in riot test suites while preserving the existing two-stage plan/run CI design.

The generated GitLab pipeline now discovers each matching riot venv, creates one plan job per suite that loops over its venv hashes, and fans out run jobs by venv and CI node. The jobs reuse the prebuilt base venvs and a shared ddtest build artifact.

Implementation

  • Add ddtest: true suite metadata for the selected suites and validate that every matching riot venv declares DDTEST_TESTS_LOCATION.
  • Teach gen_gitlab_config.py to collect riot hashes, Python versions, test locations, and ddtest-specific pytest options, then emit the corresponding plan/run matrices.
  • Use Riot's run --command override to prepare and execute each selected venv, removing the custom scripts/ddtest-riot.py bridge and its manual environment reconstruction.
  • Preserve coverage handling, snapshot test-agent routing, CI Visibility options, and existing legacy Riot commands.

No ddtest source changes are included.

Testing

  • Generated the complete GitLab CI configuration successfully.
  • Passed the targeted generator tests (11 passed).
  • Passed formatting/style, Riot, suitespec, spelling, shell syntax, and CI dependency validation checks.

Risks

  • The new path is opt-in through suitespec metadata; legacy riot jobs remain unchanged.
  • CI behavior depends on the generated configuration and the shared build artifacts; failures remain visible per suite and venv.

Additional Notes

The implementation intentionally avoids per-venv base-venv rebuilds and keeps ddtest's plan/run responsibilities separate from Riot's venv lifecycle management.

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codeowners resolved as

Resolved from the full PR diff against main using the target branch CODEOWNERS file.
CODEOWNERS team requests not listed below are not required by the current file set.

No remaining files require a CODEOWNERS review.

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 26, 2026

Copy link
Copy Markdown

Circular import analysis

⚠️ Existing circular imports

There are 3 circular imports that already exist on the base branch and have not been changed by this PR.

ddtrace.errortracking._handled_exceptions.bytecode_injector -> ddtrace.errortracking._handled_exceptions.callbacks -> ddtrace.errortracking._handled_exceptions.collector -> ddtrace.errortracking._handled_exceptions.bytecode_reporting -> ddtrace.errortracking._handled_exceptions.bytecode_injector
ddtrace.llmobs -> ddtrace.llmobs._evaluators -> ddtrace.llmobs._evaluators.format -> ddtrace.llmobs._experiment -> ddtrace.llmobs
ddtrace.appsec._asm_request_context -> ddtrace.appsec._iast._iast_request_context_base -> ddtrace.appsec._iast._iast_env -> ddtrace.appsec._iast.reporter -> ddtrace.appsec._exploit_prevention.stack_traces -> ddtrace.appsec._asm_request_context

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 26, 2026

Copy link
Copy Markdown

Dependency direction analysis

⚠️ Existing dependency direction violations

There are 230 dependency direction violations that already exist on the base branch and have not been changed by this PR.

Show existing violations (showing 5 of 230 highest severity)
ddtrace.internal.tracemethods -×-> ddtrace.trace  (internal-core -> product:tracing, score=134)
ddtrace.debugging._signal.tracing -×-> ddtrace.trace  (product:debugging -> product:tracing, score=132)
ddtrace.llmobs._evaluators.runner -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=132)
ddtrace.llmobs._integrations.openai -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=132)
ddtrace.llmobs._integrations.mcp -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=132)

To see all violations, download the layers-base.json and layers-pr.json artifacts from this CI job and run:

uv run --script scripts/import-analysis/layers.py compare layers-base.json layers-pr.json

@datadog-official

datadog-official Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 49780db | Docs | View more details | Give us feedback!

@gnufede gnufede added changelog/no-changelog A changelog entry is not required for this PR. CI labels Aug 26, 2026
@pr-commenter

pr-commenter Bot commented Aug 26, 2026

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-09-03 14:35:21

Comparing candidate commit 49780db in PR branch gnufede/ddtest-dogfooding with baseline commit 8a2c6be in branch main.

📊 Benchmarking dashboard

Found 0 performance improvements and 6 performance regressions! Performance is the same for 580 metrics, 10 unstable metrics, 2 known flaky benchmarks, 16 flaky benchmarks without significant changes.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

scenario:httppropagationextract-tracecontext_headers

  • 🟥 execution_time [+2.387µs; +2.661µs] or [+7.147%; +7.966%]

scenario:httppropagationinject-ids_only

  • 🟥 execution_time [+2.259µs; +2.395µs] or [+13.411%; +14.216%]

scenario:iastaspects-rstrip_aspect

  • 🟥 execution_time [+83.045µs; +92.948µs] or [+22.085%; +24.719%]

scenario:iastaspectsospath-ospathbasename_aspect

  • 🟥 execution_time [+107.861µs; +115.036µs] or [+27.062%; +28.862%]

scenario:telemetryaddmetric-1-count-metric-1-times

  • 🟥 execution_time [+507.689ns; +541.012ns] or [+18.514%; +19.729%]

scenario:tracer-small

  • 🟥 execution_time [+37.834µs; +39.670µs] or [+11.526%; +12.085%]

Unstable benchmarks

These benchmarks have a confidence interval too wide to call a change; treat them as noise rather than signal.

scenario:coreapiscenario-context_with_data_listeners

  • unstable execution_time [-816.511ns; +661.164ns] or [-7.360%; +5.960%]

scenario:coreapiscenario-core_dispatch_1_listener

  • unstable execution_time [-35.445ns; +30.622ns] or [-5.797%; +5.008%]

scenario:coreapiscenario-core_dispatch_50_listeners

  • unstable execution_time [-1682.628ns; +1618.047ns] or [-9.887%; +9.507%]

scenario:coreapiscenario-core_dispatch_exception_listeners

  • unstable execution_time [-1174.391ns; +1303.575ns] or [-9.074%; +10.072%]

scenario:coreapiscenario-core_dispatch_listeners

  • unstable execution_time [-335.789ns; +313.389ns] or [-9.152%; +8.542%]

scenario:coreapiscenario-core_dispatch_no_args_listeners

  • unstable execution_time [-297.237ns; +213.138ns] or [-10.133%; +7.266%]

scenario:coreapiscenario-core_dispatch_with_results_1_listener

  • unstable execution_time [-159.648ns; -14.936ns] or [-13.235%; -1.238%]

scenario:coreapiscenario-core_dispatch_with_results_50_listeners

  • unstable execution_time [-3660.788ns; +4370.953ns] or [-8.969%; +10.709%]

scenario:coreapiscenario-core_dispatch_with_results_listeners

  • unstable execution_time [-742.674ns; +801.040ns] or [-9.176%; +9.897%]

scenario:packagesupdateimporteddependencies-import_many_stdlib_cached

  • unstable execution_time [-55722.813ns; +54647.417ns] or [-9.659%; +9.473%]

Known flaky benchmarks

These benchmarks are marked as flaky and will not trigger a failure. Modify FLAKY_BENCHMARKS_REGEX to control which benchmarks are marked as flaky.

scenario:iastaspects-swapcase_aspect

  • 🟥 execution_time [+46.002µs; +53.179µs] or [+16.734%; +19.345%]

scenario:span-start

  • 🟥 execution_time [+1.413ms; +1.575ms] or [+9.925%; +11.069%]

Known flaky benchmarks without significant changes:

  • scenario:errortrackingflasksqli-baseline
  • scenario:flasksimple-iast-get
  • scenario:iastaspects-casefold_aspect
  • scenario:iastaspects-casefold_noaspect
  • scenario:iastaspects-index_aspect
  • scenario:iastaspects-ljust_noaspect
  • scenario:iastaspects-lower_aspect
  • scenario:iastaspects-replace_aspect
  • scenario:iastaspects-title_noaspect
  • scenario:iastaspects-translate_aspect
  • scenario:iastaspects-translate_noaspect
  • scenario:iastaspects-upper_noaspect
  • scenario:packagespackageforrootmodulemapping-cache_off
  • scenario:packagespackageforrootmodulemapping-cache_on
  • scenario:sethttpmeta-all-enabled
  • scenario:telemetryaddmetric-record-100-metrics

@gnufede
gnufede force-pushed the gnufede/ddtest-dogfooding branch from 7267505 to 7ae1d3f Compare August 26, 2026 12:58
@gnufede

gnufede commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

@DataDog review

@datadog-official datadog-official Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datadog Autotest: FAIL

The ddtest switch does not keep each suite's discovery path or pytest selection. Matrix needs also combine plan artifacts from unrelated riot hashes, so some new jobs can skip required tests or use a plan for another environment.

Open Bits AI session

🤖 Datadog Autotest · Commit 0f9bff1 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

Comment thread .gitlab/tests.yml Outdated
Comment thread scripts/gen_gitlab_config.py Outdated
Comment thread scripts/gen_gitlab_config.py Outdated
Comment thread scripts/gen_gitlab_config.py Outdated
@gnufede gnufede changed the title ci: dogfood ddtest for the internal suite (standalone pilot) feat(ci): dogfood ddtest across Riot test suites Aug 27, 2026
@gnufede gnufede changed the title feat(ci): dogfood ddtest across Riot test suites ci: dogfood ddtest across riot test suites Aug 27, 2026
Comment thread tests/contrib/suitespec.yml
Comment thread tests/contrib/suitespec.yml
Comment thread riotfile.py Outdated
gnufede added a commit that referenced this pull request Aug 27, 2026
## Summary

Stacked follow-up to #19870 that removes the standalone
`scripts/ddtest-infer-service` helper while preserving the pre-import
service override that ddtest requires.

## Changes

- Add explicit `ddtest_service` values to every ddtest-enabled suite in
`tests/suitespec.yml`, `tests/contrib/suitespec.yml`,
`tests/llmobs/suitespec.yml`, and `tests/appsec/suitespec.yml`.
- Have `scripts/gen_gitlab_config.py` require the metadata and emit
`_DD_PYTEST_XDIST_INFERRED_SERVICE` directly on each generated ddtest
run job.
- Remove the shell command substitution and delete
`scripts/ddtest-infer-service`.
- Add generator coverage for the emitted service variable.

This keeps the variable available before Riot starts pytest, when the
controller imports ddtrace, while making the expected suite-level
service visible and reviewable in suitespec instead of reimplementing
package discovery in a shell helper.

## Testing

- `scripts/lint suitespec-check`
- `scripts/gen_gitlab_config.py`
- `scripts/run-tests -s --venv 1c8641e -- --
tests/internal/test_gen_gitlab_config.py` (12 passed)

No customer-facing changelog is required.
@gnufede

gnufede commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

@DataDog review

@datadog-official datadog-official Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datadog Autotest: PASS

More details

The specialist candidate refers to a file that this PR does not change. The effective three-dot diff has no reportable finding.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Datadog Autotest · Commit 2b40758 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

gnufede added a commit that referenced this pull request Aug 28, 2026
Add ddtest: true to appsec_threats_fastapi_iast (tests/appsec/suitespec.yml)
and mistralai (tests/llmobs/suitespec.yml), with corresponding riotfile.py
changes (DDTEST_SUITE_PATH, DDTEST_TESTS_LOCATION, command placeholders).

appsec_threats_fastapi_iast also adds:
- DDTEST_PYTEST_ADDOPTS: -k 'Test_FastAPI and not Test_FastAPI_RC' to
  exclude the RC test class (which needs DD_REMOTE_CONFIGURATION_ENABLED=true,
  handled by the dedicated appsec_threats_fastapi_rc suite).
- services: [testagent] for snapshot comparison.
- env: _DD_PYTEST_XDIST_INFERRED_SERVICE for stable service inference.

Split from #19870 to isolate CODEOWNER approvals.
gnufede added a commit that referenced this pull request Aug 28, 2026
Add ddtest: true to appsec_threats_fastapi_iast (tests/appsec/suitespec.yml)
and mistralai (tests/llmobs/suitespec.yml), with corresponding riotfile.py
changes (DDTEST_SUITE_PATH, DDTEST_TESTS_LOCATION, command placeholders).

appsec_threats_fastapi_iast also adds:
- DDTEST_PYTEST_ADDOPTS: -k 'Test_FastAPI and not Test_FastAPI_RC' to
  exclude the RC test class (which needs DD_REMOTE_CONFIGURATION_ENABLED=true,
  handled by the dedicated appsec_threats_fastapi_rc suite).
- services: [testagent] for snapshot comparison.
- env: _DD_PYTEST_XDIST_INFERRED_SERVICE for stable service inference.

Split from #19870 to isolate CODEOWNER approvals.
gnufede added a commit that referenced this pull request Aug 28, 2026
Add ddtest: true (ddtest_nodes: 2) to appsec_integrations_django
(tests/appsec/suitespec.yml) and profile (tests/profiling/suitespec.yml)
suites, with corresponding riotfile.py changes (DDTEST_SUITE_PATH,
DDTEST_TESTS_LOCATION, command placeholders).

Split from #19870 to isolate CODEOWNER approvals.
gnufede added a commit that referenced this pull request Aug 28, 2026
Add ddtest: true to appsec_threats_fastapi_iast (tests/appsec/suitespec.yml)
and mistralai (tests/llmobs/suitespec.yml), with corresponding riotfile.py
changes (DDTEST_SUITE_PATH, DDTEST_TESTS_LOCATION, command placeholders).

appsec_threats_fastapi_iast also adds:
- DDTEST_PYTEST_ADDOPTS: -k 'Test_FastAPI and not Test_FastAPI_RC' to
  exclude the RC test class (which needs DD_REMOTE_CONFIGURATION_ENABLED=true,
  handled by the dedicated appsec_threats_fastapi_rc suite).
- services: [testagent] for snapshot comparison.
- env: _DD_PYTEST_XDIST_INFERRED_SERVICE for stable service inference.

Split from #19870 to isolate CODEOWNER approvals.
gnufede added a commit that referenced this pull request Aug 28, 2026
Add ddtest: true (ddtest_nodes: 2) to appsec_integrations_django
(tests/appsec/suitespec.yml) and profile (tests/profiling/suitespec.yml)
suites, with corresponding riotfile.py changes (DDTEST_SUITE_PATH,
DDTEST_TESTS_LOCATION, command placeholders).

Split from #19870 to isolate CODEOWNER approvals.
gnufede added a commit that referenced this pull request Aug 28, 2026
Add ddtest: true to appsec_threats_fastapi_iast (tests/appsec/suitespec.yml)
and mistralai (tests/llmobs/suitespec.yml), with corresponding riotfile.py
changes (DDTEST_SUITE_PATH, DDTEST_TESTS_LOCATION, command placeholders).

appsec_threats_fastapi_iast also adds:
- DDTEST_PYTEST_ADDOPTS: -k 'Test_FastAPI and not Test_FastAPI_RC' to
  exclude the RC test class (which needs DD_REMOTE_CONFIGURATION_ENABLED=true,
  handled by the dedicated appsec_threats_fastapi_rc suite).
- services: [testagent] for snapshot comparison.
- env: _DD_PYTEST_XDIST_INFERRED_SERVICE for stable service inference.

Split from #19870 to isolate CODEOWNER approvals.
gnufede added a commit that referenced this pull request Aug 28, 2026
Add ddtest: true (ddtest_nodes: 2) to appsec_integrations_django
(tests/appsec/suitespec.yml) and profile (tests/profiling/suitespec.yml)
suites, with corresponding riotfile.py changes (DDTEST_SUITE_PATH,
DDTEST_TESTS_LOCATION, command placeholders).

Split from #19870 to isolate CODEOWNER approvals.
gnufede added a commit that referenced this pull request Aug 28, 2026
Add ddtest: true to appsec_threats_fastapi_iast (tests/appsec/suitespec.yml)
and mistralai (tests/llmobs/suitespec.yml), with corresponding riotfile.py
changes (DDTEST_SUITE_PATH, DDTEST_TESTS_LOCATION, command placeholders).

appsec_threats_fastapi_iast also adds:
- DDTEST_PYTEST_ADDOPTS: -k 'Test_FastAPI and not Test_FastAPI_RC' to
  exclude the RC test class (which needs DD_REMOTE_CONFIGURATION_ENABLED=true,
  handled by the dedicated appsec_threats_fastapi_rc suite).
- services: [testagent] for snapshot comparison.
- env: _DD_PYTEST_XDIST_INFERRED_SERVICE for stable service inference.

Split from #19870 to isolate CODEOWNER approvals.
gnufede added a commit that referenced this pull request Aug 28, 2026
Add ddtest: true (ddtest_nodes: 2) to appsec_integrations_django
(tests/appsec/suitespec.yml) and profile (tests/profiling/suitespec.yml)
suites, with corresponding riotfile.py changes (DDTEST_SUITE_PATH,
DDTEST_TESTS_LOCATION, command placeholders).

Split from #19870 to isolate CODEOWNER approvals.
@gnufede
gnufede force-pushed the gnufede/ddtest-dogfooding branch from 78daa37 to fa94b69 Compare September 3, 2026 10:29
@gnufede
gnufede force-pushed the gnufede/ddtest-dogfooding branch from 17524e9 to 30d176c Compare September 3, 2026 10:59
@gnufede
gnufede force-pushed the gnufede/ddtest-dogfooding branch from 30d176c to 17524e9 Compare September 3, 2026 10:59
@gnufede

gnufede commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

/merge -f --reason "merge queue failing on unrelated jobs"

@gh-worker-devflow-routing-ef8351

gh-worker-devflow-routing-ef8351 Bot commented Sep 3, 2026

Copy link
Copy Markdown

View all feedbacks in Devflow UI.

2026-09-03 15:49:51 UTC ℹ️ Start processing command /merge -f --reason "merge queue failing on unrelated jobs"


2026-09-03 15:49:54 UTC ❌ MergeQueue

PR already in the queue with status in_progress

@gnufede

gnufede commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

/merge -f --reason "merge queue failing on unrelated jobs"

@gh-worker-devflow-routing-ef8351

gh-worker-devflow-routing-ef8351 Bot commented Sep 3, 2026

Copy link
Copy Markdown

View all feedbacks in Devflow UI.

2026-09-03 15:50:48 UTC ℹ️ Start processing command /merge -f --reason "merge queue failing on unrelated jobs"


2026-09-03 15:50:54 UTC ℹ️ MergeQueue: pull request added to the queue

The expected merge time in main is approximately 0s (p90).


2026-09-03 15:51:04 UTC ℹ️ MergeQueue: This merge request was merged

Warning

This change was merged without running any pre merge CI checks

Reason: merge queue failing on unrelated jobs

@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot merged commit 390562c into main Sep 3, 2026
1407 checks passed
@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot deleted the gnufede/ddtest-dogfooding branch September 3, 2026 15:51
gh-worker-dd-mergequeue-cf854d Bot pushed a commit that referenced this pull request Sep 8, 2026
## Description

PR #19870 made the DDTest job generator select snapshot-specific templates whenever a suite uses `ddtest: true` and `snapshot: true`. For uv suites, it emits `.ddtest_base_uv_snapshot` and `.ddtest_run_uv_snapshot`, but #19870 only defined the non-snapshot uv templates.

The bug remained hidden until #20034 migrated `integration_testagent` to a suitespec matrix. GitLab then rejected the generated child pipeline because `.ddtest_run_uv_snapshot` did not exist. No test jobs could start. The same issue would affect any future snapshot suite using both DDTest and uv.

## Fix

- Define `.ddtest_base_uv_snapshot` by extending the existing `.test_base_uv_snapshot`. This reuses its Datadog Agent and test-agent services, test-agent URL setup, and project symlink.
- Define `.ddtest_run_uv_snapshot` by extending `.ddtest_run_uv` and taking its services from the snapshot base.
- Keep dependency installation and DDTest execution identical to the normal uv path. Only the snapshot test-agent setup is added.

## Testing

- Generated `integration_testagent` jobs from the #20034 head with this commit applied.
- GitLab CI lint accepted the complete generated child configuration.
- All 17 generator tests passed on Python 3.12 through `scripts/run-tests`.
- `scripts/lint checks` passed.

## Risks

Low. Riot jobs and non-snapshot uv jobs are unchanged. The new templates are only selected for DDTest snapshot suites using uv.

## Additional Notes

No customer-facing change.

Co-authored-by: munir.abdinur <munir.abdinur@datadoghq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/no-changelog A changelog entry is not required for this PR. CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants