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

XUnit: Test discovery is taking more than 1 hour #2549

Closed
pawanbrn opened this issue Jul 13, 2022 · 29 comments
Closed

XUnit: Test discovery is taking more than 1 hour #2549

pawanbrn opened this issue Jul 13, 2022 · 29 comments

Comments

@pawanbrn
Copy link

We are using XUnit for API tests and currently we have more than 3k tests but it takes 63 minutes of time to actually discover it and then only its ready to execute.

XUnit: 2.4.1
XUnit.Runner.VisualStudio: 2.4.5
Visual Studio 2019 (Version: 16.11.15)
Visual Studio 2022 (Version: 17.2.3)

I tried in both VS but same results.

========== Test discovery finished: 3515 Tests found in 63 min ==========

@justhoma-zz
Copy link

We are seeing a similar issue with our solution. It's nowhere near as bad but it's still considerable:

XUnit: 2.4.1
XUnit.Runner.VisualStudio: 2.4.5
Visual Studio 2022 (Version: 17.2.6)

========== Starting test discovery ==========
omitted for brevity but the tests are split across 25 different 'test' projects
========== Test discovery finished: 5863 Tests found in 11.6 min ==========

@rainman-306
Copy link

We're experiencing issues as well, discovery takes long time, running tests typically completes under a minute.

xunit: 2.4.1
xunit.runner.visualstudio: 2.4.5
VS 2022: 17.2.6

Computer:
i7 1.3 GHz
32 GB memory
2 TB SSD

========== Starting test discovery ==========
...
========== Test discovery finished: 3545 Tests found in 20.4 min ==========

@bradwilson
Copy link
Member

Is anybody able to reproduce this outside of Visual Studio? Is anybody able to provide a repro project?

@justhoma-zz
Copy link

Not sure how you would reproduce this outside of VS? Any pointers? Is there a way to debug? increase logging level?
I cannot share our source and it only appears to be an issue with large solutions.

@pawanbrn
Copy link
Author

I tried once with Jetbrains rider and seems to be same issue where it takes longer time to discover.
It works fine with new Test project of XUnit when number of tests are less.

And same I can't share repo as belongs to official.

@bradwilson
Copy link
Member

My guess, since you have no repro, is that you are doing something during discovery that is taking a long time. We have a lot of extensibility points here, but the most likely one is that the actual data discovery is what's taking so long.

Try setting preEnumerateTheories to false and see if that resolves it. If it does, then your data discovery is to blame. You could disable that configuration file option and then update all your MemberData attributes to set DisableDiscoveryEnumeration to True, and then use a process of elimination to figure out which tests are to blame. (In v2, there's no way to set DisableDiscoveryEnumeration for ClassData, so if that is the source of your problem, then moving it to MemberData where you can disable discovery is your only alternative to just turning off pre-enumeration entirely.)

@bradwilson
Copy link
Member

Not sure how you would reproduce this outside of VS?

With dotnet test (for .NET Core projects) or xunit.console (for .NET Framework projects).

@justhoma-zz
Copy link

justhoma-zz commented Jul 29, 2022

Setting preEnumerateTheories to false appeared to make no appreciable difference.

Here's the log from within VS in case it helps:

Log level is set to Informational (Default).
Connected to test environment '< Local Windows Environment >'
Test data store opened in 3.491 sec.
========== Starting test discovery ==========
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:35.90]   Discovering: Visa.Ips.Repository.Sql.UnitTests
[xUnit.net 00:00:36.25]   Discovered:  Visa.Ips.Repository.Sql.UnitTests
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:50.36]   Discovering: Visa.Ips.Services.IntegrationTests
[xUnit.net 00:00:54.21]   Discovered:  Visa.Ips.Services.IntegrationTests
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:23.79]   Discovering: Visa.Ips.RulesC.UnitTests
[xUnit.net 00:00:25.57]   Discovered:  Visa.Ips.RulesC.UnitTests
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:20.86]   Discovering: Visa.Ips.RulesDToH.UnitTests
[xUnit.net 00:00:21.38]   Discovered:  Visa.Ips.RulesDToH.UnitTests
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:28.52]   Discovering: Visa.Ips.Controllers.UnitTests
[xUnit.net 00:00:28.98]   Discovered:  Visa.Ips.Controllers.UnitTests
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:26.02]   Discovering: Visa.Ips.ControllersDToH.UnitTests
[xUnit.net 00:00:26.26]   Discovered:  Visa.Ips.ControllersDToH.UnitTests
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:27.16]   Discovering: Visa.Ips.Repository.CentralNotificationProcessing.UnitTests
[xUnit.net 00:00:27.34]   Discovered:  Visa.Ips.Repository.CentralNotificationProcessing.UnitTests
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:29.72]   Discovering: Visa.Ips.Repository.Idempotent.UnitTests
[xUnit.net 00:00:29.91]   Discovered:  Visa.Ips.Repository.Idempotent.UnitTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:24.29]   Discovering: Visa.Ips.Repository.Sql.IntegrationTests
[xUnit.net 00:00:24.52]   Discovered:  Visa.Ips.Repository.Sql.IntegrationTests
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:17.02]   Discovering: Visa.Ips.Offline.IntegrationTests
[xUnit.net 00:00:17.12]   Discovered:  Visa.Ips.Offline.IntegrationTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:19.59]   Discovering: Visa.Ips.Performance.IntegrationTests
[xUnit.net 00:00:19.67]   Discovered:  Visa.Ips.Performance.IntegrationTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:15.79]   Discovering: Visa.Ips.RulesAToB.UnitTests
[xUnit.net 00:00:16.09]   Discovered:  Visa.Ips.RulesAToB.UnitTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:17.74]   Discovering: Visa.Ips.ControllersIToO.UnitTests
[xUnit.net 00:00:17.86]   Discovered:  Visa.Ips.ControllersIToO.UnitTests
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:17.26]   Discovering: Visa.Ips.Repository.Idempotent.IntegrationTests
[xUnit.net 00:00:17.37]   Discovered:  Visa.Ips.Repository.Idempotent.IntegrationTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:15.94]   Discovering: Visa.Ips.UnitTests
[xUnit.net 00:00:16.06]   Discovered:  Visa.Ips.UnitTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:17.85]   Discovering: Visa.Ips.RulesIToO.UnitTests
[xUnit.net 00:00:18.10]   Discovered:  Visa.Ips.RulesIToO.UnitTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:18.55]   Discovering: Visa.Ips.Services.UnitTests
[xUnit.net 00:00:18.81]   Discovered:  Visa.Ips.Services.UnitTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:18.63]   Discovering: Visa.Ips.Services.Common.UnitTests
[xUnit.net 00:00:18.83]   Discovered:  Visa.Ips.Services.Common.UnitTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:22.46]   Discovering: Visa.Ips.ControllersPToZ.UnitTests
[xUnit.net 00:00:22.59]   Discovered:  Visa.Ips.ControllersPToZ.UnitTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:19.16]   Discovering: Visa.Ips.RulesPToZ.UnitTests
[xUnit.net 00:00:19.66]   Discovered:  Visa.Ips.RulesPToZ.UnitTests
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:27.86]   Discovering: Visa.Ips.Controllers.Core.UnitTests
[xUnit.net 00:00:28.10]   Discovered:  Visa.Ips.Controllers.Core.UnitTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:25.38]   Discovering: Visa.Ips.Repository.CentralNotificationProcessing.IntegrationTests
[xUnit.net 00:00:25.63]   Discovered:  Visa.Ips.Repository.CentralNotificationProcessing.IntegrationTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:22.51]   Discovering: Visa.Ips.Offline.UnitTests
[xUnit.net 00:00:22.70]   Discovered:  Visa.Ips.Offline.UnitTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:16.37]   Discovering: Visa.Ips.ControllersAToB.UnitTests
[xUnit.net 00:00:16.51]   Discovered:  Visa.Ips.ControllersAToB.UnitTests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:20.75]   Discovering: Visa.Ips.ControllersC.UnitTests
[xUnit.net 00:00:21.07]   Discovered:  Visa.Ips.ControllersC.UnitTests
========== Test discovery finished: 5863 Tests found in 11.7 min ==========

It's difficult to be sure, because the output is very different when running dotnet test from the command line, however it does not appear to exhibit the same behvaior.

@bradwilson
Copy link
Member

bradwilson commented Jul 31, 2022

How about turning diagnosticMessages and internalDiagnosticMessages both to true, to see if anything shows up there?

@bradwilson
Copy link
Member

It's also strange that VS isn't running any of those discoveries in parallel. Even 16 seconds is a long time for discovery (IMO), but if it were running all the discoveries in parallel, you'd be looking at a minute or less instead of 12 minutes. 😞

@bradwilson
Copy link
Member

Okay, now that I look closer, something is very strange here. They all seem to be long delayed before discovery starts, but discovery itself happens very quickly. Example:

[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:35.90]   Discovering: Visa.Ips.Repository.Sql.UnitTests
[xUnit.net 00:00:36.25]   Discovered:  Visa.Ips.Repository.Sql.UnitTests

Why did VSTest wait 35 seconds before starting discovery? The actual discovery took well under half a second.

@justhoma-zz
Copy link

I created a new solution and added three new Test Projects based on the xUnit Test Project template. I changed the code inside each of the 'UnitTest1' classes to:

[Fact]
public void PassingTest() => Assert.Equal(4, Add(2, 2));

[Fact]
public void FailingTest() => Assert.Equal(5, Add(2, 2));

static int Add(int x, int y) => x + y;

As you can see by the logs below the actual test discovery is negligible, however it still took 22 seconds to complete.

========== Starting test discovery ==========
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.7)
[xUnit.net 00:00:03.35]   Discovering: TestProject1
[xUnit.net 00:00:03.46]   Discovered:  TestProject1
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.7)
[xUnit.net 00:00:03.25]   Discovering: TestProject2
[xUnit.net 00:00:03.34]   Discovered:  TestProject2
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.7)
[xUnit.net 00:00:03.30]   Discovering: TestProject3
[xUnit.net 00:00:03.43]   Discovered:  TestProject3
========== Test discovery finished: 6 Tests found in 22.6 sec ==========

I enabled both diagnosticMessages and internalDiagnosticMessages but I did not see any additional output during test discovery.

@nohwnd
Copy link

nohwnd commented Aug 1, 2022

It's also strange that VS isn't running any of those discoveries in parallel. Even 16 seconds is a long time for discovery (IMO), but if it were running all the discoveries in parallel, you'd be looking at a minute or less instead of 12 minutes. 😞

We started doing that, and it will ship in the next version of VS (17.3).

@nohwnd
Copy link

nohwnd commented Aug 1, 2022

I can't repro this, I am using VS 17.2.6 and 2.4.5 runner, and 2.4.1 framework. Net 6, and the tests shown above:

Log level is set to Informational (Default).
Connected to test environment '< Local Windows Environment >'
========== Starting test discovery ==========
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.5+1caef2f33e (64-bit .NET 6.0.7)
[xUnit.net 00:00:00.31]   Discovering: xunit-discovery-delay
[xUnit.net 00:00:00.34]   Discovered:  xunit-discovery-delay
========== Test discovery finished: 2 Tests found in 850.3 ms ==========

For your repro you could enable VSTest (TestPlatform) diagnostic logs in the test menu, and then grab the logs from your %TEMP%\TestPlatformLogs:

image

@justhoma-zz
Copy link

Log file attached:

logs.txt

@nohwnd
Copy link

nohwnd commented Aug 1, 2022

@justhoma is that all that was there? Only a single file? The info there is not complete, it only shows the execution up until extensions are loaded, which is happening before discovery even starts.

@justhoma-zz
Copy link

It was the only file which is odd.
Anyway, I closed the solution, deleted the contents of the %temp%\TestPlatformLogs and the .vs directory and reopened the solution and that produced 4 files:
logs.host.22-08-01_06-54-09_82793_9.txt
logs.host.22-08-01_06-54-17_17006_12.txt
logs.txt
logs.host.22-08-01_06-53-54_17137_7.txt

@nohwnd
Copy link

nohwnd commented Aug 1, 2022

This is the relevant part of the log, there is 5s gap when xunit does something. I don't think this is vstest fault, we try to log everything that is happening, and console just waits for testhost to send some events, and testhost does nothing:

Testhost: 
TpTrace Verbose: 0 : 38344, 4, 2022/08/01, 06:54:03.210, 4482552861390, testhost.dll, DiscovererEnumerator.DiscoverTestsFromSingleDiscoverer: Loading tests for Xunit.Runner.VisualStudio.VsTestRunner
TpTrace Information: 0 : 38344, 4, 2022/08/01, 06:54:03.244, 4482553203181, testhost.dll, TestDiscoveryManager.RunMessage: calling TestRunMessage(Informational, [xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.7)) callback.
>>> TpTrace Information: 0 : 38344, 4, 2022/08/01, 06:54:03.245, 4482553216272, testhost.dll, [xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.7)
TpTrace Verbose: 0 : 38344, 4, 2022/08/01, 06:54:03.246, 4482553224518, testhost.dll, TestRequestHandler.SendData:  sending data from testhost: {"Version":5,"MessageType":"TestSession.Message","Payload":{"MessageLevel":0,"Message":"[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.7)"}}
TpTrace Verbose: 0 : 38344, 10, 2022/08/01, 06:54:03.742, 4482558184874, testhost.dll, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: [::ffff:127.0.0.1]:61762 localEndPoint: [::ffff:127.0.0.1]:61781
TpTrace Verbose: 0 : 38344, 10, 2022/08/01, 06:54:04.745, 4482568213526, testhost.dll, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: [::ffff:127.0.0.1]:61762 localEndPoint: [::ffff:127.0.0.1]:61781
TpTrace Verbose: 0 : 38344, 10, 2022/08/01, 06:54:05.749, 4482578256948, testhost.dll, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: [::ffff:127.0.0.1]:61762 localEndPoint: [::ffff:127.0.0.1]:61781
TpTrace Verbose: 0 : 38344, 10, 2022/08/01, 06:54:06.756, 4482588329108, testhost.dll, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: [::ffff:127.0.0.1]:61762 localEndPoint: [::ffff:127.0.0.1]:61781
TpTrace Verbose: 0 : 38344, 10, 2022/08/01, 06:54:07.762, 4482598384064, testhost.dll, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: [::ffff:127.0.0.1]:61762 localEndPoint: [::ffff:127.0.0.1]:61781
TpTrace Verbose: 0 : 38344, 10, 2022/08/01, 06:54:08.769, 4482608450983, testhost.dll, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: [::ffff:127.0.0.1]:61762 localEndPoint: [::ffff:127.0.0.1]:61781
5s later >>> TpTrace Information: 0 : 38344, 4, 2022/08/01, 06:54:08.804, 4482608803302, testhost.dll, AssemblyResolver.OnResolve: xunit.runner.reporters.netcoreapp10: Resolving assembly.
TpTrace Information: 0 : 38344, 4, 2022/08/01, 06:54:08.804, 4482608809351, testhost.dll, AssemblyResolver.OnResolve: xunit.runner.reporters.netcoreapp10: Searching in: 'C:\Users\justhoma\source\repos\TestProject1\TestProject1\bin\Debug\net6.0'.
TpTrace Information: 0 : 38344, 4, 2022/08/01, 06:54:08.812, 4482608881051, testhost.dll, AssemblyResolver.OnResolve: xunit.runner.reporters.netcoreapp10: Loading assembly 'C:\Users\justhoma\source\repos\TestProject1\TestProject1\bin\Debug\net6.0\xunit.runner.reporters.netcoreapp10.dll'.
TpTrace Information: 0 : 38344, 4, 2022/08/01, 06:54:08.841, 4482609173012, testhost.dll, AssemblyResolver.OnResolve: Resolved assembly: xunit.runner.reporters.netcoreapp10, from path: C:\Users\justhoma\source\repos\TestProject1\TestProject1\bin\Debug\net6.0\xunit.runner.reporters.netcoreapp10.dll
TpTrace Information: 0 : 38344, 4, 2022/08/01, 06:54:08.992, 4482610689406, testhost.dll, TestDiscoveryManager.RunMessage: calling TestRunMessage(Informational, [xUnit.net 00:00:05.77]   Discovering: TestProject1) callback.
vstest.console: 
TpTrace Information: 0 : 49428, 12, 2022/08/01, 06:54:03.250, 4482553271459, vstest.console.exe, DiscoveryRequest.SendDiscoveryMessage: Completed.
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:03.251, 4482553275556, vstest.console.exe, MulticastDelegateUtilities.SafeInvoke: LengthPrefixCommunicationChannel: MessageReceived: Invoking callback 1/1 for Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestSender+<>c__DisplayClass27_0., took 3 ms.
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:03.251, 4482553279564, vstest.console.exe, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: 127.0.0.1:61781 localEndPoint: 127.0.0.1:61762
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:04.255, 4482563313488, vstest.console.exe, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: 127.0.0.1:61781 localEndPoint: 127.0.0.1:61762
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:05.261, 4482573378347, vstest.console.exe, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: 127.0.0.1:61781 localEndPoint: 127.0.0.1:61762
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:06.266, 4482583426377, vstest.console.exe, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: 127.0.0.1:61781 localEndPoint: 127.0.0.1:61762
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:07.274, 4482593505483, vstest.console.exe, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: 127.0.0.1:61781 localEndPoint: 127.0.0.1:61762
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:08.279, 4482603560317, vstest.console.exe, TcpClientExtensions.MessageLoopAsync: Polling on remoteEndPoint: 127.0.0.1:61781 localEndPoint: 127.0.0.1:61762
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:08.994, 4482610711094, vstest.console.exe, TcpClientExtensions.MessageLoopAsync: NotifyDataAvailable remoteEndPoint: 127.0.0.1:61781 localEndPoint: 127.0.0.1:61762
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:08.994, 4482610716950, vstest.console.exe, TestRequestSender.OnDiscoveryMessageReceived: Received message: {"Version":5,"MessageType":"TestSession.Message","Payload":{"MessageLevel":0,"Message":"[xUnit.net 00:00:05.77]   Discovering: TestProject1"}}
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:08.995, 4482610725339, vstest.console.exe, MulticastDelegateUtilities.SafeInvoke: DiscoveryRequest.RawMessageReceived: Invoking callback 1/1 for Microsoft.VisualStudio.TestPlatform.Client.DesignMode.DesignModeTestEventsRegistrar., took 0 ms.
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:08.996, 4482610730645, vstest.console.exe, DiscoveryRequest.SendDiscoveryMessage: Starting.
TpTrace Verbose: 0 : 49428, 12, 2022/08/01, 06:54:08.996, 4482610735038, vstest.console.exe, MulticastDelegateUtilities.SafeInvoke: DiscoveryRequest.OnTestMessageRecieved: Invoking callbacks was skipped because there are no subscribers.

I guess the best way to diagnose this would be to start perfview, record the execution, and look at flame graph in the related time slice:

Start perfView, select Collect > Collect, add additional event source to capture test platform events *TestPlatform so we can identify just the correct time slice. Then press Start Collection in perfView.

image

(You can also unclick Merge and Zip to save time).

In VS you can do Clean, then Re-build to force test re-discovery.

Then you can stop the collection, and it will open the etl file for you. You double click Events, type testPlat on the top, and then use Ctrl to select the adapter discovery start and stop events:

image

You will probably see more of them, choose a pair of them, and open CPU stacks, select the testhost process for your chosen pair of events, and double click it:

image

Then copy paste the timestamps of the events to start and end so you see only the relevant time slice, and press enter:

image

You can then switch to flame graph. Select "Group class entries" and Fold% 1, and you should see something like this:

image

There you can do File > Save View as > and select Speedscope json format and maybe post that resulting file, and also screen shot of that flamegraph.

@bradwilson
Copy link
Member

I enabled both diagnosticMessages and internalDiagnosticMessages but I did not see any additional output during test discovery.

I'm not 100% sure your configuration file is correct, because enabling diagnosticMessages should have at least changed the output like this (example):

Discovering: test.xunit.assert (app domain = off, method display = ClassAndMethod, method display options = None)
Discovered:  test.xunit.assert (found 577 test cases)

Since we don't see any additional output here, that also makes me suspect that your preEnuemrateTheories change didn't take effect, either.

@bradwilson
Copy link
Member

This is the relevant part of the log, there is 5s gap when xunit does something

I realize now digging into the source for the VSTest adapter, we print the banner at a different time than I expected. Oops. 😁 So you're right, it's definitely all in our code.

Before you see the "Discovering" banner, we are basically setting up the app domain and loading the assemblies. Here's the banner printing and the parsing of the RunSettings XML (neither should take any time): https://github.com/xunit/visualstudio.xunit/blob/main/src/xunit.runner.visualstudio/VsTestRunner.cs#L86-L109

And then here's the discovery: https://github.com/xunit/visualstudio.xunit/blob/b0b4704a7c4e1bd901cd50f40e7fd4ea36f0deb2/src/xunit.runner.visualstudio/VsTestRunner.cs#L218-L334

We can see the "Test discovery started" message being sent on line 299. So tracing through this, as near as I can tell, it's all about assembly loading. Why does a test assembly and its dependencies take 15 to 60 seconds to load? That I'm not sure about. I'm hoping the internal diagnostic messages (which should include a list of all assembly resolution) might give a direction to look.

@justhoma-zz
Copy link

Here's what I see when I add the xunit.runner.json file with diagnosticMessages and internalDiagnosticMessages set to true to the test solution I referred to above:

{
  "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
  "diagnosticMessages": true,
  "internalDiagnosticMessages": true
}
========== Starting test discovery ==========
[xUnit.net 00:00:00.02] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.7)
[xUnit.net 00:00:07.62]   Discovering: TestProject3 (method display = ClassAndMethod, method display options = None)
[xUnit.net 00:00:07.79] TestProject3: Discovered test case 'TestProject3.UnitTest1.PassingTest' (ID = '56ab3fb72d3fb96df28b5dbb2d059fb0f87e35f6', VS FQN = 'TestProject3.UnitTest1.PassingTest')
[xUnit.net 00:00:07.96] TestProject3: Discovered test case 'TestProject3.UnitTest1.FailingTest' (ID = '986d3a5813c71d77db79bfd7b54515c4b8323c48', VS FQN = 'TestProject3.UnitTest1.FailingTest')
[xUnit.net 00:00:07.96]   Discovered:  TestProject3 (found 2 test cases)
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.7)
[xUnit.net 00:00:05.13]   Discovering: TestProject2 (method display = ClassAndMethod, method display options = None)
[xUnit.net 00:00:05.22] TestProject2: Discovered test case 'TestProject2.UnitTest1.PassingTest' (ID = '9f13873e7dfd8be94f695895e7a3c555604d0a83', VS FQN = 'TestProject2.UnitTest1.PassingTest')
[xUnit.net 00:00:05.28] TestProject2: Discovered test case 'TestProject2.UnitTest1.FailingTest' (ID = '8083b2ca6c5f36acb720515eee3715d756915e60', VS FQN = 'TestProject2.UnitTest1.FailingTest')
[xUnit.net 00:00:05.28]   Discovered:  TestProject2 (found 2 test cases)
[xUnit.net 00:00:00.01] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.7)
[xUnit.net 00:00:03.60]   Discovering: TestProject1 (method display = ClassAndMethod, method display options = None)
[xUnit.net 00:00:03.67] TestProject1: Discovered test case 'TestProject1.UnitTest1.PassingTest' (ID = '9413f9b8c14a3c7ed434204ae984982d508f1176', VS FQN = 'TestProject1.UnitTest1.PassingTest')
[xUnit.net 00:00:03.71] TestProject1: Discovered test case 'TestProject1.UnitTest1.FailingTest' (ID = 'f3adb2e49021bac643eb5960a70701505de2d9f2', VS FQN = 'TestProject1.UnitTest1.FailingTest')
[xUnit.net 00:00:03.72]   Discovered:  TestProject1 (found 2 test cases)
========== Test discovery finished: 6 Tests found in 47 sec ==========

Is this enough or would you like me to try the other solution?

@justhoma-zz
Copy link

@justhoma-zz
Copy link

@nohwnd When is VS (17.3) expected to be released? This is becoming a fairly big issue and appears to be impacting pretty much all our dotnet solutions.

@bradwilson
Copy link
Member

Is this issue related? Slow performance on discovery / running due to discovering TestReporters

Seems like a pretty likely explanation.

@justhoma-zz
Copy link

Any plans to do anything?

@bradwilson
Copy link
Member

It sounds like we're waiting on a fix from Visual Studio.

@kiwidev
Copy link

kiwidev commented Aug 9, 2022

Note in the issue mentioned above (if I get time I'll work up a PR), the fix shouldn't require Visual Studio - its inside the visualstudio.xunit project.
I notice that the main xunit runner does the same thing at https://github.com/xunit/xunit/blob/main/src/xunit.v3.runner.msbuild/xunit.cs#L405

Ideally there would be some sort of filtering applied (such as *.reporters.*.dll which matches the default xunit dll), but this wouldn't be backwards compatible without adding a flag (to the commandline or the xunit config etc).

In my testing, this was definitely causing a delay prior to the discovery starting that matches the descriptions above.

I don't know what percentage of users would usually use custom reporters but I would expect it to be on the lower side.

@nohwnd
Copy link

nohwnd commented Aug 11, 2022

@justhoma I think it released yesterday?

@kiwidev FWIW in vstest we currently use a naming convention e.g. *TestAdapter.dll, and then an assembly level attribute also by convention (we know the shape of it, but the extension author defines it in their extension):

[assembly: TestExtensionTypes(new global::System.Type[]
{
	typeof(MSTestDiscoverer),
	typeof(MSTestExecutor)
})]

When found we inspect only those types for the desired type of extension, rather than inspecting all types.

@bradwilson
Copy link
Member

Closing as a dup of xunit/visualstudio.xunit#317.

robin-aws added a commit to dafny-lang/dafny that referenced this issue Sep 20, 2023
#4568)

Addresses xunit/xunit#2549 to reduce our
integration test shard execution time from > 1 hour to <= 30 mins.

The TL;DR is that xUnit has an extension mechanism that attempts to load
every class in every available DLL to see if it extends a given
interface. This manifests in a huge delay on startup before any tests
begin to run, e.g. 52 mins in this case:
https://github.com/dafny-lang/dafny/actions/runs/6241813664/job/16944685069#step:22:146
(make sure you turn on Show Timestamps!) This was steadily getting worse
as we added more classes, especially
#4438 as it added a bunch of
Dafny-generated code.

Fortunately xUnit 2.5.1 added a knob to switch off this discovery, which
we're definitely not using.

<small>By submitting this pull request, I confirm that my contribution
is made under the terms of the [MIT
license](https://github.com/dafny-lang/dafny/blob/master/LICENSE.txt).</small>
keyboardDrummer pushed a commit to dafny-lang/dafny that referenced this issue Sep 26, 2023
#4568)

Addresses xunit/xunit#2549 to reduce our
integration test shard execution time from > 1 hour to <= 30 mins.

The TL;DR is that xUnit has an extension mechanism that attempts to load
every class in every available DLL to see if it extends a given
interface. This manifests in a huge delay on startup before any tests
begin to run, e.g. 52 mins in this case:
https://github.com/dafny-lang/dafny/actions/runs/6241813664/job/16944685069#step:22:146
(make sure you turn on Show Timestamps!) This was steadily getting worse
as we added more classes, especially
#4438 as it added a bunch of
Dafny-generated code.

Fortunately xUnit 2.5.1 added a knob to switch off this discovery, which
we're definitely not using.

<small>By submitting this pull request, I confirm that my contribution
is made under the terms of the [MIT
license](https://github.com/dafny-lang/dafny/blob/master/LICENSE.txt).</small>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants