[wasm] Don't use workload for tfm < net6.0 (#56606)
authorAnkit Jain <radical@gmail.com>
Sun, 15 Aug 2021 18:10:26 +0000 (14:10 -0400)
committerGitHub <noreply@github.com>
Sun, 15 Aug 2021 18:10:26 +0000 (13:10 -0500)
* Bump sdk used for testing to 6.0.100-rc.1.21402.6

* InstallWorkloadFromArtifacts: Add OnlyUpdateManifests parameter

* [wasm] Run Wasm.Build.Tests with sdk/no-workload/+EMSDK

Currently, Wasm.Build.Tests are run in two modes:

1. sdk(`$(SdkVersionForWorkloadTesting)`)+workload installed
2. sdk(from global.json)+EMSDK+LocalBuild targets

this commit changes (2) to:

2. sdk(`$(SdkVersionForWorkloadTesting)`), no workload installed, +
   EMSDK+LocalBuild targets

This makes it closer to what a user would actually use.

Also, for the workload tests, this removes `$(WasmNativeWorkload)`
always being set to `true`. The workload should be setting that, and not
the tests.

* Wasm.Build.Tests: Add test for net5.0 blazor projects

* Disable unrelated builds for now

* Revert "Disable unrelated builds for now"

This reverts commit 6fa0efe2ffcfdbcfaba3bdf519a7717809c22672.

* Rename OnlyWasmBuildTests -> TestWasmBuildTests

32 files changed:
eng/Versions.props
eng/pipelines/runtime.yml
eng/testing/tests.mobile.targets
src/libraries/Directory.Build.props
src/libraries/Directory.Build.targets
src/libraries/sendtohelixhelp.proj
src/libraries/tests.proj
src/libraries/workloads-testing.targets
src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets.in
src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs
src/tests/BuildWasmApps/Wasm.Build.Tests/BlazorWasmTests.cs
src/tests/BuildWasmApps/Wasm.Build.Tests/BuildEnvironment.cs
src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs
src/tests/BuildWasmApps/Wasm.Build.Tests/CommandResult.cs
src/tests/BuildWasmApps/Wasm.Build.Tests/EnvironmentVariables.cs
src/tests/BuildWasmApps/Wasm.Build.Tests/Wasm.Build.Tests.csproj
src/tests/BuildWasmApps/Wasm.Build.Tests/data/Local.Directory.Build.props
src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.cmd
src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.sh
src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.props
src/tests/BuildWasmApps/testassets/Blazor_net50/App.razor [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/Blazor_net50.csproj [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/Pages/Counter.razor [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/Pages/FetchData.razor [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/Pages/Index.razor [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/Program.cs [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/MainLayout.razor [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/MainLayout.razor.css [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/NavMenu.razor [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/NavMenu.razor.css [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/SurveyPrompt.razor [new file with mode: 0644]
src/tests/BuildWasmApps/testassets/Blazor_net50/_Imports.razor [new file with mode: 0644]

index d63aaeb..53d03a6 100644 (file)
     <SQLitePCLRawbundle_greenVersion>2.0.4</SQLitePCLRawbundle_greenVersion>
     <MoqVersion>4.12.0</MoqVersion>
     <FsCheckVersion>2.14.3</FsCheckVersion>
-    <SdkVersionForWorkloadTesting>6.0.100-rc.1.21370.2</SdkVersionForWorkloadTesting>
+    <SdkVersionForWorkloadTesting>6.0.100-rc.1.21402.6</SdkVersionForWorkloadTesting>
     <!-- Docs -->
     <MicrosoftPrivateIntellisenseVersion>5.0.0-preview-20201009.2</MicrosoftPrivateIntellisenseVersion>
     <!-- ILLink -->
index f21c7e8..0fca635 100644 (file)
@@ -324,7 +324,7 @@ jobs:
     jobParameters:
       testGroup: innerloop
       nameSuffix: AllSubsets_Mono_WasmBuildTests
-      buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:OnlyWasmBuildTests=true /p:TestAssemblies=false
+      buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmBuildTests=true /p:TestAssemblies=false
       timeoutInMinutes: 180
       condition: >-
         or(
index d264a9a..0cb9a22 100644 (file)
@@ -7,10 +7,6 @@
 
     <PublishingTestsRun>true</PublishingTestsRun>
     <BundleTestAppTargets>BundleTestAppleApp;BundleTestAndroidApp</BundleTestAppTargets>
-
-    <!-- this catches the case when we are running tests, but not archiving them.
-         In case of archiving, the workload gets installed by code elsewhere -->
-    <InstallWorkloadForTesting Condition="'$(TestUsingWorkloads)' == 'true' and '$(ArchiveTests)' != 'true'">true</InstallWorkloadForTesting>
   </PropertyGroup>
 
   <PropertyGroup Condition="'$(EnableAggressiveTrimming)' == 'true'">
index 054d426..e81806e 100644 (file)
   </PropertyGroup>
 
   <PropertyGroup Condition="'$(TargetsMobile)' == 'true'">
-    <SdkPathForWorkloadTesting Condition="'$(SdkPathForWorkloadTesting)' == ''">$(ArtifactsBinDir)dotnet-workload\</SdkPathForWorkloadTesting>
-    <SdkPathForWorkloadTesting>$([MSBuild]::NormalizeDirectory($(SdkPathForWorkloadTesting)))</SdkPathForWorkloadTesting>
+    <SdkWithNoWorkloadForTestingPath>$(ArtifactsBinDir)sdk-no-workload\</SdkWithNoWorkloadForTestingPath>
+    <SdkWithNoWorkloadForTestingPath>$([MSBuild]::NormalizeDirectory($(SdkWithNoWorkloadForTestingPath)))</SdkWithNoWorkloadForTestingPath>
 
-    <SdkForWorkloadTestingStampPath>$(SdkPathForWorkloadTesting)version-$(SdkVersionForWorkloadTesting).stamp</SdkForWorkloadTestingStampPath>
+    <SdkWithNoWorkloadStampPath>$(SdkWithNoWorkloadForTestingPath)version-$(SdkVersionForWorkloadTesting).stamp</SdkWithNoWorkloadStampPath>
+    <SdkWithNoWorkload_WorkloadStampPath>$(SdkWithWorkloadForTestingPath)workload.stamp</SdkWithNoWorkload_WorkloadStampPath>
+
+    <SdkWithWorkloadForTestingPath>$(ArtifactsBinDir)dotnet-workload\</SdkWithWorkloadForTestingPath>
+    <SdkWithWorkloadForTestingPath>$([MSBuild]::NormalizeDirectory($(SdkWithWorkloadForTestingPath)))</SdkWithWorkloadForTestingPath>
+
+    <SdkWithWorkloadStampPath>$(SdkWithWorkloadForTestingPath)version-$(SdkVersionForWorkloadTesting).stamp</SdkWithWorkloadStampPath>
+    <SdkWithWorkload_WorkloadStampPath>$(SdkWithWorkloadForTestingPath)workload.stamp</SdkWithWorkload_WorkloadStampPath>
   </PropertyGroup>
 
   <Import Project="$(RepositoryEngineeringDir)testing\tests.props" Condition="'$(EnableTestSupport)' == 'true'" />
index af5bc71..ca9b42f 100644 (file)
@@ -10,8 +10,6 @@
   <PropertyGroup Condition="'$(TestUsingWorkloads)' == 'true'">
     <!-- for non-ci builds, we install the sdk when tests are run -->
     <InstallWorkloadForTesting Condition="'$(ContinuousIntegrationBuild)' == 'true' and '$(ArchiveTests)' == 'true'">true</InstallWorkloadForTesting>
-
-    <WorkloadStampFile>$(SdkPathForWorkloadTesting)workload.stamp</WorkloadStampFile>
   </PropertyGroup>
 
   <!-- resources.targets need to be imported before the Arcade SDK. -->
index e9ddef9..b106d31 100644 (file)
     <TestRunNamePrefix Condition="'$(Scenario)' != ''">$(TestRunNamePrefix)$(Scenario)-</TestRunNamePrefix>
 
     <FailOnTestFailure Condition="'$(WaitForWorkItemCompletion)' != ''">$(WaitForWorkItemCompletion)</FailOnTestFailure>
-    <NeedsToBuildWasmAppsOnHelix Condition="'$(TargetOS)' == 'Browser' and '$(NeedsToBuildWasmAppsOnHelix)' == '' and '$(Scenario)' == 'BuildWasmApps'">true</NeedsToBuildWasmAppsOnHelix>
     <EMSDK_PATH Condition="$([MSBuild]::IsOSPlatform('WINDOWS')) and '$(EMSDK_PATH)' == ''">$(RepoRoot)src\mono\wasm\emsdk\</EMSDK_PATH>
 
-    <NeedsWorkload Condition="'$(TestUsingWorkloads)' == 'true'">true</NeedsWorkload>
-    <NeedsEMSDK Condition="'$(NeedsToBuildWasmAppsOnHelix)' == 'true' and '$(NeedsWorkload)' != 'true'">true</NeedsEMSDK>
+    <NeedsWorkload Condition="'$(Scenario)' == 'BuildWasmApps'">true</NeedsWorkload>
+    <NeedsEMSDK Condition="'$(NeedsToBuildWasmAppsOnHelix)' == 'true' or ('$(Scenario)' == 'BuildWasmApps' and '$(TestUsingWorkloads)' != 'true')">true</NeedsEMSDK>
     <NeedsToRunOnBrowser Condition="'$(TargetOS)' == 'Browser' and ('$(Scenario)' == 'WasmTestOnBrowser' or '$(Scenario)' == 'BuildWasmApps')">true</NeedsToRunOnBrowser>
+
+    <SdkForWorkloadTestingDirName Condition="'$(NeedsWorkload)' == 'true' and '$(TestUsingWorkloads)' == 'true'">dotnet-workload</SdkForWorkloadTestingDirName>
+    <SdkForWorkloadTestingDirName Condition="'$(NeedsWorkload)' == 'true' and '$(TestUsingWorkloads)' != 'true'">sdk-no-workload</SdkForWorkloadTestingDirName>
   </PropertyGroup>
 
   <PropertyGroup Condition="'$(HelixType)' == ''">
     <HelixPreCommand Include="printenv | grep COMPlus" />
   </ItemGroup>
 
-  <ItemGroup Condition="'$(TestUsingWorkloads)' == 'true'">
-    <HelixCommandPrefixItem Condition="'$(WindowsShell)' != 'true'" Include="PATH=$HELIX_CORRELATION_PAYLOAD/dotnet-workload:$PATH" />
-    <HelixCommandPrefixItem Condition="'$(WindowsShell)' == 'true'" Include="PATH=%HELIX_CORRELATION_PAYLOAD%\dotnet-workload%3B%PATH%" />
+  <ItemGroup Condition="'$(NeedsWorkload)' == 'true'">
+    <HelixCommandPrefixItem Condition="'$(WindowsShell)' != 'true'" Include="PATH=$HELIX_CORRELATION_PAYLOAD/$(SdkForWorkloadTestingDirName):$PATH" />
+    <HelixCommandPrefixItem Condition="'$(WindowsShell)' == 'true'" Include="PATH=%HELIX_CORRELATION_PAYLOAD%\$(SdkForWorkloadTestingDirName)%3B%PATH%" />
 
-    <HelixCommandPrefixItem Condition="'$(WindowsShell)' != 'true'" Include="DOTNET_CLI_HOME=$HELIX_CORRELATION_PAYLOAD/dotnet-workload" />
-    <!--<HelixCommandPrefixItem Condition="'$(WindowsShell)' == 'true'" Include="DOTNET_CLI_HOME=%HELIX_CORRELATION_PAYLOAD%\dotnet-workload" />-->
+    <HelixCommandPrefixItem Condition="'$(WindowsShell)' != 'true'" Include="DOTNET_CLI_HOME=$HELIX_CORRELATION_PAYLOAD/$(SdkForWorkloadTestingDirName)" />
+    <!--<HelixCommandPrefixItem Condition="'$(WindowsShell)' == 'true'" Include="DOTNET_CLI_HOME=%HELIX_CORRELATION_PAYLOAD%\$(SdkForWorkloadTestingDirName)" />-->
 
-    <HelixCommandPrefixItem Condition="'$(WindowsShell)' != 'true'" Include="DOTNET_ROOT=$HELIX_CORRELATION_PAYLOAD/dotnet-workload" />
-    <!--<HelixCommandPrefixItem Condition="'$(WindowsShell)' == 'true'" Include="DOTNET_ROOT=%HELIX_CORRELATION_PAYLOAD%\dotnet-workload" />-->
+    <HelixCommandPrefixItem Condition="'$(WindowsShell)' != 'true'" Include="DOTNET_ROOT=$HELIX_CORRELATION_PAYLOAD/$(SdkForWorkloadTestingDirName)" />
+    <!--<HelixCommandPrefixItem Condition="'$(WindowsShell)' == 'true'" Include="DOTNET_ROOT=%HELIX_CORRELATION_PAYLOAD%\$(SdkForWorkloadTestingDirName)" />-->
 
-    <HelixCommandPrefixItem Condition="'$(WindowsShell)' != 'true'" Include="SDK_FOR_WORKLOAD_TESTING_PATH=%24{HELIX_CORRELATION_PAYLOAD}/dotnet-workload" />
-    <HelixCommandPrefixItem Condition="'$(WindowsShell)' == 'true'" Include="SDK_FOR_WORKLOAD_TESTING_PATH=%HELIX_CORRELATION_PAYLOAD%\dotnet-workload" />
+    <HelixCommandPrefixItem Condition="'$(WindowsShell)' != 'true'" Include="SDK_FOR_WORKLOAD_TESTING_PATH=%24{HELIX_CORRELATION_PAYLOAD}/$(SdkForWorkloadTestingDirName)" />
+    <HelixCommandPrefixItem Condition="'$(WindowsShell)' == 'true'" Include="SDK_FOR_WORKLOAD_TESTING_PATH=%HELIX_CORRELATION_PAYLOAD%\$(SdkForWorkloadTestingDirName)" />
 
     <HelixCommandPrefixItem Include="DOTNET_CLI_TELEMETRY_OPTOUT=1" />
-    <HelixCommandPrefixItem Include="TEST_USING_WORKLOADS=true" />
+    <HelixCommandPrefixItem Condition="'$(TestUsingWorkloads)' == 'true'" Include="TEST_USING_WORKLOADS=true" />
   </ItemGroup>
 
   <PropertyGroup Condition="'$(NeedsDotNetSdk)' == 'true'">
       </HelixPostCommands>
     </PropertyGroup>
 
-    <Error Condition="'$(TestUsingWorkloads)' == 'true' and ('$(SdkPathForWorkloadTesting)' == '' or !Exists($(SdkPathForWorkloadTesting)))"
-           Text="Could not find workload at %24(SdkPathForWorkloadTesting)=$(SdkPathForWorkloadTesting)" />
+    <Error Condition="'$(NeedsWorkload)' == 'true' and '$(TestUsingWorkloads)' == 'true' and ('$(SdkWithWorkloadForTestingPath)' == '' or !Exists($(SdkWithWorkloadForTestingPath)))"
+           Text="Could not find workload at %24(SdkWithWorkloadForTestingPath)=$(SdkWithWorkloadForTestingPath)" />
+
+    <Error Condition="'$(NeedsWorkload)' == 'true' and '$(TestUsingWorkloads)' != 'true' and ('$(SdkWithNoWorkloadForTestingPath)' == '' or !Exists($(SdkWithNoWorkloadForTestingPath)))"
+           Text="Could not find workload at %24(SdkWithNoWorkloadForTestingPath)=$(SdkWithNoWorkloadForTestingPath)" />
 
     <ItemGroup Condition="'$(NeedsWorkload)' == 'true'">
-      <HelixCorrelationPayload Include="$(SdkPathForWorkloadTesting)"     Destination="dotnet-workload" />
-      <HelixCorrelationPayload Include="$(MicrosoftNetCoreAppRefPackDir)" Destination="microsoft.netcore.app.ref" />
+      <HelixCorrelationPayload Include="$(SdkWithWorkloadForTestingPath)"     Destination="$(SdkForWorkloadTestingDirName)" Condition="'$(TestUsingWorkloads)' == 'true'" />
+      <HelixCorrelationPayload Include="$(SdkWithNoWorkloadForTestingPath)"   Destination="$(SdkForWorkloadTestingDirName)" Condition="'$(TestUsingWorkloads)' != 'true'" />
+
+      <HelixCorrelationPayload Include="$(MicrosoftNetCoreAppRefPackDir)"     Destination="microsoft.netcore.app.ref" />
     </ItemGroup>
 
     <ItemGroup Condition="'$(NeedsEMSDK)' == 'true'">
index 4505550..5e8f9b5 100644 (file)
                       AdditionalProperties="%(AdditionalProperties);SkipTrimmingProjectsRestore=true" />
     <ProjectReference Include="@(TrimmingTestProjects)" />
 
-    <!-- wasm.build.tests are run on non-aot regular run -->
+    <!-- wasm.build.tests are run on _WasmBuildTests job on CI, and with library tests locally. -->
     <ProjectReference Include="$(RepoRoot)\src\tests\BuildWasmApps\**\*.Tests.csproj"
                       Exclude="@(ProjectExclusions)"
                       Condition="'$(TargetOS)' == 'Browser' and
-                                    (('$(ContinuousIntegrationBuild)' == 'true' and '$(OnlyWasmBuildTests)' == 'true') or
+                                    (('$(ContinuousIntegrationBuild)' == 'true' and '$(TestWasmBuildTests)' == 'true') or
                                      ('$(ContinuousIntegrationBuild)' != 'true' and '$(TestAssemblies)' == 'true'))"
                       BuildInParallel="false" />
   </ItemGroup>
   </ItemGroup>
 
   <!-- Don't build samples, and functional tests on EAT, AOT, and WBT lanes -->
-  <ItemGroup Condition="'$(ArchiveTests)' == 'true' and '$(TargetOS)' == 'Browser' and '$(BuildAOTTestsOnHelix)' != 'true' and '$(OnlyWasmBuildTests)' != 'true'">
+  <ItemGroup Condition="'$(ArchiveTests)' == 'true' and '$(TargetOS)' == 'Browser' and '$(BuildAOTTestsOnHelix)' != 'true' and '$(TestWasmBuildTests)' != 'true'">
     <ProjectReference Include="$(MonoProjectRoot)sample\wasm\**\*.Sample.csproj"
                       Exclude="@(ProjectExclusions)"
                       BuildInParallel="true" />
index d08c595..3e668a3 100644 (file)
@@ -1,12 +1,32 @@
 <Project>
-  <Target Name="ProvisionSdkForWorkloadTesting" Condition="!Exists($(SdkForWorkloadTestingStampPath)) and '$(InstallWorkloadForTesting)' == 'true'">
-    <Error Text="%24(SdkPathForWorkloadTesting) is not set" Condition="'$(SdkPathForWorkloadTesting)' == ''" />
+  <Target Name="ProvisionSdkForWorkloadTesting"
+          DependsOnTargets="_ProvisionSdkWithNoWorkload"
+          Condition="!Exists($(SdkWithNoWorkloadStampPath)) or !Exists($(SdkWithWorkloadStampPath))">
+
+    <Error Text="%24(SdkWithWorkloadForTestingPath) is not set" Condition="'$(SdkWithWorkloadForTestingPath)' == ''" />
+    <Error Text="%24(SdkVersionForWorkloadTesting) is not set" Condition="'$(SdkVersionForWorkloadTesting)' == ''" />
+
+    <Message Text="** Installing sdk $(SdkWithWorkloadForTestingPath) for workload based tests into $(SdkWithWorkloadForTestingPath)" Importance="High" />
+
+    <RemoveDir Directories="$(SdkWithWorkloadForTestingPath)" />
+    <MakeDir Directories="$(SdkWithWorkloadForTestingPath)" />
+
+    <ItemGroup>
+      <_SourceFiles Include="$(SdkWithNoWorkloadForTestingPath)\**" />
+    </ItemGroup>
+
+    <Copy SourceFiles="@(_SourceFiles)" DestinationFolder="$(SdkWithWorkloadForTestingPath)\%(_SourceFiles.RecursiveDir)" />
+    <WriteLinesToFile File="$(SdkWithWorkloadStampPath)" Lines="" Overwrite="true" />
+  </Target>
+
+  <Target Name="_ProvisionSdkWithNoWorkload" Condition="!Exists($(SdkWithNoWorkloadStampPath))">
+    <Error Text="%24(SdkWithNoWorkloadForTestingPath) is not set" Condition="'$(SdkWithNoWorkloadForTestingPath)' == ''" />
     <Error Text="%24(SdkVersionForWorkloadTesting) is not set" Condition="'$(SdkVersionForWorkloadTesting)' == ''" />
 
-    <Message Text="** Installing sdk $(SdkVersionForWorkloadTesting) for workload based tests" Importance="High" />
+    <Message Text="** Installing sdk $(SdkWithNoWorkloadForTestingPath) for workload based tests into $(SdkWithNoWorkloadForTestingPath)" Importance="High" />
 
-    <RemoveDir Directories="$(SdkPathForWorkloadTesting)" />
-    <MakeDir Directories="$(SdkPathForWorkloadTesting)" />
+    <RemoveDir Directories="$(SdkWithNoWorkloadForTestingPath)" />
+    <MakeDir Directories="$(SdkWithNoWorkloadForTestingPath)" />
 
     <PropertyGroup>
       <_DotNetInstallScriptPath Condition="!$([MSBuild]::IsOSPlatform('windows'))">$(DOTNET_INSTALL_DIR)/dotnet-install.sh</_DotNetInstallScriptPath>
     </PropertyGroup>
 
     <Exec Condition="!$([MSBuild]::IsOSPlatform('windows'))"
-          Command="chmod +x $(_DotNetInstallScriptPath); $(_DotNetInstallScriptPath) -i $(SdkPathForWorkloadTesting) -v $(SdkVersionForWorkloadTesting)" />
+          Command="chmod +x $(_DotNetInstallScriptPath); $(_DotNetInstallScriptPath) -i $(SdkWithNoWorkloadForTestingPath) -v $(SdkVersionForWorkloadTesting)" />
 
     <Exec Condition="$([MSBuild]::IsOSPlatform('windows'))"
-          Command='powershell -ExecutionPolicy ByPass -NoProfile -command "&amp; $(_DotNetInstallScriptPath) -InstallDir $(SdkPathForWorkloadTesting) -Version $(SdkVersionForWorkloadTesting)"' />
+          Command='powershell -ExecutionPolicy ByPass -NoProfile -command "&amp; $(_DotNetInstallScriptPath) -InstallDir $(SdkWithNoWorkloadForTestingPath) -Version $(SdkVersionForWorkloadTesting)"' />
 
-    <WriteLinesToFile File="$(SdkForWorkloadTestingStampPath)" Lines="" Overwrite="true" />
+    <WriteLinesToFile File="$(SdkWithNoWorkloadStampPath)" Lines="" Overwrite="true" />
   </Target>
 
   <Target Name="GetWorkloadInputs">
 
   <Target Name="InstallWorkloadUsingArtifacts"
           AfterTargets="ArchiveTests"
-          DependsOnTargets="ProvisionSdkForWorkloadTesting;GetWorkloadInputs"
+          DependsOnTargets="ProvisionSdkForWorkloadTesting;GetWorkloadInputs;_InstallWorkload;_UpdateManifestsForSdkWithNoWorkload"
+          Condition="'$(InstallWorkloadForTesting)' == 'true'" />
+
+  <Target Name="_InstallWorkload"
           Inputs="@(AvailableNuGetsInArtifacts)"
-          Outputs="$(WorkloadStampFile)"
-          Condition="'$(InstallWorkloadForTesting)' == 'true'">
+          Outputs="$(SdkWithWorkload_WorkloadStampPath)">
 
     <ItemGroup>
       <_PropsForAOTCrossBuild Include="TestingWorkloads=true" />
                      VersionBand="$(SdkBandVersion)"
                      LocalNuGetsPath="$(LibrariesShippingPackagesDir)"
                      ExtraNuGetSources="@(_NuGetSourceForWorkloads)"
-                     SdkDir="$(SdkPathForWorkloadTesting)" />
+                     SdkDir="$(SdkWithWorkloadForTestingPath)" />
+    <WriteLinesToFile File="$(SdkWithWorkload_WorkloadStampPath)" Lines="" Overwrite="true" />
+  </Target>
+
+  <Target Name="_UpdateManifestsForSdkWithNoWorkload"
+          Inputs="@(AvailableNuGetsInArtifacts)"
+          Outputs="$(SdkWithNoWorkload_WorkloadStampPath)">
+
+    <InstallWorkloadFromArtifacts
+                     WorkloadId="@(WorkloadIdForTesting)"
+                     VersionBand="$(SdkBandVersion)"
+                     LocalNuGetsPath="$(LibrariesShippingPackagesDir)"
+                     ExtraNuGetSources="@(_NuGetSourceForWorkloads)"
+                     SdkDir="$(SdkWithNoWorkloadForTestingPath)"
+                     OnlyUpdateManifests="true"/>
 
-    <WriteLinesToFile File="$(WorkloadStampFile)" Lines="" Overwrite="true" />
+    <WriteLinesToFile File="$(SdkWithNoWorkload_WorkloadStampPath)" Lines="" Overwrite="true" />
   </Target>
 </Project>
index 276bf50..d9a9dc2 100644 (file)
@@ -1,17 +1,33 @@
-<Project>
+<Project TreatAsLocalProperty="UsingBrowserRuntimeWorkload;WasmNativeWorkload">
     <PropertyGroup>
         <RuntimePackInWorkloadVersion>${PackageVersion}</RuntimePackInWorkloadVersion>
+        <BrowserWorkloadDisabled Condition="'$(BrowserWorkloadDisabled)' == '' and
+                                            '$(RuntimeIdentifier)' == 'browser-wasm' and
+                                            '$(TargetFrameworkIdentifier)' == '.NETCoreApp' and
+                                            !$([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '6.0'))">true</BrowserWorkloadDisabled>
     </PropertyGroup>
+
+    <PropertyGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm' and '$(BrowserWorkloadDisabled)' == 'true'">
+        <_NativeBuildNeeded Condition="'$(RunAOTCompilation)' == 'true'">true</_NativeBuildNeeded>
+        <WorkloadDisabledWithReason Condition="'$(_NativeBuildNeeded)' == 'true'">WebAssembly workloads (required for AOT) are only supported for projects targeting net6.0+</WorkloadDisabledWithReason>
+    </PropertyGroup>
+
     <PropertyGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm' AND '$(UsingBrowserRuntimeWorkload)' == ''">
         <UsingBrowserRuntimeWorkload Condition="'$(RunAOTCompilation)' == 'true' or '$(UsingMicrosoftNETSdkBlazorWebAssembly)' != 'true'" >true</UsingBrowserRuntimeWorkload>
         <UsingBrowserRuntimeWorkload Condition="'$(UsingBrowserRuntimeWorkload)' == ''" >$(WasmNativeWorkload)</UsingBrowserRuntimeWorkload>
     </PropertyGroup>
+
+    <PropertyGroup Condition="'$(BrowserWorkloadDisabled)' == 'true'">
+        <UsingBrowserRuntimeWorkload>false</UsingBrowserRuntimeWorkload>
+        <WasmNativeWorkload>false</WasmNativeWorkload>
+    </PropertyGroup>
+
     <PropertyGroup Condition="'$(UsingMicrosoftNETSdkBlazorWebAssembly)' == 'true' and '$(UsingBrowserRuntimeWorkload)' == 'true'">
       <WasmGenerateAppBundle>false</WasmGenerateAppBundle>
       <UsingBlazorAOTWorkloadManifest>true</UsingBlazorAOTWorkloadManifest>
     </PropertyGroup>
 
-    <Import Condition="'$(RunAOTCompilation)' == 'true'" Project="Sdk.props" Sdk="Microsoft.NET.Runtime.MonoAOTCompiler.Task" />
+    <Import Condition="'$(RunAOTCompilation)' == 'true' and '$(BrowserWorkloadDisabled)' != 'true'" Project="Sdk.props" Sdk="Microsoft.NET.Runtime.MonoAOTCompiler.Task" />
 
     <ImportGroup Condition="'$(TargetPlatformIdentifier)' == 'android'">
         <Import Project="Sdk.props" Sdk="Microsoft.NET.Runtime.MonoTargets.Sdk" />
                         />
     </ItemGroup>
 
+    <Target Name="ErrorDisabledWorkload" Condition="'$(WorkloadDisabledWithReason)' != ''" BeforeTargets="Publish">
+      <Error Text="$(WorkloadDisabledWithReason)" />
+    </Target>
 </Project>
index 4b4a283..295ee92 100644 (file)
@@ -30,6 +30,8 @@ namespace Microsoft.Workload.Build.Tasks
         [Required, NotNull]
         public string?        SdkDir             { get; set; }
 
+        public bool           OnlyUpdateManifests{ get; set; }
+
         public ITaskItem[]    ExtraNuGetSources  { get; set; } = Array.Empty<ITaskItem>();
 
         public override bool Execute()
@@ -52,6 +54,9 @@ namespace Microsoft.Workload.Build.Tasks
             if (!InstallWorkloadManifest(WorkloadId.GetMetadata("ManifestName"), WorkloadId.GetMetadata("Version"), nugetConfigContents, stopOnMissing: true))
                 return false;
 
+            if (OnlyUpdateManifests)
+                return !Log.HasLoggedErrors;
+
             string nugetConfigPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
             File.WriteAllText(nugetConfigPath, nugetConfigContents);
 
index 002ca24..2059142 100644 (file)
@@ -1,6 +1,7 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using System.Collections.Generic;
 using System.IO;
 using Xunit;
 using Xunit.Abstractions;
@@ -55,5 +56,66 @@ namespace Wasm.Build.Tests
             //
             // playwright?
         }
+
+        public static TheoryData<string, bool, bool> Net50TestData = new()
+        {
+            { "Debug", /*aot*/ true, /*expectError*/ true },
+            { "Debug", /*aot*/ false, /*expectError*/ false },
+            { "Release", /*aot*/ true, /*expectError*/ true },
+            { "Release", /*aot*/ false, /*expectError*/ false }
+        };
+
+        [ConditionalTheory(typeof(BuildTestBase), nameof(IsNotUsingWorkloads))]
+        [MemberData(nameof(Net50TestData))]
+        public void Net50ProjectsWithNoPacksInstalled(string config, bool aot, bool expectError)
+            => BuildNet50Project(config, aot, expectError);
+
+        [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))]
+        [MemberData(nameof(Net50TestData))]
+        public void Net50ProjectsWithPacksInstalled(string config, bool aot, bool expectError)
+            => BuildNet50Project(config, aot, expectError);
+
+        private void BuildNet50Project(string config, bool aot, bool errorExpected)
+        {
+            string id = $"Blazor_net50_{config}_{aot}";
+            InitPaths(id);
+            if (Directory.Exists(_projectDir))
+                Directory.Delete(_projectDir, recursive: true);
+            Directory.CreateDirectory(_projectDir);
+            Directory.CreateDirectory(Path.Combine(_projectDir, ".nuget"));
+
+            string directoryBuildTargets = @"<Project>
+                <Target Name=""PrintAllProjects"" BeforeTargets=""Build"">
+                    <Message Text=""** UsingBrowserRuntimeWorkload: '$(UsingBrowserRuntimeWorkload)'"" Importance=""High"" />
+                </Target>
+            </Project>";
+
+            File.Copy(Path.Combine(BuildEnvironment.TestDataPath, "nuget6.config"), Path.Combine(_projectDir, "nuget.config"));
+            File.WriteAllText(Path.Combine(_projectDir, "Directory.Build.props"), "<Project />");
+            File.WriteAllText(Path.Combine(_projectDir, "Directory.Build.targets"), directoryBuildTargets);
+
+            string logPath = Path.Combine(s_buildEnv.LogRootPath, id);
+            Utils.DirectoryCopy(Path.Combine(BuildEnvironment.TestAssetsPath, "Blazor_net50"), Path.Combine(_projectDir!));
+
+            string publishLogPath = Path.Combine(logPath, $"{id}.binlog");
+            CommandResult result = new DotNetCommand(s_buildEnv)
+                                            .WithWorkingDirectory(_projectDir)
+                                            .ExecuteWithCapturedOutput("publish",
+                                                                       $"-bl:{publishLogPath}",
+                                                                       (aot ? "-p:RunAOTCompilation=true" : ""),
+                                                                       $"-p:Configuration={config}");
+
+            if (errorExpected)
+            {
+                result.EnsureExitCode(1);
+                Assert.Contains("** UsingBrowserRuntimeWorkload: 'false'", result.Output);
+                Assert.Contains("error : WebAssembly workloads (required for AOT) are only supported for projects targeting net6.0+", result.Output);
+            }
+            else
+            {
+                result.EnsureSuccessful();
+                Assert.Contains("** UsingBrowserRuntimeWorkload: 'false'", result.Output);
+            }
+        }
     }
 }
index 2212d57..8e9be9e 100644 (file)
@@ -6,6 +6,8 @@ using System.Collections.Generic;
 using System.IO;
 using System.Runtime.InteropServices;
 
+#nullable enable
+
 namespace Wasm.Build.Tests
 {
     public class BuildEnvironment
@@ -40,9 +42,14 @@ namespace Wasm.Build.Tests
             }
 
             string? sdkForWorkloadPath = EnvironmentVariables.SdkForWorkloadTestingPath;
-            if (!string.IsNullOrEmpty(sdkForWorkloadPath))
+            if (string.IsNullOrEmpty(sdkForWorkloadPath))
+                throw new Exception($"Environment variable SDK_FOR_WORKLOAD_TESTING_PATH not set");
+            if (!Directory.Exists(sdkForWorkloadPath))
+                throw new Exception($"Could not find SDK_FOR_WORKLOAD_TESTING_PATH={sdkForWorkloadPath}");
+
+            bool workloadInstalled = EnvironmentVariables.SdkHasWorkloadInstalled != null && EnvironmentVariables.SdkHasWorkloadInstalled == "true";
+            if (workloadInstalled)
             {
-                DotNet = Path.Combine(sdkForWorkloadPath, "dotnet");
                 var workloadPacksVersion = EnvironmentVariables.WorkloadPacksVersion;
                 if (string.IsNullOrEmpty(workloadPacksVersion))
                     throw new Exception($"Cannot test with workloads without WORKLOAD_PACKS_VER environment variable being set");
@@ -50,17 +57,7 @@ namespace Wasm.Build.Tests
                 RuntimePackDir = Path.Combine(sdkForWorkloadPath, "packs", "Microsoft.NETCore.App.Runtime.Mono.browser-wasm", workloadPacksVersion);
                 DirectoryBuildPropsContents = s_directoryBuildPropsForWorkloads;
                 DirectoryBuildTargetsContents = s_directoryBuildTargetsForWorkloads;
-                EnvVars = new Dictionary<string, string>()
-                {
-                    // `runtime` repo's build environment sets these, and they
-                    // mess up the build for the test project, which is using a different
-                    // dotnet
-                    ["DOTNET_INSTALL_DIR"] = sdkForWorkloadPath,
-                    ["DOTNET_MULTILEVEL_LOOKUP"] = "0",
-                    ["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "1",
-                    ["MSBuildSDKsPath"] = string.Empty,
-                    ["PATH"] = $"{sdkForWorkloadPath}{Path.PathSeparator}{Environment.GetEnvironmentVariable("PATH")}"
-                };
+                EnvVars = new Dictionary<string, string>();
 
                 var appRefDir = EnvironmentVariables.AppRefDir;
                 if (string.IsNullOrEmpty(appRefDir))
@@ -95,11 +92,7 @@ namespace Wasm.Build.Tests
                     DefaultBuildArgs = $" /p:RuntimeSrcDir={solutionRoot.FullName} /p:RuntimeConfig={s_runtimeConfig} /p:EMSDK_PATH={emsdkPath} ";
                 }
 
-                // for EMSDK runs, we don't want to get the dependencies from workloads
-                DefaultBuildArgs += " /p:MSBuildEnableWorkloadResolver=false";
-
                 IsWorkload = false;
-                DotNet = "dotnet";
                 EnvVars = new Dictionary<string, string>()
                 {
                     ["EMSDK_PATH"] = emsdkPath
@@ -109,7 +102,17 @@ namespace Wasm.Build.Tests
                 DirectoryBuildTargetsContents = s_directoryBuildTargetsForLocal;
             }
 
+            // `runtime` repo's build environment sets these, and they
+            // mess up the build for the test project, which is using a different
+            // dotnet
+            EnvVars["DOTNET_INSTALL_DIR"] = sdkForWorkloadPath;
+            EnvVars["DOTNET_MULTILEVEL_LOOKUP"] = "0";
+            EnvVars["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "1";
+            EnvVars["MSBuildSDKsPath"] = string.Empty;
+            EnvVars["PATH"] = $"{sdkForWorkloadPath}{Path.PathSeparator}{Environment.GetEnvironmentVariable("PATH")}";
+
             RuntimeNativeDir = Path.Combine(RuntimePackDir, "runtimes", "browser-wasm", "native");
+            DotNet = Path.Combine(sdkForWorkloadPath!, "dotnet");
             if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                 DotNet += ".exe";
 
index 6d08fe8..e5d0b2e 100644 (file)
@@ -43,28 +43,36 @@ namespace Wasm.Build.Tests
 
         static BuildTestBase()
         {
-            s_buildEnv = new BuildEnvironment();
-            s_runtimePackPathRegex = new Regex(s_runtimePackPathPattern);
+            try
+            {
+                s_buildEnv = new BuildEnvironment();
+                s_runtimePackPathRegex = new Regex(s_runtimePackPathPattern);
 
-            s_skipProjectCleanup = !string.IsNullOrEmpty(EnvironmentVariables.SkipProjectCleanup) && EnvironmentVariables.SkipProjectCleanup == "1";
+                s_skipProjectCleanup = !string.IsNullOrEmpty(EnvironmentVariables.SkipProjectCleanup) && EnvironmentVariables.SkipProjectCleanup == "1";
 
-            if (string.IsNullOrEmpty(EnvironmentVariables.XHarnessCliPath))
-                s_xharnessRunnerCommand = "xharness";
-            else
-                s_xharnessRunnerCommand = EnvironmentVariables.XHarnessCliPath;
+                if (string.IsNullOrEmpty(EnvironmentVariables.XHarnessCliPath))
+                    s_xharnessRunnerCommand = "xharness";
+                else
+                    s_xharnessRunnerCommand = EnvironmentVariables.XHarnessCliPath;
 
-            string? nugetPackagesPath = Environment.GetEnvironmentVariable("NUGET_PACKAGES");
-            if (!string.IsNullOrEmpty(nugetPackagesPath))
+                string? nugetPackagesPath = Environment.GetEnvironmentVariable("NUGET_PACKAGES");
+                if (!string.IsNullOrEmpty(nugetPackagesPath))
+                {
+                    if (!Directory.Exists(nugetPackagesPath))
+                        Directory.CreateDirectory(nugetPackagesPath);
+                }
+
+                Console.WriteLine ("");
+                Console.WriteLine ($"==============================================================================================");
+                Console.WriteLine ($"=============== Running with {(s_buildEnv.IsWorkload ? "Workloads" : "EMSDK")} ===============");
+                Console.WriteLine ($"==============================================================================================");
+                Console.WriteLine ("");
+            }
+            catch (Exception ex)
             {
-                if (!Directory.Exists(nugetPackagesPath))
-                    Directory.CreateDirectory(nugetPackagesPath);
+                Console.WriteLine ($"Exception: {ex}");
+                throw;
             }
-
-            Console.WriteLine ("");
-            Console.WriteLine ($"==============================================================================================");
-            Console.WriteLine ($"=============== Running with {(s_buildEnv.IsWorkload ? "Workloads" : "EMSDK")} ===============");
-            Console.WriteLine ($"==============================================================================================");
-            Console.WriteLine ("");
         }
 
         public BuildTestBase(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
index 24228f6..db95f8b 100644 (file)
@@ -25,10 +25,13 @@ namespace Wasm.Build.Tests
         }
 
         public void EnsureSuccessful(string messagePrefix = "", bool suppressOutput = false)
+            => EnsureExitCode(0, messagePrefix, suppressOutput);
+
+        public void EnsureExitCode(int expectedExitCode = 0, string messagePrefix = "", bool suppressOutput = false)
         {
-            if (ExitCode != 0)
+            if (ExitCode != expectedExitCode)
             {
-                StringBuilder message = new StringBuilder($"{messagePrefix} Command failed with exit code {ExitCode}: {StartInfo.FileName} {StartInfo.Arguments}");
+                StringBuilder message = new StringBuilder($"{messagePrefix} Expected {expectedExitCode} exit code but got {ExitCode}: {StartInfo.FileName} {StartInfo.Arguments}");
 
                 if (!suppressOutput)
                 {
index 5ab3ad4..506aafe 100644 (file)
@@ -10,6 +10,7 @@ namespace Wasm.Build.Tests
     internal static class EnvironmentVariables
     {
         internal static readonly string? SdkForWorkloadTestingPath = Environment.GetEnvironmentVariable("SDK_FOR_WORKLOAD_TESTING_PATH");
+        internal static readonly string? SdkHasWorkloadInstalled   = Environment.GetEnvironmentVariable("SDK_HAS_WORKLOAD_INSTALLED");
         internal static readonly string? WorkloadPacksVersion      = Environment.GetEnvironmentVariable("WORKLOAD_PACKS_VER");
         internal static readonly string? AppRefDir                 = Environment.GetEnvironmentVariable("AppRefDir");
         internal static readonly string? WasmBuildSupportDir       = Environment.GetEnvironmentVariable("WasmBuildSupportDir");
index d670971..2994b3f 100644 (file)
@@ -13,7 +13,9 @@
     <DefineConstants Condition="'$(ContinuousIntegrationBuild)' != 'true'">TEST_DEBUG_CONFIG_ALSO</DefineConstants>
     <!-- This project should not build against the live built .NETCoreApp targeting pack as it contributes to the build itself. -->
     <UseLocalTargetingRuntimePack>false</UseLocalTargetingRuntimePack>
+
     <TestUsingWorkloads Condition="'$(TestUsingWorkloads)' == ''">true</TestUsingWorkloads>
+    <InstallWorkloadForTesting>true</InstallWorkloadForTesting>
 
     <!-- don't run any wasm build steps -->
     <WasmBuildAppAfterThisTarget />
index 3282feb..1a9c112 100644 (file)
@@ -1,8 +1,5 @@
 <Project>
   <PropertyGroup>
-    <!-- disable workloads for this emsdk build -->
-    <MSBuildEnableWorkloadResolver>false</MSBuildEnableWorkloadResolver>
-
     <_WasmTargetsDir Condition="'$(RuntimeSrcDir)' != ''">$(RuntimeSrcDir)\src\mono\wasm\build\</_WasmTargetsDir>
     <_WasmTargetsDir Condition="'$(WasmBuildSupportDir)' != ''">$(WasmBuildSupportDir)\wasm\</_WasmTargetsDir>
     <EMSDK_PATH Condition="'$(WasmBuildSupportDir)' != ''">$(WasmBuildSupportDir)\emsdk\</EMSDK_PATH>
index 0c2cfd8..9577232 100644 (file)
@@ -44,9 +44,13 @@ REM Functions
 :SetEnvVars
 if [%TEST_USING_WORKLOADS%] == [true] (
     set "PATH=%BASE_DIR%\dotnet-workload;%PATH%"
+    set SDK_HAS_WORKLOAD_INSTALLED=true
     set "SDK_FOR_WORKLOAD_TESTING_PATH=%BASE_DIR%\dotnet-workload"
     set "AppRefDir=%BASE_DIR%\microsoft.netcore.app.ref"
 ) else (
+    set "PATH=%BASE_DIR%\sdk-no-workload;%PATH%"
+    set SDK_HAS_WORKLOAD_INSTALLED=false
+    set "SDK_FOR_WORKLOAD_TESTING_PATH=%BASE_DIR%\sdk-no-workload"
     set "WasmBuildSupportDir=%BASE_DIR%\build"
 )
 EXIT /b 0
index d210c70..66f8893 100644 (file)
@@ -22,10 +22,15 @@ function set_env_vars()
 {
     if [ "x$TEST_USING_WORKLOADS" = "xtrue" ]; then
         export PATH=$BASE_DIR/dotnet-workload:$PATH
+        export SDK_HAS_WORKLOAD_INSTALLED=true
         export SDK_FOR_WORKLOAD_TESTING_PATH=$BASE_DIR/dotnet-workload
         export AppRefDir=$BASE_DIR/microsoft.netcore.app.ref
     elif [ ! -z "$HELIX_WORKITEM_UPLOAD_ROOT" ]; then
         export WasmBuildSupportDir=$BASE_DIR/build
+    else
+        export PATH=$BASE_DIR/sdk-no-workload:$PATH
+        export SDK_HAS_WORKLOAD_INSTALLED=false
+        export SDK_FOR_WORKLOAD_TESTING_PATH=$BASE_DIR/sdk-no-workload
     fi
 }
 
index 6d85040..2cae1d8 100644 (file)
@@ -1,7 +1,6 @@
 <Project>
   <PropertyGroup>
     <RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
-    <WasmNativeWorkload>true</WasmNativeWorkload>
     <PublishTrimmed>true</PublishTrimmed>
   </PropertyGroup>
 </Project>
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/App.razor b/src/tests/BuildWasmApps/testassets/Blazor_net50/App.razor
new file mode 100644 (file)
index 0000000..b941644
--- /dev/null
@@ -0,0 +1,10 @@
+<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
+    <Found Context="routeData">
+        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
+    </Found>
+    <NotFound>
+        <LayoutView Layout="@typeof(MainLayout)">
+            <p>Sorry, there's nothing at this address.</p>
+        </LayoutView>
+    </NotFound>
+</Router>
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/Blazor_net50.csproj b/src/tests/BuildWasmApps/testassets/Blazor_net50/Blazor_net50.csproj
new file mode 100644 (file)
index 0000000..533c048
--- /dev/null
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.8" />
+    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.8" PrivateAssets="all" />
+    <PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
+  </ItemGroup>
+
+</Project>
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/Pages/Counter.razor b/src/tests/BuildWasmApps/testassets/Blazor_net50/Pages/Counter.razor
new file mode 100644 (file)
index 0000000..8641f78
--- /dev/null
@@ -0,0 +1,16 @@
+@page "/counter"
+
+<h1>Counter</h1>
+
+<p>Current count: @currentCount</p>
+
+<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
+
+@code {
+    private int currentCount = 0;
+
+    private void IncrementCount()
+    {
+        currentCount++;
+    }
+}
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/Pages/FetchData.razor b/src/tests/BuildWasmApps/testassets/Blazor_net50/Pages/FetchData.razor
new file mode 100644 (file)
index 0000000..4432ee5
--- /dev/null
@@ -0,0 +1,55 @@
+@page "/fetchdata"
+@inject HttpClient Http
+
+<h1>Weather forecast</h1>
+
+<p>This component demonstrates fetching data from the server.</p>
+
+@if (forecasts == null)
+{
+    <p><em>Loading...</em></p>
+}
+else
+{
+    <table class="table">
+        <thead>
+            <tr>
+                <th>Date</th>
+                <th>Temp. (C)</th>
+                <th>Temp. (F)</th>
+                <th>Summary</th>
+            </tr>
+        </thead>
+        <tbody>
+            @foreach (var forecast in forecasts)
+            {
+                <tr>
+                    <td>@forecast.Date.ToShortDateString()</td>
+                    <td>@forecast.TemperatureC</td>
+                    <td>@forecast.TemperatureF</td>
+                    <td>@forecast.Summary</td>
+                </tr>
+            }
+        </tbody>
+    </table>
+}
+
+@code {
+    private WeatherForecast[] forecasts;
+
+    protected override async Task OnInitializedAsync()
+    {
+        forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
+    }
+
+    public class WeatherForecast
+    {
+        public DateTime Date { get; set; }
+
+        public int TemperatureC { get; set; }
+
+        public string Summary { get; set; }
+
+        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
+    }
+}
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/Pages/Index.razor b/src/tests/BuildWasmApps/testassets/Blazor_net50/Pages/Index.razor
new file mode 100644 (file)
index 0000000..e54d914
--- /dev/null
@@ -0,0 +1,7 @@
+@page "/"
+
+<h1>Hello, world!</h1>
+
+Welcome to your new app.
+
+<SurveyPrompt Title="How is Blazor working for you?" />
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/Program.cs b/src/tests/BuildWasmApps/testassets/Blazor_net50/Program.cs
new file mode 100644 (file)
index 0000000..b1926ec
--- /dev/null
@@ -0,0 +1,25 @@
+using System;
+using System.Net.Http;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Text;
+using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace Blazor_net50
+{
+    public class Program
+    {
+        public static async Task Main(string[] args)
+        {
+            var builder = WebAssemblyHostBuilder.CreateDefault(args);
+            builder.RootComponents.Add<App>("#app");
+
+            builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
+
+            await builder.Build().RunAsync();
+        }
+    }
+}
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/MainLayout.razor b/src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/MainLayout.razor
new file mode 100644 (file)
index 0000000..b416cb9
--- /dev/null
@@ -0,0 +1,17 @@
+@inherits LayoutComponentBase
+
+<div class="page">
+    <div class="sidebar">
+        <NavMenu />
+    </div>
+
+    <div class="main">
+        <div class="top-row px-4">
+            <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
+        </div>
+
+        <div class="content px-4">
+            @Body
+        </div>
+    </div>
+</div>
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/MainLayout.razor.css b/src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/MainLayout.razor.css
new file mode 100644 (file)
index 0000000..43c355a
--- /dev/null
@@ -0,0 +1,70 @@
+.page {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+}
+
+.main {
+    flex: 1;
+}
+
+.sidebar {
+    background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
+}
+
+.top-row {
+    background-color: #f7f7f7;
+    border-bottom: 1px solid #d6d5d5;
+    justify-content: flex-end;
+    height: 3.5rem;
+    display: flex;
+    align-items: center;
+}
+
+    .top-row ::deep a, .top-row .btn-link {
+        white-space: nowrap;
+        margin-left: 1.5rem;
+    }
+
+    .top-row a:first-child {
+        overflow: hidden;
+        text-overflow: ellipsis;
+    }
+
+@media (max-width: 640.98px) {
+    .top-row:not(.auth) {
+        display: none;
+    }
+
+    .top-row.auth {
+        justify-content: space-between;
+    }
+
+    .top-row a, .top-row .btn-link {
+        margin-left: 0;
+    }
+}
+
+@media (min-width: 641px) {
+    .page {
+        flex-direction: row;
+    }
+
+    .sidebar {
+        width: 250px;
+        height: 100vh;
+        position: sticky;
+        top: 0;
+    }
+
+    .top-row {
+        position: sticky;
+        top: 0;
+        z-index: 1;
+    }
+
+    .main > div {
+        padding-left: 2rem !important;
+        padding-right: 1.5rem !important;
+    }
+}
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/NavMenu.razor b/src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/NavMenu.razor
new file mode 100644 (file)
index 0000000..d2f6197
--- /dev/null
@@ -0,0 +1,37 @@
+<div class="top-row pl-4 navbar navbar-dark">
+    <a class="navbar-brand" href="">Blazor_net50</a>
+    <button class="navbar-toggler" @onclick="ToggleNavMenu">
+        <span class="navbar-toggler-icon"></span>
+    </button>
+</div>
+
+<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
+    <ul class="nav flex-column">
+        <li class="nav-item px-3">
+            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
+                <span class="oi oi-home" aria-hidden="true"></span> Home
+            </NavLink>
+        </li>
+        <li class="nav-item px-3">
+            <NavLink class="nav-link" href="counter">
+                <span class="oi oi-plus" aria-hidden="true"></span> Counter
+            </NavLink>
+        </li>
+        <li class="nav-item px-3">
+            <NavLink class="nav-link" href="fetchdata">
+                <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
+            </NavLink>
+        </li>
+    </ul>
+</div>
+
+@code {
+    private bool collapseNavMenu = true;
+
+    private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
+
+    private void ToggleNavMenu()
+    {
+        collapseNavMenu = !collapseNavMenu;
+    }
+}
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/NavMenu.razor.css b/src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/NavMenu.razor.css
new file mode 100644 (file)
index 0000000..acc5f9f
--- /dev/null
@@ -0,0 +1,62 @@
+.navbar-toggler {
+    background-color: rgba(255, 255, 255, 0.1);
+}
+
+.top-row {
+    height: 3.5rem;
+    background-color: rgba(0,0,0,0.4);
+}
+
+.navbar-brand {
+    font-size: 1.1rem;
+}
+
+.oi {
+    width: 2rem;
+    font-size: 1.1rem;
+    vertical-align: text-top;
+    top: -2px;
+}
+
+.nav-item {
+    font-size: 0.9rem;
+    padding-bottom: 0.5rem;
+}
+
+    .nav-item:first-of-type {
+        padding-top: 1rem;
+    }
+
+    .nav-item:last-of-type {
+        padding-bottom: 1rem;
+    }
+
+    .nav-item ::deep a {
+        color: #d7d7d7;
+        border-radius: 4px;
+        height: 3rem;
+        display: flex;
+        align-items: center;
+        line-height: 3rem;
+    }
+
+.nav-item ::deep a.active {
+    background-color: rgba(255,255,255,0.25);
+    color: white;
+}
+
+.nav-item ::deep a:hover {
+    background-color: rgba(255,255,255,0.1);
+    color: white;
+}
+
+@media (min-width: 641px) {
+    .navbar-toggler {
+        display: none;
+    }
+
+    .collapse {
+        /* Never collapse the sidebar for wide screens */
+        display: block;
+    }
+}
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/SurveyPrompt.razor b/src/tests/BuildWasmApps/testassets/Blazor_net50/Shared/SurveyPrompt.razor
new file mode 100644 (file)
index 0000000..67828b5
--- /dev/null
@@ -0,0 +1,16 @@
+<div class="alert alert-secondary mt-4" role="alert">
+    <span class="oi oi-pencil mr-2" aria-hidden="true"></span>
+    <strong>@Title</strong>
+
+    <span class="text-nowrap">
+        Please take our
+        <a target="_blank" class="font-weight-bold" href="https://go.microsoft.com/fwlink/?linkid=2137916">brief survey</a>
+    </span>
+    and tell us what you think.
+</div>
+
+@code {
+    // Demonstrates how a parent component can supply parameters
+    [Parameter]
+    public string Title { get; set; }
+}
diff --git a/src/tests/BuildWasmApps/testassets/Blazor_net50/_Imports.razor b/src/tests/BuildWasmApps/testassets/Blazor_net50/_Imports.razor
new file mode 100644 (file)
index 0000000..d6b66f2
--- /dev/null
@@ -0,0 +1,10 @@
+@using System.Net.Http
+@using System.Net.Http.Json
+@using Microsoft.AspNetCore.Components.Forms
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using Microsoft.AspNetCore.Components.Web.Virtualization
+@using Microsoft.AspNetCore.Components.WebAssembly.Http
+@using Microsoft.JSInterop
+@using Blazor_net50
+@using Blazor_net50.Shared