Private/Template/VesterTemplate.Tests.ps1
<#
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. http://vester.readthedocs.io/en/latest/ #> # 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) Compare-Object -ReferenceObject $Desired -DifferenceObject (& $Actual -as $Type) | 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 throw $_ } } #Try/Catch } #It } #Foreach Inventory }#Describe }#Foreach Tests }#Foreach Final.Scope |