Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 26, 2025

The ExecDefaultContainerStdOut test was failing intermittently with "address already in use" errors when tests ran in parallel. The root cause was a static port counter in WebSocketTestBase that incremented from 13255, causing port conflicts when multiple test instances started simultaneously.

Changes

  • Replace static port allocation with OS-assigned ports: Use http://127.0.0.1:0 instead of incrementing port counter
  • Eagerly bind ports in constructor: Start the host immediately to acquire the assigned port, then retrieve the actual address via IServerAddressesFeature
  • Remove redundant host startup: Delete Host.StartAsync() call from test since host is already running
  • Clarify property mutability: Add explicit private set to ServerBaseAddress and WebSocketBaseAddress properties

This follows the same pattern already used in MockKubeApiServer elsewhere in the codebase.

// Before: static port counter caused conflicts
private static int nextPort = 13255;
int port = Interlocked.Increment(ref nextPort);
ServerBaseAddress = new Uri($"http://localhost:{port}");

// After: OS assigns available port dynamically
Host = WebHost.CreateDefaultBuilder()
    .UseUrls("http://127.0.0.1:0")
    .Build();
Host.Start();

var serverAddress = Host.ServerFeatures.Get<IServerAddressesFeature>()?.Addresses.FirstOrDefault();
ServerBaseAddress = new Uri(serverAddress);

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • crl.comodoca.com
    • Triggering command: /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/csharp/csharp/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj --packages /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • idp.issuer.url
    • Triggering command: /usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net8.0/KubernetesClient.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net8.0/KubernetesClient.Tests.deps.json /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net8.0/testhost.dll --port 45675 --endpoint 127.0.0.1:045675 --role client --parentprocessid 6013 --telemetryoptedin false (dns block)
    • Triggering command: /usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net9.0/KubernetesClient.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net9.0/KubernetesClient.Tests.deps.json /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net9.0/testhost.dll --port 45053 --endpoint 127.0.0.1:045053 --role client --parentprocessid 6052 --telemetryoptedin false (dns block)
    • Triggering command: /usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net10.0/KubernetesClient.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net10.0/KubernetesClient.Tests.deps.json /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net10.0/testhost.dll --port 41007 --endpoint 127.0.0.1:041007 --role client --parentprocessid 6053 --telemetryoptedin false (dns block)
  • ocsp.comodoca.com
    • Triggering command: /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/csharp/csharp/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj --packages /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

fix flaky test

[xUnit.net 00:05:03.72] Can exec in pod's default container, STDOUT only [FAIL]
Failed Can exec in pod's default container, STDOUT only [59 ms]
Error Message:
System.IO.IOException : Failed to bind to address http://127.0.0.1:13260: address already in use.
---- Microsoft.AspNetCore.Connections.AddressInUseException : Only one usage of each socket address (protocol/network address/port) is normally permitted.
-------- System.Net.Sockets.SocketException : Only one usage of each socket address (protocol/network address/port) is normally permitted.


💡 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.

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Nov 26, 2025
Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Copilot
Once this PR has been reviewed and has the lgtm label, please ask for approval from tg123. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

1 similar comment
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Copilot
Once this PR has been reviewed and has the lgtm label, please ask for approval from tg123. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Nov 26, 2025
Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Nov 26, 2025
Copilot AI changed the title [WIP] Fix flaky test related to socket address usage Fix flaky test by using dynamic port allocation instead of static counter Nov 26, 2025
Copilot AI requested a review from tg123 November 26, 2025 11:04
Copilot finished work on behalf of tg123 November 26, 2025 11:04
@tg123 tg123 marked this pull request as ready for review November 26, 2025 19:28
Copilot AI review requested due to automatic review settings November 26, 2025 19:28
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Nov 26, 2025
@tg123
Copy link
Member

tg123 commented Nov 26, 2025

/LGTM

I thought it is a global webhost issue, seems websocket test only

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Nov 26, 2025
Copilot finished reviewing on behalf of tg123 November 26, 2025 19:30
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 issue caused by port conflicts when tests run in parallel. The solution replaces a static port counter with OS-assigned dynamic ports, following the same pattern already established by MockKubeApiServer in the codebase.

Key Changes

  • Switched from static port allocation (incrementing from 13255) to OS-assigned ports using http://127.0.0.1:0
  • Eagerly start the web host in the constructor to acquire and retrieve the assigned port via IServerAddressesFeature
  • Removed redundant Host.StartAsync() call from test since host is now started in base class constructor

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
tests/KubernetesClient.Tests/WebSocketTestBase.cs Replaced static port counter with OS-assigned port allocation, added logic to retrieve actual port from server features, and made property setters explicit
tests/KubernetesClient.Tests/PodExecTests.cs Removed redundant Host.StartAsync() call now that host is started in base class constructor

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}

ServerBaseAddress = new Uri(serverAddress);
WebSocketBaseAddress = new Uri(serverAddress.Replace("http://", "ws://"));
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

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

The string replacement approach serverAddress.Replace("http://", "ws://") could be fragile. Consider using UriBuilder for a more robust conversion:

var uriBuilder = new UriBuilder(serverAddress)
{
    Scheme = "ws"
};
WebSocketBaseAddress = uriBuilder.Uri;

This handles edge cases better (e.g., https/wss, preserving all URI components).

Suggested change
WebSocketBaseAddress = new Uri(serverAddress.Replace("http://", "ws://"));
var uriBuilder = new UriBuilder(serverAddress)
{
Scheme = "ws"
};
WebSocketBaseAddress = uriBuilder.Uri;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants