Skip to content

Commit c994d1a

Browse files
Merge remote-tracking branch 'origin/main' into dev/cheena/split-data-stream-tests
2 parents 893c197 + d169900 commit c994d1a

7 files changed

Lines changed: 222 additions & 6 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FROM mcr.microsoft.com/devcontainers/dotnet:10.0-noble
2+
3+
# Install .NET 8.0 and 9.0 runtimes and targeting packs (needed to build and run tests targeting these TFMs).
4+
# The base image ships the latest .NET SDK (10.0) which can build for older TFMs,
5+
# but the matching runtimes are required to *execute* those targets, and the
6+
# targeting packs (ref assemblies) are required to *compile* against them.
7+
COPY --from=mcr.microsoft.com/dotnet/sdk:8.0 /usr/share/dotnet/shared /usr/share/dotnet/shared
8+
COPY --from=mcr.microsoft.com/dotnet/sdk:9.0 /usr/share/dotnet/shared /usr/share/dotnet/shared
9+
COPY --from=mcr.microsoft.com/dotnet/sdk:8.0 /usr/share/dotnet/packs /usr/share/dotnet/packs
10+
COPY --from=mcr.microsoft.com/dotnet/sdk:9.0 /usr/share/dotnet/packs /usr/share/dotnet/packs
11+
12+
# Install jq for JSON manipulation in setup scripts.
13+
RUN apt-get update && apt-get install -y --no-install-recommends jq && rm -rf /var/lib/apt/lists/*
14+
15+
# Install go-sqlcmd (standalone binary, works on Ubuntu without dependency issues).
16+
ARG SQLCMD_VERSION=v1.9.0
17+
ARG SQLCMD_SHA256_amd64="b896bac71cf6ad8feca125bb42be61999116d8566a078ed475893372ccf8c0f2"
18+
ARG SQLCMD_SHA256_arm64="e5de98d635bfecf337acadf9d84a8f4f3cdcf38b2978b9dcd83aed20425c64ef"
19+
RUN arch="$(dpkg --print-architecture)" \
20+
&& case "$arch" in \
21+
amd64) SQLCMD_ARCH="linux-amd64" ;; \
22+
arm64) SQLCMD_ARCH="linux-arm64" ;; \
23+
*) echo "Unsupported architecture: $arch" && exit 1 ;; \
24+
esac \
25+
&& curl -fsSL "https://github.com/microsoft/go-sqlcmd/releases/download/${SQLCMD_VERSION}/sqlcmd-${SQLCMD_ARCH}.tar.bz2" \
26+
-o /tmp/sqlcmd.tar.bz2 \
27+
&& if [ "$arch" = "amd64" ]; then echo "$SQLCMD_SHA256_amd64 /tmp/sqlcmd.tar.bz2" | sha256sum -c -; fi \
28+
&& if [ "$arch" = "arm64" ]; then echo "$SQLCMD_SHA256_arm64 /tmp/sqlcmd.tar.bz2" | sha256sum -c -; fi \
29+
&& tar xjf /tmp/sqlcmd.tar.bz2 -C /usr/local/bin/ sqlcmd \
30+
&& chmod +x /usr/local/bin/sqlcmd \
31+
&& rm -f /tmp/sqlcmd.tar.bz2

.devcontainer/devcontainer.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "Microsoft.Data.SqlClient",
3+
"dockerComposeFile": "docker-compose.yml",
4+
"service": "devcontainer",
5+
"workspaceFolder": "/workspaces/SqlClient",
6+
"features": {
7+
"ghcr.io/devcontainers/features/powershell:2.0.1": {}
8+
},
9+
"customizations": {
10+
"vscode": {
11+
"extensions": [
12+
"ms-azuretools.vscode-containers",
13+
"ms-dotnettools.csdevkit",
14+
"ms-dotnettools.csharp",
15+
"GitHub.copilot",
16+
"ms-mssql.mssql"
17+
],
18+
"settings": {
19+
"dotnet.defaultSolution": "src/Microsoft.Data.SqlClient.sln"
20+
}
21+
}
22+
},
23+
"postCreateCommand": "bash .devcontainer/setup-sqlserver.sh",
24+
"remoteUser": "vscode"
25+
}

.devcontainer/docker-compose.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
services:
2+
devcontainer:
3+
build:
4+
context: .
5+
dockerfile: Dockerfile
6+
volumes:
7+
- ..:/workspaces/SqlClient:cached
8+
- sql-config:/sql-config:ro
9+
command: sleep infinity
10+
depends_on:
11+
sqlserver:
12+
condition: service_healthy
13+
environment:
14+
- SQL_SERVER_HOST=sqlserver
15+
- SQL_SERVER_PORT=1433
16+
- SQL_SERVER_SA_PASSWORD_FILE=/sql-config/sa-password
17+
networks:
18+
- default
19+
20+
sqlserver:
21+
image: mcr.microsoft.com/mssql/server:2025-latest
22+
# Adding user: root lets the entrypoint script create the password file,
23+
# after which sqlservr internally drops privileges to the mssql user.
24+
# This is the officially supported approach for SQL Server Linux containers.
25+
# https://learn.microsoft.com/sql/linux/sql-server-linux-docker-container-security
26+
user: root
27+
entrypoint: /sql-entrypoint/sqlserver-entrypoint.sh
28+
volumes:
29+
- sql-config:/sql-config
30+
- ./sqlserver-entrypoint.sh:/sql-entrypoint/sqlserver-entrypoint.sh:ro
31+
environment:
32+
ACCEPT_EULA: "Y"
33+
MSSQL_PID: "Developer"
34+
ports:
35+
- "1433:1433"
36+
healthcheck:
37+
test: /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "$$(cat /sql-config/sa-password)" -C -Q "SELECT 1" || exit 1
38+
interval: 10s
39+
timeout: 5s
40+
retries: 10
41+
start_period: 30s
42+
networks:
43+
- default
44+
45+
volumes:
46+
sql-config:

.devcontainer/setup-sqlserver.sh

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env bash
2+
# -------------------------------------------------------------------
3+
# Initializes the SQL Server instance running in the devcontainer
4+
# companion service with the test databases required by the test suite.
5+
# -------------------------------------------------------------------
6+
set -euo pipefail
7+
8+
SQL_HOST="${SQL_SERVER_HOST:-sqlserver}"
9+
SQL_PORT="${SQL_SERVER_PORT:-1433}"
10+
SA_PASSWORD_FILE="${SQL_SERVER_SA_PASSWORD_FILE:-/sql-config/sa-password}"
11+
12+
# Wait for the auto-generated SA password file from the sqlserver service.
13+
# The sqlserver entrypoint writes this file on startup; the shared volume
14+
# may not be visible immediately when postCreateCommand begins.
15+
echo "Waiting for SA password file at ${SA_PASSWORD_FILE}..."
16+
for i in $(seq 1 30); do
17+
if [ -f "$SA_PASSWORD_FILE" ]; then
18+
break
19+
fi
20+
if [ "$i" -eq 30 ]; then
21+
echo "ERROR: SA password file not found at $SA_PASSWORD_FILE after 60 s" >&2
22+
exit 1
23+
fi
24+
sleep 2
25+
done
26+
SA_PASSWORD="$(cat "$SA_PASSWORD_FILE")"
27+
28+
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
29+
30+
# Write test config file so the test suite can find the connection string.
31+
CONFIG_DIR="${REPO_ROOT}/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities"
32+
CONFIG_DEFAULT_FILE="${CONFIG_DIR}/config.default.json"
33+
CONFIG_FILE="${CONFIG_DIR}/config.json"
34+
echo "Writing test config to ${CONFIG_FILE} (based on ${CONFIG_DEFAULT_FILE})..."
35+
TCP_CONN_STR="Data Source=tcp:${SQL_HOST},${SQL_PORT};Database=Northwind;User Id=sa;Password=${SA_PASSWORD};Encrypt=false;TrustServerCertificate=true"
36+
# config.default.json contains JS-style comments (// ...) which are not valid JSON.
37+
# Strip single-line comments before feeding to jq.
38+
sed 's|//.*||' "${CONFIG_DEFAULT_FILE}" \
39+
| jq --arg cs "${TCP_CONN_STR}" \
40+
'.TCPConnectionString = $cs | .NPConnectionString = "" | .SupportsIntegratedSecurity = false' \
41+
> "${CONFIG_FILE}"
42+
echo "Test config written."
43+
44+
echo "Waiting for SQL Server at ${SQL_HOST}:${SQL_PORT} to become available..."
45+
for i in $(seq 1 30); do
46+
if sqlcmd -S "${SQL_HOST},${SQL_PORT}" -U sa -P "${SA_PASSWORD}" -C -Q "SELECT 1" &>/dev/null; then
47+
break
48+
fi
49+
if [ "$i" -eq 30 ]; then
50+
echo "ERROR: SQL Server did not become available in time." >&2
51+
exit 1
52+
fi
53+
sleep 2
54+
done
55+
echo "SQL Server is ready."
56+
57+
# Ensure Northwind database exists
58+
echo "Ensuring Northwind database exists..."
59+
DB_EXISTS_RAW="$(sqlcmd -S "${SQL_HOST},${SQL_PORT}" -U sa -P "${SA_PASSWORD}" -C -h -1 -W \
60+
-Q "SET NOCOUNT ON; SELECT COUNT(*) FROM sys.databases WHERE name = N'Northwind';" | tr -d '\r')"
61+
DB_EXISTS="$(echo "$DB_EXISTS_RAW" | tr -d ' ')"
62+
if [ "$DB_EXISTS" = "0" ]; then
63+
echo "Northwind database not found, creating..."
64+
sqlcmd -S "${SQL_HOST},${SQL_PORT}" -U sa -P "${SA_PASSWORD}" -C \
65+
-i "${REPO_ROOT}/tools/testsql/createNorthwindDb.sql"
66+
echo "Northwind database created."
67+
else
68+
echo "Northwind database already exists; skipping creation script."
69+
fi
70+
71+
echo "SQL Server test database setup complete."
72+
echo ""
73+
echo "Connection info:"
74+
echo " Host: ${SQL_HOST}"
75+
echo " Port: ${SQL_PORT}"
76+
echo " User: sa"
77+
echo " Password: ${SA_PASSWORD}"
78+
echo ""
79+
echo "Example sqlcmd:"
80+
echo " sqlcmd -S ${SQL_HOST},${SQL_PORT} -U sa -P '${SA_PASSWORD}' -C"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env bash
2+
# -------------------------------------------------------------------
3+
# Generates a random SA password and writes it to /sql-config/sa-password
4+
# so both the devcontainer and sqlserver service can use it.
5+
#
6+
# Called as the sqlserver entrypoint (before SQL Server starts).
7+
# -------------------------------------------------------------------
8+
set -euo pipefail
9+
10+
PASSWORD_FILE="/sql-config/sa-password"
11+
12+
# -------------------------------------------------------------------
13+
#
14+
# These permissions are required for the sqlserver entrypoint to write the password file
15+
# and for the devcontainer setup script to read it. The shared volume may be owned by root,
16+
# so we set permissive permissions to ensure both sides can access it.
17+
#
18+
# The sqlserver entrypoint will overwrite the password file on startup,
19+
# so we don't need to worry about other users modifying it.
20+
#
21+
# -------------------------------------------------------------------
22+
chmod 777 /sql-config 2>/dev/null || true
23+
24+
# Generate a password only if one doesn't already exist (container restart).
25+
if [ ! -f "$PASSWORD_FILE" ]; then
26+
# 32-byte random base64 + required character classes for SQL Server policy.
27+
RAW="$(head -c 32 /dev/urandom | base64 | tr -d '/+=' | head -c 24)"
28+
# SQL Server requires uppercase, lowercase, digit, and symbol.
29+
GENERATED="A1a@${RAW}"
30+
echo -n "$GENERATED" > "$PASSWORD_FILE"
31+
fi
32+
33+
PASSWORD="$(cat "$PASSWORD_FILE")"
34+
export MSSQL_SA_PASSWORD="$PASSWORD"
35+
36+
# Hand off to the real SQL Server entrypoint.
37+
exec /opt/mssql/bin/sqlservr

eng/pipelines/common/templates/steps/configure-sql-server-macos-step.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# See the LICENSE file in the project root for more information. #
55
#################################################################################
66

7-
# This step installs the latest SQL Server 2022 onto the macOS host as a docker container and
7+
# This step installs the latest SQL Server 2025 onto the macOS host as a docker container and
88
# configures it for use.
99

1010
parameters:
@@ -37,12 +37,12 @@ steps:
3737
HOMEBREW_ACCEPT_EULA=Y brew install mssql-tools18
3838
colima start --arch x86_64
3939
docker --version
40-
docker pull mcr.microsoft.com/mssql/server:2022-latest
40+
docker pull mcr.microsoft.com/mssql/server:2025-latest
4141
4242
# Password for the SA user (required)
4343
MSSQL_SA_PW="${{ parameters.saPassword }}"
4444
45-
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=$MSSQL_SA_PW" -p 1433:1433 -p 1434:1434 --name sql1 --hostname sql1 -d mcr.microsoft.com/mssql/server:2022-latest
45+
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=$MSSQL_SA_PW" -p 1433:1433 -p 1434:1434 --name sql1 --hostname sql1 -d mcr.microsoft.com/mssql/server:2025-latest
4646
4747
sleep 5
4848

tools/GenAPI/Microsoft.DotNet.GenAPI/Microsoft.DotNet.GenAPI.csproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,5 @@
2323
<ProjectReference Include="..\Microsoft.Cci.Extensions\Microsoft.Cci.Extensions.csproj" />
2424

2525
<PackageReference Include="McMaster.Extensions.CommandLineUtils" />
26-
<PackageReference Include="System.Diagnostics.TextWriterTraceListener" />
27-
<PackageReference Include="System.Diagnostics.TraceSource" />
28-
<PackageReference Include="System.Private.Uri" />
2926
</ItemGroup>
3027
</Project>

0 commit comments

Comments
 (0)