From 95b697bd569eee4dadd5d31b729cb58690fef023 Mon Sep 17 00:00:00 2001 From: Drew Scoggins Date: Tue, 29 Sep 2026 16:58:15 -0700 Subject: [PATCH] =?UTF-8?q?Revert=20"Revert=20"Run=20CoreCLR=20microbenchm?= =?UTF-8?q?arks=20on=20macOS=2026=20Arm64=20M4=20(#5323)"=20(#5=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 56bcf79b8055fc86576715fb86e8a8b90ca8eab1. --- eng/pipelines/runtime-perf-jobs.yml | 24 ++++++++++++ scripts/dotnet.py | 5 ++- scripts/tests/test_dotnet.py | 60 ++++++++++++++++++++++++++++- 3 files changed, 85 insertions(+), 4 deletions(-) diff --git a/eng/pipelines/runtime-perf-jobs.yml b/eng/pipelines/runtime-perf-jobs.yml index e11969d2394..8c850e41361 100644 --- a/eng/pipelines/runtime-perf-jobs.yml +++ b/eng/pipelines/runtime-perf-jobs.yml @@ -66,6 +66,12 @@ parameters: enabled: true configs: - linux_arm64 + - name: m4Micro + type: object + default: + enabled: true + configs: + - osx_arm64 - name: cobaltMicroR2RInterpreter type: object default: @@ -324,6 +330,24 @@ jobs: ${{ each parameter in parameters.jobParameters }}: ${{ parameter.key }}: ${{ parameter.value }} + # CoreCLR Mac M4 microbenchmarks. Older runtime branches do not build macOS Arm64 artifacts. + - ${{ if and(eq(parameters.m4Micro.enabled, true), not(or(startswith(variables['Build.SourceBranch'], 'refs/heads/release/'), startswith(variables['Build.SourceBranch'], 'refs/heads/internal/release/')))) }}: + - template: /eng/pipelines/common/platform-matrix.yml@${{ parameters.runtimeRepoAlias }} + parameters: + jobTemplate: /eng/pipelines/templates/runtime-perf-job.yml@${{ parameters.performanceRepoAlias }} + buildConfig: release + runtimeFlavor: coreclr + platforms: ${{ parameters.m4Micro.configs }} + jobParameters: + liveLibrariesBuildConfig: Release + runKind: micro + queue: 'osx.26.arm64.m4.perf' + machinePool: 'M4' + runtimeRepoAlias: ${{ parameters.runtimeRepoAlias }} + performanceRepoAlias: ${{ parameters.performanceRepoAlias }} + ${{ each parameter in parameters.jobParameters }}: + ${{ parameter.key }}: ${{ parameter.value }} + # CoreCLR Cobalt microbenchmarks runtime-async experiment — controlled by cobaltMicroRuntimeAsync toggle. # Enables the runtime-async feature via the 'runtimeasync' experiment. # Excluded on release branches — the arm64 coreclr build doesn't exist in older runtime branches. diff --git a/scripts/dotnet.py b/scripts/dotnet.py index 10fe6582bd7..44bb0c8b48c 100755 --- a/scripts/dotnet.py +++ b/scripts/dotnet.py @@ -545,8 +545,9 @@ def __init__(self, project: CSharpProjFile, bin_directory: str): if not bin_directory: raise TypeError('bin folder cannot be null.') - self.__csproj_file = path.abspath(project.file_name) - self.__working_directory = path.abspath(project.working_directory) + # Mixed symlink and physical paths can drop transitive references during restore. + self.__csproj_file = path.realpath(project.file_name) + self.__working_directory = path.realpath(project.working_directory) self.__bin_directory = bin_directory if not path.isdir(self.__working_directory): diff --git a/scripts/tests/test_dotnet.py b/scripts/tests/test_dotnet.py index 64d959a75ae..3e623d38e61 100644 --- a/scripts/tests/test_dotnet.py +++ b/scripts/tests/test_dotnet.py @@ -2,9 +2,65 @@ Because of how pytest finds things, all import modules must start with scripts. ''' -from scripts.dotnet import CSharpProject +from scripts.dotnet import CSharpProject, CSharpProjFile import os +import subprocess +from unittest.mock import Mock + +import pytest + + def test_new(): CSharpProject.new('console', 'test_new', 'test_bin', False, '.') assert os.path.isdir('test_new') - assert os.path.isfile(os.path.join('test_new', 'test_new.csproj')) \ No newline at end of file + assert os.path.isfile(os.path.join('test_new', 'test_new.csproj')) + + +@pytest.mark.parametrize("use_link", [False, True]) +@pytest.mark.parametrize("frameworks", [None, ["net10.0"]]) +def test_restore_and_build_use_canonical_project_paths(tmp_path, monkeypatch, use_link, frameworks): + project_dir = tmp_path / "project" + project_dir.mkdir() + project_file = project_dir / "test.csproj" + project_file.write_text('') + input_dir = project_dir + link = tmp_path / "alias" + if use_link: + if os.name == "nt": + subprocess.run( + [os.environ["COMSPEC"], "/c", "mklink", "/J", str(link), str(project_dir)], + check=True, + capture_output=True, + ) + else: + link.symlink_to(project_dir, target_is_directory=True) + input_dir = link + + try: + run_command = Mock() + monkeypatch.setattr("scripts.dotnet.RunCommand", run_command) + project = CSharpProject( + CSharpProjFile(str(input_dir / "test.csproj"), str(input_dir)), + str(tmp_path / "bin"), + ) + project.restore(str(tmp_path / "packages"), verbose=False) + project.build( + "Release", + verbose=False, + packages_path=str(tmp_path / "packages"), + target_framework_monikers=frameworks, + ) + + assert project.csproj_file == os.path.realpath(project_file) + assert project.working_directory == os.path.realpath(project_dir) + assert run_command.call_count == 2 + for call in run_command.call_args_list: + assert call.args[0][2] == os.path.realpath(project_file) + for call in run_command.return_value.run.call_args_list: + assert call.args == (os.path.realpath(project_dir),) + finally: + if use_link: + if os.name == "nt": + os.rmdir(link) + else: + link.unlink()