Skip to content

Latest commit

 

History

History
376 lines (272 loc) · 17.3 KB

File metadata and controls

376 lines (272 loc) · 17.3 KB

Guidelines for Building Microsoft.Data.SqlClient

This document provides all the necessary details to build the driver and run tests present in the repository.

Prerequisites

.NET SDK

The projects in this repo require the .NET 10.0 SDK to build. Please ensure you have the latest version of that SDK installed.

Tests and tools may require different .NET Runtimes that may be installed independently. For example, tests targeting .NET 8.0 will need that runtime installed.

Visual Studio

This project should be built with Visual Studio 2019+ for the best compatibility. The required set of components are provided in the below file:

Once the environment is setup properly, execute the desired set of commands below from the root folder to perform the respective operations:

Manual Test Prerequisites

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 in config.json:

    Property Description Value
    TCPConnectionString Connection String for a TCP enabled SQL Server instance. Server={servername};Database={Database_Name};Trusted_Connection=True;
    OR Data 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 in AADPasswordConnectionString https://login.windows.net/<tenant>, where <tenant> is the tenant ID of the Entra ID (Azure AD) tenant
    AADPasswordConnectionString (Optional) Connection String for testing Entra ID 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 Entra ID 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 OR false
    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 OR false
    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 is true.
    IsManagedInstance (Optional) When set to true TVP related tests will use non-Azure bsl files to compare test results. This is needed when testing against Azure Managed Instances; otherwise TVP Tests will fail on TestSet 3. The default value is false.
    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

MSBuild Reference

Targets

The following build targets are defined in build.proj:

Target Description
BuildAbstractions Restore and build the Abstractions package.
BuildAkvProvider Builds the Azure Key Vault Provider package for all supported platforms.
BuildAllConfigurations Default target. Builds the .NET Framework and .NET drivers for all target frameworks and operating systems.
BuildAzure Restore and build the Azure package.
BuildLogging Restore and build the Logging package.
BuildNetCore Builds the .NET driver for all target frameworks.
BuildNetCoreAllOS Builds the .NET driver for all target frameworks and operating systems.
BuildNetFx Builds the .NET Framework driver for all target frameworks.
BuildSqlClient Build the driver for all target frameworks.
Clean Cleans all generated files.
PackAbstractions Pack the Abstractions NuGet package into packages/. Requires BuildAbstractions first.
PackAkvProvider Pack the Azure Key Vault Provider NuGet package (requires a prior build).
PackAzure Pack the Azure NuGet package into packages/. Requires BuildAzure first.
PackLogging Pack the Logging NuGet package into packages/. Requires BuildLogging first.
Restore Restores NuGet packages.
RunTests Runs the unit, functional, and manual tests for the .NET Framework and .NET drivers
RunUnitTests Runs just the unit tests for the .NET Framework and .NET drivers
RunFunctionalTests Runs just the functional tests for the .NET Framework and .NET drivers
RunManualTests Runs just the manual tests for the .NET Framework and .NET drivers

Parameters

The following parameters may be defined as MSBuild properties to configure the build:

Name Supported Values Default Description
Configuration Debug, Release Debug Sets the release configuration.
OSGroup Unix, Windows_NT, AnyOS typically defaults to the client system's OS, unless using BuildAllConfigurations or an AnyOS specific target The operating system to target.
Platform AnyCPU, x86, x64, ARM, ARM64 AnyCPU May only be set when using package reference type or running tests.
TestSet 1, 2, 3, AE, or any combination thereof '' Build or run a subset of the manual tests. Omit (default) to run all tests.
DotnetPath Absolute file path to an installed dotnet version. The system default specified by the path variable Set to run tests using a specific dotnet version (e.g. C:\net6-win-x86)
TF net8.0, net462, net47, net471, net472, net48, net481 net9.0 in netcore, net462 in netfx Sets the target framework when building or running tests. Not applicable when building the drivers.
ResultsDirectory An absolute file path ./TestResults relative to current directory Specifies where to write test results.

Example Commands to Run Tests Using MSBuild (Recommended)

Using the default configuration and running all tests:

msbuild -t:RunTests

Using the Release configuration:

msbuild -t:RunTests -p:Configuration=Release

Running only the unit tests:

msbuild -t:RunUnitTests

Using a specific .NET runtime to run tests:

msbuild -t:RunTests -p:DotnetPath=C:\net8-win-x86\

To run tests against a specific version of .NET/.NET Framework, set the -p:TF parameter.

msbuild -t:RunTests -p:TF=net8.0
msbuild -t:RunTests -p:TF=net462

Example Commands to Run Tests using dotnet

Under the hood, the MSBuild commands to run tests use dotnet commands. But, if you wish to run them without the overhead of wrapping/unwrapping in MSBuild, you can run them directly.

To change the processor architecture that runs the test (where possible, ie, x86 on x64), use the appropriate dotnet executable.

By default, the tests will be executed on all supported .NET/.NET framework versions. To run on a specific version, pass the -f parameter with the desired version (eg net9.0).

The --filter parameter is used to select which tests run. The default category!=failing& category!=flaky&category!=interactive prevents tests that are known to be failing or flaky from running. To run a specific test, use FullyQualifiedName=[fully qualified name of the test method] as the filter parameter. To run all possible tests, even known failing and flaky ones, simply omit the filter parameter. Please note, however, that this will still omit tests that cannot run on the current platform or with the current test configuration (eg, Windows tests on Linux, or SQL DB tests when Azure Synapse is configured).

Run Functional Tests

dotnet test "src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj" \
  -p:Configuration=Release \
  --filter "category!=failing&category!=flaky&category!=interactive"

Run Manual Tests

dotnet test "src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj" \
  -p:Configuration=Release \
  --filter "category!=failing&category!=flaky&category!=interactive"

Run Unit Tests

dotnet test "src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj" \
  -p:Configuration=Release \
  --filter "category!=failing&category!=flaky&category!=interactive"

Testing with Package References

The MDS driver consists of several components, each of which produces its own NuGet package. During development, components reference each other via <ProjectReference> properties by default. This means that building and testing one component will implicitly build its project referenced dependencies.

Alternatively, the ReferenceType build property may be specified with a value of Package. This will change inter-component dependencies to use <PackageReference> dependencies, and require that dependent components be built and packaged before building the depending component. This will generate NuGet packages in the root packages/ directory, and will be automatically searched by NuGet (see our root NuGet.config).

Then, you can specify Package references be used, for example:

dotnet build -t:BuildLogging,PackLogging
dotnet build -t:BuildSqlServer,PackSqlServer
dotnet build -t:BuildAbstractions,PackAbstractions -p:ReferenceType=Package
dotnet build -t:BuildAzure,PackAzure -p:ReferenceType=Package
dotnet build -t:BuildSqlClient -p:ReferenceType=Package
dotnet build -t:GenerateMdsPackage
dotnet build -t:BuildAKVNetCore -p:ReferenceType=Package
dotnet build -t:GenerateAkvPackage

The above will build the MDS and AKV components, place their NuGet packages into the packages/ directory.

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.

Running Tests with Reference Type

Provide property to dotnet test commands for testing desired reference type.

dotnet test -p:ReferenceType=Project ...

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

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

The performance tests live here: src\Microsoft.Data.SqlClient\tests\PerformanceTests\

They can be run from the command line by following the instructions below.

Launch a shell and change into the project directory:

PowerShell:

> cd src\Microsoft.Data.SqlClient\tests\PerformanceTests

Bash:

$ cd src/Microsoft.Data.SqlClient/tests/PerformanceTests

Create Database

Create an empty database for the benchmarks to use. This example assumes a local SQL server instance using SQL authentication:

$ sqlcmd -S localhost -U sa -P password
1> create database [sqlclient-perf-db]
2> go
1> quit

The default runnerconfig.json expects a database named sqlclient-perf-db, but you may change the config to use any existing database. All tables in the database will be dropped when running the benchmarks.

Configure Runner

Configure the benchmarks by editing the runnerconfig.json file directly in the PerformanceTests directory with an appropriate connection string and benchmark settings:

{
  "ConnectionString": "Server=tcp:localhost; Integrated Security=true; Initial Catalog=sqlclient-perf-db;",
  "UseManagedSniOnWindows": false,
  "Benchmarks":
  {
    "SqlConnectionRunnerConfig":
    {
      "Enabled": true,
      "LaunchCount": 1,
      "IterationCount": 50,
      "InvocationCount":30,
      "WarmupCount": 5,
      "RowCount": 0
    },
    ...
  }
}

Individual benchmarks may be enabled or disabled, and each has several benchmarking options for fine tuning.

After making edits to runnerconfig.json you must perform a build which will copy the file into the artifacts directory alongside the benchmark DLL. By default, the benchmarks look for runnerconfig.json in the same directory as the DLL.

Optionally, to avoid polluting your git workspace and requring a build after each config change, copy runnerconfig.json to a new file, make your edits there, and then specify the new file with the RUNNER_CONFIG environment variable.

PowerShell:

> copy runnerconfig.json $HOME\.configs\runnerconfig.json

# Make edits to $HOME\.configs\runnerconfig.json

# You must set the RUNNER_CONFIG environment variable for the current shell.
> $env:RUNNER_CONFIG="${HOME}\.configs\runnerconfig.json"

Bash:

$ cp runnerconfig.json ~/.configs/runnerconfig.json

# Make edits to ~/.configs/runnerconfig.json

# Optionally export RUNNER_CONFIG.
$ export RUNNER_CONFIG=~/.configs/runnerconfig.json

Run Benchmarks

All benchmarks must be compiled and run in Release configuration.

PowerShell:

> dotnet run -c Release -f net9.0

Bash:

# Omit RUNNER_CONFIG if you exported it earlier, or if you're using the
# copy prepared by the build.
$ dotnet run -c Release -f net9.0

$ RUNNER_CONFIG=~/.configs/runnerconfig.json dotnet run -c Release -f net9.0