From ff9779533eee061f2e3a22c72e06310a751e32ab Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Tue, 9 Dec 2025 21:22:58 +0100 Subject: [PATCH 01/17] [release/8.0] Backport improvements to Http and Ssl stress tests (#122141) --- eng/docker/build-docker-sdk.ps1 | 13 +- eng/docker/build-docker-sdk.sh | 10 +- eng/docker/libraries-sdk.linux.Dockerfile | 13 +- eng/docker/libraries-sdk.windows.Dockerfile | 9 +- eng/pipelines/libraries/stress/http.yml | 70 +++---- eng/pipelines/libraries/stress/ssl.yml | 30 ++- .../System/Net/StressTests/build-local.ps1 | 79 ++++++++ .../System/Net/StressTests/build-local.sh | 83 ++++++++ .../Net/StressTests/run-docker-compose.ps1 | 90 +++++++++ .../Net/StressTests/run-docker-compose.sh | 118 +++++++++++ .../StressTests/HttpStress/Configuration.cs | 1 + .../HttpStress/Directory.Build.props | 16 +- .../HttpStress/Directory.Build.targets | 2 +- .../tests/StressTests/HttpStress/Dockerfile | 36 ++-- .../StressTests/HttpStress/HttpStress.csproj | 4 +- .../tests/StressTests/HttpStress/Program.cs | 190 +++++++++++------- .../StressTests/HttpStress/StressClient.cs | 1 + .../StressTests/HttpStress/StressServer.cs | 2 +- .../StressTests/HttpStress/build-local.ps1 | 58 +----- .../StressTests/HttpStress/build-local.sh | 77 ++----- .../StressTests/HttpStress/docker-compose.yml | 14 +- .../StressTests/HttpStress/entrypoint.ps1 | 21 ++ .../StressTests/HttpStress/entrypoint.sh | 25 +++ .../HttpStress/run-docker-compose.ps1 | 100 +-------- .../HttpStress/run-docker-compose.sh | 74 +------ .../StressTests/HttpStress/windows.Dockerfile | 14 +- .../StressTests/SslStress/Build-Local.ps1 | 55 +---- .../SslStress/Directory.Build.props | 21 +- .../SslStress/Directory.Build.targets | 2 +- .../tests/StressTests/SslStress/Dockerfile | 9 +- .../tests/StressTests/SslStress/Program.cs | 85 ++++---- .../StressTests/SslStress/SslClientBase.cs | 8 +- .../StressTests/SslStress/SslStress.csproj | 6 +- .../StressTests/SslStress/StressOperations.cs | 38 +++- .../StressTests/SslStress/build-local.sh | 72 ++----- .../StressTests/SslStress/docker-compose.yml | 12 +- .../StressTests/SslStress/entrypoint.ps1 | 21 ++ .../tests/StressTests/SslStress/entrypoint.sh | 21 ++ .../SslStress/run-docker-compose.ps1 | 76 +------ .../SslStress/run-docker-compose.sh | 69 +------ .../StressTests/SslStress/windows.Dockerfile | 9 +- 41 files changed, 857 insertions(+), 797 deletions(-) create mode 100644 src/libraries/Common/tests/System/Net/StressTests/build-local.ps1 create mode 100755 src/libraries/Common/tests/System/Net/StressTests/build-local.sh create mode 100644 src/libraries/Common/tests/System/Net/StressTests/run-docker-compose.ps1 create mode 100755 src/libraries/Common/tests/System/Net/StressTests/run-docker-compose.sh create mode 100644 src/libraries/System.Net.Http/tests/StressTests/HttpStress/entrypoint.ps1 create mode 100755 src/libraries/System.Net.Http/tests/StressTests/HttpStress/entrypoint.sh create mode 100644 src/libraries/System.Net.Security/tests/StressTests/SslStress/entrypoint.ps1 create mode 100755 src/libraries/System.Net.Security/tests/StressTests/SslStress/entrypoint.sh diff --git a/eng/docker/build-docker-sdk.ps1 b/eng/docker/build-docker-sdk.ps1 index 1a09343defbf6e..0e59796af4a37e 100755 --- a/eng/docker/build-docker-sdk.ps1 +++ b/eng/docker/build-docker-sdk.ps1 @@ -9,10 +9,11 @@ Param( [switch][Alias('w')]$buildWindowsContainers ) -$dotNetVersion="8.0" $ErrorActionPreference = "Stop" $REPO_ROOT_DIR=$(git -C "$PSScriptRoot" rev-parse --show-toplevel) +[xml]$xml = Get-Content (Join-Path $REPO_ROOT_DIR "eng\Versions.props") +$VERSION="$($xml.Project.PropertyGroup.MajorVersion[0]).$($xml.Project.PropertyGroup.MinorVersion[0])" $dockerFilePrefix="$PSScriptRoot/libraries-sdk" @@ -29,7 +30,7 @@ if ($buildWindowsContainers) } $dockerFile="$dockerFilePrefix.windows.Dockerfile" - + # Collect the following artifacts to folder, that will be used as build context for the container, # so projects can build and test against the live-built runtime: # 1. Reference assembly pack (microsoft.netcore.app.ref) @@ -54,15 +55,16 @@ if ($buildWindowsContainers) -Destination $dockerContext\targetingpacks.targets Copy-Item -Recurse -Path $REPO_ROOT_DIR\src\libraries\System.Net.Quic\src\System\Net\Quic\Interop ` -Destination $dockerContext\msquic-interop - + # In case of non-CI builds, testhost may already contain Microsoft.AspNetCore.App (see build-local.ps1 in HttpStress): - $testHostAspNetCorePath="$dockerContext\testhost\net$dotNetVersion-windows-$configuration-x64/shared/Microsoft.AspNetCore.App" + $testHostAspNetCorePath="$dockerContext\testhost\net$VERSION-windows-$configuration-x64/shared/Microsoft.AspNetCore.App" if (Test-Path $testHostAspNetCorePath) { Remove-Item -Recurse -Force $testHostAspNetCorePath } - + docker build --tag $imageName ` --build-arg CONFIGURATION=$configuration ` + --build-arg VERSION=$VERSION ` --file $dockerFile ` $dockerContext } @@ -73,6 +75,7 @@ else docker build --tag $imageName ` --build-arg CONFIGURATION=$configuration ` + --build-arg "VERSION=$VERSION" ` --file $dockerFile ` $REPO_ROOT_DIR } diff --git a/eng/docker/build-docker-sdk.sh b/eng/docker/build-docker-sdk.sh index 92fc632ec05e2a..54af435d35c16e 100755 --- a/eng/docker/build-docker-sdk.sh +++ b/eng/docker/build-docker-sdk.sh @@ -23,8 +23,12 @@ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" imagename="dotnet-sdk-libs-current" configuration="Release" +repo_root=$(git -C "$scriptroot" rev-parse --show-toplevel) +major_version=$(grep -oP '(?<=).*?(?=)' "$repo_root/eng/Versions.props") +minor_version=$(grep -oP '(?<=).*?(?=)' "$repo_root/eng/Versions.props") +version="$major_version.$minor_version" -while [[ $# > 0 ]]; do +while [[ $# -gt 0 ]]; do opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" case "$opt" in -imagename|-t) @@ -41,12 +45,12 @@ while [[ $# > 0 ]]; do esac done -repo_root=$(git rev-parse --show-toplevel) docker_file="$scriptroot/libraries-sdk.linux.Dockerfile" docker build --tag $imagename \ --build-arg CONFIGURATION=$configuration \ + --build-arg VERSION=$version \ --file $docker_file \ $repo_root -exit $? \ No newline at end of file +exit $? diff --git a/eng/docker/libraries-sdk.linux.Dockerfile b/eng/docker/libraries-sdk.linux.Dockerfile index 779c64f83c09a1..fcd48f2a568522 100644 --- a/eng/docker/libraries-sdk.linux.Dockerfile +++ b/eng/docker/libraries-sdk.linux.Dockerfile @@ -1,6 +1,6 @@ # Builds and copies library artifacts into target dotnet sdk image ARG BUILD_BASE_IMAGE=mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8 -ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:7.0-bullseye-slim +ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:latest FROM $BUILD_BASE_IMAGE as corefxbuild @@ -12,12 +12,15 @@ RUN ./build.sh clr+libs -runtimeconfiguration Release -configuration $CONFIGURAT FROM $SDK_BASE_IMAGE as target -ARG VERSION=8.0 +ARG VERSION ARG CONFIGURATION=Release ENV _DOTNET_INSTALL_CHANNEL=$VERSION +# remove the existing SDK, we want to start from a clean slate with latest daily +RUN rm -rf /usr/share/dotnet + # Install latest daily SDK: -RUN wget https://dot.net/v1/dotnet-install.sh +RUN wget https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.sh RUN bash ./dotnet-install.sh --channel $_DOTNET_INSTALL_CHANNEL --quality daily --install-dir /usr/share/dotnet # Collect the following artifacts under /live-runtime-artifacts, @@ -48,8 +51,8 @@ COPY --from=corefxbuild \ /repo/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop \ /live-runtime-artifacts/msquic-interop -# Add AspNetCore bits to testhost: -ENV _ASPNETCORE_SOURCE="/usr/share/dotnet/shared/Microsoft.AspNetCore.App/$VERSION*" +# Add AspNetCore bits to testhost, there should be only one version since we started from an image without existing SDK: +ENV _ASPNETCORE_SOURCE="/usr/share/dotnet/shared/Microsoft.AspNetCore.App/*" ENV _ASPNETCORE_DEST="/live-runtime-artifacts/testhost/net$VERSION-linux-$CONFIGURATION-x64/shared/Microsoft.AspNetCore.App" RUN mkdir -p $_ASPNETCORE_DEST RUN cp -r $_ASPNETCORE_SOURCE $_ASPNETCORE_DEST diff --git a/eng/docker/libraries-sdk.windows.Dockerfile b/eng/docker/libraries-sdk.windows.Dockerfile index 351d013468e699..f1713e76132d92 100644 --- a/eng/docker/libraries-sdk.windows.Dockerfile +++ b/eng/docker/libraries-sdk.windows.Dockerfile @@ -1,6 +1,6 @@ # escape=` # Simple Dockerfile which copies clr and library build artifacts into target dotnet sdk image -ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:7.0-nanoserver-ltsc2022 +ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:8.0-nanoserver-ltsc2022 FROM $SDK_BASE_IMAGE as target SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] @@ -11,7 +11,10 @@ ARG CONFIGURATION=Release USER ContainerAdministrator -RUN Invoke-WebRequest -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile .\dotnet-install.ps1 +# remove the existing ASP.NET SDK, we want to keep only the latest one we download later +RUN Remove-Item -Force -Recurse 'C:/Program Files/dotnet/shared/Microsoft.AspNetCore.App/*' + +RUN Invoke-WebRequest -Uri https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.ps1 -OutFile .\dotnet-install.ps1 RUN & .\dotnet-install.ps1 -Channel $env:_DOTNET_INSTALL_CHANNEL -Quality daily -InstallDir 'C:/Program Files/dotnet' USER ContainerUser @@ -19,7 +22,7 @@ USER ContainerUser COPY . /live-runtime-artifacts # Add AspNetCore bits to testhost: -ENV _ASPNETCORE_SOURCE="C:/Program Files/dotnet/shared/Microsoft.AspNetCore.App/$VERSION*" +ENV _ASPNETCORE_SOURCE="C:/Program Files/dotnet/shared/Microsoft.AspNetCore.App/*" ENV _ASPNETCORE_DEST="C:/live-runtime-artifacts/testhost/net$VERSION-windows-$CONFIGURATION-x64/shared/Microsoft.AspNetCore.App" RUN & New-Item -ItemType Directory -Path $env:_ASPNETCORE_DEST RUN Copy-Item -Recurse -Path $env:_ASPNETCORE_SOURCE -Destination $env:_ASPNETCORE_DEST diff --git a/eng/pipelines/libraries/stress/http.yml b/eng/pipelines/libraries/stress/http.yml index 0ffa778a44e857..dae5e867ae8da7 100644 --- a/eng/pipelines/libraries/stress/http.yml +++ b/eng/pipelines/libraries/stress/http.yml @@ -12,6 +12,7 @@ schedules: branches: include: - main + - release/*.0 - release/*-staging variables: @@ -35,6 +36,7 @@ extends: timeoutInMinutes: 240 variables: DUMPS_SHARE_MOUNT_ROOT: "/dumps-share" + DUMPS_SHARE: "$(Build.ArtifactStagingDirectory)/dumps/" pool: name: $(DncEngPublicBuildPool) demands: ImageOverride -equals Build.Ubuntu.2204.Amd64.Open @@ -58,10 +60,9 @@ extends: - bash: | cd '$(httpStressProject)' - export CLIENT_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/client/3.0" - export SERVER_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/server/3.0" - export HTTPSTRESS_CLIENT_ARGS="$HTTPSTRESS_CLIENT_ARGS -http 3.0" - export HTTPSTRESS_SERVER_ARGS="$HTTPSTRESS_SERVER_ARGS -http 3.0" + export STRESS_CLIENT_ARGS="$HTTPSTRESS_CLIENT_ARGS -http 3.0" + export STRESS_SERVER_ARGS="$HTTPSTRESS_SERVER_ARGS -http 3.0" + mkdir -p $DUMPS_SHARE docker-compose up --abort-on-container-exit --no-color timeoutInMinutes: 35 # In case the HTTP/3.0 run hangs, we timeout shortly after the expected 30 minute run displayName: Run HttpStress - HTTP 3.0 @@ -69,10 +70,9 @@ extends: - bash: | cd '$(httpStressProject)' - export CLIENT_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/client/2.0" - export SERVER_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/server/2.0" - export HTTPSTRESS_CLIENT_ARGS="$HTTPSTRESS_CLIENT_ARGS -http 2.0" - export HTTPSTRESS_SERVER_ARGS="$HTTPSTRESS_SERVER_ARGS -http 2.0" + export STRESS_CLIENT_ARGS="$HTTPSTRESS_CLIENT_ARGS -http 2.0" + export STRESS_SERVER_ARGS="$HTTPSTRESS_SERVER_ARGS -http 2.0" + mkdir -p $DUMPS_SHARE docker-compose down docker-compose up --abort-on-container-exit --no-color displayName: Run HttpStress - HTTP 2.0 @@ -80,10 +80,9 @@ extends: - bash: | cd '$(httpStressProject)' - export CLIENT_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/client/1.1" - export SERVER_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/server/1.1" - export HTTPSTRESS_CLIENT_ARGS="$HTTPSTRESS_CLIENT_ARGS -http 1.1" - export HTTPSTRESS_SERVER_ARGS="$HTTPSTRESS_SERVER_ARGS -http 1.1" + export STRESS_CLIENT_ARGS="$HTTPSTRESS_CLIENT_ARGS -http 1.1" + export STRESS_SERVER_ARGS="$HTTPSTRESS_SERVER_ARGS -http 1.1" + mkdir -p $DUMPS_SHARE docker-compose down docker-compose up --abort-on-container-exit --no-color displayName: Run HttpStress - HTTP 1.1 @@ -103,12 +102,7 @@ extends: timeoutInMinutes: 150 variables: DUMPS_SHARE_MOUNT_ROOT: "C:/dumps-share" - - # The 1es-windows-2022-open image has an issue where the Chocolatey-installed V1 docker-compose takes precendence over the - # V2 docker-compose required by the stress tests, see: https://github.com/actions/runner-images/issues/7080 - # This is worked around by handpicking the V2 executable. - # The workaround should be removed when the official fix is propagated into 1es-windows-2022-open, or when we switch to another image. - DOCKER_COMPOSE_CMD: "C:/ProgramData/docker/cli-plugins/docker-compose.exe" + DUMPS_SHARE: "$(Build.ArtifactStagingDirectory)/dumps/" pool: name: $(DncEngPublicBuildPool) demands: ImageOverride -equals 1es-windows-2022-open @@ -120,19 +114,12 @@ extends: lfs: false - powershell: | - # Workaround for https://github.com/microsoft/azure-pipelines-agent/issues/4554. Undo when the image bug is fixed. - Remove-Item -Path "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\Microsoft.VCToolsVersion.v143.default.txt" - $(dockerfilesFolder)/build-docker-sdk.ps1 -w -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION) echo "##vso[task.setvariable variable=succeeded;isOutput=true]true" name: buildRuntime displayName: Build CLR and Libraries - powershell: | - $env:CLIENT_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/client/" - $env:SERVER_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/server/" - New-Item -Force $env:CLIENT_DUMPS_SHARE -ItemType Directory - New-Item -Force $env:SERVER_DUMPS_SHARE -ItemType Directory $(httpStressProject)/run-docker-compose.ps1 -w -o -c $(BUILD_CONFIGURATION) -t $(sdkBaseImage) echo "##vso[task.setvariable variable=succeeded;isOutput=true]true" name: buildStress @@ -147,37 +134,28 @@ extends: - powershell: | cd '$(httpStressProject)' - $env:CLIENT_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/client/3.0" - $env:SERVER_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/server/3.0" - New-Item -Force $env:CLIENT_DUMPS_SHARE -ItemType Directory - New-Item -Force $env:SERVER_DUMPS_SHARE -ItemType Directory - $env:HTTPSTRESS_CLIENT_ARGS = "$env:HTTPSTRESS_CLIENT_ARGS -http 3.0" - $env:HTTPSTRESS_SERVER_ARGS = "$env:HTTPSTRESS_SERVER_ARGS -http 3.0" - & $env:DOCKER_COMPOSE_CMD up --abort-on-container-exit --no-color + $env:STRESS_CLIENT_ARGS = "$env:HTTPSTRESS_CLIENT_ARGS -http 3.0" + $env:STRESS_SERVER_ARGS = "$env:HTTPSTRESS_SERVER_ARGS -http 3.0" + New-Item -Force $env:DUMPS_SHARE -ItemType Directory + docker compose up --abort-on-container-exit --no-color displayName: Run HttpStress - HTTP 3.0 condition: and(eq(variables['buildRuntime.succeeded'], 'true'), eq(variables['buildStress.succeeded'], 'true')) - powershell: | cd '$(httpStressProject)' - $env:CLIENT_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/client/2.0" - $env:SERVER_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/server/2.0" - New-Item -Force $env:CLIENT_DUMPS_SHARE -ItemType Directory - New-Item -Force $env:SERVER_DUMPS_SHARE -ItemType Directory - $env:HTTPSTRESS_CLIENT_ARGS = "$env:HTTPSTRESS_CLIENT_ARGS -http 2.0" - $env:HTTPSTRESS_SERVER_ARGS = "$env:HTTPSTRESS_SERVER_ARGS -http 2.0" - & $env:DOCKER_COMPOSE_CMD up --abort-on-container-exit --no-color + $env:STRESS_CLIENT_ARGS = "$env:HTTPSTRESS_CLIENT_ARGS -http 2.0" + $env:STRESS_SERVER_ARGS = "$env:HTTPSTRESS_SERVER_ARGS -http 2.0" + New-Item -Force $env:DUMPS_SHARE -ItemType Directory + docker compose up --abort-on-container-exit --no-color displayName: Run HttpStress - HTTP 2.0 condition: and(eq(variables['buildRuntime.succeeded'], 'true'), eq(variables['buildStress.succeeded'], 'true')) - powershell: | cd '$(httpStressProject)' - $env:CLIENT_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/client/1.1" - $env:SERVER_DUMPS_SHARE="$(Build.ArtifactStagingDirectory)/dumps/server/1.1" - New-Item -Force $env:CLIENT_DUMPS_SHARE -ItemType Directory - New-Item -Force $env:SERVER_DUMPS_SHARE -ItemType Directory - $env:HTTPSTRESS_CLIENT_ARGS = "$env:HTTPSTRESS_CLIENT_ARGS -http 1.1" - $env:HTTPSTRESS_SERVER_ARGS = "$env:HTTPSTRESS_SERVER_ARGS -http 1.1" - & $env:DOCKER_COMPOSE_CMD up --abort-on-container-exit --no-color + $env:STRESS_CLIENT_ARGS = "$env:HTTPSTRESS_CLIENT_ARGS -http 1.1" + $env:STRESS_SERVER_ARGS = "$env:HTTPSTRESS_SERVER_ARGS -http 1.1" + New-Item -Force $env:DUMPS_SHARE -ItemType Directory + docker compose up --abort-on-container-exit --no-color displayName: Run HttpStress - HTTP 1.1 condition: and(eq(variables['buildRuntime.succeeded'], 'true'), eq(variables['buildStress.succeeded'], 'true')) diff --git a/eng/pipelines/libraries/stress/ssl.yml b/eng/pipelines/libraries/stress/ssl.yml index ed1306990e294b..8dd9adc3908707 100644 --- a/eng/pipelines/libraries/stress/ssl.yml +++ b/eng/pipelines/libraries/stress/ssl.yml @@ -12,6 +12,7 @@ schedules: branches: include: - main + - release/*.0 - release/*-staging variables: @@ -34,6 +35,9 @@ extends: - job: linux displayName: Docker Linux timeoutInMinutes: 120 + variables: + DUMPS_SHARE_MOUNT_ROOT: "/dumps-share" + DUMPS_SHARE: "$(Build.ArtifactStagingDirectory)/dumps/" pool: name: $(DncEngPublicBuildPool) demands: ImageOverride -equals Build.Ubuntu.2204.Amd64.Open @@ -53,9 +57,16 @@ extends: - bash: | cd '$(sslStressProject)' + export STRESS_CLIENT_ARGS=$SSLSTRESS_CLIENT_ARGS + export STRESS_SERVER_ARGS=$SSLSTRESS_SERVER_ARGS + mkdir -p $DUMPS_SHARE docker-compose up --abort-on-container-exit --no-color displayName: Run SslStress + - publish: $(Build.ArtifactStagingDirectory)/dumps + artifact: DumpsLinux + condition: failed() + - job: windows displayName: Docker NanoServer timeoutInMinutes: 120 @@ -63,11 +74,8 @@ extends: name: $(DncEngPublicBuildPool) demands: ImageOverride -equals 1es-windows-2022-open variables: - # The 1es-windows-2022-open image has an issue where the Chocolatey-installed V1 docker-compose takes precendence over the - # V2 docker-compose required by the stress tests, see: https://github.com/actions/runner-images/issues/7080 - # This is worked around by handpicking the V2 executable. - # The workaround should be removed when the official fix is propagated into 1es-windows-2022-open, or when we switch to another image. - DOCKER_COMPOSE_CMD: "C:/ProgramData/docker/cli-plugins/docker-compose.exe" + DUMPS_SHARE_MOUNT_ROOT: "C:/dumps-share" + DUMPS_SHARE: "$(Build.ArtifactStagingDirectory)/dumps/" steps: - checkout: self clean: true @@ -75,9 +83,6 @@ extends: lfs: false - powershell: | - # Workaround for https://github.com/microsoft/azure-pipelines-agent/issues/4554. Undo when the image bug is fixed. - Remove-Item -Path "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\Microsoft.VCToolsVersion.v143.default.txt" - $(dockerfilesFolder)/build-docker-sdk.ps1 -w -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION) displayName: Build CLR and Libraries @@ -87,5 +92,12 @@ extends: - powershell: | cd '$(sslStressProject)' - & $env:DOCKER_COMPOSE_CMD up --abort-on-container-exit --no-color + $env:STRESS_CLIENT_ARGS = $env:SSLSTRESS_CLIENT_ARGS + $env:STRESS_SERVER_ARGS = $env:SSLSTRESS_SERVER_ARGS + New-Item -Force $env:DUMPS_SHARE -ItemType Directory + docker compose up --abort-on-container-exit --no-color displayName: Run SslStress + + - publish: $(Build.ArtifactStagingDirectory)/dumps + artifact: DumpsWindows + condition: failed() \ No newline at end of file diff --git a/src/libraries/Common/tests/System/Net/StressTests/build-local.ps1 b/src/libraries/Common/tests/System/Net/StressTests/build-local.ps1 new file mode 100644 index 00000000000000..6aeba6c6b9d75e --- /dev/null +++ b/src/libraries/Common/tests/System/Net/StressTests/build-local.ps1 @@ -0,0 +1,79 @@ +## This is a helper script for non-containerized local build and test execution. +## It downloads and uses the daily SDK which contains the compatible AspNetCore bits. +## Usage: +## ./build-local.ps1 [TestProjectDir] [StressConfiguration] [LibrariesConfiguration] + +$RepoRoot="$(git rev-parse --show-toplevel)" +[xml]$xml = Get-Content (Join-Path $RepoRoot "eng\Versions.props") +$Version="$($xml.Project.PropertyGroup.MajorVersion[0]).$($xml.Project.PropertyGroup.MinorVersion[0])" + +function PrintUsageAndExit { + Write-Host "Usage:" + Write-Host "./build-local.ps1 [TestProjectDir] [StressConfiguration] [LibrariesConfiguration]" + Write-Host "StressConfiguration and LibrariesConfiguration default to Release!" + exit 1 +} + +if (-not ([string]::IsNullOrEmpty($args[0])) -and (Test-Path -Path $args[0])) { + $TestProjectDir = $args[0] +} else { + Write-Host "Valid TestProjectDir is required!" + PrintUsageAndExit +} + +$ProjectName = (Get-Item $TestProjectDir).Name + +$DailyDotnetRoot= Join-Path $TestProjectDir ".dotnet-daily" + +$StressConfiguration = "Release" +if (-not ([string]::IsNullOrEmpty($args[1]))) { + $StressConfiguration = $args[1] +} + +$LibrariesConfiguration = "Release" +if (-not ([string]::IsNullOrEmpty($args[2]))) { + $LibrariesConfiguration = $args[2] +} + +$TestHostRoot="$RepoRoot/artifacts/bin/testhost/net$Version-windows-$LibrariesConfiguration-x64" + +Write-Host "StressConfiguration: $StressConfiguration, LibrariesConfiguration: $LibrariesConfiguration, testhost: $TestHostRoot" + +if (-not (Test-Path -Path $TestHostRoot)) { + Write-Host "Cannot find testhost in: $TestHostRoot" + Write-Host "Make sure libraries with the requested configuration are built!" + PrintUsageAndExit + exit 1 +} + +if (-not (Test-Path -Path $DailyDotnetRoot)) { + Write-Host "Downloading daily SDK to: $DailyDotnetRoot" + New-Item -ItemType Directory -Path $DailyDotnetRoot + Invoke-WebRequest -Uri https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.ps1 -OutFile "$DailyDotnetRoot\dotnet-install.ps1" + & "$DailyDotnetRoot\dotnet-install.ps1" -NoPath -Channel $Version -Quality daily -InstallDir $DailyDotnetRoot +} else { + Write-Host "Daily SDK found in $DailyDotnetRoot" +} + +$env:DOTNET_ROOT=$DailyDotnetRoot +$env:PATH="$DailyDotnetRoot;$env:PATH" +$env:DOTNET_MULTILEVEL_LOOKUP=0 + +if (-not (Test-Path -Path "$TestHostRoot/shared/Microsoft.AspNetCore.App")) { + Write-Host "Copying Microsoft.AspNetCore.App bits from daily SDK to testhost: $TestHostRoot" + Copy-Item -Recurse -Path "$DailyDotnetRoot/shared/Microsoft.AspNetCore.App" -Destination "$TestHostRoot/shared" +} else { + Write-Host "Microsoft.AspNetCore.App found in testhost: $TestHostRoot" +} + +Write-Host "Building solution." +dotnet build -c $StressConfiguration -f "net$Version" + +$Runscript=".\run-stress-$StressConfiguration-$LibrariesConfiguration.ps1" +if (-not (Test-Path $Runscript)) { + Write-Host "Generating Runscript." + Add-Content -Path $Runscript -Value "& '$TestHostRoot/dotnet' exec --roll-forward Major ./bin/$StressConfiguration/net$Version/$ProjectName.dll `$args" +} + +Write-Host "To run tests type:" +Write-Host "$Runscript [stress test args]" diff --git a/src/libraries/Common/tests/System/Net/StressTests/build-local.sh b/src/libraries/Common/tests/System/Net/StressTests/build-local.sh new file mode 100755 index 00000000000000..cdaa86721b1db9 --- /dev/null +++ b/src/libraries/Common/tests/System/Net/StressTests/build-local.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash + +## This is a helper script for non-containerized local build and test execution. +## It downloads and uses the daily SDK which contains the compatible AspNetCore bits. +## Usage: +## ./build-local.sh [TestProjectDir] [StressConfiguration] [LibrariesConfiguration] + +if [ "$1" == "" ]; then + echo "Usage:" + echo "./build-local.sh [TestProjectDir] [StressConfiguration] [LibrariesConfiguration]" + echo "StressConfiguration and LibrariesConfiguration default to Release!" + exit 1 +fi + +projectdir=$1 +projectname=$(basename $1) +daily_dotnet_root=$projectdir/.dotnet-daily + +repo_root=$(git -C "$projectdir" rev-parse --show-toplevel) +major_version=$(grep -oP '(?<=).*?(?=)' "$repo_root/eng/Versions.props") +minor_version=$(grep -oP '(?<=).*?(?=)' "$repo_root/eng/Versions.props") +version="$major_version.$minor_version" + +stress_configuration="Release" +if [ "$2" != "" ]; then + stress_configuration=${2,,} # Lowercase all characters in $1 + stress_configuration=${stress_configuration^} # Uppercase first character +fi + +libraries_configuration="Release" +if [ "$3" != "" ]; then + libraries_configuration=${3,,} # Lowercase all characters in $1 + libraries_configuration=${libraries_configuration^} # Uppercase first character +fi + +testhost_root=$repo_root/artifacts/bin/testhost/net$version-linux-$libraries_configuration-x64 +echo "StressConfiguration: $stress_configuration, LibrariesConfiguration: $libraries_configuration, testhost: $testhost_root" + +if [[ ! -d $testhost_root ]]; then + echo "Cannot find testhost in: $testhost_root" + echo "Make sure libraries with the requested configuration are built!" + echo "Usage:" + echo "./build-local.sh [TestProjectDir] [StressConfiguration] [LibrariesConfiguration]" + echo "StressConfiguration and LibrariesConfiguration default to Release!" + exit 1 +fi + +if [[ ! -d $daily_dotnet_root ]]; then + echo "Downloading daily SDK to $daily_dotnet_root" + mkdir $daily_dotnet_root + wget https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.sh -O $daily_dotnet_root/dotnet-install.sh + bash $daily_dotnet_root/dotnet-install.sh --no-path --channel $version --quality daily --install-dir $daily_dotnet_root +else + echo "Daily SDK found in $daily_dotnet_root" +fi + +export DOTNET_ROOT=$daily_dotnet_root +export PATH=$DOTNET_ROOT:$PATH +export DOTNET_MULTILEVEL_LOOKUP=0 + +if [[ ! -d "$testhost_root/shared/Microsoft.AspNetCore.App" ]]; then + echo "Copying Microsoft.AspNetCore.App bits from daily SDK to testhost: $testhost_root" + cp -r $daily_dotnet_root/shared/Microsoft.AspNetCore.App $testhost_root/shared/Microsoft.AspNetCore.App +else + echo "Microsoft.AspNetCore.App found in testhost: $testhost_root" +fi + +echo "Building solution." +dotnet build -c $stress_configuration + +runscript=./run-stress-${stress_configuration,,}-${libraries_configuration,,}.sh +if [[ ! -f $runscript ]]; then + echo "Generating runscript." + cat >$runscript <" + exit 1 +} + +if ($useWindowsContainers) { + $env:DOCKERFILE = "windows.Dockerfile" +} + +if (!$noBuild) { + # Dockerize the stress app using docker-compose + $BuildArgs = @( + "--build-arg", "VERSION=$Version", + "--build-arg", "CONFIGURATION=$configuration" + ) + if ($sdkImageName) { + $BuildArgs += "--build-arg", "SDK_BASE_IMAGE=$sdkImageName" + } + $originalErrorPreference = $ErrorActionPreference + $ErrorActionPreference = 'Continue' + try { + write-output "docker compose --file $COMPOSE_FILE build $buildArgs" + docker compose --file $COMPOSE_FILE build @buildArgs 2>&1 + if ($LASTEXITCODE -ne 0) { + throw "docker compose exited with error code $LASTEXITCODE" + } + } + finally { + $ErrorActionPreference = $originalErrorPreference + } +} + +# Run the stress app +if (!$buildOnly) { + if ($useWindowsContainers) { + $env:DUMPS_SHARE_MOUNT_ROOT = "C:/dumps-share" + } + else { + $env:DUMPS_SHARE_MOUNT_ROOT = "/dumps-share" + } + + $env:DUMPS_SHARE = $dumpsSharePath + New-Item -Force $env:DUMPS_SHARE -ItemType Directory + + $env:STRESS_CLIENT_ARGS = $clientStressArgs + $env:STRESS_SERVER_ARGS = $serverStressArgs + docker compose --file "$COMPOSE_FILE" up --abort-on-container-exit +} diff --git a/src/libraries/Common/tests/System/Net/StressTests/run-docker-compose.sh b/src/libraries/Common/tests/System/Net/StressTests/run-docker-compose.sh new file mode 100755 index 00000000000000..6b50a01f5d2ffa --- /dev/null +++ b/src/libraries/Common/tests/System/Net/StressTests/run-docker-compose.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +# Runs the stress test using docker-compose + +# Stop script if unbound variable found (use ${var:-} if intentional) +set -u + +# Stop script if command returns non-zero exit code. +# Prevents hidden errors caused by missing error code propagation. +set -e + +source="${BASH_SOURCE[0]}" + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +repo_root=$(git -C "$scriptroot" rev-parse --show-toplevel) +major_version=$(grep -oP '(?<=).*?(?=)' "$repo_root/eng/Versions.props") +minor_version=$(grep -oP '(?<=).*?(?=)' "$repo_root/eng/Versions.props") +version="$major_version.$minor_version" +imagename="dotnet-sdk-libs-current" +configuration="Release" +buildcurrentlibraries=0 +buildonly=0 +nobuild=0 +clientstressargs="" +serverstressargs="" + +projectdir=$1 +shift 1 +if [[ ! -d "$projectdir" ]]; then + echo "First argument must be path to the stress project directory" + exit 1 +fi + +dumpssharepath="$projectdir/dumps" + +while [[ $# -gt 0 ]]; do + opt="$(printf "%s" "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" + case "$opt" in + -dumpssharepath|-d) + dumpssharepath=$2 + shift 2 + ;; + -sdkimagename|-t) + imagename=$2 + shift 2 + ;; + -configuration|-c) + configuration=$2 + shift 2 + ;; + -buildcurrentlibraries|-b) + buildcurrentlibraries=1 + shift 1 + ;; + -buildonly|-o) + buildonly=1 + shift 1 + ;; + -nobuild|-n) + nobuild=1 + shift 1 + ;; + -clientstressargs) + clientstressargs=$2 + shift 2 + ;; + -serverstressargs) + serverstressargs=$2 + shift 2 + ;; + *) + shift 1 + ;; + esac +done + +repo_root=$(git -C "$scriptroot" rev-parse --show-toplevel) + +if [[ "$buildcurrentlibraries" -eq 1 ]]; then + libraries_args=" -t $imagename -c $configuration" + + if ! "$repo_root"/eng/docker/build-docker-sdk.sh $libraries_args; then + exit 1 + fi +fi + +compose_file="$projectdir/docker-compose.yml" + +if [[ "$nobuild" -eq 0 ]]; then + build_args="--build-arg VERSION=$version --build-arg CONFIGURATION=$configuration" + if [[ -n "$imagename" ]]; then + build_args="$build_args --build-arg SDK_BASE_IMAGE=$imagename" + fi + + if ! docker-compose --file "$compose_file" build $build_args; then + exit $? + fi +fi + +if [[ "$buildonly" -eq 0 ]]; then + if [[ -n "$dumpssharepath" ]]; then + export DUMPS_SHARE="$dumpssharepath" + export DUMPS_SHARE_MOUNT_ROOT="/dumps-share" + fi + + export STRESS_CLIENT_ARGS=$clientstressargs + export STRESS_SERVER_ARGS=$serverstressargs + docker-compose --file "$compose_file" up --abort-on-container-exit + exit $? +fi diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Configuration.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Configuration.cs index baba7d94d919c5..e73e0704be164e 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Configuration.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Configuration.cs @@ -45,6 +45,7 @@ public class Configuration public bool UseHttpSys { get; set; } public bool LogAspNet { get; set; } public bool Trace { get; set; } + public bool? TrackUnobservedExceptions { get; set; } public int? ServerMaxConcurrentStreams { get; set; } public int? ServerMaxFrameSize { get; set; } public int? ServerInitialConnectionWindowSize { get; set; } diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.props b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.props index 3ee8cbfa7ae059..ab8595dbb5c92d 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.props +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.props @@ -1,18 +1,20 @@ - linux-x64 - win-x64 + linux-x64 + win-x64 $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, global.json))/ - + + + $(RepositoryRoot)src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/*.cs $(RepositoryRoot)eng/targetingpacks.targets - 8.0.0 - net8.0 - 8.0 + $(MajorVersion).$(MinorVersion) + net$(NetCoreAppCurrentVersion) Microsoft.NETCore.App $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.ref/ - $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.runtime.$(OutputRID)/$(Configuration)/ + $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.runtime.$(TargetRid)/$(Configuration)/ + false diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.targets b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.targets index e3ebd0de328758..59c504befee957 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.targets +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Directory.Build.targets @@ -6,6 +6,6 @@ Define this here because the SDK resets it unconditionally in Microsoft.NETCoreSdk.BundledVersions.props. --> - 8.0 + $(NetCoreAppCurrentVersion) \ No newline at end of file diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile index 6dc83bce1895eb..1fa0e953c6d364 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile @@ -1,47 +1,49 @@ -ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:7.0-bullseye-slim +ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:latest FROM $SDK_BASE_IMAGE -# Build latest msquic locally +# Build latest msquic locally with ASAN enabled WORKDIR /msquic RUN apt-get update -y && \ apt-get upgrade -y && \ apt-get install -y cmake clang ruby-dev gem lttng-tools libssl-dev && \ gem install fpm -RUN git clone --recursive https://github.com/dotnet/msquic -RUN cd msquic/src/msquic && \ +RUN git clone --depth 1 --single-branch --branch main --recursive https://github.com/microsoft/msquic +RUN cd msquic/ && \ mkdir build && \ - cmake -B build -DCMAKE_BUILD_TYPE=Release -DQUIC_ENABLE_LOGGING=false -DQUIC_USE_SYSTEM_LIBCRYPTO=true -DQUIC_BUILD_TOOLS=off -DQUIC_BUILD_TEST=off -DQUIC_BUILD_PERF=off && \ + cmake -B build -DCMAKE_BUILD_TYPE=Debug -DQUIC_ENABLE_LOGGING=false -DQUIC_USE_SYSTEM_LIBCRYPTO=true -DQUIC_BUILD_TOOLS=off -DQUIC_BUILD_TEST=off -DQUIC_BUILD_PERF=off -DQUIC_TLS_LIB=quictls -DQUIC_ENABLE_SANITIZERS=on && \ cd build && \ - cmake --build . --config Release -RUN cd msquic/src/msquic/build/bin/Release && \ + cmake --build . --config Debug +RUN cd msquic/build/bin/Debug && \ rm libmsquic.so && \ fpm -f -s dir -t deb -n libmsquic -v $( find -type f | cut -d "." -f 4- ) \ --license MIT --url https://github.com/microsoft/msquic --log error \ $( ls ./* | cut -d "/" -f 2 | sed -r "s/(.*)/\1=\/usr\/lib\/\1/g" ) && \ dpkg -i libmsquic_*.deb -ARG VERSION=8.0 -ARG CONFIGURATION=Release +ARG VERSION +ARG CONFIGURATION # Build the stress server WORKDIR /app COPY . . RUN dotnet build -c $CONFIGURATION \ + -p:NetCoreAppCurrentVersion=$VERSION \ -p:MsQuicInteropIncludes="/live-runtime-artifacts/msquic-interop/*.cs" \ -p:TargetingPacksTargetsLocation=/live-runtime-artifacts/targetingpacks.targets \ -p:MicrosoftNetCoreAppRefPackDir=/live-runtime-artifacts/microsoft.netcore.app.ref/ \ -p:MicrosoftNetCoreAppRuntimePackDir=/live-runtime-artifacts/microsoft.netcore.app.runtime.linux-x64/$CONFIGURATION/ -# Enable dump collection -ENV DOTNET_DbgEnableMiniDump=1 -ENV DOTNET_DbgMiniDumpType=MiniDumpWithFullMemory -ENV DOTNET_DbgMiniDumpName="/dumps-share/coredump.%p" - EXPOSE 5001 ENV VERSION=$VERSION ENV CONFIGURATION=$CONFIGURATION -ENV HTTPSTRESS_ARGS='' -CMD /live-runtime-artifacts/testhost/net$VERSION-linux-$CONFIGURATION-x64/dotnet exec --roll-forward Major \ - ./bin/$CONFIGURATION/net$VERSION/HttpStress.dll $HTTPSTRESS_ARGS +ENV STRESS_ROLE='' +ENV STRESS_ARGS='' + +# configure adress sanitizer +# Make sure ASAN_OPTIONS are compatible with CoreCLR: https://github.com/dotnet/runtime/blob/300485de6f5bf52c28192da930e1aa79cfef46df/src/native/minipal/sansupport.c#L18 +ENV ASAN_OPTIONS='symbolize=1 use_sigaltstack=0 detect_leaks=0 handle_segv=0 allocator_may_return_null=1' +ENV LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/13/libasan.so + +CMD ./entrypoint.sh diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj index b98a4bd529c76a..e0b901b9f6224d 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj @@ -6,6 +6,8 @@ True CA2252 true + + https://api.nuget.org/v3/index.json;https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json @@ -13,7 +15,7 @@ - + diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs index 0f47ae1b232fd9..c2e704b6bd8b00 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs @@ -16,8 +16,8 @@ using System.Net.Quic; using Microsoft.Quic; -[assembly:SupportedOSPlatform("windows")] -[assembly:SupportedOSPlatform("linux")] +[assembly: SupportedOSPlatform("windows")] +[assembly: SupportedOSPlatform("linux")] namespace HttpStress { @@ -30,6 +30,8 @@ public enum ExitCode { Success = 0, StressError = 1, CliError = 2 }; public static readonly bool IsQuicSupported = QuicListener.IsSupported && QuicConnection.IsSupported; + private static readonly Dictionary s_unobservedExceptions = new Dictionary(); + public static async Task Main(string[] args) { if (!TryParseCli(args, out Configuration? config)) @@ -43,76 +45,86 @@ public static async Task Main(string[] args) private static bool TryParseCli(string[] args, [NotNullWhen(true)] out Configuration? config) { var cmd = new RootCommand(); - cmd.AddOption(new Option("-n", "Max number of requests to make concurrently.") { Argument = new Argument("numWorkers", Environment.ProcessorCount) }); - cmd.AddOption(new Option("-serverUri", "Stress suite server uri.") { Argument = new Argument("serverUri", "https://localhost:5001") }); - cmd.AddOption(new Option("-runMode", "Stress suite execution mode. Defaults to Both.") { Argument = new Argument("runMode", RunMode.both) }); - cmd.AddOption(new Option("-maxExecutionTime", "Maximum stress execution time, in minutes. Defaults to infinity.") { Argument = new Argument("minutes", null) }); - cmd.AddOption(new Option("-maxContentLength", "Max content length for request and response bodies.") { Argument = new Argument("numBytes", 1000) }); - cmd.AddOption(new Option("-maxRequestUriSize", "Max query string length support by the server.") { Argument = new Argument("numChars", 5000) }); - cmd.AddOption(new Option("-maxRequestHeaderCount", "Maximum number of headers to place in request") { Argument = new Argument("numHeaders", 90) }); - cmd.AddOption(new Option("-maxRequestHeaderTotalSize", "Max request header total size.") { Argument = new Argument("numBytes", 1000) }); - cmd.AddOption(new Option("-http", "HTTP version (1.1 or 2.0 or 3.0)") { Argument = new Argument("version", HttpVersion.Version20) }); - cmd.AddOption(new Option("-connectionLifetime", "Max connection lifetime length (milliseconds).") { Argument = new Argument("connectionLifetime", null) }); - cmd.AddOption(new Option("-ops", "Indices of the operations to use") { Argument = new Argument("space-delimited indices", null) }); - cmd.AddOption(new Option("-xops", "Indices of the operations to exclude") { Argument = new Argument("space-delimited indices", null) }); - cmd.AddOption(new Option("-trace", "Enable System.Net.Http.InternalDiagnostics (client) and/or ASP.NET dignostics (server) tracing.") { Argument = new Argument("enable", false) }); - cmd.AddOption(new Option("-aspnetlog", "Enable ASP.NET warning and error logging.") { Argument = new Argument("enable", false) }); - cmd.AddOption(new Option("-listOps", "List available options.") { Argument = new Argument("enable", false) }); - cmd.AddOption(new Option("-seed", "Seed for generating pseudo-random parameters for a given -n argument.") { Argument = new Argument("seed", null) }); - cmd.AddOption(new Option("-numParameters", "Max number of query parameters or form fields for a request.") { Argument = new Argument("queryParameters", 1) }); - cmd.AddOption(new Option("-cancelRate", "Number between 0 and 1 indicating rate of client-side request cancellation attempts. Defaults to 0.1.") { Argument = new Argument("probability", 0.1) }); - cmd.AddOption(new Option("-httpSys", "Use http.sys instead of Kestrel.") { Argument = new Argument("enable", false) }); - cmd.AddOption(new Option("-winHttp", "Use WinHttpHandler for the stress client.") { Argument = new Argument("enable", false) }); - cmd.AddOption(new Option("-displayInterval", "Client stats display interval in seconds. Defaults to 5 seconds.") { Argument = new Argument("seconds", 5) }); - cmd.AddOption(new Option("-clientTimeout", "Default HttpClient timeout in seconds. Defaults to 60 seconds.") { Argument = new Argument("seconds", 60) }); - cmd.AddOption(new Option("-serverMaxConcurrentStreams", "Overrides kestrel max concurrent streams per connection.") { Argument = new Argument("streams", null) }); - cmd.AddOption(new Option("-serverMaxFrameSize", "Overrides kestrel max frame size setting.") { Argument = new Argument("bytes", null) }); - cmd.AddOption(new Option("-serverInitialConnectionWindowSize", "Overrides kestrel initial connection window size setting.") { Argument = new Argument("bytes", null) }); - cmd.AddOption(new Option("-serverMaxRequestHeaderFieldSize", "Overrides kestrel max request header field size.") { Argument = new Argument("bytes", null) }); + cmd.Options.Add(new Option("-n") { Description = "Max number of requests to make concurrently.", DefaultValueFactory = (_) => Environment.ProcessorCount }); + cmd.Options.Add(new Option("-serverUri") { Description = "Stress suite server uri.", DefaultValueFactory = (_) => "https://localhost:5001" }); + cmd.Options.Add(new Option("-runMode") { Description = "Stress suite execution mode. Defaults to Both.", DefaultValueFactory = (_) => RunMode.both }); + cmd.Options.Add(new Option("-maxExecutionTime") { Description = "Maximum stress execution time, in minutes. Defaults to infinity." }); + cmd.Options.Add(new Option("-maxContentLength") { Description = "Max content length for request and response bodies.", DefaultValueFactory = (_) => 1000 }); + cmd.Options.Add(new Option("-maxRequestUriSize") { Description = "Max query string length support by the server.", DefaultValueFactory = (_) => 5000 }); + cmd.Options.Add(new Option("-maxRequestHeaderCount") { Description = "Maximum number of headers to place in request", DefaultValueFactory = (_) => 90 }); + cmd.Options.Add(new Option("-maxRequestHeaderTotalSize") { Description = "Max request header total size.", DefaultValueFactory = (_) => 1000 }); + cmd.Options.Add(new Option("-http") + { + Description = "HTTP version (1.1 or 2.0 or 3.0)", + DefaultValueFactory = (_) => HttpVersion.Version20, + CustomParser = result => + { + if (!Version.TryParse(result.Tokens.Single().Value, out Version? parsed)) + { + result.AddError($"'{result.Tokens[0].Value}' is not a valid Version"); + } + + return parsed; + } + }); + cmd.Options.Add(new Option("-connectionLifetime") { Description = "Max connection lifetime length (milliseconds)." }); + cmd.Options.Add(new Option("-ops") { Description = "Indices of the operations to use" }); + cmd.Options.Add(new Option("-xops") { Description = "Indices of the operations to exclude" }); + cmd.Options.Add(new Option("-trace") { Description = "Enable System.Net.Http.InternalDiagnostics (client) and/or ASP.NET dignostics (server) tracing." }); + cmd.Options.Add(new Option("-aspnetlog") { Description = "Enable ASP.NET warning and error logging." }); + cmd.Options.Add(new Option("-listOps") { Description = "List available options." }); + cmd.Options.Add(new Option("-seed") { Description = "Seed for generating pseudo-random parameters for a given -n argument." }); + cmd.Options.Add(new Option("-numParameters") { Description = "Max number of query parameters or form fields for a request.", DefaultValueFactory = (_) => 1 }); + cmd.Options.Add(new Option("-cancelRate") { Description = "Number between 0 and 1 indicating rate of client-side request cancellation attempts. Defaults to 0.1.", DefaultValueFactory = (_) => 0.1 }); + cmd.Options.Add(new Option("-httpSys") { Description = "Use http.sys instead of Kestrel." }); + cmd.Options.Add(new Option("-winHttp") { Description = "Use WinHttpHandler for the stress client." }); + cmd.Options.Add(new Option("-displayInterval") { Description = "Client stats display interval in seconds. Defaults to 5 seconds.", DefaultValueFactory = (_) => 5 }); + cmd.Options.Add(new Option("-clientTimeout") { Description = "Default HttpClient timeout in seconds. Defaults to 60 seconds.", DefaultValueFactory = (_) => 60 }); + cmd.Options.Add(new Option("-serverMaxConcurrentStreams") { Description = "Overrides kestrel max concurrent streams per connection." }); + cmd.Options.Add(new Option("-serverMaxFrameSize") { Description = "Overrides kestrel max frame size setting." }); + cmd.Options.Add(new Option("-serverInitialConnectionWindowSize") { Description = "Overrides kestrel initial connection window size setting." }); + cmd.Options.Add(new Option("-serverMaxRequestHeaderFieldSize") { Description = "Overrides kestrel max request header field size." }); + cmd.Options.Add(new Option("-unobservedEx") { Description = "Enable tracking unobserved exceptions." }); ParseResult cmdline = cmd.Parse(args); if (cmdline.Errors.Count > 0) { - foreach (ParseError error in cmdline.Errors) - { - Console.WriteLine(error); - } - Console.WriteLine(); - new HelpBuilder(new SystemConsole()).Write(cmd); + cmdline.Invoke(); // this is going to print all the errors and help config = null; return false; } config = new Configuration() { - RunMode = cmdline.ValueForOption("-runMode"), - ServerUri = cmdline.ValueForOption("-serverUri"), - ListOperations = cmdline.ValueForOption("-listOps"), - - HttpVersion = cmdline.ValueForOption("-http"), - UseWinHttpHandler = cmdline.ValueForOption("-winHttp"), - ConcurrentRequests = cmdline.ValueForOption("-n"), - RandomSeed = cmdline.ValueForOption("-seed") ?? new Random().Next(), - MaxContentLength = cmdline.ValueForOption("-maxContentLength"), - MaxRequestUriSize = cmdline.ValueForOption("-maxRequestUriSize"), - MaxRequestHeaderCount = cmdline.ValueForOption("-maxRequestHeaderCount"), - MaxRequestHeaderTotalSize = cmdline.ValueForOption("-maxRequestHeaderTotalSize"), - OpIndices = cmdline.ValueForOption("-ops"), - ExcludedOpIndices = cmdline.ValueForOption("-xops"), - MaxParameters = cmdline.ValueForOption("-numParameters"), - DisplayInterval = TimeSpan.FromSeconds(cmdline.ValueForOption("-displayInterval")), - DefaultTimeout = TimeSpan.FromSeconds(cmdline.ValueForOption("-clientTimeout")), - ConnectionLifetime = cmdline.ValueForOption("-connectionLifetime").Select(TimeSpan.FromMilliseconds), - CancellationProbability = Math.Max(0, Math.Min(1, cmdline.ValueForOption("-cancelRate"))), - MaximumExecutionTime = cmdline.ValueForOption("-maxExecutionTime").Select(TimeSpan.FromMinutes), - - UseHttpSys = cmdline.ValueForOption("-httpSys"), - LogAspNet = cmdline.ValueForOption("-aspnetlog"), - Trace = cmdline.ValueForOption("-trace"), - ServerMaxConcurrentStreams = cmdline.ValueForOption("-serverMaxConcurrentStreams"), - ServerMaxFrameSize = cmdline.ValueForOption("-serverMaxFrameSize"), - ServerInitialConnectionWindowSize = cmdline.ValueForOption("-serverInitialConnectionWindowSize"), - ServerMaxRequestHeaderFieldSize = cmdline.ValueForOption("-serverMaxRequestHeaderFieldSize"), + RunMode = cmdline.GetValue("-runMode"), + ServerUri = cmdline.GetValue("-serverUri")!, + ListOperations = cmdline.GetValue("-listOps"), + + HttpVersion = cmdline.GetValue("-http")!, + UseWinHttpHandler = cmdline.GetValue("-winHttp"), + ConcurrentRequests = cmdline.GetValue("-n"), + RandomSeed = cmdline.GetValue("-seed") ?? new Random().Next(), + MaxContentLength = cmdline.GetValue("-maxContentLength"), + MaxRequestUriSize = cmdline.GetValue("-maxRequestUriSize"), + MaxRequestHeaderCount = cmdline.GetValue("-maxRequestHeaderCount"), + MaxRequestHeaderTotalSize = cmdline.GetValue("-maxRequestHeaderTotalSize"), + OpIndices = cmdline.GetValue("-ops"), + ExcludedOpIndices = cmdline.GetValue("-xops"), + MaxParameters = cmdline.GetValue("-numParameters"), + DisplayInterval = TimeSpan.FromSeconds(cmdline.GetValue("-displayInterval")), + DefaultTimeout = TimeSpan.FromSeconds(cmdline.GetValue("-clientTimeout")), + ConnectionLifetime = cmdline.GetValue("-connectionLifetime").Select(TimeSpan.FromMilliseconds), + CancellationProbability = Math.Max(0, Math.Min(1, cmdline.GetValue("-cancelRate"))), + MaximumExecutionTime = cmdline.GetValue("-maxExecutionTime").Select(TimeSpan.FromMinutes), + + UseHttpSys = cmdline.GetValue("-httpSys"), + LogAspNet = cmdline.GetValue("-aspnetlog"), + Trace = cmdline.GetValue("-trace"), + TrackUnobservedExceptions = cmdline.GetValue("-unobservedEx"), + ServerMaxConcurrentStreams = cmdline.GetValue("-serverMaxConcurrentStreams"), + ServerMaxFrameSize = cmdline.GetValue("-serverMaxFrameSize"), + ServerInitialConnectionWindowSize = cmdline.GetValue("-serverInitialConnectionWindowSize"), + ServerMaxRequestHeaderFieldSize = cmdline.GetValue("-serverMaxRequestHeaderFieldSize"), }; return true; @@ -162,8 +174,11 @@ private static async Task Run(Configuration config) string GetAssemblyInfo(Assembly assembly) => $"{assembly.Location}, modified {new FileInfo(assembly.Location).LastWriteTime}"; - Type msQuicApiType = Type.GetType("System.Net.Quic.MsQuicApi, System.Net.Quic"); - string msQuicLibraryVersion = (string)msQuicApiType.GetProperty("MsQuicLibraryVersion", BindingFlags.NonPublic | BindingFlags.Static).GetGetMethod(true).Invoke(null, Array.Empty()); + Type msQuicApiType = Type.GetType("System.Net.Quic.MsQuicApi, System.Net.Quic")!; + string msQuicLibraryVersion = (string)msQuicApiType.GetProperty("MsQuicLibraryVersion", BindingFlags.NonPublic | BindingFlags.Static)!.GetGetMethod(true)!.Invoke(null, Array.Empty())!; + bool trackUnobservedExceptions = config.TrackUnobservedExceptions.HasValue + ? config.TrackUnobservedExceptions.Value + : false; Console.WriteLine(" .NET Core: " + GetAssemblyInfo(typeof(object).Assembly)); Console.WriteLine(" ASP.NET Core: " + GetAssemblyInfo(typeof(WebHost).Assembly)); @@ -184,24 +199,19 @@ private static async Task Run(Configuration config) Console.WriteLine(" Cancellation: " + 100 * config.CancellationProbability + "%"); Console.WriteLine("Max Content Size: " + config.MaxContentLength); Console.WriteLine("Query Parameters: " + config.MaxParameters); + Console.WriteLine(" Unobserved Ex: " + (trackUnobservedExceptions ? "Tracked" : "Not tracked")); Console.WriteLine(); - if (config.HttpVersion == HttpVersion.Version30 && IsQuicSupported) + if (trackUnobservedExceptions) { - unsafe + TaskScheduler.UnobservedTaskException += (_, e) => { - // If the system gets overloaded, MsQuic has a tendency to drop incoming connections, see https://github.com/dotnet/runtime/issues/55979. - // So in case we're running H/3 stress test, we're using the same hack as for System.Net.Quic tests, which increases the time limit for pending operations in MsQuic thread pool. - object msQuicApiInstance = msQuicApiType.GetProperty("Api", BindingFlags.NonPublic | BindingFlags.Static).GetGetMethod(true).Invoke(null, Array.Empty()); - QUIC_API_TABLE* apiTable = (QUIC_API_TABLE*)(Pointer.Unbox(msQuicApiType.GetProperty("ApiTable").GetGetMethod().Invoke(msQuicApiInstance, Array.Empty()))); - QUIC_SETTINGS settings = default(QUIC_SETTINGS); - settings.IsSet.MaxWorkerQueueDelayUs = 1; - settings.MaxWorkerQueueDelayUs = 2_500_000u; // 2.5s, 10x the default - if (MsQuic.StatusFailed(apiTable->SetParam(null, MsQuic.QUIC_PARAM_GLOBAL_SETTINGS, (uint)sizeof(QUIC_SETTINGS), (byte*)&settings))) + lock (s_unobservedExceptions) { - Console.WriteLine($"Unable to set MsQuic MaxWorkerQueueDelayUs."); + string text = e.Exception.ToString(); + s_unobservedExceptions[text] = s_unobservedExceptions.GetValueOrDefault(text) + 1; } - } + }; } StressServer? server = null; @@ -228,8 +238,34 @@ private static async Task Run(Configuration config) client?.Stop(); client?.PrintFinalReport(); + if (trackUnobservedExceptions) + { + PrintUnobservedExceptions(); + } + // return nonzero status code if there are stress errors - return client?.TotalErrorCount == 0 ? ExitCode.Success : ExitCode.StressError; + return client?.TotalErrorCount == 0 && s_unobservedExceptions.Count == 0 ? ExitCode.Success : ExitCode.StressError; + } + + private static void PrintUnobservedExceptions() + { + if (s_unobservedExceptions.Count == 0) + { + Console.WriteLine("No unobserved exceptions detected."); + return; + } + + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.WriteLine($"Detected {s_unobservedExceptions.Count} unobserved exceptions:"); + Console.ResetColor(); + + int i = 1; + foreach (KeyValuePair kv in s_unobservedExceptions.OrderByDescending(p => p.Value)) + { + Console.WriteLine($"Exception type {i++}/{s_unobservedExceptions.Count} (hit {kv.Value} times):"); + Console.WriteLine(kv.Key); + Console.WriteLine(); + } } private static async Task WaitUntilMaxExecutionTimeElapsedOrKeyboardInterrupt(TimeSpan? maxExecutionTime = null) diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressClient.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressClient.cs index 4abd52e025edf5..b28479251c0d67 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressClient.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressClient.cs @@ -57,6 +57,7 @@ HttpMessageHandler CreateHttpHandler() return new SocketsHttpHandler() { PooledConnectionLifetime = _config.ConnectionLifetime.GetValueOrDefault(Timeout.InfiniteTimeSpan), + EnableMultipleHttp2Connections = true, SslOptions = new SslClientAuthenticationOptions { RemoteCertificateValidationCallback = delegate { return true; } diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs index 8eaa167fef1a8d..351220837429e8 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs @@ -52,7 +52,7 @@ public StressServer(Configuration configuration) if (configuration.UseHttpSys && OperatingSystem.IsWindows()) { // Use http.sys. This requires additional manual configuration ahead of time; - // see https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/httpsys?view=aspnetcore-2.2#configure-windows-server. + // see https://learn.microsoft.com/aspnet/core/fundamentals/servers/httpsys?view=aspnetcore-2.2#configure-windows-server. // In particular, you need to: // 1. Create a self-signed cert and install it into your local personal store, e.g. New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation "cert:\LocalMachine\My" // 2. Pre-register the URL prefix, e.g. netsh http add urlacl url=https://localhost:5001/ user=Users diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.ps1 b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.ps1 index 2530b5cbb2bfd6..de6f0119c04986 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.ps1 +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.ps1 @@ -3,61 +3,5 @@ ## Usage: ## ./build-local.ps1 [StressConfiguration] [LibrariesConfiguration] -$Version="8.0" $RepoRoot="$(git rev-parse --show-toplevel)" -$DailyDotnetRoot= "./.dotnet-daily" - -$StressConfiguration = "Release" -if (-not ([string]::IsNullOrEmpty($args[0]))) { - $StressConfiguration = $args[0] -} - -$LibrariesConfiguration = "Release" -if (-not ([string]::IsNullOrEmpty($args[1]))) { - $LibrariesConfiguration = $args[1] -} - -$TestHostRoot="$RepoRoot/artifacts/bin/testhost/net$Version-windows-$LibrariesConfiguration-x64" - -Write-Host "StressConfiguration: $StressConfiguration, LibrariesConfiguration: $LibrariesConfiguration, testhost: $TestHostRoot" - -if (-not (Test-Path -Path $TestHostRoot)) { - Write-Host "Cannot find testhost in: $TestHostRoot" - Write-Host "Make sure libraries with the requested configuration are built!" - Write-Host "Usage:" - Write-Host "./build-local.sh [StressConfiguration] [LibrariesConfiguration]" - Write-Host "StressConfiguration and LibrariesConfiguration default to Release!" - exit 1 -} - -if (-not (Test-Path -Path $DailyDotnetRoot)) { - Write-Host "Downloading daily SDK to: $DailyDotnetRoot" - New-Item -ItemType Directory -Path $DailyDotnetRoot - Invoke-WebRequest -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile "$DailyDotnetRoot\dotnet-install.ps1" - & "$DailyDotnetRoot\dotnet-install.ps1" -NoPath -Channel $Version -Quality daily -InstallDir $DailyDotnetRoot -} else { - Write-Host "Daily SDK found in $DailyDotnetRoot" -} - -$env:DOTNET_ROOT=$DailyDotnetRoot -$env:PATH="$DailyDotnetRoot;$env:PATH" -$env:DOTNET_MULTILEVEL_LOOKUP=0 - -if (-not (Test-Path -Path "$TestHostRoot/shared/Microsoft.AspNetCore.App")) { - Write-Host "Copying Microsoft.AspNetCore.App bits from daily SDK to testhost: $TestHostRoot" - Copy-Item -Recurse -Path "$DailyDotnetRoot/shared/Microsoft.AspNetCore.App" -Destination "$TestHostRoot/shared" -} else { - Write-Host "Microsoft.AspNetCore.App found in testhost: $TestHostRoot" -} - -Write-Host "Building solution." -dotnet build -c $StressConfiguration - -$Runscript=".\run-stress-$StressConfiguration-$LibrariesConfiguration.ps1" -if (-not (Test-Path $Runscript)) { - Write-Host "Generating Runscript." - Add-Content -Path $Runscript -Value "& '$TestHostRoot/dotnet' exec --roll-forward Major ./bin/$StressConfiguration/net$Version/HttpStress.dll `$args" -} - -Write-Host "To run tests type:" -Write-Host "$Runscript [stress test args]" +&$RepoRoot/src/libraries/Common/tests/System/Net/StressTests/build-local.ps1 $PSScriptRoot @args diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.sh b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.sh index 0fd20073a7305b..750bb6417efb93 100755 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.sh +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/build-local.sh @@ -1,67 +1,24 @@ #!/usr/bin/env bash -## This is a helper script for non-containerized local build and test execution. -## It downloads and uses the daily SDK which contains the compatible AspNetCore bits. -## Usage: -## ./build-local.sh [StressConfiguration] [LibrariesConfiguration] +# Stop script if unbound variable found (use ${var:-} if intentional) +set -u -version=8.0 -repo_root=$(git rev-parse --show-toplevel) -daily_dotnet_root=./.dotnet-daily +# Stop script if command returns non-zero exit code. +# Prevents hidden errors caused by missing error code propagation. +set -e -stress_configuration="Release" -if [ "$1" != "" ]; then - stress_configuration=${1,,} # Lowercase all characters in $1 - stress_configuration=${stress_configuration^} # Uppercase first character -fi +source="${BASH_SOURCE[0]}" -libraries_configuration="Release" -if [ "$2" != "" ]; then - libraries_configuration=${2,,} # Lowercase all characters in $1 - libraries_configuration=${libraries_configuration^} # Uppercase first character -fi +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" +repo_root=$(git -C "$scriptroot" rev-parse --show-toplevel) -testhost_root=$repo_root/artifacts/bin/testhost/net$version-linux-$libraries_configuration-x64 -echo "StressConfiguration: $stress_configuration, LibrariesConfiguration: $libraries_configuration, testhost: $testhost_root" +"$repo_root/src/libraries/Common/tests/System/Net/StressTests/build-local.sh" "$scriptroot" "$@" -if [[ ! -d $testhost_root ]]; then - echo "Cannot find testhost in: $testhost_root" - echo "Make sure libraries with the requested configuration are built!" - echo "Usage:" - echo "./build-local.sh [StressConfiguration] [LibrariesConfiguration]" - echo "StressConfiguration and LibrariesConfiguration default to Release!" - exit 1 -fi - -if [[ ! -d $daily_dotnet_root ]]; then - echo "Downloading daily SDK to $daily_dotnet_root" - mkdir $daily_dotnet_root - wget https://dot.net/v1/dotnet-install.sh -O $daily_dotnet_root/dotnet-install.sh - bash $daily_dotnet_root/dotnet-install.sh --no-path --channel $version --quality daily --install-dir $daily_dotnet_root -else - echo "Daily SDK found in $daily_dotnet_root" -fi - -export DOTNET_ROOT=$daily_dotnet_root -export PATH=$DOTNET_ROOT:$PATH -export DOTNET_MULTILEVEL_LOOKUP=0 - -if [[ ! -d "$testhost_root/shared/Microsoft.AspNetCore.App" ]]; then - echo "Copying Microsoft.AspNetCore.App bits from daily SDK to testhost: $testhost_root" - cp -r $daily_dotnet_root/shared/Microsoft.AspNetCore.App $testhost_root/shared/Microsoft.AspNetCore.App -else - echo "Microsoft.AspNetCore.App found in testhost: $testhost_root" -fi - -echo "Building solution." -dotnet build -c $stress_configuration - -runscript=./run-stress-${stress_configuration,,}-${libraries_configuration,,}.sh -if [[ ! -f $runscript ]]; then - echo "Generating runscript." - echo "$testhost_root/dotnet exec --roll-forward Major ./bin/$stress_configuration/net$version/HttpStress.dll \$@" > $runscript - chmod +x $runscript -fi - -echo "To run tests type:" -echo "$runscript [stress test args]" diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/docker-compose.yml b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/docker-compose.yml index c22be392756f26..ddce0b945ea6fd 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/docker-compose.yml +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/docker-compose.yml @@ -1,4 +1,4 @@ -version: '3' +version: '3' # Although the version attribute is obsolete and should be ignored, it's seemingly not the case on Build.Ubuntu.2204.Amd64.Open services: client: build: @@ -6,19 +6,23 @@ services: dockerfile: ${DOCKERFILE:-Dockerfile} image: httpstress volumes: - - "${CLIENT_DUMPS_SHARE}:${DUMPS_SHARE_MOUNT_ROOT}" + - "${DUMPS_SHARE}:${DUMPS_SHARE_MOUNT_ROOT}" links: - server environment: - - HTTPSTRESS_ARGS=-runMode client -serverUri https://server:5001 ${HTTPSTRESS_CLIENT_ARGS} + - STRESS_ARGS=-runMode client -serverUri https://server:5001 ${STRESS_CLIENT_ARGS} + - STRESS_ROLE=client + - DUMPS_SHARE_MOUNT_ROOT=${DUMPS_SHARE_MOUNT_ROOT} server: build: context: . dockerfile: ${DOCKERFILE:-Dockerfile} image: httpstress volumes: - - "${SERVER_DUMPS_SHARE}:${DUMPS_SHARE_MOUNT_ROOT}" + - "${DUMPS_SHARE}:${DUMPS_SHARE_MOUNT_ROOT}" ports: - "5001:5001" environment: - - HTTPSTRESS_ARGS=-runMode server -serverUri https://+:5001 ${HTTPSTRESS_SERVER_ARGS} + - STRESS_ARGS=-runMode server -serverUri https://+:5001 ${STRESS_SERVER_ARGS} + - STRESS_ROLE=server + - DUMPS_SHARE_MOUNT_ROOT=${DUMPS_SHARE_MOUNT_ROOT} diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/entrypoint.ps1 b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/entrypoint.ps1 new file mode 100644 index 00000000000000..d2e5d8f6033897 --- /dev/null +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/entrypoint.ps1 @@ -0,0 +1,21 @@ +New-Item -Path $env:DUMPS_SHARE_MOUNT_ROOT/$env:STRESS_ROLE -ItemType Directory -ErrorAction SilentlyContinue + +# Enable dump collection +$env:DOTNET_DbgEnableMiniDump = '1' +$env:DOTNET_DbgMiniDumpType = "MiniDumpWithFullMemory" +$env:DOTNET_DbgMiniDumpName = "$env:DUMPS_SHARE_MOUNT_ROOT/$env:STRESS_ROLE/coredump.%p.%t" + +& "C:/live-runtime-artifacts/testhost/net$env:VERSION-windows-$env:CONFIGURATION-x64/dotnet" exec --roll-forward Major ./bin/$env:CONFIGURATION/net$env:VERSION/HttpStress.dll $env:STRESS_ARGS.Split(' ',[System.StringSplitOptions]::RemoveEmptyEntries) + +$ExitCode = $LASTEXITCODE + +if ($ExitCode -ne 0) { + Write-Host "HttpStress failed, copying artifacts for investigation" + + # Copy runtime if it's not already there + if ($env:DUMPS_SHARE_MOUNT_ROOT -and !(Test-Path -Path $env:DUMPS_SHARE_MOUNT_ROOT/net$env:VERSION-windows-$env:CONFIGURATION-x64/ -ErrorAction SilentlyContinue)) { + Copy-Item -Recurse C:/live-runtime-artifacts/testhost/net$env:VERSION-windows-$env:CONFIGURATION-x64/ $env:DUMPS_SHARE_MOUNT_ROOT/ + } +} + +exit $ExitCode diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/entrypoint.sh b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/entrypoint.sh new file mode 100755 index 00000000000000..25001081e26074 --- /dev/null +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/entrypoint.sh @@ -0,0 +1,25 @@ +mkdir -p $DUMPS_SHARE_MOUNT_ROOT/$STRESS_ROLE + +ulimit -c unlimited + +# Enable dump collection +export DOTNET_DbgEnableMiniDump=1 +export DOTNET_DbgMiniDumpType=MiniDumpWithFullMemory +export DOTNET_DbgMiniDumpName="$DUMPS_SHARE_MOUNT_ROOT/$STRESS_ROLE/coredump.%p.%t" + +/live-runtime-artifacts/testhost/net$VERSION-linux-$CONFIGURATION-x64/dotnet exec --roll-forward Major ./bin/$CONFIGURATION/net$VERSION/HttpStress.dll $STRESS_ARGS + +exit_code=$? + +if [ $exit_code -ne 0 ]; then + echo "HttpStress failed, copying artifacts for investigation" + + if [ ! -d "$DUMPS_SHARE_MOUNT_ROOT/net$VERSION-linux-$CONFIGURATION-x64" ] && [ -n "$DUMPS_SHARE_MOUNT_ROOT" ]; then + # copy runtime artifacts and msquic + cp -r /live-runtime-artifacts/testhost/net$VERSION-linux-$CONFIGURATION-x64/ $DUMPS_SHARE_MOUNT_ROOT + mkdir -p $DUMPS_SHARE_MOUNT_ROOT/msquic + cp /msquic/msquic/build/bin/Debug/libmsquic.so.2 $DUMPS_SHARE_MOUNT_ROOT/msquic + fi +fi + +exit $exit_code diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.ps1 b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.ps1 index ffa44284191ad7..e26c6df7be5126 100755 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.ps1 +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.ps1 @@ -1,100 +1,4 @@ #!/usr/bin/env pwsh # Runs the stress test using docker-compose - -[CmdletBinding(PositionalBinding=$false)] -Param( - [string][Alias('c')]$configuration = "Release", # Build configuration for libraries and stress suite - [switch][Alias('w')]$useWindowsContainers, # Use windows containers, if available - [switch][Alias('b')]$buildCurrentLibraries, # Drives the stress test using libraries built from current source - [switch][Alias('pa')]$privateAspNetCore, # Drive the stress test using a private Asp.Net Core package, requires -b to be set - [switch][Alias('o')]$buildOnly, # Build, but do not run the stress app - [string][Alias('t')]$sdkImageName, # Name of the sdk image name, if built from source. - [string]$clientStressArgs = "", - [string]$serverStressArgs = "" -) - -$REPO_ROOT_DIR = $(git -C "$PSScriptRoot" rev-parse --show-toplevel) -$COMPOSE_FILE = "$PSScriptRoot/docker-compose.yml" - -# This is a workaround for an issue with 1es-windows-2022-open, which should be eventually removed. -# See comments in /eng/pipelines/libraries/stress/http.yml for more info. -$dockerComposeCmd = $env:DOCKER_COMPOSE_CMD -if (!(Test-Path $dockerComposeCmd)) { - $dockerComposeCmd = "docker-compose" -} - -# Build runtime libraries and place in a docker image - -if ($buildCurrentLibraries) -{ - if ([string]::IsNullOrEmpty($sdkImageName)) - { - $sdkImageName = "dotnet-sdk-libs-current" - } - - $LIBRARIES_BUILD_ARGS = " -t $sdkImageName -c $configuration" - if($useWindowsContainers) - { - $LIBRARIES_BUILD_ARGS += " -w" - } - if($privateAspNetCore) - { - $LIBRARIES_BUILD_ARGS += " -p" - } - - Invoke-Expression "& $REPO_ROOT_DIR/eng/docker/build-docker-sdk.ps1 $LIBRARIES_BUILD_ARGS" - - if (!$?) { exit 1 } -} -elseif ($privateAspNetCore) { - write-output "Using a private Asp.Net Core package (-pa) requires using privately built libraries. Please, enable it with -b switch." - write-output "USAGE: . $($MyInvocation.InvocationName) -b -pa " - exit 1 -} - -# Dockerize the stress app using docker-compose - -$BUILD_ARGS = "" -if (![string]::IsNullOrEmpty($sdkImageName)) -{ - $BUILD_ARGS += " --build-arg SDK_BASE_IMAGE=$sdkImageName" -} -if ($useWindowsContainers) -{ - $env:DOCKERFILE="windows.Dockerfile" -} - -$originalErrorPreference = $ErrorActionPreference -$ErrorActionPreference = 'Continue' -try { - & $dockerComposeCmd --log-level DEBUG --file "$COMPOSE_FILE" build $BUILD_ARGS.Split() 2>&1 | ForEach-Object { "$_" } - if ($LASTEXITCODE -ne 0) { - throw "docker-compose exited with error code $LASTEXITCODE" - } -} -finally { - $ErrorActionPreference = $originalErrorPreference -} - -# Run the stress app - -if (!$buildOnly) -{ - if ($useWindowsContainers) { - $env:DUMPS_SHARE_MOUNT_ROOT="C:/dumps-share" - } else { - $env:DUMPS_SHARE_MOUNT_ROOT="/dumps-share" - } - if (!$env:CLIENT_DUMPS_SHARE) { - $env:CLIENT_DUMPS_SHARE=Join-Path $env:Temp $(New-Guid) - } - if (!$env:SERVER_DUMPS_SHARE) { - $env:SERVER_DUMPS_SHARE=Join-Path $env:Temp $(New-Guid) - } - New-Item -Force $env:CLIENT_DUMPS_SHARE -ItemType Directory - New-Item -Force $env:SERVER_DUMPS_SHARE -ItemType Directory - - $env:HTTPSTRESS_CLIENT_ARGS = $clientStressArgs - $env:HTTPSTRESS_SERVER_ARGS = $serverStressArgs - & $dockerComposeCmd --file "$COMPOSE_FILE" up --abort-on-container-exit -} +$RepoRoot = $(git -C $PSScriptRoot rev-parse --show-toplevel) +Invoke-Expression "& `"$RepoRoot/src/libraries/Common/tests/System/Net/StressTests/run-docker-compose.ps1`" -TestProjectDir `"$PSScriptRoot`" $args" diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.sh b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.sh index a43ae9759172a5..302523751e182e 100755 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.sh +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.sh @@ -20,76 +20,6 @@ while [[ -h "$source" ]]; do done scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" -imagename="dotnet-sdk-libs-current" -configuration="Release" -buildcurrentlibraries=0 -buildonly=0 -clientstressargs="" -serverstressargs="" +repo_root=$(git -C "$scriptroot" rev-parse --show-toplevel) -while [[ $# > 0 ]]; do - opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" - case "$opt" in - -sdkimagename|-t) - imagename=$2 - shift 2 - ;; - -configuration|-c) - configuration=$2 - shift 2 - ;; - -buildcurrentlibraries|-b) - buildcurrentlibraries=1 - shift 1 - ;; - -buildonly|-o) - buildonly=1 - shift 1 - ;; - -clientstressargs) - clientstressargs=$2 - shift 2 - ;; - -serverstressargs) - serverstressargs=$2 - shift 2 - ;; - *) - shift 1 - ;; - esac -done - -repo_root=$(git rev-parse --show-toplevel) - -if [[ "$buildcurrentlibraries" -eq 1 ]]; then - libraries_args=" -t $imagename -c $configuration" - - if ! "$repo_root"/eng/docker/build-docker-sdk.sh $libraries_args; then - exit 1 - fi -fi - -build_args="" -if [[ -n "$imagename" ]]; then - build_args=" --build-arg SDK_BASE_IMAGE=$imagename" -fi - -compose_file="$scriptroot/docker-compose.yml" - -if ! docker-compose --file "$compose_file" build $build_args; then - exit $? -fi - -if [[ "$buildonly" -eq 0 ]]; then - export DUMPS_SHARE_MOUNT_ROOT="/dumps-share" - export CLIENT_DUMPS_SHARE="${CLIENT_DUMPS_SHARE:-$(mktemp -d)}" - export SERVER_DUMPS_SHARE="${SERVER_DUMPS_SHARE:-$(mktemp -d)}" - mkdir -p ${CLIENT_DUMPS_SHARE} - mkdir -p ${SERVER_DUMPS_SHARE} - - export HTTPSTRESS_CLIENT_ARGS=$clientstressargs - export HTTPSTRESS_SERVER_ARGS=$serverstressargs - docker-compose --file "$compose_file" up --abort-on-container-exit - exit $? -fi +"$repo_root/src/libraries/Common/tests/System/Net/StressTests/run-docker-compose.sh" "$scriptroot" "$@" diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/windows.Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/windows.Dockerfile index b090d4eb246364..2c8cc16f6dcdfb 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/windows.Dockerfile +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/windows.Dockerfile @@ -1,5 +1,5 @@ # escape=` -ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:7.0-nanoserver-ltsc2022 +ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:8.0-nanoserver-ltsc2022 FROM $SDK_BASE_IMAGE # Use powershell as the default shell @@ -12,21 +12,17 @@ ARG VERSION=8.0 ARG CONFIGURATION=Release RUN dotnet build -c $env:CONFIGURATION ` + -p:NetCoreAppCurrentVersion=$env:VERSION ` -p:MsQuicInteropIncludes="C:/live-runtime-artifacts/msquic-interop/*.cs" ` -p:TargetingPacksTargetsLocation=C:/live-runtime-artifacts/targetingpacks.targets ` -p:MicrosoftNetCoreAppRefPackDir=C:/live-runtime-artifacts/microsoft.netcore.app.ref/ ` -p:MicrosoftNetCoreAppRuntimePackDir=C:/live-runtime-artifacts/microsoft.netcore.app.runtime.win-x64/$env:CONFIGURATION/ -# Enable dump collection -ENV DOTNET_DbgEnableMiniDump=1 -ENV DOTNET_DbgMiniDumpType=MiniDumpWithFullMemory -ENV DOTNET_DbgMiniDumpName="C:/dumps-share/coredump.%p" - EXPOSE 5001 ENV VERSION=$VERSION ENV CONFIGURATION=$CONFIGURATION -ENV HTTPSTRESS_ARGS="" +ENV STRESS_ROLE='' +ENV STRESS_ARGS='' -CMD & C:/live-runtime-artifacts/testhost/net$env:VERSION-windows-$env:CONFIGURATION-x64/dotnet.exe exec --roll-forward Major ` - ./bin/$env:CONFIGURATION/net$env:VERSION/HttpStress.dll $env:HTTPSTRESS_ARGS.Split(' ',[System.StringSplitOptions]::RemoveEmptyEntries) \ No newline at end of file +CMD ./entrypoint.ps1 diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Build-Local.ps1 b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Build-Local.ps1 index 5130812a295a5e..de6f0119c04986 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Build-Local.ps1 +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Build-Local.ps1 @@ -3,58 +3,5 @@ ## Usage: ## ./build-local.ps1 [StressConfiguration] [LibrariesConfiguration] -# Note that this script does much less than it's counterpart in HttpStress. -# In SslStress it's a thin utility to generate a runscript for running the app with the live-built testhost. -# The main reason to use an equivalent solution in SslStress is consistency with HttpStress. - -$Version="8.0" $RepoRoot="$(git rev-parse --show-toplevel)" -$DailyDotnetRoot= "./.dotnet-daily" - -$StressConfiguration = "Release" -if (-not ([string]::IsNullOrEmpty($args[0]))) { - $StressConfiguration = $args[0] -} - -$LibrariesConfiguration = "Release" -if (-not ([string]::IsNullOrEmpty($args[1]))) { - $LibrariesConfiguration = $args[0] -} - -$TestHostRoot="$RepoRoot/artifacts/bin/testhost/net$Version-windows-$LibrariesConfiguration-x64" - -Write-Host "StressConfiguration: $StressConfiguration, LibrariesConfiguration: $LibrariesConfiguration, testhost: $TestHostRoot" - -if (-not (Test-Path -Path $TestHostRoot)) { - Write-Host "Cannot find testhost in: $TestHostRoot" - Write-Host "Make sure libraries with the requested configuration are built!" - Write-Host "Usage:" - Write-Host "./build-local.sh [StressConfiguration] [LibrariesConfiguration]" - Write-Host "StressConfiguration and LibrariesConfiguration default to Release!" - exit 1 -} - -if (-not (Test-Path -Path $DailyDotnetRoot)) { - Write-Host "Downloading daily SDK to: $DailyDotnetRoot" - New-Item -ItemType Directory -Path $DailyDotnetRoot - Invoke-WebRequest -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile "$DailyDotnetRoot\dotnet-install.ps1" - & "$DailyDotnetRoot\dotnet-install.ps1" -NoPath -Channel $Version -Quality daily -InstallDir $DailyDotnetRoot -} else { - Write-Host "Daily SDK found in $DailyDotnetRoot" -} - -$env:DOTNET_ROOT=$DailyDotnetRoot -$env:PATH="$DailyDotnetRoot;$env:PATH" -$env:DOTNET_MULTILEVEL_LOOKUP=0 - -Write-Host "Building solution." -dotnet build -c $StressConfiguration - -$Runscript=".\run-stress-$LibrariesConfiguration-$StressConfiguration.ps1" -if (-not (Test-Path $Runscript)) { - Write-Host "Generating Runscript." - Add-Content -Path $Runscript -Value "& '$TestHostRoot/dotnet' exec --roll-forward Major ./bin/$StressConfiguration/net$Version/SslStress.dll `$args" -} - -Write-Host "To run tests type:" -Write-Host "$Runscript [stress test args]" \ No newline at end of file +&$RepoRoot/src/libraries/Common/tests/System/Net/StressTests/build-local.ps1 $PSScriptRoot @args diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.props b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.props index 0183d8b3696f4e..ab8595dbb5c92d 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.props +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.props @@ -1,17 +1,20 @@ - linux-x64 - win-x64 - + linux-x64 + win-x64 + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, global.json))/ - + + + + $(RepositoryRoot)src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/*.cs $(RepositoryRoot)eng/targetingpacks.targets - 8.0.0 - net8.0 - 8.0 + $(MajorVersion).$(MinorVersion) + net$(NetCoreAppCurrentVersion) Microsoft.NETCore.App $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.ref/ - $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.runtime.$(OutputRID)/$(Configuration)/ + $(RepositoryRoot)artifacts/bin/microsoft.netcore.app.runtime.$(TargetRid)/$(Configuration)/ + false - \ No newline at end of file + diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.targets b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.targets index e3ebd0de328758..59c504befee957 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.targets +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Directory.Build.targets @@ -6,6 +6,6 @@ Define this here because the SDK resets it unconditionally in Microsoft.NETCoreSdk.BundledVersions.props. --> - 8.0 + $(NetCoreAppCurrentVersion) \ No newline at end of file diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Dockerfile b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Dockerfile index cfc7bd3e50418d..0767d15db79d74 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Dockerfile +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Dockerfile @@ -1,4 +1,4 @@ -ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:6.0-bullseye-slim +ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:latest FROM $SDK_BASE_IMAGE WORKDIR /app @@ -9,6 +9,7 @@ ARG VERSION=8.0 ARG CONFIGURATION=Release RUN dotnet build -c $CONFIGURATION \ + -p:NetCoreAppCurrentVersion=$VERSION \ -p:TargetingPacksTargetsLocation=/live-runtime-artifacts/targetingpacks.targets \ -p:MicrosoftNetCoreAppRefPackDir=/live-runtime-artifacts/microsoft.netcore.app.ref/ \ -p:MicrosoftNetCoreAppRuntimePackDir=/live-runtime-artifacts/microsoft.netcore.app.runtime.linux-x64/$CONFIGURATION/ @@ -17,7 +18,7 @@ EXPOSE 5001 ENV VERSION=$VERSION ENV CONFIGURATION=$CONFIGURATION -ENV SSLSTRESS_ARGS='' +ENV STRESS_ROLE='' +ENV STRESS_ARGS='' -CMD /live-runtime-artifacts/testhost/net$VERSION-linux-$CONFIGURATION-x64/dotnet exec --roll-forward Major \ - ./bin/$CONFIGURATION/net$VERSION/SslStress.dll $SSLSTRESS_ARGS \ No newline at end of file +CMD ./entrypoint.sh diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Program.cs b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Program.cs index e470e7621a18cf..03f33b516684af 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/Program.cs +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/Program.cs @@ -3,6 +3,7 @@ using System; using System.CommandLine; +using System.CommandLine.Help; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net; @@ -67,6 +68,8 @@ private static async Task Run(Configuration config) Console.WriteLine(); client = new StressClient(config); + + await client.InitializeAsync(); client.Start(); } @@ -74,13 +77,13 @@ private static async Task Run(Configuration config) try { - if (client != null) + if (client != null) { await client.StopAsync(); Console.WriteLine("client stopped"); } - if (server != null) + if (server != null) { await server.StopAsync(); Console.WriteLine("server stopped"); @@ -111,62 +114,66 @@ static async Task WaitUntilMaxExecutionTimeElapsedOrKeyboardInterrupt(TimeSpan? private static bool TryParseCli(string[] args, [NotNullWhen(true)] out Configuration? config) { var cmd = new RootCommand(); - cmd.AddOption(new Option(new[] { "--help", "-h" }, "Display this help text.")); - cmd.AddOption(new Option(new[] { "--mode", "-m" }, "Stress suite execution mode. Defaults to 'both'.") { Argument = new Argument("runMode", RunMode.both) }); - cmd.AddOption(new Option(new[] { "--cancellation-probability", "-p"}, "Cancellation probability 0 <= p <= 1 for a given connection. Defaults to 0.1") { Argument = new Argument("probability", 0.1)}); - cmd.AddOption(new Option(new[] { "--num-connections", "-n" }, "Max number of connections to open concurrently.") { Argument = new Argument("connections", Environment.ProcessorCount) }); - cmd.AddOption(new Option(new[] { "--server-endpoint", "-e" }, "Endpoint to bind to if server, endpoint to listen to if client.") { Argument = new Argument("ipEndpoint", "127.0.0.1:5002") }); - cmd.AddOption(new Option(new[] { "--max-execution-time", "-t" }, "Maximum stress suite execution time, in minutes. Defaults to infinity.") { Argument = new Argument("minutes", null) }); - cmd.AddOption(new Option(new[] { "--max-buffer-length", "-b" }, "Maximum buffer length to write on ssl stream. Defaults to 8192.") { Argument = new Argument("bytes", 8192) }); - cmd.AddOption(new Option(new[] { "--min-connection-lifetime", "-l" }, "Minimum duration for a single connection, in seconds. Defaults to 5 seconds.") { Argument = new Argument("seconds", 5) }); - cmd.AddOption(new Option(new[] { "--max-connection-lifetime", "-L" }, "Maximum duration for a single connection, in seconds. Defaults to 120 seconds.") { Argument = new Argument("seconds", 120) }); - cmd.AddOption(new Option(new[] { "--display-interval", "-i" }, "Client stats display interval, in seconds. Defaults to 5 seconds.") { Argument = new Argument("seconds", 5) }); - cmd.AddOption(new Option(new[] { "--log-server", "-S" }, "Print server logs to stdout.")); - cmd.AddOption(new Option(new[] { "--seed", "-s" }, "Seed for generating pseudo-random parameters. Also depends on the -n argument.") { Argument = new Argument("seed", (new Random().Next())) }); - - ParseResult parseResult = cmd.Parse(args); - if (parseResult.Errors.Count > 0 || parseResult.HasOption("-h")) + cmd.Options.Add(new Option("--mode", "-m") { Description = "Stress suite execution mode. Defaults to 'both'.", DefaultValueFactory = (_) => RunMode.both }); + cmd.Options.Add(new Option("--cancellation-probability", "-p") { Description = "Cancellation probability 0 <= p <= 1 for a given connection. Defaults to 0.1", DefaultValueFactory = (_) => 0.1 }); + cmd.Options.Add(new Option("--num-connections", "-n" ) { Description = "Max number of connections to open concurrently.", DefaultValueFactory = (_) => Environment.ProcessorCount }); + cmd.Options.Add(new Option("--server-endpoint", "-e" ) { - foreach (ParseError error in parseResult.Errors) + Description = "Endpoint to bind to if server, endpoint to listen to if client.", + DefaultValueFactory = (_) => IPEndPoint.Parse("127.0.0.1:5002"), + CustomParser = result => { - Console.WriteLine(error); + try + { + return ParseEndpoint(result.Tokens[0].Value); + } + catch + { + result.AddError($"'{result.Tokens[0].Value}' is not a valid endpoint"); + return default; + } } - WriteHelpText(); + }); + cmd.Options.Add(new Option("--max-execution-time", "-t" ) { Description = "Maximum stress suite execution time, in minutes. Defaults to infinity." }); + cmd.Options.Add(new Option("--max-buffer-length", "-b" ) { Description = "Maximum buffer length to write on ssl stream. Defaults to 8192.", DefaultValueFactory = (_) => 8192 }); + cmd.Options.Add(new Option("--min-connection-lifetime", "-l" ) { Description = "Minimum duration for a single connection, in seconds. Defaults to 5 seconds.", DefaultValueFactory = (_) => 5 }); + cmd.Options.Add(new Option("--max-connection-lifetime", "-L" ) { Description = "Maximum duration for a single connection, in seconds. Defaults to 120 seconds.", DefaultValueFactory = (_) => 120.0 }); + cmd.Options.Add(new Option("--display-interval", "-i" ) { Description = "Client stats display interval, in seconds. Defaults to 5 seconds.", DefaultValueFactory = (_) => 5 }); + cmd.Options.Add(new Option("--log-server", "-S") { Description = "Print server logs to stdout." }); + cmd.Options.Add(new Option("--seed", "-s" ) { Description = "Seed for generating pseudo-random parameters. Also depends on the -n argument.", DefaultValueFactory = (_) => new Random().Next() }); + + ParseResult parseResult = cmd.Parse(args); + if (parseResult.Errors.Count > 0 || parseResult.Action is HelpAction) + { + parseResult.Invoke(); // this is going to print all the errors and help config = null; return false; } config = new Configuration() { - RunMode = parseResult.ValueForOption("-m"), - MaxConnections = parseResult.ValueForOption("-n"), - CancellationProbability = Math.Max(0, Math.Min(1, parseResult.ValueForOption("-p"))), - ServerEndpoint = ParseEndpoint(parseResult.ValueForOption("-e")), - MaxExecutionTime = parseResult.ValueForOption("-t")?.Pipe(TimeSpan.FromMinutes), - MaxBufferLength = parseResult.ValueForOption("-b"), - MinConnectionLifetime = TimeSpan.FromSeconds(parseResult.ValueForOption("-l")), - MaxConnectionLifetime = TimeSpan.FromSeconds(parseResult.ValueForOption("-L")), - DisplayInterval = TimeSpan.FromSeconds(parseResult.ValueForOption("-i")), - LogServer = parseResult.HasOption("-S"), - RandomSeed = parseResult.ValueForOption("-s"), + RunMode = parseResult.GetValue("--mode"), + MaxConnections = parseResult.GetValue("--num-connections"), + CancellationProbability = Math.Max(0, Math.Min(1, parseResult.GetValue("--cancellation-probability"))), + ServerEndpoint = parseResult.GetValue("--server-endpoint"), + MaxExecutionTime = parseResult.GetValue("--max-execution-time")?.Pipe(TimeSpan.FromMinutes), + MaxBufferLength = parseResult.GetValue("--max-buffer-length"), + MinConnectionLifetime = TimeSpan.FromSeconds(parseResult.GetValue("--min-connection-lifetime")), + MaxConnectionLifetime = TimeSpan.FromSeconds(parseResult.GetValue("--max-connection-lifetime")), + DisplayInterval = TimeSpan.FromSeconds(parseResult.GetValue("--display-interval")), + LogServer = parseResult.GetValue("--log-server"), + RandomSeed = parseResult.GetValue("--seed"), }; if (config.MaxConnectionLifetime < config.MinConnectionLifetime) { Console.WriteLine("Max connection lifetime should be greater than or equal to min connection lifetime"); - WriteHelpText(); config = null; return false; } return true; - void WriteHelpText() - { - Console.WriteLine(); - new HelpBuilder(new SystemConsole()).Write(cmd); - } - static IPEndPoint ParseEndpoint(string value) { try @@ -181,7 +188,7 @@ static IPEndPoint ParseEndpoint(string value) { string hostname = match.Groups[1].Value; int port = int.Parse(match.Groups[2].Value); - switch(hostname) + switch (hostname) { case "+": case "*": diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslClientBase.cs b/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslClientBase.cs index a86438b41ef5f1..ece9d43e0ebbec 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslClientBase.cs +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslClientBase.cs @@ -30,12 +30,12 @@ public SslClientBase(Configuration config) _config = config; _aggregator = new StressResultAggregator(config.MaxConnections); - _clientTask = new Lazy(Task.Run(StartCore)); + _clientTask = new Lazy(() => Task.Run(StartCore)); } protected abstract Task HandleConnection(int workerId, long jobId, SslStream stream, TcpClient client, Random random, TimeSpan duration, CancellationToken token); - protected virtual async Task EstablishSslStream(Stream networkStream, Random random, CancellationToken token) + protected virtual async Task EstablishSslStream(Stream networkStream, CancellationToken token) { var sslStream = new SslStream(networkStream, leaveInnerStreamOpen: false); var clientOptions = new SslClientAuthenticationOptions @@ -115,7 +115,7 @@ async Task RunSingleWorker(int workerId, Random random) using var client = new TcpClient(); await client.ConnectAsync(_config.ServerEndpoint.Address, _config.ServerEndpoint.Port); var stream = new CountingStream(client.GetStream(), counter); - using SslStream sslStream = await EstablishSslStream(stream, random, cts.Token); + using SslStream sslStream = await EstablishSslStream(stream, cts.Token); await HandleConnection(workerId, jobId, sslStream, client, random, connectionLifetime, cts.Token); _aggregator.RecordSuccess(workerId); @@ -136,7 +136,7 @@ async Task RunSingleWorker(int workerId, Random random) async void CheckForStalledConnection() { await Task.Delay(10_000); - if(!isTestCompleted) + if (!isTestCompleted) { lock (Console.Out) { diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslStress.csproj b/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslStress.csproj index a2c1d8dffa5691..ec077a4ac48326 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslStress.csproj +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/SslStress.csproj @@ -3,12 +3,14 @@ Exe $(NetCoreAppCurrent) enable + + https://api.nuget.org/v3/index.json;https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json - + - \ No newline at end of file + diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/StressOperations.cs b/src/libraries/System.Net.Security/tests/StressTests/SslStress/StressOperations.cs index eea046d392fb97..1b951f30280bd2 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/StressOperations.cs +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/StressOperations.cs @@ -194,6 +194,36 @@ public sealed class StressClient : SslClientBase { public StressClient(Configuration config) : base(config) { } + public async Task InitializeAsync() + { + Console.WriteLine($"Trying to connect to the server {_config.ServerEndpoint}"); + + // Before starting the full-blown test, make sure can communicate with the server + // Needed for scenaria where we're deploying server & client in separate containers, simultaneously. + await TestConnection(maxRetries: 10); + + Console.WriteLine($"Connected successfully."); + + async Task TestConnection(int maxRetries) + { + for (int remainingRetries = maxRetries; ; remainingRetries--) + { + try + { + using var client = new TcpClient(); + await client.ConnectAsync(_config.ServerEndpoint.Address, _config.ServerEndpoint.Port); + using var sslStream = await EstablishSslStream(client.GetStream(), CancellationToken.None); + return; + } + catch (SocketException) when (remainingRetries > 0) + { + Console.WriteLine($"Test connection to {_config.ServerEndpoint} failed, {remainingRetries} attempts remaining"); + await Task.Delay(TimeSpan.FromSeconds(1)); + } + } + } + } + protected override async Task HandleConnection(int workerId, long jobId, SslStream stream, TcpClient client, Random random, TimeSpan duration, CancellationToken token) { // token used for signalling cooperative cancellation; do not pass this to SslStream methods @@ -258,7 +288,7 @@ async Task ApplyBackpressure() await Task.Delay(20); } - if(isLogged) + if (isLogged) { Console.WriteLine($"worker #{workerId}: resumed tx after {stopwatch.Elapsed}"); } @@ -297,17 +327,17 @@ async Task Monitor(CancellationToken token) { await Task.Delay(500); - if((DateTime.Now - lastWrite) >= TimeSpan.FromSeconds(10)) + if ((DateTime.Now - lastWrite) >= TimeSpan.FromSeconds(10)) { throw new Exception($"worker #{workerId} job #{jobId} has stopped writing bytes to server"); } - if((DateTime.Now - lastRead) >= TimeSpan.FromSeconds(10)) + if ((DateTime.Now - lastRead) >= TimeSpan.FromSeconds(10)) { throw new Exception($"worker #{workerId} job #{jobId} has stopped receiving bytes from server"); } } - while(!token.IsCancellationRequested && !connectionLifetimeToken.IsCancellationRequested); + while (!token.IsCancellationRequested && !connectionLifetimeToken.IsCancellationRequested); } } } diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/build-local.sh b/src/libraries/System.Net.Security/tests/StressTests/SslStress/build-local.sh index 907bd084035fbe..750bb6417efb93 100755 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/build-local.sh +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/build-local.sh @@ -1,62 +1,24 @@ #!/usr/bin/env bash -## This is a helper script for non-containerized local build and test execution. -## Usage: -## ./build-local.sh [Configuration] +# Stop script if unbound variable found (use ${var:-} if intentional) +set -u -# Note that this script does much less than it's counterpart in HttpStress. -# In SslStress it's a thin utility to generate a runscript for running the app with the live-built testhost. -# The main reason to use an equivalent solution in SslStress is consistency with HttpStress. +# Stop script if command returns non-zero exit code. +# Prevents hidden errors caused by missing error code propagation. +set -e -version=8.0 -repo_root=$(git rev-parse --show-toplevel) +source="${BASH_SOURCE[0]}" -stress_configuration="Release" -if [ "$1" != "" ]; then - stress_configuration=${1,,} # Lowercase all characters in $1 - stress_configuration=${stress_configuration^} # Uppercase first character -fi +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" +repo_root=$(git -C "$scriptroot" rev-parse --show-toplevel) -libraries_configuration="Release" -if [ "$2" != "" ]; then - libraries_configuration=${2,,} # Lowercase all characters in $1 - libraries_configuration=${libraries_configuration^} # Uppercase first character -fi +"$repo_root/src/libraries/Common/tests/System/Net/StressTests/build-local.sh" "$scriptroot" "$@" -testhost_root=$repo_root/artifacts/bin/testhost/net$version-linux-$libraries_configuration-x64 -echo "StressConfiguration: $stress_configuration, LibrariesConfiguration: $libraries_configuration, testhost: $testhost_root" - -if [[ ! -d $testhost_root ]]; then - echo "Cannot find testhost in: $testhost_root" - echo "Make sure libraries with the requested configuration are built!" - echo "Usage:" - echo "./build-local.sh [StressConfiguration] [LibrariesConfiguration]" - echo "StressConfiguration and LibrariesConfiguration default to Release!" - exit 1 -fi - -if [[ ! -d $daily_dotnet_root ]]; then - echo "Downloading daily SDK to $daily_dotnet_root" - mkdir $daily_dotnet_root - wget https://dot.net/v1/dotnet-install.sh -O $daily_dotnet_root/dotnet-install.sh - bash $daily_dotnet_root/dotnet-install.sh --no-path --channel $version --quality daily --install-dir $daily_dotnet_root -else - echo "Daily SDK found in $daily_dotnet_root" -fi - -export DOTNET_ROOT=$daily_dotnet_root -export PATH=$DOTNET_ROOT:$PATH -export DOTNET_MULTILEVEL_LOOKUP=0 - -echo "Building solution." -dotnet build -c $stress_configuration - -runscript=./run-stress-${stress_configuration,,}-${libraries_configuration,,}.sh -if [[ ! -f $runscript ]]; then - echo "Generating runscript." - echo "$testhost_root/dotnet exec --roll-forward Major ./bin/$stress_configuration/net$version/SslStress.dll \$@" > $runscript - chmod +x $runscript -fi - -echo "To run tests type:" -echo "$runscript [stress test args]" diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/docker-compose.yml b/src/libraries/System.Net.Security/tests/StressTests/SslStress/docker-compose.yml index 043302276cc553..4b71a04109b045 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/docker-compose.yml +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/docker-compose.yml @@ -1,18 +1,22 @@ -version: '3' +version: '3' # Although the version attribute is obsolete and should be ignored, it's seemingly not the case on Build.Ubuntu.2204.Amd64.Open services: client: build: context: ../../../../ # ~> src/libraries - dockerfile: ./System.Net.Security/tests/StressTests/SslStress//${DOCKERFILE:-Dockerfile} + dockerfile: ./System.Net.Security/tests/StressTests/SslStress/${DOCKERFILE:-Dockerfile} + volumes: + - "${DUMPS_SHARE}:${DUMPS_SHARE_MOUNT_ROOT}" links: - server environment: - - SSLSTRESS_ARGS=--mode client --server-endpoint server:5001 ${SSLSTRESS_CLIENT_ARGS} + - STRESS_ARGS=--mode client --server-endpoint server:5001 ${STRESS_CLIENT_ARGS} server: build: context: ../../../../ # ~> src/libraries dockerfile: ./System.Net.Security/tests/StressTests/SslStress/${DOCKERFILE:-Dockerfile} + volumes: + - "${DUMPS_SHARE}:${DUMPS_SHARE_MOUNT_ROOT}" ports: - "5001:5001" environment: - - SSLSTRESS_ARGS=--mode server --server-endpoint 0.0.0.0:5001 ${SSLSTRESS_SERVER_ARGS} + - STRESS_ARGS=--mode server --server-endpoint 0.0.0.0:5001 ${STRESS_SERVER_ARGS} diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/entrypoint.ps1 b/src/libraries/System.Net.Security/tests/StressTests/SslStress/entrypoint.ps1 new file mode 100644 index 00000000000000..c31932fa4c2ab4 --- /dev/null +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/entrypoint.ps1 @@ -0,0 +1,21 @@ +New-Item -Path $env:DUMPS_SHARE_MOUNT_ROOT/$env:STRESS_ROLE -ItemType Directory -ErrorAction SilentlyContinue + +# Enable dump collection +$env:DOTNET_DbgEnableMiniDump = '1' +$env:DOTNET_DbgMiniDumpType = "MiniDumpWithFullMemory" +$env:DOTNET_DbgMiniDumpName = "$env:DUMPS_SHARE_MOUNT_ROOT/$env:STRESS_ROLE/coredump.%p.%t" + +& "C:/live-runtime-artifacts/testhost/net$env:VERSION-windows-$env:CONFIGURATION-x64/dotnet" exec --roll-forward Major ./bin/$env:CONFIGURATION/net$env:VERSION/SslStress.dll $env:STRESS_ARGS.Split(' ',[System.StringSplitOptions]::RemoveEmptyEntries) + +$ExitCode = $LASTEXITCODE + +if ($ExitCode -ne 0) { + Write-Host "SslStress failed, copying artifacts for investigation" + + # Copy runtime if it's not already there + if ($env:DUMPS_SHARE_MOUNT_ROOT -and !(Test-Path -Path $env:DUMPS_SHARE_MOUNT_ROOT/net$env:VERSION-windows-$env:CONFIGURATION-x64/ -ErrorAction SilentlyContinue)) { + Copy-Item -Recurse C:/live-runtime-artifacts/testhost/net$env:VERSION-windows-$env:CONFIGURATION-x64/ $env:DUMPS_SHARE_MOUNT_ROOT/ + } +} + +exit $ExitCode diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/entrypoint.sh b/src/libraries/System.Net.Security/tests/StressTests/SslStress/entrypoint.sh new file mode 100755 index 00000000000000..0e964a83b43f65 --- /dev/null +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/entrypoint.sh @@ -0,0 +1,21 @@ +mkdir -p $DUMPS_SHARE_MOUNT_ROOT/$STRESS_ROLE + +# Enable dump collection +export DOTNET_DbgEnableMiniDump=1 +export DOTNET_DbgMiniDumpType=MiniDumpWithFullMemory +export DOTNET_DbgMiniDumpName="$DUMPS_SHARE_MOUNT_ROOT/$STRESS_ROLE/coredump.%p.%t" + +/live-runtime-artifacts/testhost/net$VERSION-linux-$CONFIGURATION-x64/dotnet exec --roll-forward Major ./bin/$CONFIGURATION/net$VERSION/SslStress.dll $STRESS_ARGS + +exit_code=$? + +if [ $exit_code -ne 0 ]; then + echo "SslStress failed, copying artifacts for investigation" + + if [ ! -d "$DUMPS_SHARE_MOUNT_ROOT/net$VERSION-linux-$CONFIGURATION-x64" ] && [ -n "$DUMPS_SHARE_MOUNT_ROOT" ]; then + # copy runtime artifacts and msquic + cp -r /live-runtime-artifacts/testhost/net$VERSION-linux-$CONFIGURATION-x64/ $DUMPS_SHARE_MOUNT_ROOT + fi +fi + +exit $exit_code diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.ps1 b/src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.ps1 index e22e4635c3054f..e26c6df7be5126 100755 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.ps1 +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.ps1 @@ -1,76 +1,4 @@ #!/usr/bin/env pwsh # Runs the stress test using docker-compose - -[CmdletBinding(PositionalBinding=$false)] -Param( - [string][Alias('c')]$configuration = "Release", # Build configuration for libraries and stress suite - [switch][Alias('w')]$useWindowsContainers, # Use windows containers, if available - [switch][Alias('b')]$buildCurrentLibraries, # Drives the stress test using libraries built from current source - [switch][Alias('o')]$buildOnly, # Build, but do not run the stress app - [string][Alias('t')]$sdkImageName, # Name of the sdk image name, if built from source. - [string]$clientStressArgs = "", - [string]$serverStressArgs = "" -) - -$REPO_ROOT_DIR = $(git -C "$PSScriptRoot" rev-parse --show-toplevel) -$COMPOSE_FILE = "$PSScriptRoot/docker-compose.yml" - -# This is a workaround for an issue with 1es-windows-2022-open, which should be eventually removed. -# See comments in /eng/pipelines/libraries/stress/ssl.yml for more info. -$dockerComposeCmd = $env:DOCKER_COMPOSE_CMD -if (!(Test-Path $dockerComposeCmd)) { - $dockerComposeCmd = "docker-compose" -} - -# Build runtime libraries and place in a docker image - -if ($buildCurrentLibraries) -{ - if ([string]::IsNullOrEmpty($sdkImageName)) - { - $sdkImageName = "dotnet-sdk-libs-current" - } - - $LIBRARIES_BUILD_ARGS = " -t $sdkImageName -c $configuration" - if($useWindowsContainers) - { - $LIBRARIES_BUILD_ARGS += " -w" - } - - Invoke-Expression "& $REPO_ROOT_DIR/eng/docker/build-docker-sdk.ps1 $LIBRARIES_BUILD_ARGS" - - if (!$?) { exit 1 } -} - -# Dockerize the stress app using docker-compose - -$BUILD_ARGS = "" -if (![string]::IsNullOrEmpty($sdkImageName)) -{ - $BUILD_ARGS += " --build-arg SDK_BASE_IMAGE=$sdkImageName" -} -if ($useWindowsContainers) -{ - $env:DOCKERFILE="windows.Dockerfile" -} - -$originalErrorPreference = $ErrorActionPreference -$ErrorActionPreference = 'Continue' -try { - & $dockerComposeCmd --log-level DEBUG --file "$COMPOSE_FILE" build $BUILD_ARGS.Split() 2>&1 | ForEach-Object { "$_" } - if ($LASTEXITCODE -ne 0) { - throw "docker-compose exited with error code $LASTEXITCODE" - } -} -finally { - $ErrorActionPreference = $originalErrorPreference -} - -# Run the stress app - -if (!$buildOnly) -{ - $env:SSLSTRESS_CLIENT_ARGS = $clientStressArgs - $env:SSLSTRESS_SERVER_ARGS = $serverStressArgs - & $dockerComposeCmd --file "$COMPOSE_FILE" up --abort-on-container-exit -} +$RepoRoot = $(git -C $PSScriptRoot rev-parse --show-toplevel) +Invoke-Expression "& `"$RepoRoot/src/libraries/Common/tests/System/Net/StressTests/run-docker-compose.ps1`" -TestProjectDir `"$PSScriptRoot`" $args" diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.sh b/src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.sh index d8b096ec86c189..0ea2d436351042 100755 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.sh +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.sh @@ -19,71 +19,6 @@ while [[ -h "$source" ]]; do [[ $source != /* ]] && source="$scriptroot/$source" done scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" +repo_root=$(git -C "$scriptroot" rev-parse --show-toplevel) -imagename="dotnet-sdk-libs-current" -configuration="Release" -buildcurrentlibraries=0 -buildonly=0 -clientstressargs="" -serverstressargs="" - -while [[ $# > 0 ]]; do - opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" - case "$opt" in - -sdkimagename|-t) - imagename=$2 - shift 2 - ;; - -configuration|-c) - configuration=$2 - shift 2 - ;; - -buildcurrentlibraries|-b) - buildcurrentlibraries=1 - shift 1 - ;; - -buildonly|-o) - buildonly=1 - shift 1 - ;; - -clientstressargs) - clientstressargs=$2 - shift 2 - ;; - -serverstressargs) - serverstressargs=$2 - shift 2 - ;; - *) - shift 1 - ;; - esac -done - -repo_root=$(git rev-parse --show-toplevel) - -if [[ "$buildcurrentlibraries" -eq 1 ]]; then - libraries_args=" -t $imagename -c $configuration" - - if ! "$repo_root"/eng/docker/build-docker-sdk.sh $libraries_args; then - exit 1 - fi -fi - -build_args="" -if [[ -n "$imagename" ]]; then - build_args=" --build-arg SDK_BASE_IMAGE=$imagename" -fi - -compose_file="$scriptroot/docker-compose.yml" - -if ! docker-compose --file "$compose_file" build $build_args; then - exit $? -fi - -if [[ $buildonly -eq 0 ]]; then - export SSLSTRESS_CLIENT_ARGS=$clientstressargs - export SSLSTRESS_SERVER_ARGS=$serverstressargs - docker-compose --file "$compose_file" up --abort-on-container-exit - exit $? -fi +"$repo_root/src/libraries/Common/tests/System/Net/StressTests/run-docker-compose.sh" "$scriptroot" "$@" diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/windows.Dockerfile b/src/libraries/System.Net.Security/tests/StressTests/SslStress/windows.Dockerfile index bd402f5a2a8818..e8317ac4f1af4c 100644 --- a/src/libraries/System.Net.Security/tests/StressTests/SslStress/windows.Dockerfile +++ b/src/libraries/System.Net.Security/tests/StressTests/SslStress/windows.Dockerfile @@ -1,5 +1,5 @@ # escape=` -ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:6.0-nanoserver-1809 +ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:8.0-nanoserver-ltsc2022 FROM $SDK_BASE_IMAGE # Use powershell as the default shell @@ -13,6 +13,7 @@ ARG VERSION=8.0 ARG CONFIGURATION=Release RUN dotnet build -c $env:CONFIGURATION ` + -p:NetCoreAppCurrentVersion=$env:VERSION ` -p:TargetingPacksTargetsLocation=C:/live-runtime-artifacts/targetingpacks.targets ` -p:MicrosoftNetCoreAppRefPackDir=C:/live-runtime-artifacts/microsoft.netcore.app.ref/ ` -p:MicrosoftNetCoreAppRuntimePackDir=C:/live-runtime-artifacts/microsoft.netcore.app.runtime.win-x64/$env:CONFIGURATION/ @@ -21,7 +22,7 @@ EXPOSE 5001 ENV VERSION=$VERSION ENV CONFIGURATION=$CONFIGURATION -ENV SSLSTRESS_ARGS="" +ENV STRESS_ROLE='' +ENV STRESS_ARGS='' -CMD & C:/live-runtime-artifacts/testhost/net$env:VERSION-windows-$env:CONFIGURATION-x64/dotnet.exe exec --roll-forward Major ` - ./bin/$env:CONFIGURATION/net$env:VERSION/SslStress.dll $env:SSLSTRESS_ARGS.Split() \ No newline at end of file +CMD ./entrypoint.ps1 From 2064f1239aa1ff53c461e687a508abbb10de07ed Mon Sep 17 00:00:00 2001 From: Nikola Milosavljevic Date: Mon, 15 Dec 2025 11:58:18 -0800 Subject: [PATCH 02/17] [release/8.0-staging] Use explicit versions for MSBuild properties (#122502) --- eng/Versions.props | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 6e896fbe33b83c..07d8a86414addf 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -182,10 +182,11 @@ 2.0.3 1.0.4-preview6.19326.1 2.0.5 + 17.8.3 - $(MicrosoftBuildVersion) - $(MicrosoftBuildVersion) - $(MicrosoftBuildVersion) + 17.8.3 + 17.8.3 + 17.8.3 6.2.4 6.2.4 6.2.4 From 73ce8d6eaa88833b99b5932033dc8343a81b9d32 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 14:57:53 -0800 Subject: [PATCH 03/17] [release/8.0-staging] Update dependencies from dotnet/icu (#122514) This pull request updates the following dependencies [marker]: <> (Begin:e82a8e07-8d2b-4a71-e90f-08dbcfd41ade) ## From https://github.com/dotnet/icu - **Subscription**: [e82a8e07-8d2b-4a71-e90f-08dbcfd41ade](https://maestro.dot.net/subscriptions?search=e82a8e07-8d2b-4a71-e90f-08dbcfd41ade) - **Build**: [20251212.3](https://dev.azure.com/dnceng/internal/_build/results?buildId=2859935) ([294543](https://maestro.dot.net/channel/3073/github:dotnet:icu/build/294543)) - **Date Produced**: December 12, 2025 8:16:11 PM UTC - **Commit**: [4bfba9f36e8667005d7a40ade385daabce5fc7d5](https://github.com/dotnet/icu/commit/4bfba9f36e8667005d7a40ade385daabce5fc7d5) - **Branch**: [dotnet/release/8.0](https://github.com/dotnet/icu/tree/dotnet/release/8.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [8.0.0-rtm.25565.1 to 8.0.0-rtm.25612.3][1] - Microsoft.NETCore.Runtime.ICU.Transport [1]: https://github.com/dotnet/icu/compare/b565264ebc...4bfba9f36e [DependencyUpdate]: <> (End) [marker]: <> (End:e82a8e07-8d2b-4a71-e90f-08dbcfd41ade) Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 1 - eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 8e91d49c71dab4..f6e25f4daf50d1 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,6 @@ - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5801d6b9c49df6..47703f481cc84e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/icu - b565264ebc86c4444a7a5d411f69674393d61265 + 4bfba9f36e8667005d7a40ade385daabce5fc7d5 https://github.com/dotnet/msquic diff --git a/eng/Versions.props b/eng/Versions.props index 07d8a86414addf..30239981266a17 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -230,7 +230,7 @@ 8.0.0-rc.1.23406.6 - 8.0.0-rtm.25565.1 + 8.0.0-rtm.25612.3 2.4.8 From b8974114b73d87ac190e27f615be7035119672cf Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 29 Dec 2025 12:35:18 -0800 Subject: [PATCH 04/17] [release/8.0-staging] Update dependencies from dotnet/hotreload-utils (#122731) This pull request updates the following dependencies [marker]: <> (Begin:c0fef358-3848-4a30-a438-08dbcfd61a5a) ## From https://github.com/dotnet/hotreload-utils - **Subscription**: [c0fef358-3848-4a30-a438-08dbcfd61a5a](https://maestro.dot.net/subscriptions?search=c0fef358-3848-4a30-a438-08dbcfd61a5a) - **Build**: [20251225.3](https://dev.azure.com/dnceng/internal/_build/results?buildId=2867020) ([295569](https://maestro.dot.net/channel/3073/github:dotnet:hotreload-utils/build/295569)) - **Date Produced**: December 25, 2025 11:22:01 AM UTC - **Commit**: [e7e99065bbd4a7b911d5cfa56b23d873d9675355](https://github.com/dotnet/hotreload-utils/commit/e7e99065bbd4a7b911d5cfa56b23d873d9675355) - **Branch**: [release/8.0](https://github.com/dotnet/hotreload-utils/tree/release/8.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [8.0.0-alpha.0.25574.3 to 8.0.0-alpha.0.25625.3][1] - Microsoft.DotNet.HotReload.Utils.Generator.BuildTool [1]: https://github.com/dotnet/hotreload-utils/compare/cf2f6ad655...e7e99065bb [DependencyUpdate]: <> (End) [marker]: <> (End:c0fef358-3848-4a30-a438-08dbcfd61a5a) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 47703f481cc84e..496bcebd4917e5 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://github.com/dotnet/hotreload-utils - cf2f6ad655ebd5397042ea09d529ecc0c194a499 + e7e99065bbd4a7b911d5cfa56b23d873d9675355 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 30239981266a17..e7d1ae5cf5b6a7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -199,7 +199,7 @@ 8.0.0-prerelease.25516.2 8.0.0-prerelease.25516.2 8.0.0-prerelease.25516.2 - 8.0.0-alpha.0.25574.3 + 8.0.0-alpha.0.25625.3 2.4.2 1.0.0 2.4.5 From b4fd99d90c89b624a4e830d613df41c188a8570d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 29 Dec 2025 12:37:05 -0800 Subject: [PATCH 05/17] [release/8.0-staging] Update dependencies from dotnet/runtime-assets (#122735) This pull request updates the following dependencies [marker]: <> (Begin:855db5a2-4d17-4346-a439-08dbcfd61a5a) ## From https://github.com/dotnet/runtime-assets - **Subscription**: [855db5a2-4d17-4346-a439-08dbcfd61a5a](https://maestro.dot.net/subscriptions?search=855db5a2-4d17-4346-a439-08dbcfd61a5a) - **Build**: [20251225.3](https://dev.azure.com/dnceng/internal/_build/results?buildId=2867033) ([295573](https://maestro.dot.net/channel/3073/github:dotnet:runtime-assets/build/295573)) - **Date Produced**: December 25, 2025 11:52:55 AM UTC - **Commit**: [98185bc6d28f41decb681555c343a62b3c6c165e](https://github.com/dotnet/runtime-assets/commit/98185bc6d28f41decb681555c343a62b3c6c165e) - **Branch**: [release/8.0](https://github.com/dotnet/runtime-assets/tree/release/8.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [8.0.0-beta.25565.1 to 8.0.0-beta.25625.3][1] - Microsoft.DotNet.CilStrip.Sources - System.ComponentModel.TypeConverter.TestData - System.Data.Common.TestData - System.Drawing.Common.TestData - System.Formats.Tar.TestData - System.IO.Compression.TestData - System.IO.Packaging.TestData - System.Net.TestData - System.Private.Runtime.UnicodeData - System.Runtime.Numerics.TestData - System.Runtime.TimeZoneData - System.Security.Cryptography.X509Certificates.TestData - System.Text.RegularExpressions.TestData - System.Windows.Extensions.TestData [1]: https://github.com/dotnet/runtime-assets/compare/40ac8f2e43...98185bc6d2 [DependencyUpdate]: <> (End) [marker]: <> (End:855db5a2-4d17-4346-a439-08dbcfd61a5a) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 496bcebd4917e5..6bb7591551dc30 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -185,57 +185,57 @@ https://github.com/dotnet/arcade e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e https://github.com/dotnet/llvm-project @@ -358,9 +358,9 @@ https://github.com/dotnet/hotreload-utils e7e99065bbd4a7b911d5cfa56b23d873d9675355 - + https://github.com/dotnet/runtime-assets - 40ac8f2e43695322e5472fef7f3ad85cfdd83e1e + 98185bc6d28f41decb681555c343a62b3c6c165e https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index e7d1ae5cf5b6a7..8a53e82b4cf43d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -153,20 +153,20 @@ 4.5.0 8.0.0-rc.1.23406.6 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 - 8.0.0-beta.25565.1 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 + 8.0.0-beta.25625.3 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 From 1b2d5f63f99f460399a8adf3fd1999685d6ba616 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 29 Dec 2025 12:39:02 -0800 Subject: [PATCH 06/17] [release/8.0-staging] Update dependencies from dotnet/icu (#122737) This pull request updates the following dependencies [marker]: <> (Begin:e82a8e07-8d2b-4a71-e90f-08dbcfd41ade) ## From https://github.com/dotnet/icu - **Subscription**: [e82a8e07-8d2b-4a71-e90f-08dbcfd41ade](https://maestro.dot.net/subscriptions?search=e82a8e07-8d2b-4a71-e90f-08dbcfd41ade) - **Build**: [20251225.2](https://dev.azure.com/dnceng/internal/_build/results?buildId=2867037) ([295579](https://maestro.dot.net/channel/3073/github:dotnet:icu/build/295579)) - **Date Produced**: December 25, 2025 12:12:34 PM UTC - **Commit**: [7e1e01ce174204fc50e1b221c59cbd2c7a752441](https://github.com/dotnet/icu/commit/7e1e01ce174204fc50e1b221c59cbd2c7a752441) - **Branch**: [dotnet/release/8.0](https://github.com/dotnet/icu/tree/dotnet/release/8.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [8.0.0-rtm.25612.3 to 8.0.0-rtm.25625.2][1] - Microsoft.NETCore.Runtime.ICU.Transport [1]: https://github.com/dotnet/icu/compare/4bfba9f36e...7e1e01ce17 [DependencyUpdate]: <> (End) [marker]: <> (End:e82a8e07-8d2b-4a71-e90f-08dbcfd41ade) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6bb7591551dc30..365787291f98d0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/icu - 4bfba9f36e8667005d7a40ade385daabce5fc7d5 + 7e1e01ce174204fc50e1b221c59cbd2c7a752441 https://github.com/dotnet/msquic diff --git a/eng/Versions.props b/eng/Versions.props index 8a53e82b4cf43d..5f008f5da619e5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -230,7 +230,7 @@ 8.0.0-rc.1.23406.6 - 8.0.0-rtm.25612.3 + 8.0.0-rtm.25625.2 2.4.8 From 23310207909efab5014934cea4115f86e18d0e61 Mon Sep 17 00:00:00 2001 From: Nikola Milosavljevic Date: Tue, 6 Jan 2026 10:45:05 -0800 Subject: [PATCH 07/17] [release/8.0-staging] Update OpenSSL dependency for openSUSE and SLES (#122654) Fixes: https://github.com/dotnet/runtime/issues/122653 `libopenssl3` is supported and installed by default on all of the supported distro releases listed at https://learn.microsoft.com/en-us/dotnet/core/install/linux-sles?tabs=dotnet8 and https://learn.microsoft.com/en-us/dotnet/core/install/linux-opensuse?tabs=dotnet8 `libopenssl3` is also supported and installed by default on openSUSE Tumbleweed release. This release does not have any other, older, version of this library. --- .../dotnet-runtime-deps/dotnet-runtime-deps-opensuse.42.proj | 2 +- .../dotnet-runtime-deps/dotnet-runtime-deps-sles.12.proj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-opensuse.42.proj b/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-opensuse.42.proj index 6453d117728d4e..369bf7f7cabfcd 100644 --- a/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-opensuse.42.proj +++ b/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-opensuse.42.proj @@ -5,6 +5,6 @@ - + \ No newline at end of file diff --git a/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-sles.12.proj b/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-sles.12.proj index 912692f5d7f26f..f007b2acb63ee8 100644 --- a/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-sles.12.proj +++ b/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-sles.12.proj @@ -5,6 +5,6 @@ - + \ No newline at end of file From 3380e5d1965e3fb56305f6388ba6426ca187cc2e Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 8 Jan 2026 10:55:05 -0800 Subject: [PATCH 08/17] [release/8.0-staging] Add fetchTags: false to checkout steps in pipeline YAML files (#122417) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `fetchTags: false` to Azure Pipelines checkout steps to skip fetching git tags during repository checkout, reducing network overhead and improving checkout performance. ## Changes - Updated 8 YAML files containing 10 total checkout steps in `eng/pipelines/`: - Pipeline templates: `base-job.yml`, `xplat-job.yml`, `build-job.yml` - Stress test pipelines: `http.yml`, `ssl.yml` (2 occurrences each) - Path evaluation and build jobs: `evaluate-paths-job.yml`, `global-build-job.yml` - Official build jobs: `prepare-signed-artifacts.yml` Note: Changes to `eng/common/` templates were excluded as those are shared infrastructure files managed separately. ## Example ```yaml - checkout: self clean: true fetchDepth: $(checkoutFetchDepth) fetchTags: false # Added to skip tag fetching ```
Original prompt > Update the checkout step in the runtime CI yml to specify fetchTags: false.
--- ✨ Let Copilot coding agent [set things up for you](https://github.com/dotnet/runtime/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com> Co-authored-by: Elinor Fung --- eng/pipelines/common/evaluate-paths-job.yml | 1 + eng/pipelines/common/global-build-job.yml | 1 + eng/pipelines/common/templates/runtimes/xplat-job.yml | 1 + eng/pipelines/installer/jobs/build-job.yml | 1 + eng/pipelines/libraries/base-job.yml | 1 + eng/pipelines/libraries/stress/http.yml | 2 ++ eng/pipelines/libraries/stress/ssl.yml | 2 ++ eng/pipelines/official/jobs/prepare-signed-artifacts.yml | 1 + 8 files changed, 10 insertions(+) diff --git a/eng/pipelines/common/evaluate-paths-job.yml b/eng/pipelines/common/evaluate-paths-job.yml index 64c3a12584c27b..ebf3c930fb70ae 100644 --- a/eng/pipelines/common/evaluate-paths-job.yml +++ b/eng/pipelines/common/evaluate-paths-job.yml @@ -34,6 +34,7 @@ jobs: - checkout: self clean: true fetchDepth: 2 + fetchTags: false - ${{ if ne(parameters.paths[0], '') }}: - ${{ each path in parameters.paths }}: diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 86cea9fbd98a20..0eda6a6b7c1a6b 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -149,6 +149,7 @@ jobs: - checkout: self clean: true + fetchTags: false # If running in source build mode, a git stash will be used for the inner clone. Avoid setting a fetch depth, # as a stash of a shallow cloned repo is not currently supported. ${{ if ne(parameters.isSourceBuild, true) }}: diff --git a/eng/pipelines/common/templates/runtimes/xplat-job.yml b/eng/pipelines/common/templates/runtimes/xplat-job.yml index 625d88d63d3e97..1b8fdde3c000be 100644 --- a/eng/pipelines/common/templates/runtimes/xplat-job.yml +++ b/eng/pipelines/common/templates/runtimes/xplat-job.yml @@ -104,5 +104,6 @@ jobs: - checkout: self clean: true fetchDepth: $(checkoutFetchDepth) + fetchTags: false - ${{ parameters.steps }} diff --git a/eng/pipelines/installer/jobs/build-job.yml b/eng/pipelines/installer/jobs/build-job.yml index 43f19c69ccacfc..26338238551dd7 100644 --- a/eng/pipelines/installer/jobs/build-job.yml +++ b/eng/pipelines/installer/jobs/build-job.yml @@ -294,6 +294,7 @@ jobs: - checkout: self clean: true fetchDepth: $(checkoutFetchDepth) + fetchTags: false - ${{ if ne(variables['System.TeamProject'], 'public') }}: - ${{ if ne(parameters.osGroup, 'windows') }}: diff --git a/eng/pipelines/libraries/base-job.yml b/eng/pipelines/libraries/base-job.yml index 54fe98e7d85bbf..936a1462df22e0 100644 --- a/eng/pipelines/libraries/base-job.yml +++ b/eng/pipelines/libraries/base-job.yml @@ -127,6 +127,7 @@ jobs: - checkout: self clean: true fetchDepth: $(checkoutFetchDepth) + fetchTags: false - ${{ if and(ne(parameters.liveRuntimeBuildConfig, ''), eq(parameters.runTests, true)) }}: - template: /eng/pipelines/common/download-artifact-step.yml diff --git a/eng/pipelines/libraries/stress/http.yml b/eng/pipelines/libraries/stress/http.yml index dae5e867ae8da7..665ac79db810c4 100644 --- a/eng/pipelines/libraries/stress/http.yml +++ b/eng/pipelines/libraries/stress/http.yml @@ -45,6 +45,7 @@ extends: - checkout: self clean: true fetchDepth: 5 + fetchTags: false - bash: | $(dockerfilesFolder)/build-docker-sdk.sh -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION) && \ @@ -112,6 +113,7 @@ extends: clean: true fetchDepth: 5 lfs: false + fetchTags: false - powershell: | $(dockerfilesFolder)/build-docker-sdk.ps1 -w -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION) diff --git a/eng/pipelines/libraries/stress/ssl.yml b/eng/pipelines/libraries/stress/ssl.yml index 8dd9adc3908707..cf84a63ba50ea6 100644 --- a/eng/pipelines/libraries/stress/ssl.yml +++ b/eng/pipelines/libraries/stress/ssl.yml @@ -46,6 +46,7 @@ extends: - checkout: self clean: true fetchDepth: 5 + fetchTags: false - bash: | $(dockerfilesFolder)/build-docker-sdk.sh -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION) @@ -81,6 +82,7 @@ extends: clean: true fetchDepth: 5 lfs: false + fetchTags: false - powershell: | $(dockerfilesFolder)/build-docker-sdk.ps1 -w -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION) diff --git a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml index 540f392e796389..d7ffff9985a734 100644 --- a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml +++ b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml @@ -32,6 +32,7 @@ jobs: - checkout: self clean: true fetchDepth: 20 + fetchTags: false - ${{ if eq(parameters.isOfficialBuild, true) }}: - task: NuGetAuthenticate@1 From 8742c0456faeeb7d5f5759db1c22e67d4ee07f0c Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 8 Jan 2026 13:36:43 -0800 Subject: [PATCH 09/17] [release/8.0-staging] Fix analyzer crash on C# 14 extensions (#122199) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport of https://github.com/dotnet/runtime/pull/121351 to release/8.0-staging ## Customer Impact Fixes a customer-reported crash in ILLink analyzer in a net8.0 project that uses C# 14 extension members. Customer issue: https://github.com/dotnet/runtime/issues/120728 ``` warning AD0001: Analyzer 'ILLink.RoslynAnalyzer.DynamicallyAccessedMembersAnalyzer' threw an exception of type 'System.InvalidCastException' with message 'Unable to cast object of type 'Microsoft.CodeAnalysis.CSharp.Symbols.PublicModel.NonErrorNamedTypeSymbol' to type 'Microsoft.CodeAnalysis.IMethodSymbol'.'. ``` ## Regression No - crash only happens for language features introduced after .NET 8 was released. ## Testing Tested locally. We can't add automated testing because this repo doesn't reference a new enough version of Roslyn to build tests with extension members. ## Risk Low, analyzer-only fix, with limited scope.
Fixes https://github.com/dotnet/runtime/issues/120728 main PR https://github.com/dotnet/runtime/pull/121351 # Description Backports fix for analyzer crash when encountering C# 14 extension members. The crash occurred because the analyzer assumed `parameter.ContainingSymbol` is always `IMethodSymbol`, which is false for extension member parameters where the container is an extension type. **Core analyzer changes:** - Remove `MethodParameterValue` constructors that cast `parameter.ContainingSymbol` to `IMethodSymbol` - Require explicit `IMethodSymbol` parameter in `ParameterProxy` constructor - Skip analysis for extension members in `GetParameterTargetValue` (return `TopValue` when `ContainingSymbol` is not `IMethodSymbol`) - Update `VisitInstanceReference` to use new `ParameterProxy` constructor (without unrelated static method checks) **Test infrastructure:** - Add `Microsoft.Net.Compilers.Toolset` package reference for C# preview features - Add workaround in `ResultChecker.cs` to skip validation of compiler-generated extension member types (`<>E__` prefix) - Add `ExtensionsDataFlow.cs` test (enabled) - Add `ExtensionMembersDataFlow.cs` test (disabled until C# 14 available) **Note:** NativeAOT test changes from original PR excluded as `ILCompiler.Trimming.Tests` doesn't exist in 8.0. # Customer Impact Without this fix, the Roslyn analyzer crashes when analyzing code that uses or references C# 14 extension members, breaking the build or IDE experience. # Regression No. This is a new feature compatibility fix for C# 14, not a regression from 8.0 functionality. # Testing - All 60 DataFlow analyzer tests pass - New `ExtensionsDataFlow` test validates fix for regular extension methods - ILLink.RoslynAnalyzer builds cleanly # Risk Low. Changes are surgical and isolated to extension member handling: - Early-exit paths for extension members prevent processing unsupported constructs - Existing code paths unchanged (all parameters with method containers work as before) - Test coverage validates no regressions in standard scenarios # Package authoring signed off? N/A - Changes are internal to analyzer implementation, no public API surface modified.
Original prompt > Backport https://github.com/dotnet/runtime/pull/121351 to release/8.0-staging.
--- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey). --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com> Co-authored-by: Sven Boemer --- .../TrimAnalysis/MethodParameterValue.cs | 5 -- .../TrimAnalysis/ParameterProxy.cs | 6 +- .../TrimAnalysis/TrimAnalysisVisitor.cs | 8 ++- .../DataFlowTests.cs | 6 ++ .../DataFlow/ExtensionsDataFlow.cs | 66 +++++++++++++++++++ 5 files changed, 81 insertions(+), 10 deletions(-) create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExtensionsDataFlow.cs diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodParameterValue.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodParameterValue.cs index 67668004433ce9..589b0e8130efdf 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodParameterValue.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodParameterValue.cs @@ -9,11 +9,6 @@ namespace ILLink.Shared.TrimAnalysis { internal partial record MethodParameterValue { - public MethodParameterValue (IParameterSymbol parameterSymbol) - : this (new ParameterProxy (parameterSymbol)) { } - public MethodParameterValue (IMethodSymbol methodSymbol, ParameterIndex parameterIndex, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) - : this (new (new (methodSymbol), parameterIndex), dynamicallyAccessedMemberTypes) { } - public MethodParameterValue (ParameterProxy parameter) : this (parameter, FlowAnnotations.GetMethodParameterAnnotation (parameter)) { } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ParameterProxy.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ParameterProxy.cs index f57de9138dbf88..baa21aca62c8a4 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ParameterProxy.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ParameterProxy.cs @@ -9,10 +9,10 @@ namespace ILLink.Shared.TypeSystemProxy { internal partial struct ParameterProxy { - public ParameterProxy (IParameterSymbol parameter) + public ParameterProxy (IParameterSymbol parameter, IMethodSymbol method) { - Method = new ((IMethodSymbol) parameter.ContainingSymbol); - Index = (ParameterIndex) parameter.Ordinal + (Method.HasImplicitThis () ? 1 : 0); + Method = new (method); + Index = (ParameterIndex) parameter.Ordinal + (method.HasImplicitThis () ? 1 : 0); } public partial ReferenceKind GetReferenceKind () diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs index b960e2a461f97d..3eea09e78d4348 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs @@ -113,7 +113,7 @@ public override MultiValue VisitInstanceReference (IInstanceReferenceOperation i // The instance reference operation represents a 'this' or 'base' reference to the containing type, // so we get the annotation from the containing method. if (instanceRef.Type != null && instanceRef.Type.IsTypeInterestingForDataflow ()) - return new MethodParameterValue (Method, (ParameterIndex) 0, Method.GetDynamicallyAccessedMemberTypes ()); + return new MethodParameterValue (new ParameterProxy (new (Method), (ParameterIndex) 0)); return TopValue; } @@ -187,7 +187,11 @@ public override MultiValue GetFieldTargetValue (IFieldSymbol field) public override MultiValue GetParameterTargetValue (IParameterSymbol parameter) { - return parameter.Type.IsTypeInterestingForDataflow () ? new MethodParameterValue (parameter) : TopValue; + // Skip analysis for extension members (we have no way to represent a parameter on an extension type). + if (parameter.ContainingSymbol is not IMethodSymbol method) + return TopValue; + + return parameter.Type.IsTypeInterestingForDataflow () ? new MethodParameterValue (new ParameterProxy (parameter, method)) : TopValue; } public override void HandleAssignment (MultiValue source, MultiValue target, IOperation operation) diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs index 29622dc32365c3..9add1124769a19 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs @@ -131,6 +131,12 @@ public Task EventDataFlow () return RunTest (); } + [Fact] + public Task ExtensionsDataFlow () + { + return RunTest (); + } + [Fact] public Task FieldDataFlow () { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExtensionsDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExtensionsDataFlow.cs new file mode 100644 index 00000000000000..1f7b8bcb63df4d --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExtensionsDataFlow.cs @@ -0,0 +1,66 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class ExtensionsDataFlow + { + public static void Main () + { + TestExtensionMethod (); + TestExtensionMethodMismatch (); + TestExtensionMethodRequires (); + } + + [ExpectedWarning ("IL2072", "GetWithMethods", nameof (Extensions.ExtensionMethod))] + static void TestExtensionMethod () + { + GetWithFields ().ExtensionMethod (); + GetWithMethods ().ExtensionMethod (); + } + + static void TestExtensionMethodMismatch () + { + GetWithFields ().ExtensionMethodMismatch (); + } + + [ExpectedWarning ("IL2026", nameof (Extensions.ExtensionMethodRequires))] + static void TestExtensionMethodRequires () + { + GetWithFields ().ExtensionMethodRequires (); + } + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + static Type GetWithFields () => null; + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + static Type GetWithMethods () => null; + } + + [ExpectedNoWarnings] + public static class Extensions + { + public static void ExtensionMethod ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] this Type type) + { + type.RequiresPublicFields (); + } + + [ExpectedWarning ("IL2067", "RequiresPublicMethods")] + public static void ExtensionMethodMismatch ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] this Type type) + { + type.RequiresPublicMethods (); + } + + [RequiresUnreferencedCode (nameof (ExtensionMethodRequires))] + public static void ExtensionMethodRequires ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] this Type type) + { + } + } +} From 8e8c0c75afcb1615444d9ab17d7dc8a01839bb37 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Mon, 12 Jan 2026 10:09:49 -0800 Subject: [PATCH 10/17] [release/8.0] Move default build images to macos 15 (and xcode 16) (#120589) (#122423) (cherry picked from commit eaafd7c38c9707a61cf0cf8582aeac9e52b60b31) (cherry picked from commit 1905046c3ce053b2736b9c46a119edcf7832feee) --------- Co-authored-by: Eric StJohn Co-authored-by: Matous Kozak Co-authored-by: Steve Pfister Co-authored-by: Filip Navara --- eng/pipelines/common/xplat-setup.yml | 7 +- .../coreclr/templates/helix-queues-setup.yml | 8 +- .../libraries/helix-queues-setup.yml | 8 +- .../vm/amd64/jithelpers_fastwritebarriers.S | 172 +++++++++--------- src/mono/mono/metadata/icall-signatures.h | 8 +- src/mono/mono/metadata/icall.c | 3 +- src/mono/mono/mini/aot-compiler.c | 4 +- src/mono/mono/mini/decompose.c | 2 +- src/tests/issues.targets | 9 + 9 files changed, 116 insertions(+), 105 deletions(-) diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index b4014fcf7be804..5292eb6fc2bada 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -159,6 +159,9 @@ jobs: container: ${{ parameters.container }} ${{ if eq(parameters.jobParameters.pool, '') }}: + # N.B.: We should always be building on the latest available version of our build platform. + # Each of these queues should be the latest version or have a tracking issue if the latest version + # does not work for some reason. pool: # Public Linux Build Pool ${{ if and(or(in(parameters.osGroup, 'linux', 'freebsd', 'android', 'tizen'), eq(parameters.jobParameters.hostedOs, 'linux')), eq(variables['System.TeamProject'], 'public')) }}: @@ -173,12 +176,12 @@ jobs: # OSX Public Build Pool (we don't have on-prem OSX BuildPool). ${{ if and(in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator'), eq(variables['System.TeamProject'], 'public')) }}: - vmImage: 'macos-13' + vmImage: 'macos-15' # OSX Internal Pool ${{ if and(in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator'), ne(variables['System.TeamProject'], 'public')) }}: name: "Azure Pipelines" - vmImage: 'macOS-13' + vmImage: 'macos-15' os: macOS # Official Build Windows Pool diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index 104418cbdd157f..3b678b14066879 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -107,16 +107,16 @@ jobs: # OSX arm64 - ${{ if eq(parameters.platform, 'osx_arm64') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - OSX.13.ARM64.Open + - OSX.14.ARM64.Open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - OSX.13.ARM64 + - OSX.14.ARM64 # OSX x64 - ${{ if eq(parameters.platform, 'osx_x64') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - OSX.13.Amd64.Open + - OSX.14.Amd64.Open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - OSX.13.Amd64 + - OSX.14.Amd64 # windows x64 - ${{ if eq(parameters.platform, 'windows_x64') }}: diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 9d5c4b8e3e52f2..22f7b0e5102ac5 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -36,7 +36,7 @@ jobs: - (Ubuntu.2204.ArmArch.Open)AzureLinux.3.Arm64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-arm64v8 - ${{ if or(ne(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - (AzureLinux.3.ArmArch.Open)AzureLinux.3.Arm64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-helix-arm64v8 - + # Linux musl x64 - ${{ if eq(parameters.platform, 'linux_musl_x64') }}: - (Alpine.323.Amd64.Open)AzureLinux.3.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-amd64 @@ -45,7 +45,7 @@ jobs: - ${{ if eq(parameters.platform, 'linux_musl_arm64') }}: - ${{ if or(eq(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - (Alpine.323.Arm64.Open)AzureLinux.3.Arm64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-arm64v8 - + # Linux x64 - ${{ if eq(parameters.platform, 'linux_x64') }}: - ${{ if or(eq(parameters.jobParameters.interpreter, 'true'), eq(parameters.jobParameters.isSingleFile, true)) }}: @@ -76,11 +76,11 @@ jobs: # OSX arm64 - ${{ if eq(parameters.platform, 'osx_arm64') }}: - - OSX.13.ARM64.Open + - OSX.14.ARM64.Open # OSX x64 - ${{ if eq(parameters.platform, 'osx_x64') }}: - - OSX.13.Amd64.Open + - OSX.14.Amd64.Open # Android - ${{ if in(parameters.platform, 'android_x86', 'android_x64', 'linux_bionic_x64') }}: diff --git a/src/coreclr/vm/amd64/jithelpers_fastwritebarriers.S b/src/coreclr/vm/amd64/jithelpers_fastwritebarriers.S index f987751bdcb358..cf9f149e374899 100644 --- a/src/coreclr/vm/amd64/jithelpers_fastwritebarriers.S +++ b/src/coreclr/vm/amd64/jithelpers_fastwritebarriers.S @@ -39,10 +39,10 @@ PATCH_LABEL JIT_WriteBarrier_PreGrow64_Patch_Label_CardTable shr rdi, 0x0B cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardTable_PreGrow64 + // jne LOCAL_LABEL(UpdateCardTable_PreGrow64) REPRET - UpdateCardTable_PreGrow64: + LOCAL_LABEL(UpdateCardTable_PreGrow64): mov byte ptr [rdi + rax], 0xFF #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES @@ -57,17 +57,17 @@ PATCH_LABEL JIT_WriteBarrier_PreGrow64_Patch_Label_CardBundleTable cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundle_PreGrow64 + // jne LOCAL_LABEL(UpdateCardBundle_PreGrow64) REPRET - UpdateCardBundle_PreGrow64: + LOCAL_LABEL(UpdateCardBundle_PreGrow64): mov byte ptr [rdi + rax], 0xFF #endif ret .balign 16 - Exit_PreGrow64: +PATCH_LABEL Exit_PreGrow64 REPRET LEAF_END_MARKED JIT_WriteBarrier_PreGrow64, _TEXT @@ -124,10 +124,10 @@ PATCH_LABEL JIT_WriteBarrier_PostGrow64_Patch_Label_CardTable shr rdi, 0x0B cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardTable_PostGrow64 + // jne LOCAL_LABEL(UpdateCardTable_PostGrow64) REPRET - UpdateCardTable_PostGrow64: + LOCAL_LABEL(UpdateCardTable_PostGrow64): mov byte ptr [rdi + rax], 0xFF #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES @@ -142,17 +142,17 @@ PATCH_LABEL JIT_WriteBarrier_PostGrow64_Patch_Label_CardBundleTable cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundle_PostGrow64 + // jne LOCAL_LABEL(UpdateCardBundle_PostGrow64) REPRET - UpdateCardBundle_PostGrow64: + LOCAL_LABEL(UpdateCardBundle_PostGrow64): mov byte ptr [rdi + rax], 0xFF #endif ret .balign 16 - Exit_PostGrow64: +PATCH_LABEL Exit_PostGrow64 REPRET LEAF_END_MARKED JIT_WriteBarrier_PostGrow64, _TEXT @@ -183,10 +183,10 @@ PATCH_LABEL JIT_WriteBarrier_SVR64_PatchLabel_CardTable cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardTable_SVR64 + // jne LOCAL_LABEL(UpdateCardTable_SVR64) REPRET - UpdateCardTable_SVR64: + LOCAL_LABEL(UpdateCardTable_SVR64): mov byte ptr [rdi + rax], 0xFF #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES @@ -200,10 +200,10 @@ PATCH_LABEL JIT_WriteBarrier_SVR64_PatchLabel_CardBundleTable cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundle_SVR64 + // jne LOCAL_LABEL(UpdateCardBundle_SVR64) REPRET - UpdateCardBundle_SVR64: + LOCAL_LABEL(UpdateCardBundle_SVR64): mov byte ptr [rdi + rax], 0xFF #endif @@ -233,46 +233,46 @@ PATCH_LABEL JIT_WriteBarrier_Byte_Region64_Patch_Label_RegionShrDest // Check whether the region we're storing into is gen 0 - nothing to do in this case cmp byte ptr [rdi + rax], 0 .byte 0x75, 0x04 - //jne NotGen0_Byte_Region64 + //jne LOCAL_LABEL(NotGen0_Byte_Region64) REPRET NOP_2_BYTE // padding for alignment of constant - NotGen0_Byte_Region64: + LOCAL_LABEL(NotGen0_Byte_Region64): PATCH_LABEL JIT_WriteBarrier_Byte_Region64_Patch_Label_Lower movabs r9, 0xF0F0F0F0F0F0F0F0 cmp rsi, r9 .byte 0x73, 0x01 - // jae NotLow_Byte_Region64 + // jae LOCAL_LABEL(NotLow_Byte_Region64) ret - NotLow_Byte_Region64: + LOCAL_LABEL(NotLow_Byte_Region64): PATCH_LABEL JIT_WriteBarrier_Byte_Region64_Patch_Label_Upper movabs r9, 0xF0F0F0F0F0F0F0F0 cmp rsi, r9 .byte 0x72, 0x02 - // jb NotHigh_Byte_Region64 + // jb LOCAL_LABEL(NotHigh_Byte_Region64) REPRET - NotHigh_Byte_Region64: + LOCAL_LABEL(NotHigh_Byte_Region64): PATCH_LABEL JIT_WriteBarrier_Byte_Region64_Patch_Label_RegionShrSrc shr rsi, 0x16 // compute region index mov dl, [rsi + rax] cmp dl, [rdi + rax] .byte 0x72, 0x03 - // jb IsOldToYoung_Byte_Region64 + // jb LOCAL_LABEL(IsOldToYoung_Byte_Region64) REPRET nop - IsOldToYoung_Byte_Region64: + LOCAL_LABEL(IsOldToYoung_Byte_Region64): PATCH_LABEL JIT_WriteBarrier_Byte_Region64_Patch_Label_CardTable movabs rax, 0xF0F0F0F0F0F0F0F0 shr r8, 0xB cmp byte ptr [r8 + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardTable_Byte_Region64 + // jne LOCAL_LABEL(UpdateCardTable_Byte_Region64) REPRET - UpdateCardTable_Byte_Region64: + LOCAL_LABEL(UpdateCardTable_Byte_Region64): mov byte ptr [r8 + rax], 0xFF #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES shr r8, 0x0A @@ -280,10 +280,10 @@ PATCH_LABEL JIT_WriteBarrier_Byte_Region64_Patch_Label_CardBundleTable movabs rax, 0xF0F0F0F0F0F0F0F0 cmp byte ptr [r8 + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundleTable_Byte_Region64 + // jne LOCAL_LABEL(UpdateCardBundleTable_Byte_Region64) REPRET - UpdateCardBundleTable_Byte_Region64: + LOCAL_LABEL(UpdateCardBundleTable_Byte_Region64): mov byte ptr [r8 + rax], 0xFF #endif ret @@ -308,36 +308,36 @@ PATCH_LABEL JIT_WriteBarrier_Bit_Region64_Patch_Label_RegionShrDest // Check whether the region we're storing into is gen 0 - nothing to do in this case cmp byte ptr [rdi + rax], 0 .byte 0x75, 0x04 - //jne NotGen0_Bit_Region64 + //jne LOCAL_LABEL(NotGen0_Bit_Region64) REPRET NOP_2_BYTE // padding for alignment of constant - NotGen0_Bit_Region64: + LOCAL_LABEL(NotGen0_Bit_Region64): PATCH_LABEL JIT_WriteBarrier_Bit_Region64_Patch_Label_Lower movabs r9, 0xF0F0F0F0F0F0F0F0 cmp rsi, r9 .byte 0x73, 0x01 - // jae NotLow_Bit_Region64 + // jae LOCAL_LABEL(NotLow_Bit_Region64) ret - NotLow_Bit_Region64: + LOCAL_LABEL(NotLow_Bit_Region64): PATCH_LABEL JIT_WriteBarrier_Bit_Region64_Patch_Label_Upper movabs r9, 0xF0F0F0F0F0F0F0F0 cmp rsi, r9 .byte 0x72, 0x02 - // jb NotHigh_Bit_Region64 + // jb LOCAL_LABEL(NotHigh_Bit_Region64) REPRET - NotHigh_Bit_Region64: + LOCAL_LABEL(NotHigh_Bit_Region64): PATCH_LABEL JIT_WriteBarrier_Bit_Region64_Patch_Label_RegionShrSrc shr rsi, 0x16 // compute region index mov dl, [rsi + rax] cmp dl, [rdi + rax] .byte 0x72, 0x03 - // jb IsOldToYoung_Bit_Region64 + // jb LOCAL_LABEL(IsOldToYoung_Bit_Region64) REPRET nop - IsOldToYoung_Bit_Region64: + LOCAL_LABEL(IsOldToYoung_Bit_Region64): PATCH_LABEL JIT_WriteBarrier_Bit_Region64_Patch_Label_CardTable movabs rax, 0xF0F0F0F0F0F0F0F0 @@ -349,10 +349,10 @@ PATCH_LABEL JIT_WriteBarrier_Bit_Region64_Patch_Label_CardTable shl dl, cl test byte ptr [r8 + rax], dl .byte 0x74, 0x02 - // je UpdateCardTable_Bit_Region64 + // je LOCAL_LABEL(UpdateCardTable_Bit_Region64) REPRET - UpdateCardTable_Bit_Region64: + LOCAL_LABEL(UpdateCardTable_Bit_Region64): lock or byte ptr [r8 + rax], dl #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES PATCH_LABEL JIT_WriteBarrier_Bit_Region64_Patch_Label_CardBundleTable @@ -360,10 +360,10 @@ PATCH_LABEL JIT_WriteBarrier_Bit_Region64_Patch_Label_CardBundleTable shr r8, 0x0A cmp byte ptr [r8 + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundleTable_Bit_Region64 + // jne LOCAL_LABEL(UpdateCardBundleTable_Bit_Region64) REPRET - UpdateCardBundleTable_Bit_Region64: + LOCAL_LABEL(UpdateCardBundleTable_Bit_Region64): mov byte ptr [r8 + rax], 0xFF #endif ret @@ -397,10 +397,10 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PreGrow64_Patch_Label_Lower add rax, r10 cmp byte ptr [rax], 0x0 .byte 0x75, 0x03 - // jne CheckCardTable_WriteWatch_PreGrow64 + // jne LOCAL_LABEL(CheckCardTable_WriteWatch_PreGrow64) mov byte ptr [rax], 0xFF - CheckCardTable_WriteWatch_PreGrow64: + LOCAL_LABEL(CheckCardTable_WriteWatch_PreGrow64): // Check the lower ephemeral region bound. cmp rsi, r11 @@ -419,10 +419,10 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PreGrow64_Patch_Label_CardTable movabs rax, 0xF0F0F0F0F0F0F0F0 cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardTable_WriteWatch_PreGrow64 + // jne LOCAL_LABEL(UpdateCardTable_WriteWatch_PreGrow64) REPRET - UpdateCardTable_WriteWatch_PreGrow64: + LOCAL_LABEL(UpdateCardTable_WriteWatch_PreGrow64): mov byte ptr [rdi + rax], 0xFF #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES @@ -434,17 +434,17 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PreGrow64_Patch_Label_CardBundleTable cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundle_WriteWatch_PreGrow64 + // jne LOCAL_LABEL(UpdateCardBundle_WriteWatch_PreGrow64) REPRET - UpdateCardBundle_WriteWatch_PreGrow64: + LOCAL_LABEL(UpdateCardBundle_WriteWatch_PreGrow64): mov byte ptr [rdi + rax], 0xFF #endif ret .balign 16 - Exit_WriteWatch_PreGrow64: +PATCH_LABEL Exit_WriteWatch_PreGrow64 REPRET LEAF_END_MARKED JIT_WriteBarrier_WriteWatch_PreGrow64, _TEXT @@ -475,13 +475,13 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_Lower add rax, r10 cmp byte ptr [rax], 0x0 .byte 0x75, 0x06 - // jne CheckCardTable_WriteWatch_PostGrow64 + // jne LOCAL_LABEL(CheckCardTable_WriteWatch_PostGrow64) mov byte ptr [rax], 0xFF NOP_3_BYTE // padding for alignment of constant // Check the lower and upper ephemeral region bounds - CheckCardTable_WriteWatch_PostGrow64: + LOCAL_LABEL(CheckCardTable_WriteWatch_PostGrow64): cmp rsi, r11 #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES @@ -514,10 +514,10 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_CardTable shr rdi, 0x0B cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardTable_WriteWatch_PostGrow64 + // jne LOCAL_LABEL(UpdateCardTable_WriteWatch_PostGrow64) REPRET - UpdateCardTable_WriteWatch_PostGrow64: + LOCAL_LABEL(UpdateCardTable_WriteWatch_PostGrow64): mov byte ptr [rdi + rax], 0xFF #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES @@ -529,16 +529,16 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_CardBundleTable cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundle_WriteWatch_PostGrow64 + // jne LOCAL_LABEL(UpdateCardBundle_WriteWatch_PostGrow64) REPRET - UpdateCardBundle_WriteWatch_PostGrow64: + LOCAL_LABEL(UpdateCardBundle_WriteWatch_PostGrow64): mov byte ptr [rdi + rax], 0xFF #endif ret .balign 16 - Exit_WriteWatch_PostGrow64: +PATCH_LABEL Exit_WriteWatch_PostGrow64 REPRET LEAF_END_MARKED JIT_WriteBarrier_WriteWatch_PostGrow64, _TEXT @@ -578,17 +578,17 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_SVR64_PatchLabel_CardTable add rax, r10 cmp byte ptr [rax], 0x0 .byte 0x75, 0x03 - // jne CheckCardTable_WriteWatch_SVR64 + // jne LOCAL_LABEL(CheckCardTable_WriteWatch_SVR64) mov byte ptr [rax], 0xFF - CheckCardTable_WriteWatch_SVR64: + LOCAL_LABEL(CheckCardTable_WriteWatch_SVR64): shr rdi, 0x0B cmp byte ptr [rdi + r11], 0xFF .byte 0x75, 0x02 - // jne UpdateCardTable_WriteWatch_SVR64 + // jne LOCAL_LABEL(UpdateCardTable_WriteWatch_SVR64) REPRET - UpdateCardTable_WriteWatch_SVR64: + LOCAL_LABEL(UpdateCardTable_WriteWatch_SVR64): mov byte ptr [rdi + r11], 0xFF #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES @@ -600,10 +600,10 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_SVR64_PatchLabel_CardBundleTable shr rdi, 0x0A cmp byte ptr [rdi + r11], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundle_WriteWatch_SVR64 + // jne LOCAL_LABEL(UpdateCardBundle_WriteWatch_SVR64) REPRET - UpdateCardBundle_WriteWatch_SVR64: + LOCAL_LABEL(UpdateCardBundle_WriteWatch_SVR64): mov byte ptr [rdi + r11], 0xFF #endif @@ -632,57 +632,57 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_Byte_Region64_Patch_Label_RegionShrDest shr rdi, 0x16 // compute region index cmp byte ptr [rax], 0x0 .byte 0x75, 0x03 - // jne CheckGen0_WriteWatch_Byte_Region64 + // jne LOCAL_LABEL(CheckGen0_WriteWatch_Byte_Region64) mov byte ptr [rax], 0xFF - CheckGen0_WriteWatch_Byte_Region64: + LOCAL_LABEL(CheckGen0_WriteWatch_Byte_Region64): PATCH_LABEL JIT_WriteBarrier_WriteWatch_Byte_Region64_Patch_Label_RegionToGeneration mov rax, 0xF0F0F0F0F0F0F0F0 // Check whether the region we're storing into is gen 0 - nothing to do in this case cmp byte ptr [rdi + rax], 0 .byte 0x75, 0x08 - // jne NotGen0_WriteWatch_Byte_Region64 + // jne LOCAL_LABEL(NotGen0_WriteWatch_Byte_Region64) REPRET NOP_2_BYTE // padding for alignment of constant NOP_2_BYTE // padding for alignment of constant NOP_2_BYTE // padding for alignment of constant - NotGen0_WriteWatch_Byte_Region64: + LOCAL_LABEL(NotGen0_WriteWatch_Byte_Region64): PATCH_LABEL JIT_WriteBarrier_WriteWatch_Byte_Region64_Patch_Label_Lower movabs r9, 0xF0F0F0F0F0F0F0F0 cmp rsi, r9 .byte 0x73, 0x01 - // jae NotLow_WriteWatch_Byte_Region64 + // jae LOCAL_LABEL(NotLow_WriteWatch_Byte_Region64) ret - NotLow_WriteWatch_Byte_Region64: + LOCAL_LABEL(NotLow_WriteWatch_Byte_Region64): PATCH_LABEL JIT_WriteBarrier_WriteWatch_Byte_Region64_Patch_Label_Upper mov r9, 0xF0F0F0F0F0F0F0F0 cmp rsi, r9 .byte 0x72, 0x02 - // jb NotHigh_WriteWatch_Byte_Region64 + // jb LOCAL_LABEL(NotHigh_WriteWatch_Byte_Region64) REPRET - NotHigh_WriteWatch_Byte_Region64: + LOCAL_LABEL(NotHigh_WriteWatch_Byte_Region64): PATCH_LABEL JIT_WriteBarrier_WriteWatch_Byte_Region64_Patch_Label_RegionShrSrc shr rsi, 0x16 // compute region index mov dl, [rsi + rax] cmp dl, [rdi + rax] .byte 0x72, 0x03 - // jb IsOldToYoung_WriteWatch_Byte_Region64 + // jb LOCAL_LABEL(IsOldToYoung_WriteWatch_Byte_Region64) REPRET nop - IsOldToYoung_WriteWatch_Byte_Region64: + LOCAL_LABEL(IsOldToYoung_WriteWatch_Byte_Region64): PATCH_LABEL JIT_WriteBarrier_WriteWatch_Byte_Region64_Patch_Label_CardTable mov rax, 0xF0F0F0F0F0F0F0F0 shr r8, 0xB cmp byte ptr [r8 + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardTable_WriteWatch_Byte_Region64 + // jne LOCAL_LABEL(UpdateCardTable_WriteWatch_Byte_Region64) REPRET - UpdateCardTable_WriteWatch_Byte_Region64: + LOCAL_LABEL(UpdateCardTable_WriteWatch_Byte_Region64): mov byte ptr [r8 + rax], 0xFF #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES shr r8, 0x0A @@ -690,10 +690,10 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_Byte_Region64_Patch_Label_CardBundleTabl mov rax, 0xF0F0F0F0F0F0F0F0 cmp byte ptr [r8 + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundleTable_WriteWatch_Byte_Region64 + // jne LOCAL_LABEL(UpdateCardBundleTable_WriteWatch_Byte_Region64) REPRET - UpdateCardBundleTable_WriteWatch_Byte_Region64: + LOCAL_LABEL(UpdateCardBundleTable_WriteWatch_Byte_Region64): mov byte ptr [r8 + rax], 0xFF #endif ret @@ -718,47 +718,47 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_Bit_Region64_Patch_Label_RegionShrDest shr rdi, 0x16 // compute region index cmp byte ptr [rax], 0x0 .byte 0x75, 0x03 - // jne CheckGen0_WriteWatch_Bit_Region64 + // jne LOCAL_LABEL(CheckGen0_WriteWatch_Bit_Region64) mov byte ptr [rax], 0xFF - CheckGen0_WriteWatch_Bit_Region64: + LOCAL_LABEL(CheckGen0_WriteWatch_Bit_Region64): PATCH_LABEL JIT_WriteBarrier_WriteWatch_Bit_Region64_Patch_Label_RegionToGeneration mov rax, 0xF0F0F0F0F0F0F0F0 // Check whether the region we're storing into is gen 0 - nothing to do in this case cmp byte ptr [rdi + rax], 0 .byte 0x75, 0x08 - // jne NotGen0_WriteWatch_Bit_Region64 + // jne LOCAL_LABEL(NotGen0_WriteWatch_Bit_Region64) REPRET NOP_2_BYTE // padding for alignment of constant NOP_2_BYTE // padding for alignment of constant NOP_2_BYTE // padding for alignment of constant - NotGen0_WriteWatch_Bit_Region64: + LOCAL_LABEL(NotGen0_WriteWatch_Bit_Region64): PATCH_LABEL JIT_WriteBarrier_WriteWatch_Bit_Region64_Patch_Label_Lower movabs r9, 0xF0F0F0F0F0F0F0F0 cmp rsi, r9 .byte 0x73, 0x01 - // jae NotLow_WriteWatch_Bit_Region64 + // jae LOCAL_LABEL(NotLow_WriteWatch_Bit_Region64) ret - NotLow_WriteWatch_Bit_Region64: + LOCAL_LABEL(NotLow_WriteWatch_Bit_Region64): PATCH_LABEL JIT_WriteBarrier_WriteWatch_Bit_Region64_Patch_Label_Upper mov r9, 0xF0F0F0F0F0F0F0F0 cmp rsi, r9 .byte 0x72, 0x02 - // jb NotHigh_WriteWatch_Bit_Region64 + // jb LOCAL_LABEL(NotHigh_WriteWatch_Bit_Region64) REPRET - NotHigh_WriteWatch_Bit_Region64: + LOCAL_LABEL(NotHigh_WriteWatch_Bit_Region64): PATCH_LABEL JIT_WriteBarrier_WriteWatch_Bit_Region64_Patch_Label_RegionShrSrc shr rsi, 0x16 // compute region index mov dl, [rsi + rax] cmp dl, [rdi + rax] .byte 0x72, 0x03 - // jb IsOldToYoung_WriteWatch_Bit_Region64 + // jb LOCAL_LABEL(IsOldToYoung_WriteWatch_Bit_Region64) REPRET nop - IsOldToYoung_WriteWatch_Bit_Region64: + LOCAL_LABEL(IsOldToYoung_WriteWatch_Bit_Region64): PATCH_LABEL JIT_WriteBarrier_WriteWatch_Bit_Region64_Patch_Label_CardTable mov rax, 0xF0F0F0F0F0F0F0F0 @@ -770,10 +770,10 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_Bit_Region64_Patch_Label_CardTable shl dl, cl test byte ptr [r8 + rax], dl .byte 0x74, 0x02 - // je UpdateCardTable_WriteWatch_Bit_Region64 + // je LOCAL_LABEL(UpdateCardTable_WriteWatch_Bit_Region64) REPRET - UpdateCardTable_WriteWatch_Bit_Region64: + LOCAL_LABEL(UpdateCardTable_WriteWatch_Bit_Region64): lock or byte ptr [r8 + rax], dl #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES PATCH_LABEL JIT_WriteBarrier_WriteWatch_Bit_Region64_Patch_Label_CardBundleTable @@ -781,10 +781,10 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_Bit_Region64_Patch_Label_CardBundleTable shr r8, 0x0A cmp byte ptr [r8 + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundleTable_WriteWatch_Bit_Region64 + // jne LOCAL_LABEL(UpdateCardBundleTable_WriteWatch_Bit_Region64) REPRET - UpdateCardBundleTable_WriteWatch_Bit_Region64: + LOCAL_LABEL(UpdateCardBundleTable_WriteWatch_Bit_Region64): mov byte ptr [r8 + rax], 0xFF #endif ret diff --git a/src/mono/mono/metadata/icall-signatures.h b/src/mono/mono/metadata/icall-signatures.h index d45f1a569c31e8..221fcae8d58865 100644 --- a/src/mono/mono/metadata/icall-signatures.h +++ b/src/mono/mono/metadata/icall-signatures.h @@ -57,7 +57,7 @@ // mono_icall_sig_void_int32 // mono_icall_sig_void_object // mono_icall_sig_void_ptr -// mono_icall_sig_bool_ptr_ptrref +// mono_icall_sig_boolean_ptr_ptrref // mono_icall_sig_double_double_double // mono_icall_sig_float_float_float // mono_icall_sig_int_obj_ptr @@ -94,7 +94,7 @@ // mono_icall_sig_void_ptr_ptr // mono_icall_sig_void_ptr_ptrref // mono_icall_sig_void_uint32_ptrref -// mono_icall_sig_bool_ptr_int32_ptrref +// mono_icall_sig_boolean_ptr_int32_ptrref // mono_icall_sig_int32_int32_ptr_ptrref // mono_icall_sig_int32_ptr_int32_ptr // mono_icall_sig_int32_ptr_int32_ptrref @@ -182,7 +182,7 @@ ICALL_SIG (2, (void, int)) \ ICALL_SIG (2, (void, int32)) \ ICALL_SIG (2, (void, object)) \ ICALL_SIG (2, (void, ptr)) \ -ICALL_SIG (3, (bool, ptr, ptrref)) \ +ICALL_SIG (3, (boolean, ptr, ptrref)) \ ICALL_SIG (3, (double, double, double)) \ ICALL_SIG (3, (float, float, float)) \ ICALL_SIG (3, (int, obj, ptr)) \ @@ -222,7 +222,7 @@ ICALL_SIG (3, (void, ptr, object)) \ ICALL_SIG (3, (void, ptr, ptr)) \ ICALL_SIG (3, (void, ptr, ptrref)) \ ICALL_SIG (3, (void, uint32, ptrref)) \ -ICALL_SIG (4, (bool, ptr, int32, ptrref)) \ +ICALL_SIG (4, (boolean, ptr, int32, ptrref)) \ ICALL_SIG (4, (int32, int32, ptr, ptrref)) \ ICALL_SIG (4, (int32, ptr, int32, ptr)) \ ICALL_SIG (4, (int32, ptr, int32, ptrref)) \ diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 947ab70f31089b..6ba9978b16bf33 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -7185,8 +7185,7 @@ mono_lookup_icall_symbol (MonoMethod *m) // // mono_create_icall_signatures depends on this order. Handle with care. typedef enum ICallSigType { - ICALL_SIG_TYPE_bool = 0x00, - ICALL_SIG_TYPE_boolean = ICALL_SIG_TYPE_bool, + ICALL_SIG_TYPE_boolean = 0x00, ICALL_SIG_TYPE_double = 0x01, ICALL_SIG_TYPE_float = 0x02, ICALL_SIG_TYPE_int = 0x03, diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 9b4527cfb6f97b..8dcdacf07e0a89 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -14625,8 +14625,8 @@ add_preinit_got_slots (MonoAotCompile *acfg) #ifndef MONO_ARCH_HAVE_INTERP_ENTRY_TRAMPOLINE static MonoMethodSignature * const * const interp_in_static_sigs [] = { - &mono_icall_sig_bool_ptr_int32_ptrref, - &mono_icall_sig_bool_ptr_ptrref, + &mono_icall_sig_boolean_ptr_int32_ptrref, + &mono_icall_sig_boolean_ptr_ptrref, &mono_icall_sig_int32_int32_ptrref, &mono_icall_sig_int32_int32_ptr_ptrref, &mono_icall_sig_int32_ptr_int32_ptr, diff --git a/src/mono/mono/mini/decompose.c b/src/mono/mono/mini/decompose.c index 2be1ff52e416d0..b80969c29156c8 100644 --- a/src/mono/mono/mini/decompose.c +++ b/src/mono/mono/mini/decompose.c @@ -218,7 +218,7 @@ decompose_long_opcode (MonoCompile *cfg, MonoInst *ins, MonoInst **repl_ins) MONO_EMIT_NEW_COND_EXC (cfg, GT, "OverflowException"); /* The int cast is needed for the VS compiler. See Compiler Warning (level 2) C4146. */ #if SIZEOF_REGISTER == 8 - MONO_EMIT_NEW_LCOMPARE_IMM (cfg, ins->sreg1, (-(int)2147483648)); + MONO_EMIT_NEW_LCOMPARE_IMM (cfg, ins->sreg1, INT_MIN); #else g_assert (COMPILE_LLVM (cfg)); MONO_EMIT_NEW_LCOMPARE_IMM (cfg, ins->sreg1, -2147483648LL); diff --git a/src/tests/issues.targets b/src/tests/issues.targets index a5c8a27f2e41c9..b6bf5a2a809d43 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -2630,6 +2630,15 @@ + + + https://github.com/dotnet/runtime/issues/121983 + + + https://github.com/dotnet/runtime/issues/121983 + + + https://github.com/dotnet/runtime/issues/82859 From f0f6a8a5cdf6baf84013bca176f676f5e6869134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Cant=C3=BA?= Date: Wed, 7 Jan 2026 09:36:58 -0800 Subject: [PATCH 11/17] Revert "[release/8.0] Update dependencies from dotnet/arcade" (#122943) Reverts dotnet/runtime#122558 Context https://github.com/dotnet/runtime/pull/122558#issuecomment-3716001868. --- eng/Version.Details.xml | 72 +++++++++---------- eng/Versions.props | 30 ++++---- eng/common/internal-feed-operations.ps1 | 2 +- eng/common/post-build/nuget-verification.ps1 | 2 +- eng/common/post-build/post-build-utils.ps1 | 10 +-- .../templates-official/job/source-build.yml | 2 +- .../job/source-index-stage1.yml | 2 +- .../post-build/setup-maestro-vars.yml | 2 +- .../templates-official/steps/source-build.yml | 2 +- eng/common/templates/steps/source-build.yml | 2 +- eng/common/tools.ps1 | 6 +- global.json | 6 +- 12 files changed, 69 insertions(+), 69 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e4a8bb14cc5898..1072aae418bc22 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -111,9 +111,9 @@
- + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 @@ -121,69 +121,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 https://github.com/dotnet/runtime-assets @@ -334,9 +334,9 @@ https://github.com/dotnet/xharness 402df9c4f5abe6ee8519181dfb5481e04099fab0 - + https://github.com/dotnet/arcade - 4b01306353c43c151d713d152f48a4d523c41960 + e8483fe03c7d3257c68f6013441da5d72eeb8392 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 4c58816e9809ac..45ec5f325c6594 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -89,21 +89,21 @@ 8.0.100 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 2.5.1-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 - 8.0.0-beta.25611.2 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 2.5.1-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 + 8.0.0-beta.25562.3 6.0.0-preview.1.102 diff --git a/eng/common/internal-feed-operations.ps1 b/eng/common/internal-feed-operations.ps1 index c282d3ae403a09..92b77347d9904e 100644 --- a/eng/common/internal-feed-operations.ps1 +++ b/eng/common/internal-feed-operations.ps1 @@ -26,7 +26,7 @@ function SetupCredProvider { $url = 'https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1' Write-Host "Writing the contents of 'installcredprovider.ps1' locally..." - Invoke-WebRequest $url -UseBasicParsing -OutFile installcredprovider.ps1 + Invoke-WebRequest $url -OutFile installcredprovider.ps1 Write-Host 'Installing plugin...' .\installcredprovider.ps1 -Force diff --git a/eng/common/post-build/nuget-verification.ps1 b/eng/common/post-build/nuget-verification.ps1 index 6cbbcafade26bf..8467dbf8e7c218 100644 --- a/eng/common/post-build/nuget-verification.ps1 +++ b/eng/common/post-build/nuget-verification.ps1 @@ -65,7 +65,7 @@ if ($NuGetExePath) { Write-Host "Downloading nuget.exe from $nugetExeUrl..." $ProgressPreference = 'SilentlyContinue' try { - Invoke-WebRequest $nugetExeUrl -UseBasicParsing -OutFile $downloadedNuGetExe + Invoke-WebRequest $nugetExeUrl -OutFile $downloadedNuGetExe $ProgressPreference = 'Continue' } catch { $ProgressPreference = 'Continue' diff --git a/eng/common/post-build/post-build-utils.ps1 b/eng/common/post-build/post-build-utils.ps1 index 83f9efb0b364d6..534f6988d5b7fd 100644 --- a/eng/common/post-build/post-build-utils.ps1 +++ b/eng/common/post-build/post-build-utils.ps1 @@ -26,7 +26,7 @@ function Get-MaestroChannel([int]$ChannelId) { $apiHeaders = Create-MaestroApiRequestHeaders $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}?api-version=$MaestroApiVersion" - $result = try { Invoke-WebRequest -UseBasicParsing -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + $result = try { Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } return $result } @@ -36,7 +36,7 @@ function Get-MaestroBuild([int]$BuildId) { $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken $apiEndpoint = "$MaestroApiEndPoint/api/builds/${BuildId}?api-version=$MaestroApiVersion" - $result = try { return Invoke-WebRequest -UseBasicParsing -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + $result = try { return Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } return $result } @@ -47,7 +47,7 @@ function Get-MaestroSubscriptions([string]$SourceRepository, [int]$ChannelId) { $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions?sourceRepository=$SourceRepository&channelId=$ChannelId&api-version=$MaestroApiVersion" - $result = try { Invoke-WebRequest -UseBasicParsing -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + $result = try { Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } return $result } @@ -56,7 +56,7 @@ function Assign-BuildToChannel([int]$BuildId, [int]$ChannelId) { $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}/builds/${BuildId}?api-version=$MaestroApiVersion" - Invoke-WebRequest -UseBasicParsing -Method Post -Uri $apiEndpoint -Headers $apiHeaders | Out-Null + Invoke-WebRequest -Method Post -Uri $apiEndpoint -Headers $apiHeaders | Out-Null } function Trigger-Subscription([string]$SubscriptionId) { @@ -64,7 +64,7 @@ function Trigger-Subscription([string]$SubscriptionId) { $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions/$SubscriptionId/trigger?api-version=$MaestroApiVersion" - Invoke-WebRequest -UseBasicParsing -Uri $apiEndpoint -Headers $apiHeaders -Method Post | Out-Null + Invoke-WebRequest -Uri $apiEndpoint -Headers $apiHeaders -Method Post | Out-Null } function Validate-MaestroVars { diff --git a/eng/common/templates-official/job/source-build.yml b/eng/common/templates-official/job/source-build.yml index f75400757d1ea5..7b9c58a90c5ef7 100644 --- a/eng/common/templates-official/job/source-build.yml +++ b/eng/common/templates-official/job/source-build.yml @@ -61,7 +61,7 @@ jobs: ${{ if eq(variables['System.TeamProject'], 'internal') }}: name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] - image: 1es-azurelinux-3 + image: 1es-mariner-2 os: linux ${{ if ne(parameters.platform.pool, '') }}: diff --git a/eng/common/templates-official/job/source-index-stage1.yml b/eng/common/templates-official/job/source-index-stage1.yml index 8de0dfaf349434..0579e692fc8131 100644 --- a/eng/common/templates-official/job/source-index-stage1.yml +++ b/eng/common/templates-official/job/source-index-stage1.yml @@ -6,7 +6,7 @@ parameters: sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" preSteps: [] binlogPath: artifacts/log/Debug/Build.binlog - condition: eq(variables['Build.SourceBranch'], 'refs/heads/main') + condition: '' dependsOn: '' pool: '' diff --git a/eng/common/templates-official/post-build/setup-maestro-vars.yml b/eng/common/templates-official/post-build/setup-maestro-vars.yml index 3a56abf8922ef3..0c87f149a4ad77 100644 --- a/eng/common/templates-official/post-build/setup-maestro-vars.yml +++ b/eng/common/templates-official/post-build/setup-maestro-vars.yml @@ -37,7 +37,7 @@ steps: $apiHeaders.Add('Accept', 'application/json') $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") - $buildInfo = try { Invoke-WebRequest -UseBasicParsing -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } $BarId = $Env:BARBuildId $Channels = $Env:PromoteToMaestroChannels -split "," diff --git a/eng/common/templates-official/steps/source-build.yml b/eng/common/templates-official/steps/source-build.yml index c307825c91222f..b63043da4b9f3f 100644 --- a/eng/common/templates-official/steps/source-build.yml +++ b/eng/common/templates-official/steps/source-build.yml @@ -47,7 +47,7 @@ steps: # in the default public locations. internalRuntimeDownloadArgs= if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then - internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://ci.dot.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://ci.dot.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' + internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' fi buildConfig=Release diff --git a/eng/common/templates/steps/source-build.yml b/eng/common/templates/steps/source-build.yml index d08a0e92caa49e..ae06b26ea37340 100644 --- a/eng/common/templates/steps/source-build.yml +++ b/eng/common/templates/steps/source-build.yml @@ -47,7 +47,7 @@ steps: # in the default public locations. internalRuntimeDownloadArgs= if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then - internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://ci.dot.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://ci.dot.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' + internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' fi buildConfig=Release diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index b674a90618d76d..bb048ad125a8cf 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -267,7 +267,7 @@ function GetDotNetInstallScript([string] $dotnetRoot) { Retry({ Write-Host "GET $uri" - Invoke-WebRequest $uri -UseBasicParsing -OutFile $installScript + Invoke-WebRequest $uri -OutFile $installScript }) } @@ -501,7 +501,7 @@ function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) { Write-Host "Downloading $packageName $packageVersion" $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit Retry({ - Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -UseBasicParsing -OutFile $packagePath + Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -OutFile $packagePath }) Unzip $packagePath $packageDir @@ -541,7 +541,7 @@ function LocateVisualStudio([object]$vsRequirements = $null){ Create-Directory $vsWhereDir Write-Host 'Downloading vswhere' Retry({ - Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -UseBasicParsing -OutFile $vswhereExe + Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -OutFile $vswhereExe }) } diff --git a/global.json b/global.json index 075a43ef4c3126..eea4c3f60c15b8 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.122" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.25611.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.25611.2", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.25611.2", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.25562.3", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.25562.3", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.25562.3", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From f9b9060339309c4ff00b0a8ed1c531a02a8841c2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 20 Jan 2026 08:51:57 -0500 Subject: [PATCH 12/17] [release/8.0-staging] Update dependencies from dotnet/source-build-reference-packages (#123243) This pull request updates the following dependencies [marker]: <> (Begin:1626bff2-6010-444e-f998-08dbcfd3e5b0) ## From https://github.com/dotnet/source-build-reference-packages - **Subscription**: [1626bff2-6010-444e-f998-08dbcfd3e5b0](https://maestro.dot.net/subscriptions?search=1626bff2-6010-444e-f998-08dbcfd3e5b0) - **Build**: [20251215.3](https://dev.azure.com/dnceng/internal/_build/results?buildId=2861480) ([294695](https://maestro.dot.net/channel/3885/github:dotnet:source-build-reference-packages/build/294695)) - **Date Produced**: December 15, 2025 3:29:24 PM UTC - **Commit**: [44b5b62182b48c34c4b6aef28943ec3f3e82f214](https://github.com/dotnet/source-build-reference-packages/commit/44b5b62182b48c34c4b6aef28943ec3f3e82f214) - **Branch**: [release/8.0](https://github.com/dotnet/source-build-reference-packages/tree/release/8.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [8.0.0-alpha.1.25522.3 to 8.0.0-alpha.1.25615.3][1] - Microsoft.SourceBuild.Intermediate.source-build-reference-packages [1]: https://github.com/dotnet/source-build-reference-packages/compare/449148366d...44b5b62182 [DependencyUpdate]: <> (End) [marker]: <> (End:1626bff2-6010-444e-f998-08dbcfd3e5b0) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 365787291f98d0..dc9e3cb39200d6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -99,9 +99,9 @@ 81d2833ee1bf80f65cae9957c1926993ce1a299f - + https://github.com/dotnet/source-build-reference-packages - 449148366d9105de8a6470ebc4ba198926e9a30a + 44b5b62182b48c34c4b6aef28943ec3f3e82f214 From 8136db41b7e04aa72be85f54a23f4cce1cff415c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 08:54:27 -0500 Subject: [PATCH 13/17] [release/8.0-staging] [mono][hotreload] Ignore if we receive an empty update. (#123547) Backport of #120333 to release/8.0-staging /cc @thaystg ## Customer Impact - [X] Customer reported - [ ] Found internally This change was initially backported to .NET 10 and 9 back in October: 10 - https://github.com/dotnet/runtime/pull/120334 9 - https://github.com/dotnet/runtime/pull/120335 We didn't think we would need it in .NET 8, but that turned out to not be the case. This change fixes a problem with hot reload on blazor webassembly where two updates are sent to the runtime at the same time and the runtime asserts. This was previously an unsupported scenario, but recent up stack changes altered the behavior. The plan is to fix both the up stack behavior and in runtime as a defense in depth. The reasoning is that one of the two updates sent to runtime contains no IL. We can look at that one and safely ignore it. ## Regression - [ ] Yes - [X] No Not in runtime at least. This was not a supported scenario, but was trigged via a VS level change. [If yes, specify when the regression was introduced. Provide the PR or commit if known.] ## Testing Manual before and after testing [How was the fix verified? How was the issue missed previously? What tests were added?] ## Risk Low [High/Medium/Low. Justify the indication by mentioning how risks were measured and addressed.] **IMPORTANT**: If this backport is for a servicing release, please verify that: - For .NET 8 and .NET 9: The PR target branch is `release/X.0-staging`, not `release/X.0`. - For .NET 10+: The PR target branch is `release/X.0` (no `-staging` suffix). ## Package authoring no longer needed in .NET 9 **IMPORTANT**: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version. Keep in mind that we still need package authoring in .NET 8 and older versions. --------- Co-authored-by: Thays Grazia Co-authored-by: Thays Grazia Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/mono/mono/component/hot_reload.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/component/hot_reload.c b/src/mono/mono/component/hot_reload.c index 2245fcb4a1578e..ce2b555438fa49 100644 --- a/src/mono/mono/component/hot_reload.c +++ b/src/mono/mono/component/hot_reload.c @@ -2574,9 +2574,11 @@ hot_reload_apply_changes (int origin, MonoImage *image_base, gconstpointer dmeta if (!assembly_update_supported (image_base, error)) { return; } - + if (dmeta_bytes == 0 && dil_bytes_orig == 0) // we may receive empty updates + { + return; + } static int first_origin = -1; - if (first_origin < 0) { first_origin = origin; } From 6aaca788618300717d30ff31339e512b8f1b3cce Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Mon, 2 Feb 2026 08:59:26 -0500 Subject: [PATCH 14/17] [release/8.0-staging] Bump iOS & tvOS queues (#123768) All MacOS 13 queues no longer exist. --- eng/pipelines/coreclr/templates/helix-queues-setup.yml | 5 ++--- eng/pipelines/libraries/helix-queues-setup.yml | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index 3b678b14066879..5dec2f7a0cc98e 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -56,12 +56,11 @@ jobs: # iOS devices - ${{ if in(parameters.platform, 'ios_arm64') }}: - - OSX.13.Amd64.Iphone.Open + - OSX.15.Amd64.Iphone.Open # tvOS devices - ${{ if in(parameters.platform, 'tvos_arm64') }}: - - OSX.13.Amd64.AppleTV.Open - + - OSX.15.Amd64.AppleTV.Open # Linux arm - ${{ if eq(parameters.platform, 'linux_arm') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 22f7b0e5102ac5..1df5b90baf86bd 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -98,12 +98,11 @@ jobs: # iOS devices - ${{ if in(parameters.platform, 'ios_arm64') }}: - - OSX.13.Amd64.Iphone.Open + - OSX.15.Amd64.Iphone.Open # tvOS devices - ${{ if in(parameters.platform, 'tvos_arm64') }}: - - OSX.13.Amd64.AppleTV.Open - + - OSX.15.Amd64.AppleTV.Open # windows x64 - ${{ if eq(parameters.platform, 'windows_x64') }}: # netcoreapp From 899167807134075ecc66b2ce4705bfc1178188a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:27:32 +0100 Subject: [PATCH 15/17] [release/8.0-staging] Update MsQuicSchannelVersion to 2.4.16 (#123937) Update MsQuic version published with dotnet/runtime on Windows. Backport of https://github.com/dotnet/runtime/pull/121198 ## Customer Impact No ## Regression No ## Testing Automated tests ## Risk Low, change only in patch version and we've been running with 2.4.16 in main and .NET 10 for many months. --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 5f008f5da619e5..befafcd35eee1b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -232,7 +232,7 @@ 8.0.0-rtm.25625.2 - 2.4.8 + 2.4.16 16.0.5-alpha.1.25311.1 16.0.5-alpha.1.25311.1 From 2c7e75764f2aafc900fdee323ce21f2c11c8cbef Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 00:02:25 +0000 Subject: [PATCH 16/17] [release/8.0-staging] Update dependencies from dotnet/hotreload-utils (#123618) This pull request updates the following dependencies [marker]: <> (Begin:c0fef358-3848-4a30-a438-08dbcfd61a5a) ## From https://github.com/dotnet/hotreload-utils - **Subscription**: [c0fef358-3848-4a30-a438-08dbcfd61a5a](https://maestro.dot.net/subscriptions?search=c0fef358-3848-4a30-a438-08dbcfd61a5a) - **Build**: [20260126.2](https://dev.azure.com/dnceng/internal/_build/results?buildId=2887725) ([298834](https://maestro.dot.net/channel/3073/github:dotnet:hotreload-utils/build/298834)) - **Date Produced**: January 26, 2026 9:10:24 AM UTC - **Commit**: [6074d7872b31463f8b6741589ba543c8d80ce42d](https://github.com/dotnet/hotreload-utils/commit/6074d7872b31463f8b6741589ba543c8d80ce42d) - **Branch**: [release/8.0](https://github.com/dotnet/hotreload-utils/tree/release/8.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [8.0.0-alpha.0.25625.3 to 8.0.0-alpha.0.26076.2][1] - Microsoft.DotNet.HotReload.Utils.Generator.BuildTool [1]: https://github.com/dotnet/hotreload-utils/compare/e7e99065bb...6074d7872b [DependencyUpdate]: <> (End) [marker]: <> (End:c0fef358-3848-4a30-a438-08dbcfd61a5a) Co-authored-by: dotnet-maestro[bot] Co-authored-by: Steve Pfister --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index dc9e3cb39200d6..992f114b39d410 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://github.com/dotnet/hotreload-utils - e7e99065bbd4a7b911d5cfa56b23d873d9675355 + 6074d7872b31463f8b6741589ba543c8d80ce42d https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index befafcd35eee1b..ac12176910be98 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -199,7 +199,7 @@ 8.0.0-prerelease.25516.2 8.0.0-prerelease.25516.2 8.0.0-prerelease.25516.2 - 8.0.0-alpha.0.25625.3 + 8.0.0-alpha.0.26076.2 2.4.2 1.0.0 2.4.5 From c85bfd37d4df50dea299782e38a58a5c188ed6bd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 18:11:17 -0800 Subject: [PATCH 17/17] [automated] Merge branch 'release/8.0' => 'release/8.0-staging' (#124246) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I detected changes in the release/8.0 branch which have not been merged yet to release/8.0-staging. I'm a robot and am configured to help you automatically keep release/8.0-staging up to date, so I've opened this PR. This PR merges commits made on release/8.0 by the following committers: * wfurt * vseanreesermsft * akoeplinger * dotnet-maestro[bot] * github-actions[bot] * jeffhandley * bartonjs * jozkee ## Instructions for merging from UI This PR will not be auto-merged. When pull request checks pass, complete this PR by creating a merge commit, *not* a squash or rebase commit. merge button instructions If this repo does not allow creating merge commits from the GitHub UI, use command line instructions. ## Instructions for merging via command line Run these commands to merge this pull request from the command line. ``` sh git fetch git checkout release/8.0 git pull --ff-only git checkout release/8.0-staging git pull --ff-only git merge --no-ff release/8.0 # If there are merge conflicts, resolve them and then run git merge --continue to complete the merge # Pushing the changes to the PR branch will re-trigger PR validation. git push https://github.com/dotnet/runtime HEAD:merge/release/8.0-to-release/8.0-staging ```
or if you are using SSH ``` git push git@github.com:dotnet/runtime HEAD:merge/release/8.0-to-release/8.0-staging ```
After PR checks are complete push the branch ``` git push ``` ## Instructions for resolving conflicts :warning: If there are merge conflicts, you will need to resolve them manually before merging. You can do this [using GitHub][resolve-github] or using the [command line][resolve-cli]. [resolve-github]: https://help.github.com/articles/resolving-a-merge-conflict-on-github/ [resolve-cli]: https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/ ## Instructions for updating this pull request Contributors to this repo have permission update this pull request by pushing to the branch 'merge/release/8.0-to-release/8.0-staging'. This can be done to resolve conflicts or make other changes to this pull request before it is merged. The provided examples assume that the remote is named 'origin'. If you have a different remote name, please replace 'origin' with the name of your remote. ``` git fetch git checkout -b merge/release/8.0-to-release/8.0-staging origin/release/8.0-staging git pull https://github.com/dotnet/runtime merge/release/8.0-to-release/8.0-staging (make changes) git commit -m "Updated PR with my changes" git push https://github.com/dotnet/runtime HEAD:merge/release/8.0-to-release/8.0-staging ```
or if you are using SSH ``` git fetch git checkout -b merge/release/8.0-to-release/8.0-staging origin/release/8.0-staging git pull git@github.com:dotnet/runtime merge/release/8.0-to-release/8.0-staging (make changes) git commit -m "Updated PR with my changes" git push git@github.com:dotnet/runtime HEAD:merge/release/8.0-to-release/8.0-staging ```
Contact .NET Core Engineering (dotnet/dnceng) if you have questions or issues. Also, if this PR was generated incorrectly, help us fix it. See https://github.com/dotnet/arcade/blob/main/.github/workflows/scripts/inter-branch-merge.ps1. --------- Co-authored-by: Mirroring Co-authored-by: vseanreesermsft <78103370+vseanreesermsft@users.noreply.github.com> Co-authored-by: David Cantú Co-authored-by: Jeremy Barton Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: dotnet-maestro[bot] Co-authored-by: Jeff Handley Co-authored-by: Sean Reeser Co-authored-by: Miha Zupan Co-authored-by: Nikola Milosavljevic Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com> Co-authored-by: Elinor Fung Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com> Co-authored-by: Sven Boemer Co-authored-by: Andy Gocke Co-authored-by: Eric StJohn Co-authored-by: Matous Kozak Co-authored-by: Steve Pfister Co-authored-by: Filip Navara Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com> Co-authored-by: Alexander Köplinger Co-authored-by: Tomas Weinfurt --- NuGet.config | 2 +- eng/Version.Details.xml | 8 +- eng/Versions.props | 6 +- eng/pipelines/common/evaluate-paths-job.yml | 8 +- .../System.Security.Cryptography.Cose.csproj | 4 +- .../Security/Cryptography/Cose/CoseMessage.cs | 56 ++++++-- .../tests/CoseMessageTests.DecodeMultiSign.cs | 126 ++++++++++++++++++ .../tests/CoseMessageTests.DecodeSign1.cs | 125 +++++++++++++++++ .../CoseMessageTests.Sign.CustomHeaderMaps.cs | 55 +++++--- 9 files changed, 350 insertions(+), 40 deletions(-) diff --git a/NuGet.config b/NuGet.config index d7ff98733a3537..d74fa2a4c62854 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c567a80367fb2e..81b9dc541bcf8e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,13 +90,13 @@ 8bb0f2d5f3b6b9dff32e2643642bea09bf6ae38d
- + https://github.com/dotnet/emsdk - 3cbd998b237cdde910fd4c4964207a87dd04c837 + badf9f97aaf4c2166b17bd6475ca73958c11e309 - + https://github.com/dotnet/emsdk - 3cbd998b237cdde910fd4c4964207a87dd04c837 + badf9f97aaf4c2166b17bd6475ca73958c11e309 diff --git a/eng/Versions.props b/eng/Versions.props index 6bd28d7bda1860..9f3768ffab74f1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,11 +1,11 @@ - 8.0.23 + 8.0.25 8 0 - 23 + 25 8.0.100 7.0.20 6.0.36 @@ -254,7 +254,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.23 + 8.0.25 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda diff --git a/eng/pipelines/common/evaluate-paths-job.yml b/eng/pipelines/common/evaluate-paths-job.yml index ebf3c930fb70ae..93e2aa23b9c044 100644 --- a/eng/pipelines/common/evaluate-paths-job.yml +++ b/eng/pipelines/common/evaluate-paths-job.yml @@ -28,7 +28,13 @@ jobs: - job: evaluate_paths displayName: Evaluate Paths pool: - vmImage: 'ubuntu-latest' + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $(DncEngPublicBuildPool) + demands: ImageOverride -equals build.azurelinux.3.amd64.open + ${{ else }}: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals build.azurelinux.3.amd64 + os: linux steps: - checkout: self diff --git a/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj b/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj index e8dc5ff2663a1a..1b411e3ce4f158 100644 --- a/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj +++ b/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj @@ -4,8 +4,8 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true true - 1 - false + 2 + true Provides support for CBOR Object Signing and Encryption (COSE). diff --git a/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseMessage.cs b/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseMessage.cs index 6395c966246ff1..39cb6a0a874f7d 100644 --- a/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseMessage.cs +++ b/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseMessage.cs @@ -295,10 +295,19 @@ private static void DecodeUnprotectedBucket(CborReader reader, CoseHeaderMap hea private static void DecodeBucket(CborReader reader, CoseHeaderMap headerParameters) { - int? length = reader.ReadStartMap(); - for (int i = 0; i < length; i++) + reader.ReadStartMap(); + + while (true) { - CoseHeaderLabel label = reader.PeekState() switch + CborReaderState state = reader.PeekState(); + + if (state == CborReaderState.EndMap) + { + reader.ReadEndMap(); + break; + } + + CoseHeaderLabel label = state switch { CborReaderState.UnsignedInteger or CborReaderState.NegativeInteger => new CoseHeaderLabel(reader.ReadInt32()), CborReaderState.TextString => new CoseHeaderLabel(reader.ReadTextString()), @@ -306,9 +315,23 @@ private static void DecodeBucket(CborReader reader, CoseHeaderMap headerParamete }; CoseHeaderValue value = CoseHeaderValue.FromEncodedValue(reader.ReadEncodedValue().Span); - headerParameters.Add(label, value); + + try + { + headerParameters.Add(label, value); + } + catch (ArgumentException e) + { + // Lift the well-known header value validation into a CryptographicException. + if (e.ParamName == "value") + { + throw new CryptographicException(e.Message); + } + + Debug.Fail("Unexpected ArgumentException from CoseHeaderMap.Add"); + throw new CryptographicException(SR.DecodeErrorWhileDecodingSeeInnerEx, e); + } } - reader.ReadEndMap(); } private static byte[]? DecodePayload(CborReader reader) @@ -563,13 +586,23 @@ internal static bool MissingCriticalHeaders(CoseHeaderMap? protectedHeders, out return false; } + bool empty = true; + var reader = new CborReader(critHeaderValue.EncodedValue); - int length = reader.ReadStartArray().GetValueOrDefault(); - Debug.Assert(length > 0); + reader.ReadStartArray(); - for (int i = 0; i < length; i++) + while (true) { - CoseHeaderLabel label = reader.PeekState() switch + CborReaderState state = reader.PeekState(); + + if (state == CborReaderState.EndArray) + { + reader.ReadEndArray(); + break; + } + + empty = false; + CoseHeaderLabel label = state switch { CborReaderState.UnsignedInteger or CborReaderState.NegativeInteger => new CoseHeaderLabel(reader.ReadInt32()), CborReaderState.TextString => new CoseHeaderLabel(reader.ReadTextString()), @@ -583,6 +616,11 @@ internal static bool MissingCriticalHeaders(CoseHeaderMap? protectedHeders, out } } + if (empty) + { + throw new CryptographicException(SR.CriticalHeadersMustBeArrayOfAtLeastOne); + } + labelName = null; return false; } diff --git a/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.DecodeMultiSign.cs b/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.DecodeMultiSign.cs index 57fd753af4c011..229ef187377512 100644 --- a/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.DecodeMultiSign.cs +++ b/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.DecodeMultiSign.cs @@ -144,5 +144,131 @@ public void DecodeMultiSign_IndefiniteLengthArray_ShorterByOne(string hexCborPay CryptographicException ex = Assert.Throws(() => CoseMessage.DecodeMultiSign(cborPayload)); Assert.Null(ex.InnerException); } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(false, true)] + public void DecodeMultiSignThrowsIfCriticalHeaderIsMissing(bool detached, bool useIndefiniteLength) + { + const string AttachedDefiniteHex = + "D8628440A054546869732069732074686520636F6E74656E742E818347A20126" + + "0281182AA05840ECB8C39BE15156FB6567C33634C75396D7FE1042C84FE54B9C" + + "EFA51E674C0CB227A8C08E558B6047668BBE3311749776670D1583A14B3A2DD8" + + "7F63F0FA298452"; + + const string AttachedIndefiniteHex = + "D8628440A054546869732069732074686520636F6E74656E742E818348A20126" + + "029F182AFFA05840F62CB760AC27D393D88ED392D5D4D55A02B0BB75261E75FE" + + "9B346C280DA6B93BE7F5B1B66B74561513EA52CAA2C66FE7474010035C678DA6" + + "B3549D3E671166EB"; + + const string DetachedDefiniteHex = + "D8628440A0F6818347A201260281182AA05840F96CE3D0999F34BE0E3FC62AE2" + + "AB25DD8D88F7154E6FADD5FFFEAF78F89DB97AC3E599ADB555C8442BD520F3F4" + + "8CB6A320B864677E26D1FA79FEDD79C3BCA927"; + + const string DetachedIndefiniteHex = + "D8628440A0F6818348A20126029F182AFFA0584028E95F7F9267CED0061339A7" + + "6602D823774EDA3E8D53B0A4FA436B71B0DBCA6F03F561A67355374AF494648C" + + "941558146F9C22B17542EBAF23497D27635A1829"; + + string inputHex = (detached, useIndefiniteLength) switch + { + (false, false) => AttachedDefiniteHex, + (false, true) => AttachedIndefiniteHex, + (true, false) => DetachedDefiniteHex, + (true, true) => DetachedIndefiniteHex, + }; + + AssertExtensions.ThrowsContains( + () => CoseMessage.DecodeMultiSign(ByteUtils.HexToByteArray(inputHex)), + "Critical Header '42' missing from protected map."); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(false, true)] + public void DecodeMultiSignThrowsIfCriticalHeadersIsEmpty(bool detached, bool useIndefiniteLength) + { + const string AttachedDefiniteHex = + "D8628440A054546869732069732074686520636F6E74656E742E818345A20126" + + "0280A05840B5F9E21078643A74B181ED294AC72C71F20AC5CA7AD037F559C68E" + + "06148429396A4194133763AB6918D747ACEE820CC430C2E891E3E2D5EECF6126" + + "1CEA33C6D4"; + + const string AttachedIndefiniteHex = + "D8628440A054546869732069732074686520636F6E74656E742E818346A20126" + + "029FFFA05840DDF3C0B85415AD1628C0B50C0F3FEDE675C1003484687CDFA3FA" + + "09285D5A31D48ADF11744BE0AE87F0189408A9CF38F0572537E8A786D505B6A6" + + "EE2008B91C74"; + + const string DetachedDefiniteHex = + "D8628440A0F6818345A201260280A05840EB66EE9E064CAB2E2F50244661734D" + + "9AEBD959BD21278E8D4827870DFE10C27B52E3E21D29185FC64526DC3B80C108" + + "548E956E9DBDDC7B23D100C17715AEE163"; + + const string DetachedIndefiniteHex = + "D8628440A0F6818346A20126029FFFA05840FC954ABD1611F7C6EEDD7FE71C3F" + + "62821AD46ED1988500F3309D0C607F0F151A69D0FC7BC968B2C36AEE68AC2B9A" + + "9580DFE1244F6E5F834183497F21EA5900C1"; + + string inputHex = (detached, useIndefiniteLength) switch + { + (false, false) => AttachedDefiniteHex, + (false, true) => AttachedIndefiniteHex, + (true, false) => DetachedDefiniteHex, + (true, true) => DetachedIndefiniteHex, + }; + + AssertExtensions.ThrowsContains( + () => CoseMessage.DecodeMultiSign(ByteUtils.HexToByteArray(inputHex)), + "Critical Headers must be a CBOR array of at least one element."); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(false, true)] + public void DecodeMultiSignThrowsIfCriticalHeaderIsOfUnknownType(bool detached, bool useIndefiniteLength) + { + const string AttachedDefiniteHex = + "D8628440A054546869732069732074686520636F6E74656E742E818347A20126" + + "0281412AA05840FCAFEDBE41693C7BA43FB58E2CF06182BE1BF340122CC5AFD4" + + "F59172C7E95166FF8E98FE9A0C2BEFEA135FD800DE6CA9A281D49B141CB93B17" + + "D992E693540F8A"; + + const string AttachedIndefiniteHex = + "D8628440A054546869732069732074686520636F6E74656E742E818348A20126" + + "029F412AFFA058400D3F4426B26007D731677D99B542E524847FF3927BCA74E4" + + "1823B09D6CA57A0E107F93DFE5DB851F4CEE8C0E4AF83E3540848F026FCD761F" + + "91CA2ED8D5F98134"; + + const string DetachedDefiniteHex = + "D8628440A0F6818347A201260281412AA0584008E0EEF66622FEC926CB651E90" + + "13D8628AB72581533761EDE52972FE6DFBF2C4BADB6C218E8AD1E28F8192DFB2" + + "8A82A4444A74C370AEA6C63AC982EABCD52874"; + + const string DetachedIndefiniteHex = + "D8628440A0F6818348A20126029F412AFFA05840C6DDCA2F35B7B285AB594963" + + "E9DB43CBDC77842256A7D1D31704749C7446AD5A67BBC02F9DBAF8F394ECCCA7" + + "8E8B63E5BB746F0205EE5732DFB2E00EBA3D5F48"; + + string inputHex = (detached, useIndefiniteLength) switch + { + (false, false) => AttachedDefiniteHex, + (false, true) => AttachedIndefiniteHex, + (true, false) => DetachedDefiniteHex, + (true, true) => DetachedIndefiniteHex, + }; + + AssertExtensions.ThrowsContains( + () => CoseMessage.DecodeMultiSign(ByteUtils.HexToByteArray(inputHex)), + "Header '2' does not accept the specified value."); + } } } diff --git a/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.DecodeSign1.cs b/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.DecodeSign1.cs index 8d3fdb27ad5dea..f06db0413a97b2 100644 --- a/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.DecodeSign1.cs +++ b/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.DecodeSign1.cs @@ -102,5 +102,130 @@ public void DecodeSign1_IndefiniteLengthArray_ShorterByOne() CryptographicException ex = Assert.Throws(() => CoseMessage.DecodeSign1(cborPayload)); Assert.Null(ex.InnerException); } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(false, true)] + public void DecodeSign1ThrowsIfCriticalHeaderIsMissing(bool detached, bool useIndefiniteLength) + { + const string AttachedDefiniteHex = + "D28447A201260281182AA054546869732069732074686520636F6E74656E742E" + + "5840F78745BDFA8CDF90ED6EC130BC8D97F43C8A52899920221832A1E758A1E7" + + "590827148F6D1A76673E7E9615F628730B19F07707B6FB1C9CD7B6D4E2B3C3F0" + + "DEAD"; + + const string AttachedIndefiniteHex = + "D28448A20126029F182AFFA054546869732069732074686520636F6E74656E74" + + "2E58408B07F60298F64453356EAF005C630A4576AF4C66E0327579BB81B5D726" + + "3836AA9419B1312298DD47BC10BA22D6DEEE35F1526948BF098915816149B46A" + + "3C9981"; + + const string DetachedDefiniteHex = + "D28447A201260281182AA0F6584089B093A038B0636940F9273EF11214B64CC1" + + "BB862305EDEC9C772A3D5089A54A6CBBA00323FA59A593A828F157653DEE15B0" + + "EBBDC070D02CDFD13E8A9F2ECA1B"; + + const string DetachedIndefiniteHex = + "D28448A20126029F182AFFA0F658409B35B9FD294BDF36EEF7494D0EC9E19F6A2" + + "106638FD4A2A31B816FED80493772DCEA8B64F6618119E278379F83E1A62BA382" + + "21B9F1AC705FAD8612DC6B0478A0"; + + string inputHex = (detached, useIndefiniteLength) switch + { + (false, false) => AttachedDefiniteHex, + (false, true) => AttachedIndefiniteHex, + (true, false) => DetachedDefiniteHex, + (true, true) => DetachedIndefiniteHex, + }; + + AssertExtensions.ThrowsContains( + () => CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(inputHex)), + "Critical Header '42' missing from protected map."); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(false, true)] + public void DecodeSign1ThrowsIfCriticalHeadersIsEmpty(bool detached, bool useIndefiniteLength) + { + const string AttachedDefiniteHex = + "D28445A201260280A054546869732069732074686520636F6E74656E742E5840" + + "57C7EE86AF06B1ABB002480CE148DFDA06C2CA4AFE83E9C7AE3493EA13E06E9B" + + "0A4C713F7FDCDD2F8731103CDA28B83313E411988B88AC7716E43307B5AF22FD"; + + const string AttachedIndefiniteHex = + "D28446A20126029FFFA054546869732069732074686520636F6E74656E742E58" + + "401B941A9C799270827BE5139EC5F3DE4E072913F6473C7278E691D6C58D407A" + + "23DB3176383E8429AA558418EE33CB7DFFD2CF251EEC93B6CFC300D0D9679CE5" + + "42"; + + const string DetachedDefiniteHex = + "D28445A201260280A0F658409B0EBC937A969A7D4BB2AA0B1004091EDAA00AE2" + + "BBCCBB994B7278C9E50C6C734B3A53CB5B87A99E75F63D16B73757CA23C99CF0" + + "8F8F909A1332DAC05D9DB1C0"; + + const string DetachedIndefiniteHex = + "D28446A20126029FFFA0F65840CA96F1292FEE2B787DC75D91553024E70DD62B" + + "EA0BFE284024385C6D9493EEF6F055825E79244B63E76F69A419C3A36B3B1F18" + + "34789A23983D685B7CDA231E86"; + + string inputHex = (detached, useIndefiniteLength) switch + { + (false, false) => AttachedDefiniteHex, + (false, true) => AttachedIndefiniteHex, + (true, false) => DetachedDefiniteHex, + (true, true) => DetachedIndefiniteHex, + }; + + AssertExtensions.ThrowsContains( + () => CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(inputHex)), + "Critical Headers must be a CBOR array of at least one element."); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(false, true)] + public void DecodeSign1ThrowsIfCriticalHeaderIsOfUnknownType(bool detached, bool useIndefiniteLength) + { + const string AttachedDefiniteHex = + "D28447A201260281412AA054546869732069732074686520636F6E74656E742E" + + "58403529AC69F69A80B4055CFFCA88F010390509E0A9D4D0083F23DF46841144" + + "B7E9D7CC11E90D0D51103672083449B439B71EAF6B922C011CC471D8E1D577C6" + + "B954"; + + const string AttachedIndefiniteHex = + "D28448A20126029F412AFFA054546869732069732074686520636F6E74656E74" + + "2E5840FE8A2CBBBA2A154361BEF0892D11FF621A1DBDCBD1A955020DD7D85ED8" + + "15C43B3AB39A32561AAEF679D08FD561339AC9A4E537B2E91DC120A32F406455" + + "F3353F"; + + const string DetachedDefiniteHex = + "D28447A201260281412AA0F65840AB87DA5ABA5A470C7508F5F1724744458407" + + "897746890428F877AD593F9D90E5503A6D1B3369AF77952223D5C474CBB8EC62" + + "9726F967921A4AB91DC8F86DA1CF"; + + const string DetachedIndefiniteHex = + "D28448A20126029F412AFFA0F658409613065203B619BE9CEC1CC596F59C7395" + + "5AEE8BD492F16B72D2C0F443AE70E5E5B1D615A06A90145078B41A1CA12D4067" + + "D6C6CEEB2C19B3747A0926305EBA09"; + + string inputHex = (detached, useIndefiniteLength) switch + { + (false, false) => AttachedDefiniteHex, + (false, true) => AttachedIndefiniteHex, + (true, false) => DetachedDefiniteHex, + (true, true) => DetachedIndefiniteHex, + }; + + AssertExtensions.ThrowsContains( + () => CoseMessage.DecodeSign1(ByteUtils.HexToByteArray(inputHex)), + "Header '2' does not accept the specified value."); + } } } diff --git a/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.Sign.CustomHeaderMaps.cs b/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.Sign.CustomHeaderMaps.cs index e7e3fe1ca782b3..af02047626165c 100644 --- a/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.Sign.CustomHeaderMaps.cs +++ b/src/libraries/System.Security.Cryptography.Cose/tests/CoseMessageTests.Sign.CustomHeaderMaps.cs @@ -517,12 +517,14 @@ public void SignWithCborNegativeIntegerRepresentationAlgorithmHeaderValue(ulong Assert.Throws(() => Sign(s_sampleContent, DefaultKey, DefaultHash, protectedHeaders)); } - [Fact] - public void SignWithCriticalHeaders() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void SignWithCriticalHeaders(bool useIndefiniteLength) { CoseHeaderMap protectedHeaders = GetHeaderMapWithAlgorithm(DefaultAlgorithm); List<(CoseHeaderLabel, ReadOnlyMemory)> expectedProtectedHeaders = GetExpectedProtectedHeaders(DefaultAlgorithm); - AddCriticalHeaders(protectedHeaders, expectedProtectedHeaders, includeSpecifiedCritHeader: true); + AddCriticalHeaders(protectedHeaders, expectedProtectedHeaders, includeSpecifiedCritHeader: true, useIndefiniteLength); CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash, protectedHeaders); ReadOnlySpan encodedMessage = Sign(s_sampleContent, signer); @@ -530,18 +532,22 @@ public void SignWithCriticalHeaders() AssertCoseSignMessage(encodedMessage, s_sampleContent, DefaultKey, DefaultAlgorithm, expectedProtectedHeaders); } - [Fact] - public void SignWithCriticalHeaders_NotTransportingTheSpecifiedCriticalHeaderThrows() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void SignWithCriticalHeaders_NotTransportingTheSpecifiedCriticalHeaderThrows(bool useIndefiniteLength) { CoseHeaderMap protectedHeaders = GetHeaderMapWithAlgorithm(DefaultAlgorithm); - AddCriticalHeaders(protectedHeaders, null, includeSpecifiedCritHeader: false); + AddCriticalHeaders(protectedHeaders, null, includeSpecifiedCritHeader: false, useIndefiniteLength); CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash, protectedHeaders); Assert.Throws("signer", () => Sign(s_sampleContent, signer)); } - [Fact] - public void MultiSign_SignWithCriticalHeaders_BodyHeaders() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void MultiSign_SignWithCriticalHeaders_BodyHeaders(bool useIndefiniteLength) { if (MessageKind != CoseMessageKind.MultiSign) { @@ -550,7 +556,7 @@ public void MultiSign_SignWithCriticalHeaders_BodyHeaders() CoseHeaderMap bodyProtectedHeaders = GetEmptyHeaderMap(); List<(CoseHeaderLabel, ReadOnlyMemory)> expectedBodyProtected = GetEmptyExpectedHeaders(); - AddCriticalHeaders(bodyProtectedHeaders, expectedBodyProtected, includeSpecifiedCritHeader: true); + AddCriticalHeaders(bodyProtectedHeaders, expectedBodyProtected, includeSpecifiedCritHeader: true, useIndefiniteLength); CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash); ReadOnlySpan encodedMessage = Sign(s_sampleContent, signer, bodyProtectedHeaders); @@ -558,8 +564,10 @@ public void MultiSign_SignWithCriticalHeaders_BodyHeaders() AssertCoseSignMessage(encodedMessage, s_sampleContent, DefaultKey, DefaultAlgorithm, expectedMultiSignBodyProtectedHeaders: expectedBodyProtected); } - [Fact] - public void MultiSign_SignWithCriticalHeaders_NotTransportingTheSpecifiedCriticalHeaderThrows_BodyHeaders() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void MultiSign_SignWithCriticalHeaders_NotTransportingTheSpecifiedCriticalHeaderThrows_BodyHeaders(bool useIndefiniteLength) { if (MessageKind != CoseMessageKind.MultiSign) { @@ -567,14 +575,16 @@ public void MultiSign_SignWithCriticalHeaders_NotTransportingTheSpecifiedCritica } CoseHeaderMap bodyProtectedHeaders = GetEmptyHeaderMap(); - AddCriticalHeaders(bodyProtectedHeaders, null, includeSpecifiedCritHeader: false); + AddCriticalHeaders(bodyProtectedHeaders, null, includeSpecifiedCritHeader: false, useIndefiniteLength); CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash); Assert.Throws("protectedHeaders", () => Sign(s_sampleContent, signer, bodyProtectedHeaders)); } - [Fact] - public void MultiSign_SignWithCriticalHeaders_AddSignature() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void MultiSign_SignWithCriticalHeaders_AddSignature(bool useIndefiniteLength) { if (MessageKind != CoseMessageKind.MultiSign) { @@ -588,7 +598,7 @@ public void MultiSign_SignWithCriticalHeaders_AddSignature() CoseHeaderMap signProtectedHeaders = GetHeaderMapWithAlgorithm(DefaultAlgorithm); List<(CoseHeaderLabel, ReadOnlyMemory)> expectedSignProtected = GetExpectedProtectedHeaders(DefaultAlgorithm); - AddCriticalHeaders(signProtectedHeaders, expectedSignProtected, includeSpecifiedCritHeader: true); + AddCriticalHeaders(signProtectedHeaders, expectedSignProtected, includeSpecifiedCritHeader: true, useIndefiniteLength); CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash, signProtectedHeaders); AddSignature(multiSignMsg, s_sampleContent, signer); @@ -596,8 +606,10 @@ public void MultiSign_SignWithCriticalHeaders_AddSignature() AssertCoseSignMessage(multiSignMsg.Encode(), s_sampleContent, DefaultKey, DefaultAlgorithm, expectedProtectedHeaders: expectedSignProtected); } - [Fact] - public void MultiSign_SignWithCriticalHeaders_NotTransportingTheSpecifiedCriticalHeaderThrows_AddSignature() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void MultiSign_SignWithCriticalHeaders_NotTransportingTheSpecifiedCriticalHeaderThrows_AddSignature(bool useIndefiniteLength) { if (MessageKind != CoseMessageKind.MultiSign) { @@ -610,18 +622,21 @@ public void MultiSign_SignWithCriticalHeaders_NotTransportingTheSpecifiedCritica multiSignMsg.RemoveSignature(0); CoseHeaderMap signProtectedHeaders = GetHeaderMapWithAlgorithm(DefaultAlgorithm); - AddCriticalHeaders(signProtectedHeaders, null, includeSpecifiedCritHeader: false); + AddCriticalHeaders(signProtectedHeaders, null, includeSpecifiedCritHeader: false, useIndefiniteLength); CoseSigner signer = GetCoseSigner(DefaultKey, DefaultHash, signProtectedHeaders); Assert.Throws("signer", () => AddSignature(multiSignMsg, s_sampleContent, signer)); } private static void AddCriticalHeaders( - CoseHeaderMap protectedHeaders, List<(CoseHeaderLabel, ReadOnlyMemory)>? expectedHeaders, bool includeSpecifiedCritHeader) + CoseHeaderMap protectedHeaders, + List<(CoseHeaderLabel, ReadOnlyMemory)>? expectedHeaders, + bool includeSpecifiedCritHeader, + bool useIndefiniteLength) { Assert.Equal(expectedHeaders != null, includeSpecifiedCritHeader); - CoseHeaderValue critValue = CoseHeaderValue.FromEncodedValue(GetDummyCritHeaderValue()); + CoseHeaderValue critValue = CoseHeaderValue.FromEncodedValue(GetDummyCritHeaderValue(useIndefiniteLength)); protectedHeaders[CoseHeaderLabel.CriticalHeaders] = critValue; expectedHeaders?.Add((CoseHeaderLabel.CriticalHeaders, critValue.EncodedValue));