CI process performance pre-v0.5.0 (#132)

* Split up tests into smaller files
* Exclude PR builds from running SonarCloud
* Additional Pester test performance and code improvements
This commit is contained in:
Bernie White 2019-04-25 14:22:48 +10:00 коммит произвёл GitHub
Родитель 089eb16307
Коммит 185b57c6cd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 555 добавлений и 457 удалений

Просмотреть файл

@ -37,22 +37,22 @@ steps:
displayName: 'Benchmark'
condition: eq(variables['benchmark'], 'true')
# Run SonarCloud analysis
- powershell: dotnet tool install --global dotnet-sonarscanner
displayName: 'Install Sonar scanner'
condition: eq(variables['analysis'], 'true')
condition: and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['analysis'], 'true'))
- script: dotnet sonarscanner begin /k:"BernieWhite_PSRule" /o:"berniewhite-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login=$(sonarQubeToken) /v:"$(Build.BuildNumber)"
displayName: 'Prepare SonarCloud'
condition: eq(variables['analysis'], 'true')
condition: and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['analysis'], 'true'))
- script: dotnet build
displayName: 'Build solution for analysis'
condition: eq(variables['analysis'], 'true')
condition: and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['analysis'], 'true'))
- script: dotnet sonarscanner end /d:sonar.login=$(sonarQubeToken)
displayName: 'Complete SonarCloud'
condition: eq(variables['analysis'], 'true')
condition: and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['analysis'], 'true'))
# DotNet test results
- task: PublishTestResults@2

Просмотреть файл

@ -11,6 +11,10 @@ param (
$ErrorActionPreference = 'Stop';
Set-StrictMode -Version latest;
if ($Env:SYSTEM_DEBUG -eq 'true') {
$VerbosePreference = 'Continue';
}
# Setup tests paths
$rootPath = $PWD;
@ -18,24 +22,23 @@ Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule) -Force;
$here = (Resolve-Path $PSScriptRoot).Path;
Describe 'PSRule -- AllOf keyword' -Tag 'AllOf' {
Context 'AllOf' {
$testObject = @{
Key = 'Value'
}
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'AllOfTest','AllOfTestNegative';
It 'Should succeed on all positive conditions' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'AllOfTest';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $True;
$result.RuleName | Should -Be 'AllOfTest';
$filteredResult = $result | Where-Object { $_.RuleName -eq 'AllOfTest' };
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.IsSuccess() | Should -Be $True;
}
It 'Should fail on any negative conditions' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'AllOfTestNegative';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $False;
$result.RuleName | Should -Be 'AllOfTestNegative';
$filteredResult = $result | Where-Object { $_.RuleName -eq 'AllOfTestNegative' };
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.IsSuccess() | Should -Be $False;
}
}
}

Просмотреть файл

@ -11,6 +11,10 @@ param (
$ErrorActionPreference = 'Stop';
Set-StrictMode -Version latest;
if ($Env:SYSTEM_DEBUG -eq 'true') {
$VerbosePreference = 'Continue';
}
# Setup tests paths
$rootPath = $PWD;
@ -18,26 +22,23 @@ Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule) -Force;
$here = (Resolve-Path $PSScriptRoot).Path;
Describe 'PSRule -- AnyOf keyword' -Tag 'AnyOf' {
Context 'AnyOf' {
$testObject = @{
Key = 'Value'
}
It 'Should succeed on any positive conditions' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'AnyOfTest', 'AnyOfTestNegative';
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'AnyOfTest';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $True;
$result.RuleName | Should -Be 'AnyOfTest';
It 'Should succeed on any positive conditions' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'AnyOfTest' };
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.IsSuccess() | Should -Be $True;
}
It 'Should fail with all negative conditions' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'AnyOfTestNegative';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $False;
$result.RuleName | Should -Be 'AnyOfTestNegative';
$filteredResult = $result | Where-Object { $_.RuleName -eq 'AnyOfTestNegative' };
$filteredResult | Should -Not -BeNullOrEmpty;
$filteredResult.IsSuccess() | Should -Be $False;
}
}
}

Просмотреть файл

@ -1,5 +1,5 @@
#
# Unit tests for core PSRule functionality
# Unit tests for core PSRule cmdlets
#
[CmdletBinding()]
@ -28,6 +28,8 @@ $Null = New-Item -Path $outputPath -ItemType Directory -Force;
#region Invoke-PSRule
Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
$ruleFilePath = (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1');
Context 'With defaults' {
$testObject = [PSCustomObject]@{
Name = 'TestObject1'
@ -36,14 +38,14 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
$testObject.PSObject.TypeNames.Insert(0, 'TestType');
It 'Returns passed' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1';
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $True;
$result.TargetName | Should -Be 'TestObject1';
}
It 'Returns failure' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile2';
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile2';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $False;
$result.TargetName | Should -Be 'TestObject1';
@ -51,39 +53,49 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
It 'Returns inconclusive' {
$option = @{ 'Execution.InconclusiveWarning' = $False };
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile3' -Outcome All -Option $option;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile3' -Outcome All -Option $option;
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $False;
$result.OutcomeReason | Should -Be 'Inconclusive';
}
It 'Propagates PowerShell logging' {
# Warnings
$Null = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFileWithLogging.Rule.ps1') -Name 'WithWarning' -WarningVariable outWarnings -WarningAction SilentlyContinue;
$withLoggingRulePath = (Join-Path -Path $here -ChildPath 'FromFileWithLogging.Rule.ps1');
$loggingParams = @{
Path = $withLoggingRulePath
Name = 'WithWarning','WithError','WithInformation','WithVerbose'
InformationVariable = 'outInformation'
WarningVariable = 'outWarnings'
ErrorVariable = 'outErrors'
WarningAction = 'SilentlyContinue'
ErrorAction = 'SilentlyContinue'
InformationAction = 'SilentlyContinue'
}
$outVerbose = $testObject | Invoke-PSRule @loggingParams -Verbose 4>&1 | Where-Object {
$_ -is [System.Management.Automation.VerboseRecord] -and
$_.Message -like "* verbose message"
};
# Warnings, errors, information, verbose
$warningMessages = $outWarnings.ToArray();
$warningMessages.Length | Should -Be 2;
$warningMessages[0] | Should -Be 'Script warning message';
$warningMessages[1] | Should -Be 'Rule warning message';
# Errors
$Null = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFileWithLogging.Rule.ps1') -Name 'WithError' -ErrorVariable outErrors -ErrorAction SilentlyContinue -WarningAction SilentlyContinue;
$outErrors | Should -Be 'Rule error message';
# Verbose
$outVerbose = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFileWithLogging.Rule.ps1') -Name 'WithVerbose' -WarningAction SilentlyContinue -Verbose 4>&1 | Where-Object {
$_ -is [System.Management.Automation.VerboseRecord] -and
$_.Message -like "* verbose message"
};
$outVerbose.Length | Should -Be 2;
$outVerbose[0] | Should -Be 'Script verbose message';
$outVerbose[1] | Should -Be 'Rule verbose message';
# Information
$Null = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFileWithLogging.Rule.ps1') -Name 'WithInformation' -InformationVariable outInformation -InformationAction Continue -WarningAction SilentlyContinue 6>&1;
$informationMessages = $outInformation.ToArray();
$informationMessages.Length | Should -Be 2;
$informationMessages[0] | Should -Be 'Script information message';
$informationMessages[1] | Should -Be 'Rule information message';
# Verbose
$outVerbose.Length | Should -Be 2;
$outVerbose[0] | Should -Be 'Script verbose message';
$outVerbose[1] | Should -Be 'Rule verbose message';
}
It 'Propagates PowerShell exceptions' {
@ -109,20 +121,20 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
It 'Processes rule tags' {
# Ensure that rules can be selected by tag and that tags are mapped back to the rule results
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Tag @{ feature = 'tag' };
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Tag @{ feature = 'tag' };
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 5;
$result.Tag.feature | Should -BeIn 'tag';
# Ensure that tag selection is and'ed together, requiring all tags to be selected
# Tag values, will be matched without case sensitivity, but values are case sensitive
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Tag @{ feature = 'tag'; severity = 'critical'; };
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Tag @{ feature = 'tag'; severity = 'critical'; };
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 2;
$result.Tag.feature | Should -BeIn 'tag';
# Using a * wildcard in tag filter, matches rules with the tag regardless of value
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Tag @{ feature = 'tag'; severity = '*'; };
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Tag @{ feature = 'tag'; severity = '*'; };
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 4;
$result.Tag.feature | Should -BeIn 'tag';
@ -130,7 +142,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
}
It 'Processes rule script preconditions' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Tag @{ category = 'precondition-if' } -Outcome All;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Tag @{ category = 'precondition-if' } -Outcome All;
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 2;
($result | Where-Object -FilterScript { $_.RuleName -eq 'WithPreconditionTrue' }).Outcome | Should -Be 'Pass';
@ -138,7 +150,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
}
It 'Processes rule type preconditions' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Tag @{ category = 'precondition-type' } -Outcome All;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Tag @{ category = 'precondition-type' } -Outcome All;
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 2;
($result | Where-Object -FilterScript { $_.RuleName -eq 'WithTypeTrue' }).Outcome | Should -Be 'Pass';
@ -146,7 +158,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
}
It 'Processes rule dependencies' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name WithDependency1 -Outcome All;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name WithDependency1 -Outcome All;
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 5;
($result | Where-Object -FilterScript { $_.RuleName -eq 'WithDependency5' }).Outcome | Should -Be 'Fail';
@ -167,7 +179,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
)
$option = New-PSRuleOption -SuppressTargetName @{ FromFile1 = 'TestObject1'; FromFile2 = 'testobject1'; };
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Option $option -Name 'FromFile1', 'FromFile2' -Outcome All;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Option $option -Name 'FromFile1', 'FromFile2' -Outcome All;
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 4;
$result | Should -BeOfType PSRule.Rules.RuleRecord;
@ -177,7 +189,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
It 'Processes configuration' {
$option = New-PSRuleOption -BaselineConfiguration @{ Value1 = 1 };
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Option $option -Name WithConfiguration;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Option $option -Name WithConfiguration;
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $True;
}
@ -197,14 +209,14 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
It 'Returns detail' {
$option = @{ 'Execution.InconclusiveWarning' = $False };
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Tag @{ category = 'group1' } -As Detail -Option $option;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Tag @{ category = 'group1' } -As Detail -Option $option;
$result | Should -Not -BeNullOrEmpty;
$result | Should -BeOfType PSRule.Rules.RuleRecord;
}
It 'Returns summary' {
$option = @{ 'Execution.InconclusiveWarning' = $False };
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Tag @{ category = 'group1' } -As Summary -Outcome All -Option $option;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Tag @{ category = 'group1' } -As Summary -Outcome All -Option $option;
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 4;
$result | Should -BeOfType PSRule.Rules.RuleSummaryRecord;
@ -221,7 +233,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
It 'Returns filtered summary' {
$option = @{ 'Execution.InconclusiveWarning' = $False };
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Tag @{ category = 'group1' } -As Summary -Outcome Fail -Option $option;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Tag @{ category = 'group1' } -As Summary -Outcome Fail -Option $option;
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 2;
$result | Should -BeOfType PSRule.Rules.RuleSummaryRecord;
@ -233,7 +245,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
Context 'Using -Format' {
It 'Yaml String' {
$yaml = Get-Content -Path (Join-Path -Path $here -ChildPath 'ObjectFromFile.yaml') -Raw;
$result = @(Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'WithFormat' -InputObject $yaml -Format Yaml);
$result = @(Invoke-PSRule -Path $ruleFilePath -Name 'WithFormat' -InputObject $yaml -Format Yaml);
$result | Should -Not -BeNullOrEmpty;
$result.Length | Should -Be 2;
$result | Should -BeOfType PSRule.Rules.RuleRecord;
@ -242,7 +254,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
It 'Yaml FileInfo' {
$file = Get-ChildItem -Path (Join-Path -Path $here -ChildPath 'ObjectFromFile.yaml') -File;
$result = @(Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'WithFormat' -InputObject $file -Format Yaml);
$result = @(Invoke-PSRule -Path $ruleFilePath -Name 'WithFormat' -InputObject $file -Format Yaml);
$result | Should -Not -BeNullOrEmpty;
$result.Length | Should -Be 2;
$result | Should -BeOfType PSRule.Rules.RuleRecord;
@ -251,7 +263,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
It 'Json String' {
$json = Get-Content -Path (Join-Path -Path $here -ChildPath 'ObjectFromFile.json') -Raw;
$result = @(Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'WithFormat' -InputObject $json -Format Json);
$result = @(Invoke-PSRule -Path $ruleFilePath -Name 'WithFormat' -InputObject $json -Format Json);
$result | Should -Not -BeNullOrEmpty;
$result.Length | Should -Be 2;
$result | Should -BeOfType PSRule.Rules.RuleRecord;
@ -260,7 +272,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
It 'Json FileInfo' {
$file = Get-ChildItem -Path (Join-Path -Path $here -ChildPath 'ObjectFromFile.json') -File;
$result = @(Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'WithFormat' -InputObject $file -Format Json);
$result = @(Invoke-PSRule -Path $ruleFilePath -Name 'WithFormat' -InputObject $file -Format Json);
$result | Should -Not -BeNullOrEmpty;
$result.Length | Should -Be 2;
$result | Should -BeOfType PSRule.Rules.RuleRecord;
@ -271,7 +283,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
Context 'Using -ObjectPath' {
It 'Processes nested objects' {
$yaml = Get-Content -Path (Join-Path -Path $here -ChildPath 'ObjectFromNestedFile.yaml') -Raw;
$result = @(Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'WithFormat' -InputObject $yaml -Format Yaml -ObjectPath items);
$result = @(Invoke-PSRule -Path $ruleFilePath -Name 'WithFormat' -InputObject $yaml -Format Yaml -ObjectPath items);
$result | Should -Not -BeNullOrEmpty;
$result.Length | Should -Be 2;
$result | Should -BeOfType PSRule.Rules.RuleRecord;
@ -287,7 +299,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
$testObject.PSObject.TypeNames.Insert(0, 'TestType');
It 'Yaml' {
$result = @($testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1' -OutputFormat Yaml);
$result = @($testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1' -OutputFormat Yaml);
$result | Should -Not -BeNullOrEmpty;
$result | Should -BeOfType System.String;
$result -cmatch 'ruleName: FromFile1' | Should -Be $True;
@ -299,7 +311,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
}
It 'Json' {
$result = @($testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1' -OutputFormat Json);
$result = @($testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1' -OutputFormat Json);
$result | Should -Not -BeNullOrEmpty;
$result | Should -BeOfType System.String;
$result -cmatch '"ruleName":"FromFile1"' | Should -Be $True;
@ -312,7 +324,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
Context 'Using -InputFile' {
It 'Yaml' {
$result = @(Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'WithFormat' -InputPath (Join-Path -Path $here -ChildPath 'ObjectFromFile*.yaml'));
$result = @(Invoke-PSRule -Path $ruleFilePath -Name 'WithFormat' -InputPath (Join-Path -Path $here -ChildPath 'ObjectFromFile*.yaml'));
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -BeIn $True;
$result.Length | Should -Be 3;
@ -321,7 +333,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
}
It 'Json' {
$result = @(Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'WithFormat' -InputPath (Join-Path -Path $here -ChildPath 'ObjectFromFile.json'));
$result = @(Invoke-PSRule -Path $ruleFilePath -Name 'WithFormat' -InputPath (Join-Path -Path $here -ChildPath 'ObjectFromFile.json'));
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -BeIn $True;
$result.Length | Should -Be 2;
@ -341,15 +353,15 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
return $True;
}
$Null = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'ConstrainedTest1';
$Null = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'ConstrainedTest1';
Assert-MockCalled -CommandName IsDeviceGuardEnabled -ModuleName PSRule -Times 1;
}
# Check that '[Console]::WriteLine('Should fail')' is not executed
It 'Should fail to execute blocked code' {
$option = @{ 'execution.mode' = 'ConstrainedLanguage' };
{ $Null = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'ConstrainedTest2' -Option $option -ErrorAction Stop } | Should -Throw 'Cannot invoke method. Method invocation is supported only on core types in this language mode.';
{ $Null = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'ConstrainedTest3' -Option $option -ErrorAction Stop } | Should -Throw 'Cannot invoke method. Method invocation is supported only on core types in this language mode.';
{ $Null = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'ConstrainedTest2' -Option $option -ErrorAction Stop } | Should -Throw 'Cannot invoke method. Method invocation is supported only on core types in this language mode.';
{ $Null = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'ConstrainedTest3' -Option $option -ErrorAction Stop } | Should -Throw 'Cannot invoke method. Method invocation is supported only on core types in this language mode.';
$bindFn = {
param ($TargetObject)
@ -358,7 +370,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
}
$option = New-PSRuleOption -Option @{ 'execution.mode' = 'ConstrainedLanguage' } -BindTargetName $bindFn;
{ $Null = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'ConstrainedTest1' -Option $option -ErrorAction Stop } | Should -Throw 'Binding functions are not supported in this language mode.';
{ $Null = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'ConstrainedTest1' -Option $option -ErrorAction Stop } | Should -Throw 'Binding functions are not supported in this language mode.';
}
}
@ -370,7 +382,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
Value = 1
}
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1';
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $True;
$result.TargetName | Should -Be 'ObjectTargetName';
@ -381,7 +393,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
Name = 'TestObject1'
}
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1';
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $True;
$result.TargetName | Should -Be 'TestObject1';
@ -392,7 +404,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
NotName = 'TestObject1'
}
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1';
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -BeIn $True;
$result.TargetName | Should -BeIn 'f209c623345144be61087d91f30c17b01c6e86d2';
@ -438,7 +450,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
}
$option = New-PSRuleOption -Option @{ 'Binding.TargetName' = 'ResourceName', 'AlternateName', 'Metadata.Name'; 'Binding.IgnoreCase' = $True } -BindTargetName $bindFn;
$result = $testObject | Invoke-PSRule -Option $option -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1';
$result = $testObject | Invoke-PSRule -Option $option -Path $ruleFilePath -Name 'FromFile1';
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 5;
$result[0].TargetName | Should -Be 'ResourceName';
@ -448,7 +460,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
$result[4].TargetName | Should -Be 'MetadataName';
$option = New-PSRuleOption -Option @{ 'Binding.TargetName' = 'ResourceName', 'AlternateName'; 'Binding.IgnoreCase' = $False } -BindTargetName $bindFn;
$result = $testObject[0..1] | Invoke-PSRule -Option $option -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1';
$result = $testObject[0..1] | Invoke-PSRule -Option $option -Path $ruleFilePath -Name 'FromFile1';
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 2;
$result[0].TargetName | Should -Be 'AlternateName';
@ -465,29 +477,29 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
$testObject.PSObject.TypeNames.Insert(0, 'TestType');
It 'Uses default TypeName' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1';
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1';
$result | Should -Not -BeNullOrEmpty;
$result.TargetType | Should -Be 'TestType';
}
It 'Binds to custom type property by order' {
$option = @{ 'Binding.TargetType' = 'ResourceType' };
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1' -Option $option;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1' -Option $option;
$result | Should -Not -BeNullOrEmpty;
$result.TargetType | Should -Be 'ResourceType';
$option = @{ 'Binding.TargetType' = 'NotType', 'ResourceType' };
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1' -Option $option;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1' -Option $option;
$result | Should -Not -BeNullOrEmpty;
$result.TargetType | Should -Be 'ResourceType';
$option = @{ 'Binding.TargetType' = 'ResourceType', 'kind' };
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1' -Option $option;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1' -Option $option;
$result | Should -Not -BeNullOrEmpty;
$result.TargetType | Should -Be 'ResourceType';
$option = @{ 'Binding.TargetType' = 'kind', 'ResourceType' };
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1' -Option $option;
$result = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'FromFile1' -Option $option;
$result | Should -Not -BeNullOrEmpty;
$result.TargetType | Should -Be 'kind';
}
@ -507,7 +519,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
}
$option = New-PSRuleOption -Option @{ 'Binding.TargetType' = 'kind' } -BindTargetType $bindFn;
$result = $testObject | Invoke-PSRule -Option $option -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1';
$result = $testObject | Invoke-PSRule -Option $option -Path $ruleFilePath -Name 'FromFile1';
$result | Should -Not -BeNullOrEmpty;
$result.TargetType | Should -Be 'OtherType';
}
@ -521,7 +533,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
# Warning
$option = New-PSRuleOption -Option @{ 'Logging.RuleFail' = 'Warning'};
$result = $testObject | Invoke-PSRule -Option $option -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile2' -WarningVariable outWarning -WarningAction SilentlyContinue;
$result = $testObject | Invoke-PSRule -Option $option -Path $ruleFilePath -Name 'FromFile2' -WarningVariable outWarning -WarningAction SilentlyContinue;
$messages = @($outwarning);
$result | Should -Not -BeNullOrEmpty;
$result.Outcome | Should -Be 'Fail';
@ -530,7 +542,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
# Error
$option = New-PSRuleOption -Option @{ 'Logging.RuleFail' = 'Error'};
$result = $testObject | Invoke-PSRule -Option $option -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile2' -ErrorVariable outError -ErrorAction SilentlyContinue;
$result = $testObject | Invoke-PSRule -Option $option -Path $ruleFilePath -Name 'FromFile2' -ErrorVariable outError -ErrorAction SilentlyContinue;
$messages = @($outError);
$result | Should -Not -BeNullOrEmpty;
$result.Outcome | Should -Be 'Fail';
@ -539,7 +551,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
# Information
$option = New-PSRuleOption -Option @{ 'Logging.RuleFail' = 'Information'};
$result = $testObject | Invoke-PSRule -Option $option -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile2' -InformationVariable outInformation;
$result = $testObject | Invoke-PSRule -Option $option -Path $ruleFilePath -Name 'FromFile2' -InformationVariable outInformation;
$messages = @($outInformation);
$result | Should -Not -BeNullOrEmpty;
$result.Outcome | Should -Be 'Fail';
@ -554,7 +566,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
# Warning
$option = New-PSRuleOption -Option @{ 'Logging.RulePass' = 'Warning'};
$result = $testObject | Invoke-PSRule -Option $option -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1' -WarningVariable outWarning -WarningAction SilentlyContinue;
$result = $testObject | Invoke-PSRule -Option $option -Path $ruleFilePath -Name 'FromFile1' -WarningVariable outWarning -WarningAction SilentlyContinue;
$messages = @($outwarning);
$result | Should -Not -BeNullOrEmpty;
$result.Outcome | Should -Be 'Pass';
@ -563,7 +575,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
# Error
$option = New-PSRuleOption -Option @{ 'Logging.RulePass' = 'Error'};
$result = $testObject | Invoke-PSRule -Option $option -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1' -ErrorVariable outError -ErrorAction SilentlyContinue;
$result = $testObject | Invoke-PSRule -Option $option -Path $ruleFilePath -Name 'FromFile1' -ErrorVariable outError -ErrorAction SilentlyContinue;
$messages = @($outError);
$result | Should -Not -BeNullOrEmpty;
$result.Outcome | Should -Be 'Pass';
@ -572,7 +584,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
# Information
$option = New-PSRuleOption -Option @{ 'Logging.RulePass' = 'Information'};
$result = $testObject | Invoke-PSRule -Option $option -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1' -InformationVariable outInformation;
$result = $testObject | Invoke-PSRule -Option $option -Path $ruleFilePath -Name 'FromFile1' -InformationVariable outInformation;
$messages = @($outInformation);
$result | Should -Not -BeNullOrEmpty;
$result.Outcome | Should -Be 'Pass';
@ -587,6 +599,8 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
#region Test-PSRuleTarget
Describe 'Test-PSRuleTarget' -Tag 'Test-PSRuleTarget','Common' {
$ruleFilePath = (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1');
Context 'With defaults' {
$testObject = [PSCustomObject]@{
Name = 'TestObject1'
@ -594,14 +608,14 @@ Describe 'Test-PSRuleTarget' -Tag 'Test-PSRuleTarget','Common' {
It 'Returns boolean' {
# Check passing rule
$result = $testObject | Test-PSRuleTarget -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1';
$result = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'FromFile1';
$result | Should -Not -BeNullOrEmpty;
$result | Should -BeOfType System.Boolean;
$result | Should -Be $True;
# Check result with one failing rule
$option = @{ 'Execution.InconclusiveWarning' = $False };
$result = $testObject | Test-PSRuleTarget -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1', 'FromFile2', 'FromFile3' -Option $option;
$result = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'FromFile1', 'FromFile2', 'FromFile3' -Option $option;
$result | Should -Not -BeNullOrEmpty;
$result | Should -BeOfType System.Boolean;
$result | Should -Be $False;
@ -609,7 +623,7 @@ Describe 'Test-PSRuleTarget' -Tag 'Test-PSRuleTarget','Common' {
It 'Returns warnings on inconclusive' {
# Check result with an inconculsive rule
$result = $testObject | Test-PSRuleTarget -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile3' -WarningVariable outWarnings -WarningAction SilentlyContinue;
$result = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'FromFile3' -WarningVariable outWarnings -WarningAction SilentlyContinue;
$result | Should -Not -BeNullOrEmpty;
$result | Should -BeOfType System.Boolean;
$result | Should -Be $False;
@ -618,7 +632,7 @@ Describe 'Test-PSRuleTarget' -Tag 'Test-PSRuleTarget','Common' {
It 'Returns warnings on no rules' {
# Check result with no matching rules
$result = $testObject | Test-PSRuleTarget -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'NotARule' -WarningVariable outWarnings -WarningAction SilentlyContinue;
$result = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'NotARule' -WarningVariable outWarnings -WarningAction SilentlyContinue;
$result | Should -BeNullOrEmpty;
$outWarnings | Should -Be 'Could not find a matching rule. Please check that Path, Name and Tag parameters are correct.';
}
@ -637,13 +651,45 @@ Describe 'Test-PSRuleTarget' -Tag 'Test-PSRuleTarget','Common' {
It 'Returns warning when not processed' {
# Check result with no rules matching precondition
$result = $testObject | Test-PSRuleTarget -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'WithPreconditionFalse' -WarningVariable outWarnings -WarningAction SilentlyContinue;
$result = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'WithPreconditionFalse' -WarningVariable outWarnings -WarningAction SilentlyContinue;
$result | Should -Not -BeNullOrEmpty;
$result | Should -BeOfType System.Boolean;
$result | Should -Be $True;
$outWarnings | Should -Be "Target object 'TestObject1' has not been processed because no matching rules were found.";
}
}
Context 'With constrained language' {
$testObject = [PSCustomObject]@{
Name = 'TestObject1'
Value = 1
}
It 'Checks if DeviceGuard is enabled' {
Mock -CommandName IsDeviceGuardEnabled -ModuleName PSRule -Verifiable -MockWith {
return $True;
}
$Null = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'ConstrainedTest1';
Assert-MockCalled -CommandName IsDeviceGuardEnabled -ModuleName PSRule -Times 1;
}
# Check that '[Console]::WriteLine('Should fail')' is not executed
It 'Should fail to execute blocked code' {
$option = @{ 'execution.mode' = 'ConstrainedLanguage' };
{ $Null = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'ConstrainedTest2' -Option $option -ErrorAction Stop } | Should -Throw 'Cannot invoke method. Method invocation is supported only on core types in this language mode.';
{ $Null = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'ConstrainedTest3' -Option $option -ErrorAction Stop } | Should -Throw 'Cannot invoke method. Method invocation is supported only on core types in this language mode.';
$bindFn = {
param ($TargetObject)
$Null = [Console]::WriteLine('Should fail');
return 'BadName';
}
$option = New-PSRuleOption -Option @{ 'execution.mode' = 'ConstrainedLanguage' } -BindTargetName $bindFn;
{ $Null = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'ConstrainedTest1' -Option $option -ErrorAction Stop } | Should -Throw 'Binding functions are not supported in this language mode.';
}
}
}
#endregion Test-PSRuleTarget
@ -651,29 +697,31 @@ Describe 'Test-PSRuleTarget' -Tag 'Test-PSRuleTarget','Common' {
#region Get-PSRule
Describe 'Get-PSRule' -Tag 'Get-PSRule','Common' {
$ruleFilePath = (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1');
Context 'Using -Path' {
It 'Returns rules' {
# Get a list of rules
$result = Get-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1');
$result = Get-PSRule -Path $ruleFilePath;
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -BeGreaterThan 0;
}
It 'Filters by name' {
$result = Get-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1', 'FromFile3';
$result = Get-PSRule -Path $ruleFilePath -Name 'FromFile1', 'FromFile3';
$result | Should -Not -BeNullOrEmpty;
$result.Count | Should -Be 2;
$result.RuleName | Should -BeIn @('FromFile1', 'FromFile3');
}
It 'Filters by tag' {
$result = Get-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Tag @{ Test = "Test1" };
$result = Get-PSRule -Path $ruleFilePath -Tag @{ Test = 'Test1' };
$result | Should -Not -BeNullOrEmpty;
$result.RuleName | Should -Be 'FromFile1';
}
It 'Reads metadata' {
$result = Get-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'FromFile1';
$result = Get-PSRule -Path $ruleFilePath -Name 'FromFile1';
$result | Should -Not -BeNullOrEmpty;
$result.RuleName | Should -Be 'FromFile1';
$result.Description | Should -Be 'Test rule 1';
@ -717,7 +765,7 @@ Describe 'Get-PSRule' -Tag 'Get-PSRule','Common' {
return $True;
}
$Null = Get-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'ConstrainedTest1';
$Null = Get-PSRule -Path $ruleFilePath -Name 'ConstrainedTest1';
Assert-MockCalled -CommandName IsDeviceGuardEnabled -ModuleName PSRule -Times 1;
}
@ -729,365 +777,3 @@ Describe 'Get-PSRule' -Tag 'Get-PSRule','Common' {
}
#endregion Get-PSRule
#region New-PSRuleOption
Describe 'New-PSRuleOption' -Tag 'Option','Common','New-PSRuleOption' {
Context 'Read Baseline.RuleName' {
It 'from default' {
$option = New-PSRuleOption;
$option.Baseline.RuleName | Should -Be $Null;
}
It 'from Hashtable' {
# With single item
$option = New-PSRuleOption -Option @{ 'Baseline.RuleName' = 'rule1' };
$option.Baseline.RuleName | Should -BeIn 'rule1';
# With array
$option = New-PSRuleOption -Option @{ 'Baseline.RuleName' = 'rule1', 'rule2' };
$option.Baseline.RuleName | Should -BeIn 'rule1', 'rule2';
}
It 'from YAML' {
# With single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Baseline.RuleName | Should -BeIn 'rule1';
# With array
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests2.yml');
$option.Baseline.RuleName | Should -BeIn 'rule1', 'rule2';
# With flat single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests3.yml');
$option.Baseline.RuleName | Should -BeIn 'rule1';
}
}
Context 'Read Baseline.Exclude' {
It 'from default' {
$option = New-PSRuleOption;
$option.Baseline.Exclude | Should -Be $Null;
}
It 'from Hashtable' {
# With single item
$option = New-PSRuleOption -Option @{ 'Baseline.Exclude' = 'rule3' };
$option.Baseline.Exclude | Should -BeIn 'rule3';
# With array
$option = New-PSRuleOption -Option @{ 'Baseline.Exclude' = 'rule3', 'rule4' };
$option.Baseline.Exclude | Should -BeIn 'rule3', 'rule4';
}
It 'from YAML' {
# With single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Baseline.Exclude | Should -BeIn 'rule3';
# With array
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests2.yml');
$option.Baseline.Exclude | Should -BeIn 'rule3', 'rule4';
# With flat single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests3.yml');
$option.Baseline.Exclude | Should -BeIn 'rule3';
}
}
Context 'Read Baseline.Configuration' {
It 'from default' {
$option = New-PSRuleOption;
$option.Baseline.Configuration.Count | Should -Be 0;
}
It 'from Hashtable' {
$option = New-PSRuleOption -BaselineConfiguration @{ 'option1' = 'option'; 'option2' = 2; option3 = 'option3a', 'option3b' };
$option.Baseline.Configuration.option1 | Should -BeIn 'option';
$option.Baseline.Configuration.option2 | Should -Be 2;
$option.Baseline.Configuration.option3 | Should -BeIn 'option3a', 'option3b';
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Baseline.Configuration.option1 | Should -Be 'option';
$option.Baseline.Configuration.option2 | Should -Be 2;
$option.Baseline.Configuration.option3 | Should -BeIn 'option3a', 'option3b';
}
}
Context 'Read Binding.IgnoreCase' {
It 'from default' {
$option = New-PSRuleOption;
$option.Binding.IgnoreCase | Should -Be $True;
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Binding.IgnoreCase' = $False };
$option.Binding.IgnoreCase | Should -Be $False;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Binding.IgnoreCase | Should -Be $False;
}
}
Context 'Read Binding.TargetName' {
It 'from default' {
$option = New-PSRuleOption;
$option.Binding.TargetName | Should -Be $Null;
}
It 'from Hashtable' {
# With single item
$option = New-PSRuleOption -Option @{ 'Binding.TargetName' = 'ResourceName' };
$option.Binding.TargetName | Should -BeIn 'ResourceName';
# With array
$option = New-PSRuleOption -Option @{ 'Binding.TargetName' = 'ResourceName', 'AlternateName' };
$option.Binding.TargetName.Length | Should -Be 2;
$option.Binding.TargetName | Should -BeIn 'ResourceName', 'AlternateName';
}
It 'from YAML' {
# With single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Binding.TargetName | Should -BeIn 'ResourceName';
# With array
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests2.yml');
$option.Binding.TargetName | Should -BeIn 'ResourceName', 'AlternateName';
# With flat single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests3.yml');
$option.Binding.TargetName | Should -BeIn 'ResourceName';
}
}
Context 'Read Binding.TargetType' {
It 'from default' {
$option = New-PSRuleOption;
$option.Binding.TargetType | Should -Be $Null;
}
It 'from Hashtable' {
# With single item
$option = New-PSRuleOption -Option @{ 'Binding.TargetType' = 'ResourceType' };
$option.Binding.TargetType | Should -BeIn 'ResourceType';
# With array
$option = New-PSRuleOption -Option @{ 'Binding.TargetType' = 'ResourceType', 'Kind' };
$option.Binding.TargetType.Length | Should -Be 2;
$option.Binding.TargetType | Should -BeIn 'ResourceType', 'Kind';
}
It 'from YAML' {
# With single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Binding.TargetType | Should -BeIn 'ResourceType';
# With array
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests2.yml');
$option.Binding.TargetType | Should -BeIn 'ResourceType', 'Kind';
# With flat single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests3.yml');
$option.Binding.TargetType | Should -BeIn 'ResourceType';
}
}
Context 'Read Execution.LanguageMode' {
It 'from default' {
$option = New-PSRuleOption;
$option.Execution.LanguageMode | Should -Be FullLanguage;
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Execution.LanguageMode' = 'ConstrainedLanguage' };
$option.Execution.LanguageMode | Should -Be ConstrainedLanguage;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Execution.LanguageMode | Should -Be ConstrainedLanguage
}
}
Context 'Read Execution.InconclusiveWarning' {
It 'from default' {
$option = New-PSRuleOption;
$option.Execution.InconclusiveWarning | Should -Be $True;
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Execution.InconclusiveWarning' = $False };
$option.Execution.InconclusiveWarning | Should -Be $False;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Execution.InconclusiveWarning | Should -Be $False;
}
}
Context 'Read Execution.NotProcessedWarning' {
It 'from default' {
$option = New-PSRuleOption;
$option.Execution.NotProcessedWarning | Should -Be $True;
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Execution.NotProcessedWarning' = $False };
$option.Execution.NotProcessedWarning | Should -Be $False;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Execution.NotProcessedWarning | Should -Be $False;
}
}
Context 'Read Input.Format' {
It 'from default' {
$option = New-PSRuleOption;
$option.Input.Format | Should -Be 'Detect';
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Input.Format' = 'Yaml' };
$option.Input.Format | Should -Be Yaml;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Input.Format | Should -Be Yaml;
}
}
Context 'Read Input.ObjectPath' {
It 'from default' {
$option = New-PSRuleOption;
$option.Input.ObjectPath | Should -Be $Null;
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Input.ObjectPath' = 'items' };
$option.Input.ObjectPath | Should -Be 'items';
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Input.ObjectPath | Should -Be 'items';
}
}
Context 'Read Logging.RuleFail' {
It 'from default' {
$option = New-PSRuleOption;
$option.Logging.RuleFail | Should -Be 'None';
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Logging.RuleFail' = 'Error' };
$option.Logging.RuleFail | Should -Be Error;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Logging.RuleFail | Should -Be Warning;
}
}
Context 'Read Logging.RulePass' {
It 'from default' {
$option = New-PSRuleOption;
$option.Logging.RulePass | Should -Be 'None';
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Logging.RulePass' = 'Error' };
$option.Logging.RulePass | Should -Be Error;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Logging.RulePass | Should -Be Warning;
}
}
Context 'Read Output.As' {
It 'from default' {
$option = New-PSRuleOption;
$option.Output.As | Should -Be 'Detail';
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Output.As' = 'Summary' };
$option.Output.As | Should -Be Summary;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Output.As | Should -Be Summary;
}
}
Context 'Read Output.Format' {
It 'from default' {
$option = New-PSRuleOption;
$option.Output.Format | Should -Be 'None';
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Output.Format' = 'Yaml' };
$option.Output.Format | Should -Be Yaml;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Output.Format | Should -Be Json;
}
}
Context 'Read Suppression' {
It 'from default' {
$option = New-PSRuleOption;
$option.Suppression.Count | Should -Be 0;
}
It 'from Hashtable' {
$option = New-PSRuleOption -SuppressTargetName @{ 'SuppressionTest' = 'testObject1', 'testObject3' };
$option.Suppression['SuppressionTest'].TargetName | Should -BeIn 'testObject1', 'testObject3';
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Suppression['SuppressionTest1'].TargetName | Should -BeIn 'TestObject1', 'TestObject3';
$option.Suppression['SuppressionTest2'].TargetName | Should -BeIn 'TestObject1', 'TestObject3';
}
}
}
#endregion New-PSRuleOption
#region PSRule variables
Describe 'PSRule variables' -Tag 'Variables','Common' {
Context 'PowerShell automatic variables' {
$testObject = [PSCustomObject]@{
Name = 'VariableTest'
Type = 'TestType'
}
$testObject.PSObject.TypeNames.Insert(0, $testObject.Type);
It '$Rule' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'VariableTest';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $True;
$result.TargetName | Should -Be 'VariableTest';
}
}
}
#endregion PSRule variables

Просмотреть файл

@ -0,0 +1,367 @@
#
# Unit tests for PSRule options
#
[CmdletBinding()]
param (
)
# Setup error handling
$ErrorActionPreference = 'Stop';
Set-StrictMode -Version latest;
if ($Env:SYSTEM_DEBUG -eq 'true') {
$VerbosePreference = 'Continue';
}
# Setup tests paths
$rootPath = $PWD;
Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule) -Force;
$here = (Resolve-Path $PSScriptRoot).Path;
$outputPath = Join-Path -Path $rootPath -ChildPath out/tests/PSRule.Tests/Options;
Remove-Item -Path $outputPath -Force -Recurse -Confirm:$False -ErrorAction Ignore;
$Null = New-Item -Path $outputPath -ItemType Directory -Force;
#region New-PSRuleOption
Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
Context 'Read Baseline.RuleName' {
It 'from default' {
$option = New-PSRuleOption;
$option.Baseline.RuleName | Should -Be $Null;
}
It 'from Hashtable' {
# With single item
$option = New-PSRuleOption -Option @{ 'Baseline.RuleName' = 'rule1' };
$option.Baseline.RuleName | Should -BeIn 'rule1';
# With array
$option = New-PSRuleOption -Option @{ 'Baseline.RuleName' = 'rule1', 'rule2' };
$option.Baseline.RuleName | Should -BeIn 'rule1', 'rule2';
}
It 'from YAML' {
# With single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Baseline.RuleName | Should -BeIn 'rule1';
# With array
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests2.yml');
$option.Baseline.RuleName | Should -BeIn 'rule1', 'rule2';
# With flat single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests3.yml');
$option.Baseline.RuleName | Should -BeIn 'rule1';
}
}
Context 'Read Baseline.Exclude' {
It 'from default' {
$option = New-PSRuleOption;
$option.Baseline.Exclude | Should -Be $Null;
}
It 'from Hashtable' {
# With single item
$option = New-PSRuleOption -Option @{ 'Baseline.Exclude' = 'rule3' };
$option.Baseline.Exclude | Should -BeIn 'rule3';
# With array
$option = New-PSRuleOption -Option @{ 'Baseline.Exclude' = 'rule3', 'rule4' };
$option.Baseline.Exclude | Should -BeIn 'rule3', 'rule4';
}
It 'from YAML' {
# With single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Baseline.Exclude | Should -BeIn 'rule3';
# With array
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests2.yml');
$option.Baseline.Exclude | Should -BeIn 'rule3', 'rule4';
# With flat single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests3.yml');
$option.Baseline.Exclude | Should -BeIn 'rule3';
}
}
Context 'Read Baseline.Configuration' {
It 'from default' {
$option = New-PSRuleOption;
$option.Baseline.Configuration.Count | Should -Be 0;
}
It 'from Hashtable' {
$option = New-PSRuleOption -BaselineConfiguration @{ 'option1' = 'option'; 'option2' = 2; option3 = 'option3a', 'option3b' };
$option.Baseline.Configuration.option1 | Should -BeIn 'option';
$option.Baseline.Configuration.option2 | Should -Be 2;
$option.Baseline.Configuration.option3 | Should -BeIn 'option3a', 'option3b';
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Baseline.Configuration.option1 | Should -Be 'option';
$option.Baseline.Configuration.option2 | Should -Be 2;
$option.Baseline.Configuration.option3 | Should -BeIn 'option3a', 'option3b';
}
}
Context 'Read Binding.IgnoreCase' {
It 'from default' {
$option = New-PSRuleOption;
$option.Binding.IgnoreCase | Should -Be $True;
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Binding.IgnoreCase' = $False };
$option.Binding.IgnoreCase | Should -Be $False;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Binding.IgnoreCase | Should -Be $False;
}
}
Context 'Read Binding.TargetName' {
It 'from default' {
$option = New-PSRuleOption;
$option.Binding.TargetName | Should -Be $Null;
}
It 'from Hashtable' {
# With single item
$option = New-PSRuleOption -Option @{ 'Binding.TargetName' = 'ResourceName' };
$option.Binding.TargetName | Should -BeIn 'ResourceName';
# With array
$option = New-PSRuleOption -Option @{ 'Binding.TargetName' = 'ResourceName', 'AlternateName' };
$option.Binding.TargetName.Length | Should -Be 2;
$option.Binding.TargetName | Should -BeIn 'ResourceName', 'AlternateName';
}
It 'from YAML' {
# With single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Binding.TargetName | Should -BeIn 'ResourceName';
# With array
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests2.yml');
$option.Binding.TargetName | Should -BeIn 'ResourceName', 'AlternateName';
# With flat single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests3.yml');
$option.Binding.TargetName | Should -BeIn 'ResourceName';
}
}
Context 'Read Binding.TargetType' {
It 'from default' {
$option = New-PSRuleOption;
$option.Binding.TargetType | Should -Be $Null;
}
It 'from Hashtable' {
# With single item
$option = New-PSRuleOption -Option @{ 'Binding.TargetType' = 'ResourceType' };
$option.Binding.TargetType | Should -BeIn 'ResourceType';
# With array
$option = New-PSRuleOption -Option @{ 'Binding.TargetType' = 'ResourceType', 'Kind' };
$option.Binding.TargetType.Length | Should -Be 2;
$option.Binding.TargetType | Should -BeIn 'ResourceType', 'Kind';
}
It 'from YAML' {
# With single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Binding.TargetType | Should -BeIn 'ResourceType';
# With array
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests2.yml');
$option.Binding.TargetType | Should -BeIn 'ResourceType', 'Kind';
# With flat single item
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests3.yml');
$option.Binding.TargetType | Should -BeIn 'ResourceType';
}
}
Context 'Read Execution.LanguageMode' {
It 'from default' {
$option = New-PSRuleOption;
$option.Execution.LanguageMode | Should -Be FullLanguage;
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Execution.LanguageMode' = 'ConstrainedLanguage' };
$option.Execution.LanguageMode | Should -Be ConstrainedLanguage;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Execution.LanguageMode | Should -Be ConstrainedLanguage
}
}
Context 'Read Execution.InconclusiveWarning' {
It 'from default' {
$option = New-PSRuleOption;
$option.Execution.InconclusiveWarning | Should -Be $True;
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Execution.InconclusiveWarning' = $False };
$option.Execution.InconclusiveWarning | Should -Be $False;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Execution.InconclusiveWarning | Should -Be $False;
}
}
Context 'Read Execution.NotProcessedWarning' {
It 'from default' {
$option = New-PSRuleOption;
$option.Execution.NotProcessedWarning | Should -Be $True;
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Execution.NotProcessedWarning' = $False };
$option.Execution.NotProcessedWarning | Should -Be $False;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Execution.NotProcessedWarning | Should -Be $False;
}
}
Context 'Read Input.Format' {
It 'from default' {
$option = New-PSRuleOption;
$option.Input.Format | Should -Be 'Detect';
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Input.Format' = 'Yaml' };
$option.Input.Format | Should -Be Yaml;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Input.Format | Should -Be Yaml;
}
}
Context 'Read Input.ObjectPath' {
It 'from default' {
$option = New-PSRuleOption;
$option.Input.ObjectPath | Should -Be $Null;
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Input.ObjectPath' = 'items' };
$option.Input.ObjectPath | Should -Be 'items';
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Input.ObjectPath | Should -Be 'items';
}
}
Context 'Read Logging.RuleFail' {
It 'from default' {
$option = New-PSRuleOption;
$option.Logging.RuleFail | Should -Be 'None';
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Logging.RuleFail' = 'Error' };
$option.Logging.RuleFail | Should -Be Error;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Logging.RuleFail | Should -Be Warning;
}
}
Context 'Read Logging.RulePass' {
It 'from default' {
$option = New-PSRuleOption;
$option.Logging.RulePass | Should -Be 'None';
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Logging.RulePass' = 'Error' };
$option.Logging.RulePass | Should -Be Error;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Logging.RulePass | Should -Be Warning;
}
}
Context 'Read Output.As' {
It 'from default' {
$option = New-PSRuleOption;
$option.Output.As | Should -Be 'Detail';
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Output.As' = 'Summary' };
$option.Output.As | Should -Be Summary;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Output.As | Should -Be Summary;
}
}
Context 'Read Output.Format' {
It 'from default' {
$option = New-PSRuleOption;
$option.Output.Format | Should -Be 'None';
}
It 'from Hashtable' {
$option = New-PSRuleOption -Option @{ 'Output.Format' = 'Yaml' };
$option.Output.Format | Should -Be Yaml;
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Output.Format | Should -Be Json;
}
}
Context 'Read Suppression' {
It 'from default' {
$option = New-PSRuleOption;
$option.Suppression.Count | Should -Be 0;
}
It 'from Hashtable' {
$option = New-PSRuleOption -SuppressTargetName @{ 'SuppressionTest' = 'testObject1', 'testObject3' };
$option.Suppression['SuppressionTest'].TargetName | Should -BeIn 'testObject1', 'testObject3';
}
It 'from YAML' {
$option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
$option.Suppression['SuppressionTest1'].TargetName | Should -BeIn 'TestObject1', 'TestObject3';
$option.Suppression['SuppressionTest2'].TargetName | Should -BeIn 'TestObject1', 'TestObject3';
}
}
}
#endregion New-PSRuleOption

Просмотреть файл

@ -15,9 +15,7 @@ Set-StrictMode -Version latest;
$rootPath = $PWD;
Describe 'PSRule' -Tag 'PowerShellGallery' {
Context 'Module' {
It 'Can be imported' {
Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule) -Force;
}

Просмотреть файл

@ -0,0 +1,43 @@
#
# Unit tests for PSRule variables
#
[CmdletBinding()]
param (
)
# Setup error handling
$ErrorActionPreference = 'Stop';
Set-StrictMode -Version latest;
if ($Env:SYSTEM_DEBUG -eq 'true') {
$VerbosePreference = 'Continue';
}
# Setup tests paths
$rootPath = $PWD;
Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule) -Force;
$here = (Resolve-Path $PSScriptRoot).Path;
#region PSRule variables
Describe 'PSRule variables' -Tag 'Variables' {
Context 'PowerShell automatic variables' {
$testObject = [PSCustomObject]@{
Name = 'VariableTest'
Type = 'TestType'
}
$testObject.PSObject.TypeNames.Insert(0, $testObject.Type);
It '$Rule' {
$result = $testObject | Invoke-PSRule -Path (Join-Path -Path $here -ChildPath 'FromFile.Rule.ps1') -Name 'VariableTest';
$result | Should -Not -BeNullOrEmpty;
$result.IsSuccess() | Should -Be $True;
$result.TargetName | Should -Be 'VariableTest';
}
}
}
#endregion PSRule variables