Add Code coverage to Azure Pipelines BVTs (#607)

Collects code coverage on the BVTs and SpinQuic.

Co-authored-by: Nick Banks <nibanks@microsoft.com>
This commit is contained in:
Anthony Rossi 2020-07-22 22:39:05 -07:00 коммит произвёл GitHub
Родитель 10558482e2
Коммит e6cd704a90
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
12 изменённых файлов: 388 добавлений и 26 удалений

Просмотреть файл

@ -187,6 +187,35 @@ stages:
extraArgs: -Kernel extraArgs: -Kernel
kernel: true kernel: true
#
# Code Coverage
#
- stage: codecoverage
displayName: Code Coverage
dependsOn:
- build_windows
jobs:
- template: ./templates/run-bvt.yml
parameters:
pool: MsQuic-Win-Latest
platform: windows
tls: schannel
codeCoverage: true
- template: ./templates/run-spinquic.yml
parameters:
pool: MsQuic-Win-Latest
platform: windows
tls: schannel
codeCoverage: true
- template: ./templates/merge-publish-coverage.yml
parameters:
image: windows-latest
platform: windows
config: Debug
arch: x64
tls: schannel
# #
# SpinQuic Tests # SpinQuic Tests
# #

Просмотреть файл

@ -0,0 +1,48 @@
# This template contains steps to run the BVTs for a single configuration.
parameters:
image: ''
platform: ''
config: ''
arch: ''
tls: ''
jobs:
- job: merge_cc_${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }}
displayName: ${{ parameters.platform }} ${{ parameters.arch }} ${{ parameters.tls }}
dependsOn:
- bvt_${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }}_false_true
- spin_${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }}
condition: or(succeeded(), failed())
pool:
vmImage: ${{ parameters.image }}
variables:
runCodesignValidationInjection: false
steps:
- checkout: self
- task: PowerShell@2
displayName: Prepare Test Machine
inputs:
pwsh: true
filePath: scripts/prepare-machine.ps1
arguments: -Configuration Test
- task: DownloadBuildArtifacts@0
displayName: Download Build Artifacts
inputs:
artifactName: coverage
itemPattern: coverage/${{ parameters.platform }}/${{ parameters.arch }}_${{ parameters.config }}_${{ parameters.tls }}/**/*.cov
downloadPath: artifacts
- task: Powershell@2
displayName: Merge coverage
inputs:
pwsh: true
filePath: scripts/merge-coverage.ps1
arguments: -Config ${{ parameters.config }} -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }}
- task: PublishCodeCoverageResults@1
inputs:
codeCoverageTool: 'cobertura'
summaryFileLocation: '**/artifacts/coverage/**/msquiccoverage.xml'

Просмотреть файл

@ -8,11 +8,12 @@ parameters:
arch: 'x64' arch: 'x64'
tls: '' tls: ''
kernel: false kernel: false
codeCoverage: false
logProfile: 'Basic.Light' logProfile: 'Basic.Light'
extraArgs: '' extraArgs: ''
jobs: jobs:
- job: bvt_${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }}_${{ parameters.kernel }} - job: bvt_${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }}_${{ parameters.kernel }}_${{ parameters.codeCoverage }}
displayName: ${{ parameters.platform }} ${{ parameters.arch }} ${{ parameters.tls }} displayName: ${{ parameters.platform }} ${{ parameters.arch }} ${{ parameters.tls }}
${{ if ne(parameters.pool, '') }}: ${{ if ne(parameters.pool, '') }}:
pool: ${{ parameters.pool }} pool: ${{ parameters.pool }}
@ -51,7 +52,10 @@ jobs:
inputs: inputs:
pwsh: true pwsh: true
filePath: scripts/test.ps1 filePath: scripts/test.ps1
arguments: -NoProgress -IsolationMode Isolated -LogProfile ${{ parameters.logProfile }} -GenerateXmlResults -Config ${{ parameters.config }} -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }} ${{ parameters.extraArgs }} ${{ if eq(parameters.codeCoverage, true) }}:
arguments: -NoProgress -CodeCoverage -Config ${{ parameters.config }} -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }} ${{ parameters.extraArgs }}
${{ if eq(parameters.codeCoverage, false) }}:
arguments: -NoProgress -IsolationMode Isolated -LogProfile ${{ parameters.logProfile }} -GenerateXmlResults -Config ${{ parameters.config }} -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }} ${{ parameters.extraArgs }}
- template: ./upload-test-artifacts.yml - template: ./upload-test-artifacts.yml
parameters: parameters:
@ -59,3 +63,4 @@ jobs:
config: ${{ parameters.config }} config: ${{ parameters.config }}
arch: ${{ parameters.arch }} arch: ${{ parameters.arch }}
tls: ${{ parameters.tls }} tls: ${{ parameters.tls }}
codeCoverage: ${{ parameters.codeCoverage }}

Просмотреть файл

@ -7,6 +7,7 @@ parameters:
config: 'Debug' config: 'Debug'
arch: 'x64' arch: 'x64'
tls: '' tls: ''
codeCoverage: false
jobs: jobs:
- job: spin_${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }} - job: spin_${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }}
@ -47,7 +48,10 @@ jobs:
inputs: inputs:
pwsh: true pwsh: true
filePath: scripts/spin.ps1 filePath: scripts/spin.ps1
arguments: -GenerateXmlResults -Timeout 600000 -RepeatCount 6 -Config ${{ parameters.config }} -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }} ${{ if eq(parameters.codeCoverage, true) }}:
arguments: -CodeCoverage -GenerateXmlResults -Timeout 600000 -RepeatCount 6 -Config ${{ parameters.config }} -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }}
${{ if eq(parameters.codeCoverage, false) }}:
arguments: -GenerateXmlResults -Timeout 600000 -RepeatCount 6 -Config ${{ parameters.config }} -Arch ${{ parameters.arch }} -Tls ${{ parameters.tls }}
- template: ./upload-test-artifacts.yml - template: ./upload-test-artifacts.yml
parameters: parameters:
@ -55,3 +59,4 @@ jobs:
config: ${{ parameters.config }} config: ${{ parameters.config }}
arch: ${{ parameters.arch }} arch: ${{ parameters.arch }}
tls: ${{ parameters.tls }} tls: ${{ parameters.tls }}
codeCoverage: ${{ parameters.codeCoverage }}

Просмотреть файл

@ -5,14 +5,32 @@ parameters:
config: '' config: ''
arch: '' arch: ''
tls: '' tls: ''
codeCoverage: false
steps: steps:
- task: CopyFiles@2 - ${{ if eq(parameters.codeCoverage, true) }}:
displayName: Stage Artifacts - task: CopyFiles@2
inputs: displayName: Stage Coverage
sourceFolder: artifacts/logs inputs:
contents: '**/!(*-results.xml)' sourceFolder: artifacts/coverage
targetFolder: $(Build.ArtifactStagingDirectory)/${{ parameters.platform }}/${{ parameters.arch }}_${{ parameters.config }}_${{ parameters.tls }} contents: '**'
targetFolder: $(Build.ArtifactStagingDirectory)/${{ parameters.platform }}/${{ parameters.arch }}_${{ parameters.config }}_${{ parameters.tls }}
- ${{ if eq(parameters.codeCoverage, true) }}:
- task: PublishBuildArtifacts@1
displayName: Publish Coverage Output
inputs:
artifactName: coverage
pathToPublish: $(Build.ArtifactStagingDirectory)
parallel: true
- ${{ if eq(parameters.codeCoverage, false) }}:
- task: CopyFiles@2
displayName: Stage Artifacts
inputs:
sourceFolder: artifacts/logs
contents: '**/!(*-results.xml)'
targetFolder: $(Build.ArtifactStagingDirectory)/${{ parameters.platform }}/${{ parameters.arch }}_${{ parameters.config }}_${{ parameters.tls }}
- task: PublishTestResults@2 - task: PublishTestResults@2
displayName: 'Publish Test Results' displayName: 'Publish Test Results'
@ -21,10 +39,11 @@ steps:
testResultsFiles: '**/*-results.xml' testResultsFiles: '**/*-results.xml'
failTaskOnFailedTests: true failTaskOnFailedTests: true
- task: PublishBuildArtifacts@1 - ${{ if eq(parameters.codeCoverage, false) }}:
displayName: Publish Test Output - task: PublishBuildArtifacts@1
condition: failed() displayName: Publish Test Output
inputs: condition: failed()
artifactName: logs inputs:
pathToPublish: $(Build.ArtifactStagingDirectory) artifactName: logs
parallel: true pathToPublish: $(Build.ArtifactStagingDirectory)
parallel: true

Просмотреть файл

@ -115,12 +115,12 @@ elseif ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Darwin")
endif() endif()
if (QUIC_CI) if (QUIC_CI)
if (MSVC) #if (MSVC)
file(READ ${CMAKE_CURRENT_LIST_DIR}/cmake/PdbAltPath.txt PDBALTPATH) # file(READ ${CMAKE_CURRENT_LIST_DIR}/cmake/PdbAltPath.txt PDBALTPATH)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PDBALTPATH}") # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PDBALTPATH}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${PDBALTPATH}") # set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${PDBALTPATH}")
message(STATUS ${CMAKE_EXE_LINKER_FLAGS}) # message(STATUS ${CMAKE_EXE_LINKER_FLAGS})
endif() #endif()
if (QUIC_SOURCE_LINK AND MSVC) if (QUIC_SOURCE_LINK AND MSVC)
if ("${CMAKE_C_COMPILER_VERSION}" VERSION_GREATER_EQUAL "19.20") if ("${CMAKE_C_COMPILER_VERSION}" VERSION_GREATER_EQUAL "19.20")

Просмотреть файл

@ -0,0 +1,61 @@
<#
.SYNOPSIS
This script merges the coverage data.
.PARAMETER Config
Specifies the build configuration to test.
.PARAMETER Arch
The CPU architecture to test.
.PARAMETER Tls
The TLS library test.
#>
param (
[Parameter(Mandatory = $false)]
[ValidateSet("Debug", "Release")]
[string]$Config = "Debug",
[Parameter(Mandatory = $false)]
[ValidateSet("x86", "x64", "arm", "arm64")]
[string]$Arch = "x64",
[Parameter(Mandatory = $false)]
[ValidateSet("schannel", "openssl", "stub", "mitls")]
[string]$Tls = ""
)
Set-StrictMode -Version 'Latest'
$PSDefaultParameterValues['*:ErrorAction'] = 'Stop'
# Default TLS based on current platform.
if ("" -eq $Tls) {
if ($IsWindows) {
$Tls = "schannel"
} else {
$Tls = "openssl"
}
}
# Root directory of the project.
$RootDir = Split-Path $PSScriptRoot -Parent
$CoverageDir = Join-Path $RootDir "artifacts\coverage\windows\$($Arch)_$($Config)_$($Tls)"
$CoverageMergeParams = ""
foreach ($file in $(Get-ChildItem -Path $CoverageDir -Filter '*.cov')) {
$CoverageMergeParams += " --input_coverage $(Join-Path $CoverageDir $file.Name)"
}
if ($CoverageMergeParams -ne "") {
$CoverageMergeParams += " --export_type cobertura:$(Join-Path $CoverageDir "msquiccoverage.xml")"
$CoverageExe = 'C:\"Program Files"\OpenCppCoverage\OpenCppCoverage.exe'
Invoke-Expression ($CoverageExe + $CoverageMergeParams) | Out-Null
} else {
Write-Warning "No coverage results to merge!"
}

Просмотреть файл

@ -73,6 +73,31 @@ if ($IsWindows) {
$ToolName = "Microsoft.Logging.CLOG2Text.Windows" $ToolName = "Microsoft.Logging.CLOG2Text.Windows"
$DownloadUrl = "https://github.com/microsoft/CLOG/releases/download/v0.1.2" $DownloadUrl = "https://github.com/microsoft/CLOG/releases/download/v0.1.2"
Install-ClogTool -NuGetName $NuGetName -ToolName $ToolName -DownloadUrl $DownloadUrl Install-ClogTool -NuGetName $NuGetName -ToolName $ToolName -DownloadUrl $DownloadUrl
# Install OpenCppCoverage on test machines
if (!(Test-Path "C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe")) {
Write-Host "[$(Get-Date)] Installing OpenCppCoverage..."
# Download the installer.
$Installer = $null
if ([System.Environment]::Is64BitOperatingSystem) {
$Installer = "OpenCppCoverageSetup-x64-0.9.9.0.exe"
} else {
$Installer = "OpenCppCoverageSetup-x86-0.9.9.0.exe"
}
$ExeFile = Join-Path $Env:TEMP $Installer
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -Uri "https://github.com/OpenCppCoverage/OpenCppCoverage/releases/download/release-0.9.9.0/$($Installer)" -OutFile $ExeFile
# Start the installer and wait for it to finish.
Start-Process $ExeFile -Wait -ArgumentList {"/silent"} -NoNewWindow
# Delete the installer.
Remove-Item -Path $ExeFile
Write-Host "[$(Get-Date)] OpenCppCoverage installed."
}
} }
} else { } else {

Просмотреть файл

@ -36,6 +36,9 @@ This script runs an executable and collects and logs or process dumps as necessa
.Parameter EnableAppVerifier .Parameter EnableAppVerifier
Enables all basic Application Verifier checks on the executable. Enables all basic Application Verifier checks on the executable.
.Parameter CodeCoverage
Collect code coverage for the binary being run.
#> #>
param ( param (
@ -71,7 +74,10 @@ param (
[switch]$ShowOutput = $false, [switch]$ShowOutput = $false,
[Parameter(Mandatory = $false)] [Parameter(Mandatory = $false)]
[switch]$EnableAppVerifier = $false [switch]$EnableAppVerifier = $false,
[Parameter(Mandatory = $false)]
[switch]$CodeCoverage = $false
) )
Set-StrictMode -Version 'Latest' Set-StrictMode -Version 'Latest'
@ -86,6 +92,19 @@ if (!(Test-Path $Path)) {
Write-Error "$($Path) does not exist!" Write-Error "$($Path) does not exist!"
} }
# Validate the code coverage switch
if ($CodeCoverage) {
if (!$IsWindows) {
Write-Error "-CodeCoverage switch only supported on Windows";
}
if ($Debugger) {
Write-Error "-CodeCoverage switch is not supported with debugging";
}
if (!(Test-Path "C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe")) {
Write-Error "Code coverage tools are not installed";
}
}
# Root directory of the project. # Root directory of the project.
$RootDir = Split-Path $PSScriptRoot -Parent $RootDir = Split-Path $PSScriptRoot -Parent
@ -94,11 +113,19 @@ $LogScript = Join-Path $RootDir "scripts" "log.ps1"
# Executable name. # Executable name.
$ExeName = Split-Path $Path -Leaf $ExeName = Split-Path $Path -Leaf
$CoverageName = "$(Split-Path $Path -LeafBase).cov"
# Folder for log files. # Folder for log files.
$LogDir = Join-Path $RootDir "artifacts" "logs" $ExeName (Get-Date -UFormat "%m.%d.%Y.%T").Replace(':','.') $LogDir = Join-Path $RootDir "artifacts" "logs" $ExeName (Get-Date -UFormat "%m.%d.%Y.%T").Replace(':','.')
New-Item -Path $LogDir -ItemType Directory -Force | Out-Null New-Item -Path $LogDir -ItemType Directory -Force | Out-Null
# Folder for coverage files
$CoverageDir = $null
if ($CodeCoverage) {
$CoverageDir = Join-Path $RootDir "artifacts" "coverage"
New-Item -Path $CoverageDir -ItemType Directory -Force | Out-Null
}
# XML for creating a failure result data. # XML for creating a failure result data.
$FailXmlText = @" $FailXmlText = @"
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
@ -149,6 +176,10 @@ function Start-Executable {
} else { } else {
$pinfo.Arguments = "-g -G $($Path) $($Arguments)" $pinfo.Arguments = "-g -G $($Path) $($Arguments)"
} }
} elseif ($CodeCoverage) {
$pinfo.FileName = "C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe"
$pinfo.Arguments = "--modules=$(Split-Path $Path -Parent) --cover_children --sources src\core --sources src\inc --sources src\platform --excluded_sources unittest --working_dir $($LogDir) --export_type binary:$(Join-Path $CoverageDir $CoverageName) -- $($Path) $($Arguments)"
$pinfo.WorkingDirectory = $LogDir
} else { } else {
$pinfo.FileName = $Path $pinfo.FileName = $Path
$pinfo.Arguments = $Arguments $pinfo.Arguments = $Arguments
@ -266,6 +297,12 @@ function Wait-Executable($Exe) {
} }
} }
if ($CodeCoverage) {
# Copy coverage log
$LogName = "LastCoverageResults-$(Split-Path $Path -LeafBase).log"
Copy-Item (Join-Path $LogDir "LastCoverageResults.log") (Join-Path $CoverageDir $LogName) -Force
}
if ($KeepOutput) { if ($KeepOutput) {
if ($LogProfile -ne "None") { if ($LogProfile -ne "None") {
if ($ConvertLogs) { if ($ConvertLogs) {

Просмотреть файл

@ -53,6 +53,9 @@ as necessary.
.Parameter EnableAppVerifier .Parameter EnableAppVerifier
Enables all basic Application Verifier checks on the test binary. Enables all basic Application Verifier checks on the test binary.
.Parameter CodeCoverage
Collects code coverage for this test run. Incompatible with -Debugger.
#> #>
param ( param (
@ -105,7 +108,10 @@ param (
[switch]$NoProgress = $false, [switch]$NoProgress = $false,
[Parameter(Mandatory = $false)] [Parameter(Mandatory = $false)]
[switch]$EnableAppVerifier = $false [switch]$EnableAppVerifier = $false,
[Parameter(Mandatory = $false)]
[switch]$CodeCoverage = $false
) )
Set-StrictMode -Version 'Latest' Set-StrictMode -Version 'Latest'
@ -125,6 +131,22 @@ if ($Kernel -ne "" -and !$IsWindows) {
Write-Error "-Kernel switch only supported on Windows"; Write-Error "-Kernel switch only supported on Windows";
} }
# Validate the code coverage switch
if ($CodeCoverage) {
if (!$IsWindows) {
Write-Error "-CodeCoverage switch only supported on Windows";
}
if ($Debugger) {
Write-Error "-CodeCoverage switch is not supported with debugging";
}
if ($Kernel -ne "") {
Write-Error "-CodeCoverage is not supported for kernel mode tests";
}
if (!(Test-Path "C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe")) {
Write-Error "Code coverage tools are not installed";
}
}
# Root directory of the project. # Root directory of the project.
$RootDir = Split-Path $PSScriptRoot -Parent $RootDir = Split-Path $PSScriptRoot -Parent
@ -133,11 +155,19 @@ $LogScript = Join-Path $RootDir "scripts" "log.ps1"
# Executable name. # Executable name.
$TestExeName = Split-Path $Path -Leaf $TestExeName = Split-Path $Path -Leaf
$CoverageName = "$(Split-Path $Path -LeafBase).cov"
# Folder for log files. # Folder for log files.
$LogDir = Join-Path $RootDir "artifacts" "logs" $TestExeName (Get-Date -UFormat "%m.%d.%Y.%T").Replace(':','.') $LogDir = Join-Path $RootDir "artifacts" "logs" $TestExeName (Get-Date -UFormat "%m.%d.%Y.%T").Replace(':','.')
New-Item -Path $LogDir -ItemType Directory -Force | Out-Null New-Item -Path $LogDir -ItemType Directory -Force | Out-Null
# Folder for coverage files
$CoverageDir = $null
if ($CodeCoverage) {
$CoverageDir = Join-Path $RootDir "artifacts" "coverage"
New-Item -Path $CoverageDir -ItemType Directory -Force | Out-Null
}
# The file path of the final XML results. # The file path of the final XML results.
$FinalResultsPath = "$($LogDir)-results.xml" $FinalResultsPath = "$($LogDir)-results.xml"
@ -231,6 +261,11 @@ function Start-TestExecutable([String]$Arguments, [String]$OutputDir) {
} else { } else {
$pinfo.Arguments = "-g -G $($Path) $($Arguments)" $pinfo.Arguments = "-g -G $($Path) $($Arguments)"
} }
} elseif ($CodeCoverage) {
$CoverageOutput = Join-Path $OutputDir $CoverageName
$pinfo.FileName = "C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe"
$pinfo.Arguments = "--modules=$(Split-Path $Path -Parent) --cover_children --sources src\core --sources src\inc --sources src\platform --excluded_sources unittest --working_dir $($OutputDir) --export_type binary:$($CoverageOutput) -- $($Path) $($Arguments)"
$pinfo.WorkingDirectory = $OutputDir
} else { } else {
$pinfo.FileName = $Path $pinfo.FileName = $Path
$pinfo.Arguments = $Arguments $pinfo.Arguments = $Arguments
@ -391,6 +426,32 @@ function Wait-TestCase($TestCase) {
Add-XmlResults $TestCase Add-XmlResults $TestCase
} }
if ($CodeCoverage) {
$NewCoverage = Join-Path $TestCase.LogDir $Coveragename
if ($IsolationMode -eq "Isolated") {
# Merge coverage with previous runs
$PreviousCoverage = Join-Path $CoverageDir $CoverageName
if (!(Test-Path $PreviousCoverage)) {
# No previous coverage data, just copy
Copy-Item $NewCoverage $CoverageDir
} else {
# Merge new coverage data with existing coverage data
# On a developer machine, this will always merge coverage until the dev deletes old coverage.
$TempMergedCoverage = Join-Path $CoverageDir "mergetemp.cov"
$CoverageExe = 'C:\"Program Files"\OpenCppCoverage\OpenCppCoverage.exe'
$CoverageMergeParams = " --input_coverage $($PreviousCoverage) --input_coverage $($NewCoverage) --export_type binary:$($TempMergedCoverage)"
Invoke-Expression ($CoverageExe + $CoverageMergeParams) | Out-Null
Move-Item $TempMergedCoverage $PreviousCoverage -Force
}
} else {
# Copy the coverage to destination
Copy-Item $NewCoverage $CoverageDir -Force
# Copy coverage log
$LogName = "LastCoverageResults-$(Split-Path $Path -LeafBase).log"
Copy-Item (Join-Path $TestCase.LogDir "LastCoverageResults.log") (Join-Path $CoverageDir $LogName) -Force
}
}
if ($ProcessCrashed) { if ($ProcessCrashed) {
$AnyProcessCrashes = $true; $AnyProcessCrashes = $true;
} }

Просмотреть файл

@ -62,7 +62,10 @@ param (
[Parameter(Mandatory = $false)] [Parameter(Mandatory = $false)]
[ValidateSet("None", "Basic.Light", "Basic.Verbose", "Full.Light", "Full.Verbose", "SpinQuic.Light")] [ValidateSet("None", "Basic.Light", "Basic.Verbose", "Full.Light", "Full.Verbose", "SpinQuic.Light")]
[string]$LogProfile = "None" [string]$LogProfile = "None",
[Parameter(Mandatory = $false)]
[switch]$CodeCoverage = $false
) )
Set-StrictMode -Version 'Latest' Set-StrictMode -Version 'Latest'
@ -83,6 +86,19 @@ $RootDir = Split-Path $PSScriptRoot -Parent
# Path to the run-executable Powershell script. # Path to the run-executable Powershell script.
$RunExecutable = Join-Path $RootDir "scripts/run-executable.ps1" $RunExecutable = Join-Path $RootDir "scripts/run-executable.ps1"
#Validate the code coverage switch.
if ($CodeCoverage) {
if (!$IsWindows) {
Write-Error "-CodeCoverage switch only supported on Windows";
}
if ($Debugger) {
Write-Error "-CodeCoverage switch is not supported with debugging";
}
if (!(Test-Path "C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe")) {
Write-Error "Code coverage tools are not installed";
}
}
# Path to the spinquic exectuable. # Path to the spinquic exectuable.
$SpinQuic = $null $SpinQuic = $null
if ($IsWindows) { if ($IsWindows) {
@ -110,6 +126,9 @@ if ($Debugger) {
if ("None" -ne $LogProfile) { if ("None" -ne $LogProfile) {
$Arguments += " -LogProfile $($LogProfile) -ConvertLogs" $Arguments += " -LogProfile $($LogProfile) -ConvertLogs"
} }
if ($CodeCoverage) {
$Arguments += " -CodeCoverage"
}
# Run the script. # Run the script.
Invoke-Expression ($RunExecutable + " " + $Arguments) Invoke-Expression ($RunExecutable + " " + $Arguments)

Просмотреть файл

@ -55,6 +55,9 @@ This script provides helpers for running executing the MsQuic tests.
.Parameter EnableAppVerifier .Parameter EnableAppVerifier
Enables all basic Application Verifier checks on test binaries. Enables all basic Application Verifier checks on test binaries.
.Parameter CodeCoverage
Collect code coverage for this test run. Incompatible with -Kernel and -Debugger.
.EXAMPLE .EXAMPLE
test.ps1 test.ps1
@ -131,7 +134,10 @@ param (
[switch]$NoProgress = $false, [switch]$NoProgress = $false,
[Parameter(Mandatory = $false)] [Parameter(Mandatory = $false)]
[switch]$EnableAppVerifier = $false [switch]$EnableAppVerifier = $false,
[Parameter(Mandatory = $false)]
[switch]$CodeCoverage = $false
) )
Set-StrictMode -Version 'Latest' Set-StrictMode -Version 'Latest'
@ -142,6 +148,22 @@ if ($Kernel -and !$IsWindows) {
Write-Error "-Kernel switch only supported on Windows"; Write-Error "-Kernel switch only supported on Windows";
} }
#Validate the code coverage switch.
if ($CodeCoverage) {
if (!$IsWindows) {
Write-Error "-CodeCoverage switch only supported on Windows";
}
if ($Kernel) {
Write-Error "-CodeCoverage is not supported for kernel mode tests";
}
if ($Debugger) {
Write-Error "-CodeCoverage switch is not supported with debugging";
}
if (!(Test-Path "C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe")) {
Write-Error "Code coverage tools are not installed";
}
}
# Default TLS based on current platform. # Default TLS based on current platform.
if ("" -eq $Tls) { if ("" -eq $Tls) {
if ($IsWindows) { if ($IsWindows) {
@ -154,6 +176,16 @@ if ("" -eq $Tls) {
# Root directory of the project. # Root directory of the project.
$RootDir = Split-Path $PSScriptRoot -Parent $RootDir = Split-Path $PSScriptRoot -Parent
# Coverage destination directory.
$CoverageDir = Join-Path $RootDir "artifacts" "coverage"
if ($CodeCoverage) {
# Clear old coverage data
if (Test-Path $CoverageDir) {
Remove-Item -Path (Join-Path $CoverageDir '*.cov') -Force
}
}
# Path to the run-gtest Powershell script. # Path to the run-gtest Powershell script.
$RunTest = Join-Path $RootDir "scripts/run-gtest.ps1" $RunTest = Join-Path $RootDir "scripts/run-gtest.ps1"
@ -222,6 +254,9 @@ if ($NoProgress) {
if ($EnableAppVerifier) { if ($EnableAppVerifier) {
$TestArguments += " -EnableAppVerifier" $TestArguments += " -EnableAppVerifier"
} }
if ($CodeCoverage) {
$TestArguments += " -CodeCoverage"
}
# Run the script. # Run the script.
if (!$Kernel) { if (!$Kernel) {
@ -229,3 +264,21 @@ if (!$Kernel) {
Invoke-Expression ($RunTest + " -Path $MsQuicPlatTest " + $TestArguments) Invoke-Expression ($RunTest + " -Path $MsQuicPlatTest " + $TestArguments)
} }
Invoke-Expression ($RunTest + " -Path $MsQuicTest " + $TestArguments) Invoke-Expression ($RunTest + " -Path $MsQuicTest " + $TestArguments)
if ($CodeCoverage) {
# Merge code coverage results
$CoverageMergeParams = ""
foreach ($file in $(Get-ChildItem -Path $CoverageDir -Filter '*.cov')) {
$CoverageMergeParams += " --input_coverage $(Join-Path $CoverageDir $file.Name)"
}
if ($CoverageMergeParams -ne "") {
$CoverageMergeParams += " --export_type cobertura:$(Join-Path $CoverageDir "msquiccoverage.xml")"
$CoverageExe = 'C:\"Program Files"\OpenCppCoverage\OpenCppCoverage.exe'
Invoke-Expression ($CoverageExe + $CoverageMergeParams) | Out-Null
} else {
Write-Warning "No coverage results to merge!"
}
}