Skip to content

Enforce continuation diagnostics in suite fixtures - #12528

Open
amarziali wants to merge 5 commits into
masterfrom
andrea.marziali/diagnose-suite-fixture-continuations
Open

amarziali wants to merge 5 commits into
masterfrom
andrea.marziali/diagnose-suite-fixture-continuations

Conversation

@amarziali

@amarziali amarziali commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

What Does This Do

Extends the default continuation-leak diagnostics to suite-level test fixtures:

  • Spock setupSpec() and cleanupSpec()
  • JUnit @BeforeAll and @AfterAll

This closes the diagnostic window around work created before the first test or cleaned up after the last test. Reports identify whether a failure belongs to suite setup, an individual test, or suite cleanup.

Class-level @TrackScopeContinuations configuration applies to suite fixtures. The investigation skill has also been updated to describe the expanded coverage.

flowchart LR
      A["Harness initializes tracer"] --> B["Suite setup<br/>setupSpec / @BeforeAll"]
      B --> C["Per-test diagnostics"]
      C --> D["Suite cleanup<br/>cleanupSpec / @AfterAll"]
      D --> E["Harness closes tracer"]

      B -. "report suite setup leaks" .-> F["Diagnostic report"]
      C -. "report test leaks" .-> F
      D -. "report suite cleanup leaks" .-> F
Loading

Motivation

Continuation work created in suite fixtures previously fell outside the per-test diagnostic window. This could hide lifecycle problems caused during shared fixture initialization or shutdown.

See #12458

Additional Notes

Contributor Checklist

Jira ticket: [PROJ-IDENT]

@datadog-prod-us1-5

datadog-prod-us1-5 Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

🎯 Code Coverage (details)
• Patch Coverage: 100.00%
• Overall Coverage: 59.09% (+0.00%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 95f34dc | Docs | Give us feedback!

@dd-octo-sts

dd-octo-sts Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 14.03 s 14.02 s [-0.8%; +0.9%] (no difference)
startup:insecure-bank:tracing:Agent 13.00 s 13.02 s [-0.9%; +0.6%] (no difference)
startup:petclinic:appsec:Agent 17.10 s 16.90 s [+0.2%; +2.1%] (maybe worse)
startup:petclinic:iast:Agent 17.01 s 17.06 s [-1.0%; +0.5%] (no difference)
startup:petclinic:profiling:Agent 16.72 s 16.95 s [-2.4%; -0.3%] (maybe better)
startup:petclinic:sca:Agent 17.04 s 16.86 s [+0.1%; +2.0%] (maybe worse)
startup:petclinic:tracing:Agent 16.25 s 16.07 s [+0.3%; +1.9%] (maybe worse)

Commit: 95f34dcd · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

@pr-commenter

pr-commenter Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Kafka / producer-benchmark

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch andrea.marziali/diag2 andrea.marziali/diagnose-suite-fixture-continuations
git_commit_date 1789558899 1789650722
git_commit_sha f6f5508 8314d04
See matching parameters
Baseline Candidate
ci_job_date 1789652054 1789652054
ci_job_id 2053394970 2053394970
ci_pipeline_id 138164902 138164902
cpu_model Intel(R) Xeon(R) Platinum 8175M CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8175M CPU @ 2.50GHz
jdkVersion 11.0.31 11.0.31
jmhVersion 1.36 1.36
jvm /usr/lib/jvm/java-11-openjdk-amd64/bin/java /usr/lib/jvm/java-11-openjdk-amd64/bin/java
jvmArgs -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=15002 -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=15002 -Dhttp.nonProxyHosts=localhost *.localhost
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-0-sdztcad8 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-0-sdztcad8 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
vmName OpenJDK 64-Bit Server VM OpenJDK 64-Bit Server VM
vmVersion 11.0.31+11-post-1ubuntu1-22.04.2-Ubuntu 11.0.31+11-post-1ubuntu1-22.04.2-Ubuntu

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 3 metrics, 0 unstable metrics.

See unchanged results
scenario Δ mean throughput
scenario:not-instrumented/KafkaProduceBenchmark.benchProduce same
scenario:only-tracing-dsm-disabled-benchmarks/KafkaProduceBenchmark.benchProduce same
scenario:only-tracing-dsm-enabled-benchmarks/KafkaProduceBenchmark.benchProduce same

@pr-commenter

pr-commenter Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Kafka / consumer-benchmark

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch andrea.marziali/diag2 andrea.marziali/diagnose-suite-fixture-continuations
git_commit_date 1789558899 1789650722
git_commit_sha f6f5508 8314d04
See matching parameters
Baseline Candidate
ci_job_date 1789652093 1789652093
ci_job_id 2053394971 2053394971
ci_pipeline_id 138164902 138164902
cpu_model Intel(R) Xeon(R) Platinum 8175M CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8175M CPU @ 2.50GHz
jdkVersion 11.0.31 11.0.31
jmhVersion 1.36 1.36
jvm /usr/lib/jvm/java-11-openjdk-amd64/bin/java /usr/lib/jvm/java-11-openjdk-amd64/bin/java
jvmArgs -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=15002 -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=15002 -Dhttp.nonProxyHosts=localhost *.localhost
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-0-2lm8nq30 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-0-2lm8nq30 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
vmName OpenJDK 64-Bit Server VM OpenJDK 64-Bit Server VM
vmVersion 11.0.31+11-post-1ubuntu1-22.04.2-Ubuntu 11.0.31+11-post-1ubuntu1-22.04.2-Ubuntu

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 3 metrics, 0 unstable metrics.

See unchanged results
scenario Δ mean throughput
scenario:not-instrumented/KafkaConsumerBenchmark.benchConsume same
scenario:only-tracing-dsm-disabled-benchmarks/KafkaConsumerBenchmark.benchConsume same
scenario:only-tracing-dsm-enabled-benchmarks/KafkaConsumerBenchmark.benchConsume unsure
[+660.810op/s; +9293.947op/s] or [+0.400%; +5.632%]

@amarziali
amarziali force-pushed the andrea.marziali/diag2 branch 2 times, most recently from 7dcb090 to 9549280 Compare September 22, 2026 06:46
@amarziali
amarziali force-pushed the andrea.marziali/diagnose-suite-fixture-continuations branch from 8314d04 to 7cfcfcd Compare September 22, 2026 09:00
@amarziali
amarziali force-pushed the andrea.marziali/diag2 branch 3 times, most recently from 94df599 to 8411dfd Compare September 25, 2026 15:16
Base automatically changed from andrea.marziali/diag2 to master September 28, 2026 08:10
@amarziali
amarziali force-pushed the andrea.marziali/diagnose-suite-fixture-continuations branch from 7cfcfcd to d8d4453 Compare September 28, 2026 08:43
@amarziali amarziali added type: feature Enhancements and improvements comp: testing Testing tag: no release notes Changes to exclude from release notes tag: override groovy enforcement Override the "Enforce Groovy Migration" check labels Sep 28, 2026
@amarziali
amarziali marked this pull request as ready for review September 28, 2026 12:28
@amarziali
amarziali requested review from a team as code owners September 28, 2026 12:28
@amarziali
amarziali requested review from ygree and removed request for a team September 28, 2026 12:28
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-28T12:32:40.920392Z d8d4453 Draft marked ready
🔒 Security Review ✅ Completed 2026-09-28T12:32:44.770040Z d8d4453 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@datadog-prod-us1-5 datadog-prod-us1-5 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.

Bits Code Review: FAIL

When a suite-setup fixture (@BeforeAll or setupSpec) fails before any test executes, the pending suite-setup diagnostic window is never flushed, so continuation failures are misattributed to suite cleanup or silently dropped — affecting both the JUnit (ScopeDiagnosticsExtension.java) and Spock (InstrumentationSpecification.groovy) instrumentation paths.

Open Bits AI session

🤖 Bits Code Review · Commit d8d4453 · @DataDog review to ask questions

@amarziali
amarziali requested a review from a team as a code owner September 28, 2026 13:56
@amarziali
amarziali requested review from AlexeyKuznetsov-DD and removed request for a team September 28, 2026 13:56

@datadog-prod-us1-5 datadog-prod-us1-5 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.

Bits Code Review: PASS

More details

Suite setup and cleanup are enclosed by distinct continuation-diagnostic scopes for JUnit and Spock, with class-level tracking configuration preserved across the fixture lifecycle.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Bits Code Review · Commit 7113065 · @DataDog review to ask questions

@dougqh dougqh 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.

The general direction looks good to me, but I'd like to separate the checks some.

I think some checks we should always strictly enforce in automatic instrumentation - for instance, no double finish, no double resolve, etc.
However, in manual instrumentation, I think we should tolerate misuse to avoid harming the customer application.
And since you can also use manual code to modify an automatic span, the mix needs to be tolerated, too. (That might need to be a separate PR).

I also think there are cases in automatic instrumentation where "leaks" must be tolerated.
While I understand that we want to avoid them from a timeliness and memory pressure perspective, we don’t control the APIs so we cannot guarantee that a continuation is resolved or cancelled.

So I'd like to see that check (and maybe only that check) be optional in automatic instrumentation tests. I'd still like a reason for opting out, but only from the continuation resolution/cancellation requirement.

@amarziali

Copy link
Copy Markdown
Contributor Author

I think some checks we should always strictly enforce in automatic instrumentation - for instance, no double finish, no double resolve, etc. However, in manual instrumentation, I think we should tolerate misuse to avoid harming the customer application. And since you can also use manual code to modify an automatic span, the mix needs to be tolerated, too. (That might need to be a separate PR).

@dougqh manual instrumentation is usually excluded by this harness since we only enforce instrumentation tests and not all the tests. Also, the annotation allows disabling for specific tests as escape hatch

So I'd like to see that check (and maybe only that check) be optional in automatic instrumentation tests. I'd still like a reason for opting out, but only from the continuation resolution/cancellation requirement.

I think indeed this check must be enabled and optionally disabled if and only if the enforcement is not compatible with the testing but not using it as "I cannot solve the issue in this instrumentation" since this maps to Flaky.

Please also note that the enforcement already runs on master. That PR is about doing the same on BeforeAll, AfterAll (aka test once initialisers / cleanup)

@ygree ygree 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.

The new Spock extension rejected method-level @TrackScopeContinuations annotations, breaking supported per-feature opt-outs and preventing the entire spec from running. Fixed in #12707 by accepting feature annotations, with a regression test covering the failure.

@dougqh

dougqh commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

I still think the right solution is to split the strict checks that we can always guarantee from those that we cannot.

The thing that we cannot guarantee is that a continuation will be resolved or cancelled. Unfortunately even if there is a cancel-like operation on the library being instrumented, we cannot guarantee that user code will call it. I actually think those are tests that we should be writing for each instrumentation, and I don't regard them as flaky. Maybe we just need some other more tolerant waiting mechanism for those cases instead.

And while I agree it would be nice if we could make all the instrumentations fully strict all the time, I don't see how that's possible. And as long as scenarios remain where strictness cannot be guaranteed, we need a way to test it.

@amarziali

Copy link
Copy Markdown
Contributor Author

The new Spock extension rejected method-level @TrackScopeContinuations annotations, breaking supported per-feature opt-outs and preventing the entire spec from running. Fixed in #12707 by accepting feature annotations, with a regression test covering the failure.

Good catch and thanks for having proposed a solution @ygree I've just merged in this branch

@amarziali

Copy link
Copy Markdown
Contributor Author

I still think the right solution is to split the strict checks that we can always guarantee from those that we cannot.

The thing that we cannot guarantee is that a continuation will be resolved or cancelled. Unfortunately even if there is a cancel-like operation on the library being instrumented, we cannot guarantee that user code will call it. I actually think those are tests that we should be writing for each instrumentation, and I don't regard them as flaky. Maybe we just need some other more tolerant waiting mechanism for those cases instead.

And while I agree it would be nice if we could make all the instrumentations fully strict all the time, I don't see how that's possible. And as long as scenarios remain where strictness cannot be guaranteed, we need a way to test it.

I agree with the narrow premise that we cannot force arbitrary application code to call a library’s cancellation API. Where I disagree is the conclusion that this means unresolved continuations must generally be tolerated by automatic instrumentation tests.

The harness is not asserting that every possible application behaves correctly. It is asserting that the bounded scenario created by a test leaves no captured work behind. If a test deliberately models abandonment, then that particular test may need different expectations, but I think we should first have a concrete example and define the intended production behavior.

In many cases, “the user may never call cancel” is precisely why the instrumentation must either avoid capturing the request context or release it on the library’s actual discard, timeout, close, or eviction path.

@bric3 bric3 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.

I agree with the intent and the implementation mostluy.

Usual test scenario should leave no unresolved continuations, that's fine by me. I guess I would have this question on shared fixtures, does it makes sense to have continuation(s) remaining valid until suite teardown? I don't have a concrete fixture requiring this today, so I'm comfortable revisiting it when one appears.


I'm approving, but before merging, please handle the nested case.

@amarziali
amarziali requested a review from ygree October 1, 2026 12:41

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: testing Testing tag: no release notes Changes to exclude from release notes tag: override groovy enforcement Override the "Enforce Groovy Migration" check type: feature Enhancements and improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants