2020-07-09 10:53:29 +03:00
function Get-CommandResult {
Param (
[ Parameter ( Mandatory )][ string ] $Command
)
# CMD trick to suppress and show error output because some commands write to stderr (for example, "python --version")
[ string[] ] $output = & $env:comspec / c " $Command 2>&1"
$exitCode = $LASTEXITCODE
return @ {
Output = $output
ExitCode = $exitCode
}
}
2020-07-16 07:30:34 +03:00
# Gets path to the tool, analogue of 'which tool'
function Get-WhichTool($tool ) {
return ( Get-Command $tool ). Path
}
2020-07-09 10:53:29 +03:00
# Gets value of environment variable by the name
function Get-EnvironmentVariable($variable ) {
2020-07-20 18:57:00 +03:00
return [ System.Environment ]:: GetEnvironmentVariable ( $variable , "Machine" )
2020-07-09 10:53:29 +03:00
}
# Update environment variables without reboot
function Update-Environment {
$variables = [ Environment ]:: GetEnvironmentVariables ( "Machine" )
$variables . Keys | ForEach-Object {
$key = $_
$value = $variables [ $key ]
Set-Item -Path "env: $key " -Value $value
}
# We need to refresh PATH the latest one because it could include other variables "%M2_HOME%/bin"
$env:PATH = [ Environment ]:: GetEnvironmentVariable ( "PATH" , "Machine" )
}
# Run Pester tests for specific tool
function Invoke-PesterTests {
Param (
[ Parameter ( Mandatory )][ string ] $TestFile ,
[ string ] $TestName
)
$testPath = "C:\image\Tests\ ${TestFile} .Tests.ps1"
if ( -not ( Test-Path $testPath )) {
throw "Unable to find test file ' $TestFile ' on ' $testPath '."
}
$configuration = [ PesterConfiguration ] @ {
Run = @ { Path = $testPath ; PassThru = $true }
Output = @ { Verbosity = "Detailed" }
}
if ( $TestName ) {
$configuration . Filter . FullName = $TestName
}
2021-08-27 09:38:18 +03:00
if ( $TestFile -eq "*" ) {
$configuration . TestResult . Enabled = $true
$configuration . TestResult . OutputPath = "C:\image\Tests\testResults.xml"
}
2020-07-09 10:53:29 +03:00
# Update environment variables without reboot
Update-Environment
# Switch ErrorActionPreference to Stop temporary to make sure that tests will on silent errors too
$backupErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = "Stop"
$results = Invoke-Pester -Configuration $configuration
$ErrorActionPreference = $backupErrorActionPreference
# Fail in case if no tests are run
if ( -not ( $results -and ( $results . FailedCount -eq 0 ) -and ( $results . PassedCount -gt 0 ))) {
$results
2020-07-09 13:22:07 +03:00
throw "Test run has failed"
2020-07-09 10:53:29 +03:00
}
}
# Pester Assert to check exit code of command
function ShouldReturnZeroExitCode {
Param (
2020-07-09 13:22:07 +03:00
[ String ] $ActualValue ,
[ switch ] $Negate ,
2020-07-09 10:53:29 +03:00
[ string ] $Because
)
$result = Get-CommandResult $ActualValue
[ bool ] $succeeded = $result . ExitCode -eq 0
if ( $Negate ) { $succeeded = -not $succeeded }
if ( -not $succeeded )
{
2020-07-10 14:38:45 +03:00
$commandOutputIndent = " " * 4
$commandOutput = ( $result . Output | ForEach-Object { " ${commandOutputIndent}${_} " }) -join " `n "
2020-07-09 10:53:29 +03:00
$failureMessage = "Command ' ${ActualValue} ' has finished with exit code ${actualExitCode} `n ${commandOutput} "
}
return [ PSCustomObject ] @ {
Succeeded = $succeeded
FailureMessage = $failureMessage
}
}
2021-06-21 14:09:51 +03:00
# Pester Assert to check exit code of command with given parameter, the assertion performed up to 3 checks (without '-', with 1 and 2 '-') until succeeded
function ShouldReturnZeroExitCodeWithParam {
param (
[ Parameter ( Mandatory )] [ string ] $ActualValue ,
[ switch ] $Negate ,
[ string ] $CallParameter = "version" ,
[ string ] $CallerSessionState
)
$delimiterCharacter = ""
while ( $delimiterCharacter . Length -le 2 )
{
$callParameterWithDelimeter = $delimiterCharacter + $CallParameter
$commandToCheck = " $ActualValue $callParameterWithDelimeter "
[ bool ] $succeeded = ( ShouldReturnZeroExitCode -ActualValue $commandToCheck ). Succeeded
if ( $succeeded )
{
break
}
$delimiterCharacter += '-'
}
if ( $Negate ) { $succeeded = -not $succeeded }
if ( -not $succeeded )
{
$failureMessage = "Tool ' $ActualValue ' has not returned 0 exit code for any of these flags: ' $CallParameter ' or '- $CallParameter ' or '-- $CallParameter '"
}
return [ PSCustomObject ] @ {
Succeeded = $succeeded
FailureMessage = $failureMessage
}
}
2020-07-13 13:37:04 +03:00
# Pester Assert to match output of command
function ShouldMatchCommandOutput {
Param (
[ String ] $ActualValue ,
[ String ] $RegularExpression ,
[ switch ] $Negate
)
$output = ( Get-CommandResult $ActualValue ). Output | Out-String
[ bool ] $succeeded = $output -cmatch $RegularExpression
if ( $Negate ) {
$succeeded = -not $succeeded
}
$failureMessage = ''
if ( -not $succeeded ) {
if ( $Negate ) {
2020-07-13 14:42:40 +03:00
$failureMessage = "Expected regular expression ' $RegularExpression ' for ' $ActualValue ' command to not match ' $output ', but it did match."
2020-07-13 13:37:04 +03:00
}
else {
2020-07-13 14:42:40 +03:00
$failureMessage = "Expected regular expression ' $RegularExpression ' for ' $ActualValue ' command to match ' $output ', but it did not match."
2020-07-13 13:37:04 +03:00
}
}
return [ PSCustomObject ] @ {
Succeeded = $succeeded
FailureMessage = $failureMessage
}
}
2021-05-25 11:13:12 +03:00
If ( Get-Command -Name Add-ShouldOperator -ErrorAction SilentlyContinue ) {
Add-ShouldOperator -Name ReturnZeroExitCode -InternalName ShouldReturnZeroExitCode -Test ${ function : ShouldReturnZeroExitCode }
2021-06-21 14:09:51 +03:00
Add-ShouldOperator -Name ReturnZeroExitCodeWithParam -InternalName ShouldReturnZeroExitCodeWithParam -Test ${ function : ShouldReturnZeroExitCodeWithParam }
2021-05-25 11:13:12 +03:00
Add-ShouldOperator -Name MatchCommandOutput -InternalName ShouldMatchCommandOutput -Test ${ function : ShouldMatchCommandOutput }
2020-07-09 10:53:29 +03:00
}