Vester项目创建了Pester测试,这些测试遵循Describe,It,Try,Catch,Remdiate的特定模式来测试然后修复VMWare环境的问题,例如。 Update-DNS.Tests.ps1
在半伪代码中,算法的核心如下:
Param(
[switch]$Remediate = $false
)
Process {
Describe -Name "Test Group Name" -Tag @("Tag") -Fixture {
#Some code to load up state for the test group
foreach ($Thing in $Things) {
It -name "Name of first test" -test {
#Some code to load up state for the test
try {
#Conditional tests using Pester syntax
} catch {
if ($Remediate) {
Write-Warning -Message $_
Write-Warning -Message "Remediation Message"
#Code to remediate issues
} else {
throw $_
}
}
}
}
}
}
我希望能够编写允许以下Pester像DSL语法的代码:
Param(
[switch]$Remediate = $false
)
CheckGroup "AD User Checks" {
ForEach($Aduser in (Get-aduser -Filter * -Properties HomeDirectory)) {
Check "Home directory path exists" {
Condition {
if ($Aduser.HomeDirectory) {
Test-path $Aduser.HomeDirectory | Should be $true
}
}
Remdiation "Create home directory that doesn't exist" {
New-Item -ItemType Directory -Path $Aduser.HomeDirectory
}
}
}
}
运行此操作会导致实际运行以下内容:
Describe -Name "AD User Checks" -Fixture {
ForEach($Aduser in (Get-aduser -Filter * -Properties HomeDirectory)) {
It -name "Home directory path exists" -test {
try {
if ($Aduser.HomeDirectory) {
Test-path $Aduser.HomeDirectory | Should be $true
}
} catch {
if ($Remediate) {
Write-Warning -Message $_
Write-Warning -Message "Create home directory that doesn't exist"
New-Item -ItemType Directory -Path $Aduser.HomeDirectory
} else {
throw $_
}
}
}
}
}
如何实施专为执行检查和修复而设计的DSL?
以下是我为尝试实现此目的而编写的一些代码:
Function CheckGroup {
param (
[Parameter(Mandatory, Position = 0)][String]$Name,
[Parameter(Position = 1)]$CheckGroupScriptBlock
)
Describe $CheckGroupName -Fixture $CheckGroupScriptBlock
}
Function Check {
param (
[Parameter(Mandatory, Position = 0)][String]$Name,
$ConditionScriptBlock,
$RemediationScriptBlock
)
It -name $Name -test {
try {
& $ConditionScriptBlock
} catch {
& $RemediationScriptBlock
}
}
}
Function Condition {
[CmdletBinding()]
param (
[Parameter(Position = 1)]$ScriptBlock
)
& $ScriptBlock
}
Function Remediation {
[CmdletBinding()]
param (
$Name,
[Parameter(Position = 1)]$ScriptBlock,
[bool]$Remediate = $false
)
if ($Remediate) {
Write-Verbose $_
Write-Verbose $Name
& $ScriptBlock
} else {
throw $_
}
}
对于函数Check
我真的需要能够将单个脚本块作为参数接收,但不知何故在脚本块内部发现Condition
和Remediation
函数调用并且将它们从脚本块中分离出来,并将它们混合到Try {} Catch {}
函数It
内Check
内的适当位置。