[mono][tests] Parallel AOT compilation of runtime tests on iOS platforms (#86089)
authorMilos Kotlar <kotlarmilos@gmail.com>
Fri, 21 Jul 2023 15:56:47 +0000 (17:56 +0200)
committerGitHub <noreply@github.com>
Fri, 21 Jul 2023 15:56:47 +0000 (17:56 +0200)
The Helix payload is generated using the runtime pipeline. Then, the libraries pipeline is utilized to AOT compile and execute the tests on Helix. The build-runtime-tests-and-send-to-helix.yml is updated with the compileOnHelix parameter, which if set, uses the libraries/helix.yml template instead of the runtime send-to-helix-step.yml template. The runtime and libraries pipelines are updated to support AOT compilation of runtime tests on Helix.

12 files changed:
eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml
eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml
eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml
eng/testing/tests.ioslike.targets
eng/testing/tests.mobile.targets
eng/testing/tests.targets
src/mono/msbuild/apple/build/AppleBuild.props
src/mono/msbuild/apple/build/AppleBuild.targets
src/mono/msbuild/apple/data/ProxyProjectForAOTOnHelix.proj
src/tests/Directory.Build.targets
src/tests/build.proj
src/tests/issues.targets

index 396fd6e..93fef95 100644 (file)
@@ -27,6 +27,8 @@ parameters:
   enableMicrobuild: ''
   gatherAssetManifests: false
   shouldContinueOnError: false
+  compileOnHelix: false
+  interpreter: false
 
 steps:
   - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests.yml
@@ -72,49 +74,64 @@ steps:
           env:
             __MonoToolPrefix: aarch64-linux-gnu-
 
-  #  Send tests to Helix
-  - template: /eng/pipelines/common/templates/runtimes/send-to-helix-step.yml
-    parameters:
-      displayName: Send tests to Helix
-      buildConfig: $(buildConfigUpper)
-      archType: ${{ parameters.archType }}
-      osGroup: ${{ parameters.osGroup }}
-      osSubgroup: ${{ parameters.osSubgroup}}
-      coreClrRepoRoot: $(Build.SourcesDirectory)/src/coreclr
-      shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
-      runtimeFlavor: ${{ parameters.runtimeFlavor }}
-      runtimeVariant: ${{ parameters.runtimeVariant }}
+  # Checks the value of the compileOnHelix parameter
+  # and if set invokes libraries pipeline for AOT on Helix
+  - ${{ if eq(parameters.compileOnHelix, 'true') }}:
+    - template: /eng/pipelines/libraries/helix.yml
+      parameters:
+        osGroup: ${{ parameters.osGroup }}
+        runtimeFlavor: ${{ parameters.runtimeFlavor }}
+        archType: ${{ parameters.archType }}
+        targetRid: ${{ parameters.targetRid }}
+        buildConfig: ${{ parameters.buildConfig }}
+        interpreter: ${{ parameters.interpreter }}
+        testRunNamePrefixSuffix: ${{ parameters.testRunNamePrefixSuffix }}
+        extraHelixArguments: ${{ parameters.extraHelixArguments }}
+        helixQueues: ${{ parameters.helixQueues }}
+        creator: ${{ parameters.creator }}
+  - ${{ else }}:
+    - template: /eng/pipelines/common/templates/runtimes/send-to-helix-step.yml
+      parameters:
+        displayName: Send tests to Helix
+        buildConfig: $(buildConfigUpper)
+        archType: ${{ parameters.archType }}
+        osGroup: ${{ parameters.osGroup }}
+        osSubgroup: ${{ parameters.osSubgroup}}
+        coreClrRepoRoot: $(Build.SourcesDirectory)/src/coreclr
+        shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
+        runtimeFlavor: ${{ parameters.runtimeFlavor }}
+        runtimeVariant: ${{ parameters.runtimeVariant }}
 
-      ${{ if eq(variables['System.TeamProject'], 'public') }}:
-        creator: $(Build.DefinitionName)
+        ${{ if eq(variables['System.TeamProject'], 'public') }}:
+          creator: $(Build.DefinitionName)
 
-        helixBuild: $(Build.BuildNumber)
-        helixSource: $(_HelixSource)
+          helixBuild: $(Build.BuildNumber)
+          helixSource: $(_HelixSource)
 
-        ${{ if ne(parameters.readyToRun, true) }}:
-          helixType: 'test/functional/cli/'
+          ${{ if ne(parameters.readyToRun, true) }}:
+            helixType: 'test/functional/cli/'
 
-        helixQueues: ${{ parameters.helixQueues }}
+          helixQueues: ${{ parameters.helixQueues }}
 
-        # This tests whether an array is empty
-        ${{ if eq(join('', parameters.helixQueues), '') }}:
-          condition: false
+          # This tests whether an array is empty
+          ${{ if eq(join('', parameters.helixQueues), '') }}:
+            condition: false
 
-        publishTestResults: true
+          publishTestResults: true
 
-        timeoutPerTestInMinutes: $(timeoutPerTestInMinutes)
-        timeoutPerTestCollectionInMinutes: $(timeoutPerTestCollectionInMinutes)
+          timeoutPerTestInMinutes: $(timeoutPerTestInMinutes)
+          timeoutPerTestCollectionInMinutes: $(timeoutPerTestCollectionInMinutes)
 
-        runCrossGen2: ${{ eq(parameters.readyToRun, true) }}
-        compositeBuildMode: ${{ parameters.compositeBuildMode }}
-        runInUnloadableContext: ${{ parameters.runInUnloadableContext }}
-        nativeAotTest: ${{ parameters.nativeAotTest }}
+          runCrossGen2: ${{ eq(parameters.readyToRun, true) }}
+          compositeBuildMode: ${{ parameters.compositeBuildMode }}
+          runInUnloadableContext: ${{ parameters.runInUnloadableContext }}
+          nativeAotTest: ${{ parameters.nativeAotTest }}
 
-        ${{ if eq(variables['System.TeamProject'], 'internal') }}:
-          # Access token variable for internal project from the
-          # DotNet-HelixApi-Access variable group
-          helixAccessToken: $(HelixApiAccessToken)
+          ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+            # Access token variable for internal project from the
+            # DotNet-HelixApi-Access variable group
+            helixAccessToken: $(HelixApiAccessToken)
 
-        helixProjectArguments: '$(Build.SourcesDirectory)/src/tests/Common/helixpublishwitharcade.proj'
+          helixProjectArguments: '$(Build.SourcesDirectory)/src/tests/Common/helixpublishwitharcade.proj'
 
-        scenarios: ${{ parameters.scenarios }}
+          scenarios: ${{ parameters.scenarios }}
index bc30978..db25975 100644 (file)
@@ -45,7 +45,8 @@ jobs:
         extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true
 
 #
-# Build the whole product using Mono for iOS/tvOS and run runtime tests with iOS/tvOS devices
+# iOS/tvOS devices
+# Build the whole product using Mono and run runtime tests
 #
 - template: /eng/pipelines/common/platform-matrix.yml
   parameters:
@@ -82,9 +83,11 @@ jobs:
       extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml
       extraStepsParameters:
         creator: dotnet-bot
-        # FIXME: Currently, tracing/eventpipe tests are only enabled on iOS platforms. It should be expanded to include all runtime tests. Tracking issue: https://github.com/dotnet/runtime/issues/84254
-        testBuildArgs: tree tracing/eventpipe
+        compileOnHelix: true
+        interpreter: true
+        testBuildArgs: /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildTestsOnHelix=true
         testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+        extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true
 
 #
 # Build the whole product using NativeAOT for iOS/tvOS and run runtime tests with iOS/tvOS devices
index d764397..357d5b8 100644 (file)
@@ -85,9 +85,11 @@ jobs:
       extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml
       extraStepsParameters:
         creator: dotnet-bot
-        # FIXME: Currently, tracing/eventpipe tests are only enabled on iOS platforms. It should be expanded to include all runtime tests. Tracking issue: https://github.com/dotnet/runtime/issues/84254
-        testBuildArgs: tree tracing/eventpipe
+        compileOnHelix: true
+        interpreter: true
+        testBuildArgs: /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildTestsOnHelix=true
         testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+        extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true
 
 #
 # Build the whole product using Native AOT for iOSSimulator/tvOSSimulator and run runtime tests with iOS/tvOS simulators
index 9054882..192e936 100644 (file)
     <_AOTBuildCommand>$(_AOTBuildCommand) </_AOTBuildCommand>
 
     <_ResetSimulatorSwitch Condition="'$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'tvossimulator'">--reset-simulator</_ResetSimulatorSwitch>
-    <_SignalAppEndSwitch Condition="'$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvos'">--signal-app-end</_SignalAppEndSwitch>
+    <_SignalAppEndSwitch>--signal-app-end</_SignalAppEndSwitch>
+    <_AppleSignCommand Condition="'$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvos'">sign &quot;$app&quot;</_AppleSignCommand>
 
     <_AfterBuildCommands>
       mv $XHARNESS_OUT/AOTBuild.binlog &quot;$HELIX_WORKITEM_UPLOAD_ROOT&quot;
-      sign &quot;$app&quot;
+      $(_AppleSignCommand)
       xharness apple test --app &quot;$app&quot; --output-directory &quot;$output_directory&quot; --target &quot;$target&quot; --timeout &quot;$timeout&quot; --xcode &quot;$xcode_path&quot; -v --launch-timeout &quot;$launch_timeout&quot; $(_ResetSimulatorSwitch) $(_SignalAppEndSwitch) -- </_AfterBuildCommands>
 
     <RunScriptCommand>$(_AOTBuildCommand) $(_AfterBuildCommands)</RunScriptCommand>
     </PropertyGroup>
 
     <ItemGroup>
-      <BundleFiles Condition="'%(AppleAssembliesToBundle._IsNative)' != 'true'"
-                   Include="@(AppleAssembliesToBundle)"         TargetDir="publish\%(AppleAssembliesToBundle.RecursiveDir)" />
-      <BundleFiles Include="@(AppleNativeFilesToBundle)"        TargetDir="publish\%(AppleNativeFilesToBundle.RecursiveDir)" />
-      <BundleFiles Include="$(RuntimeConfigFilePath)"           TargetDir="publish" />
+      <!-- 
+        Checks if the directory name "AppleAssembliesToBundle" is equal to the "AssemblyName",
+        if they match, consider it as the root directory and copy the files there,
+        otherwise, copy the files to a subdirectory.
+      -->
+      <BundleFiles Condition="'%(AppleAssembliesToBundle._IsNative)' != 'true' and ($([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName('%(AppleAssembliesToBundle.Identity)')))) == '$(AssemblyName)' or '$(IsRuntimeTests)' != 'true')"
+              Include="@(AppleAssembliesToBundle)"                    TargetDir="publish" />
+      <BundleFiles Condition="'%(AppleAssembliesToBundle._IsNative)' != 'true' and $([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName('%(AppleAssembliesToBundle.Identity)')))) != '$(AssemblyName)' and  '$(IsRuntimeTests)' == 'true'"
+                   Include="@(AppleAssembliesToBundle)"               TargetDir="publish\$([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName('%(AppleAssembliesToBundle.Identity)'))))" />
+
+      <BundleFiles Include="@(AppleNativeFilesToBundle)"              TargetDir="publish" />
 
-      <BundleFiles Include="$(MonoProjectRoot)\msbuild\apple\data\*" TargetDir="publish" />
+      <BundleFiles Include="$(MonoProjectRoot)\msbuild\apple\data\*"  TargetDir="publish" />
       <ExtraFiles Condition="'%(AppleAssembliesToBundle._IsNative)' == 'true'"
-                  Include="@(AppleAssembliesToBundle)"          TargetDir="extraFiles\%(AppleAssembliesToBundle.RecursiveDir)" />
+                  Include="@(AppleAssembliesToBundle)"                TargetDir="extraFiles" />
     </ItemGroup>
 
     <ItemGroup Condition="'$(DebuggerSupport)' == 'true'">
       <_ApplePropertyNames Include="HybridGlobalization" />
       <_ApplePropertyNames Include="AssemblyName" />
       <_ApplePropertyNames Include="MonoEnableLLVM" />
+      <_ApplePropertyNames Include="UseRuntimeComponents" />
+      <_ApplePropertyNames Include="IsRuntimeTests" />
 
       <_ApplePropertiesToPass
         Include="$(%(_ApplePropertyNames.Identity))"
 
     <PropertyGroup>
       <Optimized Condition="'$(Configuration)' == 'Release'">true</Optimized>
-      <MainLibraryFileName Condition="'$(MainLibraryFileName)' == ''">AppleTestRunner.dll</MainLibraryFileName>
+      <MainLibraryFileName Condition="'$(MainLibraryFileName)' == '' and '$(IsRuntimeTests)' != 'true'">AppleTestRunner.dll</MainLibraryFileName>
     
       <AppleBuildDir>$(PublishDir)</AppleBuildDir>
       <AppleBundleDir>$(BundleDir)</AppleBundleDir>
index b150d2b..2770c97 100644 (file)
@@ -8,7 +8,8 @@
     <RunScriptOutputPath>$([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)'))</RunScriptOutputPath>
 
     <PublishingTestsRun>true</PublishingTestsRun>
-    <PublishTestAsSelfContainedDependsOn>Publish</PublishTestAsSelfContainedDependsOn>
+    <PublishTestAsSelfContainedDependsOn Condition="'$(PublishTestAsSelfContainedDependsOn)' == ''">Publish</PublishTestAsSelfContainedDependsOn>
+    <PublishTestAsSelfContainedAfterTargets Condition="'$(PublishTestAsSelfContainedAfterTargets)' == ''">Build</PublishTestAsSelfContainedAfterTargets>
 
     <SkipWorkloadsTestingTargetsImport Condition="'$(SkipWorkloadsTestingTargetsImport)' == ''">true</SkipWorkloadsTestingTargetsImport>
   </PropertyGroup>
 
   <Target Name="PublishTestAsSelfContained"
           Condition="'$(IsCrossTargetingBuild)' != 'true'"
-          AfterTargets="Build"
+          AfterTargets="$(PublishTestAsSelfContainedAfterTargets)"
           DependsOnTargets="$(PublishTestAsSelfContainedDependsOn);$(BundleTestAppTargets);ArchiveTests" />
 
   <Target Name="PrepareForTestUsingWorkloads"
index 1677d0f..f4bf46c 100644 (file)
       <RunScriptCommands Include="@(PostRunScriptCommands)" />
     </ItemGroup>
 
+    <PropertyGroup Condition="'$(RunScriptOutputDirectory)' != ''">
+      <RunScriptOutputPath>$([MSBuild]::NormalizePath('$(RunScriptOutputDirectory)', '$(RunScriptOutputName)'))</RunScriptOutputPath>
+    </PropertyGroup>
+
     <GenerateRunScript RunCommands="@(RunScriptCommands)"
                        SetCommands="@(SetScriptCommands)"
                        TemplatePath="$(RunScriptInputPath)"
index 046c341..75426eb 100644 (file)
@@ -2,7 +2,6 @@
   <!-- iOS/tvOS device + arm64 simulators need to AOT -->
   <PropertyGroup Condition="'$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvos' or (('$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'tvossimulator') And '$(TargetArchitecture)' == 'arm64')">
     <RunAOTCompilation Condition="'$(RunAOTCompilation)' == ''">true</RunAOTCompilation>
-    <iOSLikeDedup Condition="'$(iOSLikeDedup)' == ''">true</iOSLikeDedup>
   </PropertyGroup>
 
   <!-- iOS/tvOS arm64 simulators do not support JIT, so force interpreter fallback, devices should FullAOT -->
@@ -11,6 +10,7 @@
   </PropertyGroup>
 
   <PropertyGroup>
+    <iOSLikeDedup Condition="'$(iOSLikeDedup)' == '' and '$(RunAOTCompilation)' == 'true' and '$(MonoForceInterpreter)' != 'true'">true</iOSLikeDedup>
     <RuntimeIdentifier>$(TargetOS)-$(TargetArchitecture.ToLowerInvariant())</RuntimeIdentifier>
     <UseMonoRuntime>true</UseMonoRuntime>
     <UseMonoJustInterp Condition="'$(RunAOTCompilation)' == 'true' and '$(MonoForceInterpreter)' == 'true'">true</UseMonoJustInterp>
index f2efa7f..d2e8520 100644 (file)
 
     <ItemGroup>
       <_AotExcludeAssemblies Include="*System.Runtime.WindowsRuntime.dll" />
+      <_AssembliesToBundleInternal>
+        <_InternalForceInterpret Condition="'$(MonoForceInterpreter)' == 'true' and '%(FileName)%(Extension)' != 'System.Private.CoreLib.dll'">true</_InternalForceInterpret>
+        <_IsNative>false</_IsNative>
+      </_AssembliesToBundleInternal>
 
       <_AotInputAssemblies Include="@(_AssembliesToBundleInternal)" 
                            Condition="'%(_AssembliesToBundleInternal._InternalForceInterpret)' != 'true'">
index 8666057..6c166f7 100644 (file)
       <AppleBuildDir>$(OriginalPublishDir)</AppleBuildDir>
       <AppleBundleDir>$(TestRootDir)AppBundle\</AppleBundleDir>
 
-      <MainLibraryFileName>$(OriginalPublishDir)AppleTestRunner.dll</MainLibraryFileName>
+      <MainLibraryFileName Condition="'$(MainLibraryFileName)' == '' and '$(IsRuntimeTests)' != 'true'">$(OriginalPublishDir)AppleTestRunner.dll</MainLibraryFileName>
       <Optimized Condition="'$(Configuration)' != 'Debug'">true</Optimized>
     </PropertyGroup>
 
+    <PropertyGroup Condition="'$(UseRuntimeComponents)' == 'true'">
+      <RuntimeComponents>diagnostics_tracing;marshal-ilgen</RuntimeComponents>
+      <DiagnosticPorts>127.0.0.1:9000,nosuspend,listen</DiagnosticPorts>
+    </PropertyGroup>
+
     <ItemGroup>
       <!-- Figure out if we can support JustInterp mode -->
       <AppleAssembliesToBundle Include="$(OriginalPublishDir)**\*.dll" Exclude="$(OriginalPublishDir)\**\*.resources.dll" />
index fe92291..c8b7799 100644 (file)
@@ -9,6 +9,29 @@
   <Import Project="$(MSBuildThisFileDirectory)/Common/disableversioncheck.targets"
           Condition="'$(DisableVersionCheckImported)' != 'true'" />
 
+  <PropertyGroup Condition="'$(TargetsAppleMobile)' == 'true' and '$(RuntimeFlavor)' == 'mono'">
+    <OSPlatformConfig>$(TargetOS).AnyCPU.$(Configuration)</OSPlatformConfig>
+    <TestArchiveRoot>$(ArtifactsDir)helix/</TestArchiveRoot>
+    <TestArchiveTestsRoot>$(TestArchiveRoot)tests/</TestArchiveTestsRoot>
+    <TestArchiveTestsDir>$(TestArchiveTestsRoot)$(OSPlatformConfig)/</TestArchiveTestsDir>
+    <TestArchiveRuntimeRoot>$(TestArchiveRoot)runtime/</TestArchiveRuntimeRoot>
+
+    <PublishTestAsSelfContainedDependsOn>BuildMonoiOSApp</PublishTestAsSelfContainedDependsOn>
+    <PublishTestAsSelfContainedAfterTargets>BuildMonoiOSApp</PublishTestAsSelfContainedAfterTargets>
+    <BundleTestAppleAppDependsOn>GenerateRunScript</BundleTestAppleAppDependsOn>
+
+    <IsRuntimeTests>true</IsRuntimeTests>
+  </PropertyGroup>
+
+  <Import Project="$(RepositoryEngineeringDir)testing\tests.targets"
+          Condition="'$(TargetsAppleMobile)' == 'true' and '$(RuntimeFlavor)' == 'mono'" />
+
+  <Target Name="_SetRunScriptOutputDirectory" Condition="'$(TargetsAppleMobile)' == 'true' and '$(RuntimeFlavor)' == 'mono' and '$(IsRuntimeTests)' == 'true'" BeforeTargets="GenerateRunScript">
+    <PropertyGroup>
+      <RunScriptOutputDirectory>$(ArtifactsDir)/tests/coreclr/obj/$(TargetOS).$(Platform).$(Configuration)/Managed/build/iOSApps/$(TestProjectName)/AppBundle</RunScriptOutputDirectory>
+    </PropertyGroup>
+  </Target>
+
   <!-- Default priority building values. -->
   <PropertyGroup>
     <DisableProjectBuild Condition="'$(IsMergedTestRunnerAssembly)' == 'true' and $(BuildAsStandalone)">true</DisableProjectBuild>
 
      <!-- There are currently no native project binaries on wasm or Android -->
      <Error  Text="The native project files are missing in $(NativeProjectOutputFolder) please run build from the root of the repo at least once"
-             Condition="'@(NativeProjectBinaries)' == '' And '$(TargetOS)' != 'browser' And '$(TargetOS)' != 'android' And '$(TargetOS)' != 'ios' And '$(TargetOS)' != 'iossimulator'"/>
+             Condition="'@(NativeProjectBinaries)' == '' And '$(TargetOS)' != 'browser' And '$(TargetsMobile)' != 'true'"/>
 
      <Copy
         SourceFiles="@(NativeProjectBinaries)"
index af5f69c..e20d07c 100644 (file)
       <XUnitWrapperDll>$(CMDDIR_GrandParent)/$(CategoryWithSlash)/$(XUnitWrapperFileName)</XUnitWrapperDll>
       <BuildDir>$(IntermediateOutputPath)\iOSApps\$(Category)</BuildDir>
       <FinalPath>$(XUnitTestBinBase)$(CategoryWithSlash)\$(Category).app</FinalPath>
-      <RuntimeComponents>diagnostics_tracing;marshal-ilgen</RuntimeComponents>
-      <DiagnosticPorts>127.0.0.1:9000,nosuspend,listen</DiagnosticPorts>
-      <RunAOTCompilation>True</RunAOTCompilation>
+      <_MobileIntermediateOutputPath>$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'mobile'))</_MobileIntermediateOutputPath>
     </PropertyGroup>
 
     <PropertyGroup>
       <RuntimePackOSSuffix Condition="'$(TargetOS)' == 'ios'" >ios</RuntimePackOSSuffix>
       <RuntimePackOSSuffix Condition="'$(TargetOS)' == 'tvossimulator'" >tvossimulator</RuntimePackOSSuffix>
       <RuntimePackOSSuffix Condition="'$(TargetOS)' == 'tvos'" >tvos</RuntimePackOSSuffix>
+      <RuntimePackOSSuffix Condition="'$(TargetOS)' == 'maccatalyst'" >maccatalyst</RuntimePackOSSuffix>
+
       <MicrosoftNetCoreAppRuntimePackDir>$(ArtifactsBinDir)microsoft.netcore.app.runtime.$(RuntimePackOSSuffix)-$(TargetArchitecture)/$(Configuration)/runtimes/$(RuntimePackOSSuffix)-$(TargetArchitecture)</MicrosoftNetCoreAppRuntimePackDir>
       <MicrosoftNetCoreAppRuntimePackNativeDir>$(MicrosoftNetCoreAppRuntimePackDir)/native</MicrosoftNetCoreAppRuntimePackNativeDir>
-    </PropertyGroup>
 
-    <PropertyGroup>
-      <!-- FIXME: Currently, tracing/eventpipe tests only work with the Mono Interpreter. Mono interpreter should be only enabled for simulator targets. -->
-      <MonoForceInterpreter>True</MonoForceInterpreter>
+      <BundleDir>$([MSBuild]::NormalizeDirectory('$(BuildDir)', 'AppBundle'))</BundleDir>
     </PropertyGroup>
     <ItemGroup>
       <AllTestScripts Include="$(_CMDDIR)\**\*.sh" Exclude="$(_CMDDIR)\**\AppBundle\*.sh" />
-    </ItemGroup>
-    <ItemGroup>
       <TestExclusions Include="@(ExcludeList->Metadata('FullPath'))" Condition="$(HaveExcludes)" />
       <TestScripts Include="@(AllTestScripts)" Exclude="@(TestExclusions)" />
       <TestDllPaths Include="$([System.IO.Path]::ChangeExtension('%(TestScripts.Identity)', 'dll'))" />
       <TestDlls Include="%(TestDllPaths.Identity)" Condition="Exists(%(TestDllPaths.Identity))" />
-      <AssembliesInTestDirs Include="%(AllCMDsPresent.RelativeDir)*.dll" Exclude="@(TestAssemblies)"/>
       <RuntimePackLibs Include="$(MicrosoftNetCoreAppRuntimePackDir)lib/**/*.dll" />
-      <TestTargetingPathLibs Include="$(TargetingPackPath)/*.dll" />
-    </ItemGroup>
-    <ItemGroup>
+      <RuntimePackNativeLibs Include="$(MicrosoftNetCoreAppRuntimePackDir)/**/*.dll;$(MicrosoftNetCoreAppRuntimePackDir)/native/**/*.a;$(MicrosoftNetCoreAppRuntimePackDir)/native/**/*.dylib;$(MicrosoftNetCoreAppRuntimePackDir)/native/icudt.dat" />
+      <EntryPoints Include="testdir-%(TestDlls.Filename)/%(TestDlls.Filename).dll" />
       <ExtraDlls Include="%(TestDlls.RelativeDir)*.dll" Exclude="@(TestDlls)">
         <TestDllFilename>@(TestDlls->'%(Filename)')</TestDllFilename>
       </ExtraDlls>
-    </ItemGroup>
-    <PropertyGroup>
-      <BundleDir>$([MSBuild]::NormalizeDirectory('$(BuildDir)', 'AppBundle'))</BundleDir>
-    </PropertyGroup>
-    <ItemGroup>
-      <RuntimePackNativeLibs Include="$(MicrosoftNetCoreAppRuntimePackDir)/**/*.dll;$(MicrosoftNetCoreAppRuntimePackDir)/native/**/*.a;$(MicrosoftNetCoreAppRuntimePackDir)/native/**/*.dylib" />
+      <TestTargetingPathLibs Include="$(TargetingPackPath)/*.dll" />
     </ItemGroup>
 
     <RemoveDir Directories="$(BundleDir)" />
     <Copy
         SourceFiles="@(RuntimePackLibs)"
         DestinationFolder="$(BuildDir)" />
-
     <Copy
         SourceFiles="@(TestTargetingPathLibs)"
         DestinationFolder="$(BuildDir)" />
         SourceFiles="%(ExtraDlls.Identity)"
         DestinationFolder="$(BuildDir)/testdir-%(ExtraDlls.TestDllFilename)" />
 
-    <ItemGroup>
-      <MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm64' and '$(TargetOS)' != 'MacCatalyst'" Include="mtriple=arm64-ios" />
-      <MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm64' and '$(TargetOS)' == 'MacCatalyst'" Include="mtriple=arm64-apple-ios14.2-macabi" />
-      <MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm'" Include="mtriple=armv7-ios" />
-      <MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'x64' and '$(TargetOS)' != 'MacCatalyst'" Include="mtriple=x86_64-ios" />
-      <MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'x64' and '$(TargetOS)' == 'MacCatalyst'" Include="mtriple=x86_64-apple-ios13.5-macabi" />
-      <MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'x86'" Include="mtriple=i386-ios" />
-      <MonoAOTCompilerDefaultAotArguments Include="static" />
-      <MonoAOTCompilerDefaultAotArguments Include="dwarfdebug" />
-      <MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm'" Include="mattr=+crc" /> <!-- enable System.Runtime.Intrinsics.Arm (Crc32 and ArmBase for now) -->
-      <MonoAOTCompilerDefaultAotArguments Include="direct-icalls" />
-
-      <MonoAOTCompilerDefaultAotArguments Include="nimt-trampolines=2000" />
-      <MonoAOTCompilerDefaultAotArguments Include="ntrampolines=40000" />
-      <MonoAOTCompilerDefaultAotArguments Include="nrgctx-fetch-trampolines=256" />
-      <MonoAOTCompilerDefaultAotArguments Include="ngsharedvt-trampolines=4400" />
-      <MonoAOTCompilerDefaultAotArguments Include="nftnptr-arg-trampolines=4000" />
-      <MonoAOTCompilerDefaultAotArguments Include="nrgctx-trampolines=40000" />
-
-      <MonoAOTCompilerDefaultProcessArguments Include="-O=gsharedvt" />
-    </ItemGroup>
-
-    <PropertyGroup>
-      <_AOTMode Condition="'$(MonoForceInterpreter)' != 'true'">Full</_AOTMode>
-      <_AOTMode Condition="'$(MonoForceInterpreter)' == 'true'">JustInterp</_AOTMode>
-      <AotArguments>@(MonoAOTCompilerDefaultAotArguments, ';')</AotArguments>
-      <ProcessArguments>@(MonoAOTCompilerDefaultProcessArguments, ';')</ProcessArguments>
-      <_MobileIntermediateOutputPath>$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'mobile'))</_MobileIntermediateOutputPath>
-    </PropertyGroup>
-
-    <ItemGroup>
-        <_AppleAssembliesInternal Include="$(BuildDir)/**/*.dll" />
-
-        <_AppleAssembliesInternal>
-            <_InternalForceInterpret Condition="'$(MonoForceInterpreter)' == 'true' and '%(FileName)%(Extension)' != 'System.Private.CoreLib.dll'">true</_InternalForceInterpret>
-            <_IsNative>false</_IsNative>
-        </_AppleAssembliesInternal>
-
-        <_AotInputAssemblies Include="@(_AppleAssembliesInternal)"
-                            Condition="'%(_AppleAssembliesInternal._InternalForceInterpret)' != 'true'">
-            <AotArguments>$(AotArguments)</AotArguments>
-            <ProcessArguments>$(ProcessArguments)</ProcessArguments>
-        </_AotInputAssemblies>
-
-        <_AOT_InternalForceInterpretAssemblies Include="@(_AppleAssembliesInternal->WithMetadataValue('_InternalForceInterpret', 'true'))" />
-        <_AppleAssembliesInternal Remove="@(_AppleAssembliesInternal)" />
-    </ItemGroup>
-
     <MakeDir Directories="$(_MobileIntermediateOutputPath)" />
 
-    <PropertyGroup Condition="'$(RuntimeFlavor)' == 'Mono'">
-      <_MonoAotCrossCompilerPath>$([MSBuild]::NormalizePath($(MonoAotCrossDir), 'mono-aot-cross'))</_MonoAotCrossCompilerPath>
-      <_MonoAotCrossCompilerPath Condition="$([MSBuild]::IsOSPlatform('WINDOWS'))">$(_MonoAotCrossCompilerPath).exe</_MonoAotCrossCompilerPath>
-      <DevTeamProvisioning>-</DevTeamProvisioning>
+    <PropertyGroup>
+      <PublishDir>$(BuildDir)/</PublishDir>
+      <TestProjectName>$(AssemblyName)</TestProjectName>
+      <IgnoreForCI Condition="@(TestDlls->Count()) == 0">true</IgnoreForCI>
+      <UseRuntimeComponents>true</UseRuntimeComponents>
     </PropertyGroup>
-    <ItemGroup Condition="'$(RuntimeFlavor)' == 'Mono'">
-      <MonoAotCrossCompiler Include="$(_MonoAotCrossCompilerPath)" RuntimeIdentifier="$(TargetOS.ToLowerInvariant())-$(TargetArchitecture.ToLowerInvariant())" />
-    </ItemGroup>
-
-    <RemoveDuplicates
-        Inputs="@(_AotInputAssemblies)">
-        <Output
-            TaskParameter="Filtered"
-            ItemName="_AotInputAssembliesDedup"/>
-    </RemoveDuplicates>
-    <Message Text="RunAOTCompilation $(RunAOTCompilation)" Importance="High"/>
-    <MonoAOTCompiler Condition="'$(RunAOTCompilation)' == 'true'"
-        CompilerBinaryPath="@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','$(TargetOS.ToLowerInvariant())-$(TargetArchitecture.ToLowerInvariant())'))"
-        OutputDir="$(_MobileIntermediateOutputPath)"
-        Mode="$(_AOTMode)"
-        OutputType="AsmOnly"
-        Assemblies="@(_AotInputAssembliesDedup)"
-        AotModulesTablePath="$(BundleDir)\modules.m"
-        AotModulesTableLanguage="ObjC"
-        IntermediateOutputPath="$(_MobileIntermediateOutputPath)"
-        AdditionalAssemblySearchPaths="$(CORE_ROOT)">
-        <Output TaskParameter="CompiledAssemblies" ItemName="_AppleAssembliesInternal" />
-    </MonoAOTCompiler>
-
-    <ItemGroup>
-      <_AppleAssembliesInternal Include="@(_AOT_InternalForceInterpretAssemblies)" />
-    </ItemGroup>
-
-    <RemoveDuplicates
-        Inputs="@(_AppleAssembliesInternal)">
-        <Output
-            TaskParameter="Filtered"
-            ItemName="_AppleAssembliesInternalDedup"/>
-    </RemoveDuplicates>
 
-    <AppleAppBuilderTask
-        TargetOS="$(TargetOS)"
-        ProjectName="$(AssemblyName)"
-        AppDir="$(BuildDir)"
-        MonoRuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackNativeDir)/include/mono-2.0"
-        Assemblies="@(_AppleAssembliesInternalDedup)"
-        Arch="$(TargetArchitecture)"
-        OutputDirectory="$(BundleDir)"
-        Optimized="True"
-        DevTeamProvisioning="$(DevTeamProvisioning)"
-        BuildAppBundle="True"
-        GenerateXcodeProject="True"
-        UseConsoleUITemplate="True"
-        ForceAOT="$(RunAOTCompilation)"
-        RuntimeComponents="$(RuntimeComponents)"
-        DiagnosticPorts="$(DiagnosticPorts)"
-        InvariantGlobalization="true"
-        ForceInterpreter="$(MonoForceInterpreter)"
-        EnableAppSandbox="$(EnableAppSandbox)">
-      <Output TaskParameter="AppBundlePath" PropertyName="AppBundlePath" />
-      <Output TaskParameter="XcodeProjectPath" PropertyName="XcodeProjectPath" />
-    </AppleAppBuilderTask>
-
-    <!-- Apparently MSBuild cannot move directories and recursively copying a
-         a directory requires writing some sort of recursive traversal
-         logic yourself. -->
-    <ItemGroup>
-      <RecursiveCopyHack Include="$(AppBundlePath)/**/*.*" />
-    </ItemGroup>
-    <MakeDir Directories="$(FinalPath)" />
-    <Copy SourceFiles="@(RecursiveCopyHack)" DestinationFolder="$(FinalPath)/%(RecursiveDir)" />
-    <RemoveDir Directories="$(AppBundlePath)" />
-    <Message Importance="High" Text="App: $(FinalPath)" />
+    <UpdateRunScriptToHandleMultipleEntryPoints EntryPoints="@(EntryPoints)" RunScriptCommand="$(RunScriptCommand)" AppName="$(Category)" Condition="'$(BuildTestsOnHelix)' == 'true'">
+      <Output TaskParameter="OutputScript" PropertyName="RunScriptCommand" />
+    </UpdateRunScriptToHandleMultipleEntryPoints>
   </Target>
 
+  <UsingTask
+    TaskName="UpdateRunScriptToHandleMultipleEntryPoints"
+    TaskFactory="RoslynCodeTaskFactory"
+    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
+  <ParameterGroup>
+    <EntryPoints ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
+    <RunScriptCommand ParameterType="System.String" Required="true" />
+    <AppName ParameterType="System.String" Required="true" />
+    <OutputScript ParameterType="System.String" Output="true" />
+  </ParameterGroup>
+  <Task>
+    <Using Namespace="System"/>
+    <Using Namespace="Microsoft.Build.Framework"/>
+    <Using Namespace="Microsoft.Build.Utilities"/>
+    <Using Namespace="System.Linq"/>
+    <Using Namespace="System.Text"/>
+
+    <!-- 
+      This code fragment updates the default run script for Helix. 
+      With the library tests, there is a single entry point provided as MainLibraryFileName. With the runtime tests, a bundle may have multiple main entry points. The code makes the following changes:
+      - For each main entry point, it adds the mlaunch environment parameter MONO_APPLE_APP_ENTRY_POINT_LIB_NAME
+      - After each execution, it renames the log file to match the MONO_APPLE_APP_ENTRY_POINT_LIB_NAME entry point
+     -->
+    <Code Type="Fragment" Language="cs">
+      <![CDATA[
+        string[] lines = RunScriptCommand.Split('\n');
+        string lastLine = lines[lines.Length - 1];
+        StringBuilder resultBuilder = new StringBuilder();
+
+        // Iterate over each entry point and modify the run script
+        foreach (ITaskItem item in EntryPoints)
+        {
+            string value = item.ItemSpec;
+            
+            // Add the MONO_APPLE_APP_ENTRY_POINT_LIB_NAME environment parameter to the run script
+            string output = lastLine.Replace("apple test", "apple run").Replace("--signal-app-end", $"--expected-exit-code=100 --set-env=MONO_APPLE_APP_ENTRY_POINT_LIB_NAME={value}") + "&& echo \"Test passed\" || { echo \"Test failed\"; exit 1; }";
+            resultBuilder.AppendLine(output);
+
+            // Rename the log file to match the MONO_APPLE_APP_ENTRY_POINT_LIB_NAME
+            resultBuilder.AppendLine("mv \"${output_directory}/net.dot."+AppName+".log\" \"${output_directory}/"+value.Split('/')[0]+".log\"");
+        }
+
+        StringBuilder outputScriptBuilder = new StringBuilder(string.Join("\n", lines.Take(lines.Length - 1)));
+        outputScriptBuilder.AppendLine();
+        outputScriptBuilder.Append(resultBuilder.ToString());
+
+        OutputScript = outputScriptBuilder.ToString();
+      ]]>
+    </Code>
+  </Task>
+</UsingTask>
 
   <!-- This target builds a Native AOT iOS App -->
   <Target Name="BuildNativeAOTiOSApp" DependsOnTargets="SetupOSSpecificProps">
index 2533601..b1d9c5a 100644 (file)
     </ItemGroup>
 
     <!-- Known failures for mono runtime on *all* architectures/operating systems in interpreter runtime mode -->
-    <ItemGroup Condition="'$(RuntimeFlavor)' == 'mono' and '$(RuntimeVariant)' == 'monointerpreter' ">
+    <ItemGroup Condition="('$(RuntimeFlavor)' == 'mono' and '$(RuntimeVariant)' == 'monointerpreter') or '$(TargetsAppleMobile)' == 'true'">
         <ExcludeList Include = "$(XunitTestBinBase)/JIT/jit64/opt/cse/HugeArray1/**">
             <Issue>https://github.com/dotnet/runtime/issues/46622</Issue>
         </ExcludeList>
         <!-- End interpreter issues -->
     </ItemGroup>
 
-    <ItemGroup Condition="'$(RuntimeFlavor)' == 'mono' and ('$(RuntimeVariant)' == 'llvmaot' or '$(TargetOS)' == 'ios')">
+    <ItemGroup Condition="'$(RuntimeFlavor)' == 'mono' and ('$(RuntimeVariant)' == 'llvmaot' or '$(TargetsAppleMobile)' == 'true')">
         <ExcludeList Include = "$(XunitTestBinBase)JIT/Methodical/ELEMENT_TYPE_IU/u_conv_r/**">
             <Issue>needs triage</Issue>
         </ExcludeList>
         </ExcludeList>
     </ItemGroup>
 
-    <ItemGroup Condition="'$(RuntimeFlavor)' == 'mono' and ('$(RuntimeVariant)' == 'llvmfullaot' or '$(TargetOS)' == 'ios')">
+    <ItemGroup Condition="'$(RuntimeFlavor)' == 'mono' and ('$(RuntimeVariant)' == 'llvmfullaot' or '$(TargetsAppleMobile)' == 'true')">
         <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/explicitlayout/objrefandnonobjrefoverlap/case1/**">
             <Issue>expected failure: overlapped structs fail at AOT compile time, not runtime</Issue>
         </ExcludeList>
         </ExcludeList>
     </ItemGroup>
 
-    <ItemGroup Condition="'$(RuntimeFlavor)' == 'mono' and ('$(RuntimeVariant)' == 'llvmfullaot' or '$(RuntimeVariant)' == 'llvmaot' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'tvossimulator')">
+    <ItemGroup Condition="'$(RuntimeFlavor)' == 'mono' and ('$(RuntimeVariant)' == 'llvmfullaot' or '$(RuntimeVariant)' == 'llvmaot' or '$(TargetsAppleMobile)' == 'true')">
         <ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/CLR-x86-JIT/V1.1-M1-Beta1/b143840/b143840/*">
             <Issue>https://github.com/dotnet/runtime/issues/48914</Issue>
         </ExcludeList>
     </ItemGroup>
 
 
-    <ItemGroup Condition=" '$(TargetArchitecture)' == 'wasm' " >
+    <ItemGroup Condition="'$(TargetArchitecture)' == 'wasm' or '$(TargetsAppleMobile)' == 'true'">
         <ExcludeList Include="$(XunitTestBinBase)/baseservices/finalization/CriticalFinalizer/**">
             <Issue>https://github.com/dotnet/runtime/issues/75756</Issue>
         </ExcludeList>
         <ExcludeList Include="$(XunitTestBinBase)/Loader/StartupHooks/**">
             <Issue>Loads an assembly from file</Issue>
         </ExcludeList>
+    </ItemGroup>
+
+    <ItemGroup Condition="'$(TargetArchitecture)' == 'wasm'">
         <ExcludeList Include = "$(XunitTestBinBase)/tracing/eventcounter/incrementingeventcounter/**">
             <Issue>System.Threading.Thread.UnsafeStart not supported</Issue>
         </ExcludeList>
         </ExcludeList>
     </ItemGroup>
 
-    <ItemGroup Condition="'$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios'" >
+    <ItemGroup Condition="'$(TargetsAppleMobile)' == 'true'" >
         <ExcludeList Include = "$(XunitTestBinBase)/Interop/PInvoke/Miscellaneous/MultipleAssembliesWithSamePInvoke/MAWSPITest/**">
             <Issue>missing assembly</Issue>
         </ExcludeList>
         <ExcludeList Include = "$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_r/**">
             <Issue>needs triage</Issue>
         </ExcludeList>
-    </ItemGroup>
-
-    <ItemGroup Condition="'$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'tvossimulator' or '$(TargetOS)' == 'iossimulator'" >
-        <ExcludeList Include="$(XunitTestBinBase)/tracing/eventpipe/rundownvalidation/**">
+        <ExcludeList Include = "$(XunitTestBinBase)/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_r/**">
             <Issue>needs triage</Issue>
         </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/tracing/eventpipe/buffersize/**">
+        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/StaticVirtualMethods/GenericContext/**">
+            <Issue>needs triage</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/GC/Regressions/v2.0-beta1/149926/149926/*">
             <Issue>needs triage</Issue>
         </ExcludeList>
     </ItemGroup>
 
-    <ItemGroup Condition=" '$(TargetArchitecture)' == 'wasm' or ('$(TargetOS)' == 'android' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios')">
+    <ItemGroup Condition="'$(TargetArchitecture)' == 'wasm' or '$(TargetsMobile)' == 'true'">
         <ExcludeList Include="$(XunitTestBinBase)/Interop/MonoAPI/**">
             <Issue>mobile and wasm don't support tests with native libraries.  wasm also needs static linking</Issue>
         </ExcludeList>
     </ItemGroup>
 
+    <ItemGroup Condition="'$(TargetOS)' == 'tvos'">
+        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/StaticVirtualMethods/RegressionTests/**">
+            <Issue>needs triage</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/explicitlayout/Regressions/empty/*">
+            <Issue>needs triage</Issue>
+        </ExcludeList>
+    </ItemGroup>
+
+    <ItemGroup Condition="'$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'tvossimulator'">
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/RyuJIT/**">
+            <Issue>needs triage</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/**">
+            <Issue>needs triage</Issue>
+        </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/Regressions/coreclr/**">
+            <Issue>needs triage</Issue>
+        </ExcludeList>
+    </ItemGroup>
+
     <Target Name="GetFilteredExcludeList" Returns="@(FilteredExcludeList)">
         <ItemGroup>
             <FilteredExcludeList