Skip to content
Open
30 changes: 20 additions & 10 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ fi
echo ""
echo "Generating SQL Server password..."
SA_PASSWORD="$(openssl rand -base64 16 | tr -dc 'A-Za-z0-9' | head -c 16)Aa1!"
echo "$SA_PASSWORD" > /tmp/.sqlserver_sa_password
chmod 600 /tmp/.sqlserver_sa_password
# mktemp creates 0600; chmod before writing keeps it owner-only without touching the global umask.
SQL_ENV_FILE="$(mktemp)"
chmod 600 "$SQL_ENV_FILE"
printf 'ACCEPT_EULA=Y\nMSSQL_SA_PASSWORD=%s\n' "$SA_PASSWORD" > "$SQL_ENV_FILE"

# Start SQL Server container (use Azure SQL Edge for ARM64 compatibility)
# This is optional - if Docker-in-Docker fails, the devcontainer still works
Expand All @@ -63,15 +65,16 @@ echo "Starting SQL Server container (optional)..."
ARCH=$(uname -m)
if [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then
echo "Detected ARM64 - using Azure SQL Edge..."
docker run -e 'ACCEPT_EULA=Y' -e "MSSQL_SA_PASSWORD=$SA_PASSWORD" \
docker run --env-file "$SQL_ENV_FILE" \
-p 1433:1433 --name sqlserver \
-d mcr.microsoft.com/azure-sql-edge:latest && SQL_STARTED=true || SQL_STARTED=false
else
echo "Detected x86_64 - using SQL Server 2025..."
docker run -e 'ACCEPT_EULA=Y' -e "MSSQL_SA_PASSWORD=$SA_PASSWORD" \
docker run --env-file "$SQL_ENV_FILE" \
-p 1433:1433 --name sqlserver \
-d mcr.microsoft.com/mssql/server:2025-latest && SQL_STARTED=true || SQL_STARTED=false
fi
rm -f "$SQL_ENV_FILE"

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

# Write to /etc/environment for system-wide persistence
echo "DB_CONNECTION_STRING=\"$DB_CONNECTION_STRING\"" | sudo tee -a /etc/environment > /dev/null

# Also add to shell rc files for immediate availability in new terminals
echo "export DB_CONNECTION_STRING=\"$DB_CONNECTION_STRING\"" >> ~/.bashrc
echo "export DB_CONNECTION_STRING=\"$DB_CONNECTION_STRING\"" >> ~/.zshrc
# Keep the credential in a user-only file and source it from interactive shells.
MSSQL_ENV_FILE="$HOME/.mssql_python_env"
# Scope umask to this write only so the file is owner-only from creation; global umask stays untouched.
( umask 077; printf "export DB_CONNECTION_STRING='%s'\n" "$DB_CONNECTION_STRING" > "$MSSQL_ENV_FILE" )
chmod 600 "$MSSQL_ENV_FILE"

# Remove plaintext entries left by older versions of this script.
[ -f /etc/environment ] && sudo sed -i '/^DB_CONNECTION_STRING=/d' /etc/environment
[ -f ~/.bashrc ] && sed -i '/^export DB_CONNECTION_STRING=/d' ~/.bashrc
[ -f ~/.zshrc ] && sed -i '/^export DB_CONNECTION_STRING=/d' ~/.zshrc
rm -f /tmp/.sqlserver_sa_password
grep -qxF 'source ~/.mssql_python_env' ~/.bashrc 2>/dev/null || echo 'source ~/.mssql_python_env' >> ~/.bashrc
grep -qxF 'source ~/.mssql_python_env' ~/.zshrc 2>/dev/null || echo 'source ~/.mssql_python_env' >> ~/.zshrc

# Export for current session
export DB_CONNECTION_STRING
Expand Down
28 changes: 15 additions & 13 deletions OneBranchPipelines/stages/build-linux-single-stage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
displayName: 'Start $(LINUX_TAG) $(ARCH) container'

- script: |
set -euxo pipefail
set -euo pipefail
export PATH=$PATH:`pwd`/docker
CONTAINER="build-$(LINUX_TAG)-$(ARCH)"

Expand Down Expand Up @@ -170,7 +170,7 @@
# manager is flaky under emulation (the header gate below is the real check).
if [[ "$(LINUX_TAG)" == "manylinux_2_28" ]]; then
docker exec "$CONTAINER" bash -lc '
set -uxo pipefail
set -uo pipefail
if command -v dnf >/dev/null 2>&1; then
dnf -y install gcc gcc-c++ make cmake unixODBC-devel krb5-libs keyutils-libs ccache curl || true
elif command -v yum >/dev/null 2>&1; then
Expand All @@ -181,7 +181,7 @@
'
else
docker exec "$CONTAINER" sh -lc '
set -uxo pipefail
set -uo pipefail
apk add --no-cache bash build-base cmake unixodbc-dev krb5-libs keyutils-libs ccache curl || true
gcc --version || true
cmake --version || true
Expand All @@ -199,20 +199,20 @@
# Start SQL Server container for pytest execution
# Runs on host (not in build container) to be accessible from build container via network
- script: |
set -euxo pipefail
set -euo pipefail

echo "Starting SQL Server 2022 container for testing..."
docker run -d --name sqlserver-$(LINUX_TAG)-$(ARCH) \
--platform linux/amd64 \
-e ACCEPT_EULA=Y \
-e MSSQL_SA_PASSWORD="$(DB_PASSWORD)" \
-e MSSQL_SA_PASSWORD \
-p 1433:1433 \
mcr.microsoft.com/mssql/server:2022-latest

echo "Waiting for SQL Server to be ready..."
for i in {1..30}; do
if docker exec sqlserver-$(LINUX_TAG)-$(ARCH) /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -P "$(DB_PASSWORD)" -C -Q "SELECT 1" >/dev/null 2>&1; then
if docker exec -e SQLCMDPASSWORD sqlserver-$(LINUX_TAG)-$(ARCH) /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -C -Q "SELECT 1" >/dev/null 2>&1; then

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
echo "✓ SQL Server is ready!"
break
fi
Expand All @@ -226,6 +226,8 @@
displayName: 'Start SQL Server container for testing'
env:
DB_PASSWORD: $(DB_PASSWORD)
MSSQL_SA_PASSWORD: $(DB_PASSWORD)
SQLCMDPASSWORD: $(DB_PASSWORD)

# =========================
# PHASE 2: EXTERNAL ODBC DRIVER PACKAGE
Expand Down Expand Up @@ -256,7 +258,7 @@

# Build wheels for all Python versions (3.10-3.14) and test each one
- script: |
set -euxo pipefail
set -euo pipefail
if [[ "$(LINUX_TAG)" == "manylinux_2_28" ]]; then SHELL_EXE=bash; else SHELL_EXE=sh; fi
docker exec build-$(LINUX_TAG)-$(ARCH) $SHELL_EXE -lc 'mkdir -p /workspace/dist'

Expand All @@ -269,8 +271,8 @@

if [[ "$(LINUX_TAG)" == "manylinux_2_28" ]]; then
# Manylinux (glibc-based) - use bash
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 '
set -euxo pipefail;
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 '
set -euo pipefail;

# Step 1: Setup Python environment
PY=/opt/python/${PYBIN}-${PYBIN}/bin/python;
Expand Down Expand Up @@ -339,8 +341,8 @@
'
else
# Musllinux (musl libc-based) - use sh
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 '
set -euxo pipefail;
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 '
set -euo pipefail;

# Step 1: Setup Python environment
PY=/opt/python/${PYBIN}-${PYBIN}/bin/python;
Expand Down Expand Up @@ -422,7 +424,7 @@

# Copy built artifacts from container to host for publishing
- script: |
set -euxo pipefail
set -euo pipefail

# Copy all wheels (5 Python versions) to output directory
echo "Copying wheels to host..."
Expand Down
8 changes: 5 additions & 3 deletions OneBranchPipelines/stages/build-macos-single-stage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,20 +165,22 @@
docker pull mcr.microsoft.com/mssql/server:2022-latest
docker run --name sqlserver \
-e ACCEPT_EULA=Y \
-e MSSQL_SA_PASSWORD="${DB_PASSWORD}" \
-e MSSQL_SA_PASSWORD \
-p 1433:1433 -d \
mcr.microsoft.com/mssql/server:2022-latest

# Wait for SQL Server to accept connections (up to 60 seconds)
# sqlcmd -C flag = trust server certificate (for TLS connection)
for i in {1..30}; do
docker exec sqlserver /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -P "$DB_PASSWORD" -C -Q "SELECT 1" && break
docker exec -e SQLCMDPASSWORD sqlserver /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -C -Q "SELECT 1" && break

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
sleep 2
done
displayName: 'Start SQL Server (Docker)'
env:
DB_PASSWORD: $(DB_PASSWORD)
MSSQL_SA_PASSWORD: $(DB_PASSWORD)
SQLCMDPASSWORD: $(DB_PASSWORD)

# =========================
# MSSQL_PY_CORE INSTALLATION
Expand Down
2 changes: 1 addition & 1 deletion OneBranchPipelines/stages/build-windows-single-stage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ stages:

- powershell: |
sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "CREATE DATABASE TestDB"
sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "CREATE LOGIN testuser WITH PASSWORD = '$(DB_PASSWORD)'"
"CREATE LOGIN testuser WITH PASSWORD = '$env:DB_PASSWORD'" | sqlcmd -S "(localdb)\MSSQLLocalDB"
Comment thread
gargsaumya marked this conversation as resolved.
sqlcmd -S "(localdb)\MSSQLLocalDB" -d TestDB -Q "CREATE USER testuser FOR LOGIN testuser"
sqlcmd -S "(localdb)\MSSQLLocalDB" -d TestDB -Q "ALTER ROLE db_owner ADD MEMBER testuser"
displayName: 'Setup database and user'
Expand Down
36 changes: 21 additions & 15 deletions OneBranchPipelines/stress-test-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
- powershell: |
Write-Host "Creating database and user for stress tests..."
sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "CREATE DATABASE StressTestDB"
sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "CREATE LOGIN testuser WITH PASSWORD = '$env:DB_PASSWORD'"
"CREATE LOGIN testuser WITH PASSWORD = '$env:DB_PASSWORD'" | sqlcmd -S "(localdb)\MSSQLLocalDB"
Comment thread
gargsaumya marked this conversation as resolved.
sqlcmd -S "(localdb)\MSSQLLocalDB" -d StressTestDB -Q "CREATE USER testuser FOR LOGIN testuser"
sqlcmd -S "(localdb)\MSSQLLocalDB" -d StressTestDB -Q "ALTER ROLE db_owner ADD MEMBER testuser"
Write-Host "Database setup completed"
Expand All @@ -113,7 +113,7 @@

# Run multi-threaded stress tests in an isolated subprocess.
- powershell: |
$env:DB_CONNECTION_STRING = 'Server=(localdb)\MSSQLLocalDB;Database=StressTestDB;Uid=testuser;Pwd=$(DB_PASSWORD);TrustServerCertificate=yes'
$env:DB_CONNECTION_STRING = "Server=(localdb)\MSSQLLocalDB;Database=StressTestDB;Uid=testuser;Pwd=$env:DB_PASSWORD;TrustServerCertificate=yes"
Write-Host "Starting stress tests..."

$xmlFile = "stress-test-results.xml"
Expand Down Expand Up @@ -154,17 +154,21 @@
Write-Host "Test failures detected or XML not found"
exit 1
displayName: 'Run Multi-Threaded Stress Tests'
env:
DB_PASSWORD: $(DB_PASSWORD)
continueOnError: true


# Run original stress tests
- powershell: |
$env:DB_CONNECTION_STRING = 'Server=(localdb)\MSSQLLocalDB;Database=StressTestDB;Uid=testuser;Pwd=$(DB_PASSWORD);TrustServerCertificate=yes'
$env:DB_CONNECTION_STRING = "Server=(localdb)\MSSQLLocalDB;Database=StressTestDB;Uid=testuser;Pwd=$env:DB_PASSWORD;TrustServerCertificate=yes"
python -m pytest tests/test_011_singlethreaded_stress.py -v -m "stress" --junitxml=perf-stress-test-results.xml --timeout=1800 --capture=tee-sys
$exitCode = $LASTEXITCODE
Write-Host "Pytest exit code: $exitCode"
exit $exitCode
displayName: 'Run Single-Threaded Stress Tests'
env:
DB_PASSWORD: $(DB_PASSWORD)
continueOnError: true

# Publish test results
Expand Down Expand Up @@ -257,20 +261,20 @@

# Start SQL Server container for stress tests
- script: |
set -euxo pipefail
set -euo pipefail

echo "Starting SQL Server 2022 container for stress tests..."
docker run -d --name sqlserver-stress \
--platform linux/amd64 \
-e ACCEPT_EULA=Y \
-e MSSQL_SA_PASSWORD="$(DB_PASSWORD)" \
-e MSSQL_SA_PASSWORD \
-p 1433:1433 \
mcr.microsoft.com/mssql/server:2022-latest

echo "Waiting for SQL Server to be ready..."
for i in {1..30}; do
if docker exec sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -P "$(DB_PASSWORD)" -C -Q "SELECT 1" >/dev/null 2>&1; then
if docker exec -e SQLCMDPASSWORD sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -C -Q "SELECT 1" >/dev/null 2>&1; then

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
echo "SQL Server is ready!"
break
fi
Expand All @@ -279,19 +283,21 @@
done

echo "Creating database and user for stress tests..."
docker exec sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -P "$(DB_PASSWORD)" -C -Q "CREATE DATABASE StressTestDB"
docker exec sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -P "$(DB_PASSWORD)" -C -Q "CREATE LOGIN testuser WITH PASSWORD = '$(DB_PASSWORD)'"
docker exec sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -P "$(DB_PASSWORD)" -C -d StressTestDB -Q "CREATE USER testuser FOR LOGIN testuser"
docker exec sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -P "$(DB_PASSWORD)" -C -d StressTestDB -Q "ALTER ROLE db_owner ADD MEMBER testuser"
docker exec -e SQLCMDPASSWORD sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -C -Q "CREATE DATABASE StressTestDB"

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
printf "CREATE LOGIN testuser WITH PASSWORD = '%s'\n" "$DB_PASSWORD" | \
docker exec -i -e SQLCMDPASSWORD sqlserver-stress /opt/mssql-tools18/bin/sqlcmd -S localhost -U SA -C

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
Comment thread
gargsaumya marked this conversation as resolved.
docker exec -e SQLCMDPASSWORD sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -C -d StressTestDB -Q "CREATE USER testuser FOR LOGIN testuser"

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
docker exec -e SQLCMDPASSWORD sqlserver-stress /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U SA -C -d StressTestDB -Q "ALTER ROLE db_owner ADD MEMBER testuser"

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production

echo "Database setup completed"
displayName: 'Start SQL Server container and setup database'
env:
DB_PASSWORD: $(DB_PASSWORD)
MSSQL_SA_PASSWORD: $(DB_PASSWORD)
SQLCMDPASSWORD: $(DB_PASSWORD)

# Run multi-threaded stress tests in an isolated subprocess.
- script: |
Expand Down
Loading
Loading