Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 45 additions & 117 deletions .pipelines/mssql-pipelines.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# MsSql Integration Testing Pipeline config is split into two jobs:
# 1) LinuxTests -> Run SQL Server 2019 in Linux Docker Image
# 2) WindowsTests -> Run LocalDB preinstalled on machine
# MsSql Integration Testing Pipeline config is split into parallel jobs:
# 1) linux (disabled) -> Run SQL Server 2019 in Linux Docker Image
# 2) windows_combined -> GraphQL, REST, Unit, HotReload, OpenApi, Auth, Telemetry, Caching on LocalDB
# 3) windows_configuration -> Configuration tests on LocalDB (with schema init)

trigger:
batch: true
Expand Down Expand Up @@ -151,7 +152,19 @@ jobs:
summaryFileLocation: '$(Agent.TempDirectory)/**/*cobertura.xml'


- job: windows
# MsSql Integration Testing is split into two parallel jobs (~20 min each):
#
# 1) windows_combined -> GraphQL, HotReload, REST, Unit, OpenApi, Auth,
# Telemetry, and Caching tests.
# SqlTestBase-inheriting tests (GraphQL, REST) create the DB schema;
# the remaining tests find it already in place.
#
# 2) windows_configuration -> Pure ConfigurationTests.
# No SqlTestBase tests in this bucket, so initDbSchema creates the
# schema via SqlClient before tests run.

- job: windows_combined
displayName: 'Windows - Combined Integration Tests'
pool:
vmImage: 'windows-latest'
variables:
Expand All @@ -167,117 +180,32 @@ jobs:
SqlVersionCode: '15.0'

steps:
- task: CmdLine@2
displayName: 'Set flag to publish received files when previous step fails'
condition: failed()
inputs:
script: 'echo ##vso[task.setvariable variable=publishverify]Yes'

- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'

# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
# specifying the runtime version a project targets."
- task: UseDotNet@2
displayName: Setup .NET SDK v8.0.x
inputs:
packageType: sdk
version: 8.0.x

- task: NuGetToolInstaller@1

- task: DotNetCoreCLI@2
displayName: Restore NuGet packages
inputs:
command: restore
projects: '$(solution)'
feedsToUse: config
nugetConfigPath: Nuget.config
restoreArguments: '/p:RuntimeIdentifiers=""'

- task: PowerShell@2
displayName: Install SQL LocalDB
inputs:
targetType: 'inline'
script: |
SqlLocalDb.exe start
SqlLocalDB.exe info "MSSQLLocalDB"
Write-Host "Downloading"
Import-Module BitsTransfer
Start-BitsTransfer -Source $(InstallerUrl) -Destination SqlLocalDB.msi
Write-Host "Installing"
Start-Process -FilePath "SqlLocalDB.msi" -Wait -ArgumentList "/qn", "/norestart", "/l*v SqlLocalDBInstall.log", "IACCEPTSQLLOCALDBLICENSETERMS=YES";
SqlLocalDB.exe stop MSSQLLocalDB -k
SqlLocalDB.exe delete MSSQLLocalDB

- task: PowerShell@2
displayName: 'Start MSSQLLocalDB'
inputs:
targetType: 'inline'
script: |
SqlLocalDb.exe start MSSQLLocalDB
SqlLocalDb.exe info "MSSQLLocalDB"

- task: DotNetCoreCLI@2
displayName: Build
inputs:
command: build
projects: |
**/*.csproj
!**/*Tests*.csproj
arguments: '-p:generateConfigFileForDbType=MsSql --configuration $(buildConfiguration)' # Update this to match your need

- task: DotNetCoreCLI@2
displayName: Build Test Projects
inputs:
command: build
projects: '**/*Tests/*.csproj'
arguments: '--configuration $(buildConfiguration)'

- task: FileTransform@1.206.0
displayName: 'Generate dab-config.MsSql.json'
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
fileType: 'json'
targetFiles: 'src/out/tests/*/dab-config.MsSql.json'

- task: DotNetCoreCLI@2
displayName: 'MsSql Integration Tests'
inputs:
command: test
arguments: '--filter "TestCategory=MsSql&FullyQualifiedName!~ConfigurationHotReloadTests" --no-build --configuration $(buildConfiguration) --collect "XPlat Code coverage"'
projects: '**/*Tests/*.csproj'


- task: DotNetCoreCLI@2
displayName: 'Hot-Reload Tests'
inputs:
command: test
arguments: '--filter "TestCategory=MsSql&FullyQualifiedName~ConfigurationHotReloadTests" --no-build --configuration $(buildConfiguration) --collect "XPlat Code coverage" --logger "console;verbosity=detailed"'
projects: '**/*Tests/*.csproj'
timeoutInMinutes: 45

- task: PublishCodeCoverageResults@1
displayName: 'Publish code coverage'
inputs:
codeCoverageTool: Cobertura
summaryFileLocation: '$(Agent.TempDirectory)/**/*cobertura.xml'

- task: CopyFiles@2
condition: eq(variables['publishverify'], 'Yes')
displayName: 'Copy received files to Artifact Staging'
inputs:
contents: '**\*.received.*'
targetFolder: '$(Build.ArtifactStagingDirectory)\Verify'
cleanTargetFolder: true
overWrite: true
- template: templates/mssql-test-steps.yml
parameters:
testFilter: 'TestCategory=MsSql&(FullyQualifiedName~SqlTests.GraphQL|FullyQualifiedName~ConfigurationHotReloadTests|FullyQualifiedName~SqlTests.Rest|FullyQualifiedName~UnitTests|FullyQualifiedName~OpenApi|FullyQualifiedName~Telemetry|FullyQualifiedName~Authorization|FullyQualifiedName~Caching)'
testDisplayName: 'MsSql Combined Integration Tests'
artifactSuffix: '-Combined'

- job: windows_configuration
displayName: 'Windows - Configuration Tests'
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
# Need to override the connection string set on the pipeline UI
# since windows needs a different string.
# The variable setting on the pipeline UI sets the connection string
# for the linux job above.
data-source.connection-string: Server=(localdb)\MSSQLLocalDB;Persist Security Info=False;Integrated Security=True;MultipleActiveResultSets=False;Connection Timeout=30;TrustServerCertificate=True;
InstallerUrl: https://download.microsoft.com/download/7/c/1/7c14e92e-bdcb-4f89-b7cf-93543e7112d1/SqlLocalDB.msi
SqlVersionCode: '15.0'

- task: PublishBuildArtifacts@1
displayName: 'Publish received files as Artifacts'
name: 'verifypublish'
condition: eq(variables['publishverify'], 'Yes')
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)\Verify'
ArtifactName: 'Verify'
publishLocation: 'Container'
steps:
- template: templates/mssql-test-steps.yml
parameters:
testFilter: 'TestCategory=MsSql&FullyQualifiedName!~SqlTests.GraphQL&FullyQualifiedName!~ConfigurationHotReloadTests&FullyQualifiedName!~SqlTests.Rest&FullyQualifiedName!~UnitTests&FullyQualifiedName!~OpenApi&FullyQualifiedName!~Telemetry&FullyQualifiedName!~Authorization&FullyQualifiedName!~Caching'
testDisplayName: 'MsSql Configuration Tests'
artifactSuffix: '-Configuration'
initDbSchema: true
160 changes: 160 additions & 0 deletions .pipelines/templates/mssql-test-steps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# Common setup and test execution steps for MSSQL integration test jobs.
# Used by mssql-pipelines.yml to run parallel test jobs.

parameters:
- name: testFilter
type: string
- name: testDisplayName
type: string
default: 'MsSql Integration Tests'
- name: testTimeout
type: number
default: 0
- name: additionalTestArgs
type: string
default: ''
- name: artifactSuffix
type: string
default: ''
- name: initDbSchema
type: boolean
default: false

steps:
- task: CmdLine@2
displayName: 'Set flag to publish received files'
inputs:
script: 'echo ##vso[task.setvariable variable=publishverify]Yes'

- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'

# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
# specifying the runtime version a project targets."
- task: UseDotNet@2
displayName: Setup .NET SDK v8.0.x
inputs:
packageType: sdk
version: 8.0.x

- task: NuGetToolInstaller@1

- task: DotNetCoreCLI@2
displayName: Restore NuGet packages
inputs:
command: restore
projects: '$(solution)'
feedsToUse: config
nugetConfigPath: Nuget.config
restoreArguments: '/p:RuntimeIdentifiers=""'

- task: PowerShell@2
displayName: Install SQL LocalDB
inputs:
targetType: 'inline'
script: |
SqlLocalDb.exe start
SqlLocalDB.exe info "MSSQLLocalDB"
Write-Host "Downloading"
Import-Module BitsTransfer
Start-BitsTransfer -Source $(InstallerUrl) -Destination SqlLocalDB.msi
Write-Host "Installing"
Start-Process -FilePath "SqlLocalDB.msi" -Wait -ArgumentList "/qn", "/norestart", "/l*v SqlLocalDBInstall.log", "IACCEPTSQLLOCALDBLICENSETERMS=YES";
SqlLocalDB.exe stop MSSQLLocalDB -k
SqlLocalDB.exe delete MSSQLLocalDB

- task: PowerShell@2
displayName: 'Start MSSQLLocalDB'
inputs:
targetType: 'inline'
script: |
SqlLocalDb.exe start MSSQLLocalDB
SqlLocalDb.exe info "MSSQLLocalDB"

- ${{ if eq(parameters.initDbSchema, true) }}:
- task: PowerShell@2
displayName: 'Initialize database schema'
inputs:
targetType: 'inline'
script: |
Write-Host "Running DatabaseSchema-MsSql.sql against LocalDB via SqlClient..."
$sqlFile = "$(System.DefaultWorkingDirectory)\src\Service.Tests\DatabaseSchema-MsSql.sql"
$sql = Get-Content $sqlFile -Raw
$connStr = "Server=(localdb)\MSSQLLocalDB;Integrated Security=True;TrustServerCertificate=True;Connection Timeout=30;"
$connection = New-Object System.Data.SqlClient.SqlConnection($connStr)
try {
$connection.Open()
Write-Host "Connected to LocalDB successfully."
$command = $connection.CreateCommand()
$command.CommandText = $sql
$command.CommandTimeout = 120
$command.ExecuteNonQuery() | Out-Null
Write-Host "Database schema initialized successfully."
}
catch {
Write-Error "Schema initialization failed: $_"
throw
}
finally {
$connection.Close()
}

- task: DotNetCoreCLI@2
displayName: Build
inputs:
command: build
projects: |
**/*.csproj
!**/*Tests*.csproj
arguments: '-p:generateConfigFileForDbType=MsSql --configuration $(buildConfiguration)' # Update this to match your need

- task: DotNetCoreCLI@2
displayName: Build Test Projects
inputs:
command: build
projects: '**/*Tests/*.csproj'
arguments: '--configuration $(buildConfiguration)'

- task: FileTransform@1.206.0
displayName: 'Generate dab-config.MsSql.json'
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
fileType: 'json'
targetFiles: 'src/out/tests/*/dab-config.MsSql.json'

- task: DotNetCoreCLI@2
displayName: '${{ parameters.testDisplayName }}'
inputs:
command: test
arguments: '--filter "${{ parameters.testFilter }}" --no-build --configuration $(buildConfiguration) --collect "XPlat Code coverage" ${{ parameters.additionalTestArgs }}'
projects: '**/*Tests/*.csproj'
${{ if ne(parameters.testTimeout, 0) }}:
timeoutInMinutes: ${{ parameters.testTimeout }}

- task: PublishCodeCoverageResults@1
displayName: 'Publish code coverage'
inputs:
codeCoverageTool: Cobertura
summaryFileLocation: '$(Agent.TempDirectory)/**/*cobertura.xml'

- task: CopyFiles@2
condition: eq(variables['publishverify'], 'Yes')
displayName: 'Copy received files to Artifact Staging'
inputs:
contents: '**\*.received.*'
targetFolder: '$(Build.ArtifactStagingDirectory)\Verify'
cleanTargetFolder: true
overWrite: true

- task: PublishBuildArtifacts@1
displayName: 'Publish received files as Artifacts'
name: 'verifypublish'
condition: eq(variables['publishverify'], 'Yes')
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)\Verify'
ArtifactName: 'Verify${{ parameters.artifactSuffix }}'
publishLocation: 'Container'
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Azure.DataApiBuilder.Service.Tests.UnitTests
/// can handle a wide range of valid formats correctly,
/// and throws exceptions for invalid formats as expected.
/// </summary>
[TestClass, TestCategory(TestCategory.MSSQL)]
[TestClass]
public class EntitySourceNamesParserUnitTests
{

Expand Down
2 changes: 1 addition & 1 deletion src/Service.Tests/UnitTests/RequestContextUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Azure.DataApiBuilder.Service.Tests.UnitTests
/// Context classes that are not easily tested through
/// integration testing.
/// </summary>
[TestClass, TestCategory(TestCategory.MSSQL)]
[TestClass]
public class RequestContextUnitTests
{
private static DatabaseObject _defaultDbObject = new DatabaseTable()
Expand Down
2 changes: 1 addition & 1 deletion src/Service.Tests/UnitTests/RequestValidatorUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace Azure.DataApiBuilder.Service.Tests.UnitTests
/// Unit tests for RequestValidator.cs. Makes sure the proper primary key validation
/// occurs for REST requests for FindOne().
/// </summary>
[TestClass, TestCategory(TestCategory.MSSQL)]
[TestClass]
public class RequestValidatorUnitTests
{
private static Mock<ISqlMetadataProvider> _mockMetadataStore;
Expand Down
2 changes: 1 addition & 1 deletion src/Service.Tests/UnitTests/RestServiceUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

namespace Azure.DataApiBuilder.Service.Tests.UnitTests
{
[TestClass, TestCategory(TestCategory.MSSQL)]
[TestClass]
public class RestServiceUnitTests
{
private static RestService _restService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace Azure.DataApiBuilder.Service.Tests.UnitTests
/// we throw the right exception when environment
/// variable names are not found.
/// </summary>
[TestClass, TestCategory(TestCategory.MSSQL)]
[TestClass]
public class RuntimeConfigLoaderJsonDeserializerTests
{
#region Positive Tests
Expand Down
Loading