Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port argument seems to be broken #10403

Closed
jonash871j opened this issue Oct 24, 2024 · 4 comments
Closed

Port argument seems to be broken #10403

jonash871j opened this issue Oct 24, 2024 · 4 comments

Comments

@jonash871j
Copy link

jonash871j commented Oct 24, 2024

I'm trying to run some unit tests in a docker container using dotnet vstest. The catch is that I'm doing it with host networking enabled which gives the container direct access to the host machine.

When I start the tests in the container with dotnet vstest Settings.Tests/bin/Release/net8.0/Settings.Tests.dll --Diag:log.txt, it fails and produces this output:

2024-10-24 12:32:21 VSTest version 17.11.1-release-24455-02 (x64)
2024-10-24 12:32:21 
2024-10-24 12:32:21 Starting test execution, please wait...
2024-10-24 12:32:21 Logging Vstest Diagnostics in file: /src/log.txt
2024-10-24 12:32:21 A total of 1 test files matched the specified pattern.
2024-10-24 12:33:51 
2024-10-24 12:33:51 vstest.console process failed to connect to testhost process after 90 seconds. This may occur due to machine slowness, please set environment variable VSTEST_CONNECTION_TIMEOUT to increase timeout.
2024-10-24 12:33:51 Test Run Aborted.

By taking a closer look in the log file, vstest seems to be starting a socket server on a randomly selected port and the client afterwards fails to connect to it.

Server logs:

TpTrace Verbose: 0 : 24, 5, 2024/10/24, 11:42:54.908, 18472446817718, vstest.console.dll, ParallelProxyExecutionManager.StartTestRunOnConcurrentManager: Initializing test run. Started clients: 0
TpTrace Verbose: 0 : 24, 5, 2024/10/24, 11:42:54.908, 18472446980825, vstest.console.dll, ProxyExecutionManager: Test host is always Lazy initialize.
TpTrace Verbose: 0 : 24, 5, 2024/10/24, 11:42:54.908, 18472447370742, vstest.console.dll, TestRequestSender.InitializeCommunication: initialize communication. 
TpTrace Verbose: 0 : 24, 1, 2024/10/24, 11:42:54.909, 18472447686656, vstest.console.dll, TestRunRequest.WaitForCompletion: Waiting with timeout -1.
TpTrace Information: 0 : 24, 5, 2024/10/24, 11:42:54.930, 18472469049297, vstest.console.dll, SocketServer.Start: Listening on endpoint : 127.0.0.1:44411

Client logs:

TpTrace Information: 0 : 37, 1, 2024/10/24, 11:42:55.162, 18472701433080, testhost.dll, DefaultEngineInvoker.Invoke: Start Request Processing.
TpTrace Information: 0 : 37, 11, 2024/10/24, 11:42:55.168, 18472706815112, testhost.dll, SocketClient.OnServerConnected: connected to server endpoint: 127.0.0.1:044411
TpTrace Information: 0 : 37, 12, 2024/10/24, 11:42:55.170, 18472709278718, testhost.dll, DefaultEngineInvoker.StartProcessingAsync: Connected to vstest.console, Starting process requests.
TpTrace Error: 0 : 37, 11, 2024/10/24, 11:42:55.184, 18472723009710, testhost.dll, MulticastDelegateUtilities.SafeInvoke: 1: Invoking callback 1/Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler for .SocketClient: Server Failed to Connect, failed after 0 ms with: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.AggregateException: One or more errors occurred. (Connection refused)
 ---> System.Net.Sockets.SocketException (111): Connection refused

I believe the problem is with network host mode enabled, I'll need to specify which port the server is being hosted on in the docker-compose file, before the client would be able to connect to it. So it's a bit of a problem that the port is randomly selected.

I noticed in the documentation that there is a 'Port' argument that can be parsed to vstest to use a custom port, so something like this dotnet vstest Settings.Tests/bin/Release/net8.0/Settings.Tests.dll --Port:5126 --Diag:log.txt. But I haven't been able to get this argument to work both in the docker container, but also locally when I try it out in any random test project.

From looking in the logs it seems to have picked the correct specified port, but it's unable to start hosting the vstest server. I have tried to use different ports and tried to disable to firewall, but I still get the same error.

TpTrace Information: 0 : 24, 1, 2024/10/24, 12:03:15.051, 19692643140376, vstest.console.dll, Trying to connect to server on port : 5126
TpTrace Information: 0 : 24, 1, 2024/10/24, 12:03:15.056, 19692648272397, vstest.console.dll, Trying to connect to server on socket : 127.0.0.1:5126 
TpTrace Verbose: 0 : 24, 1, 2024/10/24, 12:03:15.059, 19692651571638, vstest.console.dll, SocketCommunicationManager : SetupClientAsync : Attempting to connect to the server.
TpTrace Error: 0 : 24, 5, 2024/10/24, 12:03:15.079, 19692671730906, vstest.console.dll, Connection Failed with error System.Net.Sockets.SocketException (111): Connection refused
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
@nohwnd
Copy link
Member

nohwnd commented Oct 24, 2024

Hello, which testing framework are you using? This would be ideal case for our new testing.platform. It compiles test projects as executables, so you can very easily put them into docker container. It is supported by MSTest (stable), Xunit (preview), NUnit (preview) and TUnit (stable).

This is how you can dockerize MSTest using the no-docker-file approach:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <LangVersion>latest</LangVersion>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <EnableMSTestRunner>true</EnableMSTestRunner>
    <OutputType>Exe</OutputType>

    <!-- 
      docs: https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container 
      dotnet publish /t:PublishContainer -tl:false
      docker run helloworldtests
    -->
    <IsPublishable>true</IsPublishable>
    <EnableSdkContainerSupport>true</EnableSdkContainerSupport>
  
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="MSTest" Version="3.6.1" />

    <PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" Version="17.12.6" />
    <PackageReference Include="Microsoft.Testing.Extensions.TrxReport" Version="1.4.0" />

    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
  </ItemGroup>

  <ItemGroup>
    <Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
  </ItemGroup>

 
    <ItemGroup>
      <!-- Fix for TestingPlatform, before we release 1.5. -->
      <ContainerEnvironmentVariable Include="platformOptions__resultDirectory" Value="/tmp/TestResults"></ContainerEnvironmentVariable>
    </ItemGroup>

</Project>

The testing platform can still fallback to vstest in dotnet test, and in VS, so you should get great deal of backwards compatibility.

https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-mstest-intro

https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-platform-intro?tabs=dotnetcli

@jonash871j
Copy link
Author

jonash871j commented Oct 24, 2024

Hi, thank you for the quick response, I'm using NUnit. I'll take a look at the new testing platform.

@nohwnd
Copy link
Member

nohwnd commented Oct 24, 2024

This is the above example changed for NUnit

Image

<!-- file HelloWorldTests.csproj -->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <LangVersion>latest</LangVersion>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <IsPackable>false</IsPackable>

    <!-- Enable Testing.Platform based runner -->
    <EnableNUnitRunner>true</EnableNUnitRunner>
    <OutputType>exe</OutputType>

    <!--
      docs: https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container
      dotnet publish /t:PublishContainer -tl:false
      docker run helloworldtests
    -->
    <IsPublishable>true</IsPublishable>
    <EnableSdkContainerSupport>true</EnableSdkContainerSupport>

  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="coverlet.collector" Version="6.0.2" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
    <PackageReference Include="NUnit" Version="4.2.2" />
    <PackageReference Include="NUnit.Analyzers" Version="4.3.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="5.0.0-beta.3" />
  </ItemGroup>

  <ItemGroup>
    <Using Include="NUnit.Framework" />
  </ItemGroup>

        <PropertyGroup>
                <!-- fix for latest nunit adapter -->
                <GenerateSelfRegisteredExtensions>true</GenerateSelfRegisteredExtensions>
        </PropertyGroup>

    <ItemGroup>
      <!-- Customize output dir and hide telemetry notification. -->
      <ContainerEnvironmentVariable Include="DOTNET_CLI_TELEMETRY_OPTOUT" Value="1"></ContainerEnvironmentVariable>
      <ContainerEnvironmentVariable Include="platformOptions__resultDirectory" Value="/tmp/TestResults"></ContainerEnvironmentVariable>
    </ItemGroup>

</Project>
// file UnitTest1.cs
namespace NUnit1
{
    public class Tests
    {
        [SetUp]
        public void Setup()
        {
        }

        [Test]
        public void Test1()
        {
            Assert.Pass();
        }
    }
}

02_dockerize.zip

@jonash871j
Copy link
Author

I have done a bit of testing now and this seems to do the trick, thank you for the help 😃

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

No branches or pull requests

2 participants