From 1205106ddf15ba1bccf8c08f0b89b4e5241bc790 Mon Sep 17 00:00:00 2001 From: James Garriss <52328727+james-garriss@users.noreply.github.com> Date: Thu, 12 Dec 2024 11:58:36 -0500 Subject: [PATCH] Write unit tests for Invoke PSSA (#1450) * intentionally cause an error * add try catch block * add errorvariable and check count * try the CI flag * add erroraction stop * set ErrorActionPreference * write the error message * rethrow the err * remove ErrorActionPreference * remove try catch * use exit 1 * add write * print result * print just result * get type * check result for null * fix typo * fix lint * should work * put result outside of try catch * only try invoke pester * use configuration * send to stream * write the result * try passthru * try passthru wo config * fix lint * try for failure with bad dir * clean up code * i hate yaml lint * set correct dir * use function * fix path * test w bad dir * update powershell unit tests to use function * fix linter * move test files * debug path * find name of files * ignore dummy file * more different remove * remove file from collection * find files * source functions * test pssa install * add params to invoke call * add results test * add write test * fix pssa error (oh the irony) * Remove afterall * comment * all comms * remove alt test * test output * fix order * Fix typo * try write-host * sssh to PSSA * add before discovery * fixed scope * Split describe * fix lint * fix typo * fix another typo grrrrr * try redirect * remove write host * fix the test to be a complete sentence * Fix or * FIx or * fix or * Find last output * Condense to one it * set output to global * Suppress PSSA global * Split back into 2 describes * test concurrency * remove publish tests * remove pssa * put publish back * combine pssa check * fix lint * add missing variable * remove tests * fix lint * debug * debug * fix lint * use write-warning * debug paths * fix lint * Debug * fix scriptpath * convert to string * fix lint * invoke again * fix path * test invoke in bd * test output * suppress PSSA * tweak global * just check install * fix typo in invoke * Change to Before All * just run invoke pssa * just run pssa * tweak test * fix source * remvoe suppress * remove before discovery * list path * just invoke * don't invoke * fix source * add suppress * debug * add foreach * summarize * check exists * drop param * change to warning * change more to warning * add debug mode * finish warning * remove exit 0 * test install * use output * use 3 * check write warning * use warning variable * write out the warnings * fix the test * split tests * change location * fix warning variable name * time serial * make serial for real * Put in final form * Put workflow pipeline back * tweak docs * fix merge stuff * del files * del files on wrong branch * fix unit test * fix lint * Restore powershell tests * fxi lint * Remove old code, add comments * Use synopsis in docs * remove debugging line --- Testing/workflow/Invoke-PSSA.Tests.ps1 | 31 +++++++++++++++ .../Initialize-ScubaGearForTesting.ps1 | 6 +-- utils/workflow/Install-SeleniumForTesting.ps1 | 4 +- utils/workflow/Invoke-PSSA.ps1 | 39 ++++++++++--------- 4 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 Testing/workflow/Invoke-PSSA.Tests.ps1 diff --git a/Testing/workflow/Invoke-PSSA.Tests.ps1 b/Testing/workflow/Invoke-PSSA.Tests.ps1 new file mode 100644 index 0000000000..48010bb2f0 --- /dev/null +++ b/Testing/workflow/Invoke-PSSA.Tests.ps1 @@ -0,0 +1,31 @@ +# The purpose of this test is to verify that PSSA is working. + +# Suppress PSSA warnings here at the root of the test file. +# This allows us to run Invoke-PSSA once and use the results for both tests. +[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidGlobalVars', '')] +param() + +BeforeDiscovery { + $RepoRootPath = Join-Path -Path $PSScriptRoot -ChildPath '../..' -Resolve + $ScriptPath = Join-Path -Path $PSScriptRoot -ChildPath '../../utils/workflow/Invoke-PSSA.ps1' -Resolve + # Source the function + . $ScriptPath + # Invoke PSSA, redirecting all Write-Warnings to a variable + $Warnings = @() + Invoke-PSSA -DebuggingMode $false -RepoPath $RepoRootPath -WarningVariable Warnings + $global:Warnings = $Warnings +} + +Describe "PSSA Check" { + It "PSSA should be installed" { + $Module = Get-Module -ListAvailable -Name 'PSScriptAnalyzer' + $Module | Should -Not -BeNullOrEmpty + } + It "PSSA should write output" { + # There should be write-warning statements + $global:Warnings | Should -Not -BeNullOrEmpty + # Note: This is a bit fragile. It only works as long as one of these two + # summary statements is the final output written by the Invoke function. + $global:Warnings | Select-Object -Last 1 | Should -BeIn @("Problems were found in the PowerShell scripts.", "No problems were found in the PowerShell scripts.") + } +} diff --git a/utils/workflow/Initialize-ScubaGearForTesting.ps1 b/utils/workflow/Initialize-ScubaGearForTesting.ps1 index dc585aab29..e61fee6600 100644 --- a/utils/workflow/Initialize-ScubaGearForTesting.ps1 +++ b/utils/workflow/Initialize-ScubaGearForTesting.ps1 @@ -1,7 +1,7 @@ function Initialize-ScubaGearForTesting { <# - .DESCRIPTION - Initializes ScubaGear for testing + .SYNOPSIS + Initializes ScubaGear, which installs the necessary modules and tools to run ScubaGear. #> Write-Output 'Initializing ScubaGear for testing...' @@ -12,4 +12,4 @@ function Initialize-ScubaGearForTesting { Import-Module (Join-Path -Path $RepoRootPath -ChildPath 'PowerShell/ScubaGear') -Function Initialize-Scuba Write-Output 'Calling Initialize ScubaGear...' Initialize-SCuBA -} \ No newline at end of file +} diff --git a/utils/workflow/Install-SeleniumForTesting.ps1 b/utils/workflow/Install-SeleniumForTesting.ps1 index 51b7978a32..a3a05e1772 100644 --- a/utils/workflow/Install-SeleniumForTesting.ps1 +++ b/utils/workflow/Install-SeleniumForTesting.ps1 @@ -1,7 +1,7 @@ function Install-SeleniumForTesting { <# - .DESCRIPTION - Installs Selenium for ScubaGear testing + .SYNOPSIS + Installs Selenium PowerShell module and Chrome driver for ScubaGear testing #> Write-Output 'Installing Selenium for testing...' diff --git a/utils/workflow/Invoke-PSSA.ps1 b/utils/workflow/Invoke-PSSA.ps1 index c103173208..4dcaac00be 100644 --- a/utils/workflow/Invoke-PSSA.ps1 +++ b/utils/workflow/Invoke-PSSA.ps1 @@ -1,6 +1,6 @@ function Invoke-PSSA { <# - .DESCRIPTION + .SYNOPSIS Allows a GitHub workflow to install and use PSScriptAnalyzer (PSSA). .PARAMETER DebuggingMode When the debug parameter is true, extra debugging information is available. @@ -17,8 +17,8 @@ function Invoke-PSSA { $RepoPath ) - Write-Output "Testing PowerShell files with PSScriptAnalyzer..." - Write-Output " " + Write-Warning "Testing PowerShell files with PSScriptAnalyzer..." + Write-Warning " " # Install PSScriptAnalyzer Set-PSRepository PSGallery -InstallationPolicy Trusted @@ -26,6 +26,7 @@ function Invoke-PSSA { # Get all PowerShell script files in the repository $PsFiles = Get-ChildItem -Path $RepoPath -Include *.ps1, *ps1xml, *.psc1, *.psd1, *.psm1, *.pssc, *.psrc, *.cdxml -Recurse + # Find the PSScriptAnalyzer config file $ConfigPath = Join-Path -Path $RepoPath -ChildPath Testing/Linting/PSSA/.powershell-psscriptanalyzer.psd1 @@ -38,33 +39,33 @@ function Invoke-PSSA { foreach ($PsFile in $PsFiles) { $Results = Invoke-ScriptAnalyzer -Path $PsFile -Settings $ConfigPath foreach ($Result in $Results) { - Write-Output "File: $($Result.ScriptPath)" - Write-Output "Line: $($Result.Line)" - Write-Output "Severity: $($Result.Severity)" - Write-Output "RuleName: $($Result.RuleName)" + Write-Warning "File: $($Result.ScriptPath)" + Write-Warning "Line: $($Result.Line)" + Write-Warning "Severity: $($Result.Severity)" + Write-Warning "RuleName: $($Result.RuleName)" # Only create GitHub workflow annotation if warning or error # The ::error:: notation is how a workflow annotation is created if ($Result.Severity -eq 'Information') { - Write-Output "Message: $($Result.Message)" + Write-Warning "Message: $($Result.Message)" $InfoCount++ } elseif ($Result.Severity -eq 'Warning') { - Write-Output "::error::Message: $($Result.Message)" + Write-Warning "::error::Message: $($Result.Message)" $WarningCount++ } elseif ($Result.Severity -eq 'Error') { - Write-Output "::error::Message: $($Result.Message)" + Write-Warning "::error::Message: $($Result.Message)" $ErrorCount++ } - Write-Output " " + Write-Warning " " } } # Summarize results - Write-Output "Summary" - Write-Output " Errors: $ErrorCount" - Write-Output " Warnings: $WarningCount" - Write-Output " Information: $InfoCount" + Write-Warning "Summary" + Write-Warning " Errors: $ErrorCount" + Write-Warning " Warnings: $WarningCount" + Write-Warning " Information: $InfoCount" # If it's important to verify the version of PSSA that is used, set DebuggingMode to true. # This is not run every time because it takes too long. @@ -72,14 +73,14 @@ function Invoke-PSSA { Get-Module -ListAvailable | Where-Object { $_.Name -eq "PSScriptAnalyzer" } | Select-Object -Property Name, Version } - Write-Output " " + Write-Warning " " # Exit 1 if warnings or errors - if (($InfoCount -gt 0) -or ($WarningCount -gt 0)) { - Write-Output "Problems were found in the PowerShell scripts." + if (($ErrorCount -gt 0) -or ($WarningCount -gt 0)) { + Write-Warning "Problems were found in the PowerShell scripts." exit 1 } else { - Write-Output "No problems were found in the PowerShell scripts." + Write-Warning "No problems were found in the PowerShell scripts." } } \ No newline at end of file