Skip to content

tests: refactors redirection tests to avoid race condition - #14342

Merged
SergeyMenshykh merged 3 commits into
microsoft:mainfrom
baywet:tests/flaky-loopback
Aug 27, 2026
Merged

SergeyMenshykh merged 3 commits into
microsoft:mainfrom
baywet:tests/flaky-loopback

Conversation

@baywet

Copy link
Copy Markdown
Member

while working on #14340 I noticed some flaky unit tests are you can see in https://github.com/microsoft/semantic-kernel/actions/runs/32982261836/job/98221741513?pr=14340. This PR refactors the involved tests so they don't run into each other

@baywet
Vincent Biret (baywet) marked this pull request as ready for review August 26, 2026 16:45
@baywet
Vincent Biret (baywet) requested a review from a team as a code owner August 26, 2026 16:45
Copilot AI lite review requested due to automatic review settings August 26, 2026 16:45

Copilot AI 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.

Pull request overview

This PR refactors two redirect-related unit tests to use a shared loopback redirect server helper, aiming to eliminate test flakiness/race conditions seen when multiple tests create/tear down their own listeners.

Changes:

  • Replaced per-test HttpListener-based redirect setups with a shared RedirectLoopbackServer helper.
  • Updated redirect tests to use the helper’s BaseUri and to assert redirect-target access via a shared flag.
  • Added a new TCP-based loopback server utility under the unit test support folder.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
dotnet/src/Plugins/Plugins.UnitTests/Web/WebFileDownloadPluginTests.cs Uses the new loopback helper instead of an inline HttpListener redirect server.
dotnet/src/Plugins/Plugins.UnitTests/Core/HttpPluginTests.cs Uses the new loopback helper to validate redirects aren’t followed without relying on shared ports/listeners.
dotnet/src/Plugins/Plugins.UnitTests/Support/RedirectLoopbackServer.cs Introduces a reusable TCP loopback server that serves a 302 from /start and tracks whether the redirect target was requested.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

@github-actions github-actions 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.

MAF Automated Review — Iteration 1

Result: No findings
Scope: full PR (2 commit(s)): 2c018ec638d2, f8847407170a
Model: claude-opus-4.8

Overview

This test-only change replaces two flaky redirect tests — each of which spun up an HttpListener on a Random-guessed port with a fire-and-forget Task.Run loop — with a shared internal RedirectLoopbackServer helper bound to an ephemeral loopback port and torn down deterministically via IAsyncDisposable/await using. The redesign removes the actual race (colliding guessed ports across parallel test classes) and makes teardown deterministic by awaiting the server task. Correctness of the "redirect is not followed" assertion is anchored by the plugins' non-redirecting HttpClient (AllowAutoRedirect=false), so exactly one well-formed GET /start reaches the helper and /secret is never contacted. The project builds cleanly on the declared net10.0 target, and all TFM-gated socket/reader overloads resolve. The two residual robustness gaps in the helper (a Split(' ')[1] crash / false-positive contacted-flag, and unguarded HandleRequestAsync faults surfacing through DisposeAsync) are real but confined to abnormal loopback conditions and are already tracked verbatim by the two unresolved reviewer threads, so no new publishable finding remains.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
No publishable findings remained after source verification for this scope.

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (1)

dotnet/src/Plugins/Plugins.UnitTests/Support/RedirectLoopbackServer.cs:112

  • HandleRequestAsync parses the request line with requestLine?.Split(' ')[1], which can throw IndexOutOfRangeException for malformed / truncated requests (and null requestLine will also incorrectly mark RedirectTargetContacted). This can make the new loopback server flaky and cause tests to fail during disposal when _serverTask faults. Also, RedirectTargetContacted is currently set for any non-/start request, not just the redirect target path, which can produce false positives if the client ever requests another resource.
        var requestTarget = requestLine?.Split(' ')[1];
        if (requestTarget == "/start")
        {
            var response = $"HTTP/1.1 302 Found\r\nLocation: {new Uri(this.BaseUri, this._redirectTargetPath.TrimStart('/'))}\r\nContent-Length: 0\r\nConnection: close\r\n\r\n";
            await stream.WriteAsync(Encoding.ASCII.GetBytes(response), cancellationToken).ConfigureAwait(false);

@SergeyMenshykh
SergeyMenshykh merged commit 60264bb into microsoft:main Aug 27, 2026
18 checks passed
@baywet
Vincent Biret (baywet) deleted the tests/flaky-loopback branch August 27, 2026 16:39

This branch was previously deployed

1 inactive deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants