Skip to content

Commit 2860263

Browse files
authored
Add infrastructure for trimming and NativeAOT test apps. (#48024)
* Add infrastructure for trimming and NativeAOT test apps. This infrastructure was taken from https://github.com/dotnet/runtime/tree/c62f69be1405a8e41b56ffc05f22d791bf4c7d2d/eng/testing/linker and modified to work in dotnet/aspnetcore. Added the first test: - Generic host + value type container builder (verify that error is thrown) Contributes to #45860 * Skip IsPublishedAppTestProject projects when SkipTestBuild=true. Use `Sdk="Microsoft.NET.Sdk"` in order to skip the build correctly. Only run the AOT tests during Test. Skip "Build" and skip publishing for Helix. Ensure the IsPublishedAppTestProject projects aren't built until the shared fx is built using RequiresDelayedBuild. * Add workaround for dotnet/arcade#13406
1 parent 576c75c commit 2860263

14 files changed

+372
-4
lines changed

Directory.Build.BeforeCommonTargets.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<ExcludeFromBuild Condition="'$(IsPackable)' != 'true' and
1616
'$(SkipTestBuild)' == 'true' and
1717
($(IsTestProject) or
18+
'$(IsPublishedAppTestProject)' == 'true' or
1819
'$(IsTestAssetProject)' == 'true' or
1920
'$(IsBenchmarkProject)' == 'true' or
2021
'$(IsSampleProject)' == 'true' or

Directory.Build.props

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project>
1+
<Project>
22
<Import Project="eng\Common.props" />
33

44
<PropertyGroup>
@@ -30,6 +30,9 @@
3030
$(MSBuildProjectName.EndsWith('.Test')) OR
3131
$(MSBuildProjectName.EndsWith('.FunctionalTest')) ) ">true</IsUnitTestProject>
3232
<IsUnitTestProject Condition=" '$(IsUnitTestProject)' == '' ">false</IsUnitTestProject>
33+
<IsTrimmingTestProject Condition="$(MSBuildProjectName.EndsWith('.TrimmingTests'))">true</IsTrimmingTestProject>
34+
<IsNativeAotTestProject Condition="$(MSBuildProjectName.EndsWith('.NativeAotTests'))">true</IsNativeAotTestProject>
35+
<IsPublishedAppTestProject Condition="'$(IsTrimmingTestProject)' == 'true' or '$(IsNativeAotTestProject)' == 'true'">true</IsPublishedAppTestProject>
3336
<IsTestAssetProject Condition=" $(RepoRelativeProjectDir.Contains('testassets')) OR $(MSBuildProjectName.Contains('TestCommon'))">true</IsTestAssetProject>
3437
<IsProjectTemplateProject Condition=" ($(RepoRelativeProjectDir.Contains('ProjectTemplates')) OR $(MSBuildProjectName.Contains('ProjectTemplates')) ) AND
3538
'$(IsUnitTestProject)' != 'true' AND
@@ -39,6 +42,7 @@
3942
<IsShipping Condition=" '$(IsSampleProject)' == 'true' OR
4043
'$(IsTestAssetProject)' == 'true' OR
4144
'$(IsBenchmarkProject)' == 'true' OR
45+
'$(IsPublishedAppTestProject)' == 'true' OR
4246
$(IsUnitTestProject) ">false</IsShipping>
4347

4448
<!--
@@ -258,6 +262,7 @@
258262
<Import Project="eng\targets\Wix.Common.props" Condition="'$(MSBuildProjectExtension)' == '.wixproj'" />
259263
<Import Project="eng\targets\Npm.Common.props" Condition="'$(MSBuildProjectExtension)' == '.npmproj'" />
260264
<Import Project="eng\targets\Java.Common.props" Condition="'$(MSBuildProjectExtension)' == '.javaproj'" />
265+
<Import Project="eng\testing\linker\trimmingTests.props" Condition="'$(IsPublishedAppTestProject)' == 'true'" />
261266
<Import Project="eng\targets\Helix.props" Condition=" $(IsTestProject) " />
262267
<Import Project="eng\targets\FunctionalTestWithAssets.props" Condition=" $(IsTestProject) " />
263268

Directory.Build.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@
179179
<Import Project="eng\targets\Wix.Common.targets" Condition="'$(MSBuildProjectExtension)' == '.wixproj'" />
180180
<Import Project="eng\targets\Npm.Common.targets" Condition="'$(MSBuildProjectExtension)' == '.npmproj'" />
181181
<Import Project="eng\targets\Java.Common.targets" Condition="'$(MSBuildProjectExtension)' == '.javaproj'" />
182+
<Import Project="eng\testing\linker\trimmingTests.targets" Condition="'$(IsPublishedAppTestProject)' == 'true'" />
182183
<Import Project="eng\targets\Helix.targets" Condition=" $(IsTestProject) " />
183184
<Import Project="eng\targets\FunctionalTestWithAssets.targets"
184185
Condition=" $(IsTestProject) AND $(ContainsFunctionalTestAssets) " />

eng/RequiresDelayedBuildProjects.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
<RequiresDelayedBuild Include="$(RepoRoot)src\Grpc\JsonTranscoding\test\testassets\IntegrationTestsWebsite\IntegrationTestsWebsite.csproj" />
1818
<RequiresDelayedBuild Include="$(RepoRoot)src\Grpc\JsonTranscoding\test\testassets\Sandbox\Sandbox.csproj" />
1919
<RequiresDelayedBuild Include="$(RepoRoot)src\ProjectTemplates\test\Templates.Blazor.Tests\Templates.Blazor.Tests.csproj" />
20+
<RequiresDelayedBuild Include="$(RepoRoot)src\DefaultBuilder\test\Microsoft.AspNetCore.NativeAotTests\Microsoft.AspNetCore.NativeAotTests.proj" />
2021
</ItemGroup>
2122
</Project>

eng/common/tools.ps1

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,9 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements =
399399
# Locate Visual Studio installation or download x-copy msbuild.
400400
$vsInfo = LocateVisualStudio $vsRequirements
401401
if ($vsInfo -ne $null) {
402-
$vsInstallDir = $vsInfo.installationPath
402+
# Needed until we get https://github.com/dotnet/arcade/pull/13406/
403+
# Ensure vsInstallDir has a trailing slash
404+
$vsInstallDir = Join-path $vsInfo.installationPath "\"
403405
$vsMajorVersion = $vsInfo.installationVersion.Split('.')[0]
404406

405407
InitializeVisualStudioEnvironmentVariables $vsInstallDir $vsMajorVersion
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project>
2+
<PropertyGroup>
3+
<!-- Workaround while there is no SDK available that understands the TFM; suppress unsupported version errors. -->
4+
<NETCoreAppMaximumVersion>99.9</NETCoreAppMaximumVersion>
5+
6+
<PublishTrimmed>true</PublishTrimmed>
7+
<TrimMode>full</TrimMode>
8+
<PublishSelfContained>true</PublishSelfContained>
9+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
10+
<!-- Enable NuGet static graph evaluation to optimize incremental restore -->
11+
<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation>
12+
</PropertyGroup>
13+
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project>
2+
3+
<PropertyGroup>
4+
<!-- Used to silence the warning caused by the workaround for https://github.com/dotnet/runtime/issues/81382 -->
5+
<SuppressGenerateILCompilerExplicitPackageReferenceWarning>true</SuppressGenerateILCompilerExplicitPackageReferenceWarning>
6+
</PropertyGroup>
7+
8+
<!-- needed to reference a specific version of NetCoreApp. Workaround https://github.com/dotnet/runtime/issues/81382 -->
9+
<ItemGroup>
10+
<FrameworkReference Update="Microsoft.NETCore.App"
11+
RuntimeFrameworkVersion="$(MicrosoftNETCoreAppRuntimeVersion)" />
12+
13+
<PackageReference Include="Microsoft.Dotnet.ILCompiler"
14+
Version="$(MicrosoftNETCoreAppRuntimeVersion)" />
15+
</ItemGroup>
16+
17+
<!--
18+
Reference the Microsoft.AspNetCore.App shared framework assemblies with ProjectReference.
19+
This allows for easy dev workflow. Just need to update the product code, and re-run the tests.
20+
-->
21+
<ItemGroup>
22+
<ProjectReference Include="$(RepoRoot)src\DefaultBuilder\src\Microsoft.AspNetCore.csproj" />
23+
</ItemGroup>
24+
25+
</Project>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>{TargetFramework}</TargetFramework>
5+
<OutputType>Exe</OutputType>
6+
<RuntimeIdentifier>{RuntimeIdentifier}</RuntimeIdentifier>
7+
<PublishAot>{PublishAot}</PublishAot>
8+
<MicrosoftNETCoreAppRuntimeVersion>{MicrosoftNETCoreAppRuntimeVersion}</MicrosoftNETCoreAppRuntimeVersion>
9+
<RepoRoot>{RepoRoot}</RepoRoot>
10+
<_ExtraTrimmerArgs>{ExtraTrimmerArgs} $(_ExtraTrimmerArgs)</_ExtraTrimmerArgs>
11+
{AdditionalProperties}
12+
</PropertyGroup>
13+
14+
<ItemGroup>
15+
{RuntimeHostConfigurationOptions}
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
{AdditionalProjectReferences}
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project>
2+
<PropertyGroup>
3+
<TrimmingTestDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'trimmingTests'))</TrimmingTestDir>
4+
<TrimmingTestProjectsDir>$([MSBuild]::NormalizeDirectory('$(TrimmingTestDir)', 'projects'))</TrimmingTestProjectsDir>
5+
<ProjectTemplate>$(MSBuildThisFileDirectory)project.csproj.template</ProjectTemplate>
6+
7+
<!-- These test projects cannot be run in helix, since there is nothing to publish. -->
8+
<BuildHelixPayload>false</BuildHelixPayload>
9+
<IsPublishable>false</IsPublishable>
10+
</PropertyGroup>
11+
12+
<PropertyGroup>
13+
<!-- Microsoft.NET.Sdk needs a TFM set. Set a default one. -->
14+
<TargetFramework Condition="'$(TargetFramework)' == '' and '$(TargetFrameworks)' == ''">$(DefaultNetCoreTargetFramework)</TargetFramework>
15+
16+
<!-- Enforce build order. Ensure the Shared Fx is built before generating and publishing the test apps. -->
17+
<RequiresDelayedBuild>true</RequiresDelayedBuild>
18+
</PropertyGroup>
19+
20+
</Project>
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<Project>
2+
<Import Project="$(RepoRoot)eng\targets\ResolveReferences.targets" />
3+
4+
<ItemGroup>
5+
<TestConsoleAppSourceFiles Condition="'@(TestConsoleAppSourceFiles)' == ''" Include="$(MSBuildProjectDirectory)\*.cs" />
6+
7+
<TestSupportFiles Include="$(MSBuildThisFileDirectory)SupportFiles\Directory.Build.*">
8+
<DestinationFolder>$(TrimmingTestDir)</DestinationFolder>
9+
</TestSupportFiles>
10+
</ItemGroup>
11+
12+
<Target Name="CreateTestDir"
13+
Inputs="@(TestSupportFiles)"
14+
Outputs="@(TestSupportFiles->'%(DestinationFolder)\%(FileName)%(Extension)')">
15+
<MakeDir Directories="%(TestSupportFiles.DestinationFolder)" />
16+
<Copy SourceFiles="@(TestSupportFiles)" DestinationFolder="%(TestSupportFiles.DestinationFolder)" />
17+
</Target>
18+
19+
<Target Name="GetTestConsoleApps">
20+
<ItemGroup>
21+
<TestConsoleAppSourceFiles>
22+
<ProjectDir>$([MSBuild]::NormalizeDirectory('$(TrimmingTestProjectsDir)', '$(MSBuildProjectName)', '%(Filename)', '$(PackageRID)'))</ProjectDir>
23+
<TestRuntimeIdentifier>$(TargetRuntimeIdentifier)</TestRuntimeIdentifier>
24+
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
25+
<TargetFramework Condition="'%(TestConsoleAppSourceFiles.TargetOS)' != ''">$(DefaultNetCoreTargetFramework)-%(TestConsoleAppSourceFiles.TargetOS)</TargetFramework>
26+
</TestConsoleAppSourceFiles>
27+
<!-- We need to separate Item metadata declaration in two in order to be able to use ProjectDir and TestRuntimeIdentifier below -->
28+
<TestConsoleAppSourceFiles>
29+
<ProjectFile>%(ProjectDir)project.csproj</ProjectFile>
30+
<TestCommand>$([MSBuild]::NormalizePath('%(ProjectDir)', 'bin', '$(Configuration)', '%(TargetFramework)', '%(TestRuntimeIdentifier)', 'publish', 'project'))</TestCommand>
31+
<TestExecutionDirectory>$([MSBuild]::NormalizeDirectory('%(ProjectDir)', 'bin', '$(Configuration)', '%(TargetFramework)', '%(TestRuntimeIdentifier)', 'publish'))</TestExecutionDirectory>
32+
</TestConsoleAppSourceFiles>
33+
</ItemGroup>
34+
35+
<ItemGroup>
36+
<TestConsoleApps Include="@(TestConsoleAppSourceFiles->'%(ProjectFile)')">
37+
<ProjectCompileItems>%(FullPath)</ProjectCompileItems>
38+
</TestConsoleApps>
39+
<TestConsoleApps AdditionalProperties="MSBuildEnableWorkloadResolver=$(MSBuildEnableWorkloadResolver)" Condition="'$(MSBuildEnableWorkloadResolver)' != ''" />
40+
</ItemGroup>
41+
</Target>
42+
43+
<Target Name="GenerateProjects"
44+
DependsOnTargets="GetTestConsoleApps;CreateTestDir"
45+
Inputs="@(TestConsoleAppSourceFiles);$(ProjectTemplate);@(TestSupportFiles)"
46+
Outputs="%(TestConsoleApps.Identity)">
47+
<PropertyGroup>
48+
<_projectDir>%(TestConsoleApps.ProjectDir)\</_projectDir>
49+
<_projectFile>%(TestConsoleApps.ProjectFile)</_projectFile>
50+
<_projectSourceFile>%(TestConsoleApps.ProjectCompileItems)</_projectSourceFile>
51+
</PropertyGroup>
52+
53+
<ItemGroup Condition="'$(AdditionalProjectReferences)' != ''">
54+
<_additionalProjectReferenceTemp Include="$(AdditionalProjectReferences)" />
55+
<_additionalProjectReference Include="&lt;ProjectReference Include=&quot;$(LibrariesProjectRoot)%(_additionalProjectReferenceTemp.Identity)\src\%(_additionalProjectReferenceTemp.Identity).csproj&quot; SkipUseReferenceAssembly=&quot;true&quot; /&gt;" />
56+
</ItemGroup>
57+
58+
<PropertyGroup>
59+
<_additionalProjectReferencesString>@(_additionalProjectReference, '%0a')</_additionalProjectReferencesString>
60+
</PropertyGroup>
61+
62+
<ItemGroup>
63+
<_additionalProjectSourceFiles Include="%(TestConsoleApps.AdditionalSourceFiles)" />
64+
</ItemGroup>
65+
66+
<ItemGroup>
67+
<_switchesAsItems Include="%(TestConsoleApps.DisabledFeatureSwitches)" Value="false" />
68+
<_switchesAsItems Include="%(TestConsoleApps.EnabledFeatureSwitches)" Value="true" />
69+
70+
<_propertiesAsItems Include="%(TestConsoleApps.DisabledProperties)" Value="false" />
71+
<_propertiesAsItems Include="%(TestConsoleApps.EnabledProperties)" Value="true" />
72+
</ItemGroup>
73+
74+
<PropertyGroup>
75+
<_runtimeHostConfigurationOptionsString>@(_switchesAsItems->'&lt;RuntimeHostConfigurationOption Include=&quot;%(Identity)&quot; Value=&quot;%(Value)&quot; Trim=&quot;true&quot; /&gt;', '%0a ')</_runtimeHostConfigurationOptionsString>
76+
<_additionalPropertiesString>@(_propertiesAsItems->'&lt;%(Identity)&gt;%(Value)&lt;/%(Identity)&gt;', '%0a ')</_additionalPropertiesString>
77+
</PropertyGroup>
78+
79+
<MakeDir Directories="$(_projectDir)" />
80+
<WriteLinesToFile File="$(_projectFile)"
81+
Lines="$([System.IO.File]::ReadAllText('$(ProjectTemplate)')
82+
.Replace('{TargetFramework}', '%(TestConsoleApps.TargetFramework)')
83+
.Replace('{RuntimeIdentifier}','%(TestConsoleApps.TestRuntimeIdentifier)')
84+
.Replace('{PublishAot}','$(IsNativeAotTestProject)')
85+
.Replace('{MicrosoftNETCoreAppRuntimeVersion}','$(MicrosoftNETCoreAppRuntimeVersion)')
86+
.Replace('{RepoRoot}', '$(RepoRoot)')
87+
.Replace('{ExtraTrimmerArgs}', '%(TestConsoleApps.ExtraTrimmerArgs)')
88+
.Replace('{AdditionalProperties}', '$(_additionalPropertiesString)')
89+
.Replace('{RuntimeHostConfigurationOptions}', '$(_runtimeHostConfigurationOptionsString)')
90+
.Replace('{AdditionalProjectReferences}', '$(_additionalProjectReferencesString)')
91+
)"
92+
Overwrite="true" />
93+
<Copy SourceFiles="$(_projectSourceFile);
94+
@(_additionalProjectSourceFiles)"
95+
DestinationFolder="$(_projectDir)" />
96+
<Message Text="Generated $(_projectFile)" />
97+
</Target>
98+
99+
<Target Name="PublishTrimmedProjects"
100+
DependsOnTargets="GenerateProjects">
101+
102+
<MSBuild Projects="@(TestConsoleApps)"
103+
Targets="Restore"
104+
Condition="'$(SkipTrimmingProjectsRestore)' != 'true'"
105+
Properties="MSBuildRestoreSessionId=$([System.Guid]::NewGuid());Configuration=$(Configuration)" />
106+
107+
<MSBuild Projects="@(TestConsoleApps)"
108+
Targets="Publish"
109+
Properties="Configuration=$(Configuration);BuildProjectReferences=false" />
110+
</Target>
111+
112+
<Target Name="ExecuteApplications"
113+
DependsOnTargets="PublishTrimmedProjects"
114+
Inputs="%(TestConsoleApps.Identity)"
115+
Outputs="_unused"
116+
Condition="'$(ArchiveTests)' != 'true'">
117+
118+
<Message Importance="High" Text="[Trimming Tests] Running test: %(TestConsoleApps.ProjectCompileItems) ..." />
119+
<Exec IgnoreExitCode="true" Command="%(TestConsoleApps.TestCommand)" StandardOutputImportance="Low" WorkingDirectory="%(TestConsoleApps.TestExecutionDirectory)">
120+
<Output TaskParameter="ExitCode" PropertyName="ExecutionExitCode" />
121+
</Exec>
122+
123+
<Error Condition="'$(ExecutionExitCode)' != '100'" Text="Error: [Failed Test]: %(TestConsoleApps.ProjectCompileItems). The Command %(TestConsoleApps.TestCommand) return a non-success exit code." ContinueOnError="ErrorAndContinue" />
124+
</Target>
125+
126+
<Target Name="Test" DependsOnTargets="ExecuteApplications" />
127+
<Target Name="VSTest" DependsOnTargets="Test" />
128+
129+
<!-- define Restore/Build to do nothing, for this project only Test does the testing -->
130+
<Target Name="Restore" />
131+
<Target Name="Build" />
132+
</Project>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<ItemGroup>
4+
<TestConsoleAppSourceFiles Include="UseStartupThrowsForStructContainersTest.cs" />
5+
</ItemGroup>
6+
7+
</Project>

0 commit comments

Comments
 (0)