diff --git a/.github/instructions/ado-pipelines.instructions.md b/.github/instructions/ado-pipelines.instructions.md
index 7e0d02e4e2..3e5a66af78 100644
--- a/.github/instructions/ado-pipelines.instructions.md
+++ b/.github/instructions/ado-pipelines.instructions.md
@@ -22,7 +22,7 @@ Top-level CI/PR pipeline files:
- `dotnet-sqlclient-ci-project-reference-pipeline.yml` — CI with Project references (Release)
- `sqlclient-pr-package-ref-pipeline.yml` — PR validation with Package references
- `sqlclient-pr-project-ref-pipeline.yml` — PR validation with Project references
-- `stress/stress-tests-pipeline.yml` — Stress test pipeline and templates
+- `ci/stress/sqlclient-ci-stress-pipeline.yml` — Stress test pipeline and templates
Reusable templates are organized under:
- `common/templates/jobs/` — Job templates (`ci-build-nugets-job`, `ci-code-coverage-job`, `ci-run-tests-job`)
@@ -63,7 +63,7 @@ Stages execute in dependency order (Package reference mode requires artifacts fr
7. `verify_nuget_packages_stage` — Verify NuGet package metadata
8. `ci_run_tests_stage` — Run MDS and AKV test suites
-Stress testing is no longer a stage threaded through `dotnet-sqlclient-ci-core.yml`; it lives under `eng/pipelines/stress/` as a separate pipeline flow.
+Stress testing is no longer a stage threaded through `dotnet-sqlclient-ci-core.yml`; it lives under `eng/pipelines/ci/stress/` as a separate pipeline flow.
When adding a new build stage, respect the dependency graph and pass artifact names/versions to downstream stages.
diff --git a/.github/prompts/update-build-pipelines.prompt.md b/.github/prompts/update-build-pipelines.prompt.md
index 63c87ea9c3..a652c9f82f 100644
--- a/.github/prompts/update-build-pipelines.prompt.md
+++ b/.github/prompts/update-build-pipelines.prompt.md
@@ -22,7 +22,7 @@ Follow this workflow step-by-step:
- `sqlclient-pr-package-ref-pipeline.yml` — PR validation (package references)
- `onebranch/sqlclient-official.yml` — official OneBranch build/release pipeline
- `onebranch/sqlclient-non-official.yml` — non-official OneBranch build/release pipeline
- - `stress/stress-tests-pipeline.yml` — stress test pipeline
+ - `ci/stress/sqlclient-ci-stress-pipeline.yml` — stress test pipeline
- Shared templates live in `eng/pipelines/common/templates/` (jobs/, stages/, steps/).
- CI variables are defined in `eng/pipelines/libraries/`; OneBranch variables are defined in `eng/pipelines/onebranch/variables/`.
@@ -57,7 +57,7 @@ Follow this workflow step-by-step:
- Test filters by platform: `nonnetfxtests`, `nonnetcoreapptests`, `nonwindowstests`, `nonlinuxtests`.
- SNI testing matrix: both Native (`useManagedSNI=false`) and Managed (`useManagedSNI=true`).
- Always Encrypted tests controlled by `runAlwaysEncryptedTests` parameter.
-- Stress coverage is maintained under `eng/pipelines/stress/`, not as a stage inside `dotnet-sqlclient-ci-core.yml`.
+- Stress coverage is maintained under `eng/pipelines/ci/stress/`, not as a stage inside `dotnet-sqlclient-ci-core.yml`.
## 5. Validate
- Verify YAML syntax is valid.
diff --git a/eng/pipelines/stress/stress-tests-job.yml b/eng/pipelines/ci/stress/sqlclient-ci-stress-job.yml
similarity index 64%
rename from eng/pipelines/stress/stress-tests-job.yml
rename to eng/pipelines/ci/stress/sqlclient-ci-stress-job.yml
index dd75602d6f..f4d730c05b 100644
--- a/eng/pipelines/stress/stress-tests-job.yml
+++ b/eng/pipelines/ci/stress/sqlclient-ci-stress-job.yml
@@ -3,7 +3,10 @@
# file to you under the MIT license. See the LICENSE file in the project root for more information.
####################################################################################################
-# This job builds and runs stress tests by compiling the SqlClient projects transitively.
+# This job builds and runs stress tests against the SqlClient NuGet packages produced by the
+# sqlclient-ci-package pipeline. The package artifacts are downloaded into the local NuGet feed
+# (packages/) and the stress test projects are built in "Package" mode (ReferenceType=Package)
+# against the exact package versions produced by that pipeline.
#
# The stress tests are located here:
#
@@ -59,10 +62,6 @@ parameters:
- name: netTestRuntimes
type: object
- # The name of the Azure Pipelines pool to use.
- - name: poolName
- type: string
-
# The local SQL Server instance's 'sa' password, for use in the config file.
- name: saPassword
type: string
@@ -72,23 +71,26 @@ parameters:
- name: sqlSetupStep
type: step
- # The pool VM image to use.
+ # The pool VM image to use. Both the internal (ADO-1ES-Pool) and public (ADO-CI-1ES-Pool) pools
+ # must provide an image with this name.
+ #
+ # NOTE: This value is evaluated at template-expansion (compile) time to select the pool, so it
+ # must be a literal and must not contain any runtime expressions (e.g. $(...) macros or
+ # $[...] runtime expressions).
- name: vmImage
type: string
jobs:
- job: stress_tests_job_${{ parameters.jobNameSuffix }}
displayName: '[${{ parameters.displayNamePrefix }}] Run Stress Tests'
- pool:
- name: ${{ parameters.poolName }}
- ${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
- vmImage: ${{ parameters.vmImage }}
- ${{ else }}:
- demands:
- - imageOverride -equals ${{ parameters.vmImage }}
variables:
+ # Whether this is an internal (ADO.Net project) or public (Public project) build. Evaluated
+ # at compile time so it can drive template expressions below.
+ - name: isInternalBuild
+ value: ${{ eq(variables['System.TeamProject'], 'ADO.Net') }}
+
# Import the variable group that provides SQL Server build properties used by the
# shared configure-sql-server-*-step.yml templates (e.g. x64AliasRegistryPath,
# x86AliasRegistryPath, SQLAliasName, SQLAliasPort).
@@ -97,6 +99,11 @@ jobs:
# Import the variable group that provides SQL Server test configuration variables.
- group: ADO Test Configuration Properties
+ # The directory where the "- download:" step places the SqlClient-Driver-Packages artifact
+ # published by the triggering sqlclient-ci-package pipeline.
+ - name: packageArtifactDir
+ value: $(Pipeline.Workspace)/sqlclient-ci-package/SqlClient-Driver-Packages
+
# The top-level project file to build and run.
- name: project
value: $(Build.SourcesDirectory)/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj
@@ -128,11 +135,22 @@ jobs:
# bypassing the "--" separator. This causes app arguments to contain SDK options and triggers
# unintended behavior.
+ # Reference-mode arguments shared by build and run. The stress tests are built in "Package"
+ # mode against the SqlClient packages downloaded from the sqlclient-ci-package pipeline. The
+ # exact versions are resolved at runtime from the downloaded .nupkg filenames (see the
+ # "Stage Packages and Resolve Versions" step).
+ - name: referenceArgs
+ value: >-
+ -p:ReferenceType=Package
+ -p:SqlClientPackageVersion=$(mdsPackageVersion)
+ -p:AzurePackageVersion=$(azurePackageVersion)
+
# dotnet CLI options for build.
- name: dotnetBuildOpts
value: >-
--verbosity ${{ parameters.dotnetVerbosity }}
-p:Configuration=${{ parameters.buildConfiguration }}
+ $(referenceArgs)
# dotnet run options shared by all test steps (framework is appended per-step).
- name: dotnetRunOpts
@@ -140,11 +158,27 @@ jobs:
--no-build
--verbosity ${{ parameters.dotnetVerbosity }}
--configuration ${{ parameters.buildConfiguration }}
+ $(referenceArgs)
# Stress test options passed after the "--" separator.
- name: stressTestOpts
value: --assembly SqlClient.Stress.Tests --console
+ # Select the pool based on the requested image:
+ # - macOS images run on the Microsoft-hosted 'Azure Pipelines' pool (no 1ES macOS images).
+ # - All other images run on the 1ES pool for the current ADO project, matched via imageOverride.
+ pool:
+ ${{ if startsWith(parameters.vmImage, 'macos') }}:
+ name: 'Azure Pipelines'
+ vmImage: ${{ parameters.vmImage }}
+ ${{ else }}:
+ ${{ if eq(variables.isInternalBuild, true) }}:
+ name: ADO-1ES-Pool
+ ${{ else }}:
+ name: ADO-CI-1ES-Pool
+ demands:
+ - imageOverride -equals ${{ parameters.vmImage }}
+
steps:
# Install the .NET SDK and Runtimes.
@@ -170,9 +204,47 @@ jobs:
# Write the JSON content to the config file.
$content | Out-File -FilePath "config.jsonc"
+ # Download the SqlClient driver packages published by the triggering sqlclient-ci-package
+ # pipeline into the pipeline workspace.
+ - download: sqlclient-ci-package
+ artifact: SqlClient-Driver-Packages
+ displayName: Download SqlClient Driver Packages
+
+ # Copy the downloaded packages into the local NuGet feed (packages/) and resolve the exact
+ # Microsoft.Data.SqlClient and Microsoft.Data.SqlClient.Extensions.Azure versions from the
+ # .nupkg filenames. These versions are passed to the build via the referenceArgs variable.
+ - task: PowerShell@2
+ displayName: Stage Packages and Resolve Versions
+ inputs:
+ pwsh: true
+ targetType: inline
+ script: |
+ $ErrorActionPreference = 'Stop'
+ $feed = "$(Build.SourcesDirectory)/packages"
+ New-Item -ItemType Directory -Force -Path $feed | Out-Null
+
+ Copy-Item "$(packageArtifactDir)/*.nupkg" $feed -Force
+ Copy-Item "$(packageArtifactDir)/*.snupkg" $feed -Force -ErrorAction SilentlyContinue
+
+ $mdsPattern = '^Microsoft\.Data\.SqlClient\.(\d[^\\/]*)\.nupkg$'
+ $azurePattern = '^Microsoft\.Data\.SqlClient\.Extensions\.Azure\.(\d[^\\/]*)\.nupkg$'
+
+ $mds = Get-ChildItem "$feed/*.nupkg" | Where-Object { $_.Name -match $mdsPattern } | Select-Object -First 1
+ $azure = Get-ChildItem "$feed/*.nupkg" | Where-Object { $_.Name -match $azurePattern } | Select-Object -First 1
+
+ if (-not $mds) { throw "Microsoft.Data.SqlClient package not found in $feed" }
+ if (-not $azure) { throw "Microsoft.Data.SqlClient.Extensions.Azure package not found in $feed" }
+
+ $mdsVersion = [regex]::Match($mds.Name, $mdsPattern).Groups[1].Value
+ $azureVersion = [regex]::Match($azure.Name, $azurePattern).Groups[1].Value
+
+ Write-Host "Resolved Microsoft.Data.SqlClient version: $mdsVersion"
+ Write-Host "Resolved Microsoft.Data.SqlClient.Extensions.Azure version: $azureVersion"
+ Write-Host "##vso[task.setvariable variable=mdsPackageVersion]$mdsVersion"
+ Write-Host "##vso[task.setvariable variable=azurePackageVersion]$azureVersion"
+
# Authenticate with NuGet feeds so that upstream packages (e.g. runtime host packs) can be
- # fetched through the ADO Artifacts feed. This is required on hosted pool agents (macOS)
- # that do not have pre-configured feed credentials.
+ # fetched through the ADO Artifacts feed.
- task: NuGetAuthenticate@1
displayName: Authenticate NuGet feeds
diff --git a/eng/pipelines/stress/stress-tests-pipeline.yml b/eng/pipelines/ci/stress/sqlclient-ci-stress-pipeline.yml
similarity index 59%
rename from eng/pipelines/stress/stress-tests-pipeline.yml
rename to eng/pipelines/ci/stress/sqlclient-ci-stress-pipeline.yml
index c1eb87faab..74283a8128 100644
--- a/eng/pipelines/stress/stress-tests-pipeline.yml
+++ b/eng/pipelines/ci/stress/sqlclient-ci-stress-pipeline.yml
@@ -4,17 +4,15 @@
####################################################################################################
# This pipeline runs the stress test suite against the SqlClient projects, building them
-# transitively as necessary, triggered by successful runs of the following pipelines:
+# transitively as necessary, triggered by successful runs of the sqlclient-ci-package pipeline:
#
# Public project:
-# Triggering pipelines: PR-SqlClient-Project, CI-SqlClient (branch main only)
-# Pipeline name: sqlclient-stress
-# Pipeline URL: https://sqlclientdrivers.visualstudio.com/public/_build?definitionId=2250
+# Triggering pipeline: sqlclient-ci-package
+# Pipeline name: sqlclient-ci-stress
#
# ADO.Net project:
-# Triggering pipeline: MDS Main CI (branch internal/main only)
-# Pipeline name: sqlclient-stress
-# Pipeline URL: https://dev.azure.com/SqlClientDrivers/ADO.Net/_build?definitionId=2284
+# Triggering pipeline: sqlclient-ci-package
+# Pipeline name: sqlclient-ci-stress
# Set the pipeline run name to the day-of-year and the daily run counter.
name: $(DayOfYear)$(Rev:rr)
@@ -23,7 +21,7 @@ name: $(DayOfYear)$(Rev:rr)
pr: none
trigger: none
-# Trigger this pipeline after successful runs of the desired pipelines.
+# Trigger this pipeline after successful runs of the sqlclient-ci-package pipeline.
#
# The pipeline identifiers are displayed in the Azure DevOps UI, so it is helpful if they indicate
# the project, folder, and pipeline name, hence the verbose values below.
@@ -31,30 +29,23 @@ trigger: none
resources:
pipelines:
- # The PR-SqlClient-Project pipeline in the Public project.
- - pipeline: Public-ADO-PR-SqlClient-Project
- project: Public
- source: /ADO/PR-SqlClient-Project
+ # Trigger this pipeline when the sqlclient-ci-package pipeline completes successfully.
+ #
+ # 'project' is omitted so the resource resolves to the sqlclient-ci-package pipeline in the
+ # *current* ADO project. This scopes the trigger per project automatically: the Public
+ # registration is triggered only by Public's sqlclient-ci-package, and the ADO.Net registration
+ # only by ADO.Net's.
+ #
+ # IMPORTANT: 'source' is the bare pipeline name with no folder path. This REQUIRES the
+ # sqlclient-ci-package name to be UNIQUE within BOTH the Public and ADO.Net projects. Azure
+ # DevOps only allows omitting the folder when the name is unambiguous; if a second pipeline with
+ # this name is ever added to either project, this resource will fail to resolve and the folder
+ # path must be added back (which, because the folders differ per project, would then require a
+ # per-project approach instead of this single shared definition).
+ - pipeline: sqlclient-ci-package
+ source: sqlclient-ci-package
trigger: true
- # The CI-SqlClient pipeline in the Public project.
- - pipeline: Public-ADO-CI-SqlClient
- project: Public
- source: /ADO/CI-SqlClient
- trigger:
- branches:
- include:
- - main
-
- # The MDS Main CI pipeline in the ADO.Net project.
- - pipeline: ADO-Net-Internal-CI-MDS-Main-CI
- project: ADO.Net
- source: /CI/MDS Main CI
- trigger:
- branches:
- include:
- - internal/main
-
# Pipeline parameters, visible in the Azure DevOps UI.
parameters:
@@ -92,17 +83,6 @@ parameters:
- detailed
- diagnostic
-# Pipeline-level variables evaluated at compile time.
-variables:
- # The 1ES pool name, determined automatically by ADO project:
- # - ADO.Net -> ADO-1ES-Pool
- # - public -> ADO-CI-1ES-Pool
- - name: poolName
- ${{ if eq(variables['System.TeamProject'], 'ADO.Net') }}:
- value: ADO-1ES-Pool
- ${{ else }}:
- value: ADO-CI-1ES-Pool
-
# The stages to run.
stages:
@@ -112,10 +92,9 @@ stages:
debug: ${{ parameters.debug }}
# Run the stress tests.
- - template: /eng/pipelines/stress/stress-tests-stage.yml@self
+ - template: /eng/pipelines/ci/stress/sqlclient-ci-stress-stage.yml@self
parameters:
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
- poolName: ${{ variables.poolName }}
warnOnTestFailure: ${{ parameters.warnOnTestFailure }}
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
diff --git a/eng/pipelines/stress/stress-tests-stage.yml b/eng/pipelines/ci/stress/sqlclient-ci-stress-stage.yml
similarity index 89%
rename from eng/pipelines/stress/stress-tests-stage.yml
rename to eng/pipelines/ci/stress/sqlclient-ci-stress-stage.yml
index 1f223c5142..689d1a702b 100644
--- a/eng/pipelines/stress/stress-tests-stage.yml
+++ b/eng/pipelines/ci/stress/sqlclient-ci-stress-stage.yml
@@ -57,10 +57,6 @@ parameters:
type: object
default: [net8.0, net9.0, net10.0]
- # The 1ES pool name for Linux and Windows jobs. macOS always uses 'Azure Pipelines'.
- - name: poolName
- type: string
-
stages:
- stage: stress_tests_stage
displayName: Run Stress Tests
@@ -77,7 +73,7 @@ stages:
# ----------------------------------------------------------------------------------------------
# Build and test on Linux.
- - template: /eng/pipelines/stress/stress-tests-job.yml@self
+ - template: /eng/pipelines/ci/stress/sqlclient-ci-stress-job.yml@self
parameters:
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
@@ -88,7 +84,6 @@ stages:
# No .NET Framework runtimes on Linux.
netFrameworkTestRuntimes: []
netTestRuntimes: ${{ parameters.netTestRuntimes }}
- poolName: ${{ parameters.poolName }}
saPassword: $(saPassword)
sqlSetupStep:
template: /eng/pipelines/common/templates/steps/configure-sql-server-linux-step.yml@self
@@ -99,7 +94,7 @@ stages:
# ----------------------------------------------------------------------------------------------
# Build and test on Windows
- - template: /eng/pipelines/stress/stress-tests-job.yml@self
+ - template: /eng/pipelines/ci/stress/sqlclient-ci-stress-job.yml@self
parameters:
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
@@ -110,7 +105,6 @@ stages:
# Note that we include the .NET Framework runtimes for test runs on Windows.
netFrameworkTestRuntimes: ${{ parameters.netFrameworkTestRuntimes }}
netTestRuntimes: ${{ parameters.netTestRuntimes }}
- poolName: ${{ parameters.poolName }}
saPassword: $(saPassword)
sqlSetupStep:
template: /eng/pipelines/common/templates/steps/configure-sql-server-win-step.yml@self
@@ -123,7 +117,7 @@ stages:
# ----------------------------------------------------------------------------------------------
# Build and test on macOS.
- - template: /eng/pipelines/stress/stress-tests-job.yml@self
+ - template: /eng/pipelines/ci/stress/sqlclient-ci-stress-job.yml@self
parameters:
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
@@ -134,12 +128,10 @@ stages:
# No .NET Framework runtimes on macOS.
netFrameworkTestRuntimes: []
netTestRuntimes: ${{ parameters.netTestRuntimes }}
- # We don't have any 1ES Hosted Pool images for macOS, so we use a generic one from Azure
- # Pipelines.
- poolName: Azure Pipelines
saPassword: $(saPassword)
sqlSetupStep:
template: /eng/pipelines/common/templates/steps/configure-sql-server-macos-step.yml@self
parameters:
saPassword: $(saPassword)
+ # A macOS vmImage name routes this job to the Microsoft-hosted 'Azure Pipelines' pool.
vmImage: macos-latest
diff --git a/eng/pipelines/sqlclient-pr-package-ref-pipeline.yml b/eng/pipelines/sqlclient-pr-package-ref-pipeline.yml
index 70a37e0fa7..695145e990 100644
--- a/eng/pipelines/sqlclient-pr-package-ref-pipeline.yml
+++ b/eng/pipelines/sqlclient-pr-package-ref-pipeline.yml
@@ -54,7 +54,6 @@ pr:
- eng/pipelines/ci/*
- eng/pipelines/kerberos/*
- eng/pipelines/onebranch/*
- - eng/pipelines/stress/*
# Do not trigger commit or schedule runs for this pipeline.
trigger: none
diff --git a/eng/pipelines/sqlclient-pr-project-ref-pipeline.yml b/eng/pipelines/sqlclient-pr-project-ref-pipeline.yml
index f777626c90..14c1af4e7f 100644
--- a/eng/pipelines/sqlclient-pr-project-ref-pipeline.yml
+++ b/eng/pipelines/sqlclient-pr-project-ref-pipeline.yml
@@ -54,7 +54,6 @@ pr:
- eng/pipelines/ci/*
- eng/pipelines/kerberos/*
- eng/pipelines/onebranch/*
- - eng/pipelines/stress/*
# Do not trigger commit or schedule runs for this pipeline.
trigger: none
diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props b/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props
index addc60556f..4c180661aa 100644
--- a/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props
+++ b/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props
@@ -7,10 +7,22 @@
true
true
+
+
+
+ Project
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/SqlClient.Stress.Framework.csproj b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/SqlClient.Stress.Framework.csproj
index 6feb8f34d4..e02f3e79d2 100644
--- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/SqlClient.Stress.Framework.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/SqlClient.Stress.Framework.csproj
@@ -5,8 +5,19 @@
-
-
+
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj
index 8a2bc08b4c..d6e81b457c 100644
--- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj
@@ -10,7 +10,13 @@
-
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClient.Stress.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClient.Stress.Tests.csproj
index 90cdaf6e2b..15eb436add 100644
--- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClient.Stress.Tests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClient.Stress.Tests.csproj
@@ -5,7 +5,13 @@
-
+
+
+
+
+