Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
I am using WebApplicationFactory to run tests on Windows but am having problems when I try to run the same tests on WSL2 (e.g. using Visual Studio remote testing).
I give a repro below with the exception produced.
In the case of the repro, the problem is due to the argument --contentRoot=C:\Repos\AspNetCore.Docs.Samples\test\integration-tests\8.x\IntegrationTestsSample\src\RazorPagesProject
being passed to WebApplication.CreateBuilder(args)
which is unsuitable for WSL2.
Expected Behavior
I would greatly appreciate if you could provide a fix/workaround that allows running the same WebApplicationFactory tests on both Windows and WSL2. I use Visual Studio remote testing for WSL2 testing. It is important for me to test using WSL2 before releases as I use Linux in production.
Steps To Reproduce
In order to repro this for you, I cloned the official demo project (https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/test/integration-tests/8.x/IntegrationTestsSample) and created a solution in Visual Studio with both the test and SUT projects plus the following testEnvironments.json
(which points to WSL on my machine):
{
"version": "1",
"environments": [
{
"name": "WSL-Ubuntu-22.04",
"type": "wsl",
"wslDistribution": "Ubuntu-22.04"
}
]
}
Running the tests for the official demo project works fine on Windows but as soon as I switch to WSL2, I get the exception shown for all tests.
Exceptions (if any)
Message:
System.IO.DirectoryNotFoundException : /mnt/c/Repos/AspNetCore.Docs.Samples/test/integration-tests/8.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/bin/Debug/net8.0/C:\Repos\AspNetCore.Docs.Samples\test\integration-tests\8.x\IntegrationTestsSample\src\RazorPagesProject/
Stack Trace:
PhysicalFileProvider.ctor(String root, ExclusionFilters filters)
HostBuilder.CreateHostingEnvironment(IConfiguration hostConfiguration)
HostApplicationBuilder.Initialize(HostApplicationBuilderSettings settings, HostBuilderContext& hostBuilderContext, IHostEnvironment& environment, LoggingBuilder& logging, MetricsBuilder& metrics)
HostApplicationBuilder.ctor(HostApplicationBuilderSettings settings)
WebApplicationBuilder.ctor(WebApplicationOptions options, Action1 configureDefaults) WebApplication.CreateBuilder(String[] args) Program.<Main>$(String[] args) line 10 InvokeStub_Program.<Main>$(Object, Span
1)
MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
--- End of stack trace from previous location ---
HostingListener.CreateHost()
<>c__DisplayClass10_0.b__0(String[] args)
DeferredHostBuilder.Build()
WebApplicationFactory1.CreateHost(IHostBuilder builder) DelegatedWebApplicationFactory.CreateHost(IHostBuilder builder) WebApplicationFactory
1.ConfigureHostBuilder(IHostBuilder hostBuilder)
WebApplicationFactory1.EnsureServer() WebApplicationFactory
1.CreateDefaultClient(DelegatingHandler[] handlers)
WebApplicationFactory1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers) WebApplicationFactory
1.CreateClient(WebApplicationFactoryClientOptions options)
WebApplicationFactory`1.CreateClient()
.NET Version
8.0.300
Anything else?
I cannot find a simple workaround for this issue.
If I add the following to CustomWebApplicationFactory
:
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
builder.UseContentRoot("/mnt/c/Repos/AspNetCore.Docs.Samples/test/integration-tests/8.x/IntegrationTestsSample/src/RazorPagesProject");
}
I then get the following exception:
Message:
System.ArgumentException : The path must be absolute. (Parameter 'root')
Stack Trace:
PhysicalFileProvider.ctor(String root, ExclusionFilters filters)
<>c.<UseStaticWebAssetsCore>b__1_0(String contentRoot)
ManifestStaticWebAssetFileProvider.ctor(StaticWebAssetManifest manifest, Func`2 fileProviderFactory)
StaticWebAssetsLoader.UseStaticWebAssetsCore(IWebHostEnvironment environment, Stream manifest)
StaticWebAssetsLoader.UseStaticWebAssets(IWebHostEnvironment environment, IConfiguration configuration)
BootstrapHostBuilder.RunDefaultCallbacks()
WebApplicationBuilder.InitializeHosting(BootstrapHostBuilder bootstrapHostBuilder)
WebApplicationBuilder.ctor(WebApplicationOptions options, Action`1 configureDefaults)
WebApplication.CreateBuilder(String[] args)
Program.<Main>$(String[] args) line 10
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
--- End of stack trace from previous location ---
HostingListener.CreateHost()
<>c__DisplayClass10_0.<ResolveHostFactory>b__0(String[] args)
DeferredHostBuilder.Build()
WebApplicationFactory`1.CreateHost(IHostBuilder builder)
DelegatedWebApplicationFactory.CreateHost(IHostBuilder builder)
WebApplicationFactory`1.ConfigureHostBuilder(IHostBuilder hostBuilder)
WebApplicationFactory`1.EnsureServer()
WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
WebApplicationFactory`1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers)
WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
AuthTests.Get_SecurePageIsReturnedForAnAuthenticatedUser() line 105
--- End of stack trace from previous location ---