Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions eng/pipelines/runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -861,16 +861,61 @@ extends:
jobParameters:
timeoutInMinutes: 120
nameSuffix: CLR_Tools_Tests
# Depend on the browser-wasm libraries built below so the wasm crossgen2 R2R test
# (ILCompiler.ReadyToRun.Tests) can compile against real browser-wasm references.
dependsOn:
- build_browser_wasm_linux_Release_CLR_Tools_Tests_WasmLibs

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of all this hackery and optional WASM builds, can we add a separate ToolsTests leg (ReadyToRunTests) that simply builds the runtime as -arch wasm and then one more leg that builds as -arch arm?

We might want to move ILCompiler.ReadyToRun.Tests out of toolstests as part of that since none of the other toolstests are actually architecture specific and it's a waste of time to run them.

I believe we'll not need any of the project file hackery if we do that because CoreLib that is passed to the tests will simply be the correct corelib. The attributes in the tests can still decide whether the test should run or not.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd also be able to undo parts of #129791, specifically ba3edd9 and a2b9874 because we'd no longer need host-flavored flavor of all the JITs, only the host-flavored JIT that we're testing.

buildArgs: -s clr.aot+clr.iltools+clr.corelib+clr.nativecorelib+libs.sfx+clr.toolstests+tools.cdac+tools.cdactests -c $(_BuildConfig) -test
enablePublishTestResults: true
testResultsFormat: 'xunit'
preBuildSteps:
# Lay the browser-wasm libraries into artifacts/bin so TestPaths' WasmRuntimePackDir
# resolves and the wasm R2R test compiles against real browser-wasm references.
- template: /eng/pipelines/common/download-artifact-step.yml
parameters:
artifactName: CLR_Tools_Tests_WasmLibs_BuildArtifacts_browser_wasm_Release
artifactFileName: CLR_Tools_Tests_WasmLibs_BuildArtifacts_browser_wasm_Release$(archiveExtension)
unpackFolder: $(Build.SourcesDirectory)/artifacts/bin
cleanUnpackFolder: false
overwriteExistingFiles: true
displayName: Browser-Wasm Libraries
# We want to run AOT tests when illink changes because there's share code and tests from illink which are used by AOT
condition: >-
or(
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true),
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_cdac.containsChange'], true),
eq(variables['isRollingBuild'], true))

# Build the browser-wasm managed runtime pack that the CLR_Tools_Tests job uses
# as crossgen2 references for the wasm ReadyToRun test. Native runtime and host
# assets are omitted because the test only consumes managed assemblies.
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
buildConfig: Release
platforms:
- browser_wasm
jobParameters:
nameSuffix: CLR_Tools_Tests_WasmLibs
buildArgs: -s clr.corelib+libs+libs.pretest -c Release /p:IncludeStaticLibrariesInPack=false
timeoutInMinutes: 120
postBuildSteps:
- template: /eng/pipelines/common/upload-artifact-step.yml
parameters:
rootFolder: $(Build.SourcesDirectory)/artifacts/bin
includeRootFolder: false
archiveType: $(archiveType)
archiveExtension: $(archiveExtension)
tarCompression: $(tarCompression)
artifactName: CLR_Tools_Tests_WasmLibs_BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig)
displayName: Browser-Wasm Libraries
condition: >-
or(
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true),
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_cdac.containsChange'], true),
eq(variables['isRollingBuild'], true))
#
# Build CrossDacs
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,99 +12,105 @@
<Configurations>Debug;Release;Checked</Configurations>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<TestRunnerAdditionalArguments>-notrait category=failing</TestRunnerAdditionalArguments>
<RequireWasmReferences Condition="'$(RequireWasmReferences)' == ''">false</RequireWasmReferences>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisCSharpVersion)" />
<PackageReference Include="Microsoft.DotNet.XUnitExtensions" Version="$(MicrosoftDotNetXUnitExtensionsVersion)" />
</ItemGroup>

<!-- Test case source files are embedded as resources so we can compile them with Roslyn at test time.
Exclude subdirectory sources from compilation since they are compiled in-memory by R2RTestCaseCompiler. -->
<ItemGroup>
<Compile Remove="TestCases/*/**/*.cs" />
<EmbeddedResource Include="TestCases/**/*.cs" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="../ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj" />
<ProjectReference Include="../crossgen2/crossgen2_inbuild.csproj" ReferenceOutputAssembly="false">
<!-- crossgen2 is a CoreCLR artifact, so publish it in the CoreCLR configuration. This keeps it
alongside the other CoreCLR artifacts the test consumes (System.Private.CoreLib, the JITs)
even when this test project is built in a different configuration than CoreCLR was (e.g.
CoreCLR built Release via 'clr -rc release', but the test built/run as Debug). Mirrors the
CoreLib SetConfiguration pattern in eng/references.targets. -->
<SetConfiguration Condition="'$(Configuration)' == '$(CoreCLRConfiguration)'">CopyAllJitLibrariesToAotCompilerOutput=true</SetConfiguration>
<SetConfiguration Condition="'$(Configuration)' != '$(CoreCLRConfiguration)'">Configuration=$(CoreCLRConfiguration);CopyAllJitLibrariesToAotCompilerOutput=true</SetConfiguration>
<ProjectReference Include="../crossgen2/crossgen2_inbuild.csproj" ReferenceOutputAssembly="false" OutputItemType="Crossgen2InbuildOutputItems">
<SetConfiguration>Configuration=$(CoreCLRConfiguration);CopyAllJitLibrariesToAotCompilerOutput=true</SetConfiguration>
</ProjectReference>
</ItemGroup>

<!-- HACK: We run runtime.proj inline to build the wasm JIT and then Copy it directly into
crossgen2_inbuild's publish dir. This is hacky for two reasons:
1. crossgen2_inbuild's <Content> glob for clrjits is evaluated at project-load time,
before this target runs, so on a clean tree the glob misses the freshly installed
JITs and the direct Copy is the only thing that reliably gets the file there.
2. We reach into another project's publish dir instead of flowing outputs through the
ProjectReference protocol.
Ideally this would be replaced by a proper ProjectReference setup where the wasm JIT and
crossgen2's other dependencies flow into our own output dir via GetCopyToOutputDirectoryItems,
and R2RTest.Crossgen2Dir points at the test's bin dir instead of crossgen2_inbuild's publish dir.

In cross builds JITs land in $(CoreCLRArtifactsPath)$(BuildArchitecture)/; we mirror
eng/Subsets.props's cross-tool stanza so install/read paths agree.
Hooks into ResolveProjectReferences so it fires for `dotnet build` (and CI's `build.sh -test`,
which builds before testing). `dotnet build /t:test` alone won't trigger it. -->
<PropertyGroup>
<_BuildJitsCrossArch Condition="'$(CrossBuild)' == 'true' or '$(BuildArchitecture)' != '$(TargetArchitecture)' or '$(HostOS)' != '$(TargetOS)' or '$(EnableNativeSanitizers)' != ''">true</_BuildJitsCrossArch>
<_BuildJitsProperties>ClrAllJitsSubset=true;ClrWasmJitSubset=true;Configuration=$(CoreCLRConfiguration)</_BuildJitsProperties>
<_BuildJitsProperties Condition="!$([MSBuild]::IsOsPlatform(Windows))">$(_BuildJitsProperties);Ninja=true</_BuildJitsProperties>
<_BuildJitsProperties Condition="'$(_BuildJitsCrossArch)' == 'true'">$(_BuildJitsProperties);HostArchitecture=$(BuildArchitecture);HostCrossOS=$(HostOS);CrossBuild=false;BuildSubdirectory=$(BuildArchitecture);CMakeArgs=$(CMakeArgs) -DCLR_CROSS_COMPONENTS_BUILD=1;PgoInstrument=false;NoPgoOptimize=true</_BuildJitsProperties>
<WasmRuntimePackRoot>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'microsoft.netcore.app.runtime.browser-wasm'))</WasmRuntimePackRoot>
<WasmRuntimePackDir>$([MSBuild]::NormalizeDirectory('$(WasmRuntimePackRoot)', '$(LibrariesConfiguration)', 'runtimes', 'browser-wasm', 'lib', '$(NetCoreAppCurrent)'))</WasmRuntimePackDir>
<WasmRuntimePackNativeDir>$([MSBuild]::NormalizeDirectory('$(WasmRuntimePackRoot)', '$(LibrariesConfiguration)', 'runtimes', 'browser-wasm', 'native'))</WasmRuntimePackNativeDir>
<WasmRuntimePackDir Condition="!Exists('$(WasmRuntimePackDir)') and Exists('$(WasmRuntimePackRoot)Release/runtimes/browser-wasm/lib/$(NetCoreAppCurrent)')">$([MSBuild]::NormalizeDirectory('$(WasmRuntimePackRoot)', 'Release', 'runtimes', 'browser-wasm', 'lib', '$(NetCoreAppCurrent)'))</WasmRuntimePackDir>
<WasmRuntimePackNativeDir Condition="!Exists('$(WasmRuntimePackNativeDir)') and Exists('$(WasmRuntimePackRoot)Release/runtimes/browser-wasm/native')">$([MSBuild]::NormalizeDirectory('$(WasmRuntimePackRoot)', 'Release', 'runtimes', 'browser-wasm', 'native'))</WasmRuntimePackNativeDir>
</PropertyGroup>


<!-- The JITs must be built before crossgen2_inbuild so that they can be copied to the output directory -->
<Target Name="BuildAllJitsForReadyToRunTests"
DependsOnTargets=""
BeforeTargets="ResolveProjectReferences"
Condition="'$(DesignTimeBuild)' != 'true'">
<PropertyGroup>
<_BuildJitsCrossArch Condition="'$(CrossBuild)' == 'true' or '$(BuildArchitecture)' != '$(TargetArchitecture)' or '$(HostOS)' != '$(TargetOS)' or '$(EnableNativeSanitizers)' != ''">true</_BuildJitsCrossArch>
<_BuildJitsProperties>ClrAllJitsSubset=true;ClrWasmJitSubset=true;Configuration=$(CoreCLRConfiguration)</_BuildJitsProperties>
<_BuildJitsProperties Condition="!$([MSBuild]::IsOsPlatform(Windows))">$(_BuildJitsProperties);Ninja=true</_BuildJitsProperties>
<_BuildJitsProperties Condition="'$(_BuildJitsCrossArch)' == 'true'">$(_BuildJitsProperties);HostArchitecture=$(BuildArchitecture);HostCrossOS=$(HostOS);CrossBuild=false;BuildSubdirectory=$(BuildArchitecture);CMakeArgs=$(CMakeArgs) -DCLR_CROSS_COMPONENTS_BUILD=1;PgoInstrument=false;NoPgoOptimize=true</_BuildJitsProperties>
</PropertyGroup>
<MSBuild Projects="$(CoreClrProjectRoot)runtime.proj"
Targets="Build"
Properties="$(_BuildJitsProperties)" />
</Target>

<PropertyGroup>
<_WasmJitCrossHostArchSubdir Condition="'$(_BuildJitsCrossArch)' == 'true'">$(BuildArchitecture)/</_WasmJitCrossHostArchSubdir>
<_WasmJitFileName>$(HostLibPrefix)clrjit_universal_wasm_$(BuildArchitecture)$(HostLibSuffix)</_WasmJitFileName>
<_WasmJitSourcePath>$(CoreCLRArtifactsPath)$(_WasmJitCrossHostArchSubdir)$(_WasmJitFileName)</_WasmJitSourcePath>
<_Crossgen2InbuildPublishDir>$(CoreCLRArtifactsPath)$(BuildArchitecture)/crossgen2/</_Crossgen2InbuildPublishDir>
</PropertyGroup>
<Copy SourceFiles="$(_WasmJitSourcePath)"
DestinationFolder="$(_Crossgen2InbuildPublishDir)"
SkipUnchangedFiles="true" />
<Target Name="ValidatePathsExist"
BeforeTargets="Build"
Condition="'$(DesignTimeBuild)' != 'true'">

<Error Condition="!Exists('$(CoreCLRArtifactsPath)\$(BuildArchitecture)\crossgen2')"
Text="Crossgen2 inbuild publish directory '$(CoreCLRArtifactsPath)\$(BuildArchitecture)\crossgen2' does not exist. This is a build authoring error and should be generated in the test project build." />
<Error Condition="!Exists('$(MicrosoftNetCoreAppRuntimePackNativeDir)')"
Text="Runtime pack path '$(MicrosoftNetCoreAppRuntimePackNativeDir)' does not exist." />
<Error Condition="!Exists('$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)')"
Text="Runtime pack path '$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)' does not exist." />

<!-- Wasm runtime pack is not strictly required for local builds, but is enforced in CI with RequireWasmReferences -->
<Error Condition="'$(RequireWasmReferences)' == 'true' and (!Exists('$(WasmRuntimePackDir)') or !Exists('$(WasmRuntimePackNativeDir)System.Private.CoreLib.dll'))"
Text="The browser-wasm runtime pack was not found under '$(WasmRuntimePackRoot)'. Build and download the wasm prerequisite artifact before building this test." />
<Warning Condition="'$(RequireWasmReferences)' != 'true' and !Exists('$(WasmRuntimePackDir)')"
Text="Browser-wasm runtime pack path '$(WasmRuntimePackDir)' does not exist. Browser-wasm ReadyToRun tests will fall back to host references, which may cause unexpected failures. Generate by building the clr.corelib+libs+libs.pretest subsets for browser-wasm." />
<Warning Condition="'$(RequireWasmReferences)' != 'true' and !Exists('$(WasmRuntimePackNativeDir)System.Private.CoreLib.dll')"
Text="Browser-wasm System.Private.CoreLib.dll was not found under '$(WasmRuntimePackNativeDir)'. Browser-wasm ReadyToRun tests will fall back to host references, which may cause unexpected failures. Generate by building the clr.corelib+libs+libs.pretest subsets for browser-wasm." />
</Target>

<!-- Test case source files are embedded as resources so we can compile them with Roslyn at test time.
Exclude subdirectory sources from compilation since they are compiled in-memory by R2RTestCaseCompiler. -->
<ItemGroup>
<Compile Remove="TestCases/*/**/*.cs" />
<EmbeddedResource Include="TestCases/**/*.cs" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
<!-- RuntimeConfiguration values that depend on build output paths must be set in a target -->
<Target Name="SetRuntimeConfigurationOptions"
BeforeTargets="GenerateBuildRuntimeConfigurationFiles"
Condition="'$(DesignTimeBuild)' != 'true'">

<!-- Pass build-time paths to test runtime via RuntimeHostConfigurationOption -->
<ItemGroup>
<RuntimeHostConfigurationOption Include="R2RTest.Crossgen2Dir">
<Value>$(CoreCLRArtifactsPath)/$(BuildArchitecture)/crossgen2</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.RuntimePackDir">
<Value>$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.RuntimePackNativeDir">
<Value>$(MicrosoftNetCoreAppRuntimePackNativeDir)</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.RefPackDir">
<Value>$(MicrosoftNetCoreAppRefPackRefDir)</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.CoreCLRArtifactsDir">
<Value>$(CoreCLRArtifactsPath)</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.TargetArchitecture">
<Value>$(TargetArchitecture)</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.TargetOS">
<Value>$(TargetOS)</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.CoreCLRConfiguration">
<Value>$(CoreCLRConfiguration)</Value>
</RuntimeHostConfigurationOption>
</ItemGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="R2RTest.Crossgen2Dir">
<Value>@(Crossgen2InbuildOutputItems->WithMetadataValue('Filename', 'crossgen2')->WithMetadataValue('Extension', '$(ExeSuffix)')->'%(RootDir)%(Directory)')</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.RuntimePackDir">
<Value>$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.RuntimePackNativeDir">
<Value>$(MicrosoftNetCoreAppRuntimePackNativeDir)</Value>
</RuntimeHostConfigurationOption>

<RuntimeHostConfigurationOption Include="R2RTest.RequireWasmReferences">
<Value>$(RequireWasmReferences)</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.WasmRuntimePackDir">
<Value>$(WasmRuntimePackDir)</Value>
</RuntimeHostConfigurationOption>
<RuntimeHostConfigurationOption Include="R2RTest.WasmRuntimePackNativeDir">
<Value>$(WasmRuntimePackNativeDir)</Value>
</RuntimeHostConfigurationOption>

<!-- Used for gating Debug-only JIT features from being tested. -->
<RuntimeHostConfigurationOption Include="R2RTest.CoreCLRConfiguration">
<Value>$(CoreCLRConfiguration)</Value>
</RuntimeHostConfigurationOption>
</ItemGroup>

</Target>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,10 @@ public void WasmWebcilModule()
new(nameof(WasmWebcilModule), [new CrossgenAssembly(wasmWebcilModule)])
{
OutputFileExtension = ".wasm",
AdditionalArgs =
{
"--targetarch",
"wasm",
"--targetos",
"browser",
},
// Reference the real browser-wasm framework assemblies when they are available
// (e.g. the wasm tools-test job downloads them); otherwise the runner falls back
// to host references so this test still runs everywhere.
TargetRid = TargetRid.BrowserWasm,
Validate = Validate,
},
]));
Expand Down Expand Up @@ -153,7 +150,12 @@ static void Validate(ReadyToRunReader reader)
}
}

[Fact]
// Note: The arm tests compile for an arm32 target, but they are compiled with the host Corelib. If there are
// load-bearing dependencies in the arm32 corelib (that aren't present in the host corelib) that crossgen2 requires,
// these tests may fail. Wasm tests are similar, but since it doesn't require a special cross-build setup, they use
// a wasm corelib in CI. arm32 tests could be similarly set up, but it hasn't been done yet.

[ConditionalFact(typeof(TestPaths), nameof(TestPaths.ArmOnHostOSSupported))]
public void ArmThumbBitRelocationTargets()
{
var inlineableLib = new CompiledAssembly
Expand All @@ -177,7 +179,7 @@ public void ArmThumbBitRelocationTargets()
new CrossgenAssembly(inlineableLib) { Kind = Crossgen2InputKind.Reference },
])
{
Options = [Crossgen2Option.TargetArchArm],
TargetRid = TargetRid.HostArm,
Validate = Validate,
},
]));
Expand All @@ -190,7 +192,7 @@ static void Validate(ReadyToRunReader reader)
}

// JitStressProcedureSplitting is only available in Debug/Checked JIT builds.
[ConditionalFact(typeof(TestPaths), nameof(TestPaths.IsNotReleaseCoreCLR))]
[ConditionalFact(typeof(TestPaths), nameof(TestPaths.IsNotReleaseCoreCLR), nameof(TestPaths.ArmOnHostOSSupported))]
public void ArmThumbBitHotColdRuntimeFunctions()
{
var hotColdSplitting = new CompiledAssembly
Expand All @@ -204,9 +206,9 @@ public void ArmThumbBitHotColdRuntimeFunctions()
[
new(nameof(ArmThumbBitHotColdRuntimeFunctions), [new CrossgenAssembly(hotColdSplitting)])
{
TargetRid = TargetRid.HostArm,
Options =
[
Crossgen2Option.TargetArchArm,
Crossgen2Option.Optimize,
Crossgen2Option.HotColdSplitting,
],
Expand Down
Loading