18 KiB
Guidelines for Building Microsoft.Data.SqlClient
This document provides all the necessary details to build the driver and run tests present in the repository.
Visual Studio Pre-Requisites
This project should be built with Visual Studio 2019+ for the best compatibility. The required set of components are provided in the below file:
-
Visual Studio 2019 with imported components: VS19Components
-
Powershell: To build SqlClient on Linux, powershell is needed as well. Follow the distro specific instructions at Install Powershell on Linux
Once the environment is setup properly, execute the desired set of commands below from the root folder to perform the respective operations:
Building the driver
# Default Build Configuration:
msbuild
# Builds the driver for the Client OS in 'Debug' Configuration for 'AnyCPU' platform.
# Both .NET Framework (NetFx) and .NET (CoreFx) drivers are built by default (as supported by Client OS).
msbuild -t:clean
# Cleans all build directories.
msbuild -p:Configuration=Release
# Builds the driver in 'Release' Configuration for `AnyCPU` platform.
msbuild -t:restore
# Restores Nuget Packages.
msbuild -t:BuildAllConfigurations
# Builds the driver for all target OSes and supported platforms.
msbuild -p:BuildNetFx=false
# Skips building the .NET Framework (NetFx) Driver on Windows.
# On Unix the netfx driver build is automatically skipped.
msbuild -p:OSGroup=Unix
# Builds the driver for the Unix platform.
msbuild -t:BuildNetCoreAllOS
# Builds the .NET driver for all Operating Systems.
Building Tests
msbuild -t:BuildTestsNetCore
# Build the tests for the .NET driver in 'Debug' Configuration. Default .NET version is 6.0.
msbuild -t:BuildTestsNetFx
# Build the tests for the .NET Framework (NetFx) driver in 'Debug' Configuration. Default .NET Framework version is 4.6.2.
msbuild -t:BuildTestsNetCore -p:TestSet=1
# Build a subset of the manual tests. Valid values: '1', '2', '3', 'AE'. Omit to build all tests.
Running Tests
There are 2 ways to run tests, using MsBuild or Dotnet SDK.
Running from Build.proj
msbuild -t:RunFunctionalTests
# Run all functional tests in Debug configuration for *default* target framework (.NET 6.0).
msbuild -t:RunManualTests
# Run all manual tests in Debug configuration for *default* target framework (.NET 6.0).
msbuild -t:RunTests -p:configuration=Release
# Run both functional and manual tests in Release configuration for *default* target framework (.NET 6.0).
msbuild -t:RunTests -p:configuration=Release -p:DotnetPath=C:\net6-win-x86\
# Run both functional and manual tests in Release configuration for *default* target framework (.NET 6.0) against the installed dotnet tool in the provided path.
To specify custom target framework, use TF
property:
msbuild -t:RunTests -p:configuration=Release -p:TF=net8.0
msbuild -t:RunTests -p:configuration=Release -p:TF=net48
# Runs tests for specified target framework.
# TargetNetCoreVersion and TargetNetFxVersion are not to be used with TF property, they will take precedence over TF if provided.
To capture test and code coverage results in a custom directory:
msbuild -t:RunTests -p:ResultsDirectory=MyDirectory
# Runs tests with test and code coverage results placed in provided results directory.
# Default results directory is "TestResults".
Other properties can be set alongside as needed.
Running using Dotnet SDK (traditional)
Run Functional Tests
- Windows (
netfx x86
):
dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="x86" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
- Windows (
netfx x64
):
dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="x64" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
-
AnyCPU:
Project reference only builds Driver with
AnyCPU
platform, and underlying process decides to run the tests with a compatible architecture (x64, x86, ARM64).Windows (
netcoreapp
):
dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests"
Unix (netcoreapp
):
dotnet test "src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
Run Manual Tests
Pre-Requisites for running Manual tests
Manual Tests require the below setup to run:
- SQL Server with enabled Shared Memory, TCP and Named Pipes Protocols and access to the Client OS.
- Databases "NORTHWIND" and "UdtTestDb" present in SQL Server, created using SQL scripts createNorthwindDb.sql and createUdtTestDb.sql. To setup an Azure Database with "NORTHWIND" tables, use SQL Script: createNorthwindAzureDb.sql.
- Make a copy of the configuration file config.default.json and rename it to
config.json
. Update the values inconfig.json
:Property Description Value TCPConnectionString Connection String for a TCP enabled SQL Server instance. Server={servername};Database={Database_Name};Trusted_Connection=True;
ORData Source={servername};Initial Catalog={Database_Name};Integrated Security=True;
NPConnectionString Connection String for a Named Pipes enabled SQL Server instance. Server=\\{servername}\pipe\sql\query;Database={Database_Name};Trusted_Connection=True;
OR
Data Source=np:{servername};Initial Catalog={Database_Name};Integrated Security=True;
TCPConnectionStringHGSVBS (Optional) Connection String for a TCP enabled SQL Server with Host Guardian Service (HGS) attestation protocol configuration. Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = HGS; Enclave Attestation Url = {AttestationURL};
TCPConnectionStringNoneVBS (Optional) Connection String for a TCP enabled SQL Server with a VBS Enclave and using None Attestation protocol configuration. Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = NONE;
TCPConnectionStringAASSGX (Optional) Connection String for a TCP enabled SQL Server with a SGX Enclave and using Microsoft Azure Attestation (AAS) attestation protocol configuration. Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = AAS; Enclave Attestation Url = {AttestationURL};
EnclaveEnabled Enables tests requiring an enclave-configured server. TracingEnabled Enables EventSource related tests AADAuthorityURL (Optional) Identifies the OAuth2 authority resource for Server
specified inAADPasswordConnectionString
https://login.windows.net/<tenant>
, where<tenant>
is the tenant ID of the Azure Active Directory (Azure AD) tenantAADPasswordConnectionString (Optional) Connection String for testing Azure Active Directory Password Authentication. Data Source={server.database.windows.net}; Initial Catalog={Azure_DB_Name};Authentication=Active Directory Password; User ID={AAD_User}; Password={AAD_User_Password};
AADSecurePrincipalId (Optional) The Application Id of a registered application which has been granted permission to the database defined in the AADPasswordConnectionString. {Application ID} AADSecurePrincipalSecret (Optional) A Secret defined for a registered application which has been granted permission to the database defined in the AADPasswordConnectionString. {Secret} AzureKeyVaultURL (Optional) Azure Key Vault Identifier URL https://{keyvaultname}.vault.azure.net/
AzureKeyVaultTenantId (Optional) The Azure Active Directory tenant (directory) Id of the service principal. {Tenant ID of Active Directory} SupportsIntegratedSecurity (Optional) Whether or not the USER running tests has integrated security access to the target SQL Server. true
ORfalse
LocalDbAppName (Optional) If Local Db Testing is supported, this property configures the name of Local DB App instance available in client environment. Empty string value disables Local Db testing. Name of Local Db App to connect to. LocalDbSharedInstanceName (Optional) If LocalDB testing is supported and the instance is shared, this property configures the name of the shared instance of LocalDB to connect to. Name of shared instance of LocalDB. FileStreamDirectory (Optional) If File Stream is enabled on SQL Server, pass local directory path to be used for setting up File Stream enabled database. D:\\escaped\\absolute\\path\\to\\directory\\
UseManagedSNIOnWindows (Optional) Enables testing with Managed SNI on Windows true
ORfalse
DNSCachingConnString Connection string for a server that supports DNS Caching EnclaveAzureDatabaseConnString (Optional) Connection string for Azure database with enclaves ManagedIdentitySupported (Optional) When set to false
Managed Identity related tests won't run. The default value istrue
.IsManagedInstance (Optional) When set to true
TVP related tests will use on non-Azure bs files to compare test results. this is needed when testing against Managed Instances or TVP Tests will fail on Test set 3. The default value isfalse
.PowerShellPath The full path to PowerShell.exe. This is not required if the path is present in the PATH environment variable. D:\\escaped\\absolute\\path\\to\\PowerShell.exe
Commands to run Manual Tests
- Windows (
netfx x86
):
dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="x86" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
- Windows (
netfx x64
):
dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="x64" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
- Windows (
netfx
):
dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
- Windows (
netcoreapp
):
dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests"
- Unix (
netcoreapp
):
dotnet test "src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
Run A Single Test
dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "FullyQualifiedName=Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted.CspProviderExt.TestKeysFromCertificatesCreatedWithMultipleCryptoProviders"
Testing with Custom ReferenceType
Tests can be built and run with custom "Reference Type" property that enables different styles of testing:
- "Project" => Build and run tests with Microsoft.Data.SqlClient as Project Reference
- "Package" => Build and run tests with Microsoft.Data.SqlClient as Package Reference with configured "TestMicrosoftDataSqlClientVersion" in "Versions.props" file.
************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" REFERENCE TYPE *************** CREATE A NUGET PACKAGE WITH BELOW COMMAND AND ADD TO LOCAL FOLDER + UPDATE NUGET CONFIG FILE TO READ FROM THAT LOCATION
msbuild -p:configuration=Release
A non-AnyCPU platform reference can only be used with package reference type. Otherwise, the specified platform will be replaced with AnyCPU in the build process.
Building Tests with Reference Type
For .NET, all 4 reference types are supported:
msbuild -t:BuildTestsNetCore -p:ReferenceType=Project
# Default setting uses Project Reference.
msbuild -t:BuildTestsNetCore -p:ReferenceType=Package
For .NET Framework, below reference types are supported:
msbuild -t:BuildTestsNetFx -p:ReferenceType=Project
# Default setting uses Project Reference.
msbuild -t:BuildTestsNetFx -p:ReferenceType=Package
Running Tests with Reference Type
Provide property to dotnet test
commands for testing desired reference type.
dotnet test -p:ReferenceType=Project ...
Testing with Custom TargetFramework (traditional)
Tests can be built and run with custom Target Frameworks. See the below examples.
Building Tests with custom target framework
msbuild -t:BuildTestsNetFx -p:TargetNetFxVersion=net462
# Build the tests for custom TargetFramework (.NET Framework)
# Applicable values: net462 (Default) | net47 | net471 net472 | net48 | net481
msbuild -t:BuildTestsNetCore -p:TargetNetCoreVersion=net6.0
# Build the tests for custom TargetFramework (.NET)
# Applicable values: net6.0 | net8.0
Running Tests with custom target framework (traditional)
dotnet test -p:TargetNetFxVersion=net462 ...
# Use above property to run Functional Tests with custom TargetFramework (.NET Framework)
# Applicable values: net462 (Default) | net47 | net471 net472 | net48 | net481
dotnet test -p:TargetNetCoreVersion=net6.0 ...
# Use above property to run Functional Tests with custom TargetFramework (.NET)
# Applicable values: net6.0 | net8.0
Using Managed SNI on Windows
Managed SNI can be enabled on Windows by enabling the below AppContext switch:
Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows
Set truncation on for scaled decimal parameters
Scaled decimal parameter truncation can be enabled by enabling the below AppContext switch:
Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal
Enabling row version null behavior
SqlDataReader
returns a DBNull
value instead of an empty byte[]
. To enable the legacy behavior, you must enable the following AppContext switch on application startup:
Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior
Suppressing TLS security warning
When connecting to a server, if a protocol lower than TLS 1.2 is negotiated, a security warning is output to the console. This warning can be suppressed on SQL connections with Encrypt = false
by enabling the following AppContext switch on application startup:
Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning
Debugging SqlClient on Linux from Windows
For enhanced developer experience, we support debugging SqlClient on Linux from Windows, using the project "Microsoft.Data.SqlClient.DockerLinuxTest" that requires "Container Tools" to be enabled in Visual Studio. You may import configuration: VS19Components.vsconfig if not enabled already.
This project is also included in docker-compose.yml
to demonstrate connectivity with SQL Server docker image.
To run the same:
-
Build the Solution in Visual Studio
-
Set
docker-compose
as Startup Project -
Run "Docker-Compose" launch configuration.
-
You will see similar message in Debug window:
Connected to SQL Server v15.00.4023 from Unix 4.19.76.0 The program 'dotnet' has exited with code 0 (0x0).
-
Now you can write code in Program.cs to debug SqlClient on Linux!
Troubleshooting Docker issues
There may be times where connection cannot be made to SQL Server, we found below ideas helpful:
-
Clear Docker images to create clean image from time-to-time, and clear docker cache if needed by running
docker system prune
in Command Prompt. -
If you face
Microsoft.Data.SqlClient.SNI.dll not found
errors when debugging, try updating the below properties in the netcore\Microsoft.Data.SqlClient.csproj file and try again:<OSGroup>Unix</OSGroup> <TargetsWindows>false</TargetsWindows> <TargetsUnix>true</TargetsUnix>
Collecting Code Coverage
Using VSTest
dotnet test <test_properties...> --collect:"Code Coverage"
Using Coverlet Collector
dotnet test <test_properties...> --collect:"XPlat Code Coverage"
Run Performance Tests
Running Performance test project directly
Project location from Root: src\Microsoft.Data.SqlClient\tests\PerformanceTests\Microsoft.Data.SqlClient.PerformanceTests.csproj
Configure runnerconfig.json
file with connection string and preferred settings to run Benchmark Jobs.
cd src\Microsoft.Data.SqlClient\tests\PerformanceTests
dotnet run -c Release -f net6.0|net8.0
Only "Release Configuration" applies to Performance Tests