diff --git a/tests/Microsoft.DotNet.Docker.Tests/TestAppArtifacts/Dockerfile.blazorwasm.linux b/tests/Microsoft.DotNet.Docker.Tests/TestAppArtifacts/Dockerfile.blazorwasm.linux new file mode 100644 index 0000000000..c9792aedd2 --- /dev/null +++ b/tests/Microsoft.DotNet.Docker.Tests/TestAppArtifacts/Dockerfile.blazorwasm.linux @@ -0,0 +1,43 @@ +ARG sdk_image +ARG use_wasm_tools + + +FROM $sdk_image AS pre_build_wasm_tools_false +ARG port +EXPOSE $port +WORKDIR /source +COPY NuGet.config . + + +FROM pre_build_wasm_tools_false AS pre_build_wasm_tools_true +WORKDIR /source +COPY NuGet.config . +RUN dotnet workload install --configfile NuGet.config --skip-manifest-update wasm-tools \ + && . /etc/os-release \ + && case $ID in \ + alpine) apk add --no-cache python3 ;; \ + debian | ubuntu) apt-get update \ + && apt-get install -y --no-install-recommends python3 \ + && rm -rf /var/lib/apt/lists/* ;; \ + mariner | azurelinux) tdnf install -y python3 \ + && tdnf clean all ;; \ + esac + + +FROM pre_build_wasm_tools_${use_wasm_tools} AS build +WORKDIR /source/app +COPY app/*.csproj . +RUN dotnet restore +COPY app/ . +RUN dotnet build --no-restore + + +FROM build AS publish_wasmtools_true +RUN dotnet publish -r browser-wasm -c Release --self-contained true -o out + + +FROM build AS publish_wasmtools_false +RUN dotnet publish --no-restore -c Release -o out + + +FROM publish_wasmtools_${use_wasm_tools} AS final diff --git a/tests/Microsoft.DotNet.Docker.Tests/TestAppArtifacts/Dockerfile.linux b/tests/Microsoft.DotNet.Docker.Tests/TestAppArtifacts/Dockerfile.linux index 9cc27609a1..aecba349c6 100644 --- a/tests/Microsoft.DotNet.Docker.Tests/TestAppArtifacts/Dockerfile.linux +++ b/tests/Microsoft.DotNet.Docker.Tests/TestAppArtifacts/Dockerfile.linux @@ -4,11 +4,9 @@ ARG runtime_deps_image FROM $sdk_image AS build - ARG rid ARG NuGetFeedPassword ARG port - EXPOSE $port WORKDIR /source @@ -16,57 +14,16 @@ COPY NuGet.config . WORKDIR /source/app COPY app/*.csproj . RUN dotnet restore -r $rid - COPY app/ . RUN dotnet build --no-restore -FROM $sdk_image AS blazorwasm_build - -ARG rid -ARG NuGetFeedPassword -ARG port - -EXPOSE $port - -WORKDIR /source -COPY NuGet.config . - -RUN dotnet workload install --configfile NuGet.config --skip-manifest-update wasm-tools \ - && . /etc/os-release \ - && case $ID in \ - alpine) apk add --no-cache python3 ;; \ - debian | ubuntu) apt-get update \ - && apt-get install -y --no-install-recommends python3 \ - && rm -rf /var/lib/apt/lists/* ;; \ - mariner | azurelinux) tdnf install -y python3 \ - && tdnf clean all ;; \ - esac - -WORKDIR /source/app -COPY app/*.csproj . -RUN dotnet restore -r $rid - -COPY app/ . -RUN dotnet build --no-restore - - -FROM blazorwasm_build AS blazorwasm_publish - -ARG rid -RUN dotnet publish -r $rid -c Release --self-contained true -o out - - FROM build AS test - ARG rid ARG NuGetFeedPassword - WORKDIR /source/tests - COPY tests/*.csproj . RUN dotnet restore -r $rid - COPY tests/ . ENTRYPOINT ["dotnet", "test", "--logger:trx", "--no-restore"] @@ -76,9 +33,7 @@ RUN dotnet publish --no-restore -c Release -o out FROM $runtime_image AS fx_dependent_app - ARG port - EXPOSE $port WORKDIR /app COPY --from=publish_fx_dependent /source/app/out ./ @@ -91,9 +46,7 @@ RUN dotnet publish -r $rid -c Release --self-contained true -o out FROM $runtime_deps_image AS self_contained_app - ARG port - EXPOSE $port WORKDIR /app COPY --from=publish_self_contained /source/app/out ./ @@ -101,12 +54,10 @@ ENTRYPOINT ["./app"] FROM build AS publish_aot - RUN dotnet publish -r $rid --no-restore -o /app FROM $runtime_deps_image AS aot_app - WORKDIR /app COPY --from=publish_aot /app . USER $APP_UID diff --git a/tests/Microsoft.DotNet.Docker.Tests/TestScenarios/BlazorWasmScenario.cs b/tests/Microsoft.DotNet.Docker.Tests/TestScenarios/BlazorWasmScenario.cs index 8ebf7b9c56..0d02ffcfd3 100644 --- a/tests/Microsoft.DotNet.Docker.Tests/TestScenarios/BlazorWasmScenario.cs +++ b/tests/Microsoft.DotNet.Docker.Tests/TestScenarios/BlazorWasmScenario.cs @@ -4,16 +4,23 @@ namespace Microsoft.DotNet.Docker.Tests; -public class BlazorWasmScenario(ProductImageData imageData, DockerHelper dockerHelper, ITestOutputHelper outputHelper, bool useWasmTools) +public class BlazorWasmScenario( + ProductImageData imageData, + DockerHelper dockerHelper, + ITestOutputHelper outputHelper, + bool useWasmTools) : WebScenario(imageData, dockerHelper, outputHelper) { + protected override string Dockerfile { get; } = $"Dockerfile.blazorwasm.{OSDockerfileSuffix}"; protected override string SampleName { get; } = "blazorwasm"; // Currently, only some platforms support the wasm-tools workload. // In the case that wasm-tools isn't supported, even though blazorwasm's publish output isn't framework dependent, // running the standard publish in the fx_dependent target gives us the correct static site output. - protected override string BuildStageTarget { get; } = useWasmTools ? "blazorwasm_publish" : "publish_fx_dependent"; + protected override string BuildStageTarget { get; } = "final"; protected override string? TestStageTarget { get; } = null; + protected override string[] CustomDockerBuildArgs { get; } = + [ $"use_wasm_tools={useWasmTools.ToString().ToLowerInvariant()}" ]; // Known issue: Blazor ignores the ASPNETCORE_HTTP_PORTS environment variable that we set in runtime-deps. // We need to manually override it with ASPNETCORE_URLS. diff --git a/tests/Microsoft.DotNet.Docker.Tests/TestScenarios/ProjectTemplateTestScenario.cs b/tests/Microsoft.DotNet.Docker.Tests/TestScenarios/ProjectTemplateTestScenario.cs index f75f47455a..a487310cce 100644 --- a/tests/Microsoft.DotNet.Docker.Tests/TestScenarios/ProjectTemplateTestScenario.cs +++ b/tests/Microsoft.DotNet.Docker.Tests/TestScenarios/ProjectTemplateTestScenario.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Threading.Tasks; using Xunit.Abstractions; @@ -15,31 +16,25 @@ public abstract class ProjectTemplateTestScenario : TestScenario, IDisposable { private bool _disposed; + protected static string OSDockerfileSuffix { get; } = DockerHelper.IsLinuxContainerModeEnabled ? "linux" : "windows"; protected static string? AdminUser { get; } = DockerHelper.IsLinuxContainerModeEnabled ? "root" : null; - protected static string? NonRootUser { get; } = DockerHelper.IsLinuxContainerModeEnabled ? "app" : "ContainerUser"; protected DockerHelper DockerHelper { get; } - protected ProductImageData ImageData { get; } - protected ITestOutputHelper OutputHelper { get; } - protected TestSolution TestSolution { get; } - protected bool NonRootUserSupported { get; init; } + protected bool NonRootUserSupported { get; } - protected abstract string SampleName { get; } + protected virtual string Dockerfile { get; } = $"Dockerfile.{OSDockerfileSuffix}"; + protected virtual string[] CustomDockerBuildArgs { get; } = []; - // Target stages refer to stages in TestAppArtifacts/Dockerfile.linux + protected abstract string SampleName { get; } protected abstract string BuildStageTarget { get; } - protected abstract string? TestStageTarget { get; } - protected abstract string[] AppStageTargets { get; } - protected abstract DotNetImageRepo RuntimeImageRepo { get; } - protected abstract DotNetImageRepo SdkImageRepo { get; } public ProjectTemplateTestScenario( @@ -101,6 +96,7 @@ protected string Build(string stageTarget, string[]? customBuildArgs) { DockerHelper.Build( tag: tag, + dockerfile: Path.Combine(DockerHelper.TestArtifactsDir, Dockerfile), target: stageTarget, contextDir: TestSolution.SolutionDir, platform: ImageData.Platform, @@ -128,7 +124,7 @@ protected override async Task ExecuteInternalAsync() // publish command with a different RID than the default would end up restoring images. This is not // what we'd want and plus it would fail in that case if it was targeting a private NuGet feed because // the password isn't necessarily provided in that stage. - string[] customBuildArgs = [ $"rid={ImageData.Rid}" ]; + string[] customBuildArgs = [ ..CustomDockerBuildArgs, $"rid={ImageData.Rid}" ]; // Build and run app on SDK image string buildTag = Build(BuildStageTarget, customBuildArgs);