This adds support for setting per-project optimization flags, and sets them for these projects so they don't OOM.
Microsoft.Extensions.Logging.Generators.Roslyn3.11.Tests
Microsoft.Extensions.Logging.Generators.Roslyn4.0.Tests
System.Text.Json.SourceGeneration.Roslyn3.11.Unit.Tests
System.Text.Json.SourceGeneration.Roslyn4.0.Unit.Tests
System.Text.RegularExpressions.Generators.Tests
Some individual ones are disabled due to
#58226, and #60899 .
Additionally, if a AOT build fails, then on linux it dumps the last few lines from dmesg, to help identify it was an oom-kill.
Fixes #51961 .
Co-authored-by: Larry Ewing <lewing@microsoft.com>
--- /dev/null
+#!/usr/bin/env bash
+
+EXECUTION_DIR=$(dirname $0)
+SCENARIO=$3
+
+cd $EXECUTION_DIR
+
+if [ -z "$HELIX_WORKITEM_UPLOAD_ROOT" ]; then
+ XHARNESS_OUT="$EXECUTION_DIR/xharness-output"
+else
+ XHARNESS_OUT="$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output"
+fi
+
+if [ ! -z "$XHARNESS_CLI_PATH" ]; then
+ # When running in CI, we only have the .NET runtime available
+ # We need to call the XHarness CLI DLL directly via dotnet exec
+ HARNESS_RUNNER="dotnet exec $XHARNESS_CLI_PATH"
+else
+ HARNESS_RUNNER="dotnet xharness"
+fi
+
+if [ "$SCENARIO" == "WasmTestOnBrowser" ]; then
+ XHARNESS_COMMAND="test-browser"
+elif [ -z "$XHARNESS_COMMAND" ]; then
+ XHARNESS_COMMAND="test"
+fi
+
+function _buildAOTFunc()
+{
+ local projectFile=$1
+ local binLog=$2
+ shift 2
+
+ time dotnet msbuild $projectFile /bl:$binLog $*
+ local buildExitCode=$?
+
+ echo "\n** Performance summary for the build **\n"
+ dotnet msbuild $binLog -clp:PerformanceSummary -v:q -nologo
+ if [[ "$(uname -s)" == "Linux" && $buildExitCode -ne 0 ]]; then
+ echo "\nLast few messages from dmesg:\n"
+ dmesg | tail -n 20
+ fi
+
+ echo
+ echo
+
+ return $buildExitCode
+}
+
+# RunCommands defined in tests.mobile.targets
+[[RunCommands]]
+
+_exitCode=$?
+
+echo "XHarness artifacts: $XHARNESS_OUT"
+
+exit $_exitCode
<RunScriptInputName Condition="'$(BuildTestsOnHelix)' == 'true' and '$(TargetsAppleMobile)' == 'true'">AppleHelixRunnerTemplate.sh</RunScriptInputName>
<RunScriptInputName Condition="'$(BuildTestsOnHelix)' != 'true' and '$(TargetsAppleMobile)' == 'true'">AppleRunnerTemplate.sh</RunScriptInputName>
<RunScriptInputName Condition="'$(TargetOS)' == 'Android'">AndroidRunnerTemplate.sh</RunScriptInputName>
- <RunScriptInputName Condition="'$(TargetOS)' == 'Browser' and '$(OS)' != 'Windows_NT'">WasmRunnerTemplate.sh</RunScriptInputName>
+ <RunScriptInputName Condition="'$(TargetOS)' == 'Browser' and '$(OS)' != 'Windows_NT' and '$(BuildAOTTestsOnHelix)' == 'true'">WasmRunnerAOTTemplate.sh</RunScriptInputName>
+ <RunScriptInputName Condition="'$(TargetOS)' == 'Browser' and '$(OS)' != 'Windows_NT' and '$(BuildAOTTestsOnHelix)' != 'true'">WasmRunnerTemplate.sh</RunScriptInputName>
<RunScriptInputName Condition="'$(TargetOS)' == 'Browser' and '$(OS)' == 'Windows_NT'">WasmRunnerTemplate.cmd</RunScriptInputName>
</PropertyGroup>
</PropertyGroup>
<PropertyGroup Condition="'$(BuildAOTTestsOnHelix)' == 'true'">
- <_AOTBuildCommand>dotnet msbuild publish/ProxyProjectForAOTOnHelix.proj /bl:$XHARNESS_OUT/AOTBuild.binlog</_AOTBuildCommand>
+ <_AOTBuildCommand>_buildAOTFunc publish/ProxyProjectForAOTOnHelix.proj $XHARNESS_OUT/AOTBuild.binlog</_AOTBuildCommand>
<!-- running aot-helix tests locally, so we can test with the same project file as CI -->
<_AOTBuildCommand Condition="'$(ContinuousIntegrationBuild)' != 'true'">$(_AOTBuildCommand) /p:RuntimeSrcDir=$(RepoRoot) /p:RuntimeConfig=$(Configuration)</_AOTBuildCommand>
- <_AOTBuildCommand>$(_AOTBuildCommand) /p:RunAOTCompilation=$(RunAOTCompilation) /p:EmccLinkOptimizationFlag='-Oz -Wl%252C-O0 -Wl%252C-lto-O0'</_AOTBuildCommand>
+ <_AOTBuildCommand>$(_AOTBuildCommand) /p:RunAOTCompilation=$(RunAOTCompilation)</_AOTBuildCommand>
<_AOTBuildCommand>$(_AOTBuildCommand) && cd wasm_build/AppBundle</_AOTBuildCommand>
<RunScriptCommand Condition="'$(RunScriptCommand)' == ''">$(_AOTBuildCommand)</RunScriptCommand>
AssemblyFile="$(WasmBuildTasksAssemblyPath)" />
<Target Name="_BundleAOTTestWasmAppForHelix" DependsOnTargets="PrepareForWasmBuildApp">
+ <PropertyGroup Condition="'$(IsHighAotMemoryUsageTest)' == 'true' and '$(ContinuousIntegrationBuild)' == 'true'">
+ <DisableParallelEmccCompile Condition="'$(DisableParallelEmccCompile)' == ''">true</DisableParallelEmccCompile>
+ <EmccLinkOptimizationFlag Condition="'$(EmccLinkOptimizationFlag)' == ''">-O2</EmccLinkOptimizationFlag>
+ </PropertyGroup>
+
<PropertyGroup>
<_MainAssemblyPath Condition="'%(WasmAssembliesToBundle.FileName)' == $(AssemblyName) and '%(WasmAssembliesToBundle.Extension)' == '.dll'">%(WasmAssembliesToBundle.Identity)</_MainAssemblyPath>
<RuntimeConfigFilePath>$([System.IO.Path]::ChangeExtension($(_MainAssemblyPath), '.runtimeconfig.json'))</RuntimeConfigFilePath>
+ <EmccLinkOptimizationFlag Condition="'$(EmccLinkOptimizationFlag)' == ''">-Oz -Wl%252C-O0 -Wl%252C-lto-O0</EmccLinkOptimizationFlag>
</PropertyGroup>
<Error Text="Item WasmAssembliesToBundle is empty. This is likely an authoring error." Condition="@(WasmAssembliesToBundle->Count()) == 0" />
<!-- To recreate the original project on helix, we need to set the wasm properties also, same as the
library test project. Eg. $(InvariantGlobalization) -->
<ItemGroup>
- <_WasmPropertyNames Include="InvariantGlobalization" />
<_WasmPropertyNames Include="AOTMode" />
- <_WasmPropertyNames Include="WasmDebugLevel" />
+ <_WasmPropertyNames Include="AssemblyName" />
+ <_WasmPropertyNames Include="DisableParallelAot" />
+ <_WasmPropertyNames Include="DisableParallelEmccCompile" />
+ <_WasmPropertyNames Include="EmccCompileOptimizationFlag" />
+ <_WasmPropertyNames Include="EmccLinkOptimizationFlag" />
+ <_WasmPropertyNames Include="IncludeSatelliteAssembliesInVFS" />
+ <_WasmPropertyNames Include="InvariantGlobalization" />
<_WasmPropertyNames Include="WasmBuildNative" />
- <_WasmPropertyNames Include="_WasmDevel" />
- <_WasmPropertyNames Include="WasmLinkIcalls" />
+ <_WasmPropertyNames Include="WasmDebugLevel" />
<_WasmPropertyNames Include="WasmDedup" />
- <_WasmPropertyNames Include="IncludeSatelliteAssembliesInVFS" />
- <_WasmPropertyNames Include="AssemblyName" />
+ <_WasmPropertyNames Include="WasmLinkIcalls" />
+ <_WasmPropertyNames Include="WasmNativeStrip" />
+ <_WasmPropertyNames Include="_WasmDevel" />
<_WasmPropertiesToPass
Include="$(%(_WasmPropertyNames.Identity))"
<WasmDebugLevel Condition="'$(DebuggerSupport)' == 'true' and '$(WasmDebugLevel)' == ''">-1</WasmDebugLevel>
</PropertyGroup>
- <ItemGroup Condition="'$(IncludeSatelliteAssembliesInVFS)' == 'true'">
+ <ItemGroup Condition="'$(IncludeSatelliteAssembliesInVFS)' == 'true' and '$(BuildAOTTestsOnHelix)' != 'true'">
<_SatelliteAssemblies Include="$(PublishDir)*\*.resources.dll" />
<_SatelliteAssemblies CultureName="$([System.IO.Directory]::GetParent('%(Identity)').Name)" />
<_SatelliteAssemblies TargetPath="%(CultureName)\%(FileName)%(Extension)" />
<PropertyGroup>
<RoslynApiVersion>$(MicrosoftCodeAnalysisCSharpWorkspacesVersion_3_11)</RoslynApiVersion>
+ <IsHighAotMemoryUsageTest>true</IsHighAotMemoryUsageTest>
</PropertyGroup>
<Import Project="Microsoft.Extensions.Logging.Generators.targets"/>
<PropertyGroup>
<RoslynApiVersion>$(MicrosoftCodeAnalysisCSharpWorkspacesVersion)</RoslynApiVersion>
<DefineConstants>$(DefineConstants);ROSLYN4_0_OR_GREATER</DefineConstants>
+ <IsHighAotMemoryUsageTest>true</IsHighAotMemoryUsageTest>
+ <EmccLinkOptimizationFlag Condition="'$(ContinuousIntegrationBuild)' == 'true'">-O1</EmccLinkOptimizationFlag>
+ <WasmNativeStrip>false</WasmNativeStrip>
</PropertyGroup>
<Import Project="Microsoft.Extensions.Logging.Generators.targets"/>
}
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/58226", TestPlatforms.Browser)]
public void NameClashSourceGeneration()
{
// Without resolution.
}
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/58226", TestPlatforms.Browser)]
public void ProgramsThatDontUseGeneratorCompile()
{
// No STJ usage.
}
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/58226", TestPlatforms.Browser)]
public void WarnOnClassesWithInitOnlyProperties()
{
Compilation compilation = CompilationHelper.CreateCompilationWithInitOnlyProperties();
}
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/58226", TestPlatforms.Browser)]
public void WarnOnClassesWithInaccessibleJsonIncludeProperties()
{
Compilation compilation = CompilationHelper.CreateCompilationWithInaccessibleJsonIncludeProperties();
namespace System.Text.Json.SourceGeneration.UnitTests
{
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/58226", TestPlatforms.Browser)]
public class GeneratorTests
{
[Fact]
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RoslynApiVersion>$(MicrosoftCodeAnalysisCSharpWorkspacesVersion_3_11)</RoslynApiVersion>
+ <IsHighAotMemoryUsageTest>true</IsHighAotMemoryUsageTest>
</PropertyGroup>
<Import Project="System.Text.Json.SourceGeneration.Unit.Tests.targets" />
<PropertyGroup>
<RoslynApiVersion>$(MicrosoftCodeAnalysisCSharpWorkspacesVersion)</RoslynApiVersion>
<DefineConstants>$(DefineConstants);ROSLYN4_0_OR_GREATER</DefineConstants>
+ <IsHighAotMemoryUsageTest>true</IsHighAotMemoryUsageTest>
</PropertyGroup>
<Import Project="System.Text.Json.SourceGeneration.Unit.Tests.targets" />
public class TypeWrapperTests
{
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/58226", TestPlatforms.Browser)]
public void MetadataLoadFilePathHandle()
{
// Create a MetadataReference from new code.
}
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/58226", TestPlatforms.Browser)]
public void CanGetAttributes()
{
string source = @"
public static IEnumerable<object[]> Match_In_Different_Cultures_CriticalCases_TestData() =>
Match_In_Different_Cultures_CriticalCases_TestData_For(RegexOptions.None).Union(Match_In_Different_Cultures_CriticalCases_TestData_For(RegexOptions.Compiled));
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/60899", TestPlatforms.Browser)]
[Theory]
[MemberData(nameof(Match_In_Different_Cultures_TestData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/60697", TestPlatforms.iOS | TestPlatforms.tvOS)]
<Nullable>enable</Nullable>
<!-- xUnit2008 is about regexes and isn't appropriate in the test project for regexes -->
<NoWarn>$(NoWarn);xUnit2008</NoWarn>
+ <IsHighAotMemoryUsageTest>true</IsHighAotMemoryUsageTest>
</PropertyGroup>
<ItemGroup>
</PropertyGroup>
<ItemGroup Condition="'$(TargetOS)' == 'Browser' and '$(BuildAOTTestsOnHelix)' == 'true' and '$(RunDisabledWasmTests)' != 'true' and '$(RunAOTCompilation)' == 'true'">
- <!-- Exceeds VM resources in CI on compilation: https://github.com/dotnet/runtime/issues/51961 -->
- <ProjectExclusions Include="$(MSBuildThisFileDirectory)Microsoft.Extensions.Logging.Abstractions\tests\Microsoft.Extensions.Logging.Generators.Tests\Microsoft.Extensions.Logging.Generators.Roslyn3.11.Tests.csproj" />
- <ProjectExclusions Include="$(MSBuildThisFileDirectory)Microsoft.Extensions.Logging.Abstractions\tests\Microsoft.Extensions.Logging.Generators.Tests\Microsoft.Extensions.Logging.Generators.Roslyn4.0.Tests.csproj" />
</ItemGroup>
<!-- Projects that don't support code coverage measurement. -->
<!-- https://github.com/dotnet/runtime/issues/58226 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices\tests\DllImportGenerator.UnitTests\DllImportGenerator.Unit.Tests.csproj" />
- <ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Text.Json\tests\System.Text.Json.SourceGeneration.Unit.Tests\System.Text.Json.SourceGeneration.Roslyn3.11.Unit.Tests.csproj" />
- <ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Text.Json\tests\System.Text.Json.SourceGeneration.Unit.Tests\System.Text.Json.SourceGeneration.Roslyn4.0.Unit.Tests.csproj" />
-
- <!-- hhttps://github.com/dotnet/runtime/issues/60048 -->
- <ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Text.RegularExpressions\tests\System.Text.RegularExpressions.Tests.csproj" />
- <ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Text.RegularExpressions\tests\System.Text.RegularExpressions.Generators.Tests\System.Text.RegularExpressions.Generators.Tests.csproj" />
</ItemGroup>
<!-- Aggressive Trimming related failures -->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <WasmCopyAppZipToHelixTestDir Condition="'$(ArchiveTests)' == 'true'">true</WasmCopyAppZipToHelixTestDir>
+ <!-- don't need to run this on helix -->
+ <WasmCopyAppZipToHelixTestDir>false</WasmCopyAppZipToHelixTestDir>
<WasmMainJSPath>runtime.js</WasmMainJSPath>
</PropertyGroup>
<_WasmPInvokeTablePath>$(_WasmIntermediateOutputPath)pinvoke-table.h</_WasmPInvokeTablePath>
<_WasmPInvokeHPath>$(_WasmRuntimePackIncludeDir)wasm\pinvoke.h</_WasmPInvokeHPath>
<_DriverGenCPath>$(_WasmIntermediateOutputPath)driver-gen.c</_DriverGenCPath>
+ <DisableParallelAot Condition="'$(DisableParallelAot)' == ''">false</DisableParallelAot>
+ <DisableParallelEmccCompile Condition="'$(DisableParallelEmccCompile)' == ''">$(DisableParallelAot)</DisableParallelEmccCompile>
<_DriverGenCNeeded Condition="'$(_DriverGenCNeeded)' == '' and '$(_WasmShouldAOT)' == 'true'">true</_DriverGenCNeeded>
<!-- warm up the cache -->
<Exec Command="$(_EmBuilder) build MINIMAL" EnvironmentVariables="@(EmscriptenEnvVars)" StandardOutputImportance="Low" StandardErrorImportance="Low" />
- <Message Text="Compiling native assets with emcc. This may take a while ..." Importance="High" />
+ <Message Text="Compiling native assets with emcc with $(EmccCompileOptimizationFlag). This may take a while ..." Importance="High" />
<ItemGroup>
<_WasmSourceFileToCompile Remove="@(_WasmSourceFileToCompile)" />
<_WasmSourceFileToCompile Include="@(_WasmRuntimePackSrcFile)" Dependencies="%(_WasmRuntimePackSrcFile.Dependencies);$(_EmccDefaultFlagsRsp);$(_EmccCompileRsp)" />
SourceFiles="@(_WasmSourceFileToCompile)"
Arguments='"@$(_EmccDefaultFlagsRsp)" "@$(_EmccCompileRsp)"'
EnvironmentVariables="@(EmscriptenEnvVars)"
+ DisableParallelCompile="$(DisableParallelEmccCompile)"
OutputMessageImportance="$(_EmccCompileOutputMessageImportance)">
<Output TaskParameter="OutputFiles" ItemName="FileWrites" />
</EmccCompile>
<_BitCodeFile Dependencies="%(_BitCodeFile.Dependencies);$(_EmccDefaultFlagsRsp);$(_EmccCompileBitcodeRsp)" />
</ItemGroup>
- <Message Text="Compiling assembly bitcode files..." Importance="High" Condition="@(_BitCodeFile->Count()) > 0" />
+ <Message Text="Compiling assembly bitcode files with $(EmccLinkOptimizationFlag) ..." Importance="High" Condition="@(_BitCodeFile->Count()) > 0" />
<EmccCompile
SourceFiles="@(_BitCodeFile)"
Arguments=""@$(_EmccDefaultFlagsRsp)" "@$(_EmccCompileBitcodeRsp)""
EnvironmentVariables="@(EmscriptenEnvVars)"
+ DisableParallelCompile="$(DisableParallelEmccCompile)"
OutputMessageImportance="$(_EmccCompileOutputMessageImportance)">
<Output TaskParameter="OutputFiles" ItemName="FileWrites" />
</EmccCompile>
DependsOnTargets="_WasmSelectRuntimeComponentsForLinking;_WasmCompileAssemblyBitCodeFilesForAOT;_WasmWriteRspFilesForLinking"
Returns="@(FileWrites)" >
- <Message Text="Linking with emcc. This may take a while ..." Importance="High" />
+ <Message Text="Linking with emcc with $(EmccLinkOptimizationFlag). This may take a while ..." Importance="High" />
<Message Text="Running emcc with @(_EmccLinkStepArgs->'%(Identity)', ' ')" Importance="Low" />
<Exec Command='emcc "@$(_EmccDefaultFlagsRsp)" "@$(_EmccLinkRsp)"' EnvironmentVariables="@(EmscriptenEnvVars)" />
<ItemGroup>
new ParallelOptions { MaxDegreeOfParallelism = allowedParallelism },
(args, state) => PrecompileLibraryParallel(args, state));
- Log.LogMessage(MessageImportance.High, $"result: {result.IsCompleted}");
if (result.IsCompleted)
{
int numUnchanged = _totalNumAssemblies - _numCompiled;
using System;
using System.Collections.Generic;
+using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
Directory.CreateDirectory(supportFilesDir);
var i = 0;
+ StringDictionary targetPathTable = new();
foreach (var item in FilesToIncludeInFileSystem)
{
string? targetPath = item.GetMetadata("TargetPath");
// We normalize paths from `\` to `/` as MSBuild items could use `\`.
targetPath = targetPath.Replace('\\', '/');
+ if (targetPathTable.ContainsKey(targetPath))
+ {
+ string firstPath = Path.GetFullPath(targetPathTable[targetPath]!);
+ string secondPath = Path.GetFullPath(item.ItemSpec);
+
+ if (firstPath == secondPath)
+ {
+ Log.LogWarning($"Found identical vfs mappings for target path: {targetPath}, source file: {firstPath}. Ignoring.");
+ continue;
+ }
+
+ throw new LogAsErrorException($"Found more than one file mapping to the target VFS path: {targetPath}. Source files: {firstPath}, and {secondPath}");
+ }
+
+ targetPathTable[targetPath] = item.ItemSpec;
var generatedFileName = $"{i++}_{Path.GetFileName(item.ItemSpec)}";