如何在PowerShell中创建类似于Pester的DSL?

时间:2016-11-08 22:54:16

标签: powershell

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我真的需要能够将单个脚本块作为参数接收,但不知何故在脚本块内部发现ConditionRemediation函数调用并且将它们从脚本块中分离出来,并将它们混合到Try {} Catch {}函数ItCheck内的适当位置。

0 个答案:

没有答案