tasks/DscResource.Test.build.ps1
Param ( # Project path [Parameter()] [string] $ProjectPath = (property ProjectPath $BuildRoot), [Parameter()] # Base directory of all output (default to 'output') [string] $OutputDirectory = (property OutputDirectory (Join-Path $BuildRoot 'output')), [Parameter()] [string] $ProjectName = (property ProjectName $( (Get-ChildItem $BuildRoot\*\*.psd1 | Where-Object { ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop } catch { $false }) } ).BaseName ) ), [Parameter()] [string] $ModuleVersion = (property ModuleVersion $( try { (gitversion | ConvertFrom-Json -ErrorAction Stop).InformationalVersion } catch { Write-Verbose "Error attempting to use GitVersion $($_)" '' } )), [Parameter()] [string] $DscTestOutputFolder = (property DscTestOutputFolder 'testResults'), [Parameter()] [string] $DscTestOutputFormat = (property DscTestOutputFormat ''), [Parameter()] [string[]] $DscTestScript = (property DscTestScript ''), [Parameter()] [string[]] $DscTestTag = (property DscTestTag @()), [Parameter()] [string[]] $DscTestExcludeTag = (property DscTestExcludeTag @()), # Build Configuration object [Parameter()] $BuildInfo = (property BuildInfo @{ }) ) # Synopsis: Making sure the Module meets some quality standard (help, tests) task Invoke_DscResource_tests { if (!(Split-Path -isAbsolute $OutputDirectory)) { $OutputDirectory = Join-Path -Path $ProjectPath -ChildPath $OutputDirectory Write-Build Yellow "Absolute path to Output Directory is $OutputDirectory" } if (!(Split-Path -isAbsolute $DscTestOutputFolder)) { $DscTestOutputFolder = Join-Path $OutputDirectory $DscTestOutputFolder } if (!(Test-Path $DscTestOutputFolder)) { Write-Build Yellow "Creating folder $DscTestOutputFolder" $null = New-Item -ItemType Directory -force $DscTestOutputFolder -ErrorAction Stop } $DscTestScript = $DscTestScript.Where{ ![string]::IsNullOrEmpty($_) } $DscTestTag = $DscTestTag.Where{ ![string]::IsNullOrEmpty($_) } $DscTestExcludeTag = $DscTestExcludeTag.Where{ ![string]::IsNullOrEmpty($_) } $DefaultDscTestParams = @{ OutputFormat = 'NUnitXML' OutputFile = $DscTestOutputFullPath PassThru = $true # ProjectPath = $ProjectPath } # Build.ps1 parameters should be top priority # BuildInfo values should come next # Otherwise we should set some defaults Import-Module Pester,DscResource.Test -ErrorAction Stop $DscTestCmd = Get-Command Invoke-DscResourceTest foreach ($ParamName in $DscTestCmd.Parameters.Keys) { $TaskParamName = "DscTest$ParamName" if (!(Get-Variable -Name $TaskParamName -ValueOnly -ErrorAction SilentlyContinue) -and ($DscTestBuildConfig = $BuildInfo.DscTest)) { # The Variable is set to '' so we should try to use the Config'd one if exists if ($ParamValue = $DscTestBuildConfig.($ParamName)) { Write-Build DarkGray "Using $TaskParamName from Build Config" Set-Variable -Name $TaskParamName -Value $ParamValue } # or use a default if available elseif ($DefaultDscTestParams.ContainsKey($ParamName)) { Write-Build DarkGray "Using $TaskParamName from Defaults" Set-Variable -Name $TaskParamName -Value $DefaultDscTestParams.($ParamName) } } else { Write-Build DarkGray "Using $TaskParamName from Build Invocation Parameters" } } "`tProject Path = $ProjectPath" "`tProject Name = $ProjectName" "`tTest Scripts = $($DscTestScript -join ', ')" "`tTags = $($DscTestTag -join ', ')" "`tExclude Tags = $($DscTestExcludeTag -join ', ')" "`tModuleVersion = $ModuleVersion" "`tBuildModuleOutput = $BuildModuleOutput" if ([String]::IsNullOrEmpty($ModuleVersion)) { $ModuleInfo = Import-PowerShellDataFile "$BuildModuleOutput/$ProjectName/*/$ProjectName.psd1" -ErrorAction Stop if ($PreReleaseTag = $ModuleInfo.PrivateData.PSData.Prerelease) { $ModuleVersion = $ModuleInfo.ModuleVersion + "-" + $PreReleaseTag } else { $ModuleVersion = $ModuleInfo.ModuleVersion } } else { $ModuleVersion, $BuildMetadata = $ModuleVersion -split '\+', 2 $ModuleVersionFolder, $PreReleaseTag = $ModuleVersion -split '\-', 2 } $os = if ($isWindows -or $PSVersionTable.PSVersion.Major -le 5) { 'Windows' } elseif ($isMacOS) { 'MacOS' } else { 'Linux' } $PSVersion = 'PSv.{0}' -f $PSVersionTable.PSVersion $DscTestOutputFileFileName = "DscTest_{0}_v{1}.{2}.{3}.xml" -f $ProjectName, $ModuleVersion, $os, $PSVersion $DscTestOutputFullPath = Join-Path $DscTestOutputFolder "$($DscTestOutputFormat)_$DscTestOutputFileFileName" $DscTestParams = @{ OutputFormat = $DscTestOutputFormat OutputFile = $DscTestOutputFullPath PassThru = $true } if ($DscTestModule) { $DscTestParams.Add('Module', $DscTestModule) } elseif ($DscTestFullyQualifiedModule) { $DscTestParams.Add('FullyQualifiedModule', $DscTestFullyQualifiedModule) } else { $DscTestParams.Add('ProjectPath', $ProjectPath) } if ($DscTestExcludeTag.count -gt 0) { $DscTestParams.Add('ExcludeTag', $DscTestExcludeTag) } if ($DscTestTag.Count -gt 0) { $DscTestParams.Add('Tag', $DscTestTag) } # Test folders is specified, override invoke-DscResourceTest internal default if ($DscTestScript.count -gt 0) { $DscTestParams.Add('Script', @()) Write-Build DarkGray " Adding DscTestScript to params" foreach ($TestFolder in $DscTestScript) { if (!(Split-Path -isAbsolute $TestFolder)) { $TestFolder = Join-Path $ProjectPath $TestFolder } Write-Build DarkGray " ... $TestFolder" # The Absolute path to this folder exists, adding to the list of DscTest scripts to run if (Test-Path $TestFolder) { $DscTestParams.Script += $TestFolder } } } foreach ($ParamName in $DscTestCmd.Parameters.keys) { $ParamValueFromScope = (Get-Variable "DscTest$ParamName" -ValueOnly -ErrorAction SilentlyContinue) if (!$DscTestParams.ContainsKey($ParamName) -and $ParamValueFromScope) { $DscTestParams.Add($ParamName, $ParamValueFromScope) } } Write-Verbose -Message ($DscTestParams | ConvertTo-Json) $script:TestResults = Invoke-DscResourceTest @DscTestParams $DscTestResultObjectCliXml = Join-Path $DscTestOutputFolder "DscTestObject_$DscTestOutputFileFileName" $null = $script:TestResults | Export-CliXml -Path $DscTestResultObjectCliXml -Force } # Synopsis: This task ensures the build job fails if the test aren't successful. task Fail_Build_if_DscResource_Tests_failed { "Asserting that no test failed" if (!(Split-Path -isAbsolute $OutputDirectory)) { $OutputDirectory = Join-Path -Path $ProjectPath -ChildPath $OutputDirectory Write-Build Yellow "Absolute path to Output Directory is $OutputDirectory" } if (!(Split-Path -isAbsolute $DscTestOutputFolder)) { $DscTestOutputFolder = Join-Path $OutputDirectory $DscTestOutputFolder } $os = if ($isWindows -or $PSVersionTable.PSVersion.Major -le 5) { 'Windows' } elseif ($isMacOS) { 'MacOS' } else { 'Linux' } if ([String]::IsNullOrEmpty($ModuleVersion)) { $ModuleInfo = Import-PowerShellDataFile "$OutputDirectory/$ProjectName/*/$ProjectName.psd1" -ErrorAction Stop if ($PreReleaseTag = $ModuleInfo.PrivateData.PSData.Prerelease) { $ModuleVersion = $ModuleInfo.ModuleVersion + "-" + $PreReleaseTag } else { $ModuleVersion = $ModuleInfo.ModuleVersion } } else { $ModuleVersion, $BuildMetadata = $ModuleVersion -split '\+', 2 $ModuleVersionFolder, $PreReleaseTag = $ModuleVersion -split '\-', 2 } $PSVersion = 'PSv.{0}' -f $PSVersionTable.PSVersion $DscTestOutputFileFileName = "DscTest_{0}_v{1}.{2}.{3}.xml" -f $ProjectName, $ModuleVersion, $os, $PSVersion $DscTestResultObjectClixml = Join-Path $DscTestOutputFolder "DscTestObject_$DscTestOutputFileFileName" Write-Build White "`tDscTest Output Object = $DscTestResultObjectClixml" if (-Not (Test-Path $DscTestResultObjectClixml)) { Throw "No command were tested. $DscTestResultObjectClixml not found" } else { $DscTestObject = Import-Clixml -Path $DscTestResultObjectClixml -ErrorAction Stop assert ($DscTestObject.FailedCount -eq 0) ('Failed {0} tests. Aborting Build' -f $DscTestObject.FailedCount) } } # Synopsis: Uploading Unit Test results to AppVeyor task Upload_DscResourceTest_Results_To_AppVeyor -If { (property BuildSystem 'unknown') -eq 'AppVeyor' } { if (!(Split-Path -isAbsolute $OutputDirectory)) { $OutputDirectory = Join-Path -Path $ProjectPath -ChildPath $OutputDirectory Write-Build Yellow "Absolute path to Output Directory is $OutputDirectory" } if (!(Split-Path -isAbsolute $DscTestOutputFolder)) { $DscTestOutputFolder = Join-Path $OutputDirectory $DscTestOutputFolder } if (!(Test-Path $DscTestOutputFolder)) { Write-Build Yellow "Creating folder $DscTestOutputFolder" $null = New-Item -ItemType Directory -force $DscTestOutputFolder -ErrorAction Stop } $os = if ($isWindows -or $PSVersionTable.PSVersion.Major -le 5) { 'Windows' } elseif ($isMacOS) { 'MacOS' } else { 'Linux' } if ([String]::IsNullOrEmpty($ModuleVersion)) { $ModuleInfo = Import-PowerShellDataFile "$OutputDirectory/$ProjectName/*/$ProjectName.psd1" -ErrorAction Stop if ($PreReleaseTag = $ModuleInfo.PrivateData.PSData.Prerelease) { $ModuleVersion = $ModuleInfo.ModuleVersion + "-" + $PreReleaseTag } else { $ModuleVersion = $ModuleInfo.ModuleVersion } } else { $ModuleVersion, $BuildMetadata = $ModuleVersion -split '\+', 2 $ModuleVersionFolder, $PreReleaseTag = $ModuleVersion -split '\-', 2 } $PSVersion = 'PSv.{0}' -f $PSVersionTable.PSVersion $DscTestOutputFileFileName = "DscResource.Test_{0}_v{1}.{2}.{3}.xml" -f $ProjectName, $ModuleVersion, $os, $PSVersion $DscTestOutputFullPath = Join-Path $DscTestOutputFolder "$($DscTestOutputFormat)_$DscTestOutputFileFileName" $TestResultFile = Get-Item $DscTestOutputFullPath -ErrorAction Ignore if ($TestResultFile) { Write-Build Green " Uploading test results $TestResultFile to Appveyor" $TestResultFile | Add-TestResultToAppveyor Write-Build Green " Upload Complete" } } # Synopsis: Meta task that runs Quality Tests, and fails if they're not successful task DscResource_Tests_Stop_On_Fail Invoke_DscResource_tests, Upload_DscResourceTest_Results_To_AppVeyor, Fail_Build_if_DscResource_Tests_failed |