Skip to content

Commit f3e34e6

Browse files
gargsaumyaCopilot
andauthored
FIX: Remove credential exposure from CI/CD pipelines (#715)
### Work Item / Issue Reference <!-- IMPORTANT: Please follow the PR template guidelines below. For mssql-python maintainers: Insert your ADO Work Item ID below For external contributors: Insert Github Issue number below Only one reference is required - either GitHub issue OR ADO Work Item. --> <!-- mssql-python maintainers: ADO Work Item --> > [AB#46465](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/46465) <!-- External contributors: GitHub Issue --> > GitHub Issue: #<ISSUE_NUMBER> ------------------------------------------------------------------- ### Summary <!-- Insert your summary of changes below. Minimum 10 characters required. --> This pull request improves the handling of sensitive credentials and environment variables for SQL Server setup and testing across development scripts and CI pipelines. The changes enhance security by avoiding plaintext password exposure, standardize environment variable usage, and make scripts more robust and portable. Temporary credential files now use owner-only permissions, unique names where applicable, termination-safe cleanup, and fail-closed deletion. SQL Server setup configuration paths are quoted so temporary directories containing spaces remain supported. **Credential Management and Security Improvements:** * In `.devcontainer/post-create.sh`, SQL Server passwords are now written to a secure temporary environment file (`umask 077`), and the credentials are kept in a user-only file (`~/.mssql_python_env`). The script also removes plaintext credentials from `/etc/environment` and shell RC files, and ensures credentials are sourced securely in new shell sessions. [[1]](diffhunk://#diff-bcf66a848607b49d2a45edfad434f6808017ee9d18f5a20dde6670745010d89aR54-R58) [[2]](diffhunk://#diff-bcf66a848607b49d2a45edfad434f6808017ee9d18f5a20dde6670745010d89aL88-R102) * Docker containers for SQL Server in CI pipelines now receive passwords via environment variables (`MSSQL_SA_PASSWORD`, `SQLCMDPASSWORD`) instead of command-line arguments, reducing the risk of leaking secrets in process lists or logs. [[1]](diffhunk://#diff-3be0faed094a0cc74e9ec006d00e54b2f4178571f1f7eb13de87467df606f86aL202-R215) [[2]](diffhunk://#diff-3be0faed094a0cc74e9ec006d00e54b2f4178571f1f7eb13de87467df606f86aR229-R230) [[3]](diffhunk://#diff-0dd29b7d361d605955e0542e840b8f59473bb2f9b623712bf8b3bc5da865ddc6L168-R183) [[4]](diffhunk://#diff-09b6212130ccaeeb948dc695662528e4480836a4d8dc18f56b1d946060746c5bL260-R277) **Pipeline and Script Robustness:** * Shell scripts in CI pipelines (`build-linux-single-stage.yml`, `stress-test-pipeline.yml`) have been updated to use stricter error handling (`set -euo pipefail`) for improved reliability and easier debugging. [[1]](diffhunk://#diff-3be0faed094a0cc74e9ec006d00e54b2f4178571f1f7eb13de87467df606f86aL139-R139) [[2]](diffhunk://#diff-3be0faed094a0cc74e9ec006d00e54b2f4178571f1f7eb13de87467df606f86aL173-R173) [[3]](diffhunk://#diff-3be0faed094a0cc74e9ec006d00e54b2f4178571f1f7eb13de87467df606f86aL184-R184) [[4]](diffhunk://#diff-3be0faed094a0cc74e9ec006d00e54b2f4178571f1f7eb13de87467df606f86aL259-R261) [[5]](diffhunk://#diff-3be0faed094a0cc74e9ec006d00e54b2f4178571f1f7eb13de87467df606f86aL272-R275) [[6]](diffhunk://#diff-3be0faed094a0cc74e9ec006d00e54b2f4178571f1f7eb13de87467df606f86aL340-R343) [[7]](diffhunk://#diff-3be0faed094a0cc74e9ec006d00e54b2f4178571f1f7eb13de87467df606f86aL421-R423) [[8]](diffhunk://#diff-09b6212130ccaeeb948dc695662528e4480836a4d8dc18f56b1d946060746c5bL260-R277) **Cross-Platform and Pipeline Consistency:** * Windows and Linux pipelines now consistently use environment variables for passing sensitive information to SQL Server and `sqlcmd`, including for database and user creation. This includes changes to how PowerShell scripts interpolate passwords, and how SQL Server is installed/configured on Windows using a secure configuration file. [[1]](diffhunk://#diff-b134d9c8339176b133043f7c9407b630a17f96f764c7b88106599f4b27a26d85L172-R172) [[2]](diffhunk://#diff-09b6212130ccaeeb948dc695662528e4480836a4d8dc18f56b1d946060746c5bL106-R106) [[3]](diffhunk://#diff-09b6212130ccaeeb948dc695662528e4480836a4d8dc18f56b1d946060746c5bL116-R116) [[4]](diffhunk://#diff-09b6212130ccaeeb948dc695662528e4480836a4d8dc18f56b1d946060746c5bR157-R171) [[5]](diffhunk://#diff-09b6212130ccaeeb948dc695662528e4480836a4d8dc18f56b1d946060746c5bL282-R300) [[6]](diffhunk://#diff-296c8f902bbd70f34ee1c8c32383c8c99165fe4c8e5b0f234f8f22246e56a621L88-R88) [[7]](diffhunk://#diff-296c8f902bbd70f34ee1c8c32383c8c99165fe4c8e5b0f234f8f22246e56a621L115-R135) [[8]](diffhunk://#diff-296c8f902bbd70f34ee1c8c32383c8c99165fe4c8e5b0f234f8f22246e56a621R149) [[9]](diffhunk://#diff-296c8f902bbd70f34ee1c8c32383c8c99165fe4c8e5b0f234f8f22246e56a621L137-R158) **Backward Compatibility and Cleanup:** * The devcontainer script now removes legacy plaintext password files and entries, ensuring no old credentials are left behind after upgrades. These changes collectively make the development and CI environments more secure and maintainable by standardizing credential handling and improving script reliability. <!-- ### PR Title Guide > For feature requests FEAT: (short-description) > For non-feature requests like test case updates, config updates , dependency updates etc CHORE: (short-description) > For Fix requests FIX: (short-description) > For doc update requests DOC: (short-description) > For Formatting, indentation, or styling update STYLE: (short-description) > For Refactor, without any feature changes REFACTOR: (short-description) > For performance improvements PERF: (short-description) > For release related changes, without any feature changes RELEASE: #<RELEASE_VERSION> (short-description) ### Contribution Guidelines External contributors: - Create a GitHub issue first: https://github.com/microsoft/mssql-python/issues/new - Link the GitHub issue in the "GitHub Issue" section above - Follow the PR title format and provide a meaningful summary mssql-python maintainers: - Create an ADO Work Item following internal processes - Link the ADO Work Item in the "ADO Work Item" section above - Follow the PR title format and provide a meaningful summary --> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: gargsaumya <192222169+gargsaumya@users.noreply.github.com>
1 parent c963ee1 commit f3e34e6

6 files changed

Lines changed: 243 additions & 80 deletions

File tree

‎.devcontainer/post-create.sh‎

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,14 @@ fi
5252
echo ""
5353
echo "Generating SQL Server password..."
5454
SA_PASSWORD="$(openssl rand -base64 16 | tr -dc 'A-Za-z0-9' | head -c 16)Aa1!"
55-
echo "$SA_PASSWORD" > /tmp/.sqlserver_sa_password
56-
chmod 600 /tmp/.sqlserver_sa_password
55+
# mktemp creates 0600; chmod before writing keeps it owner-only without touching the global umask.
56+
SQL_ENV_FILE="$(mktemp)"
57+
chmod 600 "$SQL_ENV_FILE"
58+
trap 'rm -f "$SQL_ENV_FILE"' EXIT
59+
trap 'exit 129' HUP
60+
trap 'exit 130' INT
61+
trap 'exit 143' TERM
62+
printf 'ACCEPT_EULA=Y\nMSSQL_SA_PASSWORD=%s\n' "$SA_PASSWORD" > "$SQL_ENV_FILE"
5763

5864
# Start SQL Server container (use Azure SQL Edge for ARM64 compatibility)
5965
# This is optional - if Docker-in-Docker fails, the devcontainer still works
@@ -63,15 +69,17 @@ echo "Starting SQL Server container (optional)..."
6369
ARCH=$(uname -m)
6470
if [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then
6571
echo "Detected ARM64 - using Azure SQL Edge..."
66-
docker run -e 'ACCEPT_EULA=Y' -e "MSSQL_SA_PASSWORD=$SA_PASSWORD" \
72+
docker run --env-file "$SQL_ENV_FILE" \
6773
-p 1433:1433 --name sqlserver \
6874
-d mcr.microsoft.com/azure-sql-edge:latest && SQL_STARTED=true || SQL_STARTED=false
6975
else
7076
echo "Detected x86_64 - using SQL Server 2025..."
71-
docker run -e 'ACCEPT_EULA=Y' -e "MSSQL_SA_PASSWORD=$SA_PASSWORD" \
77+
docker run --env-file "$SQL_ENV_FILE" \
7278
-p 1433:1433 --name sqlserver \
7379
-d mcr.microsoft.com/mssql/server:2025-latest && SQL_STARTED=true || SQL_STARTED=false
7480
fi
81+
rm -f "$SQL_ENV_FILE"
82+
trap - EXIT HUP INT TERM
7583

7684
if [ "$SQL_STARTED" = "true" ]; then
7785
echo "Waiting for SQL Server to start..."
@@ -85,12 +93,18 @@ fi
8593
# Set DB_CONNECTION_STRING environment variable (persist across all terminals)
8694
DB_CONNECTION_STRING="Server=localhost,1433;Database=master;UID=sa;PWD=$SA_PASSWORD;TrustServerCertificate=Yes;Encrypt=Yes"
8795

88-
# Write to /etc/environment for system-wide persistence
89-
echo "DB_CONNECTION_STRING=\"$DB_CONNECTION_STRING\"" | sudo tee -a /etc/environment > /dev/null
90-
91-
# Also add to shell rc files for immediate availability in new terminals
92-
echo "export DB_CONNECTION_STRING=\"$DB_CONNECTION_STRING\"" >> ~/.bashrc
93-
echo "export DB_CONNECTION_STRING=\"$DB_CONNECTION_STRING\"" >> ~/.zshrc
96+
# Keep the credential in a user-only file and source it from interactive shells.
97+
MSSQL_ENV_FILE="$HOME/.mssql_python_env"
98+
# Scope umask to this write only so the file is owner-only from creation; global umask stays untouched.
99+
( umask 077; touch "$MSSQL_ENV_FILE"; chmod 600 "$MSSQL_ENV_FILE"; printf "export DB_CONNECTION_STRING='%s'\n" "$DB_CONNECTION_STRING" > "$MSSQL_ENV_FILE" )
100+
101+
# Remove plaintext entries left by older versions of this script.
102+
[ -f /etc/environment ] && sudo sed -i '/^DB_CONNECTION_STRING=/d' /etc/environment
103+
[ -f ~/.bashrc ] && sed -i '/^export DB_CONNECTION_STRING=/d' ~/.bashrc
104+
[ -f ~/.zshrc ] && sed -i '/^export DB_CONNECTION_STRING=/d' ~/.zshrc
105+
rm -f /tmp/.sqlserver_sa_password
106+
grep -qxF 'source ~/.mssql_python_env' ~/.bashrc 2>/dev/null || echo 'source ~/.mssql_python_env' >> ~/.bashrc
107+
grep -qxF 'source ~/.mssql_python_env' ~/.zshrc 2>/dev/null || echo 'source ~/.mssql_python_env' >> ~/.zshrc
94108

95109
# Export for current session
96110
export DB_CONNECTION_STRING

‎OneBranchPipelines/stages/build-linux-single-stage.yml‎

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ stages:
136136
displayName: 'Start $(LINUX_TAG) $(ARCH) container'
137137
138138
- script: |
139-
set -euxo pipefail
139+
set -euo pipefail
140140
export PATH=$PATH:`pwd`/docker
141141
CONTAINER="build-$(LINUX_TAG)-$(ARCH)"
142142
@@ -170,7 +170,7 @@ stages:
170170
# manager is flaky under emulation (the header gate below is the real check).
171171
if [[ "$(LINUX_TAG)" == "manylinux_2_28" ]]; then
172172
docker exec "$CONTAINER" bash -lc '
173-
set -uxo pipefail
173+
set -uo pipefail
174174
if command -v dnf >/dev/null 2>&1; then
175175
dnf -y install gcc gcc-c++ make cmake unixODBC-devel krb5-libs keyutils-libs ccache curl || true
176176
elif command -v yum >/dev/null 2>&1; then
@@ -181,7 +181,7 @@ stages:
181181
'
182182
else
183183
docker exec "$CONTAINER" sh -lc '
184-
set -uxo pipefail
184+
set -uo pipefail
185185
apk add --no-cache bash build-base cmake unixodbc-dev krb5-libs keyutils-libs ccache curl || true
186186
gcc --version || true
187187
cmake --version || true
@@ -199,20 +199,20 @@ stages:
199199
# Start SQL Server container for pytest execution
200200
# Runs on host (not in build container) to be accessible from build container via network
201201
- script: |
202-
set -euxo pipefail
202+
set -euo pipefail
203203
204204
echo "Starting SQL Server 2022 container for testing..."
205205
docker run -d --name sqlserver-$(LINUX_TAG)-$(ARCH) \
206206
--platform linux/amd64 \
207207
-e ACCEPT_EULA=Y \
208-
-e MSSQL_SA_PASSWORD="$(DB_PASSWORD)" \
208+
-e MSSQL_SA_PASSWORD \
209209
-p 1433:1433 \
210210
mcr.microsoft.com/mssql/server:2022-latest
211211
212212
echo "Waiting for SQL Server to be ready..."
213213
for i in {1..30}; do
214-
if docker exec sqlserver-$(LINUX_TAG)-$(ARCH) /opt/mssql-tools18/bin/sqlcmd \
215-
-S localhost -U SA -P "$(DB_PASSWORD)" -C -Q "SELECT 1" >/dev/null 2>&1; then
214+
if docker exec -e SQLCMDPASSWORD sqlserver-$(LINUX_TAG)-$(ARCH) /opt/mssql-tools18/bin/sqlcmd \
215+
-S localhost -U SA -C -Q "SELECT 1" >/dev/null 2>&1; then
216216
echo "✓ SQL Server is ready!"
217217
break
218218
fi
@@ -226,6 +226,8 @@ stages:
226226
displayName: 'Start SQL Server container for testing'
227227
env:
228228
DB_PASSWORD: $(DB_PASSWORD)
229+
MSSQL_SA_PASSWORD: $(DB_PASSWORD)
230+
SQLCMDPASSWORD: $(DB_PASSWORD)
229231
230232
# =========================
231233
# PHASE 2: EXTERNAL ODBC DRIVER PACKAGE
@@ -256,7 +258,7 @@ stages:
256258
257259
# Build wheels for all Python versions (3.10-3.14) and test each one
258260
- script: |
259-
set -euxo pipefail
261+
set -euo pipefail
260262
if [[ "$(LINUX_TAG)" == "manylinux_2_28" ]]; then SHELL_EXE=bash; else SHELL_EXE=sh; fi
261263
docker exec build-$(LINUX_TAG)-$(ARCH) $SHELL_EXE -lc 'mkdir -p /workspace/dist'
262264
@@ -269,8 +271,8 @@ stages:
269271
270272
if [[ "$(LINUX_TAG)" == "manylinux_2_28" ]]; then
271273
# Manylinux (glibc-based) - use bash
272-
docker exec -e PYBIN=$PYBIN -e SQL_IP=$(SQL_IP) -e DB_PASSWORD="$(DB_PASSWORD)" -e MANYLINUX_TAG="$(LINUX_TAG)" -e PIP_FIND_LINKS="/workspace/odbc_wheels" build-$(LINUX_TAG)-$(ARCH) bash -lc '
273-
set -euxo pipefail;
274+
docker exec -e PYBIN=$PYBIN -e SQL_IP=$(SQL_IP) -e DB_PASSWORD -e MANYLINUX_TAG="$(LINUX_TAG)" -e PIP_FIND_LINKS="/workspace/odbc_wheels" build-$(LINUX_TAG)-$(ARCH) bash -lc '
275+
set -euo pipefail;
274276
275277
# Step 1: Setup Python environment
276278
PY=/opt/python/${PYBIN}-${PYBIN}/bin/python;
@@ -339,8 +341,8 @@ stages:
339341
'
340342
else
341343
# Musllinux (musl libc-based) - use sh
342-
docker exec -e PYBIN=$PYBIN -e SQL_IP=$(SQL_IP) -e DB_PASSWORD="$(DB_PASSWORD)" -e MANYLINUX_TAG="$(LINUX_TAG)" -e PIP_FIND_LINKS="/workspace/odbc_wheels" build-$(LINUX_TAG)-$(ARCH) sh -lc '
343-
set -euxo pipefail;
344+
docker exec -e PYBIN=$PYBIN -e SQL_IP=$(SQL_IP) -e DB_PASSWORD -e MANYLINUX_TAG="$(LINUX_TAG)" -e PIP_FIND_LINKS="/workspace/odbc_wheels" build-$(LINUX_TAG)-$(ARCH) sh -lc '
345+
set -euo pipefail;
344346
345347
# Step 1: Setup Python environment
346348
PY=/opt/python/${PYBIN}-${PYBIN}/bin/python;
@@ -422,7 +424,7 @@ stages:
422424
423425
# Copy built artifacts from container to host for publishing
424426
- script: |
425-
set -euxo pipefail
427+
set -euo pipefail
426428
427429
# Copy all wheels (5 Python versions) to output directory
428430
echo "Copying wheels to host..."

‎OneBranchPipelines/stages/build-macos-single-stage.yml‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,20 +161,22 @@ stages:
161161
docker pull mcr.microsoft.com/mssql/server:2022-latest
162162
docker run --name sqlserver \
163163
-e ACCEPT_EULA=Y \
164-
-e MSSQL_SA_PASSWORD="${DB_PASSWORD}" \
164+
-e MSSQL_SA_PASSWORD \
165165
-p 1433:1433 -d \
166166
mcr.microsoft.com/mssql/server:2022-latest
167167
168168
# Wait for SQL Server to accept connections (up to 60 seconds)
169169
# sqlcmd -C flag = trust server certificate (for TLS connection)
170170
for i in {1..30}; do
171-
docker exec sqlserver /opt/mssql-tools18/bin/sqlcmd \
172-
-S localhost -U SA -P "$DB_PASSWORD" -C -Q "SELECT 1" && break
171+
docker exec -e SQLCMDPASSWORD sqlserver /opt/mssql-tools18/bin/sqlcmd \
172+
-S localhost -U SA -C -Q "SELECT 1" && break
173173
sleep 2
174174
done
175175
displayName: 'Start SQL Server (Docker)'
176176
env:
177177
DB_PASSWORD: $(DB_PASSWORD)
178+
MSSQL_SA_PASSWORD: $(DB_PASSWORD)
179+
SQLCMDPASSWORD: $(DB_PASSWORD)
178180
179181
# =========================
180182
# MSSQL-PYTHON-RS INSTALLATION

‎OneBranchPipelines/stages/build-windows-single-stage.yml‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,20 @@ stages:
168168
169169
- powershell: |
170170
sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "CREATE DATABASE TestDB"
171-
sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "CREATE LOGIN testuser WITH PASSWORD = '$(DB_PASSWORD)'"
171+
$sqlPassword = $env:DB_PASSWORD.Replace("'", "''")
172+
$sqlPath = Join-Path $env:TEMP ("create-testuser-{0}.sql" -f [guid]::NewGuid())
173+
$sqlBytes = (New-Object System.Text.UTF8Encoding($false)).GetBytes("CREATE LOGIN testuser WITH PASSWORD = '$sqlPassword'`n")
174+
[System.IO.File]::Create($sqlPath).Dispose()
175+
try {
176+
$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
177+
icacls $sqlPath /inheritance:r /grant:r "${identity}:(F)" "SYSTEM:(R)" | Out-Null
178+
if ($LASTEXITCODE -ne 0) { throw "Failed to secure temporary SQL file" }
179+
[System.IO.File]::WriteAllBytes($sqlPath, $sqlBytes)
180+
sqlcmd -S "(localdb)\MSSQLLocalDB" -i $sqlPath -b -x -f 65001
181+
if ($LASTEXITCODE -ne 0) { throw "Failed to create the testuser login" }
182+
} finally {
183+
Remove-Item $sqlPath -Force -ErrorAction Stop
184+
}
172185
sqlcmd -S "(localdb)\MSSQLLocalDB" -d TestDB -Q "CREATE USER testuser FOR LOGIN testuser"
173186
sqlcmd -S "(localdb)\MSSQLLocalDB" -d TestDB -Q "ALTER ROLE db_owner ADD MEMBER testuser"
174187
displayName: 'Setup database and user'

‎OneBranchPipelines/stress-test-pipeline.yml‎

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,20 @@ jobs:
107107
- powershell: |
108108
Write-Host "Creating database and user for stress tests..."
109109
sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "CREATE DATABASE StressTestDB"
110-
sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "CREATE LOGIN testuser WITH PASSWORD = '$env:DB_PASSWORD'"
110+
$sqlPassword = $env:DB_PASSWORD.Replace("'", "''")
111+
$sqlPath = Join-Path $env:TEMP ("create-testuser-{0}.sql" -f [guid]::NewGuid())
112+
$sqlBytes = (New-Object System.Text.UTF8Encoding($false)).GetBytes("CREATE LOGIN testuser WITH PASSWORD = '$sqlPassword'`n")
113+
[System.IO.File]::Create($sqlPath).Dispose()
114+
try {
115+
$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
116+
icacls $sqlPath /inheritance:r /grant:r "${identity}:(F)" "SYSTEM:(R)" | Out-Null
117+
if ($LASTEXITCODE -ne 0) { throw "Failed to secure temporary SQL file" }
118+
[System.IO.File]::WriteAllBytes($sqlPath, $sqlBytes)
119+
sqlcmd -S "(localdb)\MSSQLLocalDB" -i $sqlPath -b -x -f 65001
120+
if ($LASTEXITCODE -ne 0) { throw "Failed to create the testuser login" }
121+
} finally {
122+
Remove-Item $sqlPath -Force -ErrorAction Stop
123+
}
111124
sqlcmd -S "(localdb)\MSSQLLocalDB" -d StressTestDB -Q "CREATE USER testuser FOR LOGIN testuser"
112125
sqlcmd -S "(localdb)\MSSQLLocalDB" -d StressTestDB -Q "ALTER ROLE db_owner ADD MEMBER testuser"
113126
Write-Host "Database setup completed"
@@ -117,7 +130,7 @@ jobs:
117130
118131
# Run multi-threaded stress tests in an isolated subprocess.
119132
- powershell: |
120-
$env:DB_CONNECTION_STRING = 'Server=(localdb)\MSSQLLocalDB;Database=StressTestDB;Uid=testuser;Pwd=$(DB_PASSWORD);TrustServerCertificate=yes'
133+
$env:DB_CONNECTION_STRING = "Server=(localdb)\MSSQLLocalDB;Database=StressTestDB;Uid=testuser;Pwd=$env:DB_PASSWORD;TrustServerCertificate=yes"
121134
Write-Host "Starting stress tests..."
122135
123136
$xmlFile = "stress-test-results.xml"
@@ -158,17 +171,21 @@ jobs:
158171
Write-Host "Test failures detected or XML not found"
159172
exit 1
160173
displayName: 'Run Multi-Threaded Stress Tests'
174+
env:
175+
DB_PASSWORD: $(DB_PASSWORD)
161176
continueOnError: true
162177
163178
164179
# Run original stress tests
165180
- powershell: |
166-
$env:DB_CONNECTION_STRING = 'Server=(localdb)\MSSQLLocalDB;Database=StressTestDB;Uid=testuser;Pwd=$(DB_PASSWORD);TrustServerCertificate=yes'
181+
$env:DB_CONNECTION_STRING = "Server=(localdb)\MSSQLLocalDB;Database=StressTestDB;Uid=testuser;Pwd=$env:DB_PASSWORD;TrustServerCertificate=yes"
167182
python -m pytest tests/test_011_singlethreaded_stress.py -v -m "stress" --junitxml=perf-stress-test-results.xml --timeout=1800 --capture=tee-sys
168183
$exitCode = $LASTEXITCODE
169184
Write-Host "Pytest exit code: $exitCode"
170185
exit $exitCode
171186
displayName: 'Run Single-Threaded Stress Tests'
187+
env:
188+
DB_PASSWORD: $(DB_PASSWORD)
172189
continueOnError: true
173190
174191
# Publish test results
@@ -265,20 +282,20 @@ jobs:
265282
266283
# Start SQL Server container for stress tests
267284
- script: |
268-
set -euxo pipefail
285+
set -euo pipefail
269286
270287
echo "Starting SQL Server 2022 container for stress tests..."
271288
docker run -d --name sqlserver-stress \
272289
--platform linux/amd64 \
273290
-e ACCEPT_EULA=Y \
274-
-e MSSQL_SA_PASSWORD="$(DB_PASSWORD)" \
291+
-e MSSQL_SA_PASSWORD \
275292
-p 1433:1433 \
276293
mcr.microsoft.com/mssql/server:2022-latest
277294
278295
echo "Waiting for SQL Server to be ready..."
279296
for i in {1..30}; do
280-
if docker exec sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
281-
-S localhost -U SA -P "$(DB_PASSWORD)" -C -Q "SELECT 1" >/dev/null 2>&1; then
297+
if docker exec -e SQLCMDPASSWORD sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
298+
-S localhost -U SA -C -Q "SELECT 1" >/dev/null 2>&1; then
282299
echo "SQL Server is ready!"
283300
break
284301
fi
@@ -287,19 +304,22 @@ jobs:
287304
done
288305
289306
echo "Creating database and user for stress tests..."
290-
docker exec sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
291-
-S localhost -U SA -P "$(DB_PASSWORD)" -C -Q "CREATE DATABASE StressTestDB"
292-
docker exec sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
293-
-S localhost -U SA -P "$(DB_PASSWORD)" -C -Q "CREATE LOGIN testuser WITH PASSWORD = '$(DB_PASSWORD)'"
294-
docker exec sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
295-
-S localhost -U SA -P "$(DB_PASSWORD)" -C -d StressTestDB -Q "CREATE USER testuser FOR LOGIN testuser"
296-
docker exec sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
297-
-S localhost -U SA -P "$(DB_PASSWORD)" -C -d StressTestDB -Q "ALTER ROLE db_owner ADD MEMBER testuser"
307+
docker exec -e SQLCMDPASSWORD sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
308+
-S localhost -U SA -C -Q "CREATE DATABASE StressTestDB"
309+
SQL_PASSWORD=${DB_PASSWORD//\'/\'\'}
310+
printf "CREATE LOGIN testuser WITH PASSWORD = '%s'\n" "$SQL_PASSWORD" | \
311+
docker exec -i -e SQLCMDPASSWORD sqlserver-stress /opt/mssql-tools18/bin/sqlcmd -S localhost -U SA -C -b -x
312+
docker exec -e SQLCMDPASSWORD sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
313+
-S localhost -U SA -C -d StressTestDB -Q "CREATE USER testuser FOR LOGIN testuser"
314+
docker exec -e SQLCMDPASSWORD sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
315+
-S localhost -U SA -C -d StressTestDB -Q "ALTER ROLE db_owner ADD MEMBER testuser"
298316
299317
echo "Database setup completed"
300318
displayName: 'Start SQL Server container and setup database'
301319
env:
302320
DB_PASSWORD: $(DB_PASSWORD)
321+
MSSQL_SA_PASSWORD: $(DB_PASSWORD)
322+
SQLCMDPASSWORD: $(DB_PASSWORD)
303323
304324
# Run multi-threaded stress tests in an isolated subprocess.
305325
- script: |

0 commit comments

Comments
 (0)