Private/Template/VesterTemplate.Tests.ps1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
<#
This file exists to combine simple user input (Invoke-Vester), simple user test authoring (*.Vester.ps1), and properly scoped inventory objects into a single test session that loops through all necessary combinations. It is called by Invoke-Vester via the Invoke-Pester command. https://wahlnetwork.github.io/Vester #> # Accept -WhatIf input from Invoke-Vester [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] Param( # The $cfg hashtable from a single config file [object]$Cfg, # Array of paths for tests to run against this config file [object]$TestFiles, # Pass through the user's preference to fix differences or not [switch]$Remediate ) # Gets the scope, the objects for the scope and their requested test files $Scopes = Split-Path (Split-Path $TestFiles -Parent) -Leaf | Select -Unique $Final = @() $InventoryList = @() $Datacenter = Get-Datacenter -Name $cfg.scope.datacenter -Server $cfg.vcenter.vc foreach($Scope in $Scopes) { Write-Verbose "Processing $Scope" Remove-Variable InventoryList -ErrorAction SilentlyContinue # Makes sure the variable is always fresh # Use $Scope (parent folder) to get the correct objects to test against # If changing values here, update the "$Scope -notmatch" test below as well $InventoryList = switch ($Scope) { 'vCenter' {$global:DefaultVIServer | where-object {$_.name -like "$($cfg.vcenter.vc)"}} 'Datacenter' {$Datacenter} 'Cluster' {$Datacenter | Get-Cluster -Name $cfg.scope.cluster} 'DSCluster' {$Datacenter | Get-DatastoreCluster -Name $cfg.scope.dscluster} 'Host' {$Datacenter | Get-Cluster -Name $cfg.scope.cluster | Get-VMHost -Name $cfg.scope.host} 'VM' {$Datacenter | Get-Cluster -Name $cfg.scope.cluster | Get-VM -Name $cfg.scope.vm} 'Network' {$Datacenter | Get-VDSwitch -Name $cfg.scope.vds} } $ScopeObj = [pscustomobject] @{ 'Scope' = $Scope 'InventoryList' = $InventoryList 'TestFiles' = $TestFiles | Where-Object { (Split-Path (Split-Path $_ -Parent) -Leaf) -eq $Scope } } if (($ScopeObj.InventoryList -ne $NULL) -and ($ScopeObj.TestFiles -ne $NULL)){ $Final += $ScopeObj } } # Loops through each Scope foreach($Scope in $Final.Scope) { # Pulling the inventory and test files for this scope $Inventory = ($Final | Where-Object { $_.Scope -eq $Scope }).InventoryList $Tests = ($Final | Where-Object { $_.Scope -eq $Scope }).TestFiles # The parent folder must be one of these names, to help with $Object scoping below # If adding here, also needs to be added to the switch below If ('vCenter|Datacenter|Cluster|DSCluster|Host|VM|Network' -notmatch $Scope) { Write-Warning "Skipping test $TestName. Use -Verbose for more details" Write-Verbose 'Test files should be in a folder with one of the following names:' Write-Verbose 'vCenter / Datacenter / Cluster / DSCluster / Host / VM / Network' Write-Verbose 'This helps Vester determine which inventory object(s) to use during the test.' # Use continue to skip this test and go to the next loop iteration continue } # Runs through each test file on the below objects in the current scope foreach($Test in $Tests) { Write-Verbose "Processing test file $Test" $TestName = Split-Path $Test -Leaf Describe -Name "$Scope Configuration: $TestName" -Fixture { # Pull in $Title/$Description/$Desired/$Type/$Actual/$Fix from the test file . $Test # Pump the brakes if the config value is $null If ($Desired -eq $null) { Write-Verbose "Due to null config value, skipping test $TestName" # Use continue to skip this test and go to the next loop iteration continue } # Loops through each object in the inventory list for the specific scope. # It runs one test at a time against each $Object and moves onto the next test. foreach($Object in $Inventory) { It -Name "$Scope $($Object.Name) - $Title" -Test { Try { # "& $Actual" is running the first script block to compare to $Desired # The comparison should be empty # (meaning everything is the same, as expected) $Result = (& $Actual -as $Type) Compare-Object -ReferenceObject $Desired -DifferenceObject $Result | Should BeNullOrEmpty } Catch { # If the comparison found something different, # Then check if we're going to fix it If ($Remediate) { Write-Warning -Message $_ # -WhatIf support wraps the command that would change values If ($PSCmdlet.ShouldProcess("vCenter '$($cfg.vcenter.vc)' - $Scope '$Object'", "Set '$Title' value to '$Desired'")) { Write-Warning -Message "Remediating $Object" # Execute the $Fix script block & $Fix } } Else { # -Remediate is not active, so just report the error $Message = @( "Desired: [$($Desired.gettype())] $Desired" "Actual: [$($Result.gettype())] $Result" "Synopsis: $Description" "Link: https://wahlnetwork.github.io/Vester/reference/tests/$Scope/$($Title.replace(' ','-').replace(':','')).html" "Test File: $Test" ) -join "`n" Throw $Message } } #Try/Catch } #It } #Foreach Inventory }#Describe }#Foreach Tests }#Foreach Final.Scope |