Files
PowerShell-PSDscResources/Tests/Unit/MSFT_ScriptResource.Tests.ps1

456 lines
22 KiB
PowerShell

$errorActionPreference = 'Stop'
Set-StrictMode -Version 'Latest'
# Import CommonTestHelper for Enter-DscResourceTestEnvironment, Exit-DscResourceTestEnvironment
$script:moduleRootPath = Split-Path -Path $PSScriptRoot -Parent
$script:testHelpersPath = Join-Path -Path $script:moduleRootPath -ChildPath 'TestHelpers'
Import-Module -Name (Join-Path -Path $script:testHelpersPath -ChildPath 'CommonTestHelper.psm1')
$script:testEnvironment = Enter-DscResourceTestEnvironment `
-DSCResourceModuleName 'PSDscResources' `
-DSCResourceName 'MSFT_ScriptResource' `
-TestType 'Unit'
try
{
InModuleScope 'MSFT_ScriptResource' {
$testUsername = 'TestUsername'
$testPassword = 'TestPassword'
$secureTestPassword = ConvertTo-SecureString -String $testPassword -AsPlainText -Force
$script:testCredenital = New-Object -TypeName 'System.Management.Automation.PSCredential' -ArgumentList @( $testUsername, $secureTestPassword )
Describe 'Script\Get-TargetResource' {
Mock -CommandName 'Invoke-Script' -MockWith { }
Context 'Specified get script returns null' {
$getTargetResourceParameters = @{
GetScript = 'return $null'
TestScript = 'NotUsed'
SetScript = 'NotUsed'
}
It 'Should throw an error for malformed get script' {
$errorMessage = $script:localizedData.GetScriptDidNotReturnHashtable
{ $null = Get-TargetResource @getTargetResourceParameters } | Should -Throw -ExpectedMessage $errorMessage
}
}
Mock -CommandName 'Invoke-Script' -MockWith { return "String" }
Context 'Specified get script returns a string' {
$getTargetResourceParameters = @{
GetScript = 'return "String"'
TestScript = 'NotUsed'
SetScript = 'NotUsed'
}
It 'Should throw an error for malformed get script' {
$errorMessage = $script:localizedData.GetScriptDidNotReturnHashtable
{ $null = Get-TargetResource @getTargetResourceParameters } | Should -Throw -ExpectedMessage $errorMessage
}
}
$testException = New-Object -TypeName 'System.Exception' -ArgumentList @()
$newErrorRecoredArguments = @( $testException, 'Test', [System.Management.Automation.ErrorCategory]::InvalidOperation, $null )
$testErrorRecord = New-Object -TypeName 'System.Management.Automation.ErrorRecord' -ArgumentList $newErrorRecoredArguments
Mock -CommandName 'Invoke-Script' -MockWith { return $testErrorRecord }
Context 'Specified get script throws an error' {
$getTargetResourceParameters = @{
GetScript = 'throw "Error"'
TestScript = 'NotUsed'
SetScript = 'NotUsed'
}
It 'Should throw error from get script' {
{ $null = Get-TargetResource @getTargetResourceParameters } | Should -Throw -ExpectedMessage $testErrorRecord
}
}
$testScriptResult = @{ TestResult = 'Value1' }
Mock -CommandName 'Invoke-Script' -MockWith { return $testScriptResult }
Context 'Specified get script returns a hashtable and Credential not specified' {
$getTargetResourceParameters = @{
GetScript = 'return "something"'
TestScript = 'NotUsed'
SetScript = 'NotUsed'
}
It 'Should not throw' {
{ $null = Get-TargetResource @getTargetResourceParameters } | Should -Not -Throw
}
It 'Should use script execution helper to run script' {
$expectedScriptBlock = [System.Management.Automation.ScriptBlock]::Create($getTargetResourceParameters.GetScript)
$null = Get-TargetResource @getTargetResourceParameters
$invokeScriptParameterFilter = {
$scriptBlockParameterCorrect = $null -eq (Compare-Object -ReferenceObject $expectedScriptBlock.Ast -DifferenceObject $ScriptBlock.Ast)
return $scriptBlockParameterCorrect
}
Assert-MockCalled -CommandName 'Invoke-Script' -ParameterFilter $invokeScriptParameterFilter -Times 1 -Scope 'It'
}
It 'Should return a hashtable' {
$getTargetResourceResult = Get-TargetResource @getTargetResourceParameters
$getTargetResourceResult -is [System.Collections.Hashtable] | Should -BeTrue
}
It 'Should return the output from the specified get script' {
$getTargetResourceResult = Get-TargetResource @getTargetResourceParameters
Compare-Object -ReferenceObject $testScriptResult -DifferenceObject $getTargetResourceResult | Should -Be $null
}
}
Context 'Specified get script returns a hashtable and Credential specified' {
$getTargetResourceParameters = @{
GetScript = 'return "something"'
TestScript = 'NotUsed'
SetScript = 'NotUsed'
Credential = $script:testCredenital
}
It 'Should not throw' {
{ $null = Get-TargetResource @getTargetResourceParameters } | Should -Not -Throw
}
It 'Should use script execution helper to run script with the specified Credential' {
$expectedScriptBlock = [System.Management.Automation.ScriptBlock]::Create($getTargetResourceParameters.GetScript)
$null = Get-TargetResource @getTargetResourceParameters
$invokeScriptParameterFilter = {
$scriptBlockParameterCorrect = $null -eq (Compare-Object -ReferenceObject $expectedScriptBlock.Ast -DifferenceObject $ScriptBlock.Ast)
$credentialParameterCorrect = $null -eq (Compare-Object -ReferenceObject $getTargetResourceParameters.Credential -DifferenceObject $Credential)
return $scriptBlockParameterCorrect -and $credentialParameterCorrect
}
Assert-MockCalled -CommandName 'Invoke-Script' -ParameterFilter $invokeScriptParameterFilter -Times 1 -Scope 'It'
}
It 'Should return a hashtable' {
$getTargetResourceResult = Get-TargetResource @getTargetResourceParameters
$getTargetResourceResult -is [System.Collections.Hashtable] | Should -BeTrue
}
It 'Should return the output from the specified get script' {
$getTargetResourceResult = Get-TargetResource @getTargetResourceParameters
Compare-Object -ReferenceObject $testScriptResult -DifferenceObject $getTargetResourceResult | Should -Be $null
}
}
}
Describe 'Script\Set-TargetResource' {
Mock -CommandName 'Invoke-Script' -MockWith { }
Context 'Specified set script returns correctly and Credential not specified' {
$setTargetResourceParameters = @{
GetScript = 'NotUsed'
TestScript = 'NotUsed'
SetScript = '$assignedVariable = "Value1"'
}
It 'Should not throw' {
{ Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw
}
It 'Should use script execution helper to run script' {
$expectedScriptBlock = [System.Management.Automation.ScriptBlock]::Create($setTargetResourceParameters.SetScript)
Set-TargetResource @setTargetResourceParameters
$invokeScriptParameterFilter = {
$scriptBlockParameterCorrect = $null -eq (Compare-Object -ReferenceObject $expectedScriptBlock.Ast -DifferenceObject $ScriptBlock.Ast)
return $scriptBlockParameterCorrect
}
Assert-MockCalled -CommandName 'Invoke-Script' -ParameterFilter $invokeScriptParameterFilter -Times 1 -Scope 'It'
}
}
Context 'Specified set script returns correctly and Credential specified' {
$setTargetResourceParameters = @{
GetScript = 'NotUsed'
TestScript = 'NotUsed'
SetScript = '$assignedVariable = "Value1"'
Credential = $script:testCredenital
}
It 'Should not throw' {
{ Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw
}
It 'Should use script execution helper to run script with specified Credential' {
$expectedScriptBlock = [System.Management.Automation.ScriptBlock]::Create($setTargetResourceParameters.SetScript)
Set-TargetResource @setTargetResourceParameters
$invokeScriptParameterFilter = {
$scriptBlockParameterCorrect = $null -eq (Compare-Object -ReferenceObject $expectedScriptBlock.Ast -DifferenceObject $ScriptBlock.Ast)
$credentialParameterCorrect = $null -eq (Compare-Object -ReferenceObject $setTargetResourceParameters.Credential -DifferenceObject $Credential)
return $scriptBlockParameterCorrect -and $credentialParameterCorrect
}
Assert-MockCalled -CommandName 'Invoke-Script' -ParameterFilter $invokeScriptParameterFilter -Times 1 -Scope 'It'
}
}
$testException = New-Object -TypeName 'System.Exception' -ArgumentList @()
$newErrorRecoredArguments = @( $testException, 'Test', [System.Management.Automation.ErrorCategory]::InvalidOperation, $null )
$testErrorRecord = New-Object -TypeName 'System.Management.Automation.ErrorRecord' -ArgumentList $newErrorRecoredArguments
Mock -CommandName 'Invoke-Script' -MockWith { return $testErrorRecord }
Context 'Specified set script returns an error' {
$setTargetResourceParameters = @{
GetScript = 'NotUsed'
TestScript = 'NotUsed'
SetScript = 'throw "Error"'
}
It 'Should throw error from set script' {
{ Set-TargetResource @setTargetResourceParameters } | Should -Throw -ExpectedMessage $testErrorRecord
}
}
}
Describe 'Script\Test-TargetResource' {
Mock -CommandName 'Invoke-Script' -MockWith { }
Context 'Specified test script returns null' {
$testTargetResourceParameters = @{
GetScript = 'NotUsed'
TestScript = 'return $null'
SetScript = 'NotUsed'
}
It 'Should throw an error for malformed test script' {
$errorMessage = $script:localizedData.TestScriptDidNotReturnBoolean
{ $null = Test-TargetResource @testTargetResourceParameters } | Should -Throw -ExpectedMessage $errorMessage
}
}
$testException = New-Object -TypeName 'System.Exception' -ArgumentList @()
$newErrorRecoredArguments = @( $testException, 'Test', [System.Management.Automation.ErrorCategory]::InvalidOperation, $null )
$testErrorRecord = New-Object -TypeName 'System.Management.Automation.ErrorRecord' -ArgumentList $newErrorRecoredArguments
Mock -CommandName 'Invoke-Script' -MockWith { return $testErrorRecord }
Context 'Specified test script returns an error' {
$testTargetResourceParameters = @{
GetScript = 'NotUsed'
TestScript = 'throw "Error"'
SetScript = 'NotUsed'
}
It 'Should throw error from test script' {
{ $null = Test-TargetResource @testTargetResourceParameters } | Should -Throw -ExpectedMessage $testErrorRecord
}
}
$expectedBoolean = $true
Mock -CommandName 'Invoke-Script' -MockWith { return $expectedBoolean }
Context 'Specified test script returns one boolean and Credential not specified' {
$testTargetResourceParameters = @{
GetScript = 'NotUsed'
TestScript = 'return $true'
SetScript = 'NotUsed'
}
It 'Should not throw' {
{ $null = Test-TargetResource @testTargetResourceParameters } | Should -Not -Throw
}
It 'Should use script execution helper to run script' {
$expectedScriptBlock = [System.Management.Automation.ScriptBlock]::Create($testTargetResourceParameters.TestScript)
$null = Test-TargetResource @testTargetResourceParameters
$invokeScriptParameterFilter = {
$scriptBlockParameterCorrect = $null -eq (Compare-Object -ReferenceObject $expectedScriptBlock.Ast -DifferenceObject $ScriptBlock.Ast)
return $scriptBlockParameterCorrect
}
Assert-MockCalled -CommandName 'Invoke-Script' -ParameterFilter $invokeScriptParameterFilter -Times 1 -Scope 'It'
}
It 'Should return the expected boolean' {
$testTargetResourceResult = Test-TargetResource @testTargetResourceParameters
$testTargetResourceResult | Should -Be $expectedBoolean
}
}
Context 'Specified test script returns one boolean and Credential specified' {
$testTargetResourceParameters = @{
GetScript = 'NotUsed'
TestScript = 'return $true'
SetScript = 'NotUsed'
Credential = $script:testCredenital
}
It 'Should not throw' {
{ $null = Test-TargetResource @testTargetResourceParameters } | Should -Not -Throw
}
It 'Should use script execution helper to run script with specified Credential' {
$expectedScriptBlock = [System.Management.Automation.ScriptBlock]::Create($testTargetResourceParameters.TestScript)
$null = Test-TargetResource @testTargetResourceParameters
$invokeScriptParameterFilter = {
$scriptBlockParameterCorrect = $null -eq (Compare-Object -ReferenceObject $expectedScriptBlock.Ast -DifferenceObject $ScriptBlock.Ast)
$credentialParameterCorrect = $null -eq (Compare-Object -ReferenceObject $testTargetResourceParameters.Credential -DifferenceObject $Credential)
return $scriptBlockParameterCorrect -and $credentialParameterCorrect
}
Assert-MockCalled -CommandName 'Invoke-Script' -ParameterFilter $invokeScriptParameterFilter -Times 1 -Scope 'It'
}
It 'Should return the expected boolean' {
$testTargetResourceResult = Test-TargetResource @testTargetResourceParameters
$testTargetResourceResult | Should -Be $expectedBoolean
}
}
$expectedBoolean = $false
Mock -CommandName 'Invoke-Script' -MockWith { return @( (-not $expectedBoolean), $expectedBoolean ) }
Context 'Specified test script returns multiple booleans' {
$testTargetResourceParameters = @{
GetScript = 'NotUsed'
TestScript = 'return $true, $false'
SetScript = 'NotUsed'
}
It 'Should not throw' {
{ $null = Test-TargetResource @testTargetResourceParameters } | Should -Not -Throw
}
It 'Should use script execution helper to run script' {
$expectedScriptBlock = [System.Management.Automation.ScriptBlock]::Create($testTargetResourceParameters.TestScript)
$null = Test-TargetResource @testTargetResourceParameters
$invokeScriptParameterFilter = {
$scriptBlockParameterCorrect = $null -eq (Compare-Object -ReferenceObject $expectedScriptBlock.Ast -DifferenceObject $ScriptBlock.Ast)
return $scriptBlockParameterCorrect
}
Assert-MockCalled -CommandName 'Invoke-Script' -ParameterFilter $invokeScriptParameterFilter -Times 1 -Scope 'It'
}
It 'Should return the expected boolean' {
$testTargetResourceResult = Test-TargetResource @testTargetResourceParameters
$testTargetResourceResult | Should -Be $expectedBoolean
}
}
Mock -CommandName 'Invoke-Script' -MockWith { return 'Value1' }
Context 'Specified test script returns a string' {
$testTargetResourceParameters = @{
GetScript = 'NotUsed'
TestScript = 'return "MyString"'
SetScript = 'NotUsed'
}
It 'Should throw an error for malformed test script' {
$errorMessage = $script:localizedData.TestScriptDidNotReturnBoolean
{ $null = Test-TargetResource @testTargetResourceParameters } | Should -Throw -ExpectedMessage $errorMessage
}
}
}
Describe 'Script\Invoke-Script' {
Mock -CommandName 'Invoke-Command' -MockWith { }
Context 'Specified script throws an error' {
$testErrorMessage = 'Script execution helper test error message'
$scriptExecutionHelperParameters = @{
ScriptBlock = { throw $testErrorMessage }
}
It 'Should not throw' {
{ $null = Invoke-Script @scriptExecutionHelperParameters } | Should -Not -Throw
}
It 'Should return an error record' {
$scriptExecutionHelperResult = Invoke-Script @scriptExecutionHelperParameters
$scriptExecutionHelperResult -is [System.Management.Automation.ErrorRecord] | Should -BeTrue
}
It 'Should return an error record' {
$scriptExecutionHelperResult = Invoke-Script @scriptExecutionHelperParameters
$scriptExecutionHelperResult -is [System.Management.Automation.ErrorRecord] | Should -BeTrue
}
It 'Should return error with expected message from script' {
$scriptExecutionHelperResult = Invoke-Script @scriptExecutionHelperParameters
$scriptExecutionHelperResult.Exception.Message | Should -Be $testErrorMessage
}
}
Context 'Specified script returns nothing and Credential specified' {
$scriptExecutionHelperParameters = @{
ScriptBlock = { return $null }
Credential = $script:testCredenital
}
It 'Should not throw' {
{ $null = Invoke-Script @scriptExecutionHelperParameters } | Should -Not -Throw
}
It 'Should run script through Invoke-Command using the specified Credential' {
$null = Invoke-Script @scriptExecutionHelperParameters
$invokeCommandParameterFilter = {
$scriptBlockParameterCorrect = $null -eq (Compare-Object -ReferenceObject $scriptExecutionHelperParameters.ScriptBlock.Ast -DifferenceObject $ScriptBlock.Ast)
$credentialParameterCorrect = $null -eq (Compare-Object -ReferenceObject $scriptExecutionHelperParameters.Credential -DifferenceObject $Credential)
return $scriptBlockParameterCorrect -and $credentialParameterCorrect
}
Assert-MockCalled -CommandName 'Invoke-Command' -ParameterFilter $invokeCommandParameterFilter -Times 1 -Scope 'It'
}
It 'Should return nothing' {
$scriptExecutionHelperResult = Invoke-Script @scriptExecutionHelperParameters
$scriptExecutionHelperResult | Should -Be $null
}
}
Context 'Specified script returns a result and Credential not specified' {
$testScriptResult = 'Script result'
$scriptExecutionHelperParameters = @{
ScriptBlock = { return $testScriptResult }
}
It 'Should not run script through Invoke-Command' {
$null = Invoke-Script @scriptExecutionHelperParameters
Assert-MockCalled -CommandName 'Invoke-Command' -Times 0 -Scope 'It'
}
It 'Should return result of script' {
$scriptExecutionHelperResult = Invoke-Script @scriptExecutionHelperParameters
$scriptExecutionHelperResult | Should -Be $testScriptResult
}
}
}
}
}
finally
{
Exit-DscResourceTestEnvironment -TestEnvironment $script:testEnvironment
}