Skip to content

Fix flaky HttpRequestBuffering_DoesNotBufferDisabledOrOversizedLogs test#7304

Open
Copilot wants to merge 3 commits intomainfrom
copilot/fix-flaky-http-request-buffering-test
Open

Fix flaky HttpRequestBuffering_DoesNotBufferDisabledOrOversizedLogs test#7304
Copilot wants to merge 3 commits intomainfrom
copilot/fix-flaky-http-request-buffering-test

Conversation

Copy link
Contributor

Copilot AI commented Feb 14, 2026

Fix for Flaky Test: HttpRequestBuffering_DoesNotBufferDisabledOrOversizedLogs

Summary

Fixed the flaky test by suppressing ASP.NET Core infrastructure logs (DfaMatcher and HttpLoggingMiddleware) that were non-deterministically appearing in the log output.

Changes Made

  • Removed the DfaMatcher-specific log filter that was enabling Debug logs
  • Replaced Microsoft.AspNetCore.HttpLogging filter with broader Microsoft.AspNetCore filter at LogLevel.None
  • Added specific Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware filter to override base configuration
  • Updated expected log count from 6 to 5
  • Updated comments to accurately reflect the expected logs
  • Fixed comment to correctly describe log emission order (logs 2-3 from /logatrequest, logs 4-5 from "test")

Root Cause

The test makes two HTTP requests that each trigger ASP.NET Core routing logs (DfaMatcher) and HTTP logging middleware logs. The non-determinism arose from:

  1. The original filter enabled DfaMatcher at Debug level but only accounted for one log, not two
  2. HttpLoggingMiddleware logs were being emitted due to filter priority issues

Solution

By suppressing ALL Microsoft.AspNetCore infrastructure logs (both DfaMatcher and HttpLoggingMiddleware), the test now only captures the expected application logs:

  1. Flushed Trace from "test" category
  2. Unbuffered Information from "logatrequest" category
  3. Unbuffered oversized Trace from "logatrequest" category
  4. Unbuffered Information from "test" category
  5. Unbuffered oversized Trace from "test" category

Validation

  • Test passes consistently
  • All 3 HttpRequestBuffering tests pass
  • All 106 AcceptanceTests pass
  • No other tests affected by the change
Original prompt

Problem

The test Microsoft.AspNetCore.Diagnostics.Logging.Test.AcceptanceTests.HttpRequestBuffering_DoesNotBufferDisabledOrOversizedLogs is flaky in CI, failing with:

Assert.Equal() Failure: Values differ
Expected: 6
Actual:   7

at line 950 in test/Libraries/Microsoft.AspNetCore.Diagnostics.Middleware.Tests/Logging/AcceptanceTests.cs.

Root Cause

The test makes two HTTP requests (/flushalllogs and /logatrequest). Each request goes through ASP.NET Core routing, which triggers DfaMatcher Debug-level logs. The test has a filter enabling Microsoft.AspNetCore.Routing.Matching.DfaMatcher at LogLevel.Debug, but only accounts for one DfaMatcher log in its expected count of 6.

The non-determinism arises from the interaction between per-request buffering and global buffering with AutoFlushDuration = TimeSpan.Zero:

  1. The first request (/flushalllogs) buffers a DfaMatcher Debug log in its per-request buffer, then flushes both the per-request and global buffers. This sets _lastFlushTimestamp on the global GlobalBuffer for the DfaMatcher category.
  2. The second request (/logatrequest) also produces a DfaMatcher Debug log. This log goes to a new per-request IncomingRequestLogBuffer (fresh scope, _lastFlushTimestamp = default), so it gets buffered there. Since /logatrequest never calls Flush(), the log is silently dropped when the scope disposes → 6 total logs.
  3. However, if the DfaMatcher log from the second request instead routes through the global buffer fallback (e.g., if HttpContext is briefly null during request startup), the global buffer's TryEnqueue returns false (because _lastFlushTimestamp was already set and AutoFlushDuration = Zero means GetUtcNow() >= _lastFlushTimestamp), so the log is emitted directly → 7 total logs.

Options Considered

Option A: Assert on ≥ 6 and filter by category — Rather than asserting an exact total count, assert on the specific logs by category (e.g., 3 from "test", 2 from "logatrequest"). This validates the actual buffering behavior without being sensitive to infrastructure log counts. However, it weakens the test by not catching unexpected extra logs.

Option B: Use a dedicated test logger instead of DfaMatcher — Replace the DfaMatcher dependency with explicit test loggers. The DfaMatcher logs aren't what this test is testing anyway.

Option C: Assert on exact count and filter by category — Similar to Option A but still validates that no unexpected logs appear in the categories under test.

Option D: Disable DfaMatcher logs entirely — Since this test's purpose is to verify that disabled-level and oversized logs bypass the buffer (not to test DfaMatcher buffering), suppress all Microsoft.AspNetCore logs by changing the DfaMatcher filter from LogLevel.Debug to removing it and instead setting Microsoft.AspNetCore to LogLevel.None. This eliminates the infrastructure noise entirely and makes the exact log count deterministic.

Chosen Direction: Option D

Option D is the cleanest fix. The test's purpose is to verify that disabled-level logs and oversized logs bypass the buffer — it doesn't need DfaMatcher logs to prove that. The other buffering tests (HttpRequestBuffering and HttpRequestBuffering_RespectsAutoFlush) that actually need DfaMatcher logs only make one flushing request, so they avoid the two-request problem.

Required Changes

In test/Libraries/Microsoft.AspNetCore.Diagnostics.Middleware.Tests/Logging/AcceptanceTests.cs, in the HttpRequestBuffering_DoesNotBufferDisabledOrOversizedLogs test method (starting around line 895):

  1. Remove the line builder.AddFilter("Microsoft.AspNetCore.Routing.Matching.DfaMatcher", LogLevel.Debug); (line 906). The existing filter builder.AddFilter("Microsoft.AspNetCore.HttpLogging", LogLevel.None) at line 910 should be kept, but it's no longer the only Microsoft.AspNetCore filter needed.

  2. Change the builder.AddFilter("Microsoft.AspNetCore.HttpLogging", LogLevel.None) line to suppress ALL ASP.NET Core infrastructure logs: builder.AddFilter("Microsoft.AspNetCore", LogLevel.None). This covers both HttpLogging and DfaMatcher and any other ASP.NET Core infrastructure logs. Note: in the RunAsync helper method (lines 152-177), there are already filters like .AddFilter("Microsoft.AspNetCore", LogLevel.Warning) set on the logging builder, but the test's configure delegate calls builder.AddLogging(...) which adds additional filters. The new filter Microsoft.AspNetCore at LogLevel.None in the test's own AddLogging call should take precedence for the more specific category.

  3. Update the assertion on line 950 from Assert.Equal(6, logCollector.Count) to Assert.Equal(5, logCollector.Count) — since we now expect:

    • 1st: the flushed Trace from "test" category (was buffered, then flushed by /flushalllogs)
    • 2nd: the unbuffered Information from "test" category (Information bufferin...

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Microsoft Reviewers: Open in CodeFlow

…ogs by suppressing ASP.NET Core infrastructure logs

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix flaky acceptance test for HTTP request buffering Fix flaky HttpRequestBuffering_DoesNotBufferDisabledOrOversizedLogs test Feb 14, 2026
Copilot AI requested a review from stephentoub February 14, 2026 23:45
@stephentoub stephentoub marked this pull request as ready for review February 15, 2026 11:48
@stephentoub stephentoub requested a review from a team as a code owner February 15, 2026 11:48
Copilot AI review requested due to automatic review settings February 15, 2026 11:48
@stephentoub stephentoub enabled auto-merge (squash) February 15, 2026 11:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a flaky test HttpRequestBuffering_DoesNotBufferDisabledOrOversizedLogs that was intermittently failing with "Expected: 6, Actual: 7" due to non-deterministic ASP.NET Core infrastructure logs (DfaMatcher, HttpLoggingMiddleware) from multiple HTTP requests. The test validates that disabled-level and oversized logs bypass the request buffering mechanism.

Changes:

  • Replaced selective DfaMatcher logging with complete suppression of all Microsoft.AspNetCore infrastructure logs
  • Added explicit Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware filter to override base configuration priority
  • Updated expected log count from 6 to 5 to reflect only application logs under test

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
auto-merge was automatically disabled February 19, 2026 20:56

Head branch was pushed to by a user without write access

@stephentoub stephentoub enabled auto-merge (squash) February 19, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments