[CI Visibility] Bound global coverage memory - #8926
Conversation
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8926) and master. ✅ No regressions detected - check the details below Full Metrics ComparisonFakeDbCommand
HttpMessageHandler
Comparison explanationExecution-time benchmarks measure the whole time it takes to execute a program, and are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are highlighted in **red**. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). Duration chartsFakeDbCommand (.NET Framework 4.8)gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (74ms) : 70, 78
master - mean (72ms) : 69, 75
section Bailout
This PR (8926) - mean (76ms) : 73, 80
master - mean (81ms) : 73, 89
section CallTarget+Inlining+NGEN
This PR (8926) - mean (1,091ms) : 1045, 1136
master - mean (1,096ms) : 1052, 1141
FakeDbCommand (.NET Core 3.1)gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (114ms) : 108, 120
master - mean (115ms) : 108, 121
section Bailout
This PR (8926) - mean (110ms) : 108, 113
master - mean (115ms) : 108, 122
section CallTarget+Inlining+NGEN
This PR (8926) - mean (787ms) : 764, 810
master - mean (785ms) : 763, 807
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (97ms) : 95, 100
master - mean (103ms) : 97, 109
section Bailout
This PR (8926) - mean (102ms) : 98, 107
master - mean (99ms) : 96, 103
section CallTarget+Inlining+NGEN
This PR (8926) - mean (941ms) : 907, 974
master - mean (950ms) : 901, 999
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (97ms) : 92, 102
master - mean (98ms) : 92, 105
section Bailout
This PR (8926) - mean (97ms) : 95, 99
master - mean (102ms) : 96, 108
section CallTarget+Inlining+NGEN
This PR (8926) - mean (826ms) : 789, 862
master - mean (822ms) : 782, 862
HttpMessageHandler (.NET Framework 4.8)gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (203ms) : 197, 209
master - mean (211ms) : 205, 217
section Bailout
This PR (8926) - mean (208ms) : 202, 213
master - mean (215ms) : 211, 219
section CallTarget+Inlining+NGEN
This PR (8926) - mean (1,221ms) : 1180, 1261
master - mean (1,268ms) : 1214, 1321
HttpMessageHandler (.NET Core 3.1)gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (289ms) : 282, 296
master - mean (303ms) : 294, 312
section Bailout
This PR (8926) - mean (289ms) : 286, 293
master - mean (305ms) : 295, 315
section CallTarget+Inlining+NGEN
This PR (8926) - mean (977ms) : 954, 1000
master - mean (1,009ms) : 984, 1035
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (285ms) : 278, 291
master - mean (298ms) : 291, 305
section Bailout
This PR (8926) - mean (285ms) : 278, 292
master - mean (297ms) : 291, 303
section CallTarget+Inlining+NGEN
This PR (8926) - mean (1,176ms) : 1140, 1212
master - mean (1,200ms) : 1160, 1239
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8926) - mean (283ms) : 278, 288
master - mean (300ms) : 294, 306
section Bailout
This PR (8926) - mean (285ms) : 279, 292
master - mean (301ms) : 293, 308
section CallTarget+Inlining+NGEN
This PR (8926) - mean (1,053ms) : 1015, 1092
master - mean (1,094ms) : 989, 1199
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
dd-trace-dotnet/tracer/src/Datadog.Trace.Tools.Runner/CiUtils.cs
Lines 427 to 429 in 31856d7
When dotnet test uses Microsoft Testing Platform coverage, this branch deliberately omits the Datadog in-proc collector. However, RequestSeal() is only invoked from that collector's TestSessionEnd, while code coverage remains enabled and TestModule still publishes the new pending/raw global-coverage artifacts. Those artifacts therefore never receive ready markers; reusing an explicit coverage directory leaves an incomplete protocol set that makes subsequent reconciliation reject both the stale and newly produced coverage files. Add an equivalent end-of-run sealing path for the Testing Platform case, or avoid creating protocol artifacts there.
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
BenchmarksBenchmark execution time: 2026-07-31 22:17:15 Comparing candidate commit f74fb63 in PR branch Found 0 performance improvements and 1 performance regressions! Performance is the same for 71 metrics, 0 unstable metrics, 61 known flaky benchmarks, 65 flaky benchmarks without significant changes.
|
@chatgpt-codex-connector Addressed in a79fa2d. Global coverage is now finalized from TestOptimization shutdown after active modules are closed, so Microsoft Testing Platform runs seal their output even when the Datadog in-proc collector is intentionally omitted. The finalization path is idempotent and shared with the collector. I also added unit coverage plus an MTP end-to-end test that runs twice against the same coverage directory and verifies successful reconciliation. |
|
To use Codex here, create an environment for this repo. |
eee3854 to
c62a892
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c62a892b39
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
6cb87db to
bfd8734
Compare
Snapshots difference summaryThe following differences have been observed in committed snapshots. It is meant to help the reviewer. |
8a3be12 to
36bb32a
Compare
Summary of changes
ModuleValuebuffers immediately.dotnet testcompletes.Reason for change
DefaultWithGlobalCoverageEventHandlerpreviously kept every completedCoverageContextContainerin_coveragesuntil global coverage was calculated at the end of the test process. Each context retained one or moreModuleValueinstances backed byMarshal.AllocHGlobal, so native memory grew with the number of completed tests rather than with the amount of unique code being measured.APMS-20099 reports this failure mode in a Windows VSTest/NUnit run with 5,134 tests: 60,863 live
ModuleValueinstances retained approximately 16 GB of native buffers and causedtesthost.exeto run out of memory beforeTestSessionEndcould perform the only cleanup.The fix must release completed contexts during the run without losing their contribution to the final union. It must also support multiple testhost processes, preserve the per-test payload, and avoid adding synchronization to the generated counter-increment hot path.
Implementation details
Release completed contexts without losing coverage
CoverageSessionHandlebinds each test to the exact handler, context, and lifecycle admission created at test start. This avoids closing the wrongAsyncLocalcontext and makes construction, abort, and teardown cleanup explicit.ModuleCoverageDatascans the existing byte or integer counter buffer once. A line is covered when its counter is non-zero; this preserves both line-execution and line-call-count modes, including counter overflow.GlobalCoverageAccumulator.finallyafter capture and merge, so its native buffers are released even if coverage processing fails.Preserve global coverage correctness
Moduleand retains the original metadata and executable bitmap for that module.Keep the probe hot path and IL contract unchanged
CoverageReporter<TMeta>.GetFileCounter(int)and receives the same native pointer used by the existing counter increment IL.AsyncLocalflow falls back to the process-global module buffer instead of reopening or writing to a disposed test context.Publish complete coverage across testhost processes
TestOptimizationshutdown hook seals the same idempotent finalization path, writes one immutable JSON artifact atomically, and removes the pending marker only after the artifact is durable.dotnet testinstrumentation combines only artifacts belonging to its run, applies the existing ITR backfill, and atomically publishes the finalsession-coverage-*.jsonfile.Test coverage
AsyncLocalflows, concurrent starts/snapshots/sealing, allocation and metadata failures, configured memory limits, atomic publication, run isolation, malformed artifacts, and ITR consumer behavior.GetFileCounterpointer shape, does not add exception handlers or invalidatetail.methods, and still releases buffers when instrumented code throws.testhostthrough the productiondd-trace ci runtool and packaged Datadog collector, using Coverlet 3.2.0 and 6.0.0.Other details