Skip to content

WebApplicationFactory has content root issue when running tests on WSL2 #55867

Open
@markm77

Description

@markm77

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, Span1)
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) WebApplicationFactory1.ConfigureHostBuilder(IHostBuilder hostBuilder)
WebApplicationFactory1.EnsureServer() WebApplicationFactory1.CreateDefaultClient(DelegatingHandler[] handlers)
WebApplicationFactory1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers) WebApplicationFactory1.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 ---

Metadata

Metadata

Assignees

Labels

area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesfeature-mvc-testingMVC testing package

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions