From 0c823766a2bb26401a1bc472bce9075e1bf57270 Mon Sep 17 00:00:00 2001 From: Daniel Hughes <2237515+dan-hughes@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:44:24 +0100 Subject: [PATCH] Migrate to Pester 5 (#272) --- .../{General.md => 01_general.md} | 0 ..._proposal.yml => 02_resource_proposal.yml} | 0 .../ISSUE_TEMPLATE/03_command_proposal.yml | 39 + ...ource.yml => 04_problem_with_resource.yml} | 0 .../05_problem_with_command.yml | 101 + .github/ISSUE_TEMPLATE/config.yml | 1 + .vscode/analyzersettings.psd1 | 147 +- .vscode/settings.json | 23 +- CHANGELOG.md | 21 + GitVersion.yml | 4 +- RequiredModules.psd1 | 37 +- Resolve-Dependency.ps1 | 956 ++++- Resolve-Dependency.psd1 | 16 +- azure-pipelines.yml | 2 +- build.ps1 | 102 +- build.yaml | 174 +- source/Classes/001.DnsServerReason.ps1 | 21 + source/Classes/001.ResourceBase.ps1 | 211 -- ...ase.ps1 => 012.ResourcePropertiesBase.ps1} | 0 ...nsRecordBase.ps1 => 015.DnsRecordBase.ps1} | 6 +- ...RecordCname.ps1 => 020.DnsRecordCname.ps1} | 8 +- ....DnsRecordPtr.ps1 => 020.DnsRecordPtr.ps1} | 13 +- ...{003.DnsRecordA.ps1 => 030.DnsRecordA.ps1} | 6 +- ...nsRecordAaaa.ps1 => 030.DnsRecordAaaa.ps1} | 8 +- ...03.DnsRecordMx.ps1 => 030.DnsRecordMx.ps1} | 4 + ...03.DnsRecordNs.ps1 => 030.DnsRecordNs.ps1} | 4 + ....DnsRecordSrv.ps1 => 030.DnsRecordSrv.ps1} | 4 + ...ServerCache.ps1 => 030.DnsServerCache.ps1} | 48 +- ...Setting.ps1 => 030.DnsServerDsSetting.ps1} | 44 +- ...nsServerEDns.ps1 => 030.DnsServerEDns.ps1} | 42 +- ...cursion.ps1 => 030.DnsServerRecursion.ps1} | 39 +- ...enging.ps1 => 030.DnsServerScavenging.ps1} | 43 +- ...rdAScoped.ps1 => 040.DnsRecordAScoped.ps1} | 4 + ...Scoped.ps1 => 040.DnsRecordAaaaScoped.ps1} | 4 + ...coped.ps1 => 040.DnsRecordCnameScoped.ps1} | 4 + ...MxScoped.ps1 => 040.DnsRecordMxScoped.ps1} | 4 + ...NsScoped.ps1 => 040.DnsRecordNsScoped.ps1} | 4 + ...vScoped.ps1 => 040.DnsRecordSrvScoped.ps1} | 4 + .../DSC_DnsServerClientSubnet.psm1 | 2 - .../DSC_DnsServerDiagnostics.psm1 | 2 - .../DSC_DnsServerSecondaryZone.psm1 | 2 - .../DSC_DnsServerZoneScope.psm1 | 2 - .../DSC_DnsServerZoneTransfer.psm1 | 35 +- source/DnsServerDsc.psm1 | 1 - source/Private/Assert-TimeSpan.ps1 | 2 +- source/Private/ConvertTo-TimeSpan.ps1 | 2 +- source/Private/Get-ClassName.ps1 | 43 - source/Private/Get-LocalizedDataRecursive.ps1 | 75 - source/en-US/DnsServerDsc.strings.psd1 | 2 +- source/en-US/ResourceBase.strings.psd1 | 17 - source/prefix.ps1 | 6 + .../Classes/DnsRecordA.integration.tests.ps1 | 373 +- .../DnsRecordAScoped.integration.tests.ps1 | 371 +- .../DnsRecordAaaa.integration.tests.ps1 | 371 +- .../DnsRecordAaaaScoped.integration.tests.ps1 | 371 +- .../DnsRecordCname.integration.tests.ps1 | 371 +- ...DnsRecordCnameScoped.integration.tests.ps1 | 371 +- .../Classes/DnsRecordMx.integration.tests.ps1 | 383 +- .../DnsRecordMxScoped.integration.tests.ps1 | 382 +- .../Classes/DnsRecordNs.integration.tests.ps1 | 369 +- .../DnsRecordNsScoped.integration.tests.ps1 | 369 +- .../DnsRecordPtr.integration.tests.ps1 | 370 +- .../DnsRecordPtr.v6.integration.tests.ps1 | 371 +- .../DnsRecordSrv.integration.tests.ps1 | 401 +- .../Classes/DnsRecordSrvScoped.config.ps1 | 2 - .../DnsRecordSrvScoped.integration.tests.ps1 | 401 +- .../DnsServerCache.Integration.Tests.ps1 | 1138 +++--- .../DnsServerDsSetting.Integration.Tests.ps1 | 616 ++-- .../DnsServerEDns.Integration.Tests.ps1 | 458 +-- .../DnsServerRecursion.Integration.Tests.ps1 | 458 +-- .../DnsServerScavenging.Integration.Tests.ps1 | 396 +- ...nsServerClientSubnet.Integration.Tests.ps1 | 721 ++-- ...ConditionalForwarder.Integration.Tests.ps1 | 745 ++-- ...DnsServerDiagnostics.Integration.Tests.ps1 | 213 +- ...C_DnsServerForwarder.Integration.Tests.ps1 | 637 ++-- ...DnsServerPrimaryZone.Integration.Tests.ps1 | 741 ++-- ...SC_DnsServerRootHint.Integration.Tests.ps1 | 275 +- ...DSC_DnsServerSetting.Integration.Tests.ps1 | 708 ++-- ...sServerSettingLegacy.Integration.Tests.ps1 | 164 +- ...C_DnsServerZoneAging.Integration.Tests.ps1 | 419 ++- ...C_DnsServerZoneScope.Integration.Tests.ps1 | 337 +- .../DSC_DnsServerZoneScope.config.ps1 | 1 - tests/Unit/Classes/DnsRecordA.tests.ps1 | 417 ++- tests/Unit/Classes/DnsRecordAScoped.tests.ps1 | 389 +- tests/Unit/Classes/DnsRecordAaaa.tests.ps1 | 419 ++- .../Classes/DnsRecordAaaaScoped.tests.ps1 | 390 +- tests/Unit/Classes/DnsRecordBase.tests.ps1 | 437 ++- tests/Unit/Classes/DnsRecordCname.tests.ps1 | 420 ++- .../Classes/DnsRecordCnameScoped.tests.ps1 | 390 +- tests/Unit/Classes/DnsRecordMx.tests.ps1 | 441 ++- .../Unit/Classes/DnsRecordMxScoped.tests.ps1 | 409 ++- tests/Unit/Classes/DnsRecordNs.tests.ps1 | 385 +- .../Unit/Classes/DnsRecordNsScoped.tests.ps1 | 405 ++- tests/Unit/Classes/DnsRecordPtr.tests.ps1 | 420 ++- tests/Unit/Classes/DnsRecordPtr.v6.tests.ps1 | 441 ++- tests/Unit/Classes/DnsRecordSrv.tests.ps1 | 402 ++- .../Unit/Classes/DnsRecordSrvScoped.tests.ps1 | 406 ++- tests/Unit/Classes/DnsServerCache.Tests.ps1 | 911 ++--- .../Unit/Classes/DnsServerDsSetting.Tests.ps1 | 782 ++-- tests/Unit/Classes/DnsServerEDns.Tests.ps1 | 686 ++-- .../Unit/Classes/DnsServerRecursion.Tests.ps1 | 713 ++-- .../Classes/DnsServerScavenging.Tests.ps1 | 767 ++-- tests/Unit/Classes/ResourceBase.Tests.ps1 | 650 ---- tests/Unit/DSC_DnsServerADZone.Tests.ps1 | 1020 ++++-- .../Unit/DSC_DnsServerClientSubnet.Tests.ps1 | 504 ++- ...SC_DnsServerConditionalForwarder.Tests.ps1 | 720 ++-- tests/Unit/DSC_DnsServerDiagnostics.Tests.ps1 | 671 +++- tests/Unit/DSC_DnsServerForwarder.Tests.ps1 | 478 ++- tests/Unit/DSC_DnsServerPrimaryZone.Tests.ps1 | 473 ++- tests/Unit/DSC_DnsServerRootHint.Tests.ps1 | 321 +- .../Unit/DSC_DnsServerSecondaryZone.Tests.ps1 | 502 +++ tests/Unit/DSC_DnsServerSetting.Tests.ps1 | 3210 +++++++++-------- .../Unit/DSC_DnsServerSettingLegacy.Tests.ps1 | 457 +-- tests/Unit/DSC_DnsServerZoneAging.Tests.ps1 | 488 ++- tests/Unit/DSC_DnsServerZoneScope.Tests.ps1 | 303 +- .../Unit/DSC_DnsServerZoneTransfer.Tests.ps1 | 395 +- tests/Unit/DnsServerDsc.Common.Tests.ps1 | 211 +- tests/Unit/Private/Assert-TimeSpan.Tests.ps1 | 107 +- .../Unit/Private/ConvertTo-TimeSpan.Tests.ps1 | 79 +- tests/Unit/Private/Get-ClassName.Tests.ps1 | 78 - .../Get-LocalizedDataRecursive.Tests.ps1 | 122 - 121 files changed, 21833 insertions(+), 14628 deletions(-) rename .github/ISSUE_TEMPLATE/{General.md => 01_general.md} (100%) rename .github/ISSUE_TEMPLATE/{Resource_proposal.yml => 02_resource_proposal.yml} (100%) create mode 100644 .github/ISSUE_TEMPLATE/03_command_proposal.yml rename .github/ISSUE_TEMPLATE/{Problem_with_resource.yml => 04_problem_with_resource.yml} (100%) create mode 100644 .github/ISSUE_TEMPLATE/05_problem_with_command.yml create mode 100644 source/Classes/001.DnsServerReason.ps1 delete mode 100644 source/Classes/001.ResourceBase.ps1 rename source/Classes/{001.ResourcePropertiesBase.ps1 => 012.ResourcePropertiesBase.ps1} (100%) rename source/Classes/{002.DnsRecordBase.ps1 => 015.DnsRecordBase.ps1} (97%) rename source/Classes/{002.DnsRecordCname.ps1 => 020.DnsRecordCname.ps1} (93%) rename source/Classes/{002.DnsRecordPtr.ps1 => 020.DnsRecordPtr.ps1} (97%) rename source/Classes/{003.DnsRecordA.ps1 => 030.DnsRecordA.ps1} (97%) rename source/Classes/{003.DnsRecordAaaa.ps1 => 030.DnsRecordAaaa.ps1} (96%) rename source/Classes/{003.DnsRecordMx.ps1 => 030.DnsRecordMx.ps1} (99%) rename source/Classes/{003.DnsRecordNs.ps1 => 030.DnsRecordNs.ps1} (99%) rename source/Classes/{003.DnsRecordSrv.ps1 => 030.DnsRecordSrv.ps1} (99%) rename source/Classes/{003.DnsServerCache.ps1 => 030.DnsServerCache.ps1} (74%) rename source/Classes/{003.DnsServerDsSetting.ps1 => 030.DnsServerDsSetting.ps1} (80%) rename source/Classes/{003.DnsServerEDns.ps1 => 030.DnsServerEDns.ps1} (65%) rename source/Classes/{003.DnsServerRecursion.ps1 => 030.DnsServerRecursion.ps1} (81%) rename source/Classes/{003.DnsServerScavenging.ps1 => 030.DnsServerScavenging.ps1} (75%) rename source/Classes/{004.DnsRecordAScoped.ps1 => 040.DnsRecordAScoped.ps1} (98%) rename source/Classes/{004.DnsRecordAaaaScoped.ps1 => 040.DnsRecordAaaaScoped.ps1} (97%) rename source/Classes/{003.DnsRecordCnameScoped.ps1 => 040.DnsRecordCnameScoped.ps1} (97%) rename source/Classes/{004.DnsRecordMxScoped.ps1 => 040.DnsRecordMxScoped.ps1} (98%) rename source/Classes/{004.DnsRecordNsScoped.ps1 => 040.DnsRecordNsScoped.ps1} (98%) rename source/Classes/{004.DnsRecordSrvScoped.ps1 => 040.DnsRecordSrvScoped.ps1} (98%) delete mode 100644 source/DnsServerDsc.psm1 delete mode 100644 source/Private/Get-ClassName.ps1 delete mode 100644 source/Private/Get-LocalizedDataRecursive.ps1 delete mode 100644 source/en-US/ResourceBase.strings.psd1 delete mode 100644 tests/Unit/Classes/ResourceBase.Tests.ps1 create mode 100644 tests/Unit/DSC_DnsServerSecondaryZone.Tests.ps1 delete mode 100644 tests/Unit/Private/Get-ClassName.Tests.ps1 delete mode 100644 tests/Unit/Private/Get-LocalizedDataRecursive.Tests.ps1 diff --git a/.github/ISSUE_TEMPLATE/General.md b/.github/ISSUE_TEMPLATE/01_general.md similarity index 100% rename from .github/ISSUE_TEMPLATE/General.md rename to .github/ISSUE_TEMPLATE/01_general.md diff --git a/.github/ISSUE_TEMPLATE/Resource_proposal.yml b/.github/ISSUE_TEMPLATE/02_resource_proposal.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/Resource_proposal.yml rename to .github/ISSUE_TEMPLATE/02_resource_proposal.yml diff --git a/.github/ISSUE_TEMPLATE/03_command_proposal.yml b/.github/ISSUE_TEMPLATE/03_command_proposal.yml new file mode 100644 index 00000000..362cd21d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03_command_proposal.yml @@ -0,0 +1,39 @@ +name: New command proposal +description: If you have a proposal for a new public command that you think should be added to this module. The new command that is proposed shall be able to be used by a new or existing resource. +title: "NewCommandName: New command proposal" +labels: [] +assignees: [] +body: + - type: markdown + attributes: + value: | + Please replace `NewCommandName` in the issue title (above) with your proposed command name. + + Thank you for contributing and making this module better! + - type: textarea + id: description + attributes: + label: Command proposal + description: Provide information how this command will/should work and how it will help users. + validations: + required: true + - type: textarea + id: proposedParameters + attributes: + label: Proposed parameters + description: | + List all the proposed parameters and any parameter sets that the command should have. For each parameter provide a detailed description, the data type, if a default value should be used, and if the property is limited to a set of values. + value: | + Parameter | Mandatory | Data type | Description | Default value | Allowed values + --- | --- | --- | --- | --- | --- + ParameterName | Yes | String | Detailed description | None | None + validations: + required: true + - type: textarea + id: considerations + attributes: + label: Special considerations or limitations + description: | + Provide any considerations or limitations you can think of that a contributor should take in account when coding the proposed command, and or what limitations a user will encounter or should consider when using the proposed command. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/Problem_with_resource.yml b/.github/ISSUE_TEMPLATE/04_problem_with_resource.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/Problem_with_resource.yml rename to .github/ISSUE_TEMPLATE/04_problem_with_resource.yml diff --git a/.github/ISSUE_TEMPLATE/05_problem_with_command.yml b/.github/ISSUE_TEMPLATE/05_problem_with_command.yml new file mode 100644 index 00000000..684e3580 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/05_problem_with_command.yml @@ -0,0 +1,101 @@ +name: Problem with a command +description: If you want to report a bug or suggest an enhancement to a public command in this module. +labels: [] +assignees: [] +body: + - type: markdown + attributes: + value: | + TITLE: Please be descriptive not sensationalist. + + Your feedback and support is greatly appreciated, thanks for contributing! + + Please provide information regarding your issue under each section below. + **Write N/A in sections that do not apply, or if the information is not available.** + - type: textarea + id: description + attributes: + label: Problem description + description: Details of the scenario you tried and the problem that is occurring, or the enhancement you are suggesting. + validations: + required: true + - type: textarea + id: logs + attributes: + label: Verbose logs + description: | + Verbose logs showing the problem. **NOTE! Sensitive information should be obfuscated.** _Will be automatically formatted as plain text._ + placeholder: | + Paste verbose logs here + render: text + validations: + required: true + - type: textarea + id: reproducible + attributes: + label: How to reproduce + description: Provide the steps to reproduce the problem. + validations: + required: true + - type: textarea + id: expectedBehavior + attributes: + label: Expected behavior + description: Describe what you expected to happen. + validations: + required: true + - type: textarea + id: currentBehavior + attributes: + label: Current behavior + description: Describe what actually happens. + validations: + required: true + - type: textarea + id: suggestedSolution + attributes: + label: Suggested solution + description: Do you have any suggestions how to solve the issue? + validations: + required: true + - type: textarea + id: targetNodeOS + attributes: + label: Operating system the target node is running + description: | + Please provide as much as possible about the node running the command. _Will be automatically formatted as plain text._ + + To help with this information: + - On a Linux distribution, please provide the distribution name, version, and release. The following command can help get this information: `cat /etc/*-release && cat /proc/version` + - On a Windows OS please provide edition, version, build, and language. The following command can help get this information: `Get-ComputerInfo -Property @('OsName','OsOperatingSystemSKU','OSArchitecture','WindowsVersion','WindowsBuildLabEx','OsLanguage','OsMuiLanguages')` + placeholder: | + Add operating system information here + render: text + validations: + required: true + - type: textarea + id: targetNodePS + attributes: + label: PowerShell version and build the target node is running + description: | + Please provide the version and build of PowerShell the target node is running. _Will be automatically formatted as plain text._ + + To help with this information, please run this command: `$PSVersionTable` + placeholder: | + Add PowerShell information here + render: text + validations: + required: true + - type: textarea + id: moduleVersion + attributes: + label: Module version used + description: | + Please provide the version of the module that was used. _Will be automatically formatted as plain text._ + + To help with this information, please run this command where you encountered the problem: `Get-Module -Name 'DnsServerDsc' -ListAvailable | ft Name,Version,Path` + placeholder: | + Add module information here + render: text + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 4cd69212..9917040e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -3,3 +3,4 @@ contact_links: - name: "Virtual PowerShell User Group #DSC channel" url: https://dsccommunity.org/community/contact/ about: "To talk to the community and maintainers of DSC Community, please visit the #DSC channel." + diff --git a/.vscode/analyzersettings.psd1 b/.vscode/analyzersettings.psd1 index 78312d2c..d925a620 100644 --- a/.vscode/analyzersettings.psd1 +++ b/.vscode/analyzersettings.psd1 @@ -1,44 +1,115 @@ @{ - CustomRulePath = '.\output\RequiredModules\DscResource.AnalyzerRules' - includeDefaultRules = $true - IncludeRules = @( - # DSC Resource Kit style guideline rules. - 'PSAvoidDefaultValueForMandatoryParameter', - 'PSAvoidDefaultValueSwitchParameter', - 'PSAvoidInvokingEmptyMembers', - 'PSAvoidNullOrEmptyHelpMessageAttribute', - 'PSAvoidUsingCmdletAliases', - 'PSAvoidUsingComputerNameHardcoded', - 'PSAvoidUsingDeprecatedManifestFields', - 'PSAvoidUsingEmptyCatchBlock', - 'PSAvoidUsingInvokeExpression', - 'PSAvoidUsingPositionalParameters', - 'PSAvoidShouldContinueWithoutForce', - 'PSAvoidUsingWMICmdlet', - 'PSAvoidUsingWriteHost', - 'PSDSCReturnCorrectTypesForDSCFunctions', - 'PSDSCStandardDSCFunctionsInResource', - 'PSDSCUseIdenticalMandatoryParametersForDSC', - 'PSDSCUseIdenticalParametersForDSC', - 'PSMisleadingBacktick', - 'PSMissingModuleManifestField', - 'PSPossibleIncorrectComparisonWithNull', - 'PSProvideCommentHelp', - 'PSReservedCmdletChar', - 'PSReservedParams', - 'PSUseApprovedVerbs', - 'PSUseCmdletCorrectly', - 'PSUseOutputTypeCorrectly', - 'PSAvoidGlobalVars', - 'PSAvoidUsingConvertToSecureStringWithPlainText', - 'PSAvoidUsingPlainTextForPassword', - 'PSAvoidUsingUsernameAndPasswordParams', - 'PSDSCUseVerboseMessageInDSCResource', - 'PSShouldProcess', - 'PSUseDeclaredVarsMoreThanAssignments', - 'PSUsePSCredentialType', + CustomRulePath = @( + './output/RequiredModules/DscResource.AnalyzerRules' + './output/RequiredModules/Indented.ScriptAnalyzerRules' + ) + IncludeDefaultRules = $true + IncludeRules = @( + # DSC Community style guideline rules from the module ScriptAnalyzer. + 'PSAvoidDefaultValueForMandatoryParameter' + 'PSAvoidDefaultValueSwitchParameter' + 'PSAvoidInvokingEmptyMembers' + 'PSAvoidNullOrEmptyHelpMessageAttribute' + 'PSAvoidUsingCmdletAliases' + 'PSAvoidUsingComputerNameHardcoded' + 'PSAvoidUsingDeprecatedManifestFields' + 'PSAvoidUsingEmptyCatchBlock' + 'PSAvoidUsingInvokeExpression' + 'PSAvoidUsingPositionalParameters' + 'PSAvoidShouldContinueWithoutForce' + 'PSAvoidUsingWMICmdlet' + 'PSAvoidUsingWriteHost' + 'PSDSCReturnCorrectTypesForDSCFunctions' + 'PSDSCStandardDSCFunctionsInResource' + 'PSDSCUseIdenticalMandatoryParametersForDSC' + 'PSDSCUseIdenticalParametersForDSC' + 'PSMisleadingBacktick' + 'PSMissingModuleManifestField' + 'PSPossibleIncorrectComparisonWithNull' + 'PSProvideCommentHelp' + 'PSReservedCmdletChar' + 'PSReservedParams' + 'PSUseApprovedVerbs' + 'PSUseCmdletCorrectly' + 'PSUseOutputTypeCorrectly' + 'PSAvoidGlobalVars' + 'PSAvoidUsingConvertToSecureStringWithPlainText' + 'PSAvoidUsingPlainTextForPassword' + 'PSAvoidUsingUsernameAndPasswordParams' + 'PSDSCUseVerboseMessageInDSCResource' + 'PSShouldProcess' + 'PSUseDeclaredVarsMoreThanAssignments' + 'PSUsePSCredentialType' + + # Additional rules from the module ScriptAnalyzer + 'PSUseConsistentWhitespace' + 'UseCorrectCasing' + 'PSPlaceOpenBrace' + 'PSPlaceCloseBrace' + 'AlignAssignmentStatement' + 'AvoidUsingDoubleQuotesForConstantString' + 'UseShouldProcessForStateChangingFunctions' + # Rules from the modules DscResource.AnalyzerRules 'Measure-*' + + # Rules from the module Indented.ScriptAnalyzerRules + 'AvoidCreatingObjectsFromAnEmptyString' + 'AvoidDashCharacters' + 'AvoidEmptyNamedBlocks' + 'AvoidFilter' + 'AvoidHelpMessage' + 'AvoidNestedFunctions' + 'AvoidNewObjectToCreatePSObject' + 'AvoidParameterAttributeDefaultValues' + 'AvoidProcessWithoutPipeline' + 'AvoidSmartQuotes' + 'AvoidThrowOutsideOfTry' + 'AvoidWriteErrorStop' + 'AvoidWriteOutput' + 'UseSyntacticallyCorrectExamples' ) + <# + The following types are not rules but parse errors reported by PSScriptAnalyzer + so they cannot be ecluded. They need to be filtered out from the result of + Invoke-ScriptAnalyzer. + + TypeNotFound - Because classes in the project cannot be found unless built. + RequiresModuleInvalid - Because 'using module' in prefix.ps1 cannot be resolved as source file. + #> + ExcludeRules = @() + + Rules = @{ + PSUseConsistentWhitespace = @{ + Enable = $true + CheckOpenBrace = $true + CheckInnerBrace = $true + CheckOpenParen = $true + CheckOperator = $false + CheckSeparator = $true + CheckPipe = $true + CheckPipeForRedundantWhitespace = $true + CheckParameter = $false + } + + PSPlaceOpenBrace = @{ + Enable = $true + OnSameLine = $false + NewLineAfter = $true + IgnoreOneLineBlock = $false + } + + PSPlaceCloseBrace = @{ + Enable = $true + NoEmptyLineBefore = $true + IgnoreOneLineBlock = $false + NewLineAfter = $true + } + + PSAlignAssignmentStatement = @{ + Enable = $true + CheckHashtable = $true + } + } } diff --git a/.vscode/settings.json b/.vscode/settings.json index 2f0a10e4..3f005cad 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,11 +7,12 @@ "powershell.codeFormatting.whitespaceAroundOperator": true, "powershell.codeFormatting.whitespaceAfterSeparator": true, "powershell.codeFormatting.ignoreOneLineBlock": false, - "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationAfterEveryPipeline", + "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationForFirstPipeline", "powershell.codeFormatting.preset": "Custom", "powershell.codeFormatting.alignPropertyValuePairs": true, + "powershell.codeFormatting.useConstantStrings": true, "powershell.developer.bundledModulesPath": "${cwd}/output/RequiredModules", - "powershell.scriptAnalysis.settingsPath": ".vscode\\analyzersettings.psd1", + "powershell.scriptAnalysis.settingsPath": "/.vscode/analyzersettings.psd1", "powershell.scriptAnalysis.enable": true, "files.trimTrailingWhitespace": true, "files.trimFinalNewlines": true, @@ -19,6 +20,9 @@ "files.associations": { "*.ps1xml": "xml" }, + "cSpell.dictionaries": [ + "powershell" + ], "cSpell.words": [ "COMPANYNAME", "ICONURI", @@ -34,8 +38,21 @@ "pscmdlet", "steppable" ], + "cSpell.ignorePaths": [ + ".git" + ], "[markdown]": { "files.trimTrailingWhitespace": true, "files.encoding": "utf8" - } + }, + "powershell.pester.useLegacyCodeLens": false, + "pester.testFilePath": [ + "[tT]ests/[qQ][aA]/*.[tT]ests.[pP][sS]1", + "[tT]ests/[uU]nit/**/*.[tT]ests.[pP][sS]1", + "[tT]ests/[uU]nit/*.[tT]ests.[pP][sS]1" + ], + "pester.runTestsInNewProcess": true, + "pester.pesterModulePath": "./output/RequiredModules/Pester", + "powershell.pester.codeLens": true, + "pester.suppressCodeLensNotice": true } diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fbf9067..6446be8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Update to use the build worker `windows-latest` for the necessary stages of the pipeline, and `ubuntu-latest` for the other stages. - Update pipeline to use _GitVersion.Tool_ installed by `dotnet`. + - Update unit and integration tests to Pester 5 + - DnsServer* Class Resources + - Used `DscResource.Base` + - BREAKING: Added `Reasons` property as population of this is builtin + to base class. + - Updated `prefix`, `build`, `RequiredModules` for Pester 5 and + DscResource.Base usage. + - Added tests for `DSC_DnsServerSecondaryZone`. + - Updated project related files + - `.github/ISSUE_TEMPLATES` + - `.vscode` + - `ResolveDependency.ps1` + - `build.ps1` - DnsServerDsc.Common - Added unit tests for `Convert-RootHintsToHashtable`. @@ -29,11 +42,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed unit tests for functions no longer part of the module. - Removed functions from the module manifest that are no longer part of the module. + - Pin `gitversion` version in `azure-pipelines` - DnRecordBase - Update comment regarding use of `using module` statement. - ResourceBase - Update comment regarding use of `using module` statement. +### Removed + +- DnsServerDsc + - Removed `001.ResourceBase` and replaced with `DscResource.Base`. + - Removed `Get-ClassName` and `Get-LocalizedDataRecursive` utilizing + ones provided in `DscResource.Base`. + ## [3.0.0] - 2021-05-26 ### Removed diff --git a/GitVersion.yml b/GitVersion.yml index 8a364cd4..74197c20 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,7 +1,7 @@ mode: ContinuousDelivery next-version: 0.0.1 -major-version-bump-message: '(breaking\schange|breaking|major)\b' -minor-version-bump-message: '(adds?|features?|minor)\b' +major-version-bump-message: '(breaking\schange|breaking)\b' +minor-version-bump-message: '(adds?|minor)\b' patch-version-bump-message: '\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' assembly-informational-format: '{NuGetVersionV2}+Sha.{Sha}.Date.{CommitDate}' diff --git a/RequiredModules.psd1 b/RequiredModules.psd1 index 786c6284..a5b438fb 100644 --- a/RequiredModules.psd1 +++ b/RequiredModules.psd1 @@ -1,5 +1,5 @@ @{ - PSDependOptions = @{ + PSDependOptions = @{ AddToPath = $true Target = 'output\RequiredModules' Parameters = @{ @@ -7,20 +7,27 @@ } } - InvokeBuild = 'latest' - PSScriptAnalyzer = 'latest' - Pester = '4.10.1' - Plaster = 'latest' - ModuleBuilder = 'latest' - ChangelogManagement = 'latest' - Sampler = 'latest' - 'Sampler.GitHubTasks' = 'latest' - MarkdownLinkCheck = 'latest' - 'DscResource.Test' = 'latest' - 'DscResource.AnalyzerRules' = 'latest' - xDscResourceDesigner = 'latest' - 'DscResource.DocGenerator' = 'latest' + InvokeBuild = 'latest' + PSScriptAnalyzer = 'latest' + ConvertToSARIF = 'latest' # cSpell: disable-line + Pester = 'latest' + Plaster = 'latest' + ModuleBuilder = 'latest' + ChangelogManagement = 'latest' + Sampler = 'latest' + 'Sampler.GitHubTasks' = 'latest' + MarkdownLinkCheck = 'latest' + 'DscResource.Test' = 'latest' + xDscResourceDesigner = 'latest' # Build dependent modules - 'DscResource.Common' = 'latest' + 'DscResource.Base' = 'latest' + 'DscResource.Common' = 'latest' + + 'DscResource.AnalyzerRules' = 'latest' + 'Indented.ScriptAnalyzerRules' = 'latest' + + # Prerequisite modules for documentation. + 'DscResource.DocGenerator' = 'latest' + PlatyPS = 'latest' } diff --git a/Resolve-Dependency.ps1 b/Resolve-Dependency.ps1 index 760df239..17cc98ec 100644 --- a/Resolve-Dependency.ps1 +++ b/Resolve-Dependency.ps1 @@ -9,7 +9,7 @@ .PARAMETER PSDependTarget Path for PSDepend to be bootstrapped and save other dependencies. Can also be CurrentUser or AllUsers if you wish to install the modules in - such scope. The default value is './output/RequiredModules' relative to + such scope. The default value is 'output/RequiredModules' relative to this script's path. .PARAMETER Proxy @@ -46,6 +46,21 @@ .PARAMETER WithYAML Not yet written. + .PARAMETER UseModuleFast + Specifies to use ModuleFast instead of PowerShellGet to resolve dependencies + faster. + + .PARAMETER ModuleFastBleedingEdge + Specifies to use ModuleFast code that is in the ModuleFast's main branch + in its GitHub repository. The parameter UseModuleFast must also be set to + true. + + .PARAMETER UsePSResourceGet + Specifies to use the new PSResourceGet module instead of the (now legacy) PowerShellGet module. + + .PARAMETER PSResourceGetVersion + String specifying the module version for PSResourceGet if the `UsePSResourceGet` switch is utilized. + .NOTES Load defaults for parameters values from Resolve-Dependency.psd1 if not provided as parameter. @@ -59,7 +74,7 @@ param [Parameter()] [System.String] - $PSDependTarget = (Join-Path -Path $PSScriptRoot -ChildPath './output/RequiredModules'), + $PSDependTarget = (Join-Path -Path $PSScriptRoot -ChildPath 'output/RequiredModules'), [Parameter()] [System.Uri] @@ -96,7 +111,39 @@ param [Parameter()] [System.Management.Automation.SwitchParameter] - $WithYAML + $WithYAML, + + [Parameter()] + [System.Collections.Hashtable] + $RegisterGallery, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $UseModuleFast, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ModuleFastBleedingEdge, + + [Parameter()] + [System.String] + $ModuleFastVersion, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $UsePSResourceGet, + + [Parameter()] + [System.String] + $PSResourceGetVersion, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $UsePowerShellGetCompatibilityModule, + + [Parameter()] + [System.String] + $UsePowerShellGetCompatibilityModuleVersion ) try @@ -107,17 +154,6 @@ try { Import-Module -Name Microsoft.PowerShell.Utility -RequiredVersion '3.1.0.0' } - - <# - Making sure the imported PackageManagement module is not from PS7 module - path. The VSCode PS extension is changing the $env:PSModulePath and - prioritize the PS7 path. This is an issue with PowerShellGet because - it loads an old version if available (or fail to load latest). - #> - Get-Module -ListAvailable PackageManagement | - Where-Object -Property 'ModuleBase' -NotMatch 'powershell.7' | - Select-Object -First 1 | - Import-Module -Force } Write-Verbose -Message 'Importing Bootstrap default parameters from ''$PSScriptRoot/Resolve-Dependency.psd1''.' @@ -138,7 +174,7 @@ try { if (-not $PSBoundParameters.Keys.Contains($parameterName) -and $resolveDependencyDefaults.ContainsKey($parameterName)) { - Write-Verbose -Message "Setting $parameterName with $($resolveDependencyDefaults[$parameterName])." + Write-Verbose -Message "Setting parameter '$parameterName' to value '$($resolveDependencyDefaults[$parameterName])'." try { @@ -151,7 +187,7 @@ try $PSBoundParameters.Add($parameterName, $variableValue) - Set-Variable -Name $parameterName -value $variableValue -Force -ErrorAction 'SilentlyContinue' + Set-Variable -Name $parameterName -Value $variableValue -Force -ErrorAction 'SilentlyContinue' } catch { @@ -165,248 +201,860 @@ catch Write-Warning -Message "Error attempting to import Bootstrap's default parameters from '$resolveDependencyConfigPath': $($_.Exception.Message)." } -Write-Progress -Activity 'Bootstrap:' -PercentComplete 0 -CurrentOperation 'NuGet Bootstrap' +# Handle when both ModuleFast and PSResourceGet is configured or/and passed as parameter. +if ($UseModuleFast -and $UsePSResourceGet) +{ + Write-Information -MessageData 'Both ModuleFast and PSResourceGet is configured or/and passed as parameter.' -InformationAction 'Continue' -# TODO: This should handle the parameter $AllowOldPowerShellGetModule. -$powerShellGetModule = Import-Module -Name 'PowerShellGet' -MinimumVersion '2.0' -ErrorAction 'SilentlyContinue' -PassThru + if ($PSVersionTable.PSVersion -ge '7.2') + { + $UsePSResourceGet = $false -# Install the package provider if it is not available. -$nuGetProvider = Get-PackageProvider -Name 'NuGet' -ListAvailable | Select-Object -First 1 + Write-Information -MessageData 'PowerShell 7.2 or higher being used, prefer ModuleFast over PSResourceGet.' -InformationAction 'Continue' + } + else + { + $UseModuleFast = $false -if (-not $powerShellGetModule -and -not $nuGetProvider) -{ - $providerBootstrapParameters = @{ - Name = 'nuget' - Force = $true - ForceBootstrap = $true - ErrorAction = 'Stop' + Write-Information -MessageData 'Windows PowerShell or PowerShell <=7.1 is being used, prefer PSResourceGet since ModuleFast is not supported on this version of PowerShell.' -InformationAction 'Continue' } +} - switch ($PSBoundParameters.Keys) +# Only bootstrap ModuleFast if it is not already imported. +if ($UseModuleFast -and -not (Get-Module -Name 'ModuleFast')) +{ + try { - 'Proxy' + $moduleFastBootstrapScriptBlockParameters = @{} + + if ($ModuleFastBleedingEdge) { - $providerBootstrapParameters.Add('Proxy', $Proxy) + Write-Information -MessageData 'ModuleFast is configured to use Bleeding Edge (directly from ModuleFast''s main branch).' -InformationAction 'Continue' + + $moduleFastBootstrapScriptBlockParameters.UseMain = $true } + elseif($ModuleFastVersion) + { + if ($ModuleFastVersion -notmatch 'v') + { + $ModuleFastVersion = 'v{0}' -f $ModuleFastVersion + } + + Write-Information -MessageData ('ModuleFast is configured to use version {0}.' -f $ModuleFastVersion) -InformationAction 'Continue' - 'ProxyCredential' + $moduleFastBootstrapScriptBlockParameters.Release = $ModuleFastVersion + } + else { - $providerBootstrapParameters.Add('ProxyCredential', $ProxyCredential) + Write-Information -MessageData 'ModuleFast is configured to use latest released version.' -InformationAction 'Continue' } - 'Scope' - { - $providerBootstrapParameters.Add('Scope', $Scope) + $moduleFastBootstrapUri = 'bit.ly/modulefast' # cSpell: disable-line + + Write-Debug -Message ('Using bootstrap script at {0}' -f $moduleFastBootstrapUri) + + $invokeWebRequestParameters = @{ + Uri = $moduleFastBootstrapUri + ErrorAction = 'Stop' } + + $moduleFastBootstrapScript = Invoke-WebRequest @invokeWebRequestParameters + + $moduleFastBootstrapScriptBlock = [ScriptBlock]::Create($moduleFastBootstrapScript) + + & $moduleFastBootstrapScriptBlock @moduleFastBootstrapScriptBlockParameters } + catch + { + Write-Warning -Message ('ModuleFast could not be bootstrapped. Reverting to PSResourceGet. Error: {0}' -f $_.Exception.Message) + + $UseModuleFast = $false + $UsePSResourceGet = $true + } +} - if ($AllowPrerelease) +if ($UsePSResourceGet) +{ + $psResourceGetModuleName = 'Microsoft.PowerShell.PSResourceGet' + + # If PSResourceGet was used prior it will be locked and we can't replace it. + if ((Test-Path -Path "$PSDependTarget/$psResourceGetModuleName" -PathType 'Container') -and (Get-Module -Name $psResourceGetModuleName)) { - $providerBootstrapParameters.Add('AllowPrerelease', $true) + Write-Information -MessageData ('{0} is already bootstrapped and imported into the session. If there is a need to refresh the module, open a new session and resolve dependencies again.' -f $psResourceGetModuleName) -InformationAction 'Continue' } + else + { + Write-Debug -Message ('{0} do not exist, saving the module to RequiredModules.' -f $psResourceGetModuleName) - Write-Information -MessageData 'Bootstrap: Installing NuGet Package Provider from the web (Make sure Microsoft addresses/ranges are allowed).' + $psResourceGetDownloaded = $false - $null = Install-PackageProvider @providerBootstrapParams + try + { + if (-not $PSResourceGetVersion) + { + # Default to latest version if no version is passed in parameter or specified in configuration. + $psResourceGetUri = "https://www.powershellgallery.com/api/v2/package/$psResourceGetModuleName" + } + else + { + $psResourceGetUri = "https://www.powershellgallery.com/api/v2/package/$psResourceGetModuleName/$PSResourceGetVersion" + } - $nuGetProvider = Get-PackageProvider -Name 'NuGet' -ListAvailable | Select-Object -First 1 + $invokeWebRequestParameters = @{ + # TODO: Should support proxy parameters passed to the script. + Uri = $psResourceGetUri + OutFile = "$PSDependTarget/$psResourceGetModuleName.nupkg" # cSpell: ignore nupkg + ErrorAction = 'Stop' + } - $nuGetProviderVersion = $nuGetProvider.Version.ToString() + $previousProgressPreference = $ProgressPreference + $ProgressPreference = 'SilentlyContinue' - Write-Information -MessageData "Bootstrap: Importing NuGet Package Provider version $nuGetProviderVersion to current session." + # Bootstrapping Microsoft.PowerShell.PSResourceGet. + Invoke-WebRequest @invokeWebRequestParameters - $Null = Import-PackageProvider -Name 'NuGet' -RequiredVersion $nuGetProviderVersion -Force -} + $ProgressPreference = $previousProgressPreference + + $psResourceGetDownloaded = $true + } + catch + { + Write-Warning -Message ('{0} could not be bootstrapped. Reverting to PowerShellGet. Error: {1}' -f $psResourceGetModuleName, $_.Exception.Message) + } -Write-Progress -Activity 'Bootstrap:' -PercentComplete 10 -CurrentOperation "Ensuring Gallery $Gallery is trusted" + $UsePSResourceGet = $false -# Fail if the given PSGallery is not registered. -$previousGalleryInstallationPolicy = (Get-PSRepository -Name $Gallery -ErrorAction 'Stop').InstallationPolicy + if ($psResourceGetDownloaded) + { + # On Windows PowerShell the command Expand-Archive do not like .nupkg as a zip archive extension. + $zipFileName = ((Split-Path -Path $invokeWebRequestParameters.OutFile -Leaf) -replace 'nupkg', 'zip') -Set-PSRepository -Name $Gallery -InstallationPolicy 'Trusted' -ErrorAction 'Ignore' + $renameItemParameters = @{ + Path = $invokeWebRequestParameters.OutFile + NewName = $zipFileName + Force = $true + } -try + Rename-Item @renameItemParameters + + $psResourceGetZipArchivePath = Join-Path -Path (Split-Path -Path $invokeWebRequestParameters.OutFile -Parent) -ChildPath $zipFileName + + $expandArchiveParameters = @{ + Path = $psResourceGetZipArchivePath + DestinationPath = "$PSDependTarget/$psResourceGetModuleName" + Force = $true + } + + Expand-Archive @expandArchiveParameters + + Remove-Item -Path $psResourceGetZipArchivePath + + Import-Module -Name $expandArchiveParameters.DestinationPath -Force + + # Successfully bootstrapped PSResourceGet, so let's use it. + $UsePSResourceGet = $true + } + } + + if ($UsePSResourceGet) + { + $psResourceGetModule = Get-Module -Name $psResourceGetModuleName + + $psResourceGetModuleVersion = $psResourceGetModule.Version.ToString() + + if ($psResourceGetModule.PrivateData.PSData.Prerelease) + { + $psResourceGetModuleVersion += '-{0}' -f $psResourceGetModule.PrivateData.PSData.Prerelease + } + + Write-Information -MessageData ('Using {0} v{1}.' -f $psResourceGetModuleName, $psResourceGetModuleVersion) -InformationAction 'Continue' + + if ($UsePowerShellGetCompatibilityModule) + { + $savePowerShellGetParameters = @{ + Name = 'PowerShellGet' + Path = $PSDependTarget + Repository = 'PSGallery' + TrustRepository = $true + } + + if ($UsePowerShellGetCompatibilityModuleVersion) + { + $savePowerShellGetParameters.Version = $UsePowerShellGetCompatibilityModuleVersion + + # Check if the version is a prerelease. + if ($UsePowerShellGetCompatibilityModuleVersion -match '\d+\.\d+\.\d+-.*') + { + $savePowerShellGetParameters.Prerelease = $true + } + } + + Save-PSResource @savePowerShellGetParameters + + Import-Module -Name "$PSDependTarget/PowerShellGet" + } + } +} + +# Check if legacy PowerShellGet and PSDepend must be bootstrapped. +if (-not ($UseModuleFast -or $UsePSResourceGet)) { - Write-Progress -Activity 'Bootstrap:' -PercentComplete 25 -CurrentOperation 'Checking PowerShellGet' + if ($PSVersionTable.PSVersion.Major -le 5) + { + <# + Making sure the imported PackageManagement module is not from PS7 module + path. The VSCode PS extension is changing the $env:PSModulePath and + prioritize the PS7 path. This is an issue with PowerShellGet because + it loads an old version if available (or fail to load latest). + #> + Get-Module -ListAvailable PackageManagement | + Where-Object -Property 'ModuleBase' -NotMatch 'powershell.7' | + Select-Object -First 1 | + Import-Module -Force + } - # Ensure the module is loaded and retrieve the version you have. - $powerShellGetVersion = (Import-Module -Name 'PowerShellGet' -PassThru -ErrorAction 'SilentlyContinue').Version + Write-Progress -Activity 'Bootstrap:' -PercentComplete 0 -CurrentOperation 'NuGet Bootstrap' - Write-Verbose -Message "Bootstrap: The PowerShellGet version is $powerShellGetVersion" + $importModuleParameters = @{ + Name = 'PowerShellGet' + MinimumVersion = '2.0' + MaximumVersion = '2.8.999' + ErrorAction = 'SilentlyContinue' + PassThru = $true + } - # Versions below 2.0 are considered old, unreliable & not recommended - if (-not $powerShellGetVersion -or ($powerShellGetVersion -lt [System.Version] '2.0' -and -not $AllowOldPowerShellGetModule)) + if ($AllowOldPowerShellGetModule) { - Write-Progress -Activity 'Bootstrap:' -PercentComplete 40 -CurrentOperation 'Installing newer version of PowerShellGet' - - $installPowerShellGetParameters = @{ - Name = 'PowerShellGet' - Force = $True - SkipPublisherCheck = $true - AllowClobber = $true - Scope = $Scope - Repository = $Gallery + $importModuleParameters.Remove('MinimumVersion') + } + + $powerShellGetModule = Import-Module @importModuleParameters + + # Install the package provider if it is not available. + $nuGetProvider = Get-PackageProvider -Name 'NuGet' -ListAvailable -ErrorAction 'SilentlyContinue' | + Select-Object -First 1 + + if (-not $powerShellGetModule -and -not $nuGetProvider) + { + $providerBootstrapParameters = @{ + Name = 'NuGet' + Force = $true + ForceBootstrap = $true + ErrorAction = 'Stop' + Scope = $Scope } switch ($PSBoundParameters.Keys) { 'Proxy' { - $installPowerShellGetParameters.Add('Proxy', $Proxy) + $providerBootstrapParameters.Add('Proxy', $Proxy) } 'ProxyCredential' { - $installPowerShellGetParameters.Add('ProxyCredential', $ProxyCredential) + $providerBootstrapParameters.Add('ProxyCredential', $ProxyCredential) } - 'GalleryCredential' + 'AllowPrerelease' { - $installPowerShellGetParameters.Add('Credential', $GalleryCredential) + $providerBootstrapParameters.Add('AllowPrerelease', $AllowPrerelease) } } - Write-Progress -Activity 'Bootstrap:' -PercentComplete 60 -CurrentOperation 'Installing newer version of PowerShellGet' + Write-Information -MessageData 'Bootstrap: Installing NuGet Package Provider from the web (Make sure Microsoft addresses/ranges are allowed).' - Install-Module @installPowerShellGetParameters + $null = Install-PackageProvider @providerBootstrapParameters - Remove-Module -Name 'PowerShellGet' -Force -ErrorAction 'SilentlyContinue' - Remove-Module -Name 'PackageManagement' -Force + $nuGetProvider = Get-PackageProvider -Name 'NuGet' -ListAvailable | Select-Object -First 1 - $powerShellGetModule = Import-Module PowerShellGet -Force -PassThru + $nuGetProviderVersion = $nuGetProvider.Version.ToString() - $powerShellGetVersion = $powerShellGetModule.Version.ToString() + Write-Information -MessageData "Bootstrap: Importing NuGet Package Provider version $nuGetProviderVersion to current session." - Write-Information -MessageData "Bootstrap: PowerShellGet version loaded is $powerShellGetVersion" + $Null = Import-PackageProvider -Name 'NuGet' -RequiredVersion $nuGetProviderVersion -Force } - # Try to import the PSDepend module from the available modules. - $getModuleParameters = @{ - Name = 'PSDepend' - ListAvailable = $true + if ($RegisterGallery) + { + if ($RegisterGallery.ContainsKey('Name') -and -not [System.String]::IsNullOrEmpty($RegisterGallery.Name)) + { + $Gallery = $RegisterGallery.Name + } + else + { + $RegisterGallery.Name = $Gallery + } + + Write-Progress -Activity 'Bootstrap:' -PercentComplete 7 -CurrentOperation "Verifying private package repository '$Gallery'" -Completed + + $previousRegisteredRepository = Get-PSRepository -Name $Gallery -ErrorAction 'SilentlyContinue' + + if ($previousRegisteredRepository.SourceLocation -ne $RegisterGallery.SourceLocation) + { + if ($previousRegisteredRepository) + { + Write-Progress -Activity 'Bootstrap:' -PercentComplete 9 -CurrentOperation "Re-registrering private package repository '$Gallery'" -Completed + + Unregister-PSRepository -Name $Gallery + + $unregisteredPreviousRepository = $true + } + else + { + Write-Progress -Activity 'Bootstrap:' -PercentComplete 9 -CurrentOperation "Registering private package repository '$Gallery'" -Completed + } + + Register-PSRepository @RegisterGallery + } } - $psDependModule = Get-Module @getModuleParameters + Write-Progress -Activity 'Bootstrap:' -PercentComplete 10 -CurrentOperation "Ensuring Gallery $Gallery is trusted" + + # Fail if the given PSGallery is not registered. + $previousGalleryInstallationPolicy = (Get-PSRepository -Name $Gallery -ErrorAction 'Stop').Trusted + + $updatedGalleryInstallationPolicy = $false - if ($PSBoundParameters.ContainsKey('MinimumPSDependVersion')) + if ($previousGalleryInstallationPolicy -ne $true) { - $psDependModule = $psDependModule | Where-Object -Property -eq $MinimumPSDependVersion + $updatedGalleryInstallationPolicy = $true + + # Only change policy if the repository is not trusted + Set-PSRepository -Name $Gallery -InstallationPolicy 'Trusted' -ErrorAction 'Ignore' } +} - if (-not $psDependModule) +try +{ + # Check if legacy PowerShellGet and PSDepend must be used. + if (-not ($UseModuleFast -or $UsePSResourceGet)) { - # PSDepend module not found, installing or saving it. - if ($PSDependTarget -in 'CurrentUser', 'AllUsers') + Write-Progress -Activity 'Bootstrap:' -PercentComplete 25 -CurrentOperation 'Checking PowerShellGet' + + # Ensure the module is loaded and retrieve the version you have. + $powerShellGetVersion = (Import-Module -Name 'PowerShellGet' -PassThru -ErrorAction 'SilentlyContinue').Version + + Write-Verbose -Message "Bootstrap: The PowerShellGet version is $powerShellGetVersion" + + # Versions below 2.0 are considered old, unreliable & not recommended + if (-not $powerShellGetVersion -or ($powerShellGetVersion -lt [System.Version] '2.0' -and -not $AllowOldPowerShellGetModule)) { - Write-Debug -Message "PSDepend module not found. Attempting to install from Gallery $Gallery." + Write-Progress -Activity 'Bootstrap:' -PercentComplete 40 -CurrentOperation 'Fetching newer version of PowerShellGet' + + # PowerShellGet module not found, installing or saving it. + if ($PSDependTarget -in 'CurrentUser', 'AllUsers') + { + Write-Debug -Message "PowerShellGet module not found. Attempting to install from Gallery $Gallery." + + Write-Warning -Message "Installing PowerShellGet in $PSDependTarget Scope." + + $installPowerShellGetParameters = @{ + Name = 'PowerShellGet' + Force = $true + SkipPublisherCheck = $true + AllowClobber = $true + Scope = $Scope + Repository = $Gallery + MaximumVersion = '2.8.999' + } + + switch ($PSBoundParameters.Keys) + { + 'Proxy' + { + $installPowerShellGetParameters.Add('Proxy', $Proxy) + } + + 'ProxyCredential' + { + $installPowerShellGetParameters.Add('ProxyCredential', $ProxyCredential) + } + + 'GalleryCredential' + { + $installPowerShellGetParameters.Add('Credential', $GalleryCredential) + } + } + + Write-Progress -Activity 'Bootstrap:' -PercentComplete 60 -CurrentOperation 'Installing newer version of PowerShellGet' - Write-Warning -Message "Installing PSDepend in $PSDependTarget Scope." + Install-Module @installPowerShellGetParameters + } + else + { + Write-Debug -Message "PowerShellGet module not found. Attempting to Save from Gallery $Gallery to $PSDependTarget" + + $saveModuleParameters = @{ + Name = 'PowerShellGet' + Repository = $Gallery + Path = $PSDependTarget + Force = $true + MaximumVersion = '2.8.999' + } - $installPSDependParameters = @{ - Name = 'PSDepend' - Repository = $Gallery - Force = $true - Scope = $PSDependTarget - SkipPublisherCheck = $true - AllowClobber = $true + Write-Progress -Activity 'Bootstrap:' -PercentComplete 60 -CurrentOperation "Saving PowerShellGet from $Gallery to $Scope" + + Save-Module @saveModuleParameters } - if ($MinimumPSDependVersion) + Write-Debug -Message 'Removing previous versions of PowerShellGet and PackageManagement from session' + + Get-Module -Name 'PowerShellGet' -All | Remove-Module -Force -ErrorAction 'SilentlyContinue' + Get-Module -Name 'PackageManagement' -All | Remove-Module -Force + + Write-Progress -Activity 'Bootstrap:' -PercentComplete 65 -CurrentOperation 'Loading latest version of PowerShellGet' + + Write-Debug -Message 'Importing latest PowerShellGet and PackageManagement versions into session' + + if ($AllowOldPowerShellGetModule) { - $installPSDependParameters.Add('MinimumVersion', $MinimumPSDependVersion) + $powerShellGetModule = Import-Module -Name 'PowerShellGet' -Force -PassThru } + else + { + Import-Module -Name 'PackageManagement' -MinimumVersion '1.4.8.1' -Force - Write-Progress -Activity 'Bootstrap:' -PercentComplete 75 -CurrentOperation "Installing PSDepend from $Gallery" + $powerShellGetModule = Import-Module -Name 'PowerShellGet' -MinimumVersion '2.2.5' -Force -PassThru + } - Install-Module @installPSDependParameters + $powerShellGetVersion = $powerShellGetModule.Version.ToString() + + Write-Information -MessageData "Bootstrap: PowerShellGet version loaded is $powerShellGetVersion" + } + + # Try to import the PSDepend module from the available modules. + $getModuleParameters = @{ + Name = 'PSDepend' + ListAvailable = $true } - else - { - Write-Debug -Message "PSDepend module not found. Attempting to Save from Gallery $Gallery to $PSDependTarget" - $saveModuleParameters = @{ - Name = 'PSDepend' - Repository = $Gallery - Path = $PSDependTarget + $psDependModule = Get-Module @getModuleParameters + + if ($PSBoundParameters.ContainsKey('MinimumPSDependVersion')) + { + try + { + $psDependModule = $psDependModule | Where-Object -FilterScript { $_.Version -ge $MinimumPSDependVersion } } + catch + { + throw ('There was a problem finding the minimum version of PSDepend. Error: {0}' -f $_) + } + } + + if (-not $psDependModule) + { + Write-Debug -Message 'PSDepend module not found.' - if ($MinimumPSDependVersion) + # PSDepend module not found, installing or saving it. + if ($PSDependTarget -in 'CurrentUser', 'AllUsers') { - $saveModuleParameters.add('MinimumVersion', $MinimumPSDependVersion) + Write-Debug -Message "Attempting to install from Gallery '$Gallery'." + + Write-Warning -Message "Installing PSDepend in $PSDependTarget Scope." + + $installPSDependParameters = @{ + Name = 'PSDepend' + Repository = $Gallery + Force = $true + Scope = $PSDependTarget + SkipPublisherCheck = $true + AllowClobber = $true + } + + if ($MinimumPSDependVersion) + { + $installPSDependParameters.Add('MinimumVersion', $MinimumPSDependVersion) + } + + Write-Progress -Activity 'Bootstrap:' -PercentComplete 75 -CurrentOperation "Installing PSDepend from $Gallery" + + Install-Module @installPSDependParameters } + else + { + Write-Debug -Message "Attempting to Save from Gallery $Gallery to $PSDependTarget" + + $saveModuleParameters = @{ + Name = 'PSDepend' + Repository = $Gallery + Path = $PSDependTarget + Force = $true + } + + if ($MinimumPSDependVersion) + { + $saveModuleParameters.add('MinimumVersion', $MinimumPSDependVersion) + } - Write-Progress -Activity 'Bootstrap:' -PercentComplete 75 -CurrentOperation "Saving & Importing PSDepend from $Gallery to $Scope" + Write-Progress -Activity 'Bootstrap:' -PercentComplete 75 -CurrentOperation "Saving PSDepend from $Gallery to $PSDependTarget" - Save-Module @saveModuleParameters + Save-Module @saveModuleParameters + } } - } - Write-Progress -Activity 'Bootstrap:' -PercentComplete 80 -CurrentOperation 'Loading PSDepend' + Write-Progress -Activity 'Bootstrap:' -PercentComplete 80 -CurrentOperation 'Importing PSDepend' + + $importModulePSDependParameters = @{ + Name = 'PSDepend' + ErrorAction = 'Stop' + Force = $true + } + + if ($PSBoundParameters.ContainsKey('MinimumPSDependVersion')) + { + $importModulePSDependParameters.Add('MinimumVersion', $MinimumPSDependVersion) + } + + # We should have successfully bootstrapped PSDepend. Fail if not available. + $null = Import-Module @importModulePSDependParameters + + Write-Progress -Activity 'Bootstrap:' -PercentComplete 81 -CurrentOperation 'Invoke PSDepend' - $importModulePSDependParameters = @{ - Name = 'PSDepend' - ErrorAction = 'Stop' - Force = $true + if ($WithYAML) + { + Write-Progress -Activity 'Bootstrap:' -PercentComplete 82 -CurrentOperation 'Verifying PowerShell module PowerShell-Yaml' + + if (-not (Get-Module -ListAvailable -Name 'PowerShell-Yaml')) + { + Write-Progress -Activity 'Bootstrap:' -PercentComplete 85 -CurrentOperation 'Installing PowerShell module PowerShell-Yaml' + + Write-Verbose -Message "PowerShell-Yaml module not found. Attempting to Save from Gallery '$Gallery' to '$PSDependTarget'." + + $SaveModuleParam = @{ + Name = 'PowerShell-Yaml' + Repository = $Gallery + Path = $PSDependTarget + Force = $true + } + + Save-Module @SaveModuleParam + } + else + { + Write-Verbose -Message 'PowerShell-Yaml is already available' + } + + Write-Progress -Activity 'Bootstrap:' -PercentComplete 88 -CurrentOperation 'Importing PowerShell module PowerShell-Yaml' + } } - if ($PSBoundParameters.ContainsKey('MinimumPSDependVersion')) + if (Test-Path -Path $DependencyFile) { - $importModulePSDependParameters.Add('MinimumVersion', $MinimumPSDependVersion) - } + if ($UseModuleFast -or $UsePSResourceGet) + { + $requiredModules = Import-PowerShellDataFile -Path $DependencyFile - # We should have successfully bootstrapped PSDepend. Fail if not available. - $null = Import-Module @importModulePSDependParameters + $requiredModules = $requiredModules.GetEnumerator() | + Where-Object -FilterScript { $_.Name -ne 'PSDependOptions' } - if ($WithYAML) - { - Write-Progress -Activity 'Bootstrap:' -PercentComplete 82 -CurrentOperation 'Verifying PowerShell module PowerShell-Yaml' + if ($UseModuleFast) + { + Write-Progress -Activity 'Bootstrap:' -PercentComplete 90 -CurrentOperation 'Invoking ModuleFast' - if (-not (Get-Module -ListAvailable -Name 'PowerShell-Yaml')) - { - Write-Progress -Activity 'Bootstrap:' -PercentComplete 85 -CurrentOperation 'Installing PowerShell module PowerShell-Yaml' + Write-Progress -Activity 'ModuleFast:' -PercentComplete 0 -CurrentOperation 'Restoring Build Dependencies' + + $modulesToSave = @( + 'PSDepend' # Always include PSDepend for backward compatibility. + ) - Write-Verbose -Message "PowerShell-Yaml module not found. Attempting to Save from Gallery $Gallery to $PSDependTarget" + if ($WithYAML) + { + $modulesToSave += 'PowerShell-Yaml' + } + + if ($UsePowerShellGetCompatibilityModule) + { + Write-Debug -Message 'PowerShellGet compatibility module is configured to be used.' + + # This is needed to ensure that the PowerShellGet compatibility module works. + $psResourceGetModuleName = 'Microsoft.PowerShell.PSResourceGet' + + if ($PSResourceGetVersion) + { + $modulesToSave += ('{0}:[{1}]' -f $psResourceGetModuleName, $PSResourceGetVersion) + } + else + { + $modulesToSave += $psResourceGetModuleName + } + + $powerShellGetCompatibilityModuleName = 'PowerShellGet' + + if ($UsePowerShellGetCompatibilityModuleVersion) + { + $modulesToSave += ('{0}:[{1}]' -f $powerShellGetCompatibilityModuleName, $UsePowerShellGetCompatibilityModuleVersion) + } + else + { + $modulesToSave += $powerShellGetCompatibilityModuleName + } + } + + foreach ($requiredModule in $requiredModules) + { + # If the RequiredModules.psd1 entry is an Hashtable then special handling is needed. + if ($requiredModule.Value -is [System.Collections.Hashtable]) + { + if (-not $requiredModule.Value.Version) + { + $requiredModuleVersion = 'latest' + } + else + { + $requiredModuleVersion = $requiredModule.Value.Version + } + + if ($requiredModuleVersion -eq 'latest') + { + $moduleNameSuffix = '' + + if ($requiredModule.Value.Parameters.AllowPrerelease -eq $true) + { + <# + Adding '!' to the module name indicate to ModuleFast + that is should also evaluate pre-releases. + #> + $moduleNameSuffix = '!' + } + + $modulesToSave += ('{0}{1}' -f $requiredModule.Name, $moduleNameSuffix) + } + else + { + $modulesToSave += ('{0}:[{1}]' -f $requiredModule.Name, $requiredModuleVersion) + } + } + else + { + if ($requiredModule.Value -eq 'latest') + { + $modulesToSave += $requiredModule.Name + } + else + { + # Handle different nuget version operators already present. + if ($requiredModule.Value -match '[!|:|[|(|,|>|<|=]') + { + $modulesToSave += ('{0}{1}' -f $requiredModule.Name, $requiredModule.Value) + } + else + { + # Assuming the version is a fixed version. + $modulesToSave += ('{0}:[{1}]' -f $requiredModule.Name, $requiredModule.Value) + } + } + } + } + + Write-Debug -Message ("Required modules to retrieve plan for:`n{0}" -f ($modulesToSave | Out-String)) + + $installModuleFastParameters = @{ + Destination = $PSDependTarget + DestinationOnly = $true + NoPSModulePathUpdate = $true + NoProfileUpdate = $true + Update = $true + Confirm = $false + } + + $moduleFastPlan = Install-ModuleFast -Specification $modulesToSave -Plan @installModuleFastParameters + + Write-Debug -Message ("Missing modules that need to be saved:`n{0}" -f ($moduleFastPlan | Out-String)) + + if ($moduleFastPlan) + { + # Clear all modules in plan from the current session so they can be fetched again. + $moduleFastPlan.Name | Get-Module | Remove-Module -Force - $SaveModuleParam = @{ - Name = 'PowerShell-Yaml' - Repository = $Gallery - Path = $PSDependTarget + $moduleFastPlan | Install-ModuleFast @installModuleFastParameters + } + else + { + Write-Verbose -Message 'All required modules were already up to date' + } + + Write-Progress -Activity 'ModuleFast:' -PercentComplete 100 -CurrentOperation 'Dependencies restored' -Completed } - Save-Module @SaveModuleParam + if ($UsePSResourceGet) + { + Write-Progress -Activity 'Bootstrap:' -PercentComplete 90 -CurrentOperation 'Invoking PSResourceGet' + + $modulesToSave = @( + @{ + Name = 'PSDepend' # Always include PSDepend for backward compatibility. + } + ) + + if ($WithYAML) + { + $modulesToSave += @{ + Name = 'PowerShell-Yaml' + } + } + + # Prepare hashtable that can be concatenated to the Save-PSResource parameters. + foreach ($requiredModule in $requiredModules) + { + # If the RequiredModules.psd1 entry is an Hashtable then special handling is needed. + if ($requiredModule.Value -is [System.Collections.Hashtable]) + { + $saveModuleHashtable = @{ + Name = $requiredModule.Name + } + + if ($requiredModule.Value.Version -and $requiredModule.Value.Version -ne 'latest') + { + $saveModuleHashtable.Version = $requiredModule.Value.Version + } + + if ($requiredModule.Value.Parameters.AllowPrerelease -eq $true) + { + $saveModuleHashtable.Prerelease = $true + } + + $modulesToSave += $saveModuleHashtable + } + else + { + if ($requiredModule.Value -eq 'latest') + { + $modulesToSave += @{ + Name = $requiredModule.Name + } + } + else + { + $modulesToSave += @{ + Name = $requiredModule.Name + Version = $requiredModule.Value + } + } + } + } + + $percentagePerModule = [System.Math]::Floor(100 / $modulesToSave.Length) + + $progressPercentage = 0 + + Write-Progress -Activity 'PSResourceGet:' -PercentComplete $progressPercentage -CurrentOperation 'Restoring Build Dependencies' + + foreach ($currentModule in $modulesToSave) + { + Write-Progress -Activity 'PSResourceGet:' -PercentComplete $progressPercentage -CurrentOperation 'Restoring Build Dependencies' -Status ('Saving module {0}' -f $savePSResourceParameters.Name) + + $savePSResourceParameters = @{ + Path = $PSDependTarget + TrustRepository = $true + Confirm = $false + } + + # Concatenate the module parameters to the Save-PSResource parameters. + $savePSResourceParameters += $currentModule + + # Modules that Sampler depend on that cannot be refreshed without a new session. + $skipModule = @('PowerShell-Yaml') + + if ($savePSResourceParameters.Name -in $skipModule -and (Get-Module -Name $savePSResourceParameters.Name)) + { + Write-Progress -Activity 'PSResourceGet:' -PercentComplete $progressPercentage -CurrentOperation 'Restoring Build Dependencies' -Status ('Skipping module {0}' -f $savePSResourceParameters.Name) + + Write-Information -MessageData ('Skipping the module {0} since it cannot be refresh while loaded into the session. To refresh the module open a new session and resolve dependencies again.' -f $savePSResourceParameters.Name) -InformationAction 'Continue' + } + else + { + # Clear all module from the current session so any new version fetched will be re-imported. + Get-Module -Name $savePSResourceParameters.Name | Remove-Module -Force + + Save-PSResource @savePSResourceParameters -ErrorVariable 'savePSResourceError' + + if ($savePSResourceError) + { + Write-Warning -Message 'Save-PSResource could not save (replace) one or more dependencies. This can be due to the module is loaded into the session (and referencing assemblies). Close the current session and open a new session and try again.' + } + } + + $progressPercentage += $percentagePerModule + } + + Write-Progress -Activity 'PSResourceGet:' -PercentComplete 100 -CurrentOperation 'Dependencies restored' -Completed + } } else { - Write-Verbose "PowerShell-Yaml is already available" - } + Write-Progress -Activity 'Bootstrap:' -PercentComplete 90 -CurrentOperation 'Invoking PSDepend' - Write-Progress -Activity 'Bootstrap:' -PercentComplete 88 -CurrentOperation 'Importing PowerShell module PowerShell-Yaml' + Write-Progress -Activity 'PSDepend:' -PercentComplete 0 -CurrentOperation 'Restoring Build Dependencies' - Import-Module -Name 'PowerShell-Yaml' -ErrorAction 'Stop' - } + $psDependParameters = @{ + Force = $true + Path = $DependencyFile + } - Write-Progress -Activity 'Bootstrap:' -PercentComplete 90 -CurrentOperation 'Invoke PSDepend' + # TODO: Handle when the Dependency file is in YAML, and -WithYAML is specified. + Invoke-PSDepend @psDependParameters - Write-Progress -Activity "PSDepend:" -PercentComplete 0 -CurrentOperation "Restoring Build Dependencies" + Write-Progress -Activity 'PSDepend:' -PercentComplete 100 -CurrentOperation 'Dependencies restored' -Completed + } + } + else + { + Write-Warning -Message "The dependency file '$DependencyFile' could not be found." + } - if (Test-Path -Path $DependencyFile) + Write-Progress -Activity 'Bootstrap:' -PercentComplete 100 -CurrentOperation 'Bootstrap complete' -Completed +} +finally +{ + if ($RegisterGallery) { - $psDependParameters = @{ - Force = $true - Path = $DependencyFile + Write-Verbose -Message "Removing private package repository '$Gallery'." + Unregister-PSRepository -Name $Gallery + } + + if ($unregisteredPreviousRepository) + { + Write-Verbose -Message "Reverting private package repository '$Gallery' to previous location URI:s." + + $registerPSRepositoryParameters = @{ + Name = $previousRegisteredRepository.Name + InstallationPolicy = $previousRegisteredRepository.InstallationPolicy } - # TODO: Handle when the Dependency file is in YAML, and -WithYAML is specified. - Invoke-PSDepend @psDependParameters + if ($previousRegisteredRepository.SourceLocation) + { + $registerPSRepositoryParameters.SourceLocation = $previousRegisteredRepository.SourceLocation + } + + if ($previousRegisteredRepository.PublishLocation) + { + $registerPSRepositoryParameters.PublishLocation = $previousRegisteredRepository.PublishLocation + } + + if ($previousRegisteredRepository.ScriptSourceLocation) + { + $registerPSRepositoryParameters.ScriptSourceLocation = $previousRegisteredRepository.ScriptSourceLocation + } + + if ($previousRegisteredRepository.ScriptPublishLocation) + { + $registerPSRepositoryParameters.ScriptPublishLocation = $previousRegisteredRepository.ScriptPublishLocation + } + + Register-PSRepository @registerPSRepositoryParameters } - Write-Progress -Activity "PSDepend:" -PercentComplete 100 -CurrentOperation "Dependencies restored" -Completed + if ($updatedGalleryInstallationPolicy -eq $true -and $previousGalleryInstallationPolicy -ne $true) + { + # Only try to revert installation policy if the repository exist + if ((Get-PSRepository -Name $Gallery -ErrorAction 'SilentlyContinue')) + { + # Reverting the Installation Policy for the given gallery if it was not already trusted + Set-PSRepository -Name $Gallery -InstallationPolicy 'Untrusted' + } + } - Write-Progress -Activity 'Bootstrap:' -PercentComplete 100 -CurrentOperation "Bootstrap complete" -Completed -} -finally -{ - # Reverting the Installation Policy for the given gallery - Set-PSRepository -Name $Gallery -InstallationPolicy $previousGalleryInstallationPolicy - Write-Verbose -Message "Project Bootstrapped, returning to Invoke-Build" + Write-Verbose -Message 'Project Bootstrapped, returning to Invoke-Build.' } diff --git a/Resolve-Dependency.psd1 b/Resolve-Dependency.psd1 index 2ae8c0da..a5960c26 100644 --- a/Resolve-Dependency.psd1 +++ b/Resolve-Dependency.psd1 @@ -1,5 +1,15 @@ @{ - Gallery = 'PSGallery' - AllowPrerelease = $false - WithYAML = $true + Gallery = 'PSGallery' + AllowPrerelease = $false + WithYAML = $true + + #UseModuleFast = $true + #ModuleFastVersion = '0.1.2' + #ModuleFastBleedingEdge = $true + + UsePSResourceGet = $true + #PSResourceGetVersion = '1.0.1' + + UsePowerShellGetCompatibilityModule = $true + UsePowerShellGetCompatibilityModuleVersion = '3.0.23-beta23' } diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 94f6cc3e..b01cd507 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -25,7 +25,7 @@ stages: vmImage: 'windows-latest' steps: - pwsh: | - dotnet tool install --global GitVersion.Tool + dotnet tool install --global GitVersion.Tool --version 5.* $gitVersionObject = dotnet-gitversion | ConvertFrom-Json $gitVersionObject.PSObject.Properties.ForEach{ Write-Host -Object "Setting Task Variable '$($_.Name)' with value '$($_.Value)'." diff --git a/build.ps1 b/build.ps1 index 360d1c78..f4a0faec 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,6 +1,6 @@ <# .DESCRIPTION - Bootstrap and build script for PowerShell module CI/CD pipeline + Bootstrap and build script for PowerShell module CI/CD pipeline. .PARAMETER Tasks The task or tasks to run. The default value is '.' (runs the default task). @@ -27,7 +27,10 @@ 'output/RequiredModules'. .PARAMETER PesterScript - Not yet written. + One or more paths that will override the Pester configuration in build + configuration file when running the build task Invoke_Pester_Tests. + + If running Pester 5 test, use the alias PesterPath to be future-proof. .PARAMETER PesterTag Filter which tags to run when invoking Pester tests. This is used in the @@ -53,6 +56,19 @@ .PARAMETER AutoRestore Not yet written. + + .PARAMETER UseModuleFast + Specifies to use ModuleFast instead of PowerShellGet to resolve dependencies + faster. + + .PARAMETER UsePSResourceGet + Specifies to use PSResourceGet instead of PowerShellGet to resolve dependencies + faster. This can also be configured in Resolve-Dependency.psd1. + + .PARAMETER UsePowerShellGetCompatibilityModule + Specifies to use the compatibility module PowerShellGet. This parameter + only works then the method of downloading dependencies is PSResourceGet. + This can also be configured in Resolve-Dependency.psd1. #> [CmdletBinding()] param @@ -85,6 +101,8 @@ param $RequiredModulesDirectory = $(Join-Path 'output' 'RequiredModules'), [Parameter()] + # This alias is to prepare for the rename of this parameter to PesterPath when Pester 4 support is removed + [Alias('PesterPath')] [System.Object[]] $PesterScript, @@ -116,7 +134,19 @@ param [Parameter()] [System.Management.Automation.SwitchParameter] - $AutoRestore + $AutoRestore, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $UseModuleFast, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $UsePSResourceGet, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $UsePowerShellGetCompatibilityModule ) <# @@ -127,7 +157,6 @@ param process { - if ($MyInvocation.ScriptName -notLike '*Invoke-Build.ps1') { # Only run the process block through InvokeBuild (look at the Begin block at the bottom of this script). @@ -173,7 +202,7 @@ process ConvertFrom-Yaml -Yaml (Get-Content -Raw $configFile) } - # Native Support for JSON and JSONC (by Removing comments) + # Support for JSON and JSONC (by Removing comments) when module PowerShell-Yaml is available '\.[json|jsonc]' { $jsonFile = Get-Content -Raw -Path $configFile @@ -219,6 +248,38 @@ process Set-BuildHeader -Script ([scriptblock]::Create($BuildInfo.TaskHeader)) } + <# + Add BuildModuleOutput to PSModule Path environment variable. + Moved here (not in begin block) because build file can contains BuiltSubModuleDirectory value. + #> + if ($BuiltModuleSubdirectory) + { + if (-not (Split-Path -IsAbsolute -Path $BuiltModuleSubdirectory)) + { + $BuildModuleOutput = Join-Path -Path $OutputDirectory -ChildPath $BuiltModuleSubdirectory + } + else + { + $BuildModuleOutput = $BuiltModuleSubdirectory + } + } # test if BuiltModuleSubDirectory set in build config file + elseif ($BuildInfo.ContainsKey('BuiltModuleSubDirectory')) + { + $BuildModuleOutput = Join-Path -Path $OutputDirectory -ChildPath $BuildInfo['BuiltModuleSubdirectory'] + } + else + { + $BuildModuleOutput = $OutputDirectory + } + + # Pre-pending $BuildModuleOutput folder to PSModulePath to resolve built module from this folder. + if ($powerShellModulePaths -notcontains $BuildModuleOutput) + { + Write-Host -Object "[build] Pre-pending '$BuildModuleOutput' folder to PSModulePath" -ForegroundColor Green + + $env:PSModulePath = $BuildModuleOutput + [System.IO.Path]::PathSeparator + $env:PSModulePath + } + <# Import Tasks from modules via their exported aliases when defined in Build Manifest. https://github.com/nightroman/Invoke-Build/tree/master/Tasks/Import#example-2-import-from-a-module-with-tasks @@ -299,7 +360,7 @@ process } } -Begin +begin { # Find build config if not specified. if (-not $BuildConfig) @@ -403,30 +464,6 @@ Begin } } - if ($BuiltModuleSubdirectory) - { - if (-not (Split-Path -IsAbsolute -Path $BuiltModuleSubdirectory)) - { - $BuildModuleOutput = Join-Path -Path $OutputDirectory -ChildPath $BuiltModuleSubdirectory - } - else - { - $BuildModuleOutput = $BuiltModuleSubdirectory - } - } - else - { - $BuildModuleOutput = $OutputDirectory - } - - # Pre-pending $BuildModuleOutput folder to PSModulePath to resolve built module from this folder. - if ($powerShellModulePaths -notcontains $BuildModuleOutput) - { - Write-Host -Object "[pre-build] Pre-pending '$BuildModuleOutput' folder to PSModulePath" -ForegroundColor Green - - $env:PSModulePath = $BuildModuleOutput + [System.IO.Path]::PathSeparator + $env:PSModulePath - } - <# The variable $PSDependTarget will be used below when building the splatting variable before calling Resolve-Dependency.ps1, unless overridden in the @@ -437,7 +474,8 @@ Begin if ($ResolveDependency) { - Write-Host -Object "[pre-build] Resolving dependencies." -ForegroundColor Green + Write-Host -Object "[pre-build] Resolving dependencies using preferred method." -ForegroundColor Green + $resolveDependencyParams = @{ } # If BuildConfig is a Yaml file, bootstrap powershell-yaml via ResolveDependency. @@ -453,7 +491,7 @@ Begin # The parameter has been explicitly used for calling the .build.ps1 if ($MyInvocation.BoundParameters.ContainsKey($cmdParameter)) { - $paramValue = $MyInvocation.BoundParameters.ContainsKey($cmdParameter) + $paramValue = $MyInvocation.BoundParameters.Item($cmdParameter) Write-Debug " adding $cmdParameter :: $paramValue [from user-provided parameters to Build.ps1]" diff --git a/build.yaml b/build.yaml index 324cf25e..ca3df5e4 100644 --- a/build.yaml +++ b/build.yaml @@ -1,31 +1,9 @@ --- -#################################################### -# ModuleBuilder Configuration # -#################################################### -CopyPaths: - - en-US - - DSCResources - - Modules -Encoding: UTF8 -VersionedOutputDirectory: true -Prefix: prefix.ps1 - -#################################################### -# ModuleBuilder Dependent Modules Configuration # -#################################################### - -NestedModule: - DscResource.Common: - CopyOnly: true - Path: ./output/RequiredModules/DscResource.Common - AddToManifest: false - Exclude: PSGetModuleInfo.xml - #################################################### # Pipeline Configuration # #################################################### BuildWorkflow: - '.': + ".": - build - test @@ -33,16 +11,22 @@ BuildWorkflow: - Clean - Build_Module_ModuleBuilder - Build_NestedModules_ModuleBuilder - - Create_changelog_release_output + - Create_Changelog_Release_Output + + docs: - Generate_Conceptual_Help - Generate_Wiki_Content + - Generate_Wiki_Sidebar + - Clean_Markdown_Metadata + - Package_Wiki_Content pack: - build + - docs - package_module_nupkg hqrmtest: - - DscResource_Tests_Stop_On_Fail + - Invoke_HQRM_Tests_Stop_On_Fail test: - Pester_Tests_Stop_On_Fail @@ -55,38 +39,26 @@ BuildWorkflow: - Publish_GitHub_Wiki_Content #################################################### -# PESTER Configuration # +# ModuleBuilder Configuration # #################################################### - -Pester: - OutputFormat: NUnitXML - ExcludeFromCodeCoverage: - - Modules/DscResource.Common - Script: - - tests/Unit - ExcludeTag: - Tag: - CodeCoverageThreshold: 80 - CodeCoverageOutputFile: JaCoCo_coverage.xml - CodeCoverageOutputFileEncoding: ascii - -DscTest: - ExcludeTag: - - "Common Tests - New Error-Level Script Analyzer Rules" - Tag: - ExcludeSourceFile: - - output - ExcludeModuleFile: - - Modules/DscResource.Common - MainGitBranch: main +CopyPaths: + - DSCResources + - en-US + - Modules +Prefix: prefix.ps1 +Encoding: UTF8 +VersionedOutputDirectory: true +BuiltModuleSubdirectory: builtModule ModuleBuildTasks: Sampler: - - '*.build.Sampler.ib.tasks' + - "*.build.Sampler.ib.tasks" Sampler.GitHubTasks: - - '*.ib.tasks' + - "*.ib.tasks" DscResource.DocGenerator: - - 'Task.*' + - "Task.*" + DscResource.Test: + - "Task.*" TaskHeader: | param($Path) @@ -99,10 +71,89 @@ TaskHeader: | Write-Build DarkGray " $($Task.InvocationInfo.ScriptName):$($Task.InvocationInfo.ScriptLineNumber)" "" +#################################################### +# Dependent Modules Configuration (Sampler) # +#################################################### +NestedModule: + DscResource.Common: + CopyOnly: true + Path: ./output/RequiredModules/DscResource.Common + AddToManifest: false + Exclude: PSGetModuleInfo.xml + DscResource.Base: + CopyOnly: true + Path: ./output/RequiredModules/DscResource.Base + AddToManifest: false + Exclude: PSGetModuleInfo.xml + +#################################################### +# Pester Configuration (Sampler) # +#################################################### +Pester: + Configuration: + Run: + Path: + - tests/Unit + Output: + Verbosity: Detailed + StackTraceVerbosity: Full + CIFormat: Auto + CodeCoverage: + CoveragePercentTarget: 80 + OutputPath: JaCoCo_coverage.xml + OutputEncoding: ascii + UseBreakpoints: false + TestResult: + OutputFormat: NUnitXML + OutputEncoding: ascii + ExcludeFromCodeCoverage: + - Modules/DscResource.Common + - Modules/DscResource.Base + +#################################################### +# Pester Configuration (DscResource.Test) # +#################################################### +DscTest: + Pester: + Configuration: + Filter: + ExcludeTag: + - "Common Tests - New Error-Level Script Analyzer Rules" + Output: + Verbosity: Detailed + CIFormat: Auto + TestResult: + Enabled: true + OutputFormat: NUnitXML + OutputEncoding: ascii + OutputPath: ./output/testResults/NUnitXml_HQRM_Tests.xml + Script: + ExcludeSourceFile: + - output + ExcludeModuleFile: + - Modules/DscResource.Common + - Modules/DscResource.Base + # Must exclude built module file because it should not be tested like MOF-based resources + - DnsServerDsc.psm1 + MainGitBranch: main + +#################################################### +# PSDepend Configuration # +#################################################### +Resolve-Dependency: + Gallery: "PSGallery" + AllowPrerelease: false + Verbose: false + +#################################################### +# GitHub Configuration # +#################################################### GitHubConfig: GitHubFilesToAdd: - - 'CHANGELOG.md' - GitHubConfigUserName: dscbot + - "CHANGELOG.md" + ReleaseAssets: + - output/WikiContent.zip + GitHubConfigUserName: dscbot # cSpell: disable-line GitHubConfigUserEmail: dsccommunity@outlook.com UpdateChangelogOnPrerelease: false @@ -115,6 +166,21 @@ DscResource.DocGenerator: - '\`(.+?)\`' # Match inline code-block - '\\(\\)' # Match escaped backslash - '\[[^\[]+\]\((.+?)\)' # Match markdown URL - - '_(.+?)_' # Match Italic (underscore) + - "_(.+?)_" # Match Italic (underscore) - '\*\*(.+?)\*\*' # Match bold - '\*(.+?)\*' # Match Italic (asterisk) + Publish_GitHub_Wiki_Content: + Debug: false + Generate_Wiki_Content: + MofResourceMetadata: + Type: MofResource + Category: Resources + ClassResourceMetadata: + Type: ClassResource + Category: Resources + CompositeResourceMetadata: + Type: CompositeResource + Category: Resources + Generate_Wiki_Sidebar: + Debug: false + AlwaysOverwrite: true diff --git a/source/Classes/001.DnsServerReason.ps1 b/source/Classes/001.DnsServerReason.ps1 new file mode 100644 index 00000000..198cdd5a --- /dev/null +++ b/source/Classes/001.DnsServerReason.ps1 @@ -0,0 +1,21 @@ +<# + .SYNOPSIS + The reason a property of a DSC resource is not in desired state. + + .DESCRIPTION + A DSC resource can have a read-only property `Reasons` that the compliance + part (audit via Azure Policy) of Azure AutoManage Machine Configuration + uses. The property Reasons holds an array of DnsServerReason. Each DnsServerReason + explains why a property of a DSC resource is not in desired state. +#> + +class DnsServerReason +{ + [DscProperty()] + [System.String] + $Code + + [DscProperty()] + [System.String] + $Phrase +} diff --git a/source/Classes/001.ResourceBase.ps1 b/source/Classes/001.ResourceBase.ps1 deleted file mode 100644 index 3d423ab9..00000000 --- a/source/Classes/001.ResourceBase.ps1 +++ /dev/null @@ -1,211 +0,0 @@ -<# - .SYNOPSIS - A class with methods that are equal for all class-based resources. - - .DESCRIPTION - A class with methods that are equal for all class-based resources. - - .NOTES - This class should not contain any DSC properties. -#> - -class ResourceBase -{ - # Hidden property for holding localization strings - hidden [System.Collections.Hashtable] $localizedData = @{} - - # Default constructor - ResourceBase() - { - $this.localizedData = Get-LocalizedDataRecursive -ClassName ($this | Get-ClassName -Recurse) - } - - [ResourceBase] Get() - { - $this.Assert() - - Write-Verbose -Message ($this.localizedData.GetCurrentState -f $this.DnsServer, $this.GetType().Name) - - # Get all key properties. - $keyProperty = $this | - Get-Member -MemberType 'Property' | - Select-Object -ExpandProperty Name | - Where-Object -FilterScript { - $this.GetType().GetMember($_).CustomAttributes.Where( { $_.NamedArguments.MemberName -eq 'Key' }).NamedArguments.TypedValue.Value -eq $true - } - - $getParameters = @{} - - # Set each key property to its value (property DnsServer is handled below). - $keyProperty | - Where-Object -FilterScript { - $_ -ne 'DnsServer' - } | - ForEach-Object -Process { - $getParameters[$_] = $this.$_ - } - - # Set ComputerName depending on value of DnsServer. - if ($this.DnsServer -ne 'localhost') - { - $getParameters['ComputerName'] = $this.DnsServer - } - - $getCurrentStateResult = $this.GetCurrentState($getParameters) - - $dscResourceObject = [System.Activator]::CreateInstance($this.GetType()) - - foreach ($propertyName in $this.PSObject.Properties.Name) - { - if ($propertyName -in @($getCurrentStateResult.PSObject.Properties.Name)) - { - $dscResourceObject.$propertyName = $getCurrentStateResult.$propertyName - } - } - - # Always set this as it won't be in the $getCurrentStateResult - $dscResourceObject.DnsServer = $this.DnsServer - - # Return properties. - return $dscResourceObject - } - - [void] Set() - { - $this.Assert() - - Write-Verbose -Message ($this.localizedData.SetDesiredState -f $this.DnsServer, $this.GetType().Name) - - # Call the Compare method to get enforced properties that are not in desired state. - $propertiesNotInDesiredState = $this.Compare() - - if ($propertiesNotInDesiredState) - { - $propertiesToModify = $this.GetDesiredStateForSplatting($propertiesNotInDesiredState) - - $propertiesToModify.Keys | ForEach-Object -Process { - Write-Verbose -Message ($this.localizedData.SetProperty -f $_, $propertiesToModify.$_, $this.GetType().Name) - } - - if ($this.DnsServer -ne 'localhost') - { - $propertiesToModify['ComputerName'] = $this.DnsServer - } - - <# - Call the Modify() method with the properties that should be enforced - and was not in desired state. - #> - $this.Modify($propertiesToModify) - } - else - { - Write-Verbose -Message $this.localizedData.NoPropertiesToSet - } - } - - [System.Boolean] Test() - { - Write-Verbose -Message ($this.localizedData.TestDesiredState -f $this.DnsServer, $this.GetType().Name) - - $this.Assert() - - $isInDesiredState = $true - - <# - Returns all enforced properties not in desires state, or $null if - all enforced properties are in desired state. - #> - $propertiesNotInDesiredState = $this.Compare() - - if ($propertiesNotInDesiredState) - { - $isInDesiredState = $false - } - - if ($isInDesiredState) - { - Write-Verbose -Message ($this.localizedData.InDesiredState -f $this.DnsServer, $this.GetType().Name) - } - else - { - Write-Verbose -Message ($this.localizedData.NotInDesiredState -f $this.DnsServer, $this.GetType().Name) - } - - return $isInDesiredState - } - - <# - Returns a hashtable containing all properties that should be enforced. - This method should normally not be overridden. - #> - hidden [System.Collections.Hashtable[]] Compare() - { - $currentState = $this.Get() | ConvertFrom-DscResourceInstance - $desiredState = $this | ConvertFrom-DscResourceInstance - - <# - Remove properties that have $null as the value, and remove read - properties so that there is no chance to compare those. - #> - @($desiredState.Keys) | ForEach-Object -Process { - $isReadProperty = $this.GetType().GetMember($_).CustomAttributes.Where( { $_.NamedArguments.MemberName -eq 'NotConfigurable' }).NamedArguments.TypedValue.Value -eq $true - - if ($isReadProperty -or $null -eq $desiredState[$_]) - { - $desiredState.Remove($_) - } - } - - $CompareDscParameterState = @{ - CurrentValues = $currentState - DesiredValues = $desiredState - Properties = $desiredState.Keys - ExcludeProperties = @('DnsServer') - IncludeValue = $true - } - - <# - Returns all enforced properties not in desires state, or $null if - all enforced properties are in desired state. - #> - return (Compare-DscParameterState @CompareDscParameterState) - } - - # Returns a hashtable containing all properties that should be enforced. - hidden [System.Collections.Hashtable] GetDesiredStateForSplatting([System.Collections.Hashtable[]] $Properties) - { - $desiredState = @{} - - $Properties | ForEach-Object -Process { - $desiredState[$_.Property] = $_.ExpectedValue - } - - return $desiredState - } - - # This method should normally not be overridden. - hidden [void] Assert() - { - Assert-Module -ModuleName 'DnsServer' - - $this.AssertProperties() - } - - # This method can be overridden if resource specific asserts are needed. - hidden [void] AssertProperties() - { - } - - # This method must be overridden by a resource. - hidden [void] Modify([System.Collections.Hashtable] $properties) - { - throw $this.localizedData.ModifyMethodNotImplemented - } - - # This method must be overridden by a resource. - hidden [Microsoft.Management.Infrastructure.CimInstance] GetCurrentState([System.Collections.Hashtable] $properties) - { - throw $this.localizedData.GetCurrentStateMethodNotImplemented - } -} diff --git a/source/Classes/001.ResourcePropertiesBase.ps1 b/source/Classes/012.ResourcePropertiesBase.ps1 similarity index 100% rename from source/Classes/001.ResourcePropertiesBase.ps1 rename to source/Classes/012.ResourcePropertiesBase.ps1 diff --git a/source/Classes/002.DnsRecordBase.ps1 b/source/Classes/015.DnsRecordBase.ps1 similarity index 97% rename from source/Classes/002.DnsRecordBase.ps1 rename to source/Classes/015.DnsRecordBase.ps1 index 55c30f08..cbe9a50b 100644 --- a/source/Classes/002.DnsRecordBase.ps1 +++ b/source/Classes/015.DnsRecordBase.ps1 @@ -39,7 +39,7 @@ class DnsRecordBase : ResourcePropertiesBase hidden [void] SetLocalizedData() { # Create a list of the inherited class names - $inheritedClasses = @(,$this.GetType().Name) + $inheritedClasses = @(, $this.GetType().Name) $parentClass = $this.GetType().BaseType while ($parentClass -ne [System.Object]) { @@ -51,12 +51,10 @@ class DnsRecordBase : ResourcePropertiesBase foreach ($className in $inheritedClasses) { - # Get localized data for the class - $localizationFile = "$($className).strings.psd1" try { - $tmpData = Get-LocalizedData -DefaultUICulture 'en-US' -FileName $localizationFile -ErrorAction Stop + $tmpData = Get-LocalizedData -DefaultUICulture 'en-US' -FileName $className -ErrorAction Stop # Append only previously unspecified keys in the localization data foreach ($key in $tmpData.Keys) diff --git a/source/Classes/002.DnsRecordCname.ps1 b/source/Classes/020.DnsRecordCname.ps1 similarity index 93% rename from source/Classes/002.DnsRecordCname.ps1 rename to source/Classes/020.DnsRecordCname.ps1 index db9b0a48..17c66b23 100644 --- a/source/Classes/002.DnsRecordCname.ps1 +++ b/source/Classes/020.DnsRecordCname.ps1 @@ -6,10 +6,10 @@ The DnsRecordCname DSC resource manages CNAME DNS records against a specific zone on a Domain Name System (DNS) server. .PARAMETER Name - Specifies the name of a DNS server resource record object. (Key Parameter) + Specifies the name of a DNS server resource record object. (Key Parameter) .PARAMETER HostNameAlias - Specifies a a canonical name target for a CNAME record. This must be a fully qualified domain name (FQDN). (Key Parameter) + Specifies a a canonical name target for a CNAME record. This must be a fully qualified domain name (FQDN). (Key Parameter) #> [DscResource()] @@ -23,6 +23,10 @@ class DnsRecordCname : DnsRecordBase [System.String] $HostNameAlias + DnsRecordCname() + { + } + [DnsRecordCname] Get() { return ([DnsRecordBase] $this).Get() diff --git a/source/Classes/002.DnsRecordPtr.ps1 b/source/Classes/020.DnsRecordPtr.ps1 similarity index 97% rename from source/Classes/002.DnsRecordPtr.ps1 rename to source/Classes/020.DnsRecordPtr.ps1 index eba80d7c..cce392dc 100644 --- a/source/Classes/002.DnsRecordPtr.ps1 +++ b/source/Classes/020.DnsRecordPtr.ps1 @@ -28,6 +28,10 @@ class DnsRecordPtr : DnsRecordBase hidden [System.String] $recordHostName + DnsRecordPtr() + { + } + [DnsRecordPtr] Get() { # Ensure $recordHostName is set @@ -140,7 +144,7 @@ class DnsRecordPtr : DnsRecordBase $blankSegmentCount = 8 - $segments.count # Hold the expanded segments - $newSegments = [System.Collections.ArrayList]::new() + $newSegments = [System.Collections.ArrayList]::new() # Insert missing segments foreach ($segment in $segments) @@ -151,7 +155,8 @@ class DnsRecordPtr : DnsRecordBase { $newSegments.Add('0000') } - } else + } + else { $newSegments.Add($segment) } @@ -194,7 +199,7 @@ class DnsRecordPtr : DnsRecordBase # Determine the record host name hidden [System.String] getRecordHostName([System.Net.IpAddress] $ipAddressObj) { - $reverseLookupAddressComponent = "" + $reverseLookupAddressComponent = '' switch ($ipAddressObj.AddressFamily) { @@ -228,7 +233,7 @@ class DnsRecordPtr : DnsRecordBase } # Strip the zone name from the reversed IP using a regular expression - $ptrRecordHostName = $reverseNotation -replace "\.$([System.Text.RegularExpressions.Regex]::Escape($reverseLookupAddressComponent))`$", "" + $ptrRecordHostName = $reverseNotation -replace "\.$([System.Text.RegularExpressions.Regex]::Escape($reverseLookupAddressComponent))`$", '' return $ptrRecordHostName } diff --git a/source/Classes/003.DnsRecordA.ps1 b/source/Classes/030.DnsRecordA.ps1 similarity index 97% rename from source/Classes/003.DnsRecordA.ps1 rename to source/Classes/030.DnsRecordA.ps1 index 2d1d9185..a2365d29 100644 --- a/source/Classes/003.DnsRecordA.ps1 +++ b/source/Classes/030.DnsRecordA.ps1 @@ -9,7 +9,7 @@ Specifies the name of a DNS server resource record object. (Key Parameter) .PARAMETER IPv4Address - Specifies the IPv4 address of a host. (Key Parameter) + Specifies the IPv4 address of a host. (Key Parameter) #> [DscResource()] @@ -23,6 +23,10 @@ class DnsRecordA : DnsRecordBase [System.String] $IPv4Address + DnsRecordA () + { + } + [DnsRecordA] Get() { return ([DnsRecordBase] $this).Get() diff --git a/source/Classes/003.DnsRecordAaaa.ps1 b/source/Classes/030.DnsRecordAaaa.ps1 similarity index 96% rename from source/Classes/003.DnsRecordAaaa.ps1 rename to source/Classes/030.DnsRecordAaaa.ps1 index 8fe33392..4ee8accb 100644 --- a/source/Classes/003.DnsRecordAaaa.ps1 +++ b/source/Classes/030.DnsRecordAaaa.ps1 @@ -9,7 +9,7 @@ Specifies the name of a DNS server resource record object. (Key Parameter) .PARAMETER IPv6Address - Specifies the IPv6 address of a host. (Key Parameter) + Specifies the IPv6 address of a host. (Key Parameter) #> [DscResource()] @@ -23,6 +23,10 @@ class DnsRecordAaaa : DnsRecordBase [System.String] $IPv6Address + DnsRecordAaaa() + { + } + [DnsRecordAaaa] Get() { return ([DnsRecordBase] $this).Get() @@ -55,7 +59,7 @@ class DnsRecordAaaa : DnsRecordBase } $record = Get-DnsServerResourceRecord @dnsParameters -ErrorAction SilentlyContinue | Where-Object -FilterScript { - $_.RecordData.IPv6Address -eq $this.IPv6Address + $_.RecordData.IPv6Address -eq $this.IPv6Address } return $record diff --git a/source/Classes/003.DnsRecordMx.ps1 b/source/Classes/030.DnsRecordMx.ps1 similarity index 99% rename from source/Classes/003.DnsRecordMx.ps1 rename to source/Classes/030.DnsRecordMx.ps1 index 9ca32697..6e2b2446 100644 --- a/source/Classes/003.DnsRecordMx.ps1 +++ b/source/Classes/030.DnsRecordMx.ps1 @@ -32,6 +32,10 @@ class DnsRecordMx : DnsRecordBase hidden [System.String] $recordName + DnsRecordMx() + { + } + [DnsRecordMx] Get() { $this.recordName = $this.getRecordName() diff --git a/source/Classes/003.DnsRecordNs.ps1 b/source/Classes/030.DnsRecordNs.ps1 similarity index 99% rename from source/Classes/003.DnsRecordNs.ps1 rename to source/Classes/030.DnsRecordNs.ps1 index 58885735..fad0ea55 100644 --- a/source/Classes/003.DnsRecordNs.ps1 +++ b/source/Classes/030.DnsRecordNs.ps1 @@ -23,6 +23,10 @@ class DnsRecordNs : DnsRecordBase [System.String] $NameServer + DnsRecordNs() + { + } + [DnsRecordNs] Get() { return ([DnsRecordBase] $this).Get() diff --git a/source/Classes/003.DnsRecordSrv.ps1 b/source/Classes/030.DnsRecordSrv.ps1 similarity index 99% rename from source/Classes/003.DnsRecordSrv.ps1 rename to source/Classes/030.DnsRecordSrv.ps1 index d287b560..8aac41d1 100644 --- a/source/Classes/003.DnsRecordSrv.ps1 +++ b/source/Classes/030.DnsRecordSrv.ps1 @@ -63,6 +63,10 @@ class DnsRecordSrv : DnsRecordBase return "_$($aSymbolicName)._$($aProtocol)".ToLower() } + DnsRecordSrv() + { + } + [DnsRecordSrv] Get() { return ([DnsRecordBase] $this).Get() diff --git a/source/Classes/003.DnsServerCache.ps1 b/source/Classes/030.DnsServerCache.ps1 similarity index 74% rename from source/Classes/003.DnsServerCache.ps1 rename to source/Classes/030.DnsServerCache.ps1 index aff2c64e..8b6db643 100644 --- a/source/Classes/003.DnsServerCache.ps1 +++ b/source/Classes/030.DnsServerCache.ps1 @@ -57,6 +57,9 @@ .PARAMETER StoreEmptyAuthenticationResponse Specifies whether a DNS server stores empty authoritative responses in the cache (RFC-2308). + + .PARAMETER Reasons + Returns the reason a property is not in desired state. #> [DscResource()] @@ -94,16 +97,45 @@ class DnsServerCache : ResourceBase [Nullable[System.Boolean]] $StoreEmptyAuthenticationResponse + [DscProperty(NotConfigurable)] + [DnsServerReason[]] + $Reasons + + DnsServerCache() : base ($PSScriptRoot) + { + # These properties will not be enforced. + $this.ExcludeDscProperties = @( + 'DnsServer' + ) + } + [DnsServerCache] Get() { # Call the base method to return the properties. return ([ResourceBase] $this).Get() } - # Base method Get() call this method to get the current state as a CimInstance. - [Microsoft.Management.Infrastructure.CimInstance] GetCurrentState([System.Collections.Hashtable] $properties) + # Base method Get() call this method to get the current state as a Hashtable. + [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) { - return (Get-DnsServerCache @properties) + $getParameters = @{ + ComputerName = $properties.DnsServer + } + + $getCurrentStateResult = Get-DnsServerCache @getParameters + + $state = @{ + DnsServer = $properties.DnsServer + IgnorePolicies = $getCurrentStateResult.IgnorePolicies + LockingPercent = [System.UInt32] $getCurrentStateResult.LockingPercent + MaxKBSize = [System.UInt32] $getCurrentStateResult.MaxKBSize + MaxNegativeTtl = $getCurrentStateResult.MaxNegativeTtl + MaxTtl = $getCurrentStateResult.MaxTtl + EnablePollutionProtection = $getCurrentStateResult.EnablePollutionProtection + StoreEmptyAuthenticationResponse = $getCurrentStateResult.StoreEmptyAuthenticationResponse + } + + return $state } [void] Set() @@ -140,16 +172,16 @@ class DnsServerCache : ResourceBase return ([ResourceBase] $this).Test() } - hidden [void] AssertProperties() + hidden [void] AssertProperties([System.Collections.Hashtable] $properties) { - if ($null -ne $this.MaxNegativeTtl) + if ($null -ne $properties.MaxNegativeTtl) { - Assert-TimeSpan -PropertyName 'MaxNegativeTtl' -Value $this.MaxNegativeTtl -Minimum '0.00:00:01' -Maximum '30.00:00:00' + Assert-TimeSpan -PropertyName 'MaxNegativeTtl' -Value $properties.MaxNegativeTtl -Minimum '0.00:00:01' -Maximum '30.00:00:00' } - if ($null -ne $this.MaxTtl) + if ($null -ne $properties.MaxTtl) { - Assert-TimeSpan -PropertyName 'MaxTtl' -Value $this.MaxTtl -Minimum '0.00:00:00' -Maximum '30.00:00:00' + Assert-TimeSpan -PropertyName 'MaxTtl' -Value $properties.MaxTtl -Minimum '0.00:00:00' -Maximum '30.00:00:00' } } } diff --git a/source/Classes/003.DnsServerDsSetting.ps1 b/source/Classes/030.DnsServerDsSetting.ps1 similarity index 80% rename from source/Classes/003.DnsServerDsSetting.ps1 rename to source/Classes/030.DnsServerDsSetting.ps1 index 3b235495..b0fbea9f 100644 --- a/source/Classes/003.DnsServerDsSetting.ps1 +++ b/source/Classes/030.DnsServerDsSetting.ps1 @@ -79,6 +79,9 @@ EntombedTime (section 2.2.2.2.3.23 of MS-DNSP) value that is greater than previous directory service DSTombstoneInterval seconds. You must permanently delete all such nodes from the directory server. + + .PARAMETER Reasons + Returns the reason a property is not in desired state. #> [DscResource()] @@ -112,16 +115,44 @@ class DnsServerDsSetting : ResourceBase [System.String] $TombstoneInterval + [DscProperty(NotConfigurable)] + [DnsServerReason[]] + $Reasons + + DnsServerDsSetting() : base ($PSScriptRoot) + { + # These properties will not be enforced. + $this.ExcludeDscProperties = @( + 'DnsServer' + ) + } + [DnsServerDsSetting] Get() { # Call the base method to return the properties. return ([ResourceBase] $this).Get() } - # Base method Get() call this method to get the current state as a CimInstance. - [Microsoft.Management.Infrastructure.CimInstance] GetCurrentState([System.Collections.Hashtable] $properties) + # Base method Get() call this method to get the current state as a Hashtable. + [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) { - return (Get-DnsServerDsSetting @properties) + $getParameters = @{ + ComputerName = $properties.DnsServer + } + + $getCurrentStateResult = Get-DnsServerDsSetting @getParameters + + $state = @{ + DnsServer = $properties.DnsServer + DirectoryPartitionAutoEnlistInterval = $getCurrentStateResult.DirectoryPartitionAutoEnlistInterval + LazyUpdateInterval = [System.UInt32] $getCurrentStateResult.LazyUpdateInterval + MinimumBackgroundLoadThreads = [System.UInt32] $getCurrentStateResult.MinimumBackgroundLoadThreads + PollingInterval = $getCurrentStateResult.PollingInterval + RemoteReplicationDelay = [System.UInt32] $getCurrentStateResult.RemoteReplicationDelay + TombstoneInterval = $getCurrentStateResult.TombstoneInterval + } + + return $state } [void] Set() @@ -145,18 +176,17 @@ class DnsServerDsSetting : ResourceBase return ([ResourceBase] $this).Test() } - hidden [void] AssertProperties() + hidden [void] AssertProperties([System.Collections.Hashtable] $properties) { @( 'DirectoryPartitionAutoEnlistInterval', 'TombstoneInterval' ) | ForEach-Object -Process { - $valueToConvert = $this.$_ # Only evaluate properties that have a value. - if ($null -ne $valueToConvert) + if ($null -ne $properties.$_) { - Assert-TimeSpan -PropertyName $_ -Value $valueToConvert -Minimum '0.00:00:00' + Assert-TimeSpan -PropertyName $_ -Value $properties.$_ -Minimum '0.00:00:00' } } } diff --git a/source/Classes/003.DnsServerEDns.ps1 b/source/Classes/030.DnsServerEDns.ps1 similarity index 65% rename from source/Classes/003.DnsServerEDns.ps1 rename to source/Classes/030.DnsServerEDns.ps1 index 913cf20b..5143067c 100644 --- a/source/Classes/003.DnsServerEDns.ps1 +++ b/source/Classes/030.DnsServerEDns.ps1 @@ -20,6 +20,9 @@ .PARAMETER EnableReception Specifies whether the DNS server accepts queries that contain an EDNS record. + + .PARAMETER Reasons + Returns the reason a property is not in desired state. #> [DscResource()] @@ -41,16 +44,41 @@ class DnsServerEDns : ResourceBase [Nullable[System.Boolean]] $EnableReception + [DscProperty(NotConfigurable)] + [DnsServerReason[]] + $Reasons + + DnsServerEDns() : base ($PSScriptRoot) + { + # These properties will not be enforced. + $this.ExcludeDscProperties = @( + 'DnsServer' + ) + } + [DnsServerEDns] Get() { # Call the base method to return the properties. return ([ResourceBase] $this).Get() } - # Base method Get() call this method to get the current state as a CimInstance. - [Microsoft.Management.Infrastructure.CimInstance] GetCurrentState([System.Collections.Hashtable] $properties) + # Base method Get() call this method to get the current state as a Hashtable. + [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) { - return (Get-DnsServerEDns @properties) + $getParameters = @{ + ComputerName = $properties.DnsServer + } + + $getCurrentStateResult = Get-DnsServerEDns @getParameters + + $state = @{ + DnsServer = $properties.DnsServer + CacheTimeout = $getCurrentStateResult.CacheTimeout + EnableProbes = $getCurrentStateResult.EnableProbes + EnableReception = $getCurrentStateResult.EnableReception + } + + return $state } [void] Set() @@ -74,17 +102,15 @@ class DnsServerEDns : ResourceBase return ([ResourceBase] $this).Test() } - hidden [void] AssertProperties() + hidden [void] AssertProperties([System.Collections.Hashtable] $properties) { @( 'CacheTimeout' ) | ForEach-Object -Process { - $valueToConvert = $this.$_ - # Only evaluate properties that have a value. - if ($null -ne $valueToConvert) + if ($null -ne $properties.$_) { - Assert-TimeSpan -PropertyName $_ -Value $valueToConvert -Minimum '0.00:00:00' + Assert-TimeSpan -PropertyName $_ -Value $properties.$_ -Minimum '0.00:00:00' } } } diff --git a/source/Classes/003.DnsServerRecursion.ps1 b/source/Classes/030.DnsServerRecursion.ps1 similarity index 81% rename from source/Classes/003.DnsServerRecursion.ps1 rename to source/Classes/030.DnsServerRecursion.ps1 index f0f572aa..49f56bd1 100644 --- a/source/Classes/003.DnsServerRecursion.ps1 +++ b/source/Classes/030.DnsServerRecursion.ps1 @@ -44,6 +44,9 @@ recursion occurs over a slow link. See recommendation in the documentation of [Set-DnsServerRecursion](https://docs.microsoft.com/en-us/powershell/module/dnsserver/set-dnsserverrecursion). + .PARAMETER Reasons + Returns the reason a property is not in desired state. + .NOTES The cmdlet Set-DsnServerRecursion allows to set the value 0 (zero) for the properties AdditionalTimeout, RetryInterval, and Timeout, but setting the @@ -77,16 +80,42 @@ class DnsServerRecursion : ResourceBase [Nullable[System.UInt32]] $Timeout + [DscProperty(NotConfigurable)] + [DnsServerReason[]] + $Reasons + + DnsServerRecursion() : base ($PSScriptRoot) + { + # These properties will not be enforced. + $this.ExcludeDscProperties = @( + 'DnsServer' + ) + } + [DnsServerRecursion] Get() { # Call the base method to return the properties. return ([ResourceBase] $this).Get() } - # Base method Get() call this method to get the current state as a CimInstance. - [Microsoft.Management.Infrastructure.CimInstance] GetCurrentState([System.Collections.Hashtable] $properties) + # Base method Get() call this method to get the current state as a Hashtable. + [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) { - return (Get-DnsServerRecursion @properties) + $getParameters = @{ + ComputerName = $properties.DnsServer + } + + $getCurrentStateResult = Get-DnsServerRecursion @getParameters + + $state = @{ + DnsServer = $properties.DnsServer + Enable = $getCurrentStateResult.Enable + AdditionalTimeout = [System.UInt32] $getCurrentStateResult.AdditionalTimeout + RetryInterval = [System.UInt32] $getCurrentStateResult.RetryInterval + Timeout = [System.UInt32] $getCurrentStateResult.Timeout + } + + return $state } [void] Set() @@ -111,14 +140,14 @@ class DnsServerRecursion : ResourceBase } # Called by the base method Set() and Test() to assert that all properties are valid. - hidden [void] AssertProperties() + hidden [void] AssertProperties([System.Collections.Hashtable] $properties) { @( 'AdditionalTimeout' 'RetryInterval' 'Timeout' ) | ForEach-Object -Process { - $propertyValue = $this.$_ + $propertyValue = $properties.$_ # Only evaluate properties that have a value. if ($null -ne $propertyValue -and $propertyValue -notin (1..15)) diff --git a/source/Classes/003.DnsServerScavenging.ps1 b/source/Classes/030.DnsServerScavenging.ps1 similarity index 75% rename from source/Classes/003.DnsServerScavenging.ps1 rename to source/Classes/030.DnsServerScavenging.ps1 index 5af4fd0e..0504dd74 100644 --- a/source/Classes/003.DnsServerScavenging.ps1 +++ b/source/Classes/030.DnsServerScavenging.ps1 @@ -47,6 +47,9 @@ .PARAMETER LastScavengeTime The time when the last scavenging cycle was executed. + + .PARAMETER Reasons + Returns the reason a property is not in desired state. #> [DscResource()] @@ -76,16 +79,43 @@ class DnsServerScavenging : ResourceBase [Nullable[System.DateTime]] $LastScavengeTime + [DscProperty(NotConfigurable)] + [DnsServerReason[]] + $Reasons + + DnsServerScavenging() : base ($PSScriptRoot) + { + # These properties will not be enforced. + $this.ExcludeDscProperties = @( + 'DnsServer' + ) + } + [DnsServerScavenging] Get() { # Call the base method to return the properties. return ([ResourceBase] $this).Get() } - # Base method Get() call this method to get the current state as a CimInstance. - [Microsoft.Management.Infrastructure.CimInstance] GetCurrentState([System.Collections.Hashtable] $properties) + # Base method Get() call this method to get the current state as a Hashtable. + [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) { - return (Get-DnsServerScavenging @properties) + $getParameters = @{ + ComputerName = $properties.DnsServer + } + + $getCurrentStateResult = Get-DnsServerScavenging @getParameters + + $state = @{ + DnsServer = $properties.DnsServer + ScavengingState = $getCurrentStateResult.ScavengingState + ScavengingInterval = $getCurrentStateResult.ScavengingInterval + RefreshInterval = $getCurrentStateResult.RefreshInterval + NoRefreshInterval = $getCurrentStateResult.NoRefreshInterval + LastScavengeTime = $getCurrentStateResult.LastScavengeTime + } + + return $state } [void] Set() @@ -109,19 +139,18 @@ class DnsServerScavenging : ResourceBase return ([ResourceBase] $this).Test() } - hidden [void] AssertProperties() + hidden [void] AssertProperties([System.Collections.Hashtable] $properties) { @( 'ScavengingInterval' 'RefreshInterval' 'NoRefreshInterval' ) | ForEach-Object -Process { - $valueToConvert = $this.$_ # Only evaluate properties that have a value. - if ($null -ne $valueToConvert) + if ($null -ne $properties.$_) { - Assert-TimeSpan -PropertyName $_ -Value $valueToConvert -Maximum '365.00:00:00' -Minimum '0.00:00:00' + Assert-TimeSpan -PropertyName $_ -Value $properties.$_ -Maximum '365.00:00:00' -Minimum '0.00:00:00' } } } diff --git a/source/Classes/004.DnsRecordAScoped.ps1 b/source/Classes/040.DnsRecordAScoped.ps1 similarity index 98% rename from source/Classes/004.DnsRecordAScoped.ps1 rename to source/Classes/040.DnsRecordAScoped.ps1 index f60110ed..e102f54a 100644 --- a/source/Classes/004.DnsRecordAScoped.ps1 +++ b/source/Classes/040.DnsRecordAScoped.ps1 @@ -16,6 +16,10 @@ class DnsRecordAScoped : DnsRecordA [System.String] $ZoneScope + DnsRecordAScoped () + { + } + [DnsRecordAScoped] Get() { return ([DnsRecordBase] $this).Get() diff --git a/source/Classes/004.DnsRecordAaaaScoped.ps1 b/source/Classes/040.DnsRecordAaaaScoped.ps1 similarity index 97% rename from source/Classes/004.DnsRecordAaaaScoped.ps1 rename to source/Classes/040.DnsRecordAaaaScoped.ps1 index 6582a4cd..4586c1fc 100644 --- a/source/Classes/004.DnsRecordAaaaScoped.ps1 +++ b/source/Classes/040.DnsRecordAaaaScoped.ps1 @@ -16,6 +16,10 @@ class DnsRecordAaaaScoped : DnsRecordAaaa [System.String] $ZoneScope + DnsRecordAaaaScoped() + { + } + [DnsRecordAaaaScoped] Get() { return ([DnsRecordBase] $this).Get() diff --git a/source/Classes/003.DnsRecordCnameScoped.ps1 b/source/Classes/040.DnsRecordCnameScoped.ps1 similarity index 97% rename from source/Classes/003.DnsRecordCnameScoped.ps1 rename to source/Classes/040.DnsRecordCnameScoped.ps1 index 8e843b25..e41401d8 100644 --- a/source/Classes/003.DnsRecordCnameScoped.ps1 +++ b/source/Classes/040.DnsRecordCnameScoped.ps1 @@ -16,6 +16,10 @@ class DnsRecordCnameScoped : DnsRecordCname [System.String] $ZoneScope + DnsRecordCnameScoped() + { + } + [DnsRecordCnameScoped] Get() { return ([DnsRecordBase] $this).Get() diff --git a/source/Classes/004.DnsRecordMxScoped.ps1 b/source/Classes/040.DnsRecordMxScoped.ps1 similarity index 98% rename from source/Classes/004.DnsRecordMxScoped.ps1 rename to source/Classes/040.DnsRecordMxScoped.ps1 index 747a8af7..beb0ba1b 100644 --- a/source/Classes/004.DnsRecordMxScoped.ps1 +++ b/source/Classes/040.DnsRecordMxScoped.ps1 @@ -16,6 +16,10 @@ class DnsRecordMxScoped : DnsRecordMx [System.String] $ZoneScope + DnsRecordMxScoped() + { + } + [DnsRecordMxScoped] Get() { return ([DnsRecordBase] $this).Get() diff --git a/source/Classes/004.DnsRecordNsScoped.ps1 b/source/Classes/040.DnsRecordNsScoped.ps1 similarity index 98% rename from source/Classes/004.DnsRecordNsScoped.ps1 rename to source/Classes/040.DnsRecordNsScoped.ps1 index 631d1ae7..7179ede5 100644 --- a/source/Classes/004.DnsRecordNsScoped.ps1 +++ b/source/Classes/040.DnsRecordNsScoped.ps1 @@ -16,6 +16,10 @@ class DnsRecordNsScoped : DnsRecordNs [System.String] $ZoneScope + DnsRecordNsScoped() + { + } + [DnsRecordNsScoped] Get() { return ([DnsRecordBase] $this).Get() diff --git a/source/Classes/004.DnsRecordSrvScoped.ps1 b/source/Classes/040.DnsRecordSrvScoped.ps1 similarity index 98% rename from source/Classes/004.DnsRecordSrvScoped.ps1 rename to source/Classes/040.DnsRecordSrvScoped.ps1 index bf3b4483..13a83059 100644 --- a/source/Classes/004.DnsRecordSrvScoped.ps1 +++ b/source/Classes/040.DnsRecordSrvScoped.ps1 @@ -16,6 +16,10 @@ class DnsRecordSrvScoped : DnsRecordSrv [System.String] $ZoneScope + DnsRecordSrvScoped() + { + } + [DnsRecordSrvScoped] Get() { return ([DnsRecordBase] $this).Get() diff --git a/source/DSCResources/DSC_DnsServerClientSubnet/DSC_DnsServerClientSubnet.psm1 b/source/DSCResources/DSC_DnsServerClientSubnet/DSC_DnsServerClientSubnet.psm1 index 96cc5dd2..e0542f38 100644 --- a/source/DSCResources/DSC_DnsServerClientSubnet/DSC_DnsServerClientSubnet.psm1 +++ b/source/DSCResources/DSC_DnsServerClientSubnet/DSC_DnsServerClientSubnet.psm1 @@ -234,5 +234,3 @@ function Test-TargetResource Write-Verbose -Message ($script:localizedData.InDesiredStateMessage -f $Name) return $true } #end function Test-TargetResource - -Export-ModuleMember -Function *-TargetResource diff --git a/source/DSCResources/DSC_DnsServerDiagnostics/DSC_DnsServerDiagnostics.psm1 b/source/DSCResources/DSC_DnsServerDiagnostics/DSC_DnsServerDiagnostics.psm1 index e7da4935..b68bd4aa 100644 --- a/source/DSCResources/DSC_DnsServerDiagnostics/DSC_DnsServerDiagnostics.psm1 +++ b/source/DSCResources/DSC_DnsServerDiagnostics/DSC_DnsServerDiagnostics.psm1 @@ -529,5 +529,3 @@ function Test-TargetResource return $result } - -Export-ModuleMember -Function *-TargetResource diff --git a/source/DSCResources/DSC_DnsServerSecondaryZone/DSC_DnsServerSecondaryZone.psm1 b/source/DSCResources/DSC_DnsServerSecondaryZone/DSC_DnsServerSecondaryZone.psm1 index 54b669e4..83b1683d 100644 --- a/source/DSCResources/DSC_DnsServerSecondaryZone/DSC_DnsServerSecondaryZone.psm1 +++ b/source/DSCResources/DSC_DnsServerSecondaryZone/DSC_DnsServerSecondaryZone.psm1 @@ -273,5 +273,3 @@ function Test-ResourceProperties } } #endregion - -Export-ModuleMember -Function *-TargetResource diff --git a/source/DSCResources/DSC_DnsServerZoneScope/DSC_DnsServerZoneScope.psm1 b/source/DSCResources/DSC_DnsServerZoneScope/DSC_DnsServerZoneScope.psm1 index 28253484..44ce0d42 100644 --- a/source/DSCResources/DSC_DnsServerZoneScope/DSC_DnsServerZoneScope.psm1 +++ b/source/DSCResources/DSC_DnsServerZoneScope/DSC_DnsServerZoneScope.psm1 @@ -140,5 +140,3 @@ function Test-TargetResource Write-Verbose -Message ($script:localizedData.InDesiredStateMessage -f $Name) return $true } #end function Test-TargetResource - -Export-ModuleMember -Function *-TargetResource diff --git a/source/DSCResources/DSC_DnsServerZoneTransfer/DSC_DnsServerZoneTransfer.psm1 b/source/DSCResources/DSC_DnsServerZoneTransfer/DSC_DnsServerZoneTransfer.psm1 index 1237f1f1..fab0a685 100644 --- a/source/DSCResources/DSC_DnsServerZoneTransfer/DSC_DnsServerZoneTransfer.psm1 +++ b/source/DSCResources/DSC_DnsServerZoneTransfer/DSC_DnsServerZoneTransfer.psm1 @@ -7,7 +7,7 @@ Import-Module -Name $script:dnsServerDscCommonPath $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' # Allow transfer to any server use 0, to one in name tab 1, specific one 2, no transfer 3 -$XferId2Name= @('Any','Named','Specific','None') +$XferId2Name = @('Any', 'Named', 'Specific', 'None') function Get-TargetResource { @@ -20,22 +20,22 @@ function Get-TargetResource $Name, [Parameter(Mandatory = $true)] - [ValidateSet("None","Any","Named","Specific")] + [ValidateSet('None', 'Any', 'Named', 'Specific')] [System.String] $Type ) -#region Input Validation + #region Input Validation # Check for DnsServer module/role Assert-Module -ModuleName 'DnsServer' -#endregion + #endregion Write-Verbose -Message 'Getting DNS zone.' $currentZone = Get-CimInstance ` -ClassName MicrosoftDNS_Zone ` -Namespace root\MicrosoftDNS ` - -Verbose:$false | Where-Object -FilterScript {$_.Name -eq $Name} + -Verbose:$false | Where-Object -FilterScript { $_.Name -eq $Name } @{ Name = $Name @@ -54,7 +54,7 @@ function Set-TargetResource $Name, [Parameter(Mandatory = $true)] - [ValidateSet("None","Any","Named","Specific")] + [ValidateSet('None', 'Any', 'Named', 'Specific')] [System.String] $Type, @@ -73,7 +73,6 @@ function Set-TargetResource Restart-Service -Name DNS } - function Test-TargetResource { [CmdletBinding()] @@ -85,7 +84,7 @@ function Test-TargetResource $Name, [Parameter(Mandatory = $true)] - [ValidateSet("None","Any","Named","Specific")] + [ValidateSet('None', 'Any', 'Named', 'Specific')] [System.String] $Type, @@ -94,12 +93,12 @@ function Test-TargetResource $SecondaryServer ) -#region Input Validation + #region Input Validation # Check for DnsServer module/role Assert-Module -ModuleName 'DnsServer' -#endregion + #endregion Write-Verbose -Message 'Validating DNS zone.' if ($PSBoundParameters.ContainsKey('Debug')) { @@ -119,7 +118,7 @@ function Test-ResourceProperties $Name, [Parameter(Mandatory = $true)] - [ValidateSet("None","Any","Named","Specific")] + [ValidateSet('None', 'Any', 'Named', 'Specific')] [System.String] $Type, @@ -140,7 +139,7 @@ function Test-ResourceProperties $currentZone = Get-CimInstance ` -ClassName MicrosoftDNS_Zone ` -Namespace root\MicrosoftDNS ` - -Verbose:$false | Where-Object -FilterScript {$_.Name -eq $Name} + -Verbose:$false | Where-Object -FilterScript { $_.Name -eq $Name } $currentZoneTransfer = $currentZone.SecureSecondaries # Hashtable with 2 keys: SecureSecondaries,SecondaryServers @@ -163,7 +162,7 @@ function Test-ResourceProperties 'Specific' { $Arguments['SecureSecondaries'] = 2 - $Arguments['SecondaryServers']=$SecondaryServer + $Arguments['SecondaryServers'] = $SecondaryServer } } @@ -176,10 +175,10 @@ function Test-ResourceProperties # If the Type is specific, and SecondaryServer doesn't match if (($currentZoneTransfer -eq 2) ` - -and (Compare-Object $currentZone.SecondaryServers $SecondaryServer)) + -and (Compare-Object $currentZone.SecondaryServers $SecondaryServer)) { $notDesiredPropertyMessage = ($script:localizedData.NotDesiredPropertyMessage) ` - -f ($SecondaryServer -join ','),($currentZone.SecondaryServers -join ',') + -f ($SecondaryServer -join ','), ($currentZone.SecondaryServers -join ',') Write-Verbose -Message $notDesiredPropertyMessage # Set the SecondaryServer property @@ -213,7 +212,7 @@ function Test-ResourceProperties { $notDesiredZoneMessage = $($script:localizedData.NotDesiredZoneMessage) ` -f $XferId2Name[$Arguments.SecureSecondaries], ` - $XferId2Name[$currentZoneTransfer] + $XferId2Name[$currentZoneTransfer] Write-Verbose -Message $notDesiredZoneMessage if ($Apply) @@ -225,7 +224,7 @@ function Test-ResourceProperties -Verbose:$false $setZoneMessage = $($script:localizedData.SetZoneMessage) ` - -f $Name,$XferId2Name[$Arguments.SecureSecondaries] + -f $Name, $XferId2Name[$Arguments.SecureSecondaries] Write-Verbose -Message $setZoneMessage } else @@ -234,5 +233,3 @@ function Test-ResourceProperties } } # end currentZoneTransfer -ne ExpectedZoneTransfer } - -Export-ModuleMember -Function *-TargetResource diff --git a/source/DnsServerDsc.psm1 b/source/DnsServerDsc.psm1 deleted file mode 100644 index de514a79..00000000 --- a/source/DnsServerDsc.psm1 +++ /dev/null @@ -1 +0,0 @@ -# Note: This content will get replaced as part of the module build. Do not add to this file. diff --git a/source/Private/Assert-TimeSpan.ps1 b/source/Private/Assert-TimeSpan.ps1 index 4dd8ff84..a474f2b9 100644 --- a/source/Private/Assert-TimeSpan.ps1 +++ b/source/Private/Assert-TimeSpan.ps1 @@ -3,7 +3,7 @@ Assert that the value provided can be converted to a TimeSpan object. .PARAMETER Value - The time value as a string that should be converted. + The time value as a string that should be converted. #> function Assert-TimeSpan { diff --git a/source/Private/ConvertTo-TimeSpan.ps1 b/source/Private/ConvertTo-TimeSpan.ps1 index 1ac11d50..5d320257 100644 --- a/source/Private/ConvertTo-TimeSpan.ps1 +++ b/source/Private/ConvertTo-TimeSpan.ps1 @@ -3,7 +3,7 @@ Converts a string value to a TimeSpan object. .PARAMETER Value - The time value as a string that should be converted. + The time value as a string that should be converted. .OUTPUTS Returns an TimeSpan object containing the converted value, or $null if diff --git a/source/Private/Get-ClassName.ps1 b/source/Private/Get-ClassName.ps1 deleted file mode 100644 index a025d1f8..00000000 --- a/source/Private/Get-ClassName.ps1 +++ /dev/null @@ -1,43 +0,0 @@ -<# - .SYNOPSIS - Get the class name of the passed object, and optional an array with - all inherited classes. - - .PARAMETER InputObject - The object to be evaluated. - - .OUTPUTS - Returns a string array with at least one item. -#> -function Get-ClassName -{ - [CmdletBinding()] - [OutputType([System.Object[]])] - param - ( - [Parameter(Mandatory = $true, ValueFromPipeline = $true)] - [PSObject] - $InputObject, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Recurse - ) - - # Create a list of the inherited class names - $class = @($InputObject.GetType().FullName) - - if ($Recurse.IsPresent) - { - $parentClass = $InputObject.GetType().BaseType - - while ($parentClass -ne [System.Object]) - { - $class += $parentClass.FullName - - $parentClass = $parentClass.BaseType - } - } - - return ,$class -} diff --git a/source/Private/Get-LocalizedDataRecursive.ps1 b/source/Private/Get-LocalizedDataRecursive.ps1 deleted file mode 100644 index 6f05a055..00000000 --- a/source/Private/Get-LocalizedDataRecursive.ps1 +++ /dev/null @@ -1,75 +0,0 @@ -<# - .SYNOPSIS - Get the localization strings data from one or more localization string files. - This can be used in classes to be able to inherit localization strings - from one or more parent (base) classes. - - The order of class names passed to parameter `ClassName` determines the order - of importing localization string files. First entry's localization string file - will be imported first, then next entry's localization string file, and so on. - If the second (or any consecutive) entry's localization string file contain a - localization string key that existed in a previous imported localization string - file that localization string key will be ignored. Making it possible for a - child class to override localization strings from one or more parent (base) - classes. - - .PARAMETER ClassName - An array of class names, normally provided by `Get-ClassName -Recurse`. - - .OUTPUTS - Returns a string array with at least one item. -#> -function Get-LocalizedDataRecursive -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [Parameter(Mandatory = $true, ValueFromPipeline = $true)] - [System.String[]] - $ClassName - ) - - begin - { - $localizedData = @{} - } - - process - { - foreach ($name in $ClassName) - { - if ($name -match '\.psd1') - { - # Assume we got full file name. - $localizationFileName = $name - } - else - { - # Assume we only got class name. - $localizationFileName = '{0}.strings.psd1' -f $name - } - - Write-Debug -Message ('Importing localization data from {0}' -f $localizationFileName) - - # Get localized data for the class - $classLocalizationStrings = Get-LocalizedData -DefaultUICulture 'en-US' -FileName $localizationFileName -ErrorAction 'Stop' - - # Append only previously unspecified keys in the localization data - foreach ($key in $classLocalizationStrings.Keys) - { - if (-not $localizedData.ContainsKey($key)) - { - $localizedData[$key] = $classLocalizationStrings[$key] - } - } - } - } - - end - { - Write-Debug -Message ('Localization data: {0}' -f ($localizedData | ConvertTo-JSON)) - - return $localizedData - } -} diff --git a/source/en-US/DnsServerDsc.strings.psd1 b/source/en-US/DnsServerDsc.strings.psd1 index 3b4e73db..d06dd449 100644 --- a/source/en-US/DnsServerDsc.strings.psd1 +++ b/source/en-US/DnsServerDsc.strings.psd1 @@ -6,7 +6,7 @@ #> ConvertFrom-StringData @' - PropertyHasWrongFormat = The property '{0}' has the value '{1}' that cannot be converted to [System.TimeSpan]. (DS0001) + PropertyHasWrongFormat = The property '{0}' has the value '{1}' that cannot be converted to 'System.TimeSpan'. (DS0001) TimeSpanExceedMaximumValue = The property '{0}' has the value '{1}' that exceeds the maximum value of '{2}'. (DS0002) TimeSpanBelowMinimumValue = The property '{0}' has the value '{1}' that is below the minimum value of '{2}'. (DS0003) '@ diff --git a/source/en-US/ResourceBase.strings.psd1 b/source/en-US/ResourceBase.strings.psd1 deleted file mode 100644 index f73e82d4..00000000 --- a/source/en-US/ResourceBase.strings.psd1 +++ /dev/null @@ -1,17 +0,0 @@ -<# - .SYNOPSIS - The localized resource strings in English (en-US) for the - class ResourceBase. -#> - -ConvertFrom-StringData @' - GetCurrentState = Getting the current state of {1} for the server '{0}'. (RB0001) - TestDesiredState = Determining the current state of {1} for the server '{0}'. (RB0002) - SetDesiredState = Setting the desired state of {1} for the server '{0}'. (RB0003) - NotInDesiredState = The {1} for the server '{0}' is not in desired state. (RB0004) - InDesiredState = The {1} for the server '{0}' is in desired state. (RB0005) - SetProperty = The {2} property '{0}' will be set to '{1}'. (RB0006) - NoPropertiesToSet = All properties are in desired state. (RB0007) - ModifyMethodNotImplemented = An override for the method Modify() is not implemented in the resource. (RB0008) - GetCurrentStateMethodNotImplemented = An override for the method GetCurrentState() is not implemented in the resource. (RB0009) -'@ diff --git a/source/prefix.ps1 b/source/prefix.ps1 index e142f8f6..34f904d6 100644 --- a/source/prefix.ps1 +++ b/source/prefix.ps1 @@ -1,5 +1,11 @@ +using module .\Modules\DscResource.Base + # Import nested, 'DscResource.Common' module $script:dscResourceCommonModulePath = Join-Path -Path $PSScriptRoot -ChildPath 'Modules\DscResource.Common' Import-Module -Name $script:dscResourceCommonModulePath +# TODO: The goal would be to remove this, when no classes and public or private functions need it. +$script:dnsServerDscCommonModulePath = Join-Path -Path $PSScriptRoot -ChildPath 'Modules\DnsServerDsc.Common' +Import-Module -Name $script:dnsServerDscCommonModulePath + $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' diff --git a/tests/Integration/Classes/DnsRecordA.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordA.integration.tests.ps1 index 9eb02205..5f5e154b 100644 --- a/tests/Integration/Classes/DnsRecordA.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordA.integration.tests.ps1 @@ -1,222 +1,259 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordA' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordA' -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordA' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordAScoped.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordAScoped.integration.tests.ps1 index 59f94e0b..a03b702a 100644 --- a/tests/Integration/Classes/DnsRecordAScoped.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordAScoped.integration.tests.ps1 @@ -1,222 +1,259 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordAScoped' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordAScoped' -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordAScoped' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv4Address | Should -Be $shouldBeData.IPv4Address - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordAaaa.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordAaaa.integration.tests.ps1 index 14b101f4..5294c3ba 100644 --- a/tests/Integration/Classes/DnsRecordAaaa.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordAaaa.integration.tests.ps1 @@ -1,222 +1,259 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordAaaa' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordAaaa' -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordAaaa' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordAaaaScoped.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordAaaaScoped.integration.tests.ps1 index aa7f4dbc..62790ea6 100644 --- a/tests/Integration/Classes/DnsRecordAaaaScoped.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordAaaaScoped.integration.tests.ps1 @@ -1,222 +1,259 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordAaaaScoped' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordAaaaScoped' -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordAaaaScoped' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.IPv6Address | Should -Be $shouldBeData.IPv6Address - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordCname.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordCname.integration.tests.ps1 index 3368c6be..5599cbff 100644 --- a/tests/Integration/Classes/DnsRecordCname.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordCname.integration.tests.ps1 @@ -1,222 +1,259 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordCname' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordCname' -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordCname' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordCnameScoped.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordCnameScoped.integration.tests.ps1 index 0710a689..f27dbb2e 100644 --- a/tests/Integration/Classes/DnsRecordCnameScoped.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordCnameScoped.integration.tests.ps1 @@ -1,222 +1,259 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordCnameScoped' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordCnameScoped' -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordCnameScoped' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.Name | Should -Be $shouldBeData.Name + $resourceCurrentState.HostNameAlias | Should -Be $shouldBeData.HostNameAlias - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordMx.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordMx.integration.tests.ps1 index ce25f3e6..ed67a84b 100644 --- a/tests/Integration/Classes/DnsRecordMx.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordMx.integration.tests.ps1 @@ -1,231 +1,268 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordMx' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordMx' -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordMx' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain + $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain - $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain + $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain - $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain - $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange - - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain + $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordMxScoped.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordMxScoped.integration.tests.ps1 index 4ff21e83..66c1745e 100644 --- a/tests/Integration/Classes/DnsRecordMxScoped.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordMxScoped.integration.tests.ps1 @@ -1,231 +1,267 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordMxScoped' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordMxScoped' + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordMxScoped' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ + } + AfterAll { + Wait-ForIdleLcm -Clear } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain + $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain - $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain + $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain - $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain - $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange - - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.EmailDomain | Should -Be $shouldBeData.EmailDomain + $resourceCurrentState.MailExchange | Should -Be $shouldBeData.MailExchange - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordNs.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordNs.integration.tests.ps1 index 00337414..24d0b6d2 100644 --- a/tests/Integration/Classes/DnsRecordNs.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordNs.integration.tests.ps1 @@ -1,220 +1,259 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordNs' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordNs' + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordNs' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } + + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName - $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName - $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName - $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' + + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordNsScoped.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordNsScoped.integration.tests.ps1 index 8eb5b13d..164a91c7 100644 --- a/tests/Integration/Classes/DnsRecordNsScoped.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordNsScoped.integration.tests.ps1 @@ -1,220 +1,259 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordNsScoped' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordNsScoped' + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordNsScoped' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } + + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName - $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName - $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName - $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' + + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordPtr.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordPtr.integration.tests.ps1 index cc95eaa3..0e31fb40 100644 --- a/tests/Integration/Classes/DnsRecordPtr.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordPtr.integration.tests.ps1 @@ -1,222 +1,258 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordPtr' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordPtr' + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordPtr' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile - Describe "$($script:dscResourceName)_Integration" { + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress - $resourceCurrentState.Name | Should -Be $shouldBeData.Name + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress - $resourceCurrentState.Name | Should -Be $shouldBeData.Name + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordPtr.v6.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordPtr.v6.integration.tests.ps1 index 090685b0..88f3307e 100644 --- a/tests/Integration/Classes/DnsRecordPtr.v6.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordPtr.v6.integration.tests.ps1 @@ -1,222 +1,259 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordPtr' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordPtr' -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordPtr' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).v6.config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration (IPv6)" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).v6.config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration (IPv6)" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config_v6" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config_v6" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress - $resourceCurrentState.Name | Should -Be $shouldBeData.Name + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config_v6" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config_v6" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress - $resourceCurrentState.Name | Should -Be $shouldBeData.Name + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config_v6" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config_v6" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress - $resourceCurrentState.Name | Should -Be $shouldBeData.Name - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.IpAddress | Should -Be $shouldBeData.IpAddress + $resourceCurrentState.Name | Should -Be $shouldBeData.Name - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be 'Absent' + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordSrv.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordSrv.integration.tests.ps1 index 58c7dad1..2deec418 100644 --- a/tests/Integration/Classes/DnsRecordSrv.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordSrv.integration.tests.ps1 @@ -1,240 +1,277 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordSrv' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordSrv' -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordSrv' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName + $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol + $resourceCurrentState.Port | Should -Be $shouldBeData.Port + $resourceCurrentState.Target | Should -Be $shouldBeData.Target - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName - $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol - $resourceCurrentState.Port | Should -Be $shouldBeData.Port - $resourceCurrentState.Target | Should -Be $shouldBeData.Target + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority + $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName + $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol + $resourceCurrentState.Port | Should -Be $shouldBeData.Port + $resourceCurrentState.Target | Should -Be $shouldBeData.Target - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName - $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol - $resourceCurrentState.Port | Should -Be $shouldBeData.Port - $resourceCurrentState.Target | Should -Be $shouldBeData.Target + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority + $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName - $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol - $resourceCurrentState.Port | Should -Be $shouldBeData.Port - $resourceCurrentState.Target | Should -Be $shouldBeData.Target - - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName + $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol + $resourceCurrentState.Port | Should -Be $shouldBeData.Port + $resourceCurrentState.Target | Should -Be $shouldBeData.Target - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority + $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsRecordSrvScoped.config.ps1 b/tests/Integration/Classes/DnsRecordSrvScoped.config.ps1 index 985c4aa6..fa946187 100644 --- a/tests/Integration/Classes/DnsRecordSrvScoped.config.ps1 +++ b/tests/Integration/Classes/DnsRecordSrvScoped.config.ps1 @@ -79,7 +79,6 @@ configuration DnsRecordSrvScoped_CreateRecord_Config } } - <# .SYNOPSIS Add TimeToLive, Priority, and Weight to an existing SRV record @@ -118,7 +117,6 @@ configuration DnsRecordSrvScoped_ModifyRecord_Config } } - <# .SYNOPSIS Deletes an existing SRV record diff --git a/tests/Integration/Classes/DnsRecordSrvScoped.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordSrvScoped.integration.tests.ps1 index 9b93b5e6..2c82b134 100644 --- a/tests/Integration/Classes/DnsRecordSrvScoped.integration.tests.ps1 +++ b/tests/Integration/Classes/DnsRecordSrvScoped.integration.tests.ps1 @@ -1,240 +1,277 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsRecordSrvScoped' -$script:dscResourceName = "$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordSrvScoped' -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsRecordSrvScoped' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -$initializationParams = @{ - DSCModuleName = $script:dscModuleName - DSCResourceName = $script:dscResourceName - ResourceType = 'Class' - TestType = 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment @initializationParams -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateRecord_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName + $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol + $resourceCurrentState.Port | Should -Be $shouldBeData.Port + $resourceCurrentState.Target | Should -Be $shouldBeData.Target - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName - $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol - $resourceCurrentState.Port | Should -Be $shouldBeData.Port - $resourceCurrentState.Target | Should -Be $shouldBeData.Target + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority + $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null - # Optional properties were not specified, so we just need to ensure the value exists - $resourceCurrentState.TimeToLive | Should -Not -Be $null + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be 'localhost' - $resourceCurrentState.Ensure | Should -Be 'Present' - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ModifyRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName + $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol + $resourceCurrentState.Port | Should -Be $shouldBeData.Port + $resourceCurrentState.Target | Should -Be $shouldBeData.Target - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName - $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol - $resourceCurrentState.Port | Should -Be $shouldBeData.Port - $resourceCurrentState.Target | Should -Be $shouldBeData.Target + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority + $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - # Optional properties - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } - # Defaulted properties - $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure - } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DeleteRecord_Config" + ) { + BeforeAll { + $configurationName = $_ } - Wait-ForIdleLcm -Clear + AfterAll { + Wait-ForIdleLcm -Clear + } - $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId - } - - $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName - # Key properties - $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName - $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope - $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName - $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol - $resourceCurrentState.Port | Should -Be $shouldBeData.Port - $resourceCurrentState.Target | Should -Be $shouldBeData.Target - - # Mandatory properties - $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority - $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight - - # Optional properties - if ($shouldBeData.TimeToLive) - { - $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive - } + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.SymbolicName | Should -Be $shouldBeData.SymbolicName + $resourceCurrentState.Protocol | Should -Be $shouldBeData.Protocol + $resourceCurrentState.Port | Should -Be $shouldBeData.Port + $resourceCurrentState.Target | Should -Be $shouldBeData.Target - # DnsServer is not specified in this test, so it defaults to 'localhost' - $resourceCurrentState.DnsServer | Should -Be 'localhost' + # Mandatory properties + $resourceCurrentState.Priority | Should -Be $shouldBeData.Priority + $resourceCurrentState.Weight | Should -Be $shouldBeData.Weight - # Ensure will be Absent - $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive } - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } - } + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' - Wait-ForIdleLcm -Clear + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } - #endregion -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/Classes/DnsServerCache.Integration.Tests.ps1 b/tests/Integration/Classes/DnsServerCache.Integration.Tests.ps1 index 686abe6a..e67719f4 100644 --- a/tests/Integration/Classes/DnsServerCache.Integration.Tests.ps1 +++ b/tests/Integration/Classes/DnsServerCache.Integration.Tests.ps1 @@ -1,691 +1,801 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DnsServerCache' +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsServerCache' + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false +} -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsServerCache' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_UsePolicies_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_UsePolicies_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.IgnorePolicies | Should -BeFalse + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.IgnorePolicies | Should -BeFalse } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_IgnorePolicies_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_IgnorePolicies_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.IgnorePolicies | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.IgnorePolicies | Should -BeTrue } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_LockingPercent80_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_LockingPercent80_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.LockingPercent | Should -Be 80 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.LockingPercent | Should -Be 80 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_LockingPercent100_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_LockingPercent100_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.LockingPercent | Should -Be 100 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.LockingPercent | Should -Be 100 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_MaxKBSize1000_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_MaxKBSize1000_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.MaxKBSize | Should -Be 1000 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.MaxKBSize | Should -Be 1000 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_MaxKBSize0_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_MaxKBSize0_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.MaxKBSize | Should -Be 0 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.MaxKBSize | Should -Be 0 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_MaxNegativeTtl1Hour_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_MaxNegativeTtl1Hour_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.MaxNegativeTtl | Should -Be '01:00:00' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.MaxNegativeTtl | Should -Be '01:00:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_MaxNegativeTtl15minutes_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_MaxNegativeTtl15minutes_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.MaxNegativeTtl | Should -Be '00:15:00' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.MaxNegativeTtl | Should -Be '00:15:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_MaxTtl3Days_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_MaxTtl3Days_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.MaxTtl | Should -Be '3.00:00:00' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.MaxTtl | Should -Be '3.00:00:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_MaxTtl1Days_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_MaxTtl1Days_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.MaxTtl | Should -Be '1.00:00:00' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.MaxTtl | Should -Be '1.00:00:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_DisablePollutionProtection_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DisablePollutionProtection_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.EnablePollutionProtection | Should -BeFalse + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.EnablePollutionProtection | Should -BeFalse } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_EnablePollutionProtection_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_EnablePollutionProtection_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.EnablePollutionProtection | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.EnablePollutionProtection | Should -BeTrue } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_DisableStoreEmptyAuthenticationResponse_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DisableStoreEmptyAuthenticationResponse_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.StoreEmptyAuthenticationResponse | Should -BeFalse + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.StoreEmptyAuthenticationResponse | Should -BeFalse } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_EnableStoreEmptyAuthenticationResponse_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_EnableStoreEmptyAuthenticationResponse_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.StoreEmptyAuthenticationResponse | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.StoreEmptyAuthenticationResponse | Should -BeTrue } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/Classes/DnsServerDsSetting.Integration.Tests.ps1 b/tests/Integration/Classes/DnsServerDsSetting.Integration.Tests.ps1 index 48db02d2..36f66c07 100644 --- a/tests/Integration/Classes/DnsServerDsSetting.Integration.Tests.ps1 +++ b/tests/Integration/Classes/DnsServerDsSetting.Integration.Tests.ps1 @@ -1,367 +1,435 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DnsServerDsSetting' +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsServerDsSetting' + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsServerDsSetting' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' +} + +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DirectoryPartitionAutoEnlistInterval_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_DirectoryPartitionAutoEnlistInterval_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.DirectoryPartitionAutoEnlistInterval | Should -Be '1.00:00:00' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.DirectoryPartitionAutoEnlistInterval | Should -Be '1.00:00:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_LazyUpdateInterval_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_LazyUpdateInterval_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.LazyUpdateInterval | Should -Be 3 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.LazyUpdateInterval | Should -Be 3 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_MinimumBackgroundLoadThreads_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_MinimumBackgroundLoadThreads_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.MinimumBackgroundLoadThreads | Should -Be 1 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.MinimumBackgroundLoadThreads | Should -Be 1 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_PollingInterval_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_PollingInterval_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.PollingInterval | Should -Be 180 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.PollingInterval | Should -Be 180 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_RemoteReplicationDelay_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoteReplicationDelay_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.RemoteReplicationDelay | Should -Be 30 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.RemoteReplicationDelay | Should -Be 30 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_TombstoneInterval_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_TombstoneInterval_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.TombstoneInterval | Should -Be '14.00:00:00' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.TombstoneInterval | Should -Be '14.00:00:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_All_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_All_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.DirectoryPartitionAutoEnlistInterval | Should -Be '1.00:00:00' - $resourceCurrentState.LazyUpdateInterval | Should -Be 3 - $resourceCurrentState.MinimumBackgroundLoadThreads | Should -Be 1 - $resourceCurrentState.PollingInterval | Should -Be 180 - $resourceCurrentState.RemoteReplicationDelay | Should -Be 30 - $resourceCurrentState.TombstoneInterval | Should -Be '14.00:00:00' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.DirectoryPartitionAutoEnlistInterval | Should -Be '1.00:00:00' + $resourceCurrentState.LazyUpdateInterval | Should -Be 3 + $resourceCurrentState.MinimumBackgroundLoadThreads | Should -Be 1 + $resourceCurrentState.PollingInterval | Should -Be 180 + $resourceCurrentState.RemoteReplicationDelay | Should -Be 30 + $resourceCurrentState.TombstoneInterval | Should -Be '14.00:00:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/Classes/DnsServerEDns.Integration.Tests.ps1 b/tests/Integration/Classes/DnsServerEDns.Integration.Tests.ps1 index fbe8bc36..2eb628a9 100644 --- a/tests/Integration/Classes/DnsServerEDns.Integration.Tests.ps1 +++ b/tests/Integration/Classes/DnsServerEDns.Integration.Tests.ps1 @@ -1,268 +1,324 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DnsServerEDns' +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsServerEDns' + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsServerEDns' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' +} + +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DisableProbes_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_DisableProbes_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } - - & $configurationName @configurationParameters - - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } - - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + AfterAll { + Wait-ForIdleLcm -Clear + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.EnableProbes | Should -BeFalse - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw } - Wait-ForIdleLcm -Clear + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } - $configurationName = "$($script:dscResourceName)_EnableProbes_Config" + $resourceCurrentState.EnableProbes | Should -BeFalse + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_EnableProbes_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.EnableProbes | Should -BeTrue - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw } - Wait-ForIdleLcm -Clear + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } - $configurationName = "$($script:dscResourceName)_DisableReception_Config" + $resourceCurrentState.EnableProbes | Should -BeTrue + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DisableReception_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.EnableReception | Should -BeFalse - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw } - Wait-ForIdleLcm -Clear + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } - $configurationName = "$($script:dscResourceName)_EnableReception_Config" + $resourceCurrentState.EnableReception | Should -BeFalse + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_EnableReception_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.EnableReception | Should -BeTrue - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw } - Wait-ForIdleLcm -Clear + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } - $configurationName = "$($script:dscResourceName)_SetCacheTimeout_Config" + $resourceCurrentState.EnableReception | Should -BeTrue + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetCacheTimeout_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.CacheTimeout | Should -Be '00:30:00' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + + $resourceCurrentState.CacheTimeout | Should -Be '00:30:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/Classes/DnsServerRecursion.Integration.Tests.ps1 b/tests/Integration/Classes/DnsServerRecursion.Integration.Tests.ps1 index d4c80fe4..d8d4e402 100644 --- a/tests/Integration/Classes/DnsServerRecursion.Integration.Tests.ps1 +++ b/tests/Integration/Classes/DnsServerRecursion.Integration.Tests.ps1 @@ -1,268 +1,324 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DnsServerRecursion' +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsServerRecursion' + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsServerRecursion' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' +} + +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DisableRecursion_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_DisableRecursion_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } - - & $configurationName @configurationParameters - - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } - - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + AfterAll { + Wait-ForIdleLcm -Clear + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.Enable | Should -BeFalse - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw } - Wait-ForIdleLcm -Clear + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } - $configurationName = "$($script:dscResourceName)_EnableRecursion_Config" + $resourceCurrentState.Enable | Should -BeFalse + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_EnableRecursion_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.Enable | Should -BeTrue - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw } - Wait-ForIdleLcm -Clear + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } - $configurationName = "$($script:dscResourceName)_SetAdditionalTimeout_Config" + $resourceCurrentState.Enable | Should -BeTrue + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetAdditionalTimeout_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.AdditionalTimeout | Should -Be 5 - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw } - Wait-ForIdleLcm -Clear + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } - $configurationName = "$($script:dscResourceName)_SetRetryInterval_Config" + $resourceCurrentState.AdditionalTimeout | Should -Be 5 + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetRetryInterval_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.RetryInterval | Should -Be 4 - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw } - Wait-ForIdleLcm -Clear + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } - $configurationName = "$($script:dscResourceName)_SetTimeout_Config" + $resourceCurrentState.RetryInterval | Should -Be 4 + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetTimeout_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.Timeout | Should -Be 9 - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + + $resourceCurrentState.Timeout | Should -Be 9 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/Classes/DnsServerScavenging.Integration.Tests.ps1 b/tests/Integration/Classes/DnsServerScavenging.Integration.Tests.ps1 index 5638f91f..84f7c011 100644 --- a/tests/Integration/Classes/DnsServerScavenging.Integration.Tests.ps1 +++ b/tests/Integration/Classes/DnsServerScavenging.Integration.Tests.ps1 @@ -1,230 +1,280 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DnsServerScavenging' +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsServerScavenging' + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false +} -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DnsServerScavenging' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Class' ` + -TestType 'Integration' } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile + $resourceId = "[$($script:dscResourceName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_EnableScavenging_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_EnableScavenging_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.ScavengingState | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.ScavengingState | Should -BeTrue } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_SetAllIntervals_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetAllIntervals_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.ScavengingState | Should -BeTrue - $resourceCurrentState.ScavengingInterval | Should -Be '30.00:00:00' - $resourceCurrentState.RefreshInterval | Should -Be '30.00:00:00' - $resourceCurrentState.NoRefreshInterval | Should -Be '30.00:00:00' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.ScavengingState | Should -BeTrue + $resourceCurrentState.ScavengingInterval | Should -Be '30.00:00:00' + $resourceCurrentState.RefreshInterval | Should -Be '30.00:00:00' + $resourceCurrentState.NoRefreshInterval | Should -Be '30.00:00:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_SetOneInterval_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetOneInterval_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.ScavengingState | Should -BeTrue - $resourceCurrentState.ScavengingInterval | Should -Be '6.23:00:00' - $resourceCurrentState.RefreshInterval | Should -Be '30.00:00:00' - $resourceCurrentState.NoRefreshInterval | Should -Be '30.00:00:00' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.ScavengingState | Should -BeTrue + $resourceCurrentState.ScavengingInterval | Should -Be '6.23:00:00' + $resourceCurrentState.RefreshInterval | Should -Be '30.00:00:00' + $resourceCurrentState.NoRefreshInterval | Should -Be '30.00:00:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_DisableScavenging_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DisableScavenging_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.ScavengingState | Should -BeFalse - $resourceCurrentState.ScavengingInterval | Should -Be '6.23:00:00' - $resourceCurrentState.RefreshInterval | Should -Be '30.00:00:00' - $resourceCurrentState.NoRefreshInterval | Should -Be '30.00:00:00' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.ScavengingState | Should -BeFalse + $resourceCurrentState.ScavengingInterval | Should -Be '6.23:00:00' + $resourceCurrentState.RefreshInterval | Should -Be '30.00:00:00' + $resourceCurrentState.NoRefreshInterval | Should -Be '30.00:00:00' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/DSC_DnsServerClientSubnet.Integration.Tests.ps1 b/tests/Integration/DSC_DnsServerClientSubnet.Integration.Tests.ps1 index d197c391..6d2408f3 100644 --- a/tests/Integration/DSC_DnsServerClientSubnet.Integration.Tests.ps1 +++ b/tests/Integration/DSC_DnsServerClientSubnet.Integration.Tests.ps1 @@ -1,423 +1,494 @@ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerClientSubnet' -$script:dscResourceFriendlyName = 'DnsServerClientSubnet' + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerClientSubnet' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerClientSubnet' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Integration' } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} -try -{ - #region Integration Tests - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:DSCResourceName).config.ps1" - . $configFile +Describe "$($script:DSCResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:DSCResourceName).config.ps1" + . $configFile - Describe "$($script:DSCResourceName)_Integration" { + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } + + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_AddIPv4Subnet_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_AddIPv4Subnet_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - # The variable $ConfigurationData was dot-sourced above. - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } - $resourceCurrentState.Name | Should -Be 'ClientSubnetA' - $resourceCurrentState.IPv4Subnet | Should -Be '10.1.1.0/24' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + $resourceCurrentState.Name | Should -Be 'ClientSubnetA' + $resourceCurrentState.IPv4Subnet | Should -Be '10.1.1.0/24' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -BeTrue + } + } - $configurationName = "$($script:dscResourceName)_ChangeIPv4Subnet_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ChangeIPv4Subnet_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - # The variable $ConfigurationData was dot-sourced above. - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } - $resourceCurrentState.Name | Should -Be 'ClientSubnetA' - $resourceCurrentState.IPv4Subnet | Should -Be '10.1.2.0/24' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + $resourceCurrentState.Name | Should -Be 'ClientSubnetA' + $resourceCurrentState.IPv4Subnet | Should -Be '10.1.2.0/24' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -BeTrue + } + } - $configurationName = "$($script:dscResourceName)_ArrayIPv4Subnet_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ArrayIPv4Subnet_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - # The variable $ConfigurationData was dot-sourced above. - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } - $resourceCurrentState.Name | Should -Be 'ClientSubnetA' - $resourceCurrentState.IPv4Subnet | Should -Contain '10.1.1.0/24' - $resourceCurrentState.IPv4Subnet | Should -Contain '10.1.2.0/24' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + $resourceCurrentState.Name | Should -Be 'ClientSubnetA' + $resourceCurrentState.IPv4Subnet | Should -Contain '10.1.1.0/24' + $resourceCurrentState.IPv4Subnet | Should -Contain '10.1.2.0/24' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -BeTrue + } + } - $configurationName = "$($script:dscResourceName)_RemoveIPv4Subnet_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoveIPv4Subnet_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - # The variable $ConfigurationData was dot-sourced above. - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } - $resourceCurrentState.Name | Should -Be 'ClientSubnetA' - $resourceCurrentState.Ensure | Should -Be 'Absent' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + $resourceCurrentState.Name | Should -Be 'ClientSubnetA' + $resourceCurrentState.Ensure | Should -Be 'Absent' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -BeTrue + } + } - $configurationName = "$($script:dscResourceName)_AddIPv6Subnet_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_AddIPv6Subnet_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - # The variable $ConfigurationData was dot-sourced above. - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } - $resourceCurrentState.Name | Should -Be 'ClientSubnetA' - $resourceCurrentState.IPv6Subnet | Should -Be 'db8::1/28' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + $resourceCurrentState.Name | Should -Be 'ClientSubnetA' + $resourceCurrentState.IPv6Subnet | Should -Be 'db8::1/28' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -BeTrue + } + } - $configurationName = "$($script:dscResourceName)_ChangeIPv6Subnet_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ChangeIPv6Subnet_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - # The variable $ConfigurationData was dot-sourced above. - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } - $resourceCurrentState.Name | Should -Be 'ClientSubnetA' - $resourceCurrentState.IPv6Subnet | Should -Be '2001:db8::/32' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + $resourceCurrentState.Name | Should -Be 'ClientSubnetA' + $resourceCurrentState.IPv6Subnet | Should -Be '2001:db8::/32' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -BeTrue + } + } - $configurationName = "$($script:dscResourceName)_ArrayIPv6Subnet_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ArrayIPv6Subnet_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - # The variable $ConfigurationData was dot-sourced above. - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } - $resourceCurrentState.Name | Should -Be 'ClientSubnetA' - $resourceCurrentState.IPv6Subnet | Should -Contain '2001:db8::/32' - $resourceCurrentState.IPv6Subnet | Should -Contain 'db8::1/28' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + $resourceCurrentState.Name | Should -Be 'ClientSubnetA' + $resourceCurrentState.IPv6Subnet | Should -Contain '2001:db8::/32' + $resourceCurrentState.IPv6Subnet | Should -Contain 'db8::1/28' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -BeTrue + } + } - $configurationName = "$($script:dscResourceName)_RemoveIPv6Subnet_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoveIPv6Subnet_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - # The variable $ConfigurationData was dot-sourced above. - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } - $resourceCurrentState.Ensure | Should -Be 'Absent' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + $resourceCurrentState.Ensure | Should -Be 'Absent' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -BeTrue + } } - #endregion - -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment } diff --git a/tests/Integration/DSC_DnsServerConditionalForwarder.Integration.Tests.ps1 b/tests/Integration/DSC_DnsServerConditionalForwarder.Integration.Tests.ps1 index 05b84411..653ca297 100644 --- a/tests/Integration/DSC_DnsServerConditionalForwarder.Integration.Tests.ps1 +++ b/tests/Integration/DSC_DnsServerConditionalForwarder.Integration.Tests.ps1 @@ -1,445 +1,508 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsServerConditionalForwarder' -$script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" - -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' -} -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' -} +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' - -#region INITIALIZATION -# Add zones for the integration tests to fix -$conditionalForwarderZones = @( - @{ - Name = 'nochange.none' - MasterServers = [IPAddress[]] @( - '192.168.1.1', - '192.168.1.2' - ) - }, - @{ - Name = 'fixincorrectmasters.none' - MasterServers = [IPAddress[]] @( - '192.168.1.3', - '192.168.1.4' - ) - }, - @{ - Name = 'removeexisting.none' - MasterServers = [IPAddress[]] @( - '192.168.1.1', - '192.168.1.2' - ) + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } -) -foreach ($zone in $conditionalForwarderZones) -{ - Add-DnsServerConditionalForwarderZone @zone + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerConditionalForwarder' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -# Primary zones which will either be fixed or ignored. -$primaryZones = @( - @{ - Name = 'replaceprimary.none' - ZoneFile = 'replaceprimary.none.dns' - }, - @{ - Name = 'ignoreprimary.none' - ZoneFile = 'ignoreprimary.none.dns' +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerConditionalForwarder' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Integration' + + # Add zones for the integration tests to fix + $conditionalForwarderZones = @( + @{ + Name = 'nochange.none' + MasterServers = [IPAddress[]] @( + '192.168.1.1', + '192.168.1.2' + ) + }, + @{ + Name = 'fixincorrectmasters.none' + MasterServers = [IPAddress[]] @( + '192.168.1.3', + '192.168.1.4' + ) + }, + @{ + Name = 'removeexisting.none' + MasterServers = [IPAddress[]] @( + '192.168.1.1', + '192.168.1.2' + ) + } + ) + + foreach ($zone in $conditionalForwarderZones) + { + Add-DnsServerConditionalForwarderZone @zone } -) -foreach ($zone in $primaryZones) -{ - Add-DnsServerPrimaryZone @zone + # Primary zones which will either be fixed or ignored. + $primaryZones = @( + @{ + Name = 'replaceprimary.none' + ZoneFile = 'replaceprimary.none.dns' + }, + @{ + Name = 'ignoreprimary.none' + ZoneFile = 'ignoreprimary.none.dns' + } + ) + + foreach ($zone in $primaryZones) + { + Add-DnsServerPrimaryZone @zone + } } -#endregion -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configurationFile +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment - Describe "$($script:dscResourceName)_Integration" { - BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" - } + Get-DnsServerZone | + Where-Object IsReverseLookupZone -eq $false | + Remove-DnsServerZone -Confirm:$false -Force +} - $configurationName = "$($script:dscResourceName)_NoChange_Config" +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_NoChange_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $ZoneData = $ConfigurationData.NonNodeData.$configurationName + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure - $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName - $resourceCurrentState.MasterServers | Should -Be $ConfigurationData.NonNodeData.MasterServers - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - } - Wait-ForIdleLcm -Clear + $ZoneData = $ConfigurationData.NonNodeData.$configurationName - $configurationName = "$($script:dscResourceName)_FixIncorrectMasters_Config" + $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure + $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName + $resourceCurrentState.MasterServers | Should -Be $ConfigurationData.NonNodeData.MasterServers + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_FixIncorrectMasters_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $ZoneData = $ConfigurationData.NonNodeData.$configurationName + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure - $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName - $resourceCurrentState.MasterServers | Should -Be $ConfigurationData.NonNodeData.MasterServers - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - } - Wait-ForIdleLcm -Clear + $ZoneData = $ConfigurationData.NonNodeData.$configurationName - $configurationName = "$($script:dscResourceName)_ReplacePrimary_Config" + $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure + $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName + $resourceCurrentState.MasterServers | Should -Be $ConfigurationData.NonNodeData.MasterServers + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ReplacePrimary_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $ZoneData = $ConfigurationData.NonNodeData.$configurationName + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure - $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName - $resourceCurrentState.MasterServers | Should -Be $ConfigurationData.NonNodeData.MasterServers - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - } - Wait-ForIdleLcm -Clear + $ZoneData = $ConfigurationData.NonNodeData.$configurationName - $configurationName = "$($script:dscResourceName)_CreateNew_Config" + $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure + $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName + $resourceCurrentState.MasterServers | Should -Be $ConfigurationData.NonNodeData.MasterServers + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_CreateNew_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $ZoneData = $ConfigurationData.NonNodeData.$configurationName + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure - $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName - $resourceCurrentState.MasterServers | Should -Be $ConfigurationData.NonNodeData.MasterServers - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - } - Wait-ForIdleLcm -Clear + $ZoneData = $ConfigurationData.NonNodeData.$configurationName - $configurationName = "$($script:dscResourceName)_RemoveExisting_Config" + $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure + $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName + $resourceCurrentState.MasterServers | Should -Be $ConfigurationData.NonNodeData.MasterServers + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoveExisting_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $ZoneData = $ConfigurationData.NonNodeData.$configurationName + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure - $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - } - Wait-ForIdleLcm -Clear + $ZoneData = $ConfigurationData.NonNodeData.$configurationName - $configurationName = "$($script:dscResourceName)_IgnorePrimary_Config" + $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure + $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_IgnorePrimary_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $ZoneData = $ConfigurationData.NonNodeData.$configurationName + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure - $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - } - Wait-ForIdleLcm -Clear + $ZoneData = $ConfigurationData.NonNodeData.$configurationName - $configurationName = "$($script:dscResourceName)_DoNothing_Config" + $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure + $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_DoNothing_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $ZoneData = $ConfigurationData.NonNodeData.$configurationName + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure - $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - } - Wait-ForIdleLcm -Clear - } - #endregion + $ZoneData = $ConfigurationData.NonNodeData.$configurationName -} -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment + $resourceCurrentState.Ensure | Should -Be $ZoneData.Ensure + $resourceCurrentState.Name | Should -Be $ZoneData.ZoneName + } - Get-DnsServerZone | - Where-Object IsReverseLookupZone -eq $false | - Remove-DnsServerZone -Confirm:$false -Force + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } } diff --git a/tests/Integration/DSC_DnsServerDiagnostics.Integration.Tests.ps1 b/tests/Integration/DSC_DnsServerDiagnostics.Integration.Tests.ps1 index 2263f8fa..5862e79f 100644 --- a/tests/Integration/DSC_DnsServerDiagnostics.Integration.Tests.ps1 +++ b/tests/Integration/DSC_DnsServerDiagnostics.Integration.Tests.ps1 @@ -1,109 +1,142 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsServerDiagnostics' -$script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerDiagnostics' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerDiagnostics' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Integration' } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile - Describe "$($script:dscResourceName)_Integration" { + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } + + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetDiagnostics_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_SetDiagnostics_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } - - & $configurationName @configurationParameters - - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } - - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + AfterAll { + Wait-ForIdleLcm -Clear + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.DnsServer | Should -Be $ConfigurationData.AllNodes.DnsServer - $resourceCurrentState.Answers | Should -Be $ConfigurationData.AllNodes.Answers - $resourceCurrentState.EnableLogFileRollover | Should -Be $ConfigurationData.AllNodes.EnableLogFileRollover - $resourceCurrentState.EnableLoggingForLocalLookupEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForLocalLookupEvent - $resourceCurrentState.EnableLoggingForPluginDllEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForPluginDllEvent - $resourceCurrentState.EnableLoggingForRecursiveLookupEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForRecursiveLookupEvent - $resourceCurrentState.EnableLoggingForRemoteServerEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForRemoteServerEvent - $resourceCurrentState.EnableLoggingForServerStartStopEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForServerStartStopEvent - $resourceCurrentState.EnableLoggingForTombstoneEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForTombstoneEvent - $resourceCurrentState.EnableLoggingForZoneDataWriteEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForZoneDataWriteEvent - $resourceCurrentState.EnableLoggingForZoneLoadingEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForZoneLoadingEvent - $resourceCurrentState.EnableLoggingToFile | Should -Be $ConfigurationData.AllNodes.EnableLoggingToFile - $resourceCurrentState.EventLogLevel | Should -Be $ConfigurationData.AllNodes.EventLogLevel - $resourceCurrentState.FilterIPAddressList | Should -Be $ConfigurationData.AllNodes.FilterIPAddressList - $resourceCurrentState.FullPackets | Should -Be $ConfigurationData.AllNodes.FullPackets - $resourceCurrentState.LogFilePath | Should -Be $ConfigurationData.AllNodes.LogFilePath - $resourceCurrentState.MaxMBFileSize | Should -Be $ConfigurationData.AllNodes.MaxMBFileSize - $resourceCurrentState.Notifications | Should -Be $ConfigurationData.AllNodes.Notifications - $resourceCurrentState.Queries | Should -Be $ConfigurationData.AllNodes.Queries - $resourceCurrentState.QuestionTransactions | Should -Be $ConfigurationData.AllNodes.QuestionTransactions - $resourceCurrentState.ReceivePackets | Should -Be $ConfigurationData.AllNodes.ReceivePackets - $resourceCurrentState.SaveLogsToPersistentStorage | Should -Be $ConfigurationData.AllNodes.SaveLogsToPersistentStorage - $resourceCurrentState.SendPackets | Should -Be $ConfigurationData.AllNodes.SendPackets - $resourceCurrentState.TcpPackets | Should -Be $ConfigurationData.AllNodes.TcpPackets - $resourceCurrentState.UdpPackets | Should -Be $ConfigurationData.AllNodes.UdpPackets - $resourceCurrentState.UnmatchedResponse | Should -Be $ConfigurationData.AllNodes.UnmatchedResponse - $resourceCurrentState.Update | Should -Be $ConfigurationData.AllNodes.Update - $resourceCurrentState.UseSystemEventLog | Should -Be $ConfigurationData.AllNodes.UseSystemEventLog - $resourceCurrentState.WriteThrough | Should -Be $ConfigurationData.AllNodes.WriteThrough - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + + $resourceCurrentState.DnsServer | Should -Be $ConfigurationData.AllNodes.DnsServer + $resourceCurrentState.Answers | Should -Be $ConfigurationData.AllNodes.Answers + $resourceCurrentState.EnableLogFileRollover | Should -Be $ConfigurationData.AllNodes.EnableLogFileRollover + $resourceCurrentState.EnableLoggingForLocalLookupEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForLocalLookupEvent + $resourceCurrentState.EnableLoggingForPluginDllEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForPluginDllEvent + $resourceCurrentState.EnableLoggingForRecursiveLookupEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForRecursiveLookupEvent + $resourceCurrentState.EnableLoggingForRemoteServerEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForRemoteServerEvent + $resourceCurrentState.EnableLoggingForServerStartStopEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForServerStartStopEvent + $resourceCurrentState.EnableLoggingForTombstoneEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForTombstoneEvent + $resourceCurrentState.EnableLoggingForZoneDataWriteEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForZoneDataWriteEvent + $resourceCurrentState.EnableLoggingForZoneLoadingEvent | Should -Be $ConfigurationData.AllNodes.EnableLoggingForZoneLoadingEvent + $resourceCurrentState.EnableLoggingToFile | Should -Be $ConfigurationData.AllNodes.EnableLoggingToFile + $resourceCurrentState.EventLogLevel | Should -Be $ConfigurationData.AllNodes.EventLogLevel + $resourceCurrentState.FilterIPAddressList | Should -Be $ConfigurationData.AllNodes.FilterIPAddressList + $resourceCurrentState.FullPackets | Should -Be $ConfigurationData.AllNodes.FullPackets + $resourceCurrentState.LogFilePath | Should -Be $ConfigurationData.AllNodes.LogFilePath + $resourceCurrentState.MaxMBFileSize | Should -Be $ConfigurationData.AllNodes.MaxMBFileSize + $resourceCurrentState.Notifications | Should -Be $ConfigurationData.AllNodes.Notifications + $resourceCurrentState.Queries | Should -Be $ConfigurationData.AllNodes.Queries + $resourceCurrentState.QuestionTransactions | Should -Be $ConfigurationData.AllNodes.QuestionTransactions + $resourceCurrentState.ReceivePackets | Should -Be $ConfigurationData.AllNodes.ReceivePackets + $resourceCurrentState.SaveLogsToPersistentStorage | Should -Be $ConfigurationData.AllNodes.SaveLogsToPersistentStorage + $resourceCurrentState.SendPackets | Should -Be $ConfigurationData.AllNodes.SendPackets + $resourceCurrentState.TcpPackets | Should -Be $ConfigurationData.AllNodes.TcpPackets + $resourceCurrentState.UdpPackets | Should -Be $ConfigurationData.AllNodes.UdpPackets + $resourceCurrentState.UnmatchedResponse | Should -Be $ConfigurationData.AllNodes.UnmatchedResponse + $resourceCurrentState.Update | Should -Be $ConfigurationData.AllNodes.Update + $resourceCurrentState.UseSystemEventLog | Should -Be $ConfigurationData.AllNodes.UseSystemEventLog + $resourceCurrentState.WriteThrough | Should -Be $ConfigurationData.AllNodes.WriteThrough } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/DSC_DnsServerForwarder.Integration.Tests.ps1 b/tests/Integration/DSC_DnsServerForwarder.Integration.Tests.ps1 index 5ad872ea..def1afe5 100644 --- a/tests/Integration/DSC_DnsServerForwarder.Integration.Tests.ps1 +++ b/tests/Integration/DSC_DnsServerForwarder.Integration.Tests.ps1 @@ -1,377 +1,446 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsServerForwarder' -$script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerForwarder' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerForwarder' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Integration' +} + +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetForwarderDoNotUseRootHints_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_SetForwarderDoNotUseRootHints_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' - $resourceCurrentState.IPAddresses | Should -Be $ConfigurationData.AllNodes.ForwarderIpAddress - $resourceCurrentState.UseRootHint | Should -BeFalse + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' + $resourceCurrentState.IPAddresses | Should -Be $ConfigurationData.AllNodes.ForwarderIpAddress + $resourceCurrentState.UseRootHint | Should -BeFalse } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_SetForwarderUseRootHints_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetForwarderUseRootHints_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' - $resourceCurrentState.IPAddresses | Should -Be $ConfigurationData.AllNodes.ForwarderIpAddress - $resourceCurrentState.UseRootHint | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' + $resourceCurrentState.IPAddresses | Should -Be $ConfigurationData.AllNodes.ForwarderIpAddress + $resourceCurrentState.UseRootHint | Should -BeTrue } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_RemoveForwarders_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoveForwarders_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' - $resourceCurrentState.IPAddresses | Should -BeNullOrEmpty - $resourceCurrentState.UseRootHint | Should -BeFalse + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' + $resourceCurrentState.IPAddresses | Should -BeNullOrEmpty + $resourceCurrentState.UseRootHint | Should -BeFalse } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_SetUseRootHint_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetUseRootHint_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' - $resourceCurrentState.IPAddresses | Should -BeNullOrEmpty - $resourceCurrentState.UseRootHint | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' + $resourceCurrentState.IPAddresses | Should -BeNullOrEmpty + $resourceCurrentState.UseRootHint | Should -BeTrue } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_SetEnableReordering_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetEnableReordering_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' - $resourceCurrentState.IPAddresses | Should -BeNullOrEmpty - $resourceCurrentState.EnableReordering | Should -BeTrue + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' + $resourceCurrentState.IPAddresses | Should -BeNullOrEmpty + $resourceCurrentState.EnableReordering | Should -BeTrue } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_SetDisableReordering_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetDisableReordering_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' - $resourceCurrentState.IPAddresses | Should -BeNullOrEmpty - $resourceCurrentState.EnableReordering | Should -BeFalse + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' + $resourceCurrentState.IPAddresses | Should -BeNullOrEmpty + $resourceCurrentState.EnableReordering | Should -BeFalse } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_SetTimeout_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetTimeout_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' - $resourceCurrentState.IPAddresses | Should -BeNullOrEmpty - $resourceCurrentState.Timeout | Should -Be 10 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' + $resourceCurrentState.IPAddresses | Should -BeNullOrEmpty + $resourceCurrentState.Timeout | Should -Be 10 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/DSC_DnsServerPrimaryZone.Integration.Tests.ps1 b/tests/Integration/DSC_DnsServerPrimaryZone.Integration.Tests.ps1 index f42eb7ba..880b0624 100644 --- a/tests/Integration/DSC_DnsServerPrimaryZone.Integration.Tests.ps1 +++ b/tests/Integration/DSC_DnsServerPrimaryZone.Integration.Tests.ps1 @@ -1,434 +1,501 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsServerPrimaryZone' -$script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerPrimaryZone' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerPrimaryZone' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Integration' +} + +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_AddForwardZoneUsingDefaultValues_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_AddForwardZoneUsingDefaultValues_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } - - & $configurationName @configurationParameters + AfterAll { + Wait-ForIdleLcm -Clear + } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be 'Present' - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName - $resourceCurrentState.ZoneFile | Should -Be ('{0}.dns' -f $ConfigurationData.AllNodes.ForwardZoneName) - $resourceCurrentState.DynamicUpdate | Should -Be 'None' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName + $resourceCurrentState.ZoneFile | Should -Be ('{0}.dns' -f $ConfigurationData.AllNodes.ForwardZoneName) + $resourceCurrentState.DynamicUpdate | Should -Be 'None' } - Wait-ForIdleLcm -Clear - - $configurationName = "$($script:dscResourceName)_RemoveForwardZone_Config" + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoveForwardZone_Config" + ) { + BeforeAll { + $configurationName = $_ + } - & $configurationName @configurationParameters + AfterAll { + Wait-ForIdleLcm -Clear + } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be 'Absent' - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName - $resourceCurrentState.ZoneFile | Should -BeNullOrEmpty - $resourceCurrentState.DynamicUpdate | Should -BeNullOrEmpty + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Ensure | Should -Be 'Absent' + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName + $resourceCurrentState.ZoneFile | Should -BeNullOrEmpty + $resourceCurrentState.DynamicUpdate | Should -BeNullOrEmpty } - Wait-ForIdleLcm -Clear - - $configurationName = "$($script:dscResourceName)_AddForwardZone_Config" + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_AddForwardZone_Config" + ) { + BeforeAll { + $configurationName = $_ + } - & $configurationName @configurationParameters + AfterAll { + Wait-ForIdleLcm -Clear + } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be 'Present' - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName - $resourceCurrentState.ZoneFile | Should -Be $ConfigurationData.AllNodes.ForwardZoneFile - $resourceCurrentState.DynamicUpdate | Should -Be $ConfigurationData.AllNodes.ForwardZoneDynamicUpdate + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName + $resourceCurrentState.ZoneFile | Should -Be $ConfigurationData.AllNodes.ForwardZoneFile + $resourceCurrentState.DynamicUpdate | Should -Be $ConfigurationData.AllNodes.ForwardZoneDynamicUpdate } - Wait-ForIdleLcm -Clear - - $configurationName = "$($script:dscResourceName)_RemoveForwardZone_Config" + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoveForwardZone_Config" + ) { + BeforeAll { + $configurationName = $_ + } - & $configurationName @configurationParameters + AfterAll { + Wait-ForIdleLcm -Clear + } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be 'Absent' - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName - $resourceCurrentState.ZoneFile | Should -BeNullOrEmpty - $resourceCurrentState.DynamicUpdate | Should -BeNullOrEmpty + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Ensure | Should -Be 'Absent' + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName + $resourceCurrentState.ZoneFile | Should -BeNullOrEmpty + $resourceCurrentState.DynamicUpdate | Should -BeNullOrEmpty } - Wait-ForIdleLcm -Clear - - $configurationName = "$($script:dscResourceName)_AddClassfulReverseZone_Config" + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_AddClassfulReverseZone_Config" + ) { + BeforeAll { + $configurationName = $_ + } - & $configurationName @configurationParameters + AfterAll { + Wait-ForIdleLcm -Clear + } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be 'Present' - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ClassfulReverseZoneName - $resourceCurrentState.ZoneFile | Should -Be $ConfigurationData.AllNodes.ClassfulReverseZoneFile - $resourceCurrentState.DynamicUpdate | Should -Be $ConfigurationData.AllNodes.ClassfulReverseZoneDynamicUpdate + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ClassfulReverseZoneName + $resourceCurrentState.ZoneFile | Should -Be $ConfigurationData.AllNodes.ClassfulReverseZoneFile + $resourceCurrentState.DynamicUpdate | Should -Be $ConfigurationData.AllNodes.ClassfulReverseZoneDynamicUpdate } - Wait-ForIdleLcm -Clear - - $configurationName = "$($script:dscResourceName)_RemoveClassfulReverseZone_Config" + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoveClassfulReverseZone_Config" + ) { + BeforeAll { + $configurationName = $_ + } - & $configurationName @configurationParameters + AfterAll { + Wait-ForIdleLcm -Clear + } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be 'Absent' - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ClassfulReverseZoneName - $resourceCurrentState.ZoneFile | Should -BeNullOrEmpty - $resourceCurrentState.DynamicUpdate | Should -BeNullOrEmpty + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Ensure | Should -Be 'Absent' + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ClassfulReverseZoneName + $resourceCurrentState.ZoneFile | Should -BeNullOrEmpty + $resourceCurrentState.DynamicUpdate | Should -BeNullOrEmpty } - Wait-ForIdleLcm -Clear - - $configurationName = "$($script:dscResourceName)_AddClasslessReverseZone_Config" + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_AddClasslessReverseZone_Config" + ) { + BeforeAll { + $configurationName = $_ + } - & $configurationName @configurationParameters + AfterAll { + Wait-ForIdleLcm -Clear + } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be 'Present' - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ClasslessReverseZoneName - $resourceCurrentState.ZoneFile | Should -Be ('{0}.dns' -f $ConfigurationData.AllNodes.ClasslessReverseZoneName) - $resourceCurrentState.DynamicUpdate | Should -Be 'None' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ClasslessReverseZoneName + $resourceCurrentState.ZoneFile | Should -Be ('{0}.dns' -f $ConfigurationData.AllNodes.ClasslessReverseZoneName) + $resourceCurrentState.DynamicUpdate | Should -Be 'None' } - Wait-ForIdleLcm -Clear - - $configurationName = "$($script:dscResourceName)_RemoveClasslessReverseZone_Config" + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoveClasslessReverseZone_Config" + ) { + BeforeAll { + $configurationName = $_ + } - & $configurationName @configurationParameters + AfterAll { + Wait-ForIdleLcm -Clear + } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be 'Absent' - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ClasslessReverseZoneName - $resourceCurrentState.ZoneFile | Should -BeNullOrEmpty - $resourceCurrentState.DynamicUpdate | Should -BeNullOrEmpty + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Ensure | Should -Be 'Absent' + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ClasslessReverseZoneName + $resourceCurrentState.ZoneFile | Should -BeNullOrEmpty + $resourceCurrentState.DynamicUpdate | Should -BeNullOrEmpty } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/DSC_DnsServerRootHint.Integration.Tests.ps1 b/tests/Integration/DSC_DnsServerRootHint.Integration.Tests.ps1 index 4ff8e0db..1595cdbc 100644 --- a/tests/Integration/DSC_DnsServerRootHint.Integration.Tests.ps1 +++ b/tests/Integration/DSC_DnsServerRootHint.Integration.Tests.ps1 @@ -1,152 +1,191 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsServerRootHint' -$script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerRootHint' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerRootHint' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Integration' } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile - Describe "$($script:dscResourceName)_Integration" { + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } + + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoveAllRootHints_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_RemoveAllRootHints_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } - - & $configurationName @configurationParameters - - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } - - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + AfterAll { + Wait-ForIdleLcm -Clear + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' - $resourceCurrentState.NameServer | Should -BeNullOrEmpty - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw } - Wait-ForIdleLcm -Clear + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId + } - $configurationName = "$($script:dscResourceName)_SetRootHints_Config" + $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' + $resourceCurrentState.NameServer | Should -BeNullOrEmpty + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - & $configurationName @configurationParameters + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetRootHints_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $nameServerHashtable = @{} + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - foreach ($nameServer in $resourceCurrentState.NameServer) - { - $nameServerHashtable.Add($nameServer.Key, $nameServer.Value) - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $nameServerHashtable.Count | Should -Be $ConfigurationData.AllNodes.NameServer.Count - - $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' - - $nameServerHashtable['H.ROOT-SERVERS.NET.'] | Should -Be '198.97.190.53' - $nameServerHashtable['E.ROOT-SERVERS.NET.'] | Should -Be '192.203.230.10' - $nameServerHashtable['M.ROOT-SERVERS.NET.'] | Should -Be '202.12.27.33' - $nameServerHashtable['A.ROOT-SERVERS.NET.'] | Should -Be '198.41.0.4' - $nameServerHashtable['D.ROOT-SERVERS.NET.'] | Should -Be '199.7.91.13' - $nameServerHashtable['F.ROOT-SERVERS.NET.'] | Should -Be '192.5.5.241' - $nameServerHashtable['B.ROOT-SERVERS.NET.'] | Should -Be '192.228.79.201' - $nameServerHashtable['G.ROOT-SERVERS.NET.'] | Should -Be '192.112.36.4' - $nameServerHashtable['C.ROOT-SERVERS.NET.'] | Should -Be '192.33.4.12' - $nameServerHashtable['K.ROOT-SERVERS.NET.'] | Should -Be '193.0.14.129' - $nameServerHashtable['I.ROOT-SERVERS.NET.'] | Should -Be '192.36.148.17' - $nameServerHashtable['J.ROOT-SERVERS.NET.'] | Should -Be '192.58.128.30' - $nameServerHashtable['L.ROOT-SERVERS.NET.'] | Should -Be '199.7.83.42' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + $nameServerHashtable = @{} + + foreach ($nameServer in $resourceCurrentState.NameServer) + { + $nameServerHashtable.Add($nameServer.Key, $nameServer.Value) } + + $nameServerHashtable.Count | Should -Be $ConfigurationData.AllNodes.NameServer.Count + + $resourceCurrentState.IsSingleInstance | Should -Be 'Yes' + + $nameServerHashtable['H.ROOT-SERVERS.NET.'] | Should -Be '198.97.190.53' + $nameServerHashtable['E.ROOT-SERVERS.NET.'] | Should -Be '192.203.230.10' + $nameServerHashtable['M.ROOT-SERVERS.NET.'] | Should -Be '202.12.27.33' + $nameServerHashtable['A.ROOT-SERVERS.NET.'] | Should -Be '198.41.0.4' + $nameServerHashtable['D.ROOT-SERVERS.NET.'] | Should -Be '199.7.91.13' + $nameServerHashtable['F.ROOT-SERVERS.NET.'] | Should -Be '192.5.5.241' + $nameServerHashtable['B.ROOT-SERVERS.NET.'] | Should -Be '192.228.79.201' + $nameServerHashtable['G.ROOT-SERVERS.NET.'] | Should -Be '192.112.36.4' + $nameServerHashtable['C.ROOT-SERVERS.NET.'] | Should -Be '192.33.4.12' + $nameServerHashtable['K.ROOT-SERVERS.NET.'] | Should -Be '193.0.14.129' + $nameServerHashtable['I.ROOT-SERVERS.NET.'] | Should -Be '192.36.148.17' + $nameServerHashtable['J.ROOT-SERVERS.NET.'] | Should -Be '192.58.128.30' + $nameServerHashtable['L.ROOT-SERVERS.NET.'] | Should -Be '199.7.83.42' } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/DSC_DnsServerSetting.Integration.Tests.ps1 b/tests/Integration/DSC_DnsServerSetting.Integration.Tests.ps1 index 4aa6a2be..ce996092 100644 --- a/tests/Integration/DSC_DnsServerSetting.Integration.Tests.ps1 +++ b/tests/Integration/DSC_DnsServerSetting.Integration.Tests.ps1 @@ -1,376 +1,416 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsServerSetting' -$script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerSetting' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerSetting' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Integration' } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} -try -{ - #region Integration Tests - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile - Describe "$($script:dscResourceName)_Integration" { - BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" - # This will be used to set the settings back to the original values. - $originalConfigurationData = @{ - AllNodes = @() - } + # This will be used to set the settings back to the original values. + $script:originalConfigurationData = @{ + AllNodes = @() + } + } + + Context ('When using Invoke-DscResource to get current state') { + AfterAll { + Wait-ForIdleLcm -Clear } - Context ('When using Invoke-DscResource to get current state') { - It 'Should get the values of the current state without throwing' { - { - $invokeDscResourceParameters = @{ - Name = $script:dscResourceFriendlyName - ModuleName = $script:dscModuleName - Method = 'Get' - Property = @{ - DnsServer = 'localhost' - } - ErrorAction = 'Stop' + It 'Should get the values of the current state without throwing' { + { + $invokeDscResourceParameters = @{ + Name = $script:dscResourceFriendlyName + ModuleName = $script:dscModuleName + Method = 'Get' + Property = @{ + DnsServer = 'localhost' } + ErrorAction = 'Stop' + } - $originalPropertyValues = Invoke-DscResource @invokeDscResourceParameters - - $originalPropertyText = ($originalPropertyValues | Out-String) -replace '\r?\n', "`n" - - Write-Verbose -Message ("Current state values:`n{0}" -f $originalPropertyText) -Verbose - - # Save all current values so that they can be set back at the end of the test. - $originalConfigurationData.AllNodes += @{ - NodeName = 'localhost' - CertificateFile = $env:DscPublicCertificatePath - DnsServer = 'localhost' - - AddressAnswerLimit = $originalPropertyValues.AddressAnswerLimit - AllowUpdate = $originalPropertyValues.AllowUpdate - AutoCacheUpdate = $originalPropertyValues.AutoCacheUpdate - AutoConfigFileZones = $originalPropertyValues.AutoConfigFileZones - BindSecondaries = $originalPropertyValues.BindSecondaries - BootMethod = $originalPropertyValues.BootMethod - DisableAutoReverseZone = $originalPropertyValues.DisableAutoReverseZone - EnableDirectoryPartitions = $originalPropertyValues.EnableDirectoryPartitions - EnableDnsSec = $originalPropertyValues.EnableDnsSec - ForwardDelegations = $originalPropertyValues.ForwardDelegations - ListeningIPAddress = $originalPropertyValues.ListeningIPAddress - LocalNetPriority = $originalPropertyValues.LocalNetPriority - LooseWildcarding = $originalPropertyValues.LooseWildcarding - NameCheckFlag = $originalPropertyValues.NameCheckFlag - RoundRobin = $originalPropertyValues.RoundRobin - RpcProtocol = $originalPropertyValues.RpcProtocol - SendPort = $originalPropertyValues.SendPort - StrictFileParsing = $originalPropertyValues.StrictFileParsing - UpdateOptions = $originalPropertyValues.UpdateOptions - WriteAuthorityNS = $originalPropertyValues.WriteAuthorityNS - XfrConnectTimeout = $originalPropertyValues.XfrConnectTimeout - ServerLevelPluginDll = $originalPropertyValues.ServerLevelPluginDll - AdminConfigured = $originalPropertyValues.AdminConfigured - AllowCnameAtNs = $originalPropertyValues.AllowCnameAtNs - AllowReadOnlyZoneTransfer = $originalPropertyValues.AllowReadOnlyZoneTransfer - AppendMsZoneTransferTag = $originalPropertyValues.AppendMsZoneTransferTag - AutoCreateDelegation = $originalPropertyValues.AutoCreateDelegation - DeleteOutsideGlue = $originalPropertyValues.DeleteOutsideGlue - EnableDuplicateQuerySuppression = $originalPropertyValues.EnableDuplicateQuerySuppression - EnableIPv6 = $originalPropertyValues.EnableIPv6 - EnableIQueryResponseGeneration = $originalPropertyValues.EnableIQueryResponseGeneration - EnableOnlineSigning = $originalPropertyValues.EnableOnlineSigning - EnableRsoForRodc = $originalPropertyValues.EnableRsoForRodc - EnableSendErrorSuppression = $originalPropertyValues.EnableSendErrorSuppression - EnableUpdateForwarding = $originalPropertyValues.EnableUpdateForwarding - EnableVersionQuery = $originalPropertyValues.EnableVersionQuery - EnableWinsR = $originalPropertyValues.EnableWinsR - <# + $originalPropertyValues = Invoke-DscResource @invokeDscResourceParameters + + $originalPropertyText = ($originalPropertyValues | Out-String) -replace '\r?\n', "`n" + + Write-Verbose -Message ("Current state values:`n{0}" -f $originalPropertyText) -Verbose + + # Save all current values so that they can be set back at the end of the test. + $script:originalConfigurationData.AllNodes += @{ + NodeName = 'localhost' + CertificateFile = $env:DscPublicCertificatePath + DnsServer = 'localhost' + + AddressAnswerLimit = $originalPropertyValues.AddressAnswerLimit + AllowUpdate = $originalPropertyValues.AllowUpdate + AutoCacheUpdate = $originalPropertyValues.AutoCacheUpdate + AutoConfigFileZones = $originalPropertyValues.AutoConfigFileZones + BindSecondaries = $originalPropertyValues.BindSecondaries + BootMethod = $originalPropertyValues.BootMethod + DisableAutoReverseZone = $originalPropertyValues.DisableAutoReverseZone + EnableDirectoryPartitions = $originalPropertyValues.EnableDirectoryPartitions + EnableDnsSec = $originalPropertyValues.EnableDnsSec + ForwardDelegations = $originalPropertyValues.ForwardDelegations + ListeningIPAddress = $originalPropertyValues.ListeningIPAddress + LocalNetPriority = $originalPropertyValues.LocalNetPriority + LooseWildcarding = $originalPropertyValues.LooseWildcarding + NameCheckFlag = $originalPropertyValues.NameCheckFlag + RoundRobin = $originalPropertyValues.RoundRobin + RpcProtocol = $originalPropertyValues.RpcProtocol + SendPort = $originalPropertyValues.SendPort + StrictFileParsing = $originalPropertyValues.StrictFileParsing + UpdateOptions = $originalPropertyValues.UpdateOptions + WriteAuthorityNS = $originalPropertyValues.WriteAuthorityNS + XfrConnectTimeout = $originalPropertyValues.XfrConnectTimeout + ServerLevelPluginDll = $originalPropertyValues.ServerLevelPluginDll + AdminConfigured = $originalPropertyValues.AdminConfigured + AllowCnameAtNs = $originalPropertyValues.AllowCnameAtNs + AllowReadOnlyZoneTransfer = $originalPropertyValues.AllowReadOnlyZoneTransfer + AppendMsZoneTransferTag = $originalPropertyValues.AppendMsZoneTransferTag + AutoCreateDelegation = $originalPropertyValues.AutoCreateDelegation + DeleteOutsideGlue = $originalPropertyValues.DeleteOutsideGlue + EnableDuplicateQuerySuppression = $originalPropertyValues.EnableDuplicateQuerySuppression + EnableIPv6 = $originalPropertyValues.EnableIPv6 + EnableIQueryResponseGeneration = $originalPropertyValues.EnableIQueryResponseGeneration + EnableOnlineSigning = $originalPropertyValues.EnableOnlineSigning + EnableRsoForRodc = $originalPropertyValues.EnableRsoForRodc + EnableSendErrorSuppression = $originalPropertyValues.EnableSendErrorSuppression + EnableUpdateForwarding = $originalPropertyValues.EnableUpdateForwarding + EnableVersionQuery = $originalPropertyValues.EnableVersionQuery + EnableWinsR = $originalPropertyValues.EnableWinsR + <# TODO: This value was not revert to $false on the build worker, when it was previously set to $true by test actual test. This is temporarily using the same value as the actual test, instead of $originalPropertyValues.IgnoreAllPolicies. Beign tracked in issue https://github.com/dsccommunity/DnsServerDsc/issues/260. #> - IgnoreAllPolicies = $ConfigurationData.AllNodes.IgnoreAllPolicies - IgnoreServerLevelPolicies = $originalPropertyValues.IgnoreServerLevelPolicies - LameDelegationTTL = $originalPropertyValues.LameDelegationTTL - LocalNetPriorityMask = $originalPropertyValues.LocalNetPriorityMask - MaximumRodcRsoAttemptsPerCycle = $originalPropertyValues.MaximumRodcRsoAttemptsPerCycle - MaximumRodcRsoQueueLength = $originalPropertyValues.MaximumRodcRsoQueueLength - MaximumSignatureScanPeriod = $originalPropertyValues.MaximumSignatureScanPeriod - MaximumTrustAnchorActiveRefreshInterval = $originalPropertyValues.MaximumTrustAnchorActiveRefreshInterval - MaxResourceRecordsInNonSecureUpdate = $originalPropertyValues.MaxResourceRecordsInNonSecureUpdate - NoUpdateDelegations = $originalPropertyValues.NoUpdateDelegations - OpenAclOnProxyUpdates = $originalPropertyValues.OpenAclOnProxyUpdates - PublishAutoNet = $originalPropertyValues.PublishAutoNet - QuietRecvFaultInterval = $originalPropertyValues.QuietRecvFaultInterval - QuietRecvLogInterval = $originalPropertyValues.QuietRecvLogInterval - ReloadException = $originalPropertyValues.ReloadException - RemoteIPv4RankBoost = $originalPropertyValues.RemoteIPv4RankBoost - RemoteIPv6RankBoost = $originalPropertyValues.RemoteIPv6RankBoost - RootTrustAnchorsURL = $originalPropertyValues.RootTrustAnchorsURL - ScopeOptionValue = $originalPropertyValues.ScopeOptionValue - SelfTest = $originalPropertyValues.SelfTest - SilentlyIgnoreCnameUpdateConflicts = $originalPropertyValues.SilentlyIgnoreCnameUpdateConflicts - SocketPoolExcludedPortRanges = $originalPropertyValues.SocketPoolExcludedPortRanges - SocketPoolSize = $originalPropertyValues.SocketPoolSize - SyncDsZoneSerial = $originalPropertyValues.SyncDsZoneSerial - TcpReceivePacketSize = $originalPropertyValues.TcpReceivePacketSize - VirtualizationInstanceOptionValue = $originalPropertyValues.VirtualizationInstanceOptionValue - XfrThrottleMultiplier = $originalPropertyValues.XfrThrottleMultiplier - ZoneWritebackInterval = $originalPropertyValues.ZoneWritebackInterval - } - } | Should -Not -Throw - } + IgnoreAllPolicies = $ConfigurationData.AllNodes.IgnoreAllPolicies + IgnoreServerLevelPolicies = $originalPropertyValues.IgnoreServerLevelPolicies + LameDelegationTTL = $originalPropertyValues.LameDelegationTTL + LocalNetPriorityMask = $originalPropertyValues.LocalNetPriorityMask + MaximumRodcRsoAttemptsPerCycle = $originalPropertyValues.MaximumRodcRsoAttemptsPerCycle + MaximumRodcRsoQueueLength = $originalPropertyValues.MaximumRodcRsoQueueLength + MaximumSignatureScanPeriod = $originalPropertyValues.MaximumSignatureScanPeriod + MaximumTrustAnchorActiveRefreshInterval = $originalPropertyValues.MaximumTrustAnchorActiveRefreshInterval + MaxResourceRecordsInNonSecureUpdate = $originalPropertyValues.MaxResourceRecordsInNonSecureUpdate + NoUpdateDelegations = $originalPropertyValues.NoUpdateDelegations + OpenAclOnProxyUpdates = $originalPropertyValues.OpenAclOnProxyUpdates + PublishAutoNet = $originalPropertyValues.PublishAutoNet + QuietRecvFaultInterval = $originalPropertyValues.QuietRecvFaultInterval + QuietRecvLogInterval = $originalPropertyValues.QuietRecvLogInterval + ReloadException = $originalPropertyValues.ReloadException + RemoteIPv4RankBoost = $originalPropertyValues.RemoteIPv4RankBoost + RemoteIPv6RankBoost = $originalPropertyValues.RemoteIPv6RankBoost + RootTrustAnchorsURL = $originalPropertyValues.RootTrustAnchorsURL + ScopeOptionValue = $originalPropertyValues.ScopeOptionValue + SelfTest = $originalPropertyValues.SelfTest + SilentlyIgnoreCnameUpdateConflicts = $originalPropertyValues.SilentlyIgnoreCnameUpdateConflicts + SocketPoolExcludedPortRanges = $originalPropertyValues.SocketPoolExcludedPortRanges + SocketPoolSize = $originalPropertyValues.SocketPoolSize + SyncDsZoneSerial = $originalPropertyValues.SyncDsZoneSerial + TcpReceivePacketSize = $originalPropertyValues.TcpReceivePacketSize + VirtualizationInstanceOptionValue = $originalPropertyValues.VirtualizationInstanceOptionValue + XfrThrottleMultiplier = $originalPropertyValues.XfrThrottleMultiplier + ZoneWritebackInterval = $originalPropertyValues.ZoneWritebackInterval + } + } | Should -Not -Throw } + } - Wait-ForIdleLcm -Clear + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetSettings_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $configurationName = "$($script:dscResourceName)_SetSettings_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + & $configurationName @configurationParameters - & $configurationName @configurationParameters + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } - - $resourceCurrentState.DnsServer | Should -Be $ConfigurationData.AllNodes.DnsServer - $resourceCurrentState.AddressAnswerLimit | Should -Be $ConfigurationData.AllNodes.AddressAnswerLimit - $resourceCurrentState.AllowUpdate | Should -Be $ConfigurationData.AllNodes.AllowUpdate - $resourceCurrentState.AutoCacheUpdate | Should -Be $ConfigurationData.AllNodes.AutoCacheUpdate - $resourceCurrentState.AutoConfigFileZones | Should -Be $ConfigurationData.AllNodes.AutoConfigFileZones - $resourceCurrentState.BindSecondaries | Should -Be $ConfigurationData.AllNodes.BindSecondaries - $resourceCurrentState.BootMethod | Should -Be $ConfigurationData.AllNodes.BootMethod - $resourceCurrentState.DisableAutoReverseZone | Should -Be $ConfigurationData.AllNodes.DisableAutoReverseZone - $resourceCurrentState.EnableDirectoryPartitions | Should -Be $ConfigurationData.AllNodes.EnableDirectoryPartitions - $resourceCurrentState.EnableDnsSec | Should -Be $ConfigurationData.AllNodes.EnableDnsSec - $resourceCurrentState.ListeningIPAddress | Should -Be $ConfigurationData.AllNodes.ListeningIPAddress - $resourceCurrentState.ForwardDelegations | Should -Be $ConfigurationData.AllNodes.ForwardDelegations - $resourceCurrentState.LocalNetPriority | Should -Be $ConfigurationData.AllNodes.LocalNetPriority - $resourceCurrentState.LooseWildcarding | Should -Be $ConfigurationData.AllNodes.LooseWildcarding - $resourceCurrentState.NameCheckFlag | Should -Be $ConfigurationData.AllNodes.NameCheckFlag - $resourceCurrentState.RoundRobin | Should -Be $ConfigurationData.AllNodes.RoundRobin - $resourceCurrentState.RpcProtocol | Should -Be $ConfigurationData.AllNodes.RpcProtocol - $resourceCurrentState.SendPort | Should -Be $ConfigurationData.AllNodes.SendPort - $resourceCurrentState.StrictFileParsing | Should -Be $ConfigurationData.AllNodes.StrictFileParsing - $resourceCurrentState.UpdateOptions | Should -Be $ConfigurationData.AllNodes.UpdateOptions - $resourceCurrentState.WriteAuthorityNS | Should -Be $ConfigurationData.AllNodes.WriteAuthorityNS - $resourceCurrentState.XfrConnectTimeout | Should -Be $ConfigurationData.AllNodes.XfrConnectTimeout - $resourceCurrentState.ServerLevelPluginDll | Should -Be $ConfigurationData.AllNodes.ServerLevelPluginDll - $resourceCurrentState.AdminConfigured | Should -Be $ConfigurationData.AllNodes.AdminConfigured - $resourceCurrentState.AllowCnameAtNs | Should -Be $ConfigurationData.AllNodes.AllowCnameAtNs - $resourceCurrentState.AllowReadOnlyZoneTransfer | Should -Be $ConfigurationData.AllNodes.AllowReadOnlyZoneTransfer - $resourceCurrentState.AppendMsZoneTransferTag | Should -Be $ConfigurationData.AllNodes.AppendMsZoneTransferTag - $resourceCurrentState.AutoCreateDelegation | Should -Be $ConfigurationData.AllNodes.AutoCreateDelegation - $resourceCurrentState.DeleteOutsideGlue | Should -Be $ConfigurationData.AllNodes.DeleteOutsideGlue - $resourceCurrentState.EnableDuplicateQuerySuppression | Should -Be $ConfigurationData.AllNodes.EnableDuplicateQuerySuppression - $resourceCurrentState.EnableIPv6 | Should -Be $ConfigurationData.AllNodes.EnableIPv6 - $resourceCurrentState.EnableIQueryResponseGeneration | Should -Be $ConfigurationData.AllNodes.EnableIQueryResponseGeneration - $resourceCurrentState.EnableOnlineSigning | Should -Be $ConfigurationData.AllNodes.EnableOnlineSigning - $resourceCurrentState.EnableRsoForRodc | Should -Be $ConfigurationData.AllNodes.EnableRsoForRodc - $resourceCurrentState.EnableSendErrorSuppression | Should -Be $ConfigurationData.AllNodes.EnableSendErrorSuppression - $resourceCurrentState.EnableUpdateForwarding | Should -Be $ConfigurationData.AllNodes.EnableUpdateForwarding - $resourceCurrentState.EnableVersionQuery | Should -Be $ConfigurationData.AllNodes.EnableVersionQuery - $resourceCurrentState.EnableWinsR | Should -Be $ConfigurationData.AllNodes.EnableWinsR - $resourceCurrentState.IgnoreAllPolicies | Should -Be $ConfigurationData.AllNodes.IgnoreAllPolicies - $resourceCurrentState.IgnoreServerLevelPolicies | Should -Be $ConfigurationData.AllNodes.IgnoreServerLevelPolicies - $resourceCurrentState.LameDelegationTTL | Should -Be $ConfigurationData.AllNodes.LameDelegationTTL - $resourceCurrentState.LocalNetPriorityMask | Should -Be $ConfigurationData.AllNodes.LocalNetPriorityMask - $resourceCurrentState.MaximumRodcRsoAttemptsPerCycle | Should -Be $ConfigurationData.AllNodes.MaximumRodcRsoAttemptsPerCycle - $resourceCurrentState.MaximumRodcRsoQueueLength | Should -Be $ConfigurationData.AllNodes.MaximumRodcRsoQueueLength - $resourceCurrentState.MaximumSignatureScanPeriod | Should -Be $ConfigurationData.AllNodes.MaximumSignatureScanPeriod - $resourceCurrentState.MaximumTrustAnchorActiveRefreshInterval | Should -Be $ConfigurationData.AllNodes.MaximumTrustAnchorActiveRefreshInterval - $resourceCurrentState.MaxResourceRecordsInNonSecureUpdate | Should -Be $ConfigurationData.AllNodes.MaxResourceRecordsInNonSecureUpdate - $resourceCurrentState.NoUpdateDelegations | Should -Be $ConfigurationData.AllNodes.NoUpdateDelegations - $resourceCurrentState.OpenAclOnProxyUpdates | Should -Be $ConfigurationData.AllNodes.OpenAclOnProxyUpdates - $resourceCurrentState.PublishAutoNet | Should -Be $ConfigurationData.AllNodes.PublishAutoNet - $resourceCurrentState.QuietRecvFaultInterval | Should -Be $ConfigurationData.AllNodes.QuietRecvFaultInterval - $resourceCurrentState.QuietRecvLogInterval | Should -Be $ConfigurationData.AllNodes.QuietRecvLogInterval - $resourceCurrentState.ReloadException | Should -Be $ConfigurationData.AllNodes.ReloadException - $resourceCurrentState.RemoteIPv4RankBoost | Should -Be $ConfigurationData.AllNodes.RemoteIPv4RankBoost - $resourceCurrentState.RemoteIPv6RankBoost | Should -Be $ConfigurationData.AllNodes.RemoteIPv6RankBoost - $resourceCurrentState.RootTrustAnchorsURL | Should -Be $ConfigurationData.AllNodes.RootTrustAnchorsURL - $resourceCurrentState.ScopeOptionValue | Should -Be $ConfigurationData.AllNodes.ScopeOptionValue - $resourceCurrentState.SelfTest | Should -Be $ConfigurationData.AllNodes.SelfTest - $resourceCurrentState.SilentlyIgnoreCnameUpdateConflicts | Should -Be $ConfigurationData.AllNodes.SilentlyIgnoreCnameUpdateConflicts - $resourceCurrentState.SocketPoolExcludedPortRanges | Should -Be $ConfigurationData.AllNodes.SocketPoolExcludedPortRanges - $resourceCurrentState.SocketPoolSize | Should -Be $ConfigurationData.AllNodes.SocketPoolSize - $resourceCurrentState.SyncDsZoneSerial | Should -Be $ConfigurationData.AllNodes.SyncDsZoneSerial - $resourceCurrentState.TcpReceivePacketSize | Should -Be $ConfigurationData.AllNodes.TcpReceivePacketSize - $resourceCurrentState.VirtualizationInstanceOptionValue | Should -Be $ConfigurationData.AllNodes.VirtualizationInstanceOptionValue - $resourceCurrentState.XfrThrottleMultiplier | Should -Be $ConfigurationData.AllNodes.XfrThrottleMultiplier - $resourceCurrentState.ZoneWritebackInterval | Should -Be $ConfigurationData.AllNodes.ZoneWritebackInterval - } + $resourceCurrentState.DnsServer | Should -Be $ConfigurationData.AllNodes.DnsServer + $resourceCurrentState.AddressAnswerLimit | Should -Be $ConfigurationData.AllNodes.AddressAnswerLimit + $resourceCurrentState.AllowUpdate | Should -Be $ConfigurationData.AllNodes.AllowUpdate + $resourceCurrentState.AutoCacheUpdate | Should -Be $ConfigurationData.AllNodes.AutoCacheUpdate + $resourceCurrentState.AutoConfigFileZones | Should -Be $ConfigurationData.AllNodes.AutoConfigFileZones + $resourceCurrentState.BindSecondaries | Should -Be $ConfigurationData.AllNodes.BindSecondaries + $resourceCurrentState.BootMethod | Should -Be $ConfigurationData.AllNodes.BootMethod + $resourceCurrentState.DisableAutoReverseZone | Should -Be $ConfigurationData.AllNodes.DisableAutoReverseZone + $resourceCurrentState.EnableDirectoryPartitions | Should -Be $ConfigurationData.AllNodes.EnableDirectoryPartitions + $resourceCurrentState.EnableDnsSec | Should -Be $ConfigurationData.AllNodes.EnableDnsSec + $resourceCurrentState.ListeningIPAddress | Should -Be $ConfigurationData.AllNodes.ListeningIPAddress + $resourceCurrentState.ForwardDelegations | Should -Be $ConfigurationData.AllNodes.ForwardDelegations + $resourceCurrentState.LocalNetPriority | Should -Be $ConfigurationData.AllNodes.LocalNetPriority + $resourceCurrentState.LooseWildcarding | Should -Be $ConfigurationData.AllNodes.LooseWildcarding + $resourceCurrentState.NameCheckFlag | Should -Be $ConfigurationData.AllNodes.NameCheckFlag + $resourceCurrentState.RoundRobin | Should -Be $ConfigurationData.AllNodes.RoundRobin + $resourceCurrentState.RpcProtocol | Should -Be $ConfigurationData.AllNodes.RpcProtocol + $resourceCurrentState.SendPort | Should -Be $ConfigurationData.AllNodes.SendPort + $resourceCurrentState.StrictFileParsing | Should -Be $ConfigurationData.AllNodes.StrictFileParsing + $resourceCurrentState.UpdateOptions | Should -Be $ConfigurationData.AllNodes.UpdateOptions + $resourceCurrentState.WriteAuthorityNS | Should -Be $ConfigurationData.AllNodes.WriteAuthorityNS + $resourceCurrentState.XfrConnectTimeout | Should -Be $ConfigurationData.AllNodes.XfrConnectTimeout + $resourceCurrentState.ServerLevelPluginDll | Should -Be $ConfigurationData.AllNodes.ServerLevelPluginDll + $resourceCurrentState.AdminConfigured | Should -Be $ConfigurationData.AllNodes.AdminConfigured + $resourceCurrentState.AllowCnameAtNs | Should -Be $ConfigurationData.AllNodes.AllowCnameAtNs + $resourceCurrentState.AllowReadOnlyZoneTransfer | Should -Be $ConfigurationData.AllNodes.AllowReadOnlyZoneTransfer + $resourceCurrentState.AppendMsZoneTransferTag | Should -Be $ConfigurationData.AllNodes.AppendMsZoneTransferTag + $resourceCurrentState.AutoCreateDelegation | Should -Be $ConfigurationData.AllNodes.AutoCreateDelegation + $resourceCurrentState.DeleteOutsideGlue | Should -Be $ConfigurationData.AllNodes.DeleteOutsideGlue + $resourceCurrentState.EnableDuplicateQuerySuppression | Should -Be $ConfigurationData.AllNodes.EnableDuplicateQuerySuppression + $resourceCurrentState.EnableIPv6 | Should -Be $ConfigurationData.AllNodes.EnableIPv6 + $resourceCurrentState.EnableIQueryResponseGeneration | Should -Be $ConfigurationData.AllNodes.EnableIQueryResponseGeneration + $resourceCurrentState.EnableOnlineSigning | Should -Be $ConfigurationData.AllNodes.EnableOnlineSigning + $resourceCurrentState.EnableRsoForRodc | Should -Be $ConfigurationData.AllNodes.EnableRsoForRodc + $resourceCurrentState.EnableSendErrorSuppression | Should -Be $ConfigurationData.AllNodes.EnableSendErrorSuppression + $resourceCurrentState.EnableUpdateForwarding | Should -Be $ConfigurationData.AllNodes.EnableUpdateForwarding + $resourceCurrentState.EnableVersionQuery | Should -Be $ConfigurationData.AllNodes.EnableVersionQuery + $resourceCurrentState.EnableWinsR | Should -Be $ConfigurationData.AllNodes.EnableWinsR + $resourceCurrentState.IgnoreAllPolicies | Should -Be $ConfigurationData.AllNodes.IgnoreAllPolicies + $resourceCurrentState.IgnoreServerLevelPolicies | Should -Be $ConfigurationData.AllNodes.IgnoreServerLevelPolicies + $resourceCurrentState.LameDelegationTTL | Should -Be $ConfigurationData.AllNodes.LameDelegationTTL + $resourceCurrentState.LocalNetPriorityMask | Should -Be $ConfigurationData.AllNodes.LocalNetPriorityMask + $resourceCurrentState.MaximumRodcRsoAttemptsPerCycle | Should -Be $ConfigurationData.AllNodes.MaximumRodcRsoAttemptsPerCycle + $resourceCurrentState.MaximumRodcRsoQueueLength | Should -Be $ConfigurationData.AllNodes.MaximumRodcRsoQueueLength + $resourceCurrentState.MaximumSignatureScanPeriod | Should -Be $ConfigurationData.AllNodes.MaximumSignatureScanPeriod + $resourceCurrentState.MaximumTrustAnchorActiveRefreshInterval | Should -Be $ConfigurationData.AllNodes.MaximumTrustAnchorActiveRefreshInterval + $resourceCurrentState.MaxResourceRecordsInNonSecureUpdate | Should -Be $ConfigurationData.AllNodes.MaxResourceRecordsInNonSecureUpdate + $resourceCurrentState.NoUpdateDelegations | Should -Be $ConfigurationData.AllNodes.NoUpdateDelegations + $resourceCurrentState.OpenAclOnProxyUpdates | Should -Be $ConfigurationData.AllNodes.OpenAclOnProxyUpdates + $resourceCurrentState.PublishAutoNet | Should -Be $ConfigurationData.AllNodes.PublishAutoNet + $resourceCurrentState.QuietRecvFaultInterval | Should -Be $ConfigurationData.AllNodes.QuietRecvFaultInterval + $resourceCurrentState.QuietRecvLogInterval | Should -Be $ConfigurationData.AllNodes.QuietRecvLogInterval + $resourceCurrentState.ReloadException | Should -Be $ConfigurationData.AllNodes.ReloadException + $resourceCurrentState.RemoteIPv4RankBoost | Should -Be $ConfigurationData.AllNodes.RemoteIPv4RankBoost + $resourceCurrentState.RemoteIPv6RankBoost | Should -Be $ConfigurationData.AllNodes.RemoteIPv6RankBoost + $resourceCurrentState.RootTrustAnchorsURL | Should -Be $ConfigurationData.AllNodes.RootTrustAnchorsURL + $resourceCurrentState.ScopeOptionValue | Should -Be $ConfigurationData.AllNodes.ScopeOptionValue + $resourceCurrentState.SelfTest | Should -Be $ConfigurationData.AllNodes.SelfTest + $resourceCurrentState.SilentlyIgnoreCnameUpdateConflicts | Should -Be $ConfigurationData.AllNodes.SilentlyIgnoreCnameUpdateConflicts + $resourceCurrentState.SocketPoolExcludedPortRanges | Should -Be $ConfigurationData.AllNodes.SocketPoolExcludedPortRanges + $resourceCurrentState.SocketPoolSize | Should -Be $ConfigurationData.AllNodes.SocketPoolSize + $resourceCurrentState.SyncDsZoneSerial | Should -Be $ConfigurationData.AllNodes.SyncDsZoneSerial + $resourceCurrentState.TcpReceivePacketSize | Should -Be $ConfigurationData.AllNodes.TcpReceivePacketSize + $resourceCurrentState.VirtualizationInstanceOptionValue | Should -Be $ConfigurationData.AllNodes.VirtualizationInstanceOptionValue + $resourceCurrentState.XfrThrottleMultiplier | Should -Be $ConfigurationData.AllNodes.XfrThrottleMultiplier + $resourceCurrentState.ZoneWritebackInterval | Should -Be $ConfigurationData.AllNodes.ZoneWritebackInterval + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' } + } - Wait-ForIdleLcm -Clear - - <# - This is using the same configuration, but the configuration data is - switch before running the configuration, to be able to revert back - to the original values! NOTE: This must always be the - last test for this resource! - #> - Context ('When using configuration {0} to revert to original values' -f $configurationName) { - BeforeAll { - # Switch to configuration data that holds the original values. - $ConfigurationData = $originalConfigurationData - } + <# + This is using the same configuration, but the configuration data is + switch before running the configuration, to be able to revert back + to the original values! NOTE: This must always be the + last test for this resource! + #> + BeforeDiscovery { + $configurationName = "$($script:dscResourceName)_SetSettings_Config" + } - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + Context ('When using configuration {0} to revert to original values' -f $configurationName) { + BeforeAll { + $configurationName = "$($script:dscResourceName)_SetSettings_Config" - & $configurationName @configurationParameters + $ConfigurationData = $script:originalConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + AfterAll { + Wait-ForIdleLcm -Clear + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + & $configurationName @configurationParameters - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.DnsServer | Should -Be $ConfigurationData.AllNodes.DnsServer - $resourceCurrentState.AddressAnswerLimit | Should -Be $ConfigurationData.AllNodes.AddressAnswerLimit - $resourceCurrentState.AllowUpdate | Should -Be $ConfigurationData.AllNodes.AllowUpdate - $resourceCurrentState.AutoCacheUpdate | Should -Be $ConfigurationData.AllNodes.AutoCacheUpdate - $resourceCurrentState.AutoConfigFileZones | Should -Be $ConfigurationData.AllNodes.AutoConfigFileZones - $resourceCurrentState.BindSecondaries | Should -Be $ConfigurationData.AllNodes.BindSecondaries - $resourceCurrentState.BootMethod | Should -Be $ConfigurationData.AllNodes.BootMethod - $resourceCurrentState.DisableAutoReverseZone | Should -Be $ConfigurationData.AllNodes.DisableAutoReverseZone - $resourceCurrentState.EnableDirectoryPartitions | Should -Be $ConfigurationData.AllNodes.EnableDirectoryPartitions - $resourceCurrentState.EnableDnsSec | Should -Be $ConfigurationData.AllNodes.EnableDnsSec - $resourceCurrentState.ListeningIPAddress | Should -Be $ConfigurationData.AllNodes.ListeningIPAddress - $resourceCurrentState.ForwardDelegations | Should -Be $ConfigurationData.AllNodes.ForwardDelegations - $resourceCurrentState.LocalNetPriority | Should -Be $ConfigurationData.AllNodes.LocalNetPriority - $resourceCurrentState.LooseWildcarding | Should -Be $ConfigurationData.AllNodes.LooseWildcarding - $resourceCurrentState.NameCheckFlag | Should -Be $ConfigurationData.AllNodes.NameCheckFlag - $resourceCurrentState.RoundRobin | Should -Be $ConfigurationData.AllNodes.RoundRobin - $resourceCurrentState.RpcProtocol | Should -Be $ConfigurationData.AllNodes.RpcProtocol - $resourceCurrentState.SendPort | Should -Be $ConfigurationData.AllNodes.SendPort - $resourceCurrentState.StrictFileParsing | Should -Be $ConfigurationData.AllNodes.StrictFileParsing - $resourceCurrentState.UpdateOptions | Should -Be $ConfigurationData.AllNodes.UpdateOptions - $resourceCurrentState.WriteAuthorityNS | Should -Be $ConfigurationData.AllNodes.WriteAuthorityNS - $resourceCurrentState.XfrConnectTimeout | Should -Be $ConfigurationData.AllNodes.XfrConnectTimeout - # TODO: This has been remove due to bug https://github.com/dsccommunity/DnsServerDsc/issues/259 - #$resourceCurrentState.ServerLevelPluginDll | Should -Be $ConfigurationData.AllNodes.ServerLevelPluginDll - $resourceCurrentState.AdminConfigured | Should -Be $ConfigurationData.AllNodes.AdminConfigured - $resourceCurrentState.AllowCnameAtNs | Should -Be $ConfigurationData.AllNodes.AllowCnameAtNs - $resourceCurrentState.AllowReadOnlyZoneTransfer | Should -Be $ConfigurationData.AllNodes.AllowReadOnlyZoneTransfer - $resourceCurrentState.AppendMsZoneTransferTag | Should -Be $ConfigurationData.AllNodes.AppendMsZoneTransferTag - $resourceCurrentState.AutoCreateDelegation | Should -Be $ConfigurationData.AllNodes.AutoCreateDelegation - $resourceCurrentState.DeleteOutsideGlue | Should -Be $ConfigurationData.AllNodes.DeleteOutsideGlue - $resourceCurrentState.EnableDuplicateQuerySuppression | Should -Be $ConfigurationData.AllNodes.EnableDuplicateQuerySuppression - $resourceCurrentState.EnableIPv6 | Should -Be $ConfigurationData.AllNodes.EnableIPv6 - $resourceCurrentState.EnableIQueryResponseGeneration | Should -Be $ConfigurationData.AllNodes.EnableIQueryResponseGeneration - $resourceCurrentState.EnableOnlineSigning | Should -Be $ConfigurationData.AllNodes.EnableOnlineSigning - $resourceCurrentState.EnableRsoForRodc | Should -Be $ConfigurationData.AllNodes.EnableRsoForRodc - $resourceCurrentState.EnableSendErrorSuppression | Should -Be $ConfigurationData.AllNodes.EnableSendErrorSuppression - $resourceCurrentState.EnableUpdateForwarding | Should -Be $ConfigurationData.AllNodes.EnableUpdateForwarding - $resourceCurrentState.EnableVersionQuery | Should -Be $ConfigurationData.AllNodes.EnableVersionQuery - $resourceCurrentState.EnableWinsR | Should -Be $ConfigurationData.AllNodes.EnableWinsR - $resourceCurrentState.IgnoreAllPolicies | Should -Be $ConfigurationData.AllNodes.IgnoreAllPolicies - $resourceCurrentState.IgnoreServerLevelPolicies | Should -Be $ConfigurationData.AllNodes.IgnoreServerLevelPolicies - $resourceCurrentState.LameDelegationTTL | Should -Be $ConfigurationData.AllNodes.LameDelegationTTL - $resourceCurrentState.LocalNetPriorityMask | Should -Be $ConfigurationData.AllNodes.LocalNetPriorityMask - $resourceCurrentState.MaximumRodcRsoAttemptsPerCycle | Should -Be $ConfigurationData.AllNodes.MaximumRodcRsoAttemptsPerCycle - $resourceCurrentState.MaximumRodcRsoQueueLength | Should -Be $ConfigurationData.AllNodes.MaximumRodcRsoQueueLength - $resourceCurrentState.MaximumSignatureScanPeriod | Should -Be $ConfigurationData.AllNodes.MaximumSignatureScanPeriod - $resourceCurrentState.MaximumTrustAnchorActiveRefreshInterval | Should -Be $ConfigurationData.AllNodes.MaximumTrustAnchorActiveRefreshInterval - $resourceCurrentState.MaxResourceRecordsInNonSecureUpdate | Should -Be $ConfigurationData.AllNodes.MaxResourceRecordsInNonSecureUpdate - $resourceCurrentState.NoUpdateDelegations | Should -Be $ConfigurationData.AllNodes.NoUpdateDelegations - $resourceCurrentState.OpenAclOnProxyUpdates | Should -Be $ConfigurationData.AllNodes.OpenAclOnProxyUpdates - $resourceCurrentState.PublishAutoNet | Should -Be $ConfigurationData.AllNodes.PublishAutoNet - $resourceCurrentState.QuietRecvFaultInterval | Should -Be $ConfigurationData.AllNodes.QuietRecvFaultInterval - $resourceCurrentState.QuietRecvLogInterval | Should -Be $ConfigurationData.AllNodes.QuietRecvLogInterval - $resourceCurrentState.ReloadException | Should -Be $ConfigurationData.AllNodes.ReloadException - $resourceCurrentState.RemoteIPv4RankBoost | Should -Be $ConfigurationData.AllNodes.RemoteIPv4RankBoost - $resourceCurrentState.RemoteIPv6RankBoost | Should -Be $ConfigurationData.AllNodes.RemoteIPv6RankBoost - $resourceCurrentState.RootTrustAnchorsURL | Should -Be $ConfigurationData.AllNodes.RootTrustAnchorsURL - $resourceCurrentState.ScopeOptionValue | Should -Be $ConfigurationData.AllNodes.ScopeOptionValue - $resourceCurrentState.SelfTest | Should -Be $ConfigurationData.AllNodes.SelfTest - $resourceCurrentState.SilentlyIgnoreCnameUpdateConflicts | Should -Be $ConfigurationData.AllNodes.SilentlyIgnoreCnameUpdateConflicts - $resourceCurrentState.SocketPoolExcludedPortRanges | Should -Be $ConfigurationData.AllNodes.SocketPoolExcludedPortRanges - $resourceCurrentState.SocketPoolSize | Should -Be $ConfigurationData.AllNodes.SocketPoolSize - $resourceCurrentState.SyncDsZoneSerial | Should -Be $ConfigurationData.AllNodes.SyncDsZoneSerial - $resourceCurrentState.TcpReceivePacketSize | Should -Be $ConfigurationData.AllNodes.TcpReceivePacketSize - $resourceCurrentState.VirtualizationInstanceOptionValue | Should -Be $ConfigurationData.AllNodes.VirtualizationInstanceOptionValue - $resourceCurrentState.XfrThrottleMultiplier | Should -Be $ConfigurationData.AllNodes.XfrThrottleMultiplier - $resourceCurrentState.ZoneWritebackInterval | Should -Be $ConfigurationData.AllNodes.ZoneWritebackInterval - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + + $resourceCurrentState.DnsServer | Should -Be $ConfigurationData.AllNodes.DnsServer + $resourceCurrentState.AddressAnswerLimit | Should -Be $ConfigurationData.AllNodes.AddressAnswerLimit + $resourceCurrentState.AllowUpdate | Should -Be $ConfigurationData.AllNodes.AllowUpdate + $resourceCurrentState.AutoCacheUpdate | Should -Be $ConfigurationData.AllNodes.AutoCacheUpdate + $resourceCurrentState.AutoConfigFileZones | Should -Be $ConfigurationData.AllNodes.AutoConfigFileZones + $resourceCurrentState.BindSecondaries | Should -Be $ConfigurationData.AllNodes.BindSecondaries + $resourceCurrentState.BootMethod | Should -Be $ConfigurationData.AllNodes.BootMethod + $resourceCurrentState.DisableAutoReverseZone | Should -Be $ConfigurationData.AllNodes.DisableAutoReverseZone + $resourceCurrentState.EnableDirectoryPartitions | Should -Be $ConfigurationData.AllNodes.EnableDirectoryPartitions + $resourceCurrentState.EnableDnsSec | Should -Be $ConfigurationData.AllNodes.EnableDnsSec + $resourceCurrentState.ListeningIPAddress | Should -Be $ConfigurationData.AllNodes.ListeningIPAddress + $resourceCurrentState.ForwardDelegations | Should -Be $ConfigurationData.AllNodes.ForwardDelegations + $resourceCurrentState.LocalNetPriority | Should -Be $ConfigurationData.AllNodes.LocalNetPriority + $resourceCurrentState.LooseWildcarding | Should -Be $ConfigurationData.AllNodes.LooseWildcarding + $resourceCurrentState.NameCheckFlag | Should -Be $ConfigurationData.AllNodes.NameCheckFlag + $resourceCurrentState.RoundRobin | Should -Be $ConfigurationData.AllNodes.RoundRobin + $resourceCurrentState.RpcProtocol | Should -Be $ConfigurationData.AllNodes.RpcProtocol + $resourceCurrentState.SendPort | Should -Be $ConfigurationData.AllNodes.SendPort + $resourceCurrentState.StrictFileParsing | Should -Be $ConfigurationData.AllNodes.StrictFileParsing + $resourceCurrentState.UpdateOptions | Should -Be $ConfigurationData.AllNodes.UpdateOptions + $resourceCurrentState.WriteAuthorityNS | Should -Be $ConfigurationData.AllNodes.WriteAuthorityNS + $resourceCurrentState.XfrConnectTimeout | Should -Be $ConfigurationData.AllNodes.XfrConnectTimeout + # TODO: This has been remove due to bug https://github.com/dsccommunity/DnsServerDsc/issues/259 + #$resourceCurrentState.ServerLevelPluginDll | Should -Be $ConfigurationData.AllNodes.ServerLevelPluginDll + $resourceCurrentState.AdminConfigured | Should -Be $ConfigurationData.AllNodes.AdminConfigured + $resourceCurrentState.AllowCnameAtNs | Should -Be $ConfigurationData.AllNodes.AllowCnameAtNs + $resourceCurrentState.AllowReadOnlyZoneTransfer | Should -Be $ConfigurationData.AllNodes.AllowReadOnlyZoneTransfer + $resourceCurrentState.AppendMsZoneTransferTag | Should -Be $ConfigurationData.AllNodes.AppendMsZoneTransferTag + $resourceCurrentState.AutoCreateDelegation | Should -Be $ConfigurationData.AllNodes.AutoCreateDelegation + $resourceCurrentState.DeleteOutsideGlue | Should -Be $ConfigurationData.AllNodes.DeleteOutsideGlue + $resourceCurrentState.EnableDuplicateQuerySuppression | Should -Be $ConfigurationData.AllNodes.EnableDuplicateQuerySuppression + $resourceCurrentState.EnableIPv6 | Should -Be $ConfigurationData.AllNodes.EnableIPv6 + $resourceCurrentState.EnableIQueryResponseGeneration | Should -Be $ConfigurationData.AllNodes.EnableIQueryResponseGeneration + $resourceCurrentState.EnableOnlineSigning | Should -Be $ConfigurationData.AllNodes.EnableOnlineSigning + $resourceCurrentState.EnableRsoForRodc | Should -Be $ConfigurationData.AllNodes.EnableRsoForRodc + $resourceCurrentState.EnableSendErrorSuppression | Should -Be $ConfigurationData.AllNodes.EnableSendErrorSuppression + $resourceCurrentState.EnableUpdateForwarding | Should -Be $ConfigurationData.AllNodes.EnableUpdateForwarding + $resourceCurrentState.EnableVersionQuery | Should -Be $ConfigurationData.AllNodes.EnableVersionQuery + $resourceCurrentState.EnableWinsR | Should -Be $ConfigurationData.AllNodes.EnableWinsR + $resourceCurrentState.IgnoreAllPolicies | Should -Be $ConfigurationData.AllNodes.IgnoreAllPolicies + $resourceCurrentState.IgnoreServerLevelPolicies | Should -Be $ConfigurationData.AllNodes.IgnoreServerLevelPolicies + $resourceCurrentState.LameDelegationTTL | Should -Be $ConfigurationData.AllNodes.LameDelegationTTL + $resourceCurrentState.LocalNetPriorityMask | Should -Be $ConfigurationData.AllNodes.LocalNetPriorityMask + $resourceCurrentState.MaximumRodcRsoAttemptsPerCycle | Should -Be $ConfigurationData.AllNodes.MaximumRodcRsoAttemptsPerCycle + $resourceCurrentState.MaximumRodcRsoQueueLength | Should -Be $ConfigurationData.AllNodes.MaximumRodcRsoQueueLength + $resourceCurrentState.MaximumSignatureScanPeriod | Should -Be $ConfigurationData.AllNodes.MaximumSignatureScanPeriod + $resourceCurrentState.MaximumTrustAnchorActiveRefreshInterval | Should -Be $ConfigurationData.AllNodes.MaximumTrustAnchorActiveRefreshInterval + $resourceCurrentState.MaxResourceRecordsInNonSecureUpdate | Should -Be $ConfigurationData.AllNodes.MaxResourceRecordsInNonSecureUpdate + $resourceCurrentState.NoUpdateDelegations | Should -Be $ConfigurationData.AllNodes.NoUpdateDelegations + $resourceCurrentState.OpenAclOnProxyUpdates | Should -Be $ConfigurationData.AllNodes.OpenAclOnProxyUpdates + $resourceCurrentState.PublishAutoNet | Should -Be $ConfigurationData.AllNodes.PublishAutoNet + $resourceCurrentState.QuietRecvFaultInterval | Should -Be $ConfigurationData.AllNodes.QuietRecvFaultInterval + $resourceCurrentState.QuietRecvLogInterval | Should -Be $ConfigurationData.AllNodes.QuietRecvLogInterval + $resourceCurrentState.ReloadException | Should -Be $ConfigurationData.AllNodes.ReloadException + $resourceCurrentState.RemoteIPv4RankBoost | Should -Be $ConfigurationData.AllNodes.RemoteIPv4RankBoost + $resourceCurrentState.RemoteIPv6RankBoost | Should -Be $ConfigurationData.AllNodes.RemoteIPv6RankBoost + $resourceCurrentState.RootTrustAnchorsURL | Should -Be $ConfigurationData.AllNodes.RootTrustAnchorsURL + $resourceCurrentState.ScopeOptionValue | Should -Be $ConfigurationData.AllNodes.ScopeOptionValue + $resourceCurrentState.SelfTest | Should -Be $ConfigurationData.AllNodes.SelfTest + $resourceCurrentState.SilentlyIgnoreCnameUpdateConflicts | Should -Be $ConfigurationData.AllNodes.SilentlyIgnoreCnameUpdateConflicts + $resourceCurrentState.SocketPoolExcludedPortRanges | Should -Be $ConfigurationData.AllNodes.SocketPoolExcludedPortRanges + $resourceCurrentState.SocketPoolSize | Should -Be $ConfigurationData.AllNodes.SocketPoolSize + $resourceCurrentState.SyncDsZoneSerial | Should -Be $ConfigurationData.AllNodes.SyncDsZoneSerial + $resourceCurrentState.TcpReceivePacketSize | Should -Be $ConfigurationData.AllNodes.TcpReceivePacketSize + $resourceCurrentState.VirtualizationInstanceOptionValue | Should -Be $ConfigurationData.AllNodes.VirtualizationInstanceOptionValue + $resourceCurrentState.XfrThrottleMultiplier | Should -Be $ConfigurationData.AllNodes.XfrThrottleMultiplier + $resourceCurrentState.ZoneWritebackInterval | Should -Be $ConfigurationData.AllNodes.ZoneWritebackInterval } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/DSC_DnsServerSettingLegacy.Integration.Tests.ps1 b/tests/Integration/DSC_DnsServerSettingLegacy.Integration.Tests.ps1 index eb377606..7e7c856d 100644 --- a/tests/Integration/DSC_DnsServerSettingLegacy.Integration.Tests.ps1 +++ b/tests/Integration/DSC_DnsServerSettingLegacy.Integration.Tests.ps1 @@ -1,85 +1,117 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsServerSettingLegacy' -$script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerSettingLegacy' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerSettingLegacy' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Integration' } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} -try -{ - #region Integration Tests - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile - Describe "$($script:dscResourceName)_Integration" { + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } + + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_SetSettings_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_SetSettings_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } - - & $configurationName @configurationParameters - - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } - - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + AfterAll { + Wait-ForIdleLcm -Clear + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' } - $resourceCurrentState.DnsServer | Should -Be $ConfigurationData.AllNodes.DnsServer - $resourceCurrentState.DisjointNets | Should -Be $ConfigurationData.AllNodes.DisjointNets - $resourceCurrentState.NoForwarderRecursion | Should -Be $ConfigurationData.AllNodes.NoForwarderRecursion - $resourceCurrentState.LogLevel | Should -Be $ConfigurationData.AllNodes.LogLevel - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } + + $resourceCurrentState.DnsServer | Should -Be $ConfigurationData.AllNodes.DnsServer + $resourceCurrentState.DisjointNets | Should -Be $ConfigurationData.AllNodes.DisjointNets + $resourceCurrentState.NoForwarderRecursion | Should -Be $ConfigurationData.AllNodes.NoForwarderRecursion + $resourceCurrentState.LogLevel | Should -Be $ConfigurationData.AllNodes.LogLevel } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/DSC_DnsServerZoneAging.Integration.Tests.ps1 b/tests/Integration/DSC_DnsServerZoneAging.Integration.Tests.ps1 index 23f275d8..677bf1ef 100644 --- a/tests/Integration/DSC_DnsServerZoneAging.Integration.Tests.ps1 +++ b/tests/Integration/DSC_DnsServerZoneAging.Integration.Tests.ps1 @@ -1,240 +1,297 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsServerZoneAging' -$script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerZoneAging' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerZoneAging' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Integration' } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_Prerequisites_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_Prerequisites_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw } + } - Wait-ForIdleLcm -Clear + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ForwardZone_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $configurationName = "$($script:dscResourceName)_ForwardZone_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` -and $_.ResourceId -eq $resourceId - } - - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName - $resourceCurrentState.Enabled | Should -BeTrue - $resourceCurrentState.RefreshInterval | Should -Be 240 - $resourceCurrentState.NoRefreshInterval | Should -Be 480 } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName + $resourceCurrentState.Enabled | Should -BeTrue + $resourceCurrentState.RefreshInterval | Should -Be 240 + $resourceCurrentState.NoRefreshInterval | Should -Be 480 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_ForwardZoneDisableAging_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ForwardZoneDisableAging_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName - $resourceCurrentState.Enabled | Should -BeFalse - $resourceCurrentState.RefreshInterval | Should -Be 240 - $resourceCurrentState.NoRefreshInterval | Should -Be 480 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ForwardZoneName + $resourceCurrentState.Enabled | Should -BeFalse + $resourceCurrentState.RefreshInterval | Should -Be 240 + $resourceCurrentState.NoRefreshInterval | Should -Be 480 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_ReverseZone_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_ReverseZone_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ReverseZoneName - $resourceCurrentState.Enabled | Should -BeFalse - $resourceCurrentState.RefreshInterval | Should -Be 250 - $resourceCurrentState.NoRefreshInterval | Should -Be 490 + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ReverseZoneName + $resourceCurrentState.Enabled | Should -BeFalse + $resourceCurrentState.RefreshInterval | Should -Be 250 + $resourceCurrentState.NoRefreshInterval | Should -Be 490 } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_Cleanup_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_Cleanup_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Wait-ForIdleLcm -Clear + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/DSC_DnsServerZoneScope.Integration.Tests.ps1 b/tests/Integration/DSC_DnsServerZoneScope.Integration.Tests.ps1 index c91f064e..555081e3 100644 --- a/tests/Integration/DSC_DnsServerZoneScope.Integration.Tests.ps1 +++ b/tests/Integration/DSC_DnsServerZoneScope.Integration.Tests.ps1 @@ -1,190 +1,241 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceFriendlyName = 'DnsServerZoneScope' -$script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } + + <# + Need to define that variables here to be used in the Pester Discover to + build the ForEach-blocks. + #> + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerZoneScope' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" + + # Ensure that the tests can be performed on this computer + $script:skipIntegrationTests = $false +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceFriendlyName = 'DnsServerZoneScope' + $script:dscResourceName = "DSC_$($script:dscResourceFriendlyName)" -try -{ - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Integration' } -catch [System.IO.FileNotFoundException] -{ - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + +AfterAll { + Restore-TestEnvironment -TestEnvironment $script:testEnvironment } -$script:testEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $script:dscModuleName ` - -DSCResourceName $script:dscResourceName ` - -ResourceType 'Mof' ` - -TestType 'Integration' +Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configFile -try -{ - $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" - . $configFile + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } - Describe "$($script:dscResourceName)_Integration" { + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_Prerequisites_Config" + ) { BeforeAll { - $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + $configurationName = $_ } - $configurationName = "$($script:dscResourceName)_Prerequisites_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw } + } - Wait-ForIdleLcm -Clear + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_AddZoneScope_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $configurationName = "$($script:dscResourceName)_AddZoneScope_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` -and $_.ResourceId -eq $resourceId - } - - $resourceCurrentState.Ensure | Should -Be 'Present' - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ZoneScopeName - $resourceCurrentState.ZoneName | Should -Be $ConfigurationData.AllNodes.ForwardZoneName - $resourceCurrentState.ZoneFile | Should -Be ('{0}.dns' -f $ConfigurationData.AllNodes.ZoneScopeName) } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ZoneScopeName + $resourceCurrentState.ZoneName | Should -Be $ConfigurationData.AllNodes.ForwardZoneName + $resourceCurrentState.ZoneFile | Should -Be ('{0}.dns' -f $ConfigurationData.AllNodes.ZoneScopeName) } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } - $configurationName = "$($script:dscResourceName)_RemoveZoneScope_Config" + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_RemoveZoneScope_Config" + ) { + BeforeAll { + $configurationName = $_ + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + AfterAll { + Wait-ForIdleLcm -Clear + } - & $configurationName @configurationParameters + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + & $configurationName @configurationParameters - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - It 'Should be able to call Get-DscConfiguration without throwing' { - { - $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } - It 'Should have set the resource and all the parameters should match' { - $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { - $_.ConfigurationName -eq $configurationName ` - -and $_.ResourceId -eq $resourceId - } + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } - $resourceCurrentState.Ensure | Should -Be 'Absent' - $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ZoneScopeName - $resourceCurrentState.ZoneName | Should -Be $ConfigurationData.AllNodes.ForwardZoneName - $resourceCurrentState.ZoneFile | Should -BeNullOrEmpty + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName ` + -and $_.ResourceId -eq $resourceId } - It 'Should return ''True'' when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be 'True' - } + $resourceCurrentState.Ensure | Should -Be 'Absent' + $resourceCurrentState.Name | Should -Be $ConfigurationData.AllNodes.ZoneScopeName + $resourceCurrentState.ZoneName | Should -Be $ConfigurationData.AllNodes.ForwardZoneName + $resourceCurrentState.ZoneFile | Should -BeNullOrEmpty } - Wait-ForIdleLcm -Clear + It 'Should return ''True'' when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + Context ('When using configuration <_>') -ForEach @( + "$($script:dscResourceName)_Cleanup_Config" + ) { + BeforeAll { + $configurationName = $_ + } - $configurationName = "$($script:dscResourceName)_Cleanup_Config" + AfterAll { + Wait-ForIdleLcm -Clear + } - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - $configurationParameters = @{ - OutputPath = $TestDrive - ConfigurationData = $ConfigurationData - } + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } - & $configurationName @configurationParameters + & $configurationName @configurationParameters - $startDscConfigurationParameters = @{ - Path = $TestDrive - ComputerName = 'localhost' - Wait = $true - Verbose = $true - Force = $true - ErrorAction = 'Stop' - } + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } - Start-DscConfiguration @startDscConfigurationParameters - } | Should -Not -Throw - } + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw } - - Wait-ForIdleLcm -Clear } } -finally -{ - Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} diff --git a/tests/Integration/DSC_DnsServerZoneScope.config.ps1 b/tests/Integration/DSC_DnsServerZoneScope.config.ps1 index 850f3b95..c2705fc5 100644 --- a/tests/Integration/DSC_DnsServerZoneScope.config.ps1 +++ b/tests/Integration/DSC_DnsServerZoneScope.config.ps1 @@ -52,7 +52,6 @@ configuration DSC_DnsServerZoneScope_RemoveZoneScope_Config } } - configuration DSC_DnsServerZoneScope_Cleanup_Config { Import-DscResource -ModuleName 'DnsServerDsc' diff --git a/tests/Unit/Classes/DnsRecordA.tests.ps1 b/tests/Unit/Classes/DnsRecordA.tests.ps1 index bb0ecd9d..b0966216 100644 --- a/tests/Unit/Classes/DnsRecordA.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordA.tests.ps1 @@ -1,123 +1,189 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordA DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordA -Tag 'DnsRecord', 'DnsRecordA' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -InModuleScope $ProjectName { - Describe DnsRecordA -Tag 'DnsRecord', 'DnsRecordA' { - Context 'Constructors' { - It 'Should not throw an exception when instantiated' { { [DnsRecordA]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordA]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordA' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordA' { $instance = [DnsRecordA]::new() $instance.GetType().Name | Should -Be 'DnsRecordA' } } } +} + +Describe 'Testing DnsRecordA Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordA' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordA Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordA' { - BeforeEach { $script:instanceDesiredState = [DnsRecordA] @{ ZoneName = 'contoso.com' Name = 'www' IPv4Address = '192.168.50.10' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.IPv4Address | Should -Be $script:instanceDesiredState.IPv4Address } + } - It 'Should return $false or $null respectively for the rest of the non-key properties' { - $getMethodResourceResult = $script:instanceDesiredState.Get() + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\ARecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\ARecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.IPv4Address | Should -Be $script:instanceDesiredState.IPv4Address } } - } +} - Describe "Testing DnsRecordA Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordA' { - BeforeAll { - } +Describe 'Testing DnsRecordA Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordA' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordA] @{ ZoneName = 'contoso.com' Name = 'www' @@ -128,23 +194,31 @@ InModuleScope $ProjectName { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordA] @{ - ZoneName = 'contoso.com' - Name = 'www' - IPv4Address = '192.168.50.10' - Ensure = [Ensure]::Absent + ZoneName = 'contoso.com' + Name = 'www' + IPv4Address = '192.168.50.10' + Ensure = [Ensure]::Absent } return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordA] @{ ZoneName = 'contoso.com' Name = 'www' @@ -153,25 +227,33 @@ InModuleScope $ProjectName { $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordA] @{ - ZoneName = 'contoso.com' - Name = 'www' - IPv4Address = '192.168.50.10' - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + Name = 'www' + IPv4Address = '192.168.50.10' + Ensure = [Ensure]::Present } return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordA] @{ ZoneName = 'contoso.com' Name = 'www' @@ -182,22 +264,31 @@ InModuleScope $ProjectName { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordA] @{ - ZoneName = 'contoso.com' - Name = 'www' - IPv4Address = '192.168.50.10' - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + Name = 'www' + IPv4Address = '192.168.50.10' + Ensure = [Ensure]::Present } return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordA] @{ ZoneName = 'contoso.com' Name = 'www' @@ -206,22 +297,9 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } - It 'Should return $false when the object is not found' { - #Override Get() method - $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - $mockInstanceCurrentState = [DnsRecordA] @{ - ZoneName = 'contoso.com' - Name = 'www' - IPv4Address = '192.168.50.10' - Ensure = [Ensure]::Absent - } - - return $mockInstanceCurrentState - } - $script:instanceDesiredState.Test() | Should -BeFalse - } - + BeforeDiscovery { $testCasesToFail = @( @{ ZoneName = 'contoso.com' @@ -232,22 +310,37 @@ InModuleScope $ProjectName { Ensure = 'Present' } ) + } - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $Name, - [System.String] $IPv4Address, - [System.String] $TimeToLive - ) + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordA] @{ - ZoneName = $ZoneName - Name = $Name - IPv4Address = $IPv4Address - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + Name = 'www' + IPv4Address = '192.168.50.10' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordA] @{ + ZoneName = $ZoneName + Name = $Name + IPv4Address = $IPv4Address + Ensure = [Ensure]::Present } return $mockInstanceCurrentState @@ -258,42 +351,46 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordA Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordA' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordA Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordA' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\ARecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\ARecordInstance.xml" - # Set a wrong value - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordA] @{ ZoneName = 'contoso.com' Name = 'www' @@ -301,20 +398,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordA] @{ ZoneName = 'contoso.com' Name = 'www' @@ -323,31 +433,44 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return - } + return + } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 { $script:instanceDesiredState.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordAScoped.tests.ps1 b/tests/Unit/Classes/DnsRecordAScoped.tests.ps1 index 9148bb34..085f7f8b 100644 --- a/tests/Unit/Classes/DnsRecordAScoped.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordAScoped.tests.ps1 @@ -1,52 +1,95 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordAScoped DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + Import-Module -Name $script:dscModuleName -InModuleScope $ProjectName { + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} - Describe DnsRecordAScoped -Tag 'DnsRecord', 'DnsRecordAScoped' { +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordAScoped -Tag 'DnsRecord', 'DnsRecordAScoped' { + Context 'Constructors' { + It 'Should not throw an exception when instantiate' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Constructors' { - It 'Should not throw an exception when instantiate' { { [DnsRecordAScoped]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordAScoped]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordAScoped' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordAScoped' { $instance = [DnsRecordAScoped]::new() $instance.GetType().Name | Should -Be 'DnsRecordAScoped' } } } +} + +Describe 'Testing DnsRecordAScoped Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordAScoped' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordAScoped Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordAScoped' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -54,22 +97,31 @@ InModuleScope $ProjectName { IPv4Address = '192.168.50.10' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName @@ -77,51 +129,63 @@ InModuleScope $ProjectName { $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.IPv4Address | Should -Be $script:instanceDesiredState.IPv4Address } + } - It 'Should return $false or $null respectively for the rest of the non-key properties' { - $getMethodResourceResult = $script:instanceDesiredState.Get() + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\ARecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\ARecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.IPv4Address | Should -Be $script:instanceDesiredState.IPv4Address } } - } +} - Describe "Testing DnsRecordAScoped Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordAScoped' { - BeforeAll { - } +Describe 'Testing DnsRecordAScoped Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordAScoped' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -143,14 +207,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -170,16 +242,24 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -201,13 +281,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -217,8 +306,26 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeDiscovery { + $testCasesToFail = @( + @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + Name = 'www' + IPv4Address = '192.168.50.10' + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' + } + ) + } + + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when the object is not found' { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordAScoped] @{ @@ -233,36 +340,20 @@ InModuleScope $ProjectName { } $script:instanceDesiredState.Test() | Should -BeFalse } + } - $testCasesToFail = @( - @{ - ZoneName = 'contoso.com' - ZoneScope = 'external' - Name = 'www' - IPv4Address = '192.168.50.10' - DnsServer = 'localhost' - TimeToLive = '02:00:00' # Undesired - Ensure = 'Present' - } - ) + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $ZoneScope, - [System.String] $Name, - [System.String] $IPv4Address, - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordAScoped] @{ - ZoneName = $ZoneName - ZoneScope = $ZoneScope - Name = $Name - IPv4Address = $IPv4Address - Ensure = [Ensure]::Present + ZoneName = $ZoneName + ZoneScope = $ZoneScope + Name = $Name + IPv4Address = $IPv4Address + Ensure = [Ensure]::Present } return $mockInstanceCurrentState @@ -273,42 +364,46 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordAScoped Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordAScoped' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordAScoped Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordAScoped' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\ARecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\ARecordInstance.xml" - # Set a wrong value - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordAScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -317,20 +412,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordAScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -340,31 +448,44 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return - } + return + } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 { $script:instanceDesiredState.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordAaaa.tests.ps1 b/tests/Unit/Classes/DnsRecordAaaa.tests.ps1 index 9e44aab3..2af0123f 100644 --- a/tests/Unit/Classes/DnsRecordAaaa.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordAaaa.tests.ps1 @@ -1,123 +1,190 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordAaaa DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordAaaa -Tag 'DnsRecord', 'DnsRecordAaaa' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -InModuleScope $ProjectName { - Describe DnsRecordAaaa -Tag 'DnsRecord', 'DnsRecordAaaa' { - Context 'Constructors' { - It 'Should not throw an exception when instantiated' { { [DnsRecordAaaa]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordAaaa]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordAaaa' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordAaaa' { $instance = [DnsRecordAaaa]::new() $instance.GetType().Name | Should -Be 'DnsRecordAaaa' } } } +} + +Describe 'Testing DnsRecordAaaa Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordAaaa' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordAaaa Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordAaaa' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAaaa] @{ ZoneName = 'contoso.com' Name = 'www' IPv6Address = '2001:db8:85a3::8a2e:370:7334' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.IPv6Address | Should -Be $script:instanceDesiredState.IPv6Address } + } - It 'Should return $false or $null respectively for the rest of the non-key properties' { - $getMethodResourceResult = $script:instanceDesiredState.Get() + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\AaaaRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\AaaaRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.IPv6Address | Should -Be $script:instanceDesiredState.IPv6Address } } - } - Describe "Testing DnsRecordAaaa Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordAaaa' { - BeforeAll { - } +} + +Describe 'Testing DnsRecordAaaa Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordAaaa' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAaaa] @{ ZoneName = 'contoso.com' Name = 'www' @@ -128,23 +195,31 @@ InModuleScope $ProjectName { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordAaaa] @{ - ZoneName = 'contoso.com' - Name = 'www' - IPv6Address = '2001:db8:85a3::8a2e:370:7334' - Ensure = [Ensure]::Absent + ZoneName = 'contoso.com' + Name = 'www' + IPv6Address = '2001:db8:85a3::8a2e:370:7334' + Ensure = [Ensure]::Absent } return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAaaa] @{ ZoneName = 'contoso.com' Name = 'www' @@ -153,25 +228,33 @@ InModuleScope $ProjectName { $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordAaaa] @{ - ZoneName = 'contoso.com' - Name = 'www' - IPv6Address = '2001:db8:85a3::8a2e:370:7334' - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + Name = 'www' + IPv6Address = '2001:db8:85a3::8a2e:370:7334' + Ensure = [Ensure]::Present } return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAaaa] @{ ZoneName = 'contoso.com' Name = 'www' @@ -182,22 +265,31 @@ InModuleScope $ProjectName { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordAaaa] @{ - ZoneName = 'contoso.com' - Name = 'www' - IPv6Address = '2001:db8:85a3::8a2e:370:7334' - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + Name = 'www' + IPv6Address = '2001:db8:85a3::8a2e:370:7334' + Ensure = [Ensure]::Present } return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAaaa] @{ ZoneName = 'contoso.com' Name = 'www' @@ -206,22 +298,9 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } - It 'Should return $false when the object is not found' { - #Override Get() method - $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - $mockInstanceCurrentState = [DnsRecordAaaa] @{ - ZoneName = 'contoso.com' - Name = 'www' - IPv6Address = '2001:db8:85a3::8a2e:370:7334' - Ensure = [Ensure]::Absent - } - - return $mockInstanceCurrentState - } - $script:instanceDesiredState.Test() | Should -BeFalse - } - + BeforeDiscovery { $testCasesToFail = @( @{ ZoneName = 'contoso.com' @@ -232,22 +311,38 @@ InModuleScope $ProjectName { Ensure = 'Present' } ) + } + + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $Name, - [System.String] $IPv6Address, - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordAaaa] @{ - ZoneName = $ZoneName - Name = $Name - IPv6Address = $IPv6Address - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + Name = 'www' + IPv6Address = '2001:db8:85a3::8a2e:370:7334' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordAaaa] @{ + ZoneName = $ZoneName + Name = $Name + IPv6Address = $IPv6Address + Ensure = [Ensure]::Present } return $mockInstanceCurrentState @@ -258,42 +353,46 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordAaaa Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordAaaa' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordAaaa Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordAaaa' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\AaaaRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\AaaaRecordInstance.xml" - # Set a wrong value - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordAaaa] @{ ZoneName = 'contoso.com' Name = 'www' @@ -301,20 +400,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordAaaa] @{ ZoneName = 'contoso.com' Name = 'www' @@ -323,31 +435,44 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return - } + return + } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 { $script:instanceDesiredState.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordAaaaScoped.tests.ps1 b/tests/Unit/Classes/DnsRecordAaaaScoped.tests.ps1 index 5588e617..6e8afdf7 100644 --- a/tests/Unit/Classes/DnsRecordAaaaScoped.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordAaaaScoped.tests.ps1 @@ -1,52 +1,95 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordAaaaScoped DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + Import-Module -Name $script:dscModuleName -InModuleScope $ProjectName { + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} - Describe DnsRecordAaaaScoped -Tag 'DnsRecord', 'DnsRecordAaaaScoped' { +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordAaaaScoped -Tag 'DnsRecord', 'DnsRecordAaaaScoped' { + Context 'Constructors' { + It 'Should not throw an exception when instantiate' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Constructors' { - It 'Should not throw an exception when instantiate' { { [DnsRecordAaaaScoped]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordAaaaScoped]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordAaaaScoped' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordAaaaScoped' { $instance = [DnsRecordAaaaScoped]::new() $instance.GetType().Name | Should -Be 'DnsRecordAaaaScoped' } } } +} + +Describe 'Testing DnsRecordAaaaScoped Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordAaaaScoped' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordAaaaScoped Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordAaaaScoped' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAaaaScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -54,22 +97,31 @@ InModuleScope $ProjectName { IPv6Address = '2001:db8:85a3::8a2e:370:7334' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName @@ -77,51 +129,64 @@ InModuleScope $ProjectName { $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.IPv6Address | Should -Be $script:instanceDesiredState.IPv6Address } + } - It 'Should return $false or $null respectively for the rest of the non-key properties' { - $getMethodResourceResult = $script:instanceDesiredState.Get() + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\AaaaRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\AaaaRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.IPv6Address | Should -Be $script:instanceDesiredState.IPv6Address } } - } - Describe "Testing DnsRecordAaaaScoped Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordAaaaScoped' { - BeforeAll { - } +} + +Describe 'Testing DnsRecordAaaaScoped Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordAaaaScoped' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAaaaScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -143,14 +208,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAaaaScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -170,16 +243,24 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAaaaScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -201,13 +282,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordAaaaScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -217,8 +307,26 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeDiscovery { + $testCasesToFail = @( + @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + Name = 'www' + IPv6Address = '2001:db8:85a3::8a2e:370:7334' + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' + } + ) + } + + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when the object is not found' { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordAaaaScoped] @{ @@ -233,36 +341,20 @@ InModuleScope $ProjectName { } $script:instanceDesiredState.Test() | Should -BeFalse } + } - $testCasesToFail = @( - @{ - ZoneName = 'contoso.com' - ZoneScope = 'external' - Name = 'www' - IPv6Address = '2001:db8:85a3::8a2e:370:7334' - DnsServer = 'localhost' - TimeToLive = '02:00:00' # Undesired - Ensure = 'Present' - } - ) + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $ZoneScope, - [System.String] $Name, - [System.String] $IPv6Address, - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordAaaaScoped] @{ - ZoneName = $ZoneName - ZoneScope = $ZoneScope - Name = $Name - IPv6Address = $IPv6Address - Ensure = [Ensure]::Present + ZoneName = $ZoneName + ZoneScope = $ZoneScope + Name = $Name + IPv6Address = $IPv6Address + Ensure = [Ensure]::Present } return $mockInstanceCurrentState @@ -273,42 +365,46 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordAaaaScoped Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordAaaaScoped' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordAaaaScoped Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordAaaaScoped' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\AaaaRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\AaaaRecordInstance.xml" - # Set a wrong value - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordAaaaScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -317,20 +413,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordAaaaScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -340,31 +449,44 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return - } + return + } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 { $script:instanceDesiredState.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordBase.tests.ps1 b/tests/Unit/Classes/DnsRecordBase.tests.ps1 index f9879d5d..698053c0 100644 --- a/tests/Unit/Classes/DnsRecordBase.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordBase.tests.ps1 @@ -1,113 +1,205 @@ +<# + .SYNOPSIS + Unit test for DnsRecordBase. +#> <# Must have this for the test to work where it creates a class that inherits from the DnsRecordBase class. #> using module DnsServerDsc -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force +} + +Describe DnsRecordBase { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -InModuleScope $ProjectName { - Describe DnsRecordBase { - Context 'Constructors' { - It 'Should not throw an exception when instantiated' { { [DnsRecordBase]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordBase]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordBase' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordBase' { $instance = [DnsRecordBase]::new() $instance.GetType().Name | Should -Be 'DnsRecordBase' } } + } + + Context 'Unimplemented methods' { + It 'Should throw when GetResourceRecord() is called' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Unimplemented methods' { - It 'Should throw when GetResourceRecord() is called' { { $instance = [DnsRecordBase]::new().GetResourceRecord() } | Should -Throw } + } + + It 'Should throw when AddResourceRecord() is called' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should throw when AddResourceRecord() is called' { { $instance = [DnsRecordBase]::new().AddResourceRecord() } | Should -Throw } + } + + It 'Should throw when ModifyResourceRecord(...) is called' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should throw when ModifyResourceRecord(...) is called' { { $instance = [DnsRecordBase]::new().ModifyResourceRecord($null, $null) } | Should -Throw } + } + + It 'Should throw when NewDscResourceObjectFromRecord(...) is called' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should throw when NewDscResourceObjectFromRecord(...) is called' { { $instance = [DnsRecordBase]::new().NewDscResourceObjectFromRecord($null) } | Should -Throw } } } +} - Describe 'Testing DnsRecordBase Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordBase' { - Context 'Testing abstract functionality' { - BeforeAll { - $script:instanceDesiredState = [DnsRecordBase]::new() - $script:instanceDesiredState.ZoneName = 'contoso.com' - $script:instanceDesiredState.TimeToLive = '1:00:00' - $script:instanceDesiredState.DnsServer = 'localhost' - $script:instanceDesiredState.Ensure = 'Present' +Describe 'Testing DnsRecordBase Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordBase' { + Context 'Testing abstract functionality' { + BeforeAll { + $instanceDesiredState = [DnsRecordBase] @{ + ZoneName = 'contoso.com' + TimeToLive = '1:00:00' + DnsServer = 'localhost' + Ensure = 'Present' } + } + + It 'Should throw when Get() is called' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should throw when Get() is called' { { $script:instanceDesiredState.Get() } | Should -Throw } } + } - Context 'Testing $null value passed to Set()' { - BeforeAll { - $script:instanceDesiredState = [DnsRecordBase]::new() - $script:instanceDesiredState.ZoneName = 'contoso.com' - $script:instanceDesiredState.TimeToLive = $null - $script:instanceDesiredState.DnsServer = 'localhost' - $script:instanceDesiredState.Ensure = 'Present' + Context 'Testing $null value passed to Set()' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:instanceDesiredState = [DnsRecordBase] @{ + ZoneName = 'contoso.com' + TimeToLive = $null + DnsServer = 'localhost' + Ensure = 'Present' + } } + } + + It 'Should throw when Set() is called' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should throw when Set() is called' { { $script:instanceDesiredState.Set() } | Should -Throw } } + } + + Context 'Testing subclassed (implemented) functionality' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Testing subclassed (implemented) functionality' { - BeforeAll { class MockRecordDoesNotExist : DnsRecordBase { - [System.String] GetResourceRecord() { + MockRecordDoesNotExist () + { + } + + [System.String] GetResourceRecord() + { return (Invoke-Command {}) } } - $script:instanceDesiredState = [MockRecordDoesNotExist]::new() - $script:instanceDesiredState.ZoneName = 'contoso.com' - $script:instanceDesiredState.TimeToLive = '1:00:00' - $script:instanceDesiredState.DnsServer = 'localhost' - $script:instanceDesiredState.Ensure = 'Present' + $script:instanceDesiredState = [MockRecordDoesNotExist] @{ + ZoneName = 'contoso.com' + TimeToLive = '1:00:00' + DnsServer = 'localhost' + Ensure = 'Present' + } } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $script:instanceDesiredState.Get().Ensure | Should -Be 'Absent' } + } + + It 'Should return the same values as present in properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the same values as present in properties' { $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName @@ -115,152 +207,271 @@ InModuleScope $ProjectName { $getMethodResourceResult.DnsServer | Should -Be $script:instanceDesiredState.DnsServer } } - } - Describe 'Testing DnsRecordBase Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordBase' { - Context 'Testing abstract functionality' { - BeforeAll { +} + +Describe 'Testing DnsRecordBase Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordBase' { + Context 'Testing abstract functionality' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState = [DnsRecordBase] @{ - ZoneName = 'contoso.com' + ZoneName = 'contoso.com' TimeToLive = '1:00:00' - DnsServer = 'localhost' - Ensure = 'Present' + DnsServer = 'localhost' + Ensure = 'Present' } } + } + + It 'Should throw when Set() is called' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should throw when Set() is called' { { $script:instanceDesiredState.Set() } | Should -Throw } } + } + + Context 'Testing subclassed (implemented) functionality' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Testing subclassed (implemented) functionality' { - BeforeAll { class MockRecordDoesNotExist : DnsRecordBase { - [System.String] GetResourceRecord() { + MockRecordDoesNotExist () + { + } + + [System.String] GetResourceRecord() + { Write-Verbose 'Mock subclassed GetResourceRecord()' return (Invoke-Command {}) } - [void] AddResourceRecord() { + [void] AddResourceRecord() + { Write-Verbose 'Mock subclassed AddResourceRecord()' } } $script:instanceDesiredState = [MockRecordDoesNotExist] @{ - ZoneName = 'contoso.com' + ZoneName = 'contoso.com' TimeToLive = '1:00:00' - DnsServer = 'localhost' - Ensure = 'Present' + DnsServer = 'localhost' + Ensure = 'Present' } } + } + + It 'Should execute without error' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should execute without error' { { $script:instanceDesiredState.Set() } | Should -Not -Throw } } } +} + +Describe 'Testing DnsRecordBase Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordBase' { + Context 'Testing abstract functionality' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe 'Testing DnsRecordBase Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordBase' { - Context 'Testing abstract functionality' { - BeforeAll { $script:instanceDesiredState = [DnsRecordBase] @{ - ZoneName = 'contoso.com' + ZoneName = 'contoso.com' TimeToLive = '1:00:00' - DnsServer = 'localhost' - Ensure = 'Present' + DnsServer = 'localhost' + Ensure = 'Present' } } + } + + It 'Should throw when Test() is called' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should throw when Test() is called' { { $script:instanceDesiredState.Test() } | Should -Throw } } + } - Context 'Testing subclassed (implemented) functionality' { + Context 'Testing subclassed (implemented) functionality' { + Context 'When the system is in the desired state' { BeforeAll { - class MockRecordExists : DnsRecordBase - { - [System.String] GetResourceRecord() { - Write-Verbose 'Mock subclassed GetResourceRecord()' - return "Not Null Value" - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - [MockRecordExists] NewDscResourceObjectFromRecord($record) { - Write-Verbose 'Mock subclassed NewDscResourceObjectFromRecord()' - return [MockRecordExists] @{ - ZoneName = 'contoso.com' - TimeToLive = '1:00:00' - DnsServer = 'localhost' - Ensure = 'Present' + class MockRecordExists : DnsRecordBase + { + MockRecordExists () + { } + + [System.String] GetResourceRecord() + { + Write-Verbose 'Mock subclassed GetResourceRecord()' + return 'Not Null Value' + } + + [MockRecordExists] NewDscResourceObjectFromRecord($record) + { + Write-Verbose 'Mock subclassed NewDscResourceObjectFromRecord()' + return [MockRecordExists] @{ + ZoneName = 'contoso.com' + TimeToLive = '1:00:00' + DnsServer = 'localhost' + Ensure = 'Present' + } + } + } + + $script:instanceDesiredStateExists = [MockRecordExists] @{ + ZoneName = 'contoso.com' + TimeToLive = '1:00:00' + DnsServer = 'localhost' + Ensure = 'Present' } } } - Context 'When the system is in the desired state' { - Context 'When enforcing all non-mandatory parameters' { - BeforeAll { - $script:instanceDesiredStateExists = [MockRecordExists] @{ - ZoneName = 'contoso.com' - TimeToLive = '1:00:00' - DnsServer = 'localhost' - Ensure = 'Present' - } - } + Context 'When enforcing all non-mandatory parameters' { + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredStateExists.Test() | Should -BeTrue } } + } + + Context 'When no non-mandatory parameters are enforced' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + class MockRecordExists : DnsRecordBase + { + MockRecordExists () + { + } + + [System.String] GetResourceRecord() + { + Write-Verbose 'Mock subclassed GetResourceRecord()' + return 'Not Null Value' + } + + [MockRecordExists] NewDscResourceObjectFromRecord($record) + { + Write-Verbose 'Mock subclassed NewDscResourceObjectFromRecord()' + return [MockRecordExists] @{ + ZoneName = 'contoso.com' + TimeToLive = '1:00:00' + DnsServer = 'localhost' + Ensure = 'Present' + } + } + } - Context 'When no non-mandatory parameters are enforced' { - BeforeAll { $script:instanceDesiredStateExists = [MockRecordExists] @{ ZoneName = 'contoso.com' } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredStateExists.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When a DNS record should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When a DNS record should be present' { - BeforeAll { class MockRecordDoesNotExist : DnsRecordBase { - [System.String] GetResourceRecord() { + MockRecordDoesNotExist () + { + } + + [System.String] GetResourceRecord() + { Write-Verbose 'Mock subclassed GetResourceRecord()' return (Invoke-Command {}) } } $script:instanceDesiredStateDNE = [MockRecordDoesNotExist] @{ - ZoneName = 'contoso.com' + ZoneName = 'contoso.com' TimeToLive = '1:00:00' - DnsServer = 'localhost' - Ensure = 'Present' + DnsServer = 'localhost' + Ensure = 'Present' } } + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false' { $script:instanceDesiredStateDNE.Test() | Should -BeFalse } } + } + + Context 'When a non-mandatory property is not in desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + class MockRecordExists : DnsRecordBase + { + MockRecordExists () + { + } + + [System.String] GetResourceRecord() + { + Write-Verbose 'Mock subclassed GetResourceRecord()' + return 'Not Null Value' + } + + [MockRecordExists] NewDscResourceObjectFromRecord($record) + { + Write-Verbose 'Mock subclassed NewDscResourceObjectFromRecord()' + return [MockRecordExists] @{ + ZoneName = 'contoso.com' + TimeToLive = '1:00:00' + DnsServer = 'localhost' + Ensure = 'Present' + } + } + } - Context 'When a non-mandatory property is not in desired state' { - BeforeAll { $script:instanceDesiredStateExists = [MockRecordExists] @{ - ZoneName = 'contoso.com' + ZoneName = 'contoso.com' TimeToLive = '2:00:00' } } + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false' { $script:instanceDesiredStateExists.Test() | Should -BeFalse } } diff --git a/tests/Unit/Classes/DnsRecordCname.tests.ps1 b/tests/Unit/Classes/DnsRecordCname.tests.ps1 index e341871a..a107308e 100644 --- a/tests/Unit/Classes/DnsRecordCname.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordCname.tests.ps1 @@ -1,123 +1,190 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordCname DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordCname -Tag 'DnsRecord', 'DnsRecordCname' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -InModuleScope $ProjectName { - Describe DnsRecordCname -Tag 'DnsRecord', 'DnsRecordCname' { - Context 'Constructors' { - It 'Should not throw an exception when instantiated' { { [DnsRecordCname]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordCname]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordCname' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordCname' { $instance = [DnsRecordCname]::new() $instance.GetType().Name | Should -Be 'DnsRecordCname' } } } +} + +Describe 'Testing DnsRecordCname Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordCname' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordCname Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordCname' { - BeforeEach { $script:instanceDesiredState = [DnsRecordCname] @{ ZoneName = 'contoso.com' Name = 'bar' HostNameAlias = 'quarks.contoso.com' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.HostNameAlias | Should -Be $script:instanceDesiredState.HostNameAlias } + } - It 'Should return $false or $null respectively for the rest of the non-key properties' { - $getMethodResourceResult = $script:instanceDesiredState.Get() + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\CnameRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\CnameRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.HostNameAlias | Should -Be $script:instanceDesiredState.HostNameAlias } } - } - Describe "Testing DnsRecordCname Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordCname' { - BeforeAll { - } +} + +Describe 'Testing DnsRecordCname Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordCname' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordCname] @{ ZoneName = 'contoso.com' Name = 'bar' @@ -128,23 +195,31 @@ InModuleScope $ProjectName { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordCname] @{ - ZoneName = 'contoso.com' - Name = 'bar' - HostNameAlias = 'quarks.contoso.com' - Ensure = [Ensure]::Absent + ZoneName = 'contoso.com' + Name = 'bar' + HostNameAlias = 'quarks.contoso.com' + Ensure = [Ensure]::Absent } return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordCname] @{ ZoneName = 'contoso.com' Name = 'bar' @@ -153,25 +228,33 @@ InModuleScope $ProjectName { $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordCname] @{ - ZoneName = 'contoso.com' - Name = 'bar' - HostNameAlias = 'quarks.contoso.com' - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + Name = 'bar' + HostNameAlias = 'quarks.contoso.com' + Ensure = [Ensure]::Present } return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordCname] @{ ZoneName = 'contoso.com' Name = 'bar' @@ -182,22 +265,31 @@ InModuleScope $ProjectName { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordCname] @{ - ZoneName = 'contoso.com' - Name = 'bar' - HostNameAlias = 'quarks.contoso.com' - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + Name = 'bar' + HostNameAlias = 'quarks.contoso.com' + Ensure = [Ensure]::Present } return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordCname] @{ ZoneName = 'contoso.com' Name = 'bar' @@ -206,22 +298,9 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } - It 'Should return $false when the object is not found' { - #Override Get() method - $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - $mockInstanceCurrentState = [DnsRecordCname] @{ - ZoneName = 'contoso.com' - Name = 'bar' - HostNameAlias = 'quarks.contoso.com' - Ensure = [Ensure]::Absent - } - - return $mockInstanceCurrentState - } - $script:instanceDesiredState.Test() | Should -BeFalse - } - + BeforeDiscovery { $testCasesToFail = @( @{ ZoneName = 'contoso.com' @@ -232,22 +311,38 @@ InModuleScope $ProjectName { Ensure = 'Present' } ) + } + + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordCname] @{ + ZoneName = 'contoso.com' + Name = 'bar' + HostNameAlias = 'quarks.contoso.com' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $Name, - [System.String] $HostNameAlias, - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordCname] @{ - ZoneName = $ZoneName - Name = $Name - HostNameAlias = $HostNameAlias - Ensure = [Ensure]::Present + ZoneName = $ZoneName + Name = $Name + HostNameAlias = $HostNameAlias + Ensure = [Ensure]::Present } return $mockInstanceCurrentState @@ -258,42 +353,46 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordCname Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordCname' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordCname Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordCname' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\CnameRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\CnameRecordInstance.xml" - # Set a wrong value - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordCname] @{ ZoneName = 'contoso.com' Name = 'bar' @@ -301,20 +400,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordCname] @{ ZoneName = 'contoso.com' Name = 'bar' @@ -323,31 +435,45 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } - return - } + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - { $script:instanceDesiredState.Set() } | Should -Not -Throw + return + } + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordCnameScoped.tests.ps1 b/tests/Unit/Classes/DnsRecordCnameScoped.tests.ps1 index 45f7ec04..ee4872f9 100644 --- a/tests/Unit/Classes/DnsRecordCnameScoped.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordCnameScoped.tests.ps1 @@ -1,52 +1,95 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordCnameScoped DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + Import-Module -Name $script:dscModuleName -InModuleScope $ProjectName { + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} - Describe DnsRecordCnameScoped -Tag 'DnsRecord', 'DnsRecordCnameScoped' { +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordCnameScoped -Tag 'DnsRecord', 'DnsRecordCnameScoped' { + Context 'Constructors' { + It 'Should not throw an exception when instantiate' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Constructors' { - It 'Should not throw an exception when instantiate' { { [DnsRecordCnameScoped]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordCnameScoped]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordCnameScoped' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordCnameScoped' { $instance = [DnsRecordCnameScoped]::new() $instance.GetType().Name | Should -Be 'DnsRecordCnameScoped' } } } +} + +Describe 'Testing DnsRecordCnameScoped Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordCnameScoped' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordCnameScoped Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordCnameScoped' { - BeforeEach { $script:instanceDesiredState = [DnsRecordCnameScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -54,22 +97,31 @@ InModuleScope $ProjectName { HostNameAlias = 'quarks.contoso.com' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName @@ -77,51 +129,63 @@ InModuleScope $ProjectName { $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.HostNameAlias | Should -Be $script:instanceDesiredState.HostNameAlias } + } - It 'Should return $false or $null respectively for the rest of the non-key properties' { - $getMethodResourceResult = $script:instanceDesiredState.Get() + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\CnameRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\CnameRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the same values as present in Key properties' { $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.HostNameAlias | Should -Be $script:instanceDesiredState.HostNameAlias } } - } - Describe "Testing DnsRecordCnameScoped Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordCnameScoped' { - BeforeAll { - } +} + +Describe 'Testing DnsRecordCnameScoped Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordCnameScoped' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordCnameScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -143,14 +207,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordCnameScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -170,16 +242,24 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordCnameScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -201,13 +281,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordCnameScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -217,8 +306,26 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeDiscovery { + $testCasesToFail = @( + @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + Name = 'bar' + HostNameAlias = 'quarks.contoso.com' + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' + } + ) + } + + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when the object is not found' { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordCnameScoped] @{ @@ -233,36 +340,19 @@ InModuleScope $ProjectName { } $script:instanceDesiredState.Test() | Should -BeFalse } + } - $testCasesToFail = @( - @{ - ZoneName = 'contoso.com' - ZoneScope = 'external' - Name = 'bar' - HostNameAlias = 'quarks.contoso.com' - DnsServer = 'localhost' - TimeToLive = '02:00:00' # Undesired - Ensure = 'Present' - } - ) - - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $ZoneScope, - [System.String] $Name, - [System.String] $HostNameAlias, - [System.String] $TimeToLive - ) + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordCnameScoped] @{ - ZoneName = $ZoneName - ZoneScope = $ZoneScope - Name = $Name - HostNameAlias = $HostNameAlias - Ensure = [Ensure]::Present + ZoneName = $ZoneName + ZoneScope = $ZoneScope + Name = $Name + HostNameAlias = $HostNameAlias + Ensure = [Ensure]::Present } return $mockInstanceCurrentState @@ -273,42 +363,46 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordCnameScoped Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordCnameScoped' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordCnameScoped Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordCnameScoped' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\CnameRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\CnameRecordInstance.xml" - # Set a wrong value - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordCnameScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -317,20 +411,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordCnameScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -340,31 +447,44 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return - } + return + } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 { $script:instanceDesiredState.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordMx.tests.ps1 b/tests/Unit/Classes/DnsRecordMx.tests.ps1 index 650c74d8..a0247eaf 100644 --- a/tests/Unit/Classes/DnsRecordMx.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordMx.tests.ps1 @@ -1,80 +1,138 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordMx DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordMx -Tag 'DnsRecord', 'DnsRecordMx' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -InModuleScope $ProjectName { - Describe DnsRecordMx -Tag 'DnsRecord', 'DnsRecordMx' { - Context 'Constructors' { - It 'Should not throw an exception when instantiated' { { [DnsRecordMx]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordMx]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordMx' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordMx' { $instance = [DnsRecordMx]::new() $instance.GetType().Name | Should -Be 'DnsRecordMx' } } } +} + +Describe 'Testing DnsRecordMx Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordMx' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordMx Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordMx' { - BeforeEach { $script:instanceDesiredState = [DnsRecordMx] @{ ZoneName = 'contoso.com' EmailDomain = 'contoso.com' MailExchange = 'mailserver1.contoso.com' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName $getMethodResourceResult.EmailDomain | Should -Be $script:instanceDesiredState.EmailDomain $getMethodResourceResult.MailExchange | Should -Be $script:instanceDesiredState.MailExchange } + } + + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false or $null respectively for the rest of the non-key properties' { $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Priority | Should -Be 0 @@ -82,46 +140,60 @@ InModuleScope $ProjectName { $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\MxRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\MxRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.EmailDomain | Should -Be $script:instanceDesiredState.EmailDomain $getMethodResourceResult.MailExchange | Should -Be $script:instanceDesiredState.MailExchange } } + } + + It 'Should throw when the zone name and email domain do not match' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It "Should throw when the zone name and email domain do not match" { - $script:instanceDesiredState.EmailDomain = "adventureworks.com" + $script:instanceDesiredState.EmailDomain = 'adventureworks.com' { $script:instanceDesiredState.Get() } | Should -Throw } } +} - Describe "Testing DnsRecordMx Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordMx' { - BeforeAll { - } +Describe 'Testing DnsRecordMx Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordMx' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordMx] @{ ZoneName = 'contoso.com' EmailDomain = 'contoso.com' @@ -133,24 +205,32 @@ InModuleScope $ProjectName { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordMx] @{ - ZoneName = 'contoso.com' - EmailDomain = 'contoso.com' - MailExchange = 'mailserver1.contoso.com' - Priority = 20 - Ensure = [Ensure]::Absent + ZoneName = 'contoso.com' + EmailDomain = 'contoso.com' + MailExchange = 'mailserver1.contoso.com' + Priority = 20 + Ensure = [Ensure]::Absent } return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordMx] @{ ZoneName = 'contoso.com' EmailDomain = 'contoso.com' @@ -160,26 +240,34 @@ InModuleScope $ProjectName { $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordMx] @{ - ZoneName = 'contoso.com' - EmailDomain = 'contoso.com' - MailExchange = 'mailserver1.contoso.com' - Priority = 20 - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + EmailDomain = 'contoso.com' + MailExchange = 'mailserver1.contoso.com' + Priority = 20 + Ensure = [Ensure]::Present } return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordMx] @{ ZoneName = 'contoso.com' EmailDomain = 'contoso.com' @@ -191,23 +279,32 @@ InModuleScope $ProjectName { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordMx] @{ - ZoneName = 'contoso.com' - EmailDomain = 'contoso.com' - MailExchange = 'mailserver1.contoso.com' - Priority = 20 - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + EmailDomain = 'contoso.com' + MailExchange = 'mailserver1.contoso.com' + Priority = 20 + Ensure = [Ensure]::Present } return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordMx] @{ ZoneName = 'contoso.com' EmailDomain = 'contoso.com' @@ -217,23 +314,9 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } - It 'Should return $false when the object is not found' { - #Override Get() method - $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - $mockInstanceCurrentState = [DnsRecordMx] @{ - ZoneName = 'contoso.com' - EmailDomain = 'contoso.com' - MailExchange = 'mailserver1.contoso.com' - Priority = 20 - Ensure = [Ensure]::Absent - } - - return $mockInstanceCurrentState - } - $script:instanceDesiredState.Test() | Should -BeFalse - } - + BeforeDiscovery { $testCasesToFail = @( @{ ZoneName = 'contoso.com' @@ -242,8 +325,8 @@ InModuleScope $ProjectName { Priority = 200 # Undesired DnsServer = 'localhost' TimeToLive = '01:00:00' - Ensure = [Ensure]::Present - }, @{ + Ensure = 'Present' + }, @{ ZoneName = 'contoso.com' EmailDomain = 'contoso.com' MailExchange = 'mailserver1.contoso.com' @@ -253,24 +336,40 @@ InModuleScope $ProjectName { Ensure = 'Present' } ) + } + + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $EmailDomain, - [System.String] $MailExchange, - [System.UInt16] $Priority, - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordMx] @{ - ZoneName = $ZoneName - EmailDomain = $EmailDomain - MailExchange = $MailExchange - Priority = $Priority - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + EmailDomain = 'contoso.com' + MailExchange = 'mailserver1.contoso.com' + Priority = 20 + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordMx] @{ + ZoneName = $ZoneName + EmailDomain = $EmailDomain + MailExchange = $MailExchange + Priority = $Priority + Ensure = [Ensure]::Present } return $mockInstanceCurrentState @@ -281,43 +380,47 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordMx Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordMx' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordMx Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordMx' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\MxRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\MxRecordInstance.xml" - # Set wrong values - $mockRecord.RecordData.Preference = 200 - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set wrong values + $mockRecord.RecordData.Preference = 200 + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordMx] @{ ZoneName = 'contoso.com' EmailDomain = 'contoso.com' @@ -326,20 +429,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordMx] @{ ZoneName = 'contoso.com' EmailDomain = 'contoso.com' @@ -349,31 +465,44 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return - } + return + } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 { $script:instanceDesiredState.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordMxScoped.tests.ps1 b/tests/Unit/Classes/DnsRecordMxScoped.tests.ps1 index b799350f..e19c2758 100644 --- a/tests/Unit/Classes/DnsRecordMxScoped.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordMxScoped.tests.ps1 @@ -1,52 +1,95 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordMxScoped DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} -InModuleScope $ProjectName { +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') - Describe DnsRecordMxScoped -Tag 'DnsRecord', 'DnsRecordMxScoped' { + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordMxScoped -Tag 'DnsRecord', 'DnsRecordMxScoped' { + Context 'Constructors' { + It 'Should not throw an exception when instantiate' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Constructors' { - It 'Should not throw an exception when instantiate' { { [DnsRecordMxScoped]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordMxScoped]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordMxScoped' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordMxScoped' { $instance = [DnsRecordMxScoped]::new() $instance.GetType().Name | Should -Be 'DnsRecordMxScoped' } } } +} + +Describe 'Testing DnsRecordMxScoped Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordMxScoped' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordMxScoped Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordMxScoped' { - BeforeEach { $script:instanceDesiredState = [DnsRecordMxScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -54,22 +97,31 @@ InModuleScope $ProjectName { MailExchange = 'mailserver1.contoso.com' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName @@ -77,8 +129,12 @@ InModuleScope $ProjectName { $getMethodResourceResult.EmailDomain | Should -Be $script:instanceDesiredState.EmailDomain $getMethodResourceResult.MailExchange | Should -Be $script:instanceDesiredState.MailExchange } + } + + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false or $null respectively for the rest of the non-key properties' { $getMethodResourceResult = $script:instanceDesiredState.Get() [System.Boolean] $getMethodResourceResult.Priority | Should -BeFalse @@ -86,42 +142,51 @@ InModuleScope $ProjectName { $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\MxRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\MxRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.EmailDomain | Should -Be $script:instanceDesiredState.EmailDomain $getMethodResourceResult.MailExchange | Should -Be $script:instanceDesiredState.MailExchange } } - } +} - Describe "Testing DnsRecordMxScoped Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordMxScoped' { - BeforeAll { - } +Describe 'Testing DnsRecordMxScoped Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordMxScoped' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordMxScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -145,14 +210,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordMxScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -174,16 +247,24 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordMxScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -207,13 +288,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordMxScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -224,24 +314,9 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } - It 'Should return $false when the object is not found' { - #Override Get() method - $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - $mockInstanceCurrentState = [DnsRecordMxScoped] @{ - ZoneName = 'contoso.com' - ZoneScope = 'external' - EmailDomain = 'contoso.com' - MailExchange = 'mailserver1.contoso.com' - Priority = 20 - Ensure = [Ensure]::Absent - } - - return $mockInstanceCurrentState - } - $script:instanceDesiredState.Test() | Should -BeFalse - } - + BeforeDiscovery { $testCasesToFail = @( @{ ZoneName = 'contoso.com' @@ -251,8 +326,8 @@ InModuleScope $ProjectName { Priority = 200 # Undesired DnsServer = 'localhost' TimeToLive = '01:00:00' - Ensure = [Ensure]::Present - }, @{ + Ensure = 'Present' + }, @{ ZoneName = 'contoso.com' ZoneScope = 'external' EmailDomain = 'contoso.com' @@ -263,26 +338,42 @@ InModuleScope $ProjectName { Ensure = 'Present' } ) + } + + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $ZoneScope, - [System.String] $EmailDomain, - [System.String] $MailExchange, - [System.UInt16] $Priority, - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordMxScoped] @{ - ZoneName = $ZoneName - ZoneScope = $ZoneScope - EmailDomain = $EmailDomain - MailExchange = $MailExchange - Priority = $Priority - Ensure = [Ensure]::Present + ZoneName = 'contoso.com' + ZoneScope = 'external' + EmailDomain = 'contoso.com' + MailExchange = 'mailserver1.contoso.com' + Priority = 20 + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordMxScoped] @{ + ZoneName = $ZoneName + ZoneScope = $ZoneScope + EmailDomain = $EmailDomain + MailExchange = $MailExchange + Priority = $Priority + Ensure = [Ensure]::Present } return $mockInstanceCurrentState @@ -293,43 +384,47 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordMxScoped Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordMxScoped' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordMxScoped Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordMxScoped' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\MxRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\MxRecordInstance.xml" - # Set wrong values - $mockRecord.RecordData.Preference = 200 - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set wrong values + $mockRecord.RecordData.Preference = 200 + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordMxScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -339,20 +434,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordMxScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -363,31 +471,44 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return - } + return + } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 { $script:instanceDesiredState.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } - } - Assert-VerifiableMock + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + } + + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordNs.tests.ps1 b/tests/Unit/Classes/DnsRecordNs.tests.ps1 index 18a85184..7098b782 100644 --- a/tests/Unit/Classes/DnsRecordNs.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordNs.tests.ps1 @@ -1,127 +1,197 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordNs DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordNs -Tag 'DnsRecord', 'DnsRecordNs' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -InModuleScope $ProjectName { - Describe DnsRecordNs -Tag 'DnsRecord', 'DnsRecordNs' { - Context 'Constructors' { - It 'Should not throw an exception when instantiated' { { [DnsRecordNs]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordNs]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordNs' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordNs' { $instance = [DnsRecordNs]::new() $instance.GetType().Name | Should -Be 'DnsRecordNs' } } } +} + +Describe 'Testing DnsRecordNs Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordNs' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordNs Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordNs' { - BeforeEach { $script:instanceDesiredState = [DnsRecordNs] @{ ZoneName = 'contoso.com' DomainName = 'contoso.com' NameServer = 'ns.contoso.com' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName $getMethodResourceResult.DomainName | Should -Be $script:instanceDesiredState.DomainName $getMethodResourceResult.NameServer | Should -Be $script:instanceDesiredState.NameServer } + } - It 'Should return $false or $null respectively for the rest of the non-key properties' { + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 $getMethodResourceResult = $script:instanceDesiredState.Get() - $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.DomainName | Should -Be $script:instanceDesiredState.DomainName $getMethodResourceResult.NameServer | Should -Be $script:instanceDesiredState.NameServer } } + } + + It 'Should throw when the zone name and domain name do not match' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It "Should throw when the zone name and domain name do not match" { - $script:instanceDesiredState.DomainName = "adventureworks.com" + $script:instanceDesiredState.DomainName = 'adventureworks.com' { $script:instanceDesiredState.getRecordName() } | Should -Throw } } +} - Describe "Testing DnsRecordNs Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordNs' { - BeforeAll { - } +Describe 'Testing DnsRecordNs Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordNs' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordNs] @{ ZoneName = 'contoso.com' DomainName = 'contoso.com' @@ -141,14 +211,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordNs] @{ ZoneName = 'contoso.com' DomainName = 'contoso.com' @@ -166,16 +244,24 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordNs] @{ ZoneName = 'contoso.com' DomainName = 'contoso.com' @@ -195,13 +281,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordNs] @{ ZoneName = 'contoso.com' DomainName = 'contoso.com' @@ -210,8 +305,25 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeDiscovery { + $testCasesToFail = @( + @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' + } + ) + } + + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when the object is not found' { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordNs] @{ @@ -225,26 +337,12 @@ InModuleScope $ProjectName { } $script:instanceDesiredState.Test() | Should -BeFalse } + } - $testCasesToFail = @( - @{ - ZoneName = 'contoso.com' - DomainName = 'contoso.com' - NameServer = 'ns.contoso.com' - DnsServer = 'localhost' - TimeToLive = '02:00:00' # Undesired - Ensure = 'Present' - } - ) + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $DomainName, - [System.String] $NameServer, - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordNs] @{ @@ -262,42 +360,46 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordNs Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordNs' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordNs Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordNs' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" - # Set a wrong value - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordNs] @{ ZoneName = 'contoso.com' DomainName = 'contoso.com' @@ -305,20 +407,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordNs] @{ ZoneName = 'contoso.com' DomainName = 'contoso.com' @@ -327,31 +442,45 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } - return - } + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - { $script:instanceDesiredState.Set() } | Should -Not -Throw + return + } + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordNsScoped.tests.ps1 b/tests/Unit/Classes/DnsRecordNsScoped.tests.ps1 index 365e7749..e38d5b86 100644 --- a/tests/Unit/Classes/DnsRecordNsScoped.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordNsScoped.tests.ps1 @@ -1,52 +1,95 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordNsScoped DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force -InModuleScope $ProjectName { + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') - Describe DnsRecordNsScoped -Tag 'DnsRecord', 'DnsRecordNsScoped' { + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordNsScoped -Tag 'DnsRecord', 'DnsRecordNsScoped' { + Context 'Constructors' { + It 'Should not throw an exception when instantiate' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Constructors' { - It 'Should not throw an exception when instantiate' { { [DnsRecordNsScoped]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordNsScoped]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordNsScoped' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordNsScoped' { $instance = [DnsRecordNsScoped]::new() $instance.GetType().Name | Should -Be 'DnsRecordNsScoped' } } } +} + +Describe 'Testing DnsRecordNsScoped Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordNsScoped' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordNsScoped Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordNsScoped' { - BeforeEach { $script:instanceDesiredState = [DnsRecordNsScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -54,22 +97,31 @@ InModuleScope $ProjectName { NameServer = 'ns.contoso.com' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName @@ -77,51 +129,64 @@ InModuleScope $ProjectName { $getMethodResourceResult.DomainName | Should -Be $script:instanceDesiredState.DomainName $getMethodResourceResult.NameServer | Should -Be $script:instanceDesiredState.NameServer } + } - It 'Should return $false or $null respectively for the rest of the non-key properties' { - $getMethodResourceResult = $script:instanceDesiredState.Get() + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.DomainName | Should -Be $script:instanceDesiredState.DomainName $getMethodResourceResult.NameServer | Should -Be $script:instanceDesiredState.NameServer } } - } - Describe "Testing DnsRecordNsScoped Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordNsScoped' { - BeforeAll { - } +} + +Describe 'Testing DnsRecordNsScoped Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordNsScoped' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordNsScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -143,14 +208,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordNsScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -170,16 +243,24 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordNsScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -201,13 +282,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordNsScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -217,52 +307,53 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } - - It 'Should return $false when the object is not found' { - #Override Get() method - $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - $mockInstanceCurrentState = [DnsRecordNsScoped] @{ + BeforeDiscovery { + $testCasesToFail = @( + @{ ZoneName = 'contoso.com' ZoneScope = 'external' DomainName = 'contoso.com' NameServer = 'ns.contoso.com' - Ensure = [Ensure]::Absent + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' } + ) + } - return $mockInstanceCurrentState + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse } - $script:instanceDesiredState.Test() | Should -BeFalse } + } + + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCasesToFail = @( - @{ - ZoneName = 'contoso.com' - ZoneScope = 'external' - DomainName = 'contoso.com' - NameServer = 'ns.contoso.com' - DnsServer = 'localhost' - TimeToLive = '02:00:00' # Undesired - Ensure = 'Present' - } - ) - - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $ZoneScope, - [System.String] $DomainName, - [System.String] $NameServer, - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordNsScoped] @{ - ZoneName = $ZoneName - ZoneScope = $ZoneScope - DomainName = $DomainName - NameServer = $NameServer - Ensure = [Ensure]::Present + ZoneName = $ZoneName + ZoneScope = $ZoneScope + DomainName = $DomainName + NameServer = $NameServer + Ensure = [Ensure]::Present } return $mockInstanceCurrentState @@ -273,42 +364,46 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordNsScoped Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordNsScoped' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordNsScoped Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordNsScoped' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" - # Set a wrong value - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordNsScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -317,20 +412,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordNsScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -340,31 +448,44 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return - } + return + } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 { $script:instanceDesiredState.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordPtr.tests.ps1 b/tests/Unit/Classes/DnsRecordPtr.tests.ps1 index ad087247..8415c604 100644 --- a/tests/Unit/Classes/DnsRecordPtr.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordPtr.tests.ps1 @@ -1,123 +1,188 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordPtr DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordPtr -Tag 'DnsRecord', 'DnsRecordPtr' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -InModuleScope $ProjectName { - Describe DnsRecordPtr -Tag 'DnsRecord', 'DnsRecordPtr' { - Context 'Constructors' { - It 'Should not throw an exception when instantiated' { { [DnsRecordPtr]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordPtr]::new() $instance | Should -Not -BeNullOrEmpty } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordPtr' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordPtr' { $instance = [DnsRecordPtr]::new() $instance.GetType().Name | Should -Be 'DnsRecordPtr' } } } +} + +Describe 'Testing DnsRecordPtr Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordPtr' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordPtr Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordPtr' { - BeforeEach { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.168.192.in-addr.arpa' IpAddress = '192.168.0.9' Name = 'quarks.contoso.com' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName $getMethodResourceResult.IpAddress | Should -Be $script:instanceDesiredState.IpAddress $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name } + } - It 'Should return $false or $null respectively for the rest of the non-key properties' { - $getMethodResourceResult = $script:instanceDesiredState.Get() + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the same values as present in Key properties' { $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.IpAddress | Should -Be $script:instanceDesiredState.IpAddress $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name } } - } +} - Describe "Testing DnsRecordPtr Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordPtr' { - BeforeAll { - } +Describe 'Testing DnsRecordPtr Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordPtr' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.168.192.in-addr.arpa' IpAddress = '192.168.0.9' @@ -137,14 +202,21 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } - Context 'When the configuration are present' { - BeforeEach { + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.168.192.in-addr.arpa' IpAddress = '192.168.0.9' @@ -162,16 +234,24 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.168.192.in-addr.arpa' IpAddress = '192.168.0.9' @@ -191,13 +271,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.168.192.in-addr.arpa' IpAddress = '192.168.0.9' @@ -206,8 +295,24 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } - It 'Should return $false when the object is not found' { + BeforeDiscovery { + $testCasesToFail = @( + @{ + ZoneName = '0.168.192.in-addr.arpa' + IpAddress = '192.168.0.9' + Name = 'quarks.contoso.com' + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' + } + ) + } + + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordPtr] @{ @@ -221,26 +326,12 @@ InModuleScope $ProjectName { } $script:instanceDesiredState.Test() | Should -BeFalse } + } - $testCasesToFail = @( - @{ - ZoneName = '0.168.192.in-addr.arpa' - IpAddress = '192.168.0.9' - Name = 'quarks.contoso.com' - DnsServer = 'localhost' - TimeToLive = '02:00:00' # Undesired - Ensure = 'Present' - } - ) + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $IpAddress, - [System.String] $Name, - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordPtr] @{ @@ -258,42 +349,46 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing DnsRecordPtr Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordPtr' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordPtr Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordPtr' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrRecordInstance.xml" - # Set a wrong value - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.168.192.in-addr.arpa' IpAddress = '192.168.0.9' @@ -301,20 +396,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.168.192.in-addr.arpa' IpAddress = '192.168.0.9' @@ -323,36 +431,52 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } - return - } + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - { $script:instanceDesiredState.Set() } | Should -Not -Throw + return + } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } +} - Describe "Test bad inputs (both IPv4 and IPv6)" -Tag 'Test', 'DnsRecord', 'DnsRecordPtr' { - It "Throws when the IPv4 address is malformatted" { +Describe 'Test bad inputs (both IPv4 and IPv6)' -Tag 'Test', 'DnsRecord', 'DnsRecordPtr' { + It 'Throws when the IPv4 address is malformatted' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 $malformattedIPv4State = [DnsRecordPtr] @{ ZoneName = '0.168.192.in-addr.arpa' IpAddress = '192.168.0.DS9' @@ -360,10 +484,14 @@ InModuleScope $ProjectName { Ensure = 'Present' } - { $malformattedIPv4State.Get() } | Should -Throw -ExpectedMessage ('Cannot convert value "{0}" to type "System.Net.IPAddress". Error: "An invalid IP address was specified."' -f $malformattedIPv4State.IpAddress) + { $malformattedIPv4State.Get() } | Should -Throw -ExpectedMessage ('*' + '"Cannot convert value "{0}" to type "System.Net.IPAddress". Error: "An invalid IP address was specified.""' -f $malformattedIPv4State.IpAddress) } + } + + It 'Throws when the IPv6 address is malformatted' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It "Throws when the IPv6 address is malformatted" { $malformattedIPv6State = [DnsRecordPtr] @{ ZoneName = '0.0.d.f.ip6.arpa' IpAddress = 'fd00::1::9' @@ -371,10 +499,14 @@ InModuleScope $ProjectName { Ensure = 'Present' } - { $malformattedIPv6State.Get() } | Should -Throw -ExpectedMessage ('Cannot convert value "{0}" to type "System.Net.IPAddress". Error: "An invalid IP address was specified."' -f $malformattedIPv6State.IpAddress) + { $malformattedIPv6State.Get() } | Should -Throw -ExpectedMessage ('*' + '"Cannot convert value "{0}" to type "System.Net.IPAddress". Error: "An invalid IP address was specified.""' -f $malformattedIPv6State.IpAddress) } + } + + It 'Throws when placed in an incorrect IPv4 reverse lookup zone' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It "Throws when placed in an incorrect IPv4 reverse lookup zone" { $wrongIPv4ZoneState = [DnsRecordPtr] @{ ZoneName = '0.168.192.in-addr.arpa' IpAddress = '192.168.2.9' @@ -382,10 +514,14 @@ InModuleScope $ProjectName { Ensure = 'Present' } - { $wrongIPv4ZoneState.Get() } | Should -Throw -ExpectedMessage ('"{0}" does not belong to the "{1}" zone' -f $wrongIPv4ZoneState.IpAddress, $wrongIPv4ZoneState.ZoneName) + { $wrongIPv4ZoneState.Get() } | Should -Throw -ExpectedMessage ('"{0}" does not belong to the "{1}" zone.' -f $wrongIPv4ZoneState.IpAddress, $wrongIPv4ZoneState.ZoneName) } + } + + It 'Throws when placed in an incorrect IPv6 reverse lookup zone' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It "Throws when placed in an incorrect IPv6 reverse lookup zone" { $wrongIPv6ZoneState = [DnsRecordPtr] @{ ZoneName = '1.0.0.d.f.ip6.arpa' IpAddress = 'fd00::9' @@ -393,10 +529,14 @@ InModuleScope $ProjectName { Ensure = 'Present' } - { $wrongIPv6ZoneState.Get() } | Should -Throw -ExpectedMessage ('"{0}" does not belong to the "{1}" zone' -f $wrongIPv6ZoneState.IpAddress, $wrongIPv6ZoneState.ZoneName) + { $wrongIPv6ZoneState.Get() } | Should -Throw -ExpectedMessage ('"{0}" does not belong to the "{1}" zone.' -f $wrongIPv6ZoneState.IpAddress, $wrongIPv6ZoneState.ZoneName) } + } + + It 'Throws trying to put an IPv6 address into an IPv4 reverse lookup zone' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It "Throws trying to put an IPv6 address into an IPv4 reverse lookup zone" { $zoneVersionMismatchV6InV4State = [DnsRecordPtr] @{ ZoneName = '0.168.192.in-addr.arpa' IpAddress = 'fd00::d59' @@ -406,8 +546,12 @@ InModuleScope $ProjectName { { $zoneVersionMismatchV6InV4State.Get() } | Should -Throw -ExpectedMessage ('The zone "{0}" is not an IPv6 reverse lookup zone.' -f $zoneVersionMismatchV6InV4State.ZoneName) } + } + + It 'Throws trying to put an IPv4 address into an IPv6 reverse lookup zone' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It "Throws trying to put an IPv4 address into an IPv6 reverse lookup zone" { $zoneVersionMismatchV4InV6State = [DnsRecordPtr] @{ ZoneName = '1.0.0.d.f.ip6.arpa' IpAddress = '192.168.2.9' diff --git a/tests/Unit/Classes/DnsRecordPtr.v6.tests.ps1 b/tests/Unit/Classes/DnsRecordPtr.v6.tests.ps1 index ce34bdbc..e02ac336 100644 --- a/tests/Unit/Classes/DnsRecordPtr.v6.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordPtr.v6.tests.ps1 @@ -1,34 +1,70 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordPtr.v6 DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + Import-Module -Name $script:dscModuleName -InModuleScope $ProjectName { + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} - Describe "Testing the expandIPv6String method for completeness (See Issue #255)" -Tag 'expandIPv6String', 'DnsRecord', 'DnsRecordPtr' { - $testObj = [DnsRecordPtr]::new() +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe 'Testing the expandIPv6String method for completeness (See Issue #255)' -Tag 'expandIPv6String', 'DnsRecord', 'DnsRecordPtr' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:testObj = [DnsRecordPtr]::new() + } + } - Context "Expands the following addresses correctly" { - $testCases = @" + Context 'Expands the following addresses correctly' { + BeforeDiscovery { + $testCases = @' 3ea8:1140:571c:e8d8:2e83:cb3a:0000:9431 c69e:276d:0e86:c274:c7f0:0000:8dc3:e662 db8c:e4ec:32f7:41a2:0000:842e:d212:b4c2 @@ -61,98 +97,124 @@ d861:9c60:c280:9f4e:705d:0b71:574d:7bdb 493e:81ac:19f3:0dc5:042b:0c86:0a5b:b1cc 7782:d54f:fc68:ceca:9d89:3879:a603:0e43 7358:25cb:9973:d542:6658:9a9e:84d0:6b41 -"@ -split "`r*`n" | ForEach-Object { +'@ -split "`r*`n" | ForEach-Object { @{ - FullAddress = $_ + FullAddress = $_ CompactAddress = [System.Net.IpAddress]::Parse($_).IPAddressToString } } + } + + It 'Expands -> ' -TestCases $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Expands -> ' -TestCases $testCases { - param ( - [System.String] $CompactAddress, - [System.String] $FullAddress - ) $testObj.expandIPv6String($CompactAddress) | Should -Be $FullAddress } } } +} + +Describe 'Testing DnsRecordPtr Get Method (IPv6 inputs)' -Tag 'Get', 'DnsRecord', 'DnsRecordPtr' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing DnsRecordPtr Get Method (IPv6 inputs)" -Tag 'Get', 'DnsRecord', 'DnsRecordPtr' { - BeforeEach { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.0.d.f.ip6.arpa' IpAddress = 'fd00::515c:0:0:d59' Name = 'quarks.contoso.com' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName $getMethodResourceResult.IpAddress | Should -Be $script:instanceDesiredState.IpAddress $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name } + } - It 'Should return $false or $null respectively for the rest of the non-key properties' { + It 'Should return $false or $null respectively for the rest of the non-key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 $getMethodResourceResult = $script:instanceDesiredState.Get() - $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrV6RecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrV6RecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in Key properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in Key properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.IpAddress | Should -Be $script:instanceDesiredState.IpAddress $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name } } - } - Describe "Testing DnsRecordPtr Test Method (IPv6 inputs)" -Tag 'Test', 'DnsRecord', 'DnsRecordPtr' { - BeforeAll { - } +} + +Describe 'Testing DnsRecordPtr Test Method (IPv6 inputs)' -Tag 'Test', 'DnsRecord', 'DnsRecordPtr' { + + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.0.d.f.ip6.arpa' IpAddress = 'fd00::515c:0:0:d59' @@ -163,23 +225,31 @@ d861:9c60:c280:9f4e:705d:0b71:574d:7bdb #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordPtr] @{ - ZoneName = '0.0.d.f.ip6.arpa' - IpAddress = 'fd00::515c:0:0:d59' - Name = 'quarks.contoso.com' - Ensure = [Ensure]::Absent + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent } return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.0.d.f.ip6.arpa' IpAddress = 'fd00::515c:0:0:d59' @@ -188,25 +258,33 @@ d861:9c60:c280:9f4e:705d:0b71:574d:7bdb $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordPtr] @{ - ZoneName = '0.0.d.f.ip6.arpa' - IpAddress = 'fd00::515c:0:0:d59' - Name = 'quarks.contoso.com' - Ensure = [Ensure]::Present + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Present } return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.0.d.f.ip6.arpa' IpAddress = 'fd00::515c:0:0:d59' @@ -217,72 +295,84 @@ d861:9c60:c280:9f4e:705d:0b71:574d:7bdb #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordPtr] @{ - ZoneName = '0.0.d.f.ip6.arpa' - IpAddress = 'fd00::515c:0:0:d59' - Name = 'quarks.contoso.com' - Ensure = [Ensure]::Present + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Present } return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordPtr] @{ - ZoneName = '0.0.d.f.ip6.arpa' - IpAddress = 'fd00::515c:0:0:d59' - Name = 'quarks.contoso.com' + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' TimeToLive = '1:00:00' - Ensure = [Ensure]::Present + Ensure = [Ensure]::Present } } + } + + BeforeDiscovery { + $testCasesToFail = @( + @{ + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' + } + ) + } + + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when the object is not found' { #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordPtr] @{ - ZoneName = '0.0.d.f.ip6.arpa' - IpAddress = 'fd00::515c:0:0:d59' - Name = 'quarks.contoso.com' - Ensure = [Ensure]::Absent + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' + Ensure = [Ensure]::Absent } return $mockInstanceCurrentState } $script:instanceDesiredState.Test() | Should -BeFalse } + } - $testCasesToFail = @( - @{ - ZoneName = '0.0.d.f.ip6.arpa' - IpAddress = 'fd00::515c:0:0:d59' - Name = 'quarks.contoso.com' - DnsServer = 'localhost' - TimeToLive = '02:00:00' # Undesired - Ensure = 'Present' - } - ) + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - [System.String] $IpAddress, - [System.String] $Name, - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { $mockInstanceCurrentState = [DnsRecordPtr] @{ - ZoneName = $ZoneName - IpAddress = $IpAddress - Name = $Name - Ensure = [Ensure]::Present + ZoneName = $ZoneName + IpAddress = $IpAddress + Name = $Name + Ensure = [Ensure]::Present } return $mockInstanceCurrentState @@ -293,42 +383,46 @@ d861:9c60:c280:9f4e:705d:0b71:574d:7bdb } } } +} - Describe "Testing DnsRecordPtr Set Method (IPv6 inputs)" -Tag 'Set', 'DnsRecord', 'DnsRecordPtr' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing DnsRecordPtr Set Method (IPv6 inputs)' -Tag 'Set', 'DnsRecord', 'DnsRecordPtr' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrV6RecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\PtrV6RecordInstance.xml" - # Set a wrong value - $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordPtr] @{ ZoneName = '0.0.d.f.ip6.arpa' IpAddress = 'fd00::515c:0:0:d59' @@ -336,53 +430,80 @@ d861:9c60:c280:9f4e:705d:0b71:574d:7bdb Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordPtr] @{ - ZoneName = '0.0.d.f.ip6.arpa' - IpAddress = 'fd00::515c:0:0:d59' - Name = 'quarks.contoso.com' + ZoneName = '0.0.d.f.ip6.arpa' + IpAddress = 'fd00::515c:0:0:d59' + Name = 'quarks.contoso.com' TimeToLive = '1:00:00' - Ensure = [Ensure]::Present + Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } - return - } + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - { $script:instanceDesiredState.Set() } | Should -Not -Throw + return + } + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordSrv.tests.ps1 b/tests/Unit/Classes/DnsRecordSrv.tests.ps1 index d157a067..d465c91d 100644 --- a/tests/Unit/Classes/DnsRecordSrv.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordSrv.tests.ps1 @@ -1,53 +1,96 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordSrv DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} -InModuleScope $ProjectName { +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') - Describe DnsRecordSrv -Tag 'DnsRecord', 'DnsRecordSrv' { + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordSrv -Tag 'DnsRecord', 'DnsRecordSrv' { + Context 'Constructors' { + It 'Should not throw an exception when instanciate it' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Constructors' { - It 'Should not throw an exception when instanciate it' { { [DnsRecordSrv]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordSrv]::new() $instance | Should -Not -BeNullOrEmpty $instance.GetType().Name | Should -Be 'DnsRecordSrv' } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordSrv' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordSrv' { $instance = [DnsRecordSrv]::new() $instance.GetType().Name | Should -Be 'DnsRecordSrv' } } } +} + +Describe 'Testing Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordSrv' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordSrv' { - BeforeEach { $script:instanceDesiredState = [DnsRecordSrv] @{ ZoneName = 'contoso.com' SymbolicName = 'xmpp' @@ -56,22 +99,31 @@ InModuleScope $ProjectName { Target = 'chat.contoso.com' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName @@ -80,8 +132,12 @@ InModuleScope $ProjectName { $getMethodResourceResult.Port | Should -Be $script:instanceDesiredState.Port $getMethodResourceResult.Target | Should -Be $script:instanceDesiredState.Target } + } + + It 'Should return $false or $null respectively for the rest of the properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false or $null respectively for the rest of the properties' { $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Weight | Should -Be 0 @@ -90,42 +146,51 @@ InModuleScope $ProjectName { $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\SrvRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\SrvRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.PropertyMandatory | Should -Be $script:instanceDesiredState.PropertyMandatory } } - } +} - Describe "Testing Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordSrv' { - BeforeAll { - } +Describe 'Testing Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordSrv' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordSrv] @{ ZoneName = 'contoso.com' SymbolicName = 'xmpp' @@ -135,7 +200,6 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } - #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get ` -Value { @@ -151,14 +215,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordSrv] @{ ZoneName = 'contoso.com' SymbolicName = 'xmpp' @@ -181,16 +253,24 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordSrv] @{ ZoneName = 'contoso.com' SymbolicName = 'xmpp' @@ -215,13 +295,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordSrv] @{ ZoneName = 'contoso.com' SymbolicName = 'xmpp' @@ -230,30 +319,12 @@ InModuleScope $ProjectName { Target = 'chat.contoso.com' Priority = 20 Weight = 30 - TimeToLive = "1:00:00" + TimeToLive = '1:00:00' Ensure = [Ensure]::Present } } - - It 'Should return $false when the object is not found' { - #Override Get() method - $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get ` - -Value { - $mockInstanceCurrentState = [DnsRecordSrv] @{ - ZoneName = 'contoso.com' - SymbolicName = 'xmpp' - Protocol = 'TCP' - Port = 5222 - Target = 'chat.contoso.com' - Ensure = [Ensure]::Absent - } - - return $mockInstanceCurrentState - } - $script:instanceDesiredState.Test() | Should -BeFalse - } - - + } + BeforeDiscovery { $testCasesToFail = @( @{ SymbolicName = 'xmpp' @@ -292,26 +363,34 @@ InModuleScope $ProjectName { TimeToLive = '02:00:00' # Incorrect } ) + } - It 'Should return $false when Priority is , Weight is , and TimeToLive is ' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - - [System.String] $SymbolicName, - - [System.String] $Protocol, - - [System.UInt16] $Port, + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - [System.String] $Target, + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get ` + -Value { + $mockInstanceCurrentState = [DnsRecordSrv] @{ + ZoneName = 'contoso.com' + SymbolicName = 'xmpp' + Protocol = 'TCP' + Port = 5222 + Target = 'chat.contoso.com' + Ensure = [Ensure]::Absent + } - [System.UInt16] $Priority, + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + } - [System.UInt16] $Weight, + It 'Should return $false when Priority is , Weight is , and TimeToLive is ' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get ` -Value { @@ -335,43 +414,47 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordSrv' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordSrv' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\SrvRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\SrvRecordInstance.xml" - # Set a wrong value - $mockRecord.RecordData.Priority = 300 - $mockRecord.RecordData.Weight = 400 + # Set a wrong value + $mockRecord.RecordData.Priority = 300 + $mockRecord.RecordData.Weight = 400 - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordSrv] @{ ZoneName = 'contoso.com' SymbolicName = 'xmpp' @@ -383,20 +466,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordSrv] @{ ZoneName = 'contoso.com' SymbolicName = 'xmpp' @@ -405,35 +501,49 @@ InModuleScope $ProjectName { Target = 'chat.contoso.com' Priority = 20 Weight = 30 - TimeToLive = "1:00:00" + TimeToLive = '1:00:00' Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return - } + return + } - { $script:instanceDesiredState.Set() } | Should -Not -Throw + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsRecordSrvScoped.tests.ps1 b/tests/Unit/Classes/DnsRecordSrvScoped.tests.ps1 index 65fc8b9d..3b21d349 100644 --- a/tests/Unit/Classes/DnsRecordSrvScoped.tests.ps1 +++ b/tests/Unit/Classes/DnsRecordSrvScoped.tests.ps1 @@ -1,53 +1,96 @@ <# - This pester file is an example of how organize a pester test. - There tests are based to dummy scenario. - Replace all properties, and mock commands by yours. + .SYNOPSIS + Unit test for DSC_DnsRecordSrvScoped DSC resource. #> -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} -InModuleScope $ProjectName { +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') - Describe DnsRecordSrvScoped -Tag 'DnsRecord', 'DnsRecordSrvScoped' { + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe DnsRecordSrvScoped -Tag 'DnsRecord', 'DnsRecordSrvScoped' { + Context 'Constructors' { + It 'Should not throw an exception when instanciate it' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Constructors' { - It 'Should not throw an exception when instanciate it' { { [DnsRecordSrvScoped]::new() } | Should -Not -Throw } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Has a default or empty constructor' { $instance = [DnsRecordSrvScoped]::new() $instance | Should -Not -BeNullOrEmpty $instance.GetType().Name | Should -Be 'DnsRecordSrvScoped' } } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordSrvScoped' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'Type creation' { - It 'Should be type named DnsRecordSrvScoped' { $instance = [DnsRecordSrvScoped]::new() $instance.GetType().Name | Should -Be 'DnsRecordSrvScoped' } } } +} + +Describe 'Testing Get Method' -Tag 'Get', 'DnsRecord', 'DnsRecordSrvScoped' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Describe "Testing Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordSrvScoped' { - BeforeEach { $script:instanceDesiredState = [DnsRecordSrvScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -57,22 +100,31 @@ InModuleScope $ProjectName { Target = 'chat.contoso.com' } } + } - Context "When the configuration is absent" { - BeforeAll { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose - } + Context 'When the configuration is absent' { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose } + } + + It 'Should return the state as absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as absent' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Absent' } - It 'Should return the same values as present in properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName @@ -81,8 +133,12 @@ InModuleScope $ProjectName { $getMethodResourceResult.Port | Should -Be $script:instanceDesiredState.Port $getMethodResourceResult.Target | Should -Be $script:instanceDesiredState.Target } + } + + It 'Should return $false or $null respectively for the rest of the properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $false or $null respectively for the rest of the properties' { $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Weight | Should -Be 0 @@ -91,42 +147,51 @@ InModuleScope $ProjectName { $getMethodResourceResult.DnsServer | Should -Be 'localhost' } } + } - Context "When the configuration is present" { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the configuration is present' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\SrvRecordInstance.xml" - } + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\SrvRecordInstance.xml" } + } + + It 'Should return the state as present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return the state as present' { $currentState = $script:instanceDesiredState.Get() - Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It $currentState.Ensure | Should -Be 'Present' } - It 'Should return the same values as present in properties' { + Should -Invoke Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should return the same values as present in properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $getMethodResourceResult = $script:instanceDesiredState.Get() $getMethodResourceResult.Name | Should -Be $script:instanceDesiredState.Name $getMethodResourceResult.PropertyMandatory | Should -Be $script:instanceDesiredState.PropertyMandatory } } - } +} - Describe "Testing Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordSrvScoped' { - BeforeAll { - } +Describe 'Testing Test Method' -Tag 'Test', 'DnsRecord', 'DnsRecordSrvScoped' { + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is in the desired state' { - Context 'When the configuration are absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordSrvScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -137,7 +202,6 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } - #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get ` -Value { @@ -154,14 +218,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } + } + + Context 'When the configuration are present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration are present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordSrvScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -186,16 +258,24 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return $true' { $script:instanceDesiredState.Test() | Should -BeTrue } } } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - Context 'When the configuration should be absent' { - BeforeEach { $script:instanceDesiredState = [DnsRecordSrvScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -222,13 +302,22 @@ InModuleScope $ProjectName { return $mockInstanceCurrentState } } - It 'Should return $false' { + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $script:instanceDesiredState.Test() | Should -BeFalse } } + } + + Context 'When the configuration should be present' { + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeEach { $script:instanceDesiredState = [DnsRecordSrvScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -238,31 +327,13 @@ InModuleScope $ProjectName { Target = 'chat.contoso.com' Priority = 20 Weight = 30 - TimeToLive = "1:00:00" + TimeToLive = '1:00:00' Ensure = [Ensure]::Present } } + } - It 'Should return $false when the object is not found' { - #Override Get() method - $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get ` - -Value { - $mockInstanceCurrentState = [DnsRecordSrvScoped] @{ - ZoneName = 'contoso.com' - ZoneScope = 'external' - SymbolicName = 'xmpp' - Protocol = 'TCP' - Port = 5222 - Target = 'chat.contoso.com' - Ensure = [Ensure]::Absent - } - - return $mockInstanceCurrentState - } - $script:instanceDesiredState.Test() | Should -BeFalse - } - - + BeforeDiscovery { $testCasesToFail = @( @{ SymbolicName = 'xmpp' @@ -293,6 +364,7 @@ InModuleScope $ProjectName { @{ SymbolicName = 'xmpp' ZoneName = 'contoso.com' + ZoneScope = 'external' Ensure = 'Present' Target = 'chat.contoso.com' DnsServer = 'localhost' @@ -303,34 +375,41 @@ InModuleScope $ProjectName { TimeToLive = '02:00:00' # Incorrect } ) + } - It 'Should return $false when Priority is , Weight is , and TimeToLive is ' -TestCases $testCasesToFail { - param - ( - [System.String] $ZoneName, - - [System.String] $ZoneScope, - - [System.String] $SymbolicName, - - [System.String] $Protocol, - - [System.UInt16] $Port, + It 'Should return $false when the object is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - [System.String] $Target, + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get ` + -Value { + $mockInstanceCurrentState = [DnsRecordSrvScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + SymbolicName = 'xmpp' + Protocol = 'TCP' + Port = 5222 + Target = 'chat.contoso.com' + Ensure = [Ensure]::Absent + } - [System.UInt16] $Priority, + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + } - [System.UInt16] $Weight, + It 'Should return $false when Priority is , Weight is , and TimeToLive is ' -TestCases $testCasesToFail { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - [System.String] $TimeToLive - ) #Override Get() method $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get ` -Value { $mockInstanceCurrentState = [DnsRecordSrvScoped] @{ ZoneName = $ZoneName - ZoneScope = $ZoneScope + ZoneScope = $ZoneScope SymbolicName = $SymbolicName Protocol = $Protocol Port = $Port @@ -349,42 +428,46 @@ InModuleScope $ProjectName { } } } +} - Describe "Testing Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordSrvScoped' { - BeforeAll { - # Mock the Add-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Add-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing - Mock -CommandName Remove-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose - } -Verifiable - - Mock -CommandName Set-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose - } -Verifiable - } +Describe 'Testing Set Method' -Tag 'Set', 'DnsRecord', 'DnsRecordSrvScoped' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Add-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Remove-DnsServerResourceRecord Called' -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Set-DnsServerResourceRecord Called' -Verbose + } -Verifiable + } - Context 'When the system is not in the desired state' { - BeforeAll { - $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\SrvRecordInstance.xml" + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\SrvRecordInstance.xml" - # Set a wrong value - $mockRecord.RecordData.Priority = 300 + # Set a wrong value + $mockRecord.RecordData.Priority = 300 - return $mockRecord - } + return $mockRecord } + } + + Context 'When the configuration should be absent' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be absent' { - BeforeAll { $script:instanceDesiredState = [DnsRecordSrvScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -397,20 +480,33 @@ InModuleScope $ProjectName { Ensure = [Ensure]::Absent } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = [Ensure]::Absent } + } + + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should call the correct mocks' { { $script:instanceDesiredState.Set() } | Should -Not -Throw - Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' - Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' } + + Should -Invoke -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } + + Context 'When the configuration should be present' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the configuration should be present' { - BeforeAll { $script:instanceDesiredState = [DnsRecordSrvScoped] @{ ZoneName = 'contoso.com' ZoneScope = 'external' @@ -420,35 +516,49 @@ InModuleScope $ProjectName { Target = 'chat.contoso.com' Priority = 20 Weight = 30 - TimeToLive = "1:00:00" + TimeToLive = '1:00:00' Ensure = [Ensure]::Present } } + } + + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - BeforeEach { $script:instanceDesiredState.Ensure = 'Present' } + } - It 'Should call the correct mocks when record exists' { - { $script:instanceDesiredState.Set() } | Should -Not -Throw + It 'Should call the correct mocks when record exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } - It 'Should call the correct mocks when record does not exist' { - Mock -CommandName Get-DnsServerResourceRecord -MockWith { - Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + Should -Invoke -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope It + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose 'Mock Get-DnsServerResourceRecord Called' -Verbose - return - } + return + } - { $script:instanceDesiredState.Set() } | Should -Not -Throw + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + { $script:instanceDesiredState.Set() } | Should -Not -Throw } + + Should -Invoke -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope It } + } - Assert-VerifiableMock + It 'Should call all verifiable mocks' { + Should -InvokeVerifiable } } } diff --git a/tests/Unit/Classes/DnsServerCache.Tests.ps1 b/tests/Unit/Classes/DnsServerCache.Tests.ps1 index ee7e8669..79ff84c2 100644 --- a/tests/Unit/Classes/DnsServerCache.Tests.ps1 +++ b/tests/Unit/Classes/DnsServerCache.Tests.ps1 @@ -1,53 +1,129 @@ -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = ( - Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $( - try +<# + .SYNOPSIS + Unit test for DSC_DnsServerCache DSC resource. +#> + +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe 'DnsServerCache' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + { [DnsServerCache]::new() } | Should -Not -Throw } - ) + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockInstance = [DnsServerCache]::new() + $mockInstance | Should -Not -BeNullOrEmpty + } + } } -).BaseName -Import-Module $ProjectName + Context 'Type creation' { + It 'Should be type named DnsServerCache' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$PSScriptRoot\..\Stubs\DnsServer.psm1" + $mockInstance = [DnsServerCache]::new() + $mockInstance.GetType().Name | Should -Be 'DnsServerCache' + } + } + } +} Describe 'DnsServerCache\Get()' -Tag 'Get' { Context 'When the system is in the desired state' { BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - Mock -CommandName Get-DnsServerCache -ModuleName $ProjectName -MockWith { - return New-CimInstance -ClassName 'DnsServerCache' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerCache] @{ IgnorePolicies = $true LockingPercent = 100 MaxKBSize = 0 - MaxNegativeTtl = '00:15:00' - MaxTtl = '1.00:00:00' EnablePollutionProtection = $true StoreEmptyAuthenticationResponse = $true + MaxNegativeTtl = '00:15:00' + MaxTtl = '1.00:00:00' } - } - } - BeforeEach { - $mockDnsServerCacheInstance = InModuleScope $ProjectName { - [DnsServerCache]::new() + <# + This mocks the method GetCurrentState(). + + Method Get() will call the base method Get() which will + call back to the derived class method GetCurrentState() + to get the result to return from the derived method Get(). + #> + $script:mockInstance | Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetCurrentState' -Value { + return @{ + IgnorePolicies = $true + LockingPercent = [System.UInt32] 100 + MaxKBSize = [System.UInt32] 0 + EnablePollutionProtection = $true + StoreEmptyAuthenticationResponse = $true + MaxNegativeTtl = '00:15:00' + MaxTtl = '1.00:00:00' + } + } -PassThru | Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } } } - It 'Should have correctly instantiated the resource class' { - $mockDnsServerCacheInstance | Should -Not -BeNullOrEmpty - $mockDnsServerCacheInstance.GetType().Name | Should -Be 'DnsServerCache' - } - It 'Should return the correct values for the properties when DnsServer is set to ''''' -TestCases @( @{ HostName = 'localhost' @@ -56,215 +132,251 @@ Describe 'DnsServerCache\Get()' -Tag 'Get' { HostName = 'dns.company.local' } ) { - param - ( - $HostName - ) - - $mockDnsServerCacheInstance.DnsServer = $HostName + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult = $mockDnsServerCacheInstance.Get() - - $getResult.DnsServer | Should -Be $HostName - $getResult.IgnorePolicies | Should -BeTrue - $getResult.LockingPercent | Should -Be 100 - $getResult.MaxKBSize | Should -Be 0 - $getResult.EnablePollutionProtection | Should -BeTrue - $getResult.StoreEmptyAuthenticationResponse | Should -BeTrue - $getResult.MaxNegativeTtl | Should -Be '00:15:00' - $getResult.MaxTtl | Should -Be '1.00:00:00' - - Assert-MockCalled -CommandName Get-DnsServerCache -ModuleName $ProjectName -Exactly -Times 1 -Scope It - } - } -} - -Describe 'DnsServerCache\Test()' -Tag 'Test' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - } + $script:mockInstance.DnsServer = $HostName + $script:mockInstance.GetCurrentState( + @{ + DnsServer = $HostName + } + ) - Context 'When providing an invalid interval' { - BeforeEach { - $mockDnsServerCacheInstance = InModuleScope $ProjectName { - [DnsServerCache]::new() + $getResult = $script:mockInstance.Get() + + $getResult.DnsServer | Should -Be $HostName + $getResult.IgnorePolicies | Should -BeTrue + $getResult.LockingPercent | Should -Be 100 + $getResult.MaxKBSize | Should -Be 0 + $getResult.EnablePollutionProtection | Should -BeTrue + $getResult.StoreEmptyAuthenticationResponse | Should -BeTrue + $getResult.MaxNegativeTtl | Should -Be '00:15:00' + $getResult.MaxTtl | Should -Be '1.00:00:00' + $getResult.Reasons | Should -BeNullOrEmpty } } + } - Context 'When providing a invalid value for the property MaxTtl' { - Context 'When the value is a string that cannot be converted to [System.TimeSpan]' { - It 'Should throw the correct error' { - $mockInvalidTime = '235.a:00:00' + Context 'When the system is not in the desired state' { + Context 'When property MaxKBSize has the wrong value' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerCache] @{ + IgnorePolicies = $true + LockingPercent = 100 + MaxKBSize = 0 + EnablePollutionProtection = $true + StoreEmptyAuthenticationResponse = $true + MaxNegativeTtl = '00:15:00' + MaxTtl = '1.00:00:00' + } - $mockDnsServerCacheInstance.MaxTtl = $mockInvalidTime + <# + This mocks the method GetCurrentState(). - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyHasWrongFormat + Method Get() will call the base method Get() which will + call back to the derived class method GetCurrentState() + to get the result to return from the derived method Get(). + #> + $script:mockInstance | Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetCurrentState' -Value { + return @{ + IgnorePolicies = $true + LockingPercent = [System.UInt32] 100 + MaxKBSize = [System.UInt32] 1000 + EnablePollutionProtection = $true + StoreEmptyAuthenticationResponse = $true + MaxNegativeTtl = '00:15:00' + MaxTtl = '1.00:00:00' + } + } -PassThru | Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxTtl', $mockInvalidTime) } } - Context 'When the time exceeds maximum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '31.00:00:00' - - $mockDnsServerCacheInstance.MaxTtl = $mockInvalidTime - - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanExceedMaximumValue - } - - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxTtl', $mockInvalidTime, '30.00:00:00') + It 'Should return the correct values when Hostname is ''''' -TestCases @( + @{ + HostName = 'localhost' } - } + @{ + HostName = 'dns.company.local' + } + ) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the time is below minimum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '-1.00:00:00' + $script:mockInstance.DnsServer = $HostName + $script:mockInstance.GetCurrentState( + @{ + DnsServer = $HostName + } + ) - $mockDnsServerCacheInstance.MaxTtl = $mockInvalidTime + $getResult = $script:mockInstance.Get() - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanBelowMinimumValue - } + $getResult.DnsServer | Should -Be $HostName + $getResult.IgnorePolicies | Should -BeTrue + $getResult.LockingPercent | Should -Be 100 + $getResult.MaxKBSize | Should -Be 1000 + $getResult.EnablePollutionProtection | Should -BeTrue + $getResult.StoreEmptyAuthenticationResponse | Should -BeTrue + $getResult.MaxNegativeTtl | Should -Be '00:15:00' + $getResult.MaxTtl | Should -Be '1.00:00:00' - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxTtl', $mockInvalidTime, '00:00:00') + $getResult.Reasons | Should -HaveCount 1 + $getResult.Reasons[0].Code | Should -Be 'DnsServerCache:DnsServerCache:MaxKBSize' + $getResult.Reasons[0].Phrase | Should -Be 'The property MaxKBSize should be 0, but was 1000' } } } + } +} - Context 'When providing a invalid value for the property MaxNegativeTtl' { - Context 'When the value is a string that cannot be converted to [System.TimeSpan]' { - It 'Should throw the correct error' { - $mockInvalidTime = '235.a:00:00' +Describe 'DnsServerCache\Set()' -Tag 'Set' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerCache] @{ + DnsServer = 'localhost' + IgnorePolicies = $true + LockingPercent = 100 + MaxKBSize = 0 + MaxNegativeTtl = '00:15:00' + MaxTtl = '1.00:00:00' + EnablePollutionProtection = $true + StoreEmptyAuthenticationResponse = $true + } | + # Mock method Modify which is called by the case method Set(). + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Modify' -Value { + $script:methodModifyCallCount += 1 + } -PassThru + } + } - $mockDnsServerCacheInstance.MaxNegativeTtl = $mockInvalidTime + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyHasWrongFormat - } + $script:methodModifyCallCount = 0 + } + } - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxNegativeTtl', $mockInvalidTime) - } + Context 'When the system is in the desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return $null + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } } + } - Context 'When the time exceeds maximum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '31.00:00:00' + It 'Should not call method Modify()' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerCacheInstance.MaxNegativeTtl = $mockInvalidTime + $script:mockInstance.Set() - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanExceedMaximumValue - } + $script:methodModifyCallCount | Should -Be 0 + } + } + } - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxNegativeTtl', $mockInvalidTime, '30.00:00:00') - } + Context 'When the system is not in the desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return @{ + Property = 'MaxNegativeTtl' + ExpectedValue = '00:15:00' + ActualValue = '00:12:00' + } + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } } + } - Context 'When the time is below minimum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '00:00:00' + It 'Should call method Modify()' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerCacheInstance.MaxNegativeTtl = $mockInvalidTime + $script:mockInstance.Set() - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanBelowMinimumValue - } + $script:methodModifyCallCount | Should -Be 1 + } + } + } +} - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxNegativeTtl', $mockInvalidTime, '00:00:01') - } +Describe 'DnsServerCache\Test()' -Tag 'Test' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerCache] @{ + DnsServer = 'localhost' + IgnorePolicies = $true + LockingPercent = 100 + MaxKBSize = 0 + MaxNegativeTtl = '00:15:00' + MaxTtl = '1.00:00:00' + EnablePollutionProtection = $true + StoreEmptyAuthenticationResponse = $true } } } Context 'When the system is in the desired state' { BeforeAll { - $mockDnsServerCacheInstance = InModuleScope $ProjectName { - [DnsServerCache]::new() - } - - $mockDnsServerCacheInstance.IgnorePolicies = $true - $mockDnsServerCacheInstance.LockingPercent = 100 - $mockDnsServerCacheInstance.MaxKBSize = 0 - $mockDnsServerCacheInstance.MaxNegativeTtl = '00:15:00' - $mockDnsServerCacheInstance.MaxTtl = '1.00:00:00' - $mockDnsServerCacheInstance.EnablePollutionProtection = $true - $mockDnsServerCacheInstance.StoreEmptyAuthenticationResponse = $true - - # Override Get() method - $mockDnsServerCacheInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerCache] @{ - DnsServer = 'localhost' - IgnorePolicies = $true - LockingPercent = 100 - MaxKBSize = 0 - MaxNegativeTtl = '00:15:00' - MaxTtl = '1.00:00:00' - EnablePollutionProtection = $true - StoreEmptyAuthenticationResponse = $true - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return $null + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - } + } } - It 'Should return the $true' { - $getResult = $mockDnsServerCacheInstance.Test() + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult | Should -BeTrue + $script:mockInstance.Test() | Should -BeTrue + } } } Context 'When the system is not in the desired state' { BeforeAll { - $testCases = @( - @{ - PropertyName = 'IgnorePolicies' - PropertyValue = $false - } - @{ - PropertyName = 'LockingPercent' - PropertyValue = 80 - } - @{ - PropertyName = 'MaxKBSize' - PropertyValue = '1000' - } - @{ - PropertyName = 'MaxNegativeTtl' - PropertyValue = '00:30:00' - } - @{ - PropertyName = 'MaxTtl' - PropertyValue = '3.00:00:00' - } - @{ - PropertyName = 'EnablePollutionProtection' - PropertyValue = $false - } - @{ - PropertyName = 'StoreEmptyAuthenticationResponse' - PropertyValue = $false - } - ) - } - - BeforeEach { - $mockDnsServerCacheInstance = InModuleScope $ProjectName { - [DnsServerCache]::new() - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - # Override Get() method - $mockDnsServerCacheInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerCache] @{ + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return @{ DnsServer = 'localhost' - IgnorePolicies = $true + IgnorePolicies = $false LockingPercent = 100 MaxKBSize = 0 MaxNegativeTtl = '00:15:00' @@ -272,293 +384,252 @@ Describe 'DnsServerCache\Test()' -Tag 'Test' { EnablePollutionProtection = $true StoreEmptyAuthenticationResponse = $true } + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - } + } } - It 'Should return the $false when property is not in desired state' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) - - $mockDnsServerCacheInstance.$PropertyName = $PropertyValue + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult = $mockDnsServerCacheInstance.Test() - - $getResult | Should -BeFalse + $script:mockInstance.Test() | Should -BeFalse + } } } } -Describe 'DnsServerCache\Set()' -Tag 'Set' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - } - - Context 'When providing an invalid interval' { - BeforeEach { - $mockDnsServerCacheInstance = InModuleScope $ProjectName { - [DnsServerCache]::new() - } +Describe 'DnsServerCache\AssertProperties()' -Tag 'HiddenMember' { + Context 'When the property '''' is not correct' -ForEach @( + @{ + Name = 'MaxNegativeTtl' + BadFormat = '235.a:00:00' + TooLow = '00:00:00' + TooHigh = '31.00:00:00' } + @{ + Name = 'MaxTtl' + BadFormat = '235.a:00:00' + TooLow = '-1.00:00:00' + TooHigh = '31.00:00:00' + } + ) { + BeforeAll { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When providing a invalid value for the property MaxTtl' { - Context 'When the value is a string that cannot be converted to [System.TimeSpan]' { - It 'Should throw the correct error' { - $mockInvalidTime = '235.a:00:00' - - $mockDnsServerCacheInstance.MaxTtl = $mockInvalidTime - - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyHasWrongFormat - } - - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxTtl', $mockInvalidTime) + $script:mockInstance = [DnsServerCache] @{ + DnsServer = 'localhost' } } + Mock -CommandName Assert-TimeSpan + } - Context 'When the time exceeds maximum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '31.00:00:00' - - $mockDnsServerCacheInstance.MaxTtl = $mockInvalidTime - - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanExceedMaximumValue - } + It 'Should throw the correct error when a bad format' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxTtl', $mockInvalidTime, '30.00:00:00') - } + { + $script:mockInstance.AssertProperties( + @{ + $Name = $BadFormat + } + ) + } | Should -Not -Throw } - Context 'When the time is below minimum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '-1.00:00:00' - - $mockDnsServerCacheInstance.MaxTtl = $mockInvalidTime - - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanBelowMinimumValue - } - - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxTtl', $mockInvalidTime, '00:00:00') - } - } + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It } - Context 'When providing a invalid value for the property MaxNegativeTtl' { - Context 'When the value is a string that cannot be converted to [System.TimeSpan]' { - It 'Should throw the correct error' { - $mockInvalidTime = '235.a:00:00' - - $mockDnsServerCacheInstance.MaxNegativeTtl = $mockInvalidTime + It 'Should throw the correct error when too small' -Skip:([System.String]::IsNullOrEmpty($TooLow)) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyHasWrongFormat - } - - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxNegativeTtl', $mockInvalidTime) - } + { + $script:mockInstance.AssertProperties( + @{ + $Name = $TooLow + } + ) + } | Should -Not -Throw } - Context 'When the time exceeds maximum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '31.00:00:00' - - $mockDnsServerCacheInstance.MaxNegativeTtl = $mockInvalidTime + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It + } - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanExceedMaximumValue - } + It 'Should throw the correct error when too big' -Skip:([System.String]::IsNullOrEmpty($TooHigh)) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxNegativeTtl', $mockInvalidTime, '30.00:00:00') - } + { + $script:mockInstance.AssertProperties( + @{ + $Name = $TooHigh + } + ) + } | Should -Not -Throw } - Context 'When the time is below minimum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '00:00:00' - - $mockDnsServerCacheInstance.MaxNegativeTtl = $mockInvalidTime - - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanBelowMinimumValue - } - - { $mockDnsServerCacheInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'MaxNegativeTtl', $mockInvalidTime, '00:00:01') - } - } + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It } } +} - Context 'When the system is in the desired state' { +Describe 'DnsServerCache\GetCurrentState()' -Tag 'HiddenMember' { + Context 'When object is missing in the current state' { BeforeAll { - Mock -CommandName Set-DnsServerCache -ModuleName $ProjectName + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'IgnorePolicies' - PropertyValue = $true - } - @{ - PropertyName = 'LockingPercent' - PropertyValue = 100 - } - @{ - PropertyName = 'MaxKBSize' - PropertyValue = '0' - } - @{ - PropertyName = 'MaxNegativeTtl' - PropertyValue = '00:15:00' - } - @{ - PropertyName = 'MaxTtl' - PropertyValue = '1.00:00:00' - } - @{ - PropertyName = 'EnablePollutionProtection' - PropertyValue = $true - } - @{ - PropertyName = 'StoreEmptyAuthenticationResponse' - PropertyValue = $true + $script:mockInstance = [DnsServerCache] @{ + DnsServer = 'localhost' } - ) - } - - BeforeEach { - $mockDnsServerCacheInstance = InModuleScope $ProjectName { - [DnsServerCache]::new() } - - $mockDnsServerCacheInstance.DnsServer = 'localhost' - - # Override Get() method - $mockDnsServerCacheInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerCache] @{ - DnsServer = 'localhost' - IgnorePolicies = $true - LockingPercent = 100 - MaxKBSize = 0 - MaxNegativeTtl = '00:15:00' - MaxTtl = '1.00:00:00' - EnablePollutionProtection = $true - StoreEmptyAuthenticationResponse = $true - } - } - } + Mock -CommandName Get-DnsServerCache } - It 'Should not call any mock to set a value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + It 'Should return the correct values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerCacheInstance.$PropertyName = $PropertyValue + $currentState = $script:mockInstance.GetCurrentState( + @{ + DnsServer = 'localhost' + } + ) - { $mockDnsServerCacheInstance.Set() } | Should -Not -Throw + $currentState.DnsServer | Should -Be 'localhost' + $currentState.IgnorePolicies | Should -BeFalse + $currentState.LockingPercent | Should -Be 0 + $currentState.MaxKBSize | Should -Be 0 + $currentState.MaxNegativeTtl | Should -BeNullOrEmpty + $currentState.MaxTtl | Should -BeNullOrEmpty + $currentState.EnablePollutionProtection | Should -BeFalse + $currentState.StoreEmptyAuthenticationResponse | Should -BeFalse + } - Assert-MockCalled -CommandName Set-DnsServerCache -ModuleName $ProjectName -Exactly -Times 0 -Scope It + Should -Invoke -CommandName Get-DnsServerCache -Exactly -Times 1 -Scope It } } - Context 'When the system is not in the desired state' { + Context 'When the object is present in the current state' { BeforeAll { - Mock -CommandName Set-DnsServerCache -ModuleName $ProjectName + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'IgnorePolicies' - PropertyValue = $false - } - @{ - PropertyName = 'LockingPercent' - PropertyValue = 80 - } - @{ - PropertyName = 'MaxKBSize' - PropertyValue = '1000' - } - @{ - PropertyName = 'MaxNegativeTtl' - PropertyValue = '00:30:00' - } - @{ - PropertyName = 'MaxTtl' - PropertyValue = '3.00:00:00' - } - @{ - PropertyName = 'EnablePollutionProtection' - PropertyValue = $false + $script:mockInstance = [DnsServerCache] @{ + DnsServer = 'SomeHost' } - @{ - PropertyName = 'StoreEmptyAuthenticationResponse' - PropertyValue = $false + } + Mock -CommandName Get-DnsServerCache -MockWith { + return New-CimInstance -ClassName 'DnsServerCache' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + IgnorePolicies = $true + LockingPercent = 100 + MaxKBSize = 0 + MaxNegativeTtl = '00:15:00' + MaxTtl = '1.00:00:00' + EnablePollutionProtection = $true + StoreEmptyAuthenticationResponse = $true } - ) + } } - BeforeEach { - $mockDnsServerCacheInstance = InModuleScope $ProjectName { - [DnsServerCache]::new() - } + It 'Should return the correct values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - # Override Get() method - $mockDnsServerCacheInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerCache] @{ - DnsServer = 'localhost' - IgnorePolicies = $true - LockingPercent = 100 - MaxKBSize = 0 - MaxNegativeTtl = '00:15:00' - MaxTtl = '1.00:00:00' - EnablePollutionProtection = $true - StoreEmptyAuthenticationResponse = $true - } + $currentState = $script:mockInstance.GetCurrentState( + @{ + DnsServer = 'SomeHost' } - } - } - - Context 'When parameter DnsServer is set to ''localhost''' { - It 'Should set the desired value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue ) - $mockDnsServerCacheInstance.DnsServer = 'localhost' - $mockDnsServerCacheInstance.$PropertyName = $PropertyValue - - { $mockDnsServerCacheInstance.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Set-DnsServerCache -ModuleName $ProjectName -Exactly -Times 1 -Scope It + $currentState.DnsServer | Should -Be 'SomeHost' + $currentState.IgnorePolicies | Should -BeTrue + $currentState.LockingPercent | Should -Be 100 + $currentState.MaxKBSize | Should -Be 0 + $currentState.MaxNegativeTtl | Should -Be '00:15:00' + $currentState.MaxTtl | Should -Be '1.00:00:00' + $currentState.EnablePollutionProtection | Should -BeTrue + $currentState.StoreEmptyAuthenticationResponse | Should -BeTrue } + + Should -Invoke -CommandName Get-DnsServerCache -Exactly -Times 1 -Scope It } + } +} - Context 'When parameter DnsServer is set to ''dns.company.local''' { - It 'Should set the desired value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) +Describe 'DnsServerCache\Modify()' -Tag 'HiddenMember' { + Context 'When the system is not in the desired state' { + Context 'When the property is not in desired state' -ForEach @( + @{ + PropertyName = 'IgnorePolicies' + SetPropertyName = 'IgnorePolicies' + ExpectedValue = $true + } + @{ + PropertyName = 'LockingPercent' + SetPropertyName = 'LockingPercent' + ExpectedValue = 100 + } + @{ + PropertyName = 'MaxKBSize' + SetPropertyName = 'MaxKBSize' + ExpectedValue = 0 + } + @{ + PropertyName = 'MaxNegativeTtl' + SetPropertyName = 'MaxNegativeTtl' + ExpectedValue = '00:15:00' + } + @{ + PropertyName = 'MaxTtl' + SetPropertyName = 'MaxTtl' + ExpectedValue = '1.00:00:00' + } + @{ + PropertyName = 'EnablePollutionProtection' + SetPropertyName = 'PollutionProtection' + ExpectedValue = $true + } + @{ + PropertyName = 'StoreEmptyAuthenticationResponse' + SetPropertyName = 'StoreEmptyAuthenticationResponse' + ExpectedValue = $true + } + ) { + BeforeAll { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerCache] @{ + DnsServer = 'localhost' + $PropertyName = $ExpectedValue + } | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } -PassThru + } + Mock -CommandName Set-DnsServerCache + } - $mockDnsServerCacheInstance.DnsServer = 'dns.company.local' - $mockDnsServerCacheInstance.$PropertyName = $PropertyValue + It 'Should call the correct mocks' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerCacheInstance.Set() } | Should -Not -Throw + $script:mockInstance.Modify( + # This is the properties not in desired state. + @{ + $PropertyName = $ExpectedValue + } + ) - Assert-MockCalled -CommandName Set-DnsServerCache -ModuleName $ProjectName -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Set-DnsServerCache -ParameterFilter { + $PesterBoundParameters.$SetPropertyName -eq $ExpectedValue + } -Exactly -Times 1 -Scope It + } } } } diff --git a/tests/Unit/Classes/DnsServerDsSetting.Tests.ps1 b/tests/Unit/Classes/DnsServerDsSetting.Tests.ps1 index 02a567c5..b3673a93 100644 --- a/tests/Unit/Classes/DnsServerDsSetting.Tests.ps1 +++ b/tests/Unit/Classes/DnsServerDsSetting.Tests.ps1 @@ -1,62 +1,85 @@ -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = ( - Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $( - try +<# + .SYNOPSIS + Unit test for DSC_DnsServerDsSetting DSC resource. +#> + +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - } - ) + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } -).BaseName + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} -Import-Module $ProjectName +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$PSScriptRoot\..\Stubs\DnsServer.psm1" + Import-Module -Name $script:dscModuleName -Describe 'DnsServerDsSetting\AssertProperties()' -Tag 'HiddenMember' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - } + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force - Context 'When providing an invalid interval' { - BeforeEach { - $mockDnsServerDsSettingInstance = InModuleScope $ProjectName { - [DnsServerDsSetting]::new() - } - } + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} - Context 'When the value is a string that cannot be converted to [System.TimeSpan]' { - It 'Should throw the correct error' { - $mockInvalidTime = '235.a:00:00' +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') - $mockDnsServerDsSettingInstance.DirectoryPartitionAutoEnlistInterval = $mockInvalidTime + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyHasWrongFormat - } + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe 'DnsServerDsSetting' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerDsSettingInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'DirectoryPartitionAutoEnlistInterval', $mockInvalidTime) + { [DnsServerDsSetting]::new() } | Should -Not -Throw } } - Context 'When the time is below minimum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '-1.00:00:00' + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerDsSettingInstance.TombstoneInterval = $mockInvalidTime + $mockInstance = [DnsServerDsSetting]::new() + $mockInstance | Should -Not -BeNullOrEmpty + } + } + } - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanBelowMinimumValue - } + Context 'Type creation' { + It 'Should be type named DnsServerDsSetting' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerDsSettingInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'TombstoneInterval', $mockInvalidTime, '00:00:00') + $mockInstance = [DnsServerDsSetting]::new() + $mockInstance.GetType().Name | Should -Be 'DnsServerDsSetting' } } } @@ -65,30 +88,40 @@ Describe 'DnsServerDsSetting\AssertProperties()' -Tag 'HiddenMember' { Describe 'DnsServerDsSetting\Get()' -Tag 'Get' { Context 'When the system is in the desired state' { BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - Mock -CommandName Get-DnsServerDsSetting -ModuleName $ProjectName -MockWith { - return New-CimInstance -ClassName 'DnsServerDsSetting' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerDsSetting] @{ DirectoryPartitionAutoEnlistInterval = '1.00:00:00' - LazyUpdateInterval = 3 - MinimumBackgroundLoadThreads = 1 - PollingInterval = 180 - RemoteReplicationDelay = 30 - TombstoneInterval = '14.00:00:00' + LazyUpdateInterval = 3 + MinimumBackgroundLoadThreads = 1 + PollingInterval = 180 + RemoteReplicationDelay = 30 + TombstoneInterval = '14.00:00:00' } - } - } - BeforeEach { - $mockDnsServerDsSettingInstance = InModuleScope $ProjectName { - [DnsServerDsSetting]::new() + <# + This mocks the method GetCurrentState(). + + Method Get() will call the base method Get() which will + call back to the derived class method GetCurrentState() + to get the result to return from the derived method Get(). + #> + $script:mockInstance | Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetCurrentState' -Value { + return @{ + DirectoryPartitionAutoEnlistInterval = '1.00:00:00' + LazyUpdateInterval = [System.UInt32] 3 + MinimumBackgroundLoadThreads = [System.UInt32] 1 + PollingInterval = [System.String] 180 + RemoteReplicationDelay = [System.UInt32] 30 + TombstoneInterval = '14.00:00:00' + } + } -PassThru | Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } } } - It 'Should have correctly instantiated the resource class' { - $mockDnsServerDsSettingInstance | Should -Not -BeNullOrEmpty - $mockDnsServerDsSettingInstance.GetType().Name | Should -Be 'DnsServerDsSetting' - } - It 'Should return the correct values for the properties when DnsServer is set to ''''' -TestCases @( @{ HostName = 'localhost' @@ -97,298 +130,487 @@ Describe 'DnsServerDsSetting\Get()' -Tag 'Get' { HostName = 'dns.company.local' } ) { - param - ( - $HostName - ) - - $mockDnsServerDsSettingInstance.DnsServer = $HostName + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult = $mockDnsServerDsSettingInstance.Get() + $script:mockInstance.DnsServer = $HostName + $script:mockInstance.GetCurrentState( + @{ + DnsServer = $HostName + } + ) - $getResult.DirectoryPartitionAutoEnlistInterval | Should -Be '1.00:00:00' - $getResult.LazyUpdateInterval | Should -Be 3 - $getResult.MinimumBackgroundLoadThreads | Should -Be 1 - $getResult.PollingInterval | Should -Be 180 - $getResult.RemoteReplicationDelay | Should -Be 30 - $getResult.TombstoneInterval | Should -Be '14.00:00:00' + $getResult = $script:mockInstance.Get() - Assert-MockCalled -CommandName Get-DnsServerDsSetting -ModuleName $ProjectName -Exactly -Times 1 -Scope It + $getResult.DirectoryPartitionAutoEnlistInterval | Should -Be '1.00:00:00' + $getResult.LazyUpdateInterval | Should -Be 3 + $getResult.MinimumBackgroundLoadThreads | Should -Be 1 + $getResult.PollingInterval | Should -Be 180 + $getResult.RemoteReplicationDelay | Should -Be 30 + $getResult.TombstoneInterval | Should -Be '14.00:00:00' + $getResult.Reasons | Should -BeNullOrEmpty + } } } -} -Describe 'DnsServerDsSetting\Test()' -Tag 'Test' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - } + Context 'When the system is not in the desired state' { + Context 'When property RemoteReplicationDelay has the wrong value' { + + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerDsSetting] @{ + DirectoryPartitionAutoEnlistInterval = '1.00:00:00' + LazyUpdateInterval = 3 + MinimumBackgroundLoadThreads = 1 + PollingInterval = 180 + RemoteReplicationDelay = 30 + TombstoneInterval = '14.00:00:00' + } - Context 'When the system is in the desired state' { - BeforeAll { - $mockDnsServerDsSettingInstance = InModuleScope $ProjectName { - [DnsServerDsSetting]::new() - } - - $mockDnsServerDsSettingInstance.DirectoryPartitionAutoEnlistInterval = '1.00:00:00' - $mockDnsServerDsSettingInstance.LazyUpdateInterval = 3 - $mockDnsServerDsSettingInstance.MinimumBackgroundLoadThreads = 1 - $mockDnsServerDsSettingInstance.PollingInterval = 180 - $mockDnsServerDsSettingInstance.RemoteReplicationDelay = 30 - $mockDnsServerDsSettingInstance.TombstoneInterval = '14.00:00:00' - - # Override Get() method - $mockDnsServerDsSettingInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerDsSetting] @{ - DnsServer = 'localhost' + <# + This mocks the method GetCurrentState(). + + Method Get() will call the base method Get() which will + call back to the derived class method GetCurrentState() + to get the result to return from the derived method Get(). + #> + $script:mockInstance | Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetCurrentState' -Value { + return @{ DirectoryPartitionAutoEnlistInterval = '1.00:00:00' - LazyUpdateInterval = 3 - MinimumBackgroundLoadThreads = 1 - PollingInterval = 180 - RemoteReplicationDelay = 30 - TombstoneInterval = '14.00:00:00' + LazyUpdateInterval = [System.UInt32] 3 + MinimumBackgroundLoadThreads = [System.UInt32] 1 + PollingInterval = [System.String] 180 + RemoteReplicationDelay = [System.UInt32] 60 + TombstoneInterval = '14.00:00:00' } + } -PassThru | Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } } + } + + It 'Should return the correct values for the properties when DnsServer is set to ''''' -TestCases @( + @{ + HostName = 'localhost' + } + @{ + HostName = 'dns.company.local' + } + ) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance.DnsServer = $HostName + $script:mockInstance.GetCurrentState( + @{ + DnsServer = $HostName + } + ) + + $getResult = $script:mockInstance.Get() + + $getResult.DirectoryPartitionAutoEnlistInterval | Should -Be '1.00:00:00' + $getResult.LazyUpdateInterval | Should -Be 3 + $getResult.MinimumBackgroundLoadThreads | Should -Be 1 + $getResult.PollingInterval | Should -Be 180 + $getResult.RemoteReplicationDelay | Should -Be 60 + $getResult.TombstoneInterval | Should -Be '14.00:00:00' + + $getResult.Reasons | Should -HaveCount 1 + $getResult.Reasons[0].Code | Should -Be 'DnsServerDsSetting:DnsServerDsSetting:RemoteReplicationDelay' + $getResult.Reasons[0].Phrase | Should -Be 'The property RemoteReplicationDelay should be 30, but was 60' + } + } + } + } +} + +Describe 'DnsServerDsSetting\Set()' -Tag 'Set' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerDsSetting] @{ + DnsServer = 'localhost' + DirectoryPartitionAutoEnlistInterval = '1.00:00:00' + LazyUpdateInterval = 3 + MinimumBackgroundLoadThreads = 1 + PollingInterval = 180 + RemoteReplicationDelay = 30 + TombstoneInterval = '14.00:00:00' + } | + # Mock method Modify which is called by the case method Set(). + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Modify' -Value { + $script:methodModifyCallCount += 1 + } -PassThru } + } - It 'Should return the $true' { - $getResult = $mockDnsServerDsSettingInstance.Test() + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult | Should -BeTrue + $script:methodModifyCallCount = 0 } } - Context 'When the system is not in the desired state' { + Context 'When the system is in the desired state' { BeforeAll { - $testCases = @( - @{ - PropertyName = 'DirectoryPartitionAutoEnlistInterval' - PropertyValue = "2.00:00:00" - } - @{ - PropertyName = 'LazyUpdateInterval' - PropertyValue = 1 - } - @{ - PropertyName = 'MinimumBackgroundLoadThreads' - PropertyValue = 0 - } - @{ - PropertyName = 'PollingInterval' - PropertyValue = 0 - } - @{ - PropertyName = 'RemoteReplicationDelay' - PropertyValue = 0 - } - @{ - PropertyName = 'TombstoneInterval' - PropertyValue = '01:00:00' - } - ) + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return $null + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } + } } - BeforeEach { - $mockDnsServerDsSettingInstance = InModuleScope $ProjectName { - [DnsServerDsSetting]::new() + It 'Should not call method Modify()' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance.Set() + + $script:methodModifyCallCount | Should -Be 0 } + } + } - # Override Get() method - $mockDnsServerDsSettingInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerDsSetting] @{ - DnsServer = 'localhost' - DirectoryPartitionAutoEnlistInterval = '1.00:00:00' - LazyUpdateInterval = 3 - MinimumBackgroundLoadThreads = 1 - PollingInterval = 180 - RemoteReplicationDelay = 30 - TombstoneInterval = '14.00:00:00' + Context 'When the system is not in the desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return @{ + Property = 'TombstoneInterval' + ExpectedValue = '14.00:00:00' + ActualValue = '7.00:00:00' } + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - } + } } - It 'Should return the $false when property is not in desired state' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) - - $mockDnsServerDsSettingInstance.$PropertyName = $PropertyValue + It 'Should call method Modify()' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult = $mockDnsServerDsSettingInstance.Test() + $script:mockInstance.Set() - $getResult | Should -BeFalse + $script:methodModifyCallCount | Should -Be 1 + } } } } -Describe 'DnsServerDsSetting\Set()' -Tag 'Set' { +Describe 'DnsServerDsSetting\Test()' -Tag 'Test' { BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerDsSetting] @{ + DirectoryPartitionAutoEnlistInterval = '1.00:00:00' + LazyUpdateInterval = 3 + MinimumBackgroundLoadThreads = 1 + PollingInterval = 180 + RemoteReplicationDelay = 30 + TombstoneInterval = '14.00:00:00' + } + } } Context 'When the system is in the desired state' { BeforeAll { - Mock -CommandName Set-DnsServerDsSetting -ModuleName $ProjectName - - $testCases = @( - @{ - PropertyName = 'DirectoryPartitionAutoEnlistInterval' - PropertyValue = "1.00:00:00" - } - @{ - PropertyName = 'LazyUpdateInterval' - PropertyValue = 3 - } - @{ - PropertyName = 'MinimumBackgroundLoadThreads' - PropertyValue = 1 - } - @{ - PropertyName = 'PollingInterval' - PropertyValue = 180 - } - @{ - PropertyName = 'RemoteReplicationDelay' - PropertyValue = 30 - } - @{ - PropertyName = 'TombstoneInterval' - PropertyValue = '14.00:00:00' - } - ) + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return $null + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } + } } - BeforeEach { - $mockDnsServerDsSettingInstance = InModuleScope $ProjectName { - [DnsServerDsSetting]::new() - } + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerDsSettingInstance.DnsServer = 'localhost' + $script:mockInstance.Test() | Should -BeTrue + } + } + } - # Override Get() method - $mockDnsServerDsSettingInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerDsSetting] @{ - DnsServer = 'localhost' + Context 'When the system is not in the desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return @{ + DnsServer = 'localhost' DirectoryPartitionAutoEnlistInterval = '1.00:00:00' - LazyUpdateInterval = 3 - MinimumBackgroundLoadThreads = 1 - PollingInterval = 180 - RemoteReplicationDelay = 30 - TombstoneInterval = '14.00:00:00' + LazyUpdateInterval = 3 + MinimumBackgroundLoadThreads = 1 + PollingInterval = 180 + RemoteReplicationDelay = 30 + TombstoneInterval = '7.00:00:00' } + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - } + } } - It 'Should not call any mock to set a value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerDsSettingInstance.$PropertyName = $PropertyValue - - { $mockDnsServerDsSettingInstance.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Set-DnsServerDsSetting -ModuleName $ProjectName -Exactly -Times 0 -Scope It + $script:mockInstance.Test() | Should -BeFalse + } } } +} - Context 'When the system is not in the desired state' { +Describe 'DnsServerDsSetting\AssertProperties()' -Tag 'HiddenMember' { + Context 'When the property '''' is not correct' -ForEach @( + @{ + Name = 'DirectoryPartitionAutoEnlistInterval' + BadFormat = '235.a:00:00' + TooLow = '-01:00:00' + TooHigh = '' + } + @{ + Name = 'TombstoneInterval' + BadFormat = '235.a:00:00' + TooLow = '-1.00:00:00' + TooHigh = '' + } + ) { BeforeAll { - Mock -CommandName Set-DnsServerDsSetting -ModuleName $ProjectName + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'DirectoryPartitionAutoEnlistInterval' - PropertyValue = "2.00:00:00" + $script:mockInstance = [DnsServerDsSetting] @{ + DnsServer = 'localhost' } - @{ - PropertyName = 'LazyUpdateInterval' - PropertyValue = 1 - } - @{ - PropertyName = 'MinimumBackgroundLoadThreads' - PropertyValue = 0 - } - @{ - PropertyName = 'PollingInterval' - PropertyValue = 0 - } - @{ - PropertyName = 'RemoteReplicationDelay' - PropertyValue = 0 - } - @{ - PropertyName = 'TombstoneInterval' - PropertyValue = '01:00:00' - } - ) + } + Mock -CommandName Assert-TimeSpan + } + + It 'Should throw the correct error when a bad format' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + { + $script:mockInstance.AssertProperties( + @{ + $Name = $BadFormat + } + ) + } | Should -Not -Throw + } + + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It } - BeforeEach { - $mockDnsServerDsSettingInstance = InModuleScope $ProjectName { - [DnsServerDsSetting]::new() + It 'Should throw the correct error when too small' -Skip:([System.String]::IsNullOrEmpty($TooLow)) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + { + $script:mockInstance.AssertProperties( + @{ + $Name = $TooLow + } + ) + } | Should -Not -Throw } - # Override Get() method - $mockDnsServerDsSettingInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerDsSetting] @{ - DnsServer = 'localhost' - DirectoryPartitionAutoEnlistInterval = '1.00:00:00' - LazyUpdateInterval = 3 - MinimumBackgroundLoadThreads = 1 - PollingInterval = 180 - RemoteReplicationDelay = 30 - TombstoneInterval = '14.00:00:00' + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It + } + + It 'Should throw the correct error when too big' -Skip:([System.String]::IsNullOrEmpty($TooHigh)) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + { + $script:mockInstance.AssertProperties( + @{ + $Name = $TooHigh } - } + ) + } | Should -Not -Throw + } + + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It + } + } +} + +Describe 'DnsServerDsSetting\GetCurrentState()' -Tag 'HiddenMember' { + Context 'When object is missing in the current state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerDsSetting] @{ + DnsServer = 'localhost' } + } + Mock -CommandName Get-DnsServerDsSetting } - Context 'When parameter DnsServer is set to ''localhost''' { - It 'Should set the desired value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue + It 'Should return the correct values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $currentState = $script:mockInstance.GetCurrentState( + @{ + DnsServer = 'localhost' + } ) - $mockDnsServerDsSettingInstance.DnsServer = 'localhost' - $mockDnsServerDsSettingInstance.$PropertyName = $PropertyValue + $currentState.DnsServer | Should -Be 'localhost' + $currentState.DirectoryPartitionAutoEnlistInterval | Should -BeNullOrEmpty + $currentState.LazyUpdateInterval | Should -Be 0 + $currentState.MinimumBackgroundLoadThreads | Should -Be 0 + $currentState.PollingInterval | Should -BeNullOrEmpty + $currentState.RemoteReplicationDelay | Should -Be 0 + $currentState.TombstoneInterval | Should -BeNullOrEmpty + } + + Should -Invoke -CommandName Get-DnsServerDsSetting -Exactly -Times 1 -Scope It + } + } - { $mockDnsServerDsSettingInstance.Set() } | Should -Not -Throw + Context 'When the object is present in the current state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerDsSetting -ModuleName $ProjectName -Exactly -Times 1 -Scope It + $script:mockInstance = [DnsServerDsSetting] @{ + DnsServer = 'SomeHost' + } + } + Mock -CommandName Get-DnsServerDsSetting -MockWith { + return New-CimInstance -ClassName 'DnsServerDsSetting' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + DirectoryPartitionAutoEnlistInterval = '1.00:00:00' + LazyUpdateInterval = 3 + MinimumBackgroundLoadThreads = 1 + PollingInterval = 180 + RemoteReplicationDelay = 30 + TombstoneInterval = '14.00:00:00' + } } } - Context 'When parameter DnsServer is set to ''dns.company.local''' { - It 'Should set the desired value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue + It 'Should return the correct values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $currentState = $script:mockInstance.GetCurrentState( + @{ + DnsServer = 'SomeHost' + } ) - $mockDnsServerDsSettingInstance.DnsServer = 'dns.company.local' - $mockDnsServerDsSettingInstance.$PropertyName = $PropertyValue + $currentState.DnsServer | Should -Be 'SomeHost' + $currentState.DirectoryPartitionAutoEnlistInterval | Should -Be '1.00:00:00' + $currentState.LazyUpdateInterval | Should -Be 3 + $currentState.MinimumBackgroundLoadThreads | Should -Be 1 + $currentState.PollingInterval | Should -Be 180 + $currentState.RemoteReplicationDelay | Should -Be 30 + $currentState.TombstoneInterval | Should -Be '14.00:00:00' + } + + Should -Invoke -CommandName Get-DnsServerDsSetting -Exactly -Times 1 -Scope It + } + } +} + +Describe 'DnsServerDsSetting\Modify()' -Tag 'HiddenMember' { + Context 'When the system is not in the desired state' { + Context 'When the property is not in desired state' -ForEach @( + @{ + PropertyName = 'DirectoryPartitionAutoEnlistInterval' + SetPropertyName = 'DirectoryPartitionAutoEnlistInterval' + ExpectedValue = '1.00:00:00' + } + @{ + PropertyName = 'LazyUpdateInterval' + SetPropertyName = 'LazyUpdateInterval' + ExpectedValue = 3 + } + @{ + PropertyName = 'MinimumBackgroundLoadThreads' + SetPropertyName = 'MinimumBackgroundLoadThreads' + ExpectedValue = 1 + } + @{ + PropertyName = 'PollingInterval' + SetPropertyName = 'PollingInterval' + ExpectedValue = 180 + } + @{ + PropertyName = 'RemoteReplicationDelay' + SetPropertyName = 'RemoteReplicationDelay' + ExpectedValue = 30 + } + @{ + PropertyName = 'TombstoneInterval' + SetPropertyName = 'TombstoneInterval' + ExpectedValue = '14.00:00:00' + } + ) { + BeforeAll { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerDsSetting] @{ + DnsServer = 'localhost' + $PropertyName = $ExpectedValue + } | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } -PassThru + } + Mock -CommandName Set-DnsServerDsSetting + } + + It 'Should call the correct mocks' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerDsSettingInstance.Set() } | Should -Not -Throw + $script:mockInstance.Modify( + # This is the properties not in desired state. + @{ + $PropertyName = $ExpectedValue + } + ) - Assert-MockCalled -CommandName Set-DnsServerDsSetting -ModuleName $ProjectName -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Set-DnsServerDsSetting -ParameterFilter { + $PesterBoundParameters.$SetPropertyName -eq $ExpectedValue + } -Exactly -Times 1 -Scope It + } } } } diff --git a/tests/Unit/Classes/DnsServerEDns.Tests.ps1 b/tests/Unit/Classes/DnsServerEDns.Tests.ps1 index 14321332..7cb1c726 100644 --- a/tests/Unit/Classes/DnsServerEDns.Tests.ps1 +++ b/tests/Unit/Classes/DnsServerEDns.Tests.ps1 @@ -1,49 +1,121 @@ -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = ( - Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $( - try +<# + .SYNOPSIS + Unit test for DSC_DnsServerEDns DSC resource. +#> + +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe 'DnsServerEDns' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + { [DnsServerEDns]::new() } | Should -Not -Throw + } + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockInstance = [DnsServerEDns]::new() + $mockInstance | Should -Not -BeNullOrEmpty } - ) + } } -).BaseName -Import-Module $ProjectName + Context 'Type creation' { + It 'Should be type named DnsServerEDns' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$PSScriptRoot\..\Stubs\DnsServer.psm1" + $mockInstance = [DnsServerEDns]::new() + $mockInstance.GetType().Name | Should -Be 'DnsServerEDns' + } + } + } +} Describe 'DnsServerEDns\Get()' -Tag 'Get' { Context 'When the system is in the desired state' { BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - Mock -CommandName Get-DnsServerEDns -ModuleName $ProjectName -MockWith { - return New-CimInstance -ClassName 'DnsServerEDns' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerEDns] @{ CacheTimeout = '0.00:15:00' EnableProbes = $true EnableReception = $true } - } - } - BeforeEach { - $mockDnsServerEDnsInstance = InModuleScope $ProjectName { - [DnsServerEDns]::new() + <# + This mocks the method GetCurrentState(). + + Method Get() will call the base method Get() which will + call back to the derived class method GetCurrentState() + to get the result to return from the derived method Get(). + #> + $script:mockInstance | Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetCurrentState' -Value { + return @{ + CacheTimeout = '0.00:15:00' + EnableProbes = $true + EnableReception = $true + } + } -PassThru | Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } } } - It 'Should have correctly instantiated the resource class' { - $mockDnsServerEDnsInstance | Should -Not -BeNullOrEmpty - $mockDnsServerEDnsInstance.GetType().Name | Should -Be 'DnsServerEDns' - } - It 'Should return the correct values for the properties when DnsServer is set to ''''' -TestCases @( @{ HostName = 'localhost' @@ -52,317 +124,437 @@ Describe 'DnsServerEDns\Get()' -Tag 'Get' { HostName = 'dns.company.local' } ) { - param - ( - $HostName - ) - - $mockDnsServerEDnsInstance.DnsServer = $HostName + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult = $mockDnsServerEDnsInstance.Get() + $script:mockInstance.DnsServer = $HostName + $script:mockInstance.GetCurrentState( + @{ + DnsServer = $HostName + } + ) - $getResult.DnsServer | Should -Be $HostName - $getResult.EnableProbes | Should -BeTrue - $getResult.EnableReception | Should -BeTrue - $getResult.CacheTimeout | Should -Be '0.00:15:00' + $getResult = $script:mockInstance.Get() - Assert-MockCalled -CommandName Get-DnsServerEDns -ModuleName $ProjectName -Exactly -Times 1 -Scope It + $getResult.DnsServer | Should -Be $HostName + $getResult.EnableProbes | Should -BeTrue + $getResult.EnableReception | Should -BeTrue + $getResult.CacheTimeout | Should -Be '0.00:15:00' + $getResult.Reasons | Should -BeNullOrEmpty + } } } -} -Describe 'DnsServerEDns\Test()' -Tag 'Test' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - } + Context 'When the system is not in the desired state' { + Context 'When property EnableReception has the wrong value' { - Context 'When providing an invalid interval' { - BeforeEach { - $mockDnsServerEDnsInstance = InModuleScope $ProjectName { - [DnsServerEDns]::new() - } - } + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerEDns] @{ + CacheTimeout = '0.00:15:00' + EnableProbes = $true + EnableReception = $true + } - Context 'When the value is a string that cannot be converted to [System.TimeSpan]' { - It 'Should throw the correct error' { - $mockInvalidTime = '235.a:00:00' + <# + This mocks the method GetCurrentState(). - $mockDnsServerEDnsInstance.CacheTimeout = $mockInvalidTime + Method Get() will call the base method Get() which will + call back to the derived class method GetCurrentState() + to get the result to return from the derived method Get(). + #> + $script:mockInstance | Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetCurrentState' -Value { + return @{ + CacheTimeout = '0.00:15:00' + EnableProbes = $true + EnableReception = $false + } + } -PassThru | Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } + } + } - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyHasWrongFormat + It 'Should return the correct values for the properties when DnsServer is set to ''''' -TestCases @( + @{ + HostName = 'localhost' + } + @{ + HostName = 'dns.company.local' } + ) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance.DnsServer = $HostName + $script:mockInstance.GetCurrentState( + @{ + DnsServer = $HostName + } + ) + + $getResult = $script:mockInstance.Get() - { $mockDnsServerEDnsInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'CacheTimeout', $mockInvalidTime) + $getResult.DnsServer | Should -Be $HostName + $getResult.EnableProbes | Should -BeTrue + $getResult.EnableReception | Should -BeFalse + $getResult.CacheTimeout | Should -Be '0.00:15:00' + $getResult.Reasons | Should -HaveCount 1 + $getResult.Reasons[0].Code | Should -Be 'DnsServerEDns:DnsServerEDns:EnableReception' + $getResult.Reasons[0].Phrase | Should -Be 'The property EnableReception should be true, but was false' + } } } + } +} - Context 'When the time is below minimum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '-1.00:00:00' - - $mockDnsServerEDnsInstance.CacheTimeout = $mockInvalidTime +Describe 'DnsServerEDns\Set()' -Tag 'Set' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerEDns] @{ + DnsServer = 'localhost' + CacheTimeout = '0.00:15:00' + EnableProbes = $true + EnableReception = $true + } | + # Mock method Modify which is called by the case method Set(). + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Modify' -Value { + $script:methodModifyCallCount += 1 + } -PassThru + } + } - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanBelowMinimumValue - } + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerEDnsInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'CacheTimeout', $mockInvalidTime, '00:00:00') - } + $script:methodModifyCallCount = 0 } } Context 'When the system is in the desired state' { BeforeAll { - $mockDnsServerEDnsInstance = InModuleScope $ProjectName { - [DnsServerEDns]::new() - } - - $mockDnsServerEDnsInstance.EnableReception = $true - $mockDnsServerEDnsInstance.EnableProbes = $true - $mockDnsServerEDnsInstance.CacheTimeout = '0.00:15:00' - - # Override Get() method - $mockDnsServerEDnsInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerEDns] @{ - DnsServer = 'localhost' - EnableReception = $true - EnableProbes = $true - CacheTimeout = '0.00:15:00' - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return $null + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - } + } } - It 'Should return the $true' { - $getResult = $mockDnsServerEDnsInstance.Test() + It 'Should not call method Modify()' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult | Should -BeTrue + $script:mockInstance.Set() + + $script:methodModifyCallCount | Should -Be 0 + } } } Context 'When the system is not in the desired state' { BeforeAll { - $testCases = @( - @{ - PropertyName = 'EnableProbes' - PropertyValue = $false - } - @{ - PropertyName = 'EnableReception' - PropertyValue = $false - } - @{ - PropertyName = 'CacheTimeout' - PropertyValue = '0.00:30:00' - } - ) - } - - BeforeEach { - $mockDnsServerEDnsInstance = InModuleScope $ProjectName { - [DnsServerEDns]::new() - } - - # Override Get() method - $mockDnsServerEDnsInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerEDns] @{ - DnsServer = 'localhost' - EnableReception = $true - EnableProbes = $true - CacheTimeout = '0.00:15:00' + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return @{ + Property = 'EnableProbes' + ExpectedValue = $true + ActualValue = $false } + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - } + } } - It 'Should return the $false when property is not in desired state' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + It 'Should call method Modify()' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerEDnsInstance.$PropertyName = $PropertyValue + $script:mockInstance.Set() - $getResult = $mockDnsServerEDnsInstance.Test() - - $getResult | Should -BeFalse + $script:methodModifyCallCount | Should -Be 1 + } } } } -Describe 'DnsServerEDns\Set()' -Tag 'Set' { +Describe 'DnsServerEDns\Test()' -Tag 'Test' { BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When providing an invalid interval' { - BeforeEach { - $mockDnsServerEDnsInstance = InModuleScope $ProjectName { - [DnsServerEDns]::new() + $script:mockInstance = [DnsServerEDns] @{ + CacheTimeout = '0.00:15:00' + EnableProbes = $true + EnableReception = $true } } + } - Context 'When the value is a string that cannot be converted to [System.TimeSpan]' { - It 'Should throw the correct error' { - $mockInvalidTime = '235.a:00:00' - - $mockDnsServerEDnsInstance.CacheTimeout = $mockInvalidTime + Context 'When the system is in the desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return $null + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } + } + } - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyHasWrongFormat - } + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerEDnsInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'CacheTimeout', $mockInvalidTime) + $script:mockInstance.Test() | Should -BeTrue } } + } - Context 'When the time is below minimum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '-1.00:00:00' + Context 'When the system is not in the desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerEDnsInstance.CacheTimeout = $mockInvalidTime + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return @{ + DnsServer = 'localhost' + CacheTimeout = '0.00:20:00' + EnableProbes = $false + EnableReception = $false + } + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } + } + } - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanBelowMinimumValue - } + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerEDnsInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'CacheTimeout', $mockInvalidTime, '00:00:00') + $script:mockInstance.Test() | Should -BeFalse } } } +} - Context 'When the system is in the desired state' { +Describe 'DnsServerEDns\AssertProperties()' -Tag 'HiddenMember' { + Context 'When the property '''' is not correct' -ForEach @( + @{ + Name = 'CacheTimeout' + BadFormat = '235.a:00:00' + TooLow = '-0.01:00:00' + TooHigh = '' + } + ) { BeforeAll { - Mock -CommandName Set-DnsServerEDns -ModuleName $ProjectName + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'EnableProbes' - PropertyValue = $true - } - @{ - PropertyName = 'EnableReception' - PropertyValue = $true - } - @{ - PropertyName = 'CacheTimeout' - PropertyValue = '0.00:15:00' + $script:mockInstance = [DnsServerEDns] @{ + DnsServer = 'localhost' } - ) + } + Mock -CommandName Assert-TimeSpan } - BeforeEach { - $mockDnsServerEDnsInstance = InModuleScope $ProjectName { - [DnsServerEDns]::new() + It 'Should throw the correct error when a bad format' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + { + $script:mockInstance.AssertProperties( + @{ + $Name = $BadFormat + } + ) + } | Should -Not -Throw } - $mockDnsServerEDnsInstance.DnsServer = 'localhost' + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It + } - # Override Get() method - $mockDnsServerEDnsInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerEDns] @{ - DnsServer = 'localhost' - EnableReception = $true - EnableProbes = $true - CacheTimeout = '0.00:15:00' + It 'Should throw the correct error when too small' -Skip:([System.String]::IsNullOrEmpty($TooLow)) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + { + $script:mockInstance.AssertProperties( + @{ + $Name = $TooLow } - } - } - } + ) + } | Should -Not -Throw + } - It 'Should not call any mock to set a value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It + } - $mockDnsServerEDnsInstance.$PropertyName = $PropertyValue + It 'Should throw the correct error when too big' -Skip:([System.String]::IsNullOrEmpty($TooHigh)) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerEDnsInstance.Set() } | Should -Not -Throw + { + $script:mockInstance.AssertProperties( + @{ + $Name = $TooHigh + } + ) + } | Should -Not -Throw + } - Assert-MockCalled -CommandName Set-DnsServerEDns -ModuleName $ProjectName -Exactly -Times 0 -Scope It + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It } } +} - Context 'When the system is not in the desired state' { +Describe 'DnsServerEDns\GetCurrentState()' -Tag 'HiddenMember' { + Context 'When object is missing in the current state' { BeforeAll { - Mock -CommandName Set-DnsServerEDns -ModuleName $ProjectName + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'EnableProbes' - PropertyValue = $false - } - @{ - PropertyName = 'EnableReception' - PropertyValue = $false + $script:mockInstance = [DnsServerEDns] @{ + DnsServer = 'localhost' } - @{ - PropertyName = 'CacheTimeout' - PropertyValue = '0.00:30:00' - } - ) + } + Mock -CommandName Get-DnsServerEDns } - BeforeEach { - $mockDnsServerEDnsInstance = InModuleScope $ProjectName { - [DnsServerEDns]::new() - } + It 'Should return the correct values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - # Override Get() method - $mockDnsServerEDnsInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerEDns] @{ - DnsServer = 'localhost' - EnableReception = $true - EnableProbes = $true - CacheTimeout = '0.00:15:00' - } + $currentState = $script:mockInstance.GetCurrentState( + @{ + DnsServer = 'localhost' } - } - } - - Context 'When parameter DnsServer is set to ''localhost''' { - It 'Should set the desired value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue ) - $mockDnsServerEDnsInstance.DnsServer = 'localhost' - $mockDnsServerEDnsInstance.$PropertyName = $PropertyValue + $currentState.DnsServer | Should -Be 'localhost' + $currentState.CacheTimeout | Should -BeNullOrEmpty + $currentState.EnableProbes | Should -BeFalse + $currentState.EnableReception | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerEDns -Exactly -Times 1 -Scope It + } + } - { $mockDnsServerEDnsInstance.Set() } | Should -Not -Throw + Context 'When the object is present in the current state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerEDns -ModuleName $ProjectName -Exactly -Times 1 -Scope It + $script:mockInstance = [DnsServerEDns] @{ + DnsServer = 'SomeHost' + } + } + Mock -CommandName Get-DnsServerEDns -MockWith { + return New-CimInstance -ClassName 'DnsServerEDns' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + CacheTimeout = '0.00:15:00' + EnableProbes = $true + EnableReception = $true + } } } - Context 'When parameter DnsServer is set to ''dns.company.local''' { - It 'Should set the desired value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue + It 'Should return the correct values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $currentState = $script:mockInstance.GetCurrentState( + @{ + DnsServer = 'SomeHost' + } ) - $mockDnsServerEDnsInstance.DnsServer = 'dns.company.local' - $mockDnsServerEDnsInstance.$PropertyName = $PropertyValue + $currentState.DnsServer | Should -Be 'SomeHost' + $currentState.CacheTimeout | Should -Be '0.00:15:00' + $currentState.EnableProbes | Should -BeTrue + $currentState.EnableReception | Should -BeTrue + } - { $mockDnsServerEDnsInstance.Set() } | Should -Not -Throw + Should -Invoke -CommandName Get-DnsServerEDns -Exactly -Times 1 -Scope It + } + } +} - Assert-MockCalled -CommandName Set-DnsServerEDns -ModuleName $ProjectName -Exactly -Times 1 -Scope It +Describe 'DnsServerEDns\Modify()' -Tag 'HiddenMember' { + Context 'When the system is not in the desired state' { + Context 'When the property is not in desired state' -ForEach @( + @{ + PropertyName = 'CacheTimeout' + SetPropertyName = 'CacheTimeout' + ExpectedValue = '0.00:15:00' + } + @{ + PropertyName = 'EnableProbes' + SetPropertyName = 'EnableProbes' + ExpectedValue = $true + } + @{ + PropertyName = 'EnableReception' + SetPropertyName = 'EnableReception' + ExpectedValue = $true + } + ) { + BeforeAll { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerEDns] @{ + DnsServer = 'localhost' + $PropertyName = $ExpectedValue + } | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } -PassThru + } + Mock -CommandName Set-DnsServerEDns + } + + It 'Should call the correct mocks' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance.Modify( + # This is the properties not in desired state. + @{ + $PropertyName = $ExpectedValue + } + ) + + Should -Invoke -CommandName Set-DnsServerEDns -ParameterFilter { + $PesterBoundParameters.$SetPropertyName -eq $ExpectedValue + } -Exactly -Times 1 -Scope It + } } } } diff --git a/tests/Unit/Classes/DnsServerRecursion.Tests.ps1 b/tests/Unit/Classes/DnsServerRecursion.Tests.ps1 index 617f2191..23ca6bc2 100644 --- a/tests/Unit/Classes/DnsServerRecursion.Tests.ps1 +++ b/tests/Unit/Classes/DnsServerRecursion.Tests.ps1 @@ -1,50 +1,123 @@ -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = ( - Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $( - try +<# + .SYNOPSIS + Unit test for DSC_DnsServerRecursion DSC resource. +#> + +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe 'DnsServerRecursion' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + { [DnsServerRecursion]::new() } | Should -Not -Throw } - ) + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockInstance = [DnsServerRecursion]::new() + $mockInstance | Should -Not -BeNullOrEmpty + } + } } -).BaseName -Import-Module $ProjectName + Context 'Type creation' { + It 'Should be type named DnsServerRecursion' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$PSScriptRoot\..\Stubs\DnsServer.psm1" + $mockInstance = [DnsServerRecursion]::new() + $mockInstance.GetType().Name | Should -Be 'DnsServerRecursion' + } + } + } +} Describe 'DnsServerRecursion\Get()' -Tag 'Get' { Context 'When the system is in the desired state' { BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - Mock -CommandName Get-DnsServerRecursion -ModuleName $ProjectName -MockWith { - return New-CimInstance -ClassName 'DnsServerRecursion' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerRecursion] @{ Enable = $true AdditionalTimeout = 4 RetryInterval = 3 Timeout = 8 } - } - } - BeforeEach { - $mockDnsServerRecursionInstance = InModuleScope $ProjectName { - [DnsServerRecursion]::new() + <# + This mocks the method GetCurrentState(). + + Method Get() will call the base method Get() which will + call back to the derived class method GetCurrentState() + to get the result to return from the derived method Get(). + #> + $script:mockInstance | Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetCurrentState' -Value { + return @{ + Enable = $true + AdditionalTimeout = [System.UInt32] 4 + RetryInterval = [System.UInt32] 3 + Timeout = [System.UInt32] 8 + } + } -PassThru | Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } } } - It 'Should have correctly instantiated the resource class' { - $mockDnsServerRecursionInstance | Should -Not -BeNullOrEmpty - $mockDnsServerRecursionInstance.GetType().Name | Should -Be 'DnsServerRecursion' - } - It 'Should return the correct values for the properties when DnsServer is set to ''''' -TestCases @( @{ HostName = 'localhost' @@ -53,333 +126,441 @@ Describe 'DnsServerRecursion\Get()' -Tag 'Get' { HostName = 'dns.company.local' } ) { - param - ( - $HostName - ) + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance.DnsServer = $HostName + $script:mockInstance.GetCurrentState( + @{ + DnsServer = $HostName + } + ) + + $getResult = $script:mockInstance.Get() + + $getResult.DnsServer | Should -Be $HostName + $getResult.Enable | Should -BeTrue + $getResult.AdditionalTimeout | Should -Be 4 + $getResult.RetryInterval | Should -Be 3 + $getResult.Timeout | Should -Be 8 + $getResult.Reasons | Should -BeNullOrEmpty + } + } + } - $mockDnsServerRecursionInstance.DnsServer = $HostName + Context 'When the system is not in the desired state' { + Context 'When property RetryInterval has the wrong value' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerRecursion] @{ + Enable = $true + AdditionalTimeout = 4 + RetryInterval = 3 + Timeout = 8 + } - $getResult = $mockDnsServerRecursionInstance.Get() + <# + This mocks the method GetCurrentState(). - $getResult.DnsServer | Should -Be $HostName - $getResult.Enable | Should -BeTrue - $getResult.AdditionalTimeout | Should -Be 4 - $getResult.RetryInterval | Should -Be 3 - $getResult.Timeout | Should -Be 8 + Method Get() will call the base method Get() which will + call back to the derived class method GetCurrentState() + to get the result to return from the derived method Get(). + #> + $script:mockInstance | Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetCurrentState' -Value { + return @{ + Enable = $true + AdditionalTimeout = [System.UInt32] 4 + RetryInterval = [System.UInt32] 4 + Timeout = [System.UInt32] 8 + } + } -PassThru | Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } + } + } - Assert-MockCalled -CommandName Get-DnsServerRecursion -ModuleName $ProjectName -Exactly -Times 1 -Scope It + It 'Should return the correct values for the properties when DnsServer is set to ''''' -TestCases @( + @{ + HostName = 'localhost' + } + @{ + HostName = 'dns.company.local' + } + ) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance.DnsServer = $HostName + $script:mockInstance.GetCurrentState( + @{ + DnsServer = $HostName + } + ) + + $getResult = $script:mockInstance.Get() + + $getResult.DnsServer | Should -Be $HostName + $getResult.Enable | Should -BeTrue + $getResult.AdditionalTimeout | Should -Be 4 + $getResult.RetryInterval | Should -Be 4 + $getResult.Timeout | Should -Be 8 + + $getResult.Reasons | Should -HaveCount 1 + $getResult.Reasons[0].Code | Should -Be 'DnsServerRecursion:DnsServerRecursion:RetryInterval' + $getResult.Reasons[0].Phrase | Should -Be 'The property RetryInterval should be 3, but was 4' + } + } } } } -Describe 'DnsServerRecursion\Test()' -Tag 'Test' { +Describe 'DnsServerRecursion\Set()' -Tag 'Set' { BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerRecursion] @{ + DnsServer = 'localhost' + Enable = $true + AdditionalTimeout = 4 + RetryInterval = 3 + Timeout = 8 + } | + # Mock method Modify which is called by the case method Set(). + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Modify' -Value { + $script:methodModifyCallCount += 1 + } -PassThru + } } - Context 'When providing an invalid interval' { - BeforeEach { - $mockDnsServerRecursionInstance = InModuleScope $ProjectName { - [DnsServerRecursion]::new() - } + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:methodModifyCallCount = 0 } + } - It 'Should throw the correct error when property has invalid value' -TestCases @( - @{ - PropertyName = 'AdditionalTimeout' + Context 'When the system is in the desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return $null + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } } - @{ - PropertyName = 'RetryInterval' + } + + It 'Should not call method Modify()' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance.Set() + + $script:methodModifyCallCount | Should -Be 0 } - @{ - PropertyName = 'Timeout' + } + } + + Context 'When the system is not in the desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return @{ + Property = 'AdditionalTimeout' + ExpectedValue = 4 + ActualValue = 5 + } + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } } - ) { - param - ( - $PropertyName - ) + } - $mockInvalidValue = 16 + It 'Should call method Modify()' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerRecursionInstance.$PropertyName = $mockInvalidTime + $script:mockInstance.Set() - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyIsNotInValidRange + $script:methodModifyCallCount | Should -Be 1 } + } + } +} - { $mockDnsServerRecursionInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f $PropertyName, $mockInvalidTime) +Describe 'DnsServerRecursion\Test()' -Tag 'Test' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerRecursion] @{ + DnsServer = 'localhost' + Enable = $true + AdditionalTimeout = 4 + RetryInterval = 3 + Timeout = 8 + } } } Context 'When the system is in the desired state' { BeforeAll { - $mockDnsServerRecursionInstance = InModuleScope $ProjectName { - [DnsServerRecursion]::new() - } - - $mockDnsServerRecursionInstance.Enable = $true - $mockDnsServerRecursionInstance.AdditionalTimeout = 4 - $mockDnsServerRecursionInstance.RetryInterval = 3 - $mockDnsServerRecursionInstance.Timeout = 8 - - # Override Get() method - $mockDnsServerRecursionInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerRecursion] @{ - DnsServer = 'localhost' - Enable = $true - AdditionalTimeout = 4 - RetryInterval = 3 - Timeout = 8 - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return $null + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - } + } } - It 'Should return the $true' { - $getResult = $mockDnsServerRecursionInstance.Test() + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult | Should -BeTrue + $script:mockInstance.Test() | Should -BeTrue + } } } Context 'When the system is not in the desired state' { BeforeAll { - $testCases = @( - @{ - PropertyName = 'Enable' - PropertyValue = $false - } - @{ - PropertyName = 'AdditionalTimeout' - PropertyValue = 5 - } - @{ - PropertyName = 'RetryInterval' - PropertyValue = 4 - } - @{ - PropertyName = 'Timeout' - PropertyValue = 9 - } - ) - } - - BeforeEach { - $mockDnsServerRecursionInstance = InModuleScope $ProjectName { - [DnsServerRecursion]::new() - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - # Override Get() method - $mockDnsServerRecursionInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerRecursion] @{ + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return @{ DnsServer = 'localhost' Enable = $true AdditionalTimeout = 4 RetryInterval = 3 Timeout = 8 } + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - } + } } - It 'Should return the $false when property is not in desired state' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) - - $mockDnsServerRecursionInstance.$PropertyName = $PropertyValue + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult = $mockDnsServerRecursionInstance.Test() - - $getResult | Should -BeFalse + $script:mockInstance.Test() | Should -BeFalse + } } } } -Describe 'DnsServerRecursion\Set()' -Tag 'Set' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - } +Describe 'DnsServerRecursion\AssertProperties()' -Tag 'HiddenMember' { + Context 'When the property '''' is not correct' -ForEach @( + @{ + Name = 'AdditionalTimeout' + GoodValue = 2 + BadValue = 20 + } + @{ + Name = 'RetryInterval' + GoodValue = 2 + BadValue = 20 + } + @{ + Name = 'Timeout' + GoodValue = 2 + BadValue = 20 + } + ) { + BeforeAll { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When providing an invalid interval' { - BeforeEach { - $mockDnsServerRecursionInstance = InModuleScope $ProjectName { - [DnsServerRecursion]::new() + $script:mockInstance = [DnsServerRecursion] @{ + DnsServer = 'localhost' + } } } - It 'Should throw the correct error when property has invalid value' -TestCases @( - @{ - PropertyName = 'AdditionalTimeout' - } - @{ - PropertyName = 'RetryInterval' - } - @{ - PropertyName = 'Timeout' - } - ) { - param - ( - $PropertyName - ) + It 'Should throw the correct error when a BadValue' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockInvalidValue = 16 + { + $script:mockInstance.AssertProperties( + @{ + $Name = $BadValue + } + ) + } | Should -Throw -ExpectedMessage ('*(DSR0007)') + } + } - $mockDnsServerRecursionInstance.$PropertyName = $mockInvalidTime + It 'Should not throw a GoodValue' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyIsNotInValidRange + { + $script:mockInstance.AssertProperties( + @{ + $Name = $GoodValue + } + ) + } | Should -Not -Throw } - - { $mockDnsServerRecursionInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f $PropertyName, $mockInvalidTime) } } +} - Context 'When the system is in the desired state' { +Describe 'DnsServerRecursion\GetCurrentState()' -Tag 'HiddenMember' { + Context 'When object is missing in the current state' { BeforeAll { - Mock -CommandName Set-DnsServerRecursion -ModuleName $ProjectName + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'Enable' - PropertyValue = $true - } - @{ - PropertyName = 'AdditionalTimeout' - PropertyValue = 4 - } - @{ - PropertyName = 'RetryInterval' - PropertyValue = 3 + $script:mockInstance = [DnsServerRecursion] @{ + DnsServer = 'localhost' } - @{ - PropertyName = 'Timeout' - PropertyValue = 8 - } - ) - } - - BeforeEach { - $mockDnsServerRecursionInstance = InModuleScope $ProjectName { - [DnsServerRecursion]::new() } - - $mockDnsServerRecursionInstance.DnsServer = 'localhost' - - # Override Get() method - $mockDnsServerRecursionInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerRecursion] @{ - DnsServer = 'localhost' - Enable = $true - AdditionalTimeout = 4 - RetryInterval = 3 - Timeout = 8 - } - } - } + Mock -CommandName Get-DnsServerRecursion } - It 'Should not call any mock to set a value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + It 'Should return the correct values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerRecursionInstance.$PropertyName = $PropertyValue + $currentState = $script:mockInstance.GetCurrentState( + @{ + DnsServer = 'localhost' + } + ) - { $mockDnsServerRecursionInstance.Set() } | Should -Not -Throw + $currentState.DnsServer | Should -Be 'localhost' + $currentState.Enable | Should -BeFalse + $currentState.AdditionalTimeout | Should -Be 0 + $currentState.RetryInterval | Should -Be 0 + $currentState.Timeout | Should -Be 0 + } - Assert-MockCalled -CommandName Set-DnsServerRecursion -ModuleName $ProjectName -Exactly -Times 0 -Scope It + Should -Invoke -CommandName Get-DnsServerRecursion -Exactly -Times 1 -Scope It } } - Context 'When the system is not in the desired state' { + Context 'When the object is present in the current state' { BeforeAll { - Mock -CommandName Set-DnsServerRecursion -ModuleName $ProjectName + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'Enable' - PropertyValue = $false - } - @{ - PropertyName = 'AdditionalTimeout' - PropertyValue = 5 - } - @{ - PropertyName = 'RetryInterval' - PropertyValue = 4 + $script:mockInstance = [DnsServerRecursion] @{ + DnsServer = 'SomeHost' } - @{ - PropertyName = 'Timeout' - PropertyValue = 9 + } + Mock -CommandName Get-DnsServerRecursion -MockWith { + return New-CimInstance -ClassName 'DnsServerRecursion' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + Enable = $true + AdditionalTimeout = 4 + RetryInterval = 3 + Timeout = 8 } - ) + } } - BeforeEach { - $mockDnsServerRecursionInstance = InModuleScope $ProjectName { - [DnsServerRecursion]::new() - } + It 'Should return the correct values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - # Override Get() method - $mockDnsServerRecursionInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerRecursion] @{ - DnsServer = 'localhost' - Enable = $true - AdditionalTimeout = 4 - RetryInterval = 3 - Timeout = 8 - } + $currentState = $script:mockInstance.GetCurrentState( + @{ + DnsServer = 'SomeHost' } - } - } - - Context 'When parameter DnsServer is set to ''localhost''' { - It 'Should set the desired value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue ) - $mockDnsServerRecursionInstance.DnsServer = 'localhost' - $mockDnsServerRecursionInstance.$PropertyName = $PropertyValue - - { $mockDnsServerRecursionInstance.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Set-DnsServerRecursion -ModuleName $ProjectName -Exactly -Times 1 -Scope It + $currentState.DnsServer | Should -Be 'SomeHost' + $currentState.Enable | Should -BeTrue + $currentState.AdditionalTimeout | Should -Be 4 + $currentState.RetryInterval | Should -Be 3 + $currentState.Timeout | Should -Be 8 } + + Should -Invoke -CommandName Get-DnsServerRecursion -Exactly -Times 1 -Scope It } + } +} - Context 'When parameter DnsServer is set to ''dns.company.local''' { - It 'Should set the desired value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) +Describe 'DnsServerRecursion\Modify()' -Tag 'HiddenMember' { + Context 'When the system is not in the desired state' { + Context 'When the property is not in desired state' -ForEach @( + @{ + PropertyName = 'Enable' + SetPropertyName = 'Enable' + ExpectedValue = $true + } + @{ + PropertyName = 'AdditionalTimeout' + SetPropertyName = 'AdditionalTimeout' + ExpectedValue = 4 + } + @{ + PropertyName = 'RetryInterval' + SetPropertyName = 'RetryInterval' + ExpectedValue = 5 + } + @{ + PropertyName = 'Timeout' + SetPropertyName = 'Timeout' + ExpectedValue = 7 + } + ) { + BeforeAll { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerRecursion] @{ + DnsServer = 'localhost' + $PropertyName = $ExpectedValue + } | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } -PassThru + } + Mock -CommandName Set-DnsServerRecursion + } - $mockDnsServerRecursionInstance.DnsServer = 'dns.company.local' - $mockDnsServerRecursionInstance.$PropertyName = $PropertyValue + It 'Should call the correct mocks' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerRecursionInstance.Set() } | Should -Not -Throw + $script:mockInstance.Modify( + # This is the properties not in desired state. + @{ + $PropertyName = $ExpectedValue + } + ) - Assert-MockCalled -CommandName Set-DnsServerRecursion -ModuleName $ProjectName -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Set-DnsServerRecursion -ParameterFilter { + $PesterBoundParameters.$SetPropertyName -eq $ExpectedValue + } -Exactly -Times 1 -Scope It + } } } } diff --git a/tests/Unit/Classes/DnsServerScavenging.Tests.ps1 b/tests/Unit/Classes/DnsServerScavenging.Tests.ps1 index f88b3592..cc304df2 100644 --- a/tests/Unit/Classes/DnsServerScavenging.Tests.ps1 +++ b/tests/Unit/Classes/DnsServerScavenging.Tests.ps1 @@ -1,49 +1,123 @@ -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = ( - Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $( - try +<# + .SYNOPSIS + Unit test for DSC_DnsServerScavenging DSC resource. +#> + +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force + + # Unload the stub module. + Remove-Module -Name DnsServer -Force +} + +Describe 'DnsServerScavenging' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + { [DnsServerScavenging]::new() } | Should -Not -Throw } - ) + } + + It 'Has a default or empty constructor' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockInstance = [DnsServerScavenging]::new() + $mockInstance | Should -Not -BeNullOrEmpty + } + } } -).BaseName -Import-Module $ProjectName + Context 'Type creation' { + It 'Should be type named DnsServerScavenging' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -Get-Module -Name 'DnsServer' -All | Remove-Module -Force -Import-Module -Name "$PSScriptRoot\..\Stubs\DnsServer.psm1" + $mockInstance = [DnsServerScavenging]::new() + $mockInstance.GetType().Name | Should -Be 'DnsServerScavenging' + } + } + } +} Describe 'DnsServerScavenging\Get()' -Tag 'Get' { Context 'When the system is in the desired state' { BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - Mock -CommandName Get-DnsServerScavenging -ModuleName $ProjectName -MockWith { - return New-CimInstance -ClassName 'DnsServerScavenging' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerScavenging] @{ ScavengingState = $true ScavengingInterval = '30.00:00:00' RefreshInterval = '30.00:00:00' NoRefreshInterval = '30.00:00:00' - LastScavengeTime = '2021-01-01 00:00:00' } - } - } - BeforeEach { - $mockDnsServerScavengingInstance = InModuleScope $ProjectName { - [DnsServerScavenging]::new() - } - } + <# + This mocks the method GetCurrentState(). + + Method Get() will call the base method Get() which will + call back to the derived class method GetCurrentState() + to get the result to return from the derived method Get(). + #> + $script:mockInstance | Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetCurrentState' -Value { + return @{ + ScavengingState = $true + ScavengingInterval = '30.00:00:00' + RefreshInterval = '30.00:00:00' + NoRefreshInterval = '30.00:00:00' + LastScavengeTime = '2021-01-01 00:00:00' - It 'Should have correctly instantiated the resource class' { - $mockDnsServerScavengingInstance | Should -Not -BeNullOrEmpty - $mockDnsServerScavengingInstance.GetType().Name | Should -Be 'DnsServerScavenging' + } + } -PassThru | Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } + } } It 'Should return the correct values for the properties when DnsServer is set to ''''' -TestCases @( @@ -54,371 +128,472 @@ Describe 'DnsServerScavenging\Get()' -Tag 'Get' { HostName = 'dns.company.local' } ) { - param - ( - $HostName - ) + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerScavengingInstance.DnsServer = $HostName - - $getResult = $mockDnsServerScavengingInstance.Get() - - $getResult.DnsServer | Should -Be $HostName - $getResult.ScavengingState | Should -BeTrue - $getResult.ScavengingInterval | Should -Be '30.00:00:00' - $getResult.RefreshInterval | Should -Be '30.00:00:00' - $getResult.NoRefreshInterval | Should -Be '30.00:00:00' + $script:mockInstance.DnsServer = $HostName + $script:mockInstance.GetCurrentState( + @{ + DnsServer = $HostName + } + ) - # Returns as a DateTime type and not a string. - $getResult.LastScavengeTime.ToString('yyyy-mm-dd HH:mm:ss') | Should -Be ([System.DateTime] '2021-01-01 00:00:00').ToString('yyyy-mm-dd HH:mm:ss') + $getResult = $script:mockInstance.Get() - Assert-MockCalled -CommandName Get-DnsServerScavenging -ModuleName $ProjectName -Exactly -Times 1 -Scope It + $getResult.DnsServer | Should -Be $HostName + $getResult.ScavengingState | Should -BeTrue + $getResult.ScavengingInterval | Should -Be '30.00:00:00' + $getResult.RefreshInterval | Should -Be '30.00:00:00' + $getResult.NoRefreshInterval | Should -Be '30.00:00:00' + # Returns as a DateTime type and not a string. + $getResult.LastScavengeTime.ToString('yyyy-mm-dd HH:mm:ss') | Should -Be ([System.DateTime] '2021-01-01 00:00:00').ToString('yyyy-mm-dd HH:mm:ss') + $getResult.Reasons | Should -BeNullOrEmpty + } } } -} -Describe 'DnsServerScavenging\Test()' -Tag 'Test' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - } + Context 'When the system is not in the desired state' { + Context 'When property ScavengingInterval has the wrong value' { - Context 'When providing an invalid interval' { - BeforeEach { - $mockDnsServerScavengingInstance = InModuleScope $ProjectName { - [DnsServerScavenging]::new() - } - } + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the value is a string that cannot be converted to [System.TimeSpan]' { - It 'Should throw the correct error' { - $mockInvalidTime = '235.a:00:00' + $script:mockInstance = [DnsServerScavenging] @{ + ScavengingState = $true + ScavengingInterval = '30.00:00:00' + RefreshInterval = '30.00:00:00' + NoRefreshInterval = '30.00:00:00' + } - $mockDnsServerScavengingInstance.ScavengingInterval = $mockInvalidTime + <# + This mocks the method GetCurrentState(). - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyHasWrongFormat - } + Method Get() will call the base method Get() which will + call back to the derived class method GetCurrentState() + to get the result to return from the derived method Get(). + #> + $script:mockInstance | Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetCurrentState' -Value { + return @{ + ScavengingState = $true + ScavengingInterval = '40.00:00:00' + RefreshInterval = '30.00:00:00' + NoRefreshInterval = '30.00:00:00' + LastScavengeTime = '2021-01-01 00:00:00' - { $mockDnsServerScavengingInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'ScavengingInterval', $mockInvalidTime) + } + } -PassThru | Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } + } } - } - Context 'When the time exceeds maximum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '365.00:00:01' + It 'Should return the correct values for the properties when DnsServer is set to ''''' -TestCases @( + @{ + HostName = 'localhost' + } + @{ + HostName = 'dns.company.local' + } + ) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance.DnsServer = $HostName + $script:mockInstance.GetCurrentState( + @{ + DnsServer = $HostName + } + ) - $mockDnsServerScavengingInstance.ScavengingInterval = $mockInvalidTime + $getResult = $script:mockInstance.Get() - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanExceedMaximumValue - } + $getResult.DnsServer | Should -Be $HostName + $getResult.ScavengingState | Should -BeTrue + $getResult.ScavengingInterval | Should -Be '40.00:00:00' + $getResult.RefreshInterval | Should -Be '30.00:00:00' + $getResult.NoRefreshInterval | Should -Be '30.00:00:00' + # Returns as a DateTime type and not a string. + $getResult.LastScavengeTime.ToString('yyyy-mm-dd HH:mm:ss') | Should -Be ([System.DateTime] '2021-01-01 00:00:00').ToString('yyyy-mm-dd HH:mm:ss') - { $mockDnsServerScavengingInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'ScavengingInterval', $mockInvalidTime, '365.00:00:00') + $getResult.Reasons | Should -HaveCount 1 + $getResult.Reasons[0].Code | Should -Be 'DnsServerScavenging:DnsServerScavenging:ScavengingInterval' + $getResult.Reasons[0].Phrase | Should -Be 'The property ScavengingInterval should be "30.00:00:00", but was "40.00:00:00"' + } } } + } +} - Context 'When the time is below minimum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '-1.00:00:00' - - $mockDnsServerScavengingInstance.ScavengingInterval = $mockInvalidTime +Describe 'DnsServerScavenging\Set()' -Tag 'Set' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerScavenging] @{ + ScavengingState = $true + ScavengingInterval = '30.00:00:00' + RefreshInterval = '30.00:00:00' + NoRefreshInterval = '30.00:00:00' + } | + # Mock method Modify which is called by the case method Set(). + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Modify' -Value { + $script:methodModifyCallCount += 1 + } -PassThru + } + } - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanBelowMinimumValue - } + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerScavengingInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'ScavengingInterval', $mockInvalidTime, '00:00:00') - } + $script:methodModifyCallCount = 0 } } Context 'When the system is in the desired state' { BeforeAll { - $mockDnsServerScavengingInstance = InModuleScope $ProjectName { - [DnsServerScavenging]::new() - } - - $mockDnsServerScavengingInstance.ScavengingState = $true - $mockDnsServerScavengingInstance.ScavengingInterval = '30.00:00:00' - $mockDnsServerScavengingInstance.RefreshInterval = '30.00:00:00' - $mockDnsServerScavengingInstance.NoRefreshInterval = '30.00:00:00' - $mockDnsServerScavengingInstance.LastScavengeTime = '2021-01-01 00:00:00' - - # Override Get() method - $mockDnsServerScavengingInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerScavenging] @{ - DnsServer = 'localhost' - ScavengingState = $true - ScavengingInterval = '30.00:00:00' - RefreshInterval = '30.00:00:00' - NoRefreshInterval = '30.00:00:00' - LastScavengeTime = '2021-01-01 00:00:00' - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return $null + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - } + } } - It 'Should return the $true' { - $getResult = $mockDnsServerScavengingInstance.Test() + It 'Should not call method Modify()' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult | Should -BeTrue + $script:mockInstance.Set() + + $script:methodModifyCallCount | Should -Be 0 + } } } Context 'When the system is not in the desired state' { BeforeAll { - $testCases = @( - @{ - PropertyName = 'ScavengingState' - PropertyValue = $false - } - @{ - PropertyName = 'ScavengingInterval' - PropertyValue = '7.00:00:00' - } - @{ - PropertyName = 'RefreshInterval' - PropertyValue = '7.00:00:00' - } - @{ - PropertyName = 'NoRefreshInterval' - PropertyValue = '7.00:00:00' - } - ) - } - - BeforeEach { - $mockDnsServerScavengingInstance = InModuleScope $ProjectName { - [DnsServerScavenging]::new() - } - - # Override Get() method - $mockDnsServerScavengingInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerScavenging] @{ - DnsServer = 'localhost' - ScavengingState = $true - ScavengingInterval = '30.00:00:00' - RefreshInterval = '30.00:00:00' - NoRefreshInterval = '30.00:00:00' - LastScavengeTime = '2021-01-01 00:00:00' + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return @{ + Property = 'ScavengingInterval' + ExpectedValue = '30.00:00:00' + ActualValue = '14.00:00:00' } + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return } - } + } } - It 'Should return the $false when property is not in desired state' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) - - $mockDnsServerScavengingInstance.$PropertyName = $PropertyValue + It 'Should call method Modify()' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getResult = $mockDnsServerScavengingInstance.Test() + $script:mockInstance.Set() - $getResult | Should -BeFalse + $script:methodModifyCallCount | Should -Be 1 + } } } } -Describe 'DnsServerScavenging\Set()' -Tag 'Set' { +Describe 'DnsServerScavenging\Test()' -Tag 'Test' { BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerScavenging] @{ + ScavengingState = $true + ScavengingInterval = '30.00:00:00' + RefreshInterval = '30.00:00:00' + NoRefreshInterval = '30.00:00:00' + } + } } - - Context 'When providing an invalid interval' { - BeforeEach { - $mockDnsServerScavengingInstance = InModuleScope $ProjectName { - [DnsServerScavenging]::new() + Context 'When the system is in the desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return $null + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } } } - Context 'When the value is a string that cannot be converted to [System.TimeSpan]' { - It 'Should throw the correct error' { - $mockInvalidTime = '235.a:00:00' + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerScavengingInstance.ScavengingInterval = $mockInvalidTime + $script:mockInstance.Test() | Should -BeTrue + } + } - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.PropertyHasWrongFormat + Context 'When the system is not in the desired state' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance | + # Mock method Compare() which is called by the base method Set() + Add-Member -Force -MemberType 'ScriptMethod' -Name 'Compare' -Value { + return @{ + DnsServer = 'localhost' + ScavengingState = $false + ScavengingInterval = '10.00:00:00' + RefreshInterval = '20.00:00:00' + NoRefreshInterval = '25.00:00:00' + } + } -PassThru | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } } + } - { $mockDnsServerScavengingInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'ScavengingInterval', $mockInvalidTime) + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance.Test() | Should -BeFalse + } } } + } +} - Context 'When the time exceeds maximum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '365.00:00:01' - - $mockDnsServerScavengingInstance.ScavengingInterval = $mockInvalidTime +Describe 'DnsServerScavenging\AssertProperties()' -Tag 'HiddenMember' { + Context 'When the property '''' is not correct' -ForEach @( + @{ + Name = 'ScavengingInterval' + BadFormat = '235.a:00:00' + TooLow = '-1.00:00:00' + TooHigh = '366.00:00:00' + } + @{ + Name = 'RefreshInterval' + BadFormat = '235.a:00:00' + TooLow = '-1.00:00:00' + TooHigh = '366.00:00:00' + } + @{ + Name = 'RefreshInterval' + BadFormat = '235.a:00:00' + TooLow = '-1.00:00:00' + TooHigh = '366.00:00:00' + } + ) { + BeforeAll { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanExceedMaximumValue + $script:mockInstance = [DnsServerScavenging] @{ + DnsServer = 'localhost' } + } + Mock -CommandName Assert-TimeSpan + } + + It 'Should throw the correct error when a bad format' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerScavengingInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'ScavengingInterval', $mockInvalidTime, '365.00:00:00') + { + $script:mockInstance.AssertProperties( + @{ + $Name = $BadFormat + } + ) + } | Should -Not -Throw } + + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It } - Context 'When the time is below minimum allowed value' { - It 'Should throw the correct error' { - $mockInvalidTime = '-1.00:00:00' + It 'Should throw the correct error when too small' -Skip:([System.String]::IsNullOrEmpty($TooLow)) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerScavengingInstance.ScavengingInterval = $mockInvalidTime + { + $script:mockInstance.AssertProperties( + @{ + $Name = $TooLow + } + ) + } | Should -Not -Throw + } - $mockExpectedErrorMessage = InModuleScope $ProjectName { - $script:localizedData.TimeSpanBelowMinimumValue - } + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It + } + + It 'Should throw the correct error when too big' -Skip:([System.String]::IsNullOrEmpty($TooHigh)) { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerScavengingInstance.Test() } | Should -Throw ($mockExpectedErrorMessage -f 'ScavengingInterval', $mockInvalidTime, '00:00:00') + { + $script:mockInstance.AssertProperties( + @{ + $Name = $TooHigh + } + ) + } | Should -Not -Throw } + + Should -Invoke -CommandName Assert-TimeSpan -Exactly -Times 1 -Scope It } } +} - Context 'When the system is in the desired state' { +Describe 'DnsServerScavenging\GetCurrentState()' -Tag 'HiddenMember' { + Context 'When object is missing in the current state' { BeforeAll { - Mock -CommandName Set-DnsServerScavenging -ModuleName $ProjectName + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'ScavengingState' - PropertyValue = $true - } - @{ - PropertyName = 'ScavengingInterval' - PropertyValue = '30.00:00:00' + $script:mockInstance = [DnsServerScavenging] @{ + DnsServer = 'localhost' } - @{ - PropertyName = 'RefreshInterval' - PropertyValue = '30.00:00:00' - } - @{ - PropertyName = 'NoRefreshInterval' - PropertyValue = '30.00:00:00' - } - ) - } - - BeforeEach { - $mockDnsServerScavengingInstance = InModuleScope $ProjectName { - [DnsServerScavenging]::new() } - - $mockDnsServerScavengingInstance.DnsServer = 'localhost' - - # Override Get() method - $mockDnsServerScavengingInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerScavenging] @{ - DnsServer = 'localhost' - ScavengingState = $true - ScavengingInterval = '30.00:00:00' - RefreshInterval = '30.00:00:00' - NoRefreshInterval = '30.00:00:00' - LastScavengeTime = '2021-01-01 00:00:00' - } - } - } + Mock -CommandName Get-DnsServerScavenging } - It 'Should not call any mock to set a value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + It 'Should return the correct values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $mockDnsServerScavengingInstance.$PropertyName = $PropertyValue + $currentState = $script:mockInstance.GetCurrentState( + @{ + DnsServer = 'localhost' + } + ) - { $mockDnsServerScavengingInstance.Set() } | Should -Not -Throw + $currentState.DnsServer | Should -Be 'localhost' + $currentState.ScavengingState | Should -BeFalse + $currentState.ScavengingInterval | Should -BeNullOrEmpty + $currentState.RefreshInterval | Should -BeNullOrEmpty + $currentState.NoRefreshInterval | Should -BeNullOrEmpty + $currentState.LastScavengeTime | Should -BeNullOrEmpty + } - Assert-MockCalled -CommandName Set-DnsServerScavenging -ModuleName $ProjectName -Exactly -Times 0 -Scope It + Should -Invoke -CommandName Get-DnsServerScavenging -Exactly -Times 1 -Scope It } } - Context 'When the system is not in the desired state' { + Context 'When the object is present in the current state' { BeforeAll { - Mock -CommandName Set-DnsServerScavenging -ModuleName $ProjectName + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'ScavengingState' - PropertyValue = $false - } - @{ - PropertyName = 'ScavengingInterval' - PropertyValue = '7.00:00:00' + $script:mockInstance = [DnsServerScavenging] @{ + DnsServer = 'SomeHost' } - @{ - PropertyName = 'RefreshInterval' - PropertyValue = '7.00:00:00' - } - @{ - PropertyName = 'NoRefreshInterval' - PropertyValue = '7.00:00:00' + } + Mock -CommandName Get-DnsServerScavenging -MockWith { + return New-CimInstance -ClassName 'DnsServerScavenging' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + ScavengingState = $true + ScavengingInterval = '30.00:00:00' + RefreshInterval = '30.00:00:00' + NoRefreshInterval = '30.00:00:00' + LastScavengeTime = '2021-01-01 00:00:00' } - ) + } } - BeforeEach { - $mockDnsServerScavengingInstance = InModuleScope $ProjectName { - [DnsServerScavenging]::new() - } + It 'Should return the correct values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - # Override Get() method - $mockDnsServerScavengingInstance | - Add-Member -Force -MemberType ScriptMethod -Name Get -Value { - return InModuleScope $ProjectName { - [DnsServerScavenging] @{ - DnsServer = 'localhost' - ScavengingState = $true - ScavengingInterval = '30.00:00:00' - RefreshInterval = '30.00:00:00' - NoRefreshInterval = '30.00:00:00' - LastScavengeTime = '2021-01-01 00:00:00' - } + $currentState = $script:mockInstance.GetCurrentState( + @{ + DnsServer = 'SomeHost' } - } - } - - Context 'When parameter DnsServer is set to ''localhost''' { - It 'Should set the desired value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue ) - $mockDnsServerScavengingInstance.DnsServer = 'localhost' - $mockDnsServerScavengingInstance.$PropertyName = $PropertyValue - - { $mockDnsServerScavengingInstance.Set() } | Should -Not -Throw - - Assert-MockCalled -CommandName Set-DnsServerScavenging -ModuleName $ProjectName -Exactly -Times 1 -Scope It + $currentState.DnsServer | Should -Be 'SomeHost' + $currentState.ScavengingState | Should -BeTrue + $currentState.ScavengingInterval | Should -Be '30.00:00:00' + $currentState.RefreshInterval | Should -Be '30.00:00:00' + $currentState.NoRefreshInterval | Should -Be '30.00:00:00' + $currentState.LastScavengeTime | Should -Be '2021-01-01 00:00:00' } + + Should -Invoke -CommandName Get-DnsServerScavenging -Exactly -Times 1 -Scope It } + } +} - Context 'When parameter DnsServer is set to ''dns.company.local''' { - It 'Should set the desired value for property ''''' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) +Describe 'DnsServerScavenging\Modify()' -Tag 'HiddenMember' { + Context 'When the system is not in the desired state' { + Context 'When the property is not in desired state' -ForEach @( + @{ + PropertyName = 'ScavengingState' + SetPropertyName = 'ScavengingState' + ExpectedValue = $true + } + @{ + PropertyName = 'ScavengingInterval' + SetPropertyName = 'ScavengingInterval' + ExpectedValue = '10.00:00:00' + } + @{ + PropertyName = 'RefreshInterval' + SetPropertyName = 'RefreshInterval' + ExpectedValue = '20.00:00:00' + } + @{ + PropertyName = 'NoRefreshInterval' + SetPropertyName = 'NoRefreshInterval' + ExpectedValue = '25.00:00:00' + } + ) { + BeforeAll { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockInstance = [DnsServerScavenging] @{ + DnsServer = 'localhost' + $PropertyName = $ExpectedValue + } | + Add-Member -Force -MemberType 'ScriptMethod' -Name 'AssertProperties' -Value { + return + } -PassThru + } + Mock -CommandName Set-DnsServerScavenging + } - $mockDnsServerScavengingInstance.DnsServer = 'dns.company.local' - $mockDnsServerScavengingInstance.$PropertyName = $PropertyValue + It 'Should call the correct mocks' { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - { $mockDnsServerScavengingInstance.Set() } | Should -Not -Throw + $script:mockInstance.Modify( + # This is the properties not in desired state. + @{ + $PropertyName = $ExpectedValue + } + ) - Assert-MockCalled -CommandName Set-DnsServerScavenging -ModuleName $ProjectName -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Set-DnsServerScavenging -ParameterFilter { + $PesterBoundParameters.$SetPropertyName -eq $ExpectedValue + } -Exactly -Times 1 -Scope It + } } } } diff --git a/tests/Unit/Classes/ResourceBase.Tests.ps1 b/tests/Unit/Classes/ResourceBase.Tests.ps1 deleted file mode 100644 index 7c023a78..00000000 --- a/tests/Unit/Classes/ResourceBase.Tests.ps1 +++ /dev/null @@ -1,650 +0,0 @@ -<# - Must have this for the test to work where it creates a class that inherits from - the ResourceBase class. -#> -using module DnsServerDsc - -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = ( - Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $( - try - { - Test-ModuleManifest $_.FullName -ErrorAction Stop - } - catch - { - $false - } - ) - } -).BaseName - -Import-Module $ProjectName - -Describe 'ResourceBase\GetCurrentState()' -Tag 'GetCurrentState' { - Context 'When the required methods are not overridden' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - [ResourceBase]::new() - } - } - - Context 'When there is no override for the method GetCurrentState' { - It 'Should throw the correct error' { - { $mockResourceBaseInstance.GetCurrentState(@{}) } | Should -Throw $mockResourceBaseInstance.GetCurrentStateMethodNotImplemented - } - } - } -} - -Describe 'ResourceBase\Modify()' -Tag 'Modify' { - Context 'When the required methods are not overridden' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - [ResourceBase]::new() - } - } - - - Context 'When there is no override for the method Modify' { - It 'Should throw the correct error' { - { $mockResourceBaseInstance.Modify(@{}) } | Should -Throw $mockResourceBaseInstance.ModifyMethodNotImplemented - } - } - } -} - -Describe 'ResourceBase\AssertProperties()' -Tag 'AssertProperties' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - [ResourceBase]::new() - } - } - - - It 'Should not throw' { - { $mockResourceBaseInstance.AssertProperties() } | Should -Not -Throw - } -} - -Describe 'ResourceBase\Get()' -Tag 'Get' { - Context 'When the required methods are not overridden' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - [ResourceBase]::new() - } - } - - Context 'When there is no override for the method GetCurrentState' { - It 'Should throw the correct error' { - { $mockResourceBaseInstance.GetCurrentState(@{}) } | Should -Throw $mockResourceBaseInstance.GetCurrentStateMethodNotImplemented - } - } - - Context 'When there is no override for the method Modify' { - It 'Should throw the correct error' { - { $mockResourceBaseInstance.Modify(@{}) } | Should -Throw $mockResourceBaseInstance.ModifyMethodNotImplemented - } - } - } - - Context 'When the system is in the desired state' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - Mock -CommandName Get-ClassName -MockWith { - # Only return localized strings for this class name. - @('ResourceBase') - } -ModuleName $ProjectName - - $mockResourceBaseInstance = InModuleScope $ProjectName { - class MyMockResource : ResourceBase - { - [DscProperty(Key)] - [System.String] - $DnsServer - - [DscProperty()] - [System.String] - $MyResourceProperty - - [Microsoft.Management.Infrastructure.CimInstance] GetCurrentState([System.Collections.Hashtable] $properties) - { - return New-CimInstance -ClassName 'AnyClassName' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ - MyResourceProperty = 'MyValue1' - } - } - } - - [MyMockResource]::new() - } - } - - It 'Should have correctly instantiated the resource class' { - $mockResourceBaseInstance | Should -Not -BeNullOrEmpty - $mockResourceBaseInstance.GetType().BaseType.Name | Should -Be 'ResourceBase' - } - - Context 'When DnsServer is set to ''localhost''' { - BeforeAll { - $mockResourceBaseInstance.DnsServer = 'localhost' - } - - It 'Should return the correct values for the properties' { - $getResult = $mockResourceBaseInstance.Get() - - $getResult.DnsServer | Should -Be 'localhost' - $getResult.MyResourceProperty | Should -Be 'MyValue1' - } - } - - Context 'When DnsServer is set to ''dns.company.local''' { - BeforeAll { - $mockResourceBaseInstance.DnsServer = 'dns.company.local' - } - - It 'Should return the correct values for the properties' { - $getResult = $mockResourceBaseInstance.Get() - - $getResult.DnsServer | Should -Be 'dns.company.local' - $getResult.MyResourceProperty | Should -Be 'MyValue1' - } - } - } -} - -Describe 'ResourceBase\Test()' -Tag 'Test' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - Mock -CommandName Get-ClassName -MockWith { - # Only return localized strings for this class name. - @('ResourceBase') - } -ModuleName $ProjectName - } - - Context 'When the system is in the desired state' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - class MyMockResource : ResourceBase - { - [DscProperty(Key)] - [System.String] - $DnsServer - - [DscProperty()] - [System.String] - $MyResourceProperty - - [System.Collections.Hashtable[]] Compare() - { - return $null - } - } - - [MyMockResource]::new() - } - } - - It 'Should have correctly instantiated the resource class' { - $mockResourceBaseInstance | Should -Not -BeNullOrEmpty - $mockResourceBaseInstance.GetType().BaseType.Name | Should -Be 'ResourceBase' - } - - It 'Should return $true' { - $mockResourceBaseInstance.Test() | Should -BeTrue - } - } - - Context 'When the system is not in the desired state' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - class MyMockResource : ResourceBase - { - [DscProperty(Key)] - [System.String] - $DnsServer - - [DscProperty()] - [System.String] - $MyResourceProperty - - [System.Collections.Hashtable[]] Compare() - { - # Could just return any non-null object, but mocking a real result. - return @{ - Property = 'MyResourceProperty' - ExpectedValue = '1' - ActualValue = '2' - } - } - } - - [MyMockResource]::new() - } - } - - It 'Should have correctly instantiated the resource class' { - $mockResourceBaseInstance | Should -Not -BeNullOrEmpty - $mockResourceBaseInstance.GetType().BaseType.Name | Should -Be 'ResourceBase' - } - - It 'Should return $true' { - $mockResourceBaseInstance.Test() | Should -BeFalse - } - } -} - -Describe 'ResourceBase\Compare()' -Tag 'Compare' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - Mock -CommandName Get-ClassName -MockWith { - # Only return localized strings for this class name. - @('ResourceBase') - } -ModuleName $ProjectName - } - - Context 'When the system is in the desired state' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - class MyMockResource : ResourceBase - { - [DscProperty(Key)] - [System.String] - $DnsServer - - [DscProperty()] - [System.String] - $MyResourceProperty - - [DscProperty(NotConfigurable)] - [System.String] - $MyResourceReadProperty - - [ResourceBase] Get() - { - # Creates a new instance of the mock instance MyMockResource. - $currentStateInstance = [System.Activator]::CreateInstance($this.GetType()) - - $currentStateInstance.MyResourceProperty = 'MyValue1' - $currentStateInstance.MyResourceReadProperty = 'MyReadValue1' - - return $currentStateInstance - } - } - - [MyMockResource]::new() - } - } - - It 'Should have correctly instantiated the resource class' { - $mockResourceBaseInstance | Should -Not -BeNullOrEmpty - $mockResourceBaseInstance.GetType().BaseType.Name | Should -Be 'ResourceBase' - } - - Context 'When no properties are enforced' { - It 'Should not return any property to enforce' { - $mockResourceBaseInstance.Compare() | Should -BeNullOrEmpty - } - } - - Context 'When one property are enforced but in desired state' { - BeforeAll { - $mockResourceBaseInstance.MyResourceProperty = 'MyValue1' - } - - It 'Should not return any property to enforce' { - $mockResourceBaseInstance.Compare() | Should -BeNullOrEmpty -Because 'nothing means all properties are in desired state' - } - } - } - - Context 'When the system is not in the desired state' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - class MyMockResource : ResourceBase - { - [DscProperty(Key)] - [System.String] - $DnsServer - - [DscProperty()] - [System.String] - $MyResourceProperty1 - - [DscProperty()] - [System.String] - $MyResourceProperty2 - - [DscProperty(NotConfigurable)] - [System.String] - $MyResourceReadProperty - - [ResourceBase] Get() - { - # Creates a new instance of the mock instance MyMockResource. - $currentStateInstance = [System.Activator]::CreateInstance($this.GetType()) - - $currentStateInstance.MyResourceProperty1 = 'MyValue1' - $currentStateInstance.MyResourceProperty2 = 'MyValue2' - $currentStateInstance.MyResourceReadProperty = 'MyReadValue1' - - return $currentStateInstance - } - } - - [MyMockResource]::new() - } - } - - It 'Should have correctly instantiated the resource class' { - $mockResourceBaseInstance | Should -Not -BeNullOrEmpty - $mockResourceBaseInstance.GetType().BaseType.Name | Should -Be 'ResourceBase' - } - - Context 'When only enforcing one property' { - BeforeAll { - # Set desired value for the property that should be enforced. - $mockResourceBaseInstance.MyResourceProperty1 = 'MyNewValue1' - } - - It 'Should return the correct property that is not in desired state' { - $compareResult = $mockResourceBaseInstance.Compare() - $compareResult | Should -HaveCount 1 - - $compareResult[0].Property | Should -Be 'MyResourceProperty1' - $compareResult[0].ExpectedValue | Should -Be 'MyNewValue1' - $compareResult[0].ActualValue | Should -Be 'MyValue1' - } - } - - Context 'When only enforcing two properties' { - BeforeAll { - # Set desired value for the properties that should be enforced. - $mockResourceBaseInstance.MyResourceProperty1 = 'MyNewValue1' - $mockResourceBaseInstance.MyResourceProperty2 = 'MyNewValue2' - } - - It 'Should return the correct property that is not in desired state' { - <# - The properties that are returned are not [ordered] so they can - come in any order from run to run. The test handle that. - #> - $compareResult = $mockResourceBaseInstance.Compare() - $compareResult | Should -HaveCount 2 - - $compareResult.Property | Should -Contain 'MyResourceProperty1' - $compareResult.Property | Should -Contain 'MyResourceProperty2' - - $compareProperty = $compareResult.Where( { $_.Property -eq 'MyResourceProperty1' }) - $compareProperty.ExpectedValue | Should -Be 'MyNewValue1' - $compareProperty.ActualValue | Should -Be 'MyValue1' - - $compareProperty = $compareResult.Where( { $_.Property -eq 'MyResourceProperty2' }) - $compareProperty.ExpectedValue | Should -Be 'MyNewValue2' - $compareProperty.ActualValue | Should -Be 'MyValue2' - } - } - } -} - -Describe 'ResourceBase\GetDesiredStateForSplatting()' -Tag 'GetDesiredStateForSplatting' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - [ResourceBase]::new() - } - - $mockProperties = @( - @{ - Property = 'MyResourceProperty1' - ExpectedValue = 'MyNewValue1' - ActualValue = 'MyValue1' - }, - @{ - Property = 'MyResourceProperty2' - ExpectedValue = 'MyNewValue2' - ActualValue = 'MyValue2' - } - ) - } - - It 'Should return the correct values in a hashtable' { - $getDesiredStateForSplattingResult = $mockResourceBaseInstance.GetDesiredStateForSplatting($mockProperties) - - $getDesiredStateForSplattingResult | Should -BeOfType [System.Collections.Hashtable] - - $getDesiredStateForSplattingResult.Keys | Should -HaveCount 2 - $getDesiredStateForSplattingResult.Keys | Should -Contain 'MyResourceProperty1' - $getDesiredStateForSplattingResult.Keys | Should -Contain 'MyResourceProperty2' - - $getDesiredStateForSplattingResult.MyResourceProperty1 | Should -Be 'MyNewValue1' - $getDesiredStateForSplattingResult.MyResourceProperty2 | Should -Be 'MyNewValue2' - } -} - - -Describe 'ResourceBase\Set()' -Tag 'Set' { - BeforeAll { - Mock -CommandName Assert-Module -ModuleName $ProjectName - Mock -CommandName Get-ClassName -MockWith { - # Only return localized strings for this class name. - @('ResourceBase') - } -ModuleName $ProjectName - } - - Context 'When the system is in the desired state' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - class MyMockResource : ResourceBase - { - [DscProperty(Key)] - [System.String] - $DnsServer - - [DscProperty()] - [System.String] - $MyResourceProperty1 - - [DscProperty()] - [System.String] - $MyResourceProperty2 - - # Hidden property to determine whether the method Modify() was called. - hidden [System.Collections.Hashtable] $mockModifyProperties = @{} - - [System.Collections.Hashtable[]] Compare() - { - return $null - } - - [void] Modify([System.Collections.Hashtable] $properties) - { - $this.mockModifyProperties = $properties - } - } - - [MyMockResource]::new() - } - } - - It 'Should have correctly instantiated the resource class' { - $mockResourceBaseInstance | Should -Not -BeNullOrEmpty - $mockResourceBaseInstance.GetType().BaseType.Name | Should -Be 'ResourceBase' - } - - It 'Should not set any property' { - $mockResourceBaseInstance.Set() - - $mockResourceBaseInstance.mockModifyProperties | Should -BeNullOrEmpty - } - } - - Context 'When the system is not in the desired state' { - Context 'When setting one property' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - class MyMockResource : ResourceBase - { - [DscProperty(Key)] - [System.String] - $DnsServer - - [DscProperty()] - [System.String] - $MyResourceProperty1 - - [DscProperty()] - [System.String] - $MyResourceProperty2 - - # Hidden property to determine whether the method Modify() was called. - hidden [System.Collections.Hashtable] $mockModifyProperties = @{} - - [System.Collections.Hashtable[]] Compare() - { - return @( - @{ - Property = 'MyResourceProperty1' - ExpectedValue = 'MyNewValue1' - ActualValue = 'MyValue1' - } - ) - } - - [void] Modify([System.Collections.Hashtable] $properties) - { - $this.mockModifyProperties = $properties - } - } - - [MyMockResource]::new() - } - } - - It 'Should have correctly instantiated the resource class' { - $mockResourceBaseInstance | Should -Not -BeNullOrEmpty - $mockResourceBaseInstance.GetType().BaseType.Name | Should -Be 'ResourceBase' - } - - Context 'When DnsServer is set to ''localhost''' { - BeforeAll { - $mockResourceBaseInstance.DnsServer = 'localhost' - } - - It 'Should set the correct property' { - $mockResourceBaseInstance.Set() - - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -HaveCount 1 - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -Contain 'MyResourceProperty1' - - $mockResourceBaseInstance.mockModifyProperties.MyResourceProperty1 | Should -Contain 'MyNewValue1' - } - } - - Context 'When DnsServer is set to ''dns.company.local''' { - BeforeAll { - $mockResourceBaseInstance.DnsServer = 'dns.company.local' - } - - It 'Should set the correct property' { - $mockResourceBaseInstance.Set() - - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -HaveCount 2 - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -Contain 'ComputerName' - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -Contain 'MyResourceProperty1' - - $mockResourceBaseInstance.mockModifyProperties.ComputerName | Should -Contain 'dns.company.local' - $mockResourceBaseInstance.mockModifyProperties.MyResourceProperty1 | Should -Contain 'MyNewValue1' - } - } - } - - Context 'When setting one property' { - BeforeAll { - $mockResourceBaseInstance = InModuleScope $ProjectName { - class MyMockResource : ResourceBase - { - [DscProperty(Key)] - [System.String] - $DnsServer - - [DscProperty()] - [System.String] - $MyResourceProperty1 - - [DscProperty()] - [System.String] - $MyResourceProperty2 - - # Hidden property to determine whether the method Modify() was called. - hidden [System.Collections.Hashtable] $mockModifyProperties = @{} - - [System.Collections.Hashtable[]] Compare() - { - return @( - @{ - Property = 'MyResourceProperty1' - ExpectedValue = 'MyNewValue1' - ActualValue = 'MyValue1' - }, - @{ - Property = 'MyResourceProperty2' - ExpectedValue = 'MyNewValue2' - ActualValue = 'MyValue2' - } - ) - } - - [void] Modify([System.Collections.Hashtable] $properties) - { - $this.mockModifyProperties = $properties - } - } - - [MyMockResource]::new() - } - } - - It 'Should have correctly instantiated the resource class' { - $mockResourceBaseInstance | Should -Not -BeNullOrEmpty - $mockResourceBaseInstance.GetType().BaseType.Name | Should -Be 'ResourceBase' - } - - Context 'When DnsServer is set to ''localhost''' { - BeforeAll { - $mockResourceBaseInstance.DnsServer = 'localhost' - } - - It 'Should set the correct properties' { - $mockResourceBaseInstance.Set() - - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -HaveCount 2 - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -Contain 'MyResourceProperty1' - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -Contain 'MyResourceProperty2' - - $mockResourceBaseInstance.mockModifyProperties.MyResourceProperty1 | Should -Contain 'MyNewValue1' - $mockResourceBaseInstance.mockModifyProperties.MyResourceProperty2 | Should -Contain 'MyNewValue2' - } - } - - Context 'When DnsServer is set to ''dns.company.local''' { - BeforeAll { - $mockResourceBaseInstance.DnsServer = 'dns.company.local' - } - - It 'Should set the correct properties' { - $mockResourceBaseInstance.Set() - - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -HaveCount 3 - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -Contain 'ComputerName' - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -Contain 'MyResourceProperty1' - $mockResourceBaseInstance.mockModifyProperties.Keys | Should -Contain 'MyResourceProperty2' - - $mockResourceBaseInstance.mockModifyProperties.ComputerName | Should -Contain 'dns.company.local' - $mockResourceBaseInstance.mockModifyProperties.MyResourceProperty1 | Should -Contain 'MyNewValue1' - $mockResourceBaseInstance.mockModifyProperties.MyResourceProperty2 | Should -Contain 'MyNewValue2' - } - } - } - } -} diff --git a/tests/Unit/DSC_DnsServerADZone.Tests.ps1 b/tests/Unit/DSC_DnsServerADZone.Tests.ps1 index 3d1bb017..85c35643 100644 --- a/tests/Unit/DSC_DnsServerADZone.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerADZone.Tests.ps1 @@ -1,16 +1,39 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerADZone' - -function Invoke-TestSetup -{ +<# + .SYNOPSIS + Unit test for DSC_DnsServerADZone DSC resource. +#> + +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +# Suppressing this rule because tests are mocking passwords in clear text. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerADZone' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,29 +42,33 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} -Invoke-TestSetup + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force + + Remove-Module -Name DnsServer -Force +} -try -{ - InModuleScope $script:dscResourceName { - #region Pester Test Initialization +Describe 'DSC_DnsServerADZone\Get-TargetResource' -Tag 'Get' { + BeforeAll { $testZoneName = 'example.com' $testDynamicUpdate = 'Secure' $testReplicationScope = 'Domain' $testComputerName = 'dnsserver.local' $testCredential = New-Object System.Management.Automation.PSCredential 'DummyUser', (ConvertTo-SecureString 'DummyPassword' -AsPlainText -Force) $testDirectoryPartitionName = "DomainDnsZones.$testZoneName" - $testParams = @{ - Name = $testZoneName - Verbose = $true - } $fakeDnsADZone = [PSCustomObject] @{ DistinguishedName = $null @@ -53,358 +80,799 @@ try ZoneFile = $null } - $fakePresentTargetResource = @{ - Name = $testZoneName - DynamicUpdate = $testDynamicUpdate - ReplicationScope = $testReplicationScope - DirectoryPartitionName = $testDirectoryPartitionName - Ensure = 'Present' + Mock -CommandName 'Assert-Module' + } + Context 'When DNS zone exists' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsADZone } } + It 'Should return a "System.Collections.Hashtable" object type with schema properties' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + ReplicationScope = 'Domain' + Verbose = $false + } - $fakeAbsentTargetResource = @{ Ensure = 'Absent' } - #endregion - - #region Function Get-TargetResource - Describe 'DSC_DnsServerADZone\Get-TargetResource' { - Mock -CommandName 'Assert-Module' - - It 'Returns a "System.Collections.Hashtable" object type with schema properties' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsADZone } - $targetResource = Get-TargetResource @testParams -ReplicationScope $testReplicationScope - $targetResource -is [System.Collections.Hashtable] | Should Be $true + $targetResource = Get-TargetResource @params + $targetResource -is [System.Collections.Hashtable] | Should -BeTrue $schemaFields = @('Name', 'DynamicUpdate', 'ReplicationScope', 'DirectoryPartitionName', 'Ensure') - ($Null -eq ($targetResource.Keys.GetEnumerator() | Where-Object -FilterScript { $schemaFields -notcontains $_ })) | Should Be $true + ($null -eq ($targetResource.Keys.GetEnumerator() | Where-Object -FilterScript { $schemaFields -notcontains $_ })) | Should -BeTrue } + } + } - It 'Returns "Present" when DNS zone exists and "Ensure" = "Present"' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsADZone } - $targetResource = Get-TargetResource @testParams -ReplicationScope $testReplicationScope - $targetResource.Ensure | Should Be 'Present' - } + Context 'When "Ensure" = "Present"' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsADZone } + } + It 'Should return "Present"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + ReplicationScope = 'Domain' + Verbose = $false + } - It 'Returns "Absent" when DNS zone does not exists and "Ensure" = "Present"' { - Mock -CommandName Get-DnsServerZone - $targetResource = Get-TargetResource @testParams -ReplicationScope $testReplicationScope - $targetResource.Ensure | Should Be 'Absent' + $targetResource = Get-TargetResource @params + $targetResource.Ensure | Should -Be 'Present' } + } + } - It 'Returns "Present" when DNS zone exists and "Ensure" = "Absent"' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsADZone } - $targetResource = Get-TargetResource @testParams -ReplicationScope $testReplicationScope -Ensure Absent - $targetResource.Ensure | Should Be 'Present' - } + Context 'When DNS zone does not exist and "Ensure" = "Present"' { + BeforeAll { + Mock -CommandName Get-DnsServerZone + } + It 'Should return "Absent"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + ReplicationScope = 'Domain' + Verbose = $false + } - It 'Returns "Absent" when DNS zone does not exist and "Ensure" = "Absent"' { - Mock -CommandName Get-DnsServerZone - $targetResource = Get-TargetResource @testParams -ReplicationScope $testReplicationScope -Ensure Absent - $targetResource.Ensure | Should Be 'Absent' + $targetResource = Get-TargetResource @params + $targetResource.Ensure | Should -Be 'Absent' } + } + } - Context 'When a computer name is not passed' { - BeforeAll { - Mock -CommandName New-CimSession - Mock -CommandName Remove-CimSession + Context 'When DNS zone exists and "Ensure" = "Absent"' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsADZone } + } + It 'Should return "Present"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Absent' + ReplicationScope = 'Domain' + Verbose = $false } - It 'Should not call New-CimSession' { - Get-TargetResource @testParams -ReplicationScope $testReplicationScope - Assert-MockCalled -CommandName New-CimSession -Scope It -Times 0 -Exactly + $targetResource = Get-TargetResource @params + $targetResource.Ensure | Should -Be 'Present' + } + } + } + + Context 'When DNS zone does not exist and "Ensure" = "Absent"' { + BeforeAll { + Mock -CommandName Get-DnsServerZone + } + It 'Should return "Absent"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Absent' + ReplicationScope = 'Domain' + Verbose = $false } - It 'Should not call Remove-CimSession' { - Get-TargetResource @testParams -ReplicationScope $testReplicationScope - Assert-MockCalled -CommandName Remove-CimSession -Scope It -Times 0 -Exactly + $targetResource = Get-TargetResource @params + $targetResource.Ensure | Should -Be 'Absent' + } + } + } + + Context 'When a computer name is not passed' { + BeforeAll { + Mock -CommandName New-CimSession + Mock -CommandName Remove-CimSession + Mock -CommandName Get-DnsServerZone + } + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + ReplicationScope = 'Domain' + Verbose = $false } + Get-TargetResource @params + } + + Should -Invoke -CommandName New-CimSession -Scope It -Times 0 -Exactly + Should -Invoke -CommandName Remove-CimSession -Scope It -Times 0 -Exactly + Should -Invoke -CommandName Get-DnsServerZone -Scope It -Times 1 -Exactly + } - Context 'When credential is passed' { - It 'Should throw an exception indicating a computername must also be passed' { - $withCredentialsParameter = $testParams + @{ - Credential = $testCredential - } - { Get-TargetResource @withCredentialsParameter -ReplicationScope $testReplicationScope } | Should -Throw $LocalizedData.CredentialRequiresComputerNameMessage + Context 'When credential is passed' { + It 'Should throw an exception indicating a computername must also be passed' { + InModuleScope -Parameters @{ + testCredential = $testCredential + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockErrorMessage = $script:LocalizedData.CredentialRequiresComputerNameMessage + $params = @{ + Name = 'example.com' + ReplicationScope = 'Domain' + Credential = $testCredential + Verbose = $false } + + { Get-TargetResource @params } | Should -Throw -ExpectedMessage ($mockErrorMessage) } } + } + } - Context 'When a computer name is passed' { - BeforeAll { - Mock -CommandName New-CimSession -MockWith { New-MockObject -Type Microsoft.Management.Infrastructure.CimSession } - Mock -CommandName Remove-CimSession + Context 'When a computer name is passed' { + BeforeAll { + Mock -CommandName New-CimSession -MockWith { New-MockObject -Type Microsoft.Management.Infrastructure.CimSession } + Mock -CommandName Remove-CimSession + Mock -CommandName Get-DnsServerZone + } + + It 'Should call expected mocks' { + InModuleScope -Parameters @{ + testComputerName = $testComputerName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + ReplicationScope = 'Domain' + ComputerName = $testComputerName + Verbose = $false } + Get-TargetResource @params + } - It 'Should call New-CimSession' { - $withComputerNameParameter = $testParams + @{ - ComputerName = $testComputerName - } - Get-TargetResource @withComputerNameParameter -ReplicationScope $testReplicationScope - Assert-MockCalled -CommandName New-CimSession -ParameterFilter { $computername -eq $withComputerNameParameter.ComputerName } -Scope It -Times 1 -Exactly + Should -Invoke -CommandName New-CimSession -ParameterFilter { $computername -eq $testComputerName } -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Remove-CimSession -Scope It -Times 1 -Exactly + } + } + + Context 'When credentials are passed' { + BeforeAll { + Mock -CommandName Get-DnsServerZone + Mock -CommandName New-CimSession -MockWith { New-MockObject -Type Microsoft.Management.Infrastructure.CimSession } + Mock -CommandName Remove-CimSession + } + + It 'Should call call expected mocks' { + InModuleScope -Parameters @{ + testComputerName = $testComputerName + testCredential = $testCredential + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + ReplicationScope = 'Domain' + ComputerName = $testComputerName + Credential = $testCredential + Verbose = $false } - It 'Should call Remove-CimSession' { - $withComputerNameParameter = $testParams + @{ - ComputerName = $testComputerName - } - Get-TargetResource @withComputerNameParameter -ReplicationScope $testReplicationScope - Assert-MockCalled -CommandName Remove-CimSession -Scope It -Times 1 -Exactly - } - Context 'When credentials are passed' { - BeforeAll { - Mock -CommandName Get-DnsServerZone - Mock -CommandName New-CimSession -MockWith { New-MockObject -Type Microsoft.Management.Infrastructure.CimSession } - Mock -CommandName Remove-CimSession - } - It 'Should call New-CimSession' { - $withCredentialsAndComputerParameter = $testParams + @{ - ComputerName = $testComputerName - Credential = $testCredential - } + { Get-TargetResource @params } | Should -Not -Throw + } - { Get-TargetResource @withCredentialsAndComputerParameter -ReplicationScope $testReplicationScope } | Should -Not -Throw + Should -Invoke -CommandName New-CimSession -ParameterFilter { + $ComputerName -eq $testComputerName ` + -and $credential -eq $testCredential + } -Scope It -Times 1 -Exactly + # Regression test for issue https://github.com/PowerShell/DnsServerDsc/issues/79. + Should -Invoke -CommandName Get-DnsServerZone -ParameterFilter { + $Name -eq $testZoneName + } - Assert-MockCalled -CommandName New-CimSession -ParameterFilter { - $ComputerName -eq $withCredentialsAndComputerParameter.ComputerName ` - -and $credential -eq $withCredentialsAndComputerParameter.Credential - } -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Remove-CimSession -Scope It -Times 1 -Exactly + } + } +} - # Regression test for issue https://github.com/PowerShell/DnsServerDsc/issues/79. - Assert-MockCalled -CommandName Get-DnsServerZone -ParameterFilter { - $Name -eq $withCredentialsAndComputerParameter.Name - } - } +Describe 'DSC_DnsServerADZone\Test-TargetResource' -Tag 'Test' { + BeforeAll { + $testZoneName = 'example.com' + $testDynamicUpdate = 'Secure' + $testReplicationScope = 'Domain' + $testDirectoryPartitionName = "DomainDnsZones.$testZoneName" - It 'Should call Remove-CimSession' { - $withCredentialsAndComputerParameter = $testParams + @{ - ComputerName = $testComputerName - Credential = $testCredential - } + $fakePresentTargetResource = @{ + Name = $testZoneName + DynamicUpdate = $testDynamicUpdate + ReplicationScope = $testReplicationScope + DirectoryPartitionName = $testDirectoryPartitionName + Ensure = 'Present' + } + } + Context 'When zone is present' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + } - Get-TargetResource @withCredentialsAndComputerParameter -ReplicationScope $testReplicationScope + It 'Should return a "System.Boolean" object type' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Remove-CimSession -Scope It -Times 1 -Exactly - } + $params = @{ + Name = 'example.com' + ReplicationScope = 'Domain' + Verbose = $false } + + $targetResource = Test-TargetResource @params + $targetResource -is [System.Boolean] | Should -BeTrue } } - #endregion + } + Context 'When zone is in the desired state' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + } - #region Function Test-TargetResource - Describe 'DSC_DnsServerADZone\Test-TargetResource' { - It 'Returns a "System.Boolean" object type' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - $targetResource = Test-TargetResource @testParams -ReplicationScope $testReplicationScope - $targetResource -is [System.Boolean] | Should Be $true - } + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Passes when DNS zone exists and "Ensure" = "Present"' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Test-TargetResource @testParams -Ensure Present -ReplicationScope $testReplicationScope | Should Be $true + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + Verbose = $false + } + Test-TargetResource @params | Should -BeTrue } + } + } - It 'Passes when DNS zone does not exist and "Ensure" = "Absent"' { - Mock -CommandName Get-TargetResource - Test-TargetResource @testParams -Ensure Absent -ReplicationScope $testReplicationScope | Should Be $true - } + Context 'When DNS zone does not exist and "Ensure" = "Absent"' { + BeforeAll { + Mock -CommandName Get-TargetResource + } - It 'Passes when DNS zone "DynamicUpdate" is correct' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Test-TargetResource @testParams -Ensure Present -ReplicationScope $testReplicationScope -DynamicUpdate $testDynamicUpdate | Should Be $true - } + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Passes when DNS zone "ReplicationScope" is correct' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Test-TargetResource @testParams -Ensure Present -ReplicationScope $testReplicationScope | Should Be $true + $params = @{ + Name = 'example.com' + Ensure = 'Absent' + ReplicationScope = 'Domain' + Verbose = $false + } + Test-TargetResource @params | Should -BeTrue } + } + } - It 'Passes when DNS zone "DirectoryPartitionName" is correct' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Test-TargetResource @testParams -Ensure Present -ReplicationScope $testReplicationScope -DirectoryPartitionName $testDirectoryPartitionName | Should Be $true - } + Context 'When DNS zone "DynamicUpdate" is correct' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + } - It 'Fails when DNS zone exists and "Ensure" = "Absent"' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Test-TargetResource @testParams -Ensure Absent -ReplicationScope $testReplicationScope | Should Be $false - } + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Fails when DNS zone does not exist and "Ensure" = "Present"' { - Mock -CommandName Get-TargetResource - Test-TargetResource @testParams -Ensure Present -ReplicationScope $testReplicationScope | Should Be $false + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + DynamicUpdate = 'Secure' + Verbose = $false + } + Test-TargetResource @params | Should -BeTrue } + } + } - It 'Fails when DNS zone "DynamicUpdate" is incorrect' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Test-TargetResource @testParams -Ensure Present -ReplicationScope $testReplicationScope -DynamicUpdate 'NonSecureAndSecure' | Should Be $false - } + Context 'When DNS zone "DirectoryPartitionName" is correct' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + } - It 'Fails when DNS zone "ReplicationScope" is incorrect' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Test-TargetResource @testParams -Ensure Present -ReplicationScope 'Forest' | Should Be $false + It 'Should return $true' { + InModuleScope -Parameters @{ + testDirectoryPartitionName = $testDirectoryPartitionName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + DirectoryPartitionName = $testDirectoryPartitionName + Verbose = $false + } + Test-TargetResource @params | Should -BeTrue } + } + } + + Context 'When DNS zone exists and "Ensure" = "Absent"' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + } - It 'Fails when DNS zone "DirectoryPartitionName" is incorrect' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Test-TargetResource @testParams -Ensure Present -ReplicationScope $testReplicationScope -DirectoryPartitionName 'IncorrectDirectoryPartitionName' | Should Be $false + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Absent' + ReplicationScope = 'Domain' + Verbose = $false + } + Test-TargetResource @params | Should -BeFalse } } - #endregion + } + Context 'When DNS zone does not exist and "Ensure" = "Present"' { + BeforeAll { + Mock -CommandName Get-TargetResource + } - #region Function Set-TargetResource - Describe 'DSC_DnsServerADZone\Set-TargetResource' { - Mock -CommandName Assert-Module + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Calls "Add-DnsServerPrimaryZone" when DNS zone does not exist and "Ensure" = "Present"' { - Mock -CommandName Get-TargetResource -MockWith { return $fakeAbsentTargetResource } - Mock -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } - Set-TargetResource @testParams -Ensure Present -ReplicationScope $testReplicationScope -DynamicUpdate $testDynamicUpdate - Assert-MockCalled -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } -Scope It + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + Verbose = $false + } + Test-TargetResource @params | Should -BeFalse } + } + } - It 'Calls "Remove-DnsServerZone" when DNS zone does exist and "Ensure" = "Absent"' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Mock -CommandName Remove-DnsServerZone - Set-TargetResource @testParams -Ensure Absent -ReplicationScope $testReplicationScope -DynamicUpdate $testDynamicUpdate - Assert-MockCalled -CommandName Remove-DnsServerZone -Scope It + Context 'When "DynamicUpdate" is incorrect' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + DynamicUpdate = 'NonSecureAndSecure' + Verbose = $false + } + Test-TargetResource @params | Should -BeFalse } + } + } + + Context 'When "ReplicationScope" is incorrect' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + } - It 'Calls "Set-DnsServerPrimaryZone" when DNS zone "DynamicUpdate" is incorrect' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Mock -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DynamicUpdate -eq 'NonSecureAndSecure' } - Set-TargetResource @testParams -Ensure Present -ReplicationScope $testReplicationScope -DynamicUpdate 'NonSecureAndSecure' - Assert-MockCalled -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DynamicUpdate -eq 'NonSecureAndSecure' } -Scope It + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Forest' + Verbose = $false + } + Test-TargetResource @params | Should -BeFalse } + } + } - It 'Calls "Set-DnsServerPrimaryZone" when DNS zone "ReplicationScope" is incorrect' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Mock -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $ReplicationScope -eq 'Forest' } - Set-TargetResource @testParams -Ensure Present -ReplicationScope 'Forest' - Assert-MockCalled -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $ReplicationScope -eq 'Forest' } -Scope It + Context 'When "DirectoryPartitionName" is incorrect' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + DirectoryPartitionName = 'IncorrectDirectoryPartitionName' + Verbose = $false + } + Test-TargetResource @params | Should -BeFalse } + } + } +} + +Describe 'DSC_DnsServerADZone\Set-TargetResource' -Tag 'Set' { + BeforeAll { + $testZoneName = 'example.com' + $testDynamicUpdate = 'Secure' + $testReplicationScope = 'Domain' + $testComputerName = 'dnsserver.local' + $testCredential = New-Object System.Management.Automation.PSCredential 'DummyUser', (ConvertTo-SecureString 'DummyPassword' -AsPlainText -Force) + $testDirectoryPartitionName = "DomainDnsZones.$testZoneName" + + $fakePresentTargetResource = @{ + Name = $testZoneName + DynamicUpdate = $testDynamicUpdate + ReplicationScope = $testReplicationScope + DirectoryPartitionName = $testDirectoryPartitionName + Ensure = 'Present' + } + $fakeAbsentTargetResource = @{ Ensure = 'Absent' } + + Mock -CommandName Assert-Module + } + + Context 'When DNS zone does not exist and "Ensure" = "Present"' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakeAbsentTargetResource } + Mock -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } + } + + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Calls "Set-DnsServerPrimaryZone" when DNS zone "DirectoryPartitionName" is incorrect' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Mock -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DirectoryPartitionName -eq 'IncorrectDirectoryPartitionName' } - Set-TargetResource @testParams -Ensure Present -ReplicationScope 'Custom' -DirectoryPartitionName 'IncorrectDirectoryPartitionName' - Assert-MockCalled -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DirectoryPartitionName -eq 'IncorrectDirectoryPartitionName' } -Scope It + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + DynamicUpdate = 'Secure' + Verbose = $false + } + Set-TargetResource @params } - Context 'When DirectoryPartitionName is specified and ReplicationScope is not "Custom"' { - It 'Should throw the correct exception' { - Mock -CommandName Get-TargetResource -MockWith { return $fakeAbsentTargetResource } - Mock -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } - { Set-TargetResource @testParams -Ensure Present -ReplicationScope 'Domain' ` - -DirectoryPartitionName 'DirectoryPartitionName' } | Should -Throw $LocalizedData.DirectoryPartitionReplicationScopeError + Should -Invoke -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } -Scope It -Times 1 -Exactly + } + } + + Context 'When DNS zone does not exist and "Ensure" = "Present" and "ReplicationScope is Custom"' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakeAbsentTargetResource } + Mock -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } + } + + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Custom' + DirectoryPartitionName = 'DomainDnsZones.example.com' + Verbose = $false } + Set-TargetResource @params } - Context 'When DirectoryPartitionName is changed and ReplicationScope is not "Custom"' { - It 'Should throw the correct exception' { - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Mock -CommandName Set-DnsServerPrimaryZone - { Set-TargetResource @testParams -Ensure Present -ReplicationScope 'Domain' ` - -DirectoryPartitionName 'IncorrectDirectoryPartitionName' } | Should -Throw $LocalizedData.DirectoryPartitionReplicationScopeError + Should -Invoke -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } -Scope It -Times 1 -Exactly + } + } + + Context 'When DNS zone does exist and "Ensure" = "Absent"' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + Mock -CommandName Remove-DnsServerZone + } + + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Absent' + ReplicationScope = 'Domain' + DynamicUpdate = 'Secure' + Verbose = $false } + Set-TargetResource @params } - Context 'When DirectoryPartitionName is changed and ReplicationScope is "Custom"' { - $fakePresentTargetResourceCustom = $fakePresentTargetResource.Clone() - $fakePresentTargetResourceCustom.ReplicationScope = 'Custom' + Should -Invoke -CommandName Remove-DnsServerZone -Scope It -Times 1 -Exactly + } + } + + Context 'When DNS zone "DynamicUpdate" is incorrect' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + Mock -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DynamicUpdate -eq 'NonSecureAndSecure' } + } - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResourceCustom } - Mock -CommandName Set-DnsServerPrimaryZone + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should not throw' { - { Set-TargetResource @testParams -Ensure Present -ReplicationScope 'Custom' -DirectoryPartitionName 'IncorrectDirectoryPartitionName' } | ` - Should -Not -Throw + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + DynamicUpdate = 'NonSecureAndSecure' + Verbose = $false } + Set-TargetResource @params + } + + Should -Invoke -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DynamicUpdate -eq 'NonSecureAndSecure' } -Scope It -Times 1 -Exactly + } + } + + Context 'When DNS zone "ReplicationScope" is incorrect' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + Mock -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $ReplicationScope -eq 'Forest' } + } + + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Shpould call the expected mocks' { - Assert-MockCalled -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DirectoryPartitionName -eq 'IncorrectDirectoryPartitionName' } + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Forest' + Verbose = $false } + Set-TargetResource @params } - Context 'when "Ensure" = "Present" and DNS zone does not exist and DirectoryPartitionName is set and ReplicationScope is not "Custom"' { - It 'Should throw the correct exception' { - Mock -CommandName Get-TargetResource -MockWith { return $fakeAbsentTargetResource } - Mock -CommandName Set-DnsServerPrimaryZone - { Set-TargetResource @testParams -Ensure Present -ReplicationScope 'Domain' ` - -DirectoryPartitionName 'IncorrectDirectoryPartitionName' } | Should -Throw $LocalizedData.DirectoryPartitionReplicationScopeError + Should -Invoke -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $ReplicationScope -eq 'Forest' } -Scope It -Times 1 -Exactly + } + } + + Context 'When DNS zone "DirectoryPartitionName" is incorrect' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + Mock -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DirectoryPartitionName -eq 'IncorrectDirectoryPartitionName' } + } + + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Custom' + DirectoryPartitionName = 'IncorrectDirectoryPartitionName' + Verbose = $false } + Set-TargetResource @params } - Context 'When a computer name is not passed' { - BeforeAll { - Mock -CommandName New-CimSession - Mock -CommandName Remove-CimSession - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Mock -CommandName Set-DnsServerPrimaryZone + Should -Invoke -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DirectoryPartitionName -eq 'IncorrectDirectoryPartitionName' } -Scope It + } + } + + Context 'When DirectoryPartitionName is specified and ReplicationScope is not "Custom"' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakeAbsentTargetResource } + Mock -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } + } + + It 'Should throw the correct exception' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockErrorMessage = $script:LocalizedData.DirectoryPartitionReplicationScopeError + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + DirectoryPartitionName = 'DirectoryPartitionName' + Verbose = $false } - It 'Should not call New-CimSession' { - Set-TargetResource @testParams -ReplicationScope $testReplicationScope - Assert-MockCalled -CommandName New-CimSession -Scope It -Times 0 -Exactly + + { Set-TargetResource @params } | Should -Throw -ExpectedMessage ($mockErrorMessage + '*') + } + } + } + + Context 'When DirectoryPartitionName is changed and ReplicationScope is not "Custom"' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + Mock -CommandName Set-DnsServerPrimaryZone + } + + It 'Should throw the correct exception' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockErrorMessage = $script:LocalizedData.DirectoryPartitionReplicationScopeError + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + DirectoryPartitionName = 'IncorrectDirectoryPartitionName' + Verbose = $false } - It 'Should not call Remove-CimSession' { - Set-TargetResource @testParams -ReplicationScope $testReplicationScope - Assert-MockCalled -CommandName Remove-CimSession -Scope It -Times 0 -Exactly + { Set-TargetResource @params } | Should -Throw -ExpectedMessage ($mockErrorMessage + '*') + } + } + } + + Context 'When DirectoryPartitionName is changed and ReplicationScope is "Custom"' { + BeforeAll { + $fakePresentTargetResourceCustom = $fakePresentTargetResource.Clone() + $fakePresentTargetResourceCustom.ReplicationScope = 'Custom' + + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResourceCustom } + Mock -CommandName Set-DnsServerPrimaryZone + } + + It 'Should not throw' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Custom' + DirectoryPartitionName = 'IncorrectDirectoryPartitionName' + Verbose = $false } + + { Set-TargetResource @params } | Should -Not -Throw } + } + + It 'Should call the expected mocks' { + Should -Invoke -CommandName Set-DnsServerPrimaryZone ` + -ParameterFilter { $DirectoryPartitionName -eq 'IncorrectDirectoryPartitionName' } ` + -Scope Context + } + } + + Context 'When "Ensure" = "Present" and DNS zone does not exist and DirectoryPartitionName is set and ReplicationScope is not "Custom"' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return $fakeAbsentTargetResource } + Mock -CommandName Set-DnsServerPrimaryZone + } - Context 'When a computer name is passed' { - BeforeAll { - Mock -CommandName New-CimSession -MockWith { New-MockObject -Type Microsoft.Management.Infrastructure.CimSession } - Mock -CommandName Remove-CimSession - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Mock -CommandName Set-DnsServerPrimaryZone + It 'Should throw the correct exception' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockErrorMessage = $script:LocalizedData.DirectoryPartitionReplicationScopeError + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + DirectoryPartitionName = 'IncorrectDirectoryPartitionName' + Verbose = $false } - It 'Should call New-CimSession' { - $withComputerNameParameter = $testParams + @{ - ComputerName = $testComputerName - } - Set-TargetResource @withComputerNameParameter -ReplicationScope $testReplicationScope - Assert-MockCalled -CommandName New-CimSession -ParameterFilter { $computername -eq $withComputerNameParameter.ComputerName } -Scope It -Times 1 -Exactly + { Set-TargetResource @params } | Should -Throw -ExpectedMessage ($mockErrorMessage + '*') + } + } + } + + Context 'When a computer name is not passed' { + BeforeAll { + Mock -CommandName New-CimSession + Mock -CommandName Remove-CimSession + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + Mock -CommandName Set-DnsServerPrimaryZone + } + + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Ensure = 'Present' + ReplicationScope = 'Domain' + Verbose = $false } - It 'Should call Remove-CimSession' { - $withComputerNameParameter = $testParams + @{ - ComputerName = $testComputerName - } - Set-TargetResource @withComputerNameParameter -ReplicationScope $testReplicationScope - Assert-MockCalled -CommandName Remove-CimSession -Scope It -Times 1 -Exactly + Set-TargetResource @params + } + + Should -Invoke -CommandName New-CimSession -Scope It -Times 0 -Exactly + Should -Invoke -CommandName Remove-CimSession -Scope It -Times 0 -Exactly + Should -Invoke -CommandName Set-DnsServerPrimaryZone -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Get-TargetResource -Scope It -Times 1 -Exactly + } + } + + Context 'When a computer name is passed' { + BeforeAll { + Mock -CommandName New-CimSession -MockWith { New-MockObject -Type Microsoft.Management.Infrastructure.CimSession } + Mock -CommandName Remove-CimSession + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + Mock -CommandName Set-DnsServerPrimaryZone + } + + It 'Should call expected mocks' { + InModuleScope -Parameters @{ + testComputerName = $testComputerName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + ReplicationScope = 'Domain' + ComputerName = $testComputerName + Verbose = $false } + Set-TargetResource @params + } - Context 'When credentials are passed' { - BeforeAll { - Mock -CommandName New-CimSession -MockWith { New-MockObject -Type Microsoft.Management.Infrastructure.CimSession } - Mock -CommandName Remove-CimSession - Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } - Mock -CommandName Set-DnsServerPrimaryZone - } + Should -Invoke -CommandName New-CimSession -ParameterFilter { $computername -eq $testComputerName } -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Remove-CimSession -Scope It -Times 1 -Exactly + } + } - It 'Should call New-CimSession' { - $withCredentialsAndComputerParameter = $testParams + @{ - ComputerName = $testComputerName - Credential = $testCredential - } - Set-TargetResource @withCredentialsAndComputerParameter -ReplicationScope $testReplicationScope - Assert-MockCalled -CommandName New-CimSession -ParameterFilter { $computername -eq $withCredentialsAndComputerParameter.ComputerName -and $credential -eq $withCredentialsAndComputerParameter.Credential } -Scope It -Times 1 -Exactly - } - It 'Should call Remove-CimSession' { - $withCredentialsAndComputerParameter = $testParams + @{ - ComputerName = $testComputerName - Credential = $testCredential - } - Set-TargetResource @withCredentialsAndComputerParameter -ReplicationScope $testReplicationScope - Assert-MockCalled -CommandName Remove-CimSession -Scope It -Times 1 -Exactly - } + Context 'When credentials are passed' { + BeforeAll { + Mock -CommandName New-CimSession -MockWith { New-MockObject -Type Microsoft.Management.Infrastructure.CimSession } + Mock -CommandName Remove-CimSession + Mock -CommandName Get-TargetResource -MockWith { return $fakePresentTargetResource } + Mock -CommandName Set-DnsServerPrimaryZone + } + + It 'Should call expected mocks' { + InModuleScope -Parameters @{ + testComputerName = $testComputerName + testCredential = $testCredential + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + ReplicationScope = 'Domain' + ComputerName = $testComputerName + Credential = $testCredential + Verbose = $false } + Set-TargetResource @params } + + Should -Invoke -CommandName New-CimSession -ParameterFilter { + $computername -eq $testComputerName -and $credential -eq $testCredential + } -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Remove-CimSession -Scope It -Times 1 -Exactly } - #endregion - } #end InModuleScope -} -finally -{ - Invoke-TestCleanup + } } diff --git a/tests/Unit/DSC_DnsServerClientSubnet.Tests.ps1 b/tests/Unit/DSC_DnsServerClientSubnet.Tests.ps1 index 895a446c..27c0476a 100644 --- a/tests/Unit/DSC_DnsServerClientSubnet.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerClientSubnet.Tests.ps1 @@ -1,16 +1,37 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerClientSubnet' +<# + .SYNOPSIS + Unit test for DSC_DnsServerADZone DSC resource. +#> -function Invoke-TestSetup -{ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerClientSubnet' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,144 +40,188 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} -Invoke-TestSetup + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force -try -{ - InModuleScope $script:dscResourceName { - #region Pester Test Initialization - $mocks = @{ - IPv4Present = { - [PSCustomObject]@{ - Name = 'ClientSubnetA' - IPv4Subnet = '10.1.1.0/24' - IPv6Subnet = $null - } - } - Absent = { } - IPv6Present = { - [PSCustomObject]@{ - Name = 'ClientSubnetB' - IPv4Subnet = $null - IPv6Subnet = 'db8::1/28' - } - } - BothPresent = { - [PSCustomObject]@{ - Name = 'ClientSubnetC' - IPv4Subnet = '10.1.1.0/24' - IPv6Subnet = 'db8::1/28' - } - } - GetIPv4Present = { - [PSCustomObject]@{ - Name = 'ClientSubnetA' - IPv4Subnet = '10.1.1.0/24' - IPv6Subnet = $null - } + Remove-Module -Name DnsServer -Force +} + +Describe 'DSC_DnsServerClientSubnet\Get-TargetResource' -Tag 'Get' { + BeforeAll { + $IPv4Present = { + [PSCustomObject]@{ + Name = 'ClientSubnetA' + IPv4Subnet = '10.1.1.0/24' + IPv6Subnet = $null } - GetIPv6Present = { - [PSCustomObject]@{ - Name = 'ClientSubnetB' - IPv4Subnet = $null - IPv6Subnet = 'db8::1/28' - Ensure = 'Present' - } + } + $IPv6Present = { + [PSCustomObject]@{ + Name = 'ClientSubnetB' + IPv4Subnet = $null + IPv6Subnet = 'db8::1/28' } - GetBothPresent = { - [PSCustomObject]@{ - Name = 'ClientSubnetC' - IPv4Subnet = '10.1.1.0/24' - IPv6Subnet = 'db8::1/28' - } + } + $BothPresent = { + [PSCustomObject]@{ + Name = 'ClientSubnetC' + IPv4Subnet = '10.1.1.0/24' + IPv6Subnet = 'db8::1/28' } } - #endregion + } + Context 'When the system is in the desired state' { + Context 'When the IPv4 client subnet is present' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet -MockWith $IPv4Present + } - #region Function Get-TargetResource - Describe 'DSC_DnsServerClientSubnet\Get-TargetResource' -Tag 'Get' { - Context 'When the system is in the desired state' { - It 'Should set Ensure to Present when the IPv4 client subnet is present' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.IPv4Present + It 'Should set Ensure to Present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 $getTargetResourceResult = Get-TargetResource 'ClientSubnetA' $getTargetResourceResult.Ensure | Should -Be 'Present' $getTargetResourceResult.IPv4Subnet | Should -Be '10.1.1.0/24' $getTargetResourceResult.IPv6Subnet | Should -BeNullOrEmpty - - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It } - It 'Should set Ensure to Present when the IPv6 client subnet is present' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.IPv6Present + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + } + } + + Context 'When the IPv6 client subnet is present' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet -MockWith $IPv6Present + } + + It 'Should set Ensure to Present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 $getTargetResourceResult = Get-TargetResource 'ClientSubnetB' $getTargetResourceResult.Ensure | Should -Be 'Present' $getTargetResourceResult.IPv4Subnet | Should -BeNullOrEmpty $getTargetResourceResult.IPv6Subnet | Should -Be 'db8::1/28' - - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It } - It 'Should set Ensure to Present when both client subnets are present' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.BothPresent + + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + } + } + + Context 'When both client subnets are present' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet -MockWith $BothPresent + } + + It 'Should set Ensure to Present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 $getTargetResourceResult = Get-TargetResource 'ClientSubnetC' $getTargetResourceResult.Ensure | Should -Be 'Present' $getTargetResourceResult.IPv4Subnet | Should -Be '10.1.1.0/24' $getTargetResourceResult.IPv6Subnet | Should -Be 'db8::1/28' - - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It } + + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It } + } + } - Context 'When the system is not in the desired state' { - It 'Should set Ensure to Absent when the IPv4 client subnet is not present' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.Absent + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet + } - $getTargetResourceResult = Get-TargetResource 'ClientSubnetA' - $getTargetResourceResult.Ensure | Should -Be 'Absent' - $getTargetResourceResult.IPv4Subnet | Should -BeNullOrEmpty - $getTargetResourceResult.IPv6Subnet | Should -BeNullOrEmpty + It 'Should set Ensure to Absent when the IPv4 client subnet is not present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It - } + $getTargetResourceResult = Get-TargetResource 'ClientSubnetA' + $getTargetResourceResult.Ensure | Should -Be 'Absent' + $getTargetResourceResult.IPv4Subnet | Should -BeNullOrEmpty + $getTargetResourceResult.IPv6Subnet | Should -BeNullOrEmpty + } - It 'Should set Ensure to Absent when the IPv6 client subnet is not present' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.Absent + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + } - $getTargetResourceResult = Get-TargetResource 'ClientSubnetB' - $getTargetResourceResult.Ensure | Should -Be 'Absent' - $getTargetResourceResult.IPv4Subnet | Should -BeNullOrEmpty - $getTargetResourceResult.IPv6Subnet | Should -BeNullOrEmpty + It 'Should set Ensure to Absent when the IPv6 client subnet is not present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It - } - It 'Should set Ensure to Absent when both client subnets are not present' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.Absent + $getTargetResourceResult = Get-TargetResource 'ClientSubnetB' + $getTargetResourceResult.Ensure | Should -Be 'Absent' + $getTargetResourceResult.IPv4Subnet | Should -BeNullOrEmpty + $getTargetResourceResult.IPv6Subnet | Should -BeNullOrEmpty + } - $getTargetResourceResult = Get-TargetResource 'ClientSubnetC' - $getTargetResourceResult.Ensure | Should -Be 'Absent' - $getTargetResourceResult.IPv4Subnet | Should -BeNullOrEmpty - $getTargetResourceResult.IPv6Subnet | Should -BeNullOrEmpty + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + } - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It - } + It 'Should set Ensure to Absent when both client subnets are not present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $getTargetResourceResult = Get-TargetResource 'ClientSubnetC' + $getTargetResourceResult.Ensure | Should -Be 'Absent' + $getTargetResourceResult.IPv4Subnet | Should -BeNullOrEmpty + $getTargetResourceResult.IPv6Subnet | Should -BeNullOrEmpty + } + + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + } + } +} + +Describe 'DSC_DnsServerClientSubnet\Test-TargetResource' -Tag 'Test' { + BeforeAll { + $IPv4Present = { + [PSCustomObject]@{ + Name = 'ClientSubnetA' + IPv4Subnet = '10.1.1.0/24' + IPv6Subnet = $null + } + } + $IPv6Present = { + [PSCustomObject]@{ + Name = 'ClientSubnetB' + IPv4Subnet = $null + IPv6Subnet = 'db8::1/28' + } + } + $BothPresent = { + [PSCustomObject]@{ + Name = 'ClientSubnetC' + IPv4Subnet = '10.1.1.0/24' + IPv6Subnet = 'db8::1/28' } } - #endregion Function Get-TargetResource + } + Context 'When the system is in the desired state' { + Context 'When the IPv4Subnet matches' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet $IPv4Present + } + + It 'Should return True' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - #region Function Test-TargetResource - Describe 'DSC_DnsServerClientSubnet\Test-TargetResource' -Tag 'Test' { - Context 'When the system is in the desired state' { - It 'Should return True when the IPv4Subnet matches' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.IPv4Present $params = @{ Ensure = 'Present' Name = 'ClientSubnetA' @@ -164,9 +229,18 @@ try } Test-TargetResource @params | Should -BeTrue } + } + } + + Context 'When the IPv6Subnet matches' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet $IPv6Present + } + + It 'Should return True' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return True when the IPv6Subnet matches' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.IPv6Present $params = @{ Ensure = 'Present' Name = 'ClientSubnetB' @@ -174,9 +248,18 @@ try } Test-TargetResource @params | Should -BeTrue } + } + } + + Context 'When both IPv4 and IPv6 Subnets match' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet $BothPresent + } + + It 'Should return True' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return True when both IPv4 and IPv6 Subnets match' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.BothPresent $params = @{ Ensure = 'Present' Name = 'ClientSubnetC' @@ -186,77 +269,152 @@ try Test-TargetResource @params | Should -BeTrue } } + } + } - Context 'When the system is not in the desired state' { - It 'Should return False when the Ensure doesnt match' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.Absent - $params = @{ - Ensure = 'Present' - Name = 'ClientSubnetA' - IPv4Subnet = '10.1.20.0/24' - } - Test-TargetResource @params | Should -BeFalse + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + $GetIPv4Present = { + [PSCustomObject]@{ + Name = 'ClientSubnetA' + IPv4Subnet = '10.1.1.0/24' + IPv6Subnet = $null } + } + $GetIPv6Present = { + [PSCustomObject]@{ + Name = 'ClientSubnetB' + IPv4Subnet = $null + IPv6Subnet = 'db8::1/28' + Ensure = 'Present' + } + } + } + + It 'Should return False when the Ensure doesnt match' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Ensure = 'Present' + Name = 'ClientSubnetA' + IPv4Subnet = '10.1.20.0/24' + } + Test-TargetResource @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + } + + Context 'When an IPv4 Subnet does not exist but one is configured' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet + } + + It 'Should return False' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return False when an IPv4 Subnet does not exist but one is configured' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.Absent $params = @{ Ensure = 'Present' Name = 'ClientSubnetA' IPv4Subnet = '10.1.20.0/24' } Test-TargetResource @params | Should -BeFalse - - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It } - It 'Should return False when the IPv4 Subnet does not match what is configured' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.GetIPv4Present + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + } + } + + Context 'When the IPv4 Subnet does not match what is configured' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet -MockWith $GetIPv4Present + } + + It 'Should return False' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $params = @{ Ensure = 'Present' Name = 'ClientSubnetA' IPv4Subnet = '10.1.20.0/24' } Test-TargetResource @params | Should -BeFalse - - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It } - It 'Should return False when the IPv6 Subnet does not match what is configured' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.GetIPv6Present + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + } + } + + Context 'When the IPv6 Subnet does not match what is configured' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet -MockWith $GetIPv6Present + } + + It 'Should return False' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $params = @{ Ensure = 'Present' Name = 'ClientSubnetB' IPv6Subnet = 'aab8::1/28' } Test-TargetResource @params | Should -BeFalse - - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It } - It 'Should return False when an IPv6 Subnet does not exist but one is configured' { - Mock -CommandName Get-DnsServerClientSubnet $mocks.Absent + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + } + } + + Context 'When an IPv6 Subnet does not exist but one is configured' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet + } + + It 'Should return False' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + $params = @{ Ensure = 'Present' Name = 'ClientSubnetB' IPv6Subnet = 'db8::1/28' } Test-TargetResource @params | Should -BeFalse - - Assert-MockCalled -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It } + + Should -Invoke -CommandName Get-DnsServerClientSubnet -Exactly -Times 1 -Scope It + } + } + } +} + +Describe 'DSC_DnsServerClientSubnet\Set-TargetResource' -Tag 'Set' { + BeforeAll { + $IPv4Present = { + [PSCustomObject]@{ + Name = 'ClientSubnetA' + IPv4Subnet = '10.1.1.0/24' + IPv6Subnet = $null + } + } + } + + Context 'When configuring DNS Server Client Subnets' { + Context 'When the subnet does not exist' { + BeforeAll { + Mock -CommandName Get-DnsServerClientSubnet + Mock -CommandName Add-DnsServerClientSubnet } - } - #endregion - #region Function Set-TargetResource - Describe 'DSC_DnsServerClientSubnet\Set-TargetResource' -Tag 'Set' { - Context 'When configuring DNS Server Client Subnets' { - It 'Calls Add-DnsServerClientSubnet in the set method when the subnet does not exist' { - Mock -CommandName Get-DnsServerClientSubnet - Mock -CommandName Add-DnsServerClientSubnet + It 'Should call Add-DnsServerClientSubnet in the set method' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 $params = @{ Ensure = 'Present' @@ -264,45 +422,73 @@ try IPv4Subnet = '10.1.20.0/24' } Set-TargetResource @params + } + + Should -Invoke Add-DnsServerClientSubnet -Scope It -ParameterFilter { + $Name -eq 'ClientSubnetA' -and $IPv4Subnet -eq '10.1.20.0/24' + } + } + + It 'Should call Add-DnsServerClientSubnet in the set method' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled Add-DnsServerClientSubnet -Scope It -ParameterFilter { - $Name -eq 'ClientSubnetA' -and $IPv4Subnet -eq '10.1.20.0/24' + $params = @{ + Ensure = 'Present' + Name = 'ClientSubnetB' + IPv6Subnet = 'db8::1/28' } + Set-TargetResource @params + } + + Should -Invoke Add-DnsServerClientSubnet -Scope It -ParameterFilter { + $Name -eq 'ClientSubnetB' -and $IPv6Subnet -eq 'db8::1/28' } + } + } + + Context 'When the subnet does not exist' { + BeforeAll { + Mock -CommandName Remove-DnsServerClientSubnet + Mock -CommandName Get-DnsServerClientSubnet -MockWith { return $IPv4Present } + } + + It 'Should call Remove-DnsServerClientSubnet in the set method when Ensure is Absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Calls Remove-DnsServerClientSubnet in the set method when Ensure is Absent' { - Mock -CommandName Remove-DnsServerClientSubnet - Mock -CommandName Get-DnsServerClientSubnet { return $mocks.IPv4Present } $params = @{ Ensure = 'Absent' Name = 'ClientSubnetA' IPv4Subnet = '10.1.20.0/24' } Set-TargetResource @params - - Assert-MockCalled Remove-DnsServerClientSubnet -Scope It } - It "Calls Set-DnsServerClientSubnet in the set method when Ensure is Present subnet is found" { + Should -Invoke Remove-DnsServerClientSubnet -Scope It + } + } + + Context 'When the subnet does not exist' { + BeforeAll { + Mock -CommandName Set-DnsServerClientSubnet + Mock -CommandName Get-DnsServerClientSubnet -MockWith { return $IPv4Present } + } + + It 'Should call Set-DnsServerClientSubnet in the set method when Ensure is Present subnet is found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Mock -CommandName Set-DnsServerClientSubnet - Mock -CommandName Get-DnsServerClientSubnet $mocks.IPv4Present $params = @{ Ensure = 'Present' Name = 'ClientSubnetX' IPv4Subnet = '10.1.1.0/24' } Set-TargetResource @params - - Assert-MockCalled Set-DnsServerClientSubnet -Scope It } + Should -Invoke Set-DnsServerClientSubnet -Scope It } } - #endregion - } #end InModuleScope -} -finally -{ - Invoke-TestCleanup + } } diff --git a/tests/Unit/DSC_DnsServerConditionalForwarder.Tests.ps1 b/tests/Unit/DSC_DnsServerConditionalForwarder.Tests.ps1 index c0d0485a..88d7de9d 100644 --- a/tests/Unit/DSC_DnsServerConditionalForwarder.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerConditionalForwarder.Tests.ps1 @@ -1,16 +1,37 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerConditionalForwarder' +<# + .SYNOPSIS + Unit test for DSC_DnsServerConditionalForwarder DSC resource. +#> -function Invoke-TestSetup -{ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerConditionalForwarder' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,312 +40,519 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force + + Remove-Module -Name DnsServer -Force } -Invoke-TestSetup +Context 'DSC_DnsServerConditionalForwarder\Get-TargetResource' -Tag 'Get' { + BeforeAll { + Mock Get-DnsServerZone { + @{ + MasterServers = '1.1.1.1', '2.2.2.2' + ZoneType = $script:zoneType + IsDsIntegrated = $script:isDsIntegrated + ReplicationScope = $script:ReplicationScope + DirectoryPartitionName = 'CustomName' + } + } + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:defaultParameters = @{ + Ensure = 'Present' + Name = 'domain.name' + MasterServers = '1.1.1.1', '2.2.2.2' + ReplicationScope = 'Domain' + Verbose = $VerbosePreference + } + } + } + BeforeEach { + $script:zoneType = 'Forwarder' + $script:isDsIntegrated = $true + $script:ReplicationScope = 'Domain' + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockGetParameters = $defaultParameters.Clone() + $mockGetParameters.Remove('Ensure') + $mockGetParameters.Remove('MasterServers') + $mockGetParameters.Remove('ReplicationScope') + } + } + + Context 'When the system is in the desired state' { + Context 'When the zone is present on the server' { + It 'Should exist, and is AD integrated' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $getTargetResourceResult = Get-TargetResource @mockGetParameters + + $getTargetResourceResult.MasterServers | Should -Be '1.1.1.1', '2.2.2.2' + $getTargetResourceResult.ZoneType | Should -Be 'Forwarder' + $getTargetResourceResult.ReplicationScope | Should -Be 'Domain' + } + } + + It 'When the zone exists, and is not AD integrated' { + $script:isDsIntegrated = $false + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $getTargetResourceResult = Get-TargetResource @mockGetParameters + + $getTargetResourceResult.ReplicationScope | Should -Be 'None' + } + } + } + } + + Context 'When the system is not in the desired state' { + Context 'When the zone is present on the server' { + It 'When the zone exists, and is not a forwarder' { + $script:ZoneType = 'Primary' + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $getTargetResourceResult = Get-TargetResource @mockGetParameters + + $getTargetResourceResult.ZoneType | Should -Be 'Primary' + } + } + } -try -{ - InModuleScope $script:dscResourceName { - Describe 'DSC_DnsServerConditionalForwarder' { + Context 'When the zone is not present on the server' { BeforeAll { - Mock Add-DnsServerConditionalForwarderZone - Mock Get-DnsServerZone { - [PSCustomObject]@{ - MasterServers = '1.1.1.1', '2.2.2.2' - ZoneType = $Script:zoneType - IsDsIntegrated = $Script:isDsIntegrated - ReplicationScope = $Script:ReplicationScope - DirectoryPartitionName = 'CustomName' - } + Mock Get-DnsServerZone + } + + It 'When the zone does not exist, sets Ensure to Absent' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $getTargetResourceResult = Get-TargetResource @mockGetParameters + + $getTargetResourceResult.Ensure | Should -Be 'Absent' } - Mock Remove-DnsServerZone - Mock Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } - Mock Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } - } - - BeforeEach { - $Script:zoneType = 'Forwarder' - $Script:isDsIntegrated = $true - $Script:ReplicationScope = 'Domain' - - $defaultParameters = @{ - Ensure = 'Present' - Name = 'domain.name' - MasterServers = '1.1.1.1', '2.2.2.2' - ReplicationScope = 'Domain' - Verbose = $true + } + } + } +} + +Context 'DSC_DnsServerConditionalForwarder\Set-TargetResource' -Tag 'Set' { + BeforeAll { + Mock Add-DnsServerConditionalForwarderZone + Mock Get-DnsServerZone { + @{ + MasterServers = '1.1.1.1', '2.2.2.2' + ZoneType = $script:zoneType + IsDsIntegrated = $script:isDsIntegrated + ReplicationScope = $script:ReplicationScope + DirectoryPartitionName = 'CustomName' + } + } + Mock Remove-DnsServerZone + Mock Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } + Mock Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } + } + + BeforeEach { + $script:zoneType = 'Forwarder' + $script:isDsIntegrated = $true + $script:ReplicationScope = 'Domain' + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockSetParameters = $defaultParameters.Clone() + } + } + + Context 'When the system is not in the desired state' { + Context 'When the zone is present on the server' { + It 'When Ensure is present, and a zone of a different type exists, removes and recreates the zone' { + $script:zoneType = 'Stub' + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + Set-TargetResource @mockSetParameters } + + Should -Invoke Add-DnsServerConditionalForwarderZone -Scope It + Should -Invoke Remove-DnsServerZone -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It } - Context 'DSC_DnsServerConditionalForwarder\Get-TargetResource' -Tag 'Get' { - BeforeEach { - $contextParameters = $defaultParameters.Clone() - $contextParameters.Remove('Ensure') - $contextParameters.Remove('MasterServers') - $contextParameters.Remove('ReplicationScope') + It 'When Ensure is present, requested replication scope is none, and a DsIntegrated zone exists, removes and recreates the zone' { + $script:isDsIntegrated = $true + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockSetParameters.ReplicationScope = 'None' + Set-TargetResource @mockSetParameters } - Context 'When the system is in the desired state' { - Context 'When the zone is present on the server' { - It 'When the zone exists, and is AD integrated' { - $getTargetResourceResult = Get-TargetResource @contextParameters + Should -Invoke Add-DnsServerConditionalForwarderZone -Scope It + Should -Invoke Remove-DnsServerZone -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It + } + + It 'When Ensure is present, requested zone storage is AD, and a file based zone exists, removes and recreates the zone' { + $script:isDsIntegrated = $false + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getTargetResourceResult.MasterServers | Should -Be '1.1.1.1', '2.2.2.2' - $getTargetResourceResult.ZoneType | Should -Be 'Forwarder' - $getTargetResourceResult.ReplicationScope | Should -Be 'Domain' - } + Set-TargetResource @mockSetParameters + } + + Should -Invoke Add-DnsServerConditionalForwarderZone -Scope It + Should -Invoke Remove-DnsServerZone -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It + } - It 'When the zone exists, and is not AD integrated' { - $Script:isDsIntegrated = $false + It 'When Ensure is present, and master servers differs, updates list of master servers' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getTargetResourceResult = Get-TargetResource @contextParameters + $mockSetParameters.MasterServers = '3.3.3.3', '4.4.4.4' - $getTargetResourceResult.ReplicationScope | Should -Be 'None' - } - } + Set-TargetResource @mockSetParameters } - Context 'When the system is not in the desired state' { - Context 'When the zone is present on the server' { - It 'When the zone exists, and is not a forwarder' { - $Script:ZoneType = 'Primary' + Should -Invoke Add-DnsServerConditionalForwarderZone -Times 0 -Scope It + Should -Invoke Remove-DnsServerZone -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 1 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It + } - $getTargetResourceResult = Get-TargetResource @contextParameters + It 'When Ensure is present, and the replication scope differs, attempts to move the zone' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getTargetResourceResult.ZoneType | Should -Be 'Primary' - } - } + $mockSetParameters.ReplicationScope = 'Forest' + Set-TargetResource @mockSetParameters + } - Context 'When the zone is not present on the server' { - BeforeAll { - Mock Get-DnsServerZone - } + Should -Invoke Add-DnsServerConditionalForwarderZone -Times 0 -Scope It + Should -Invoke Remove-DnsServerZone -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 1 -Scope It + } - It 'When the zone does not exist, sets Ensure to Absent' { - $getTargetResourceResult = Get-TargetResource @contextParameters + It 'When Ensure is present, the replication scope is custom, and the directory partition name differs, attempts to move the zone' { + $script:ReplicationScope = 'Custom' - $getTargetResourceResult.Ensure | Should -Be 'Absent' - } - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockSetParameters.ReplicationScope = 'Custom' + $mockSetParameters.DirectoryPartitionName = 'New' + Set-TargetResource @mockSetParameters } + + Should -Invoke Add-DnsServerConditionalForwarderZone -Times 0 -Scope It + Should -Invoke Remove-DnsServerZone -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 1 -Scope It } - Context 'DSC_DnsServerConditionalForwarder\Set-TargetResource' -Tag 'Set' { - Context 'When the system is not in the desired state' { - Context 'When the zone is present on the server' { - It 'When Ensure is present, and a zone of a different type exists, removes and recreates the zone' { - $Script:zoneType = 'Stub' - - Set-TargetResource @defaultParameters - - Assert-MockCalled Add-DnsServerConditionalForwarderZone -Scope It - Assert-MockCalled Remove-DnsServerZone -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It - } - - It 'When Ensure is present, requested replication scope is none, and a DsIntegrated zone exists, removes and recreates the zone' { - $Script:isDsIntegrated = $true - - $defaultParameters.ReplicationScope = 'None' - Set-TargetResource @defaultParameters - - Assert-MockCalled Add-DnsServerConditionalForwarderZone -Scope It - Assert-MockCalled Remove-DnsServerZone -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It - } - - It 'When Ensure is present, requested zone storage is AD, and a file based zone exists, removes and recreates the zone' { - $Script:isDsIntegrated = $false - - Set-TargetResource @defaultParameters - - Assert-MockCalled Add-DnsServerConditionalForwarderZone -Scope It - Assert-MockCalled Remove-DnsServerZone -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It - } - - It 'When Ensure is present, and master servers differs, updates list of master servers' { - $defaultParameters.MasterServers = '3.3.3.3', '4.4.4.4' - - Set-TargetResource @defaultParameters - - Assert-MockCalled Add-DnsServerConditionalForwarderZone -Times 0 -Scope It - Assert-MockCalled Remove-DnsServerZone -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 1 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It - } - - It 'When Ensure is present, and the replication scope differs, attempts to move the zone' { - $defaultParameters.ReplicationScope = 'Forest' - Set-TargetResource @defaultParameters - - Assert-MockCalled Add-DnsServerConditionalForwarderZone -Times 0 -Scope It - Assert-MockCalled Remove-DnsServerZone -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 1 -Scope It - } - - It 'When Ensure is present, the replication scope is custom, and the directory partition name differs, attempts to move the zone' { - $Script:ReplicationScope = 'Custom' - - $defaultParameters.ReplicationScope = 'Custom' - $defaultParameters.DirectoryPartitionName = 'New' - Set-TargetResource @defaultParameters - - Assert-MockCalled Add-DnsServerConditionalForwarderZone -Times 0 -Scope It - Assert-MockCalled Remove-DnsServerZone -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 1 -Scope It - } - - It 'When Ensure is absent, removes the zone' { - $defaultParameters.Ensure = 'Absent' - Set-TargetResource @defaultParameters - - Assert-MockCalled Remove-DnsServerZone -Scope It - Assert-MockCalled Add-DnsServerConditionalForwarderZone -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It - } - } - - Context 'When the zone is not present on the server' { - BeforeAll { - Mock Get-DnsServerZone - } - - It 'When Ensure is present, attempts to create the zone' { - Set-TargetResource @defaultParameters - - Assert-MockCalled Add-DnsServerConditionalForwarderZone -Scope It - Assert-MockCalled Remove-DnsServerZone -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It - Assert-MockCalled Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It - } - } + It 'When Ensure is absent, removes the zone' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockSetParameters.Ensure = 'Absent' + Set-TargetResource @mockSetParameters } + + Should -Invoke Remove-DnsServerZone -Scope It + Should -Invoke Add-DnsServerConditionalForwarderZone -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It } + } - Context 'DSC_DnsServerConditionalForwarder\Test-TargetResource' -Tag 'Test' { - Context 'When the system is in the desired state' { - Context 'When the zone is present on the server' { - It 'When Ensure is present, and the list of master servers matches, returns true' { - Test-TargetResource @defaultParameters | Should -Be $true - } - } + Context 'When the zone is not present on the server' { + BeforeAll { + Mock Get-DnsServerZone + } + + It 'When Ensure is present, attempts to create the zone' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + Set-TargetResource @mockSetParameters + } + + Should -Invoke Add-DnsServerConditionalForwarderZone -Scope It + Should -Invoke Remove-DnsServerZone -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } -Times 0 -Scope It + Should -Invoke Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } -Times 0 -Scope It + } + } + } +} + +Context 'DSC_DnsServerConditionalForwarder\Test-TargetResource' -Tag 'Test' { + BeforeAll { + Mock Get-DnsServerZone { + @{ + MasterServers = '1.1.1.1', '2.2.2.2' + ZoneType = $script:zoneType + IsDsIntegrated = $script:isDsIntegrated + ReplicationScope = $script:ReplicationScope + DirectoryPartitionName = 'CustomName' + } + } + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:defaultParameters = @{ + Ensure = 'Present' + Name = 'domain.name' + MasterServers = '1.1.1.1', '2.2.2.2' + ReplicationScope = 'Domain' + Verbose = $VerbosePreference + } + } + } + + BeforeEach { + $script:zoneType = 'Forwarder' + $script:isDsIntegrated = $true + $script:ReplicationScope = 'Domain' + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the zone is not present on the server' { - BeforeAll { - Mock Get-DnsServerZone - } + $script:mockTestParameters = $defaultParameters.Clone() + } + } - It 'When Ensure is is absent, returns true' { - $defaultParameters.Ensure = 'Absent' + Context 'When the system is in the desired state' { + Context 'When the zone is present on the server' { + It 'When Ensure is present, and the list of master servers matches, returns true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Test-TargetResource @defaultParameters | Should -Be $true - } - } + Test-TargetResource @mockTestParameters | Should -BeTrue } + } + } - Context 'When the system is not in the desired state' { - Context 'When the zone is present on the server' { - It 'When Ensure is present, and the list of master servers differs, returns false' { - $defaultParameters.MasterServers = '3.3.3.3', '4.4.4.4' + Context 'When the zone is not present on the server' { + BeforeAll { + Mock Get-DnsServerZone + } - Test-TargetResource @defaultParameters | Should -BeFalse - } + It 'When Ensure is is absent, returns true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'When Ensure is present, and the ZoneType does not match, returns false' { - $Script:ZoneType = 'Primary' + $mockTestParameters.Ensure = 'Absent' - Test-TargetResource @defaultParameters | Should -BeFalse - } + Test-TargetResource @mockTestParameters | Should -BeTrue + } + } + } + } - It 'When Ensure is present, and the zone is AD Integrated, and ReplicationScope is None, returns false' { - $defaultParameters.ReplicationScope = 'None' + Context 'When the system is not in the desired state' { + Context 'When the zone is present on the server' { + It 'When Ensure is present, and the list of master servers differs, returns false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Test-TargetResource @defaultParameters | Should -BeFalse - } + $mockTestParameters.MasterServers = '3.3.3.3', '4.4.4.4' - It 'When Ensure is present, and the zone is not AD integrated, and ReplicationScope is Domain, returns false' { - $Script:isDsIntegrated = $false + Test-TargetResource @mockTestParameters | Should -BeFalse + } + } + + It 'When Ensure is present, and the ZoneType does not match, returns false' { + $script:ZoneType = 'Primary' - Test-TargetResource @defaultParameters | Should -BeFalse - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'When Ensure is present, and the replication scope differs, returns false' { - $defaultParameters.ReplicationScope = 'Forest' + Test-TargetResource @mockTestParameters | Should -BeFalse + } + } - Test-TargetResource @defaultParameters | Should -BeFalse - } + It 'When Ensure is present, and the zone is AD Integrated, and ReplicationScope is None, returns false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockTestParameters.ReplicationScope = 'None' + + Test-TargetResource @mockTestParameters | Should -BeFalse + } + } - It 'When Ensure is present, and ReplicationScope is Custom, and the DirectoryPartitionName does not match, returns false' { - $Script:ReplicationScope = 'Custom' + It 'When Ensure is present, and the zone is not AD integrated, and ReplicationScope is Domain, returns false' { + $script:isDsIntegrated = $false - $defaultParameters.ReplicationScope = 'Custom' - $defaultParameters.DirectoryPartitionName = 'NewName' + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Test-TargetResource @defaultParameters | Should -BeFalse - } + Test-TargetResource @mockTestParameters | Should -BeFalse + } + } - It 'When Ensure is absent, returns false' { - $defaultParameters.Ensure = 'Absent' + It 'When Ensure is present, and the replication scope differs, returns false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Test-TargetResource @defaultParameters | Should -BeFalse - } + $mockTestParameters.ReplicationScope = 'Forest' - It 'When Ensure is absent, and a zone of a different type exists, returns true' { - $Script:ZoneType = 'Primary' + Test-TargetResource @mockTestParameters | Should -BeFalse + } + } - $defaultParameters.Ensure = 'Absent' + It 'When Ensure is present, and ReplicationScope is Custom, and the DirectoryPartitionName does not match, returns false' { + $script:ReplicationScope = 'Custom' - Test-TargetResource @defaultParameters | Should -Be $true - } - } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the zone is not present on the server' { - BeforeAll { - Mock Get-DnsServerZone - } + $mockTestParameters.ReplicationScope = 'Custom' + $mockTestParameters.DirectoryPartitionName = 'NewName' - It 'When Ensure is present, returns false' { - Test-TargetResource @defaultParameters | Should -BeFalse - } - } + Test-TargetResource @mockTestParameters | Should -BeFalse } } - Context 'DSC_DnsServerConditionalForwarder\Test-DscDnsServerConditionalForwarderParameter' -Tag 'Helper' { - It 'When Ensure is present, and MasterServers is not set, throws an error' { - $defaultParameters.Remove('MasterServers') + It 'When Ensure is absent, returns false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockTestParameters.Ensure = 'Absent' - { Test-TargetResource @defaultParameters } | Should -Throw -ErrorId MasterServersIsMandatory + Test-TargetResource @mockTestParameters | Should -BeFalse } + } + + It 'When Ensure is absent, and a zone of a different type exists, returns true' { + $script:ZoneType = 'Primary' + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'When Ensure is absent, and MasterServers is not set, does not not throw an error' { - { Test-TargetResource @defaultParameters } | Should -Not -Throw + $mockTestParameters.Ensure = 'Absent' + + Test-TargetResource @mockTestParameters | Should -BeTrue } + } + } - It 'When Ensure is present, and ReplicationScope is Custom, and DirectoryPartitionName is not set, throws an error' { - $defaultParameters.ReplicationScope = 'Custom' - $defaultParameters.DirectoryPartitionName = $null + Context 'When the zone is not present on the server' { + BeforeAll { + Mock Get-DnsServerZone + } - { Test-TargetResource @defaultParameters } | Should -Throw -ErrorId DirectoryPartitionNameIsMandatory + It 'When Ensure is present, returns false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + Test-TargetResource @mockTestParameters | Should -BeFalse } } } } } -finally -{ - Invoke-TestCleanup + +Context 'DSC_DnsServerConditionalForwarder\Test-DscDnsServerConditionalForwarderParameter' -Tag 'Helper' { + BeforeAll { + Mock Get-DnsServerZone { + @{ + MasterServers = '1.1.1.1', '2.2.2.2' + ZoneType = $script:zoneType + IsDsIntegrated = $script:isDsIntegrated + ReplicationScope = $script:ReplicationScope + DirectoryPartitionName = 'CustomName' + } + } + Mock Remove-DnsServerZone + Mock Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -gt 0 } + Mock Set-DnsServerConditionalForwarderZone -ParameterFilter { $MasterServers.Count -eq 0 } + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:defaultParameters = @{ + Ensure = 'Present' + Name = 'domain.name' + MasterServers = '1.1.1.1', '2.2.2.2' + ReplicationScope = 'Domain' + Verbose = $VerbosePreference + } + } + } + + BeforeEach { + $script:zoneType = 'Forwarder' + $script:isDsIntegrated = $true + $script:ReplicationScope = 'Domain' + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockHelperParameters = $defaultParameters.Clone() + } + } + + It 'When Ensure is present, and MasterServers is not set, throws an error' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockHelperParameters.Remove('MasterServers') + + { Test-TargetResource @mockHelperParameters } | Should -Throw -ErrorId 'MasterServersIsMandatory*' + } + } + + It 'When Ensure is absent, and MasterServers is not set, does not not throw an error' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + { Test-TargetResource @mockHelperParameters } | Should -Not -Throw + } + } + + It 'When Ensure is present, and ReplicationScope is Custom, and DirectoryPartitionName is not set, throws an error' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $mockHelperParameters.ReplicationScope = 'Custom' + $mockHelperParameters.DirectoryPartitionName = $null + + { Test-TargetResource @mockHelperParameters } | Should -Throw -ErrorId 'DirectoryPartitionNameIsMandatory*' + } + } } diff --git a/tests/Unit/DSC_DnsServerDiagnostics.Tests.ps1 b/tests/Unit/DSC_DnsServerDiagnostics.Tests.ps1 index a3337ba3..7f19a717 100644 --- a/tests/Unit/DSC_DnsServerDiagnostics.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerDiagnostics.Tests.ps1 @@ -1,16 +1,37 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerDiagnostics' +<# + .SYNOPSIS + Unit test for DSC_DnsServerDiagnostics DSC resource. +#> -function Invoke-TestSetup -{ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerDiagnostics' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,219 +40,503 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force + + Remove-Module -Name DnsServer -Force } -Invoke-TestSetup - -try -{ - InModuleScope $script:dscResourceName { - #region Pester Test Initialization - $testParameters = @{ - DnsServer = 'dns1.company.local' - Answers = $true - EnableLogFileRollover = $true - EnableLoggingForLocalLookupEvent = $true - EnableLoggingForPluginDllEvent = $true - EnableLoggingForRecursiveLookupEvent = $true - EnableLoggingForRemoteServerEvent = $true - EnableLoggingForServerStartStopEvent = $true - EnableLoggingForTombstoneEvent = $true - EnableLoggingForZoneDataWriteEvent = $true - EnableLoggingForZoneLoadingEvent = $true - EnableLoggingToFile = $true - EventLogLevel = 4 - FilterIPAddressList = "192.168.1.1","192.168.1.2" - FullPackets = $true - LogFilePath = 'C:\Windows\System32\DNS\DNSDiagnostics.log' - MaxMBFileSize = 500000000 - Notifications = $true - Queries = $true - QuestionTransactions = $true - ReceivePackets = $true - SaveLogsToPersistentStorage = $true - SendPackets = $true - TcpPackets = $true - UdpPackets = $true - UnmatchedResponse = $true - Update = $true - UseSystemEventLog = $true - WriteThrough = $true - } +Describe 'DSC_DnsServerDiagnostics\Get-TargetResource' -Tag 'Get' { + Context 'When the resource exists' { + BeforeAll { + $mockGetDnsServerDiagnostics = @{ + DnsServer = 'dns1.company.local' + Answers = $false + EnableLogFileRollover = $false + EnableLoggingForLocalLookupEvent = $false + EnableLoggingForPluginDllEvent = $false + EnableLoggingForRecursiveLookupEvent = $false + EnableLoggingForRemoteServerEvent = $false + EnableLoggingForServerStartStopEvent = $false + EnableLoggingForTombstoneEvent = $false + EnableLoggingForZoneDataWriteEvent = $false + EnableLoggingForZoneLoadingEvent = $false + EnableLoggingToFile = $false + EventLogLevel = 3 + FilterIPAddressList = '192.168.1.3', '192.168.1.4' + FullPackets = $false + LogFilePath = 'C:\Windows\System32\DNS_log\DNSDiagnostics.log' + MaxMBFileSize = 400000000 + Notifications = $false + Queries = $false + QuestionTransactions = $false + ReceivePackets = $false + SaveLogsToPersistentStorage = $false + SendPackets = $false + TcpPackets = $false + UdpPackets = $false + UnmatchedResponse = $false + Update = $false + UseSystemEventLog = $false + WriteThrough = $false + } - $mockGetDnsServerDiagnostics = @{ - DnsServer = 'dns1.company.local' - Answers = $false - EnableLogFileRollover = $false - EnableLoggingForLocalLookupEvent = $false - EnableLoggingForPluginDllEvent = $false - EnableLoggingForRecursiveLookupEvent = $false - EnableLoggingForRemoteServerEvent = $false - EnableLoggingForServerStartStopEvent = $false - EnableLoggingForTombstoneEvent = $false - EnableLoggingForZoneDataWriteEvent = $false - EnableLoggingForZoneLoadingEvent = $false - EnableLoggingToFile = $false - EventLogLevel = 3 - FilterIPAddressList = "192.168.1.3","192.168.1.4" - FullPackets = $false - LogFilePath = 'C:\Windows\System32\DNS_log\DNSDiagnostics.log' - MaxMBFileSize = 400000000 - Notifications = $false - Queries = $false - QuestionTransactions = $false - ReceivePackets = $false - SaveLogsToPersistentStorage = $false - SendPackets = $false - TcpPackets = $false - UdpPackets = $false - UnmatchedResponse = $false - Update = $false - UseSystemEventLog = $false - WriteThrough = $false + Mock -CommandName Get-DnsServerDiagnostics -MockWith { $mockGetDnsServerDiagnostics } } - $commonParameters += [System.Management.Automation.PSCmdlet]::CommonParameters - $commonParameters += [System.Management.Automation.PSCmdlet]::OptionalCommonParameters - - $mockParameters = @{ - Verbose = $true - Debug = $true - ErrorAction = 'stop' - WarningAction = 'Continue' - InformationAction = 'Continue' - ErrorVariable = 'err' - WarningVariable = 'warn' - OutVariable = 'out' - OutBuffer = 'outbuff' - PipelineVariable = 'pipe' - InformationVariable = 'info' - WhatIf = $true - Confirm = $true - UseTransaction = $true - DnsServer = 'dns1.company.local' + It 'Should return "something"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $getResult = Get-TargetResource -DnsServer 'dns1.company.local' + + $getResult.DnsServer | Should -Be 'dns1.company.local' + $getResult.Answers | Should -BeFalse + $getResult.EnableLogFileRollover | Should -BeFalse + $getResult.EnableLoggingForLocalLookupEvent | Should -BeFalse + $getResult.EnableLoggingForPluginDllEvent | Should -BeFalse + $getResult.EnableLoggingForRecursiveLookupEvent | Should -BeFalse + $getResult.EnableLoggingForRemoteServerEvent | Should -BeFalse + $getResult.EnableLoggingForServerStartStopEvent | Should -BeFalse + $getResult.EnableLoggingForTombstoneEvent | Should -BeFalse + $getResult.EnableLoggingForZoneDataWriteEvent | Should -BeFalse + $getResult.EnableLoggingForZoneLoadingEvent | Should -BeFalse + $getResult.EnableLoggingToFile | Should -BeFalse + $getResult.EventLogLevel | Should -Be 3 + $getResult.FilterIPAddressList | Should -Be @('192.168.1.3', '192.168.1.4') + $getResult.FullPackets | Should -BeFalse + $getResult.LogFilePath | Should -Be 'C:\Windows\System32\DNS_log\DNSDiagnostics.log' + $getResult.MaxMBFileSize | Should -Be 400000000 + $getResult.Notifications | Should -BeFalse + $getResult.Queries | Should -BeFalse + $getResult.QuestionTransactions | Should -BeFalse + $getResult.ReceivePackets | Should -BeFalse + $getResult.SaveLogsToPersistentStorage | Should -BeFalse + $getResult.SendPackets | Should -BeFalse + $getResult.TcpPackets | Should -BeFalse + $getResult.UdpPackets | Should -BeFalse + $getResult.UnmatchedResponse | Should -BeFalse + $getResult.Update | Should -BeFalse + $getResult.UseSystemEventLog | Should -BeFalse + $getResult.WriteThrough | Should -BeFalse + } + } + } + Context 'When the resource does not exist' { + BeforeAll { + Mock -CommandName Get-DnsServerDiagnostics -MockWith { throw 'Invalid Class' } } - #endregion Pester Test Initialization - - #region Example state 1 - Describe 'The system is not in the desired state' { - Mock -CommandName Assert-Module - - Context 'Get-TargetResource' { - It "Get method returns 'something'" { - Mock -CommandName Get-DnsServerDiagnostics -MockWith {$mockGetDnsServerDiagnostics} - - $getResult = Get-TargetResource -DnsServer 'dns1.company.local' - foreach ($key in $getResult.Keys) - { - if ($null -ne $getResult[$key] -and $key -ne 'DnsServer') - { - $getResult[$key] | Should be $mockGetDnsServerDiagnostics.$key - } - } - } + It 'Get throws when DnsServerDiagnostics is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + { Get-TargetResource -DnsServer 'dns1.company.local' } | Should -Throw 'Invalid Class' + } + } - It 'Get throws when DnsServerDiagnostics is not found' { - Mock -CommandName Get-DnsServerDiagnostics -MockWith {throw 'Invalid Class'} + It 'Test throws when DnsServerDiagnostics is not found' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + { Get-TargetResource -DnsServer 'dns1.company.local' } | Should -Throw 'Invalid Class' + } + } + } +} - {Get-TargetResource -DnsServer 'dns1.company.local'} | Should -Throw 'Invalid Class' +Describe 'DSC_DnsServerDiagnostics\Test-TargetResource' -Tag 'Test' { + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { return @{ + DnsServer = 'dns1.company.local' + Answers = $false + EnableLogFileRollover = $false + EnableLoggingForLocalLookupEvent = $false + EnableLoggingForPluginDllEvent = $false + EnableLoggingForRecursiveLookupEvent = $false + EnableLoggingForRemoteServerEvent = $false + EnableLoggingForServerStartStopEvent = $false + EnableLoggingForTombstoneEvent = $false + EnableLoggingForZoneDataWriteEvent = $false + EnableLoggingForZoneLoadingEvent = $false + EnableLoggingToFile = $false + EventLogLevel = 3 + FilterIPAddressList = '192.168.1.3', '192.168.1.4' + FullPackets = $false + LogFilePath = 'C:\Windows\System32\DNS_log\DNSDiagnostics.log' + MaxMBFileSize = 400000000 + Notifications = $false + Queries = $false + QuestionTransactions = $false + ReceivePackets = $false + SaveLogsToPersistentStorage = $false + SendPackets = $false + TcpPackets = $false + UdpPackets = $false + UnmatchedResponse = $false + Update = $false + UseSystemEventLog = $false + WriteThrough = $false } } + } - Context 'Test-TargetResource' { - $falseParameters = @{ - DnsServer = 'dns1.company.local' + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'Answers' + PropertyValue = $true } - - foreach ($key in $testParameters.Keys) - { - if ($key -ne 'DnsServer') - { - $falseTestParameters = $falseParameters.Clone() - $falseTestParameters.Add($key,$testParameters[$key]) - - It "Test method returns false when testing $key" { - Mock -CommandName Get-TargetResource -MockWith {$mockGetDnsServerDiagnostics} - - Test-TargetResource @falseTestParameters | Should -BeFalse - } - } + @{ + PropertyName = 'EnableLogFileRollover' + PropertyValue = $true } - } + @{ + PropertyName = 'EnableLoggingForLocalLookupEvent' + PropertyValue = $true + } + @{ + PropertyName = 'EnableLoggingForPluginDllEvent' + PropertyValue = $true + } + @{ + PropertyName = 'EnableLoggingForRecursiveLookupEvent' + PropertyValue = $true + } + @{ + PropertyName = 'EnableLoggingForRemoteServerEvent' + PropertyValue = $true + } + @{ + PropertyName = 'EnableLoggingForServerStartStopEvent' + PropertyValue = $true + } + @{ + PropertyName = 'EnableLoggingForTombstoneEvent' + PropertyValue = $true + } + @{ + PropertyName = 'EnableLoggingForZoneDataWriteEvent' + PropertyValue = $true + } + @{ + PropertyName = 'EnableLoggingForZoneLoadingEvent' + PropertyValue = $true + } + @{ + PropertyName = 'EnableLoggingToFile' + PropertyValue = $true + } + @{ + PropertyName = 'EventLogLevel' + PropertyValue = 4 + } + @{ + PropertyName = 'FilterIPAddressList' + PropertyValue = '192.168.1.1', '192.168.1.2' + } + @{ + PropertyName = 'FullPackets' + PropertyValue = $true + } + @{ + PropertyName = 'LogFilePath' + PropertyValue = 'C:\Windows\System32\DNS\DNSDiagnostics.log' + } + @{ + PropertyName = 'MaxMBFileSize' + PropertyValue = 500000000 + } + @{ + PropertyName = 'Notifications' + PropertyValue = $true + } + @{ + PropertyName = 'Queries' + PropertyValue = $true + } + @{ + PropertyName = 'QuestionTransactions' + PropertyValue = $true + } + @{ + PropertyName = 'ReceivePackets' + PropertyValue = $true + } + @{ + PropertyName = 'SaveLogsToPersistentStorage' + PropertyValue = $true + } + @{ + PropertyName = 'SendPackets' + PropertyValue = $true + } + @{ + PropertyName = 'TcpPackets' + PropertyValue = $true + } + @{ + PropertyName = 'UdpPackets' + PropertyValue = $true + } + @{ + PropertyName = 'UnmatchedResponse' + PropertyValue = $true + } + @{ + PropertyName = 'Update' + PropertyValue = $true + } + @{ + PropertyName = 'UseSystemEventLog' + PropertyValue = $true + } + @{ + PropertyName = 'WriteThrough' + PropertyValue = $true + } + ) + } - Context 'Error handling' { - It 'Test throws when DnsServerDiagnostics is not found' { - Mock -CommandName Get-DnsServerDiagnostics -MockWith {throw 'Invalid Class'} + It 'Should return $false for property ' -TestCases $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - {Get-TargetResource -DnsServer 'dns1.company.local'} | Should -Throw 'Invalid Class' + $testTargetResourceParameters = @{ + DnsServer = 'dns1.company.local' + $PropertyName = $PropertyValue } - } - - Context 'Set-TargetResource' { - It 'Set method calls Set-CimInstance' { - Mock -CommandName Get-DnsServerDiagnostics -MockWith {$mockGetDnsServerDiagnostics} - Mock -CommandName Set-DnsServerDiagnostics - Set-TargetResource @testParameters + Test-TargetResource @testTargetResourceParameters | Should -BeFalse + } + } + } - Assert-MockCalled Set-DnsServerDiagnostics -Exactly 1 + Context 'When the system is in the desired state' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { + return @{ + DnsServer = 'dns1.company.local' + Answers = $false + EnableLogFileRollover = $false + EnableLoggingForLocalLookupEvent = $false + EnableLoggingForPluginDllEvent = $false + EnableLoggingForRecursiveLookupEvent = $false + EnableLoggingForRemoteServerEvent = $false + EnableLoggingForServerStartStopEvent = $false + EnableLoggingForTombstoneEvent = $false + EnableLoggingForZoneDataWriteEvent = $false + EnableLoggingForZoneLoadingEvent = $false + EnableLoggingToFile = $false + EventLogLevel = 3 + FilterIPAddressList = '192.168.1.3', '192.168.1.4' + FullPackets = $false + LogFilePath = 'C:\Windows\System32\DNS_log\DNSDiagnostics.log' + MaxMBFileSize = 400000000 + Notifications = $false + Queries = $false + QuestionTransactions = $false + ReceivePackets = $false + SaveLogsToPersistentStorage = $false + SendPackets = $false + TcpPackets = $false + UdpPackets = $false + UnmatchedResponse = $false + Update = $false + UseSystemEventLog = $false + WriteThrough = $false } } } - #endregion Example state 1 - - #region Example state 2 - Describe 'The system is in the desired state' { - Context 'Test-TargetResource' { - Mock -CommandName Get-TargetResource -MockWith { $mockGetDnsServerDiagnostics } - $trueParameters = @{ - DnsServer = 'dns1.company.local' + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'Answers' + PropertyValue = $false } + @{ + PropertyName = 'EnableLogFileRollover' + PropertyValue = $false + } + @{ + PropertyName = 'EnableLoggingForLocalLookupEvent' + PropertyValue = $false + } + @{ + PropertyName = 'EnableLoggingForPluginDllEvent' + PropertyValue = $false + } + @{ + PropertyName = 'EnableLoggingForRecursiveLookupEvent' + PropertyValue = $false + } + @{ + PropertyName = 'EnableLoggingForRemoteServerEvent' + PropertyValue = $false + } + @{ + PropertyName = 'EnableLoggingForServerStartStopEvent' + PropertyValue = $false + } + @{ + PropertyName = 'EnableLoggingForTombstoneEvent' + PropertyValue = $false + } + @{ + PropertyName = 'EnableLoggingForZoneDataWriteEvent' + PropertyValue = $false + } + @{ + PropertyName = 'EnableLoggingForZoneLoadingEvent' + PropertyValue = $false + } + @{ + PropertyName = 'EnableLoggingToFile' + PropertyValue = $false + } + @{ + PropertyName = 'EventLogLevel' + PropertyValue = 3 + } + @{ + PropertyName = 'FilterIPAddressList' + PropertyValue = '192.168.1.3', '192.168.1.4' + } + @{ + PropertyName = 'FullPackets' + PropertyValue = $false + } + @{ + PropertyName = 'LogFilePath' + PropertyValue = 'C:\Windows\System32\DNS_log\DNSDiagnostics.log' + } + @{ + PropertyName = 'MaxMBFileSize' + PropertyValue = 400000000 + } + @{ + PropertyName = 'Notifications' + PropertyValue = $false + } + @{ + PropertyName = 'Queries' + PropertyValue = $false + } + @{ + PropertyName = 'QuestionTransactions' + PropertyValue = $false + } + @{ + PropertyName = 'ReceivePackets' + PropertyValue = $false + } + @{ + PropertyName = 'SaveLogsToPersistentStorage' + PropertyValue = $false + } + @{ + PropertyName = 'SendPackets' + PropertyValue = $false + } + @{ + PropertyName = 'TcpPackets' + PropertyValue = $false + } + @{ + PropertyName = 'UdpPackets' + PropertyValue = $false + } + @{ + PropertyName = 'UnmatchedResponse' + PropertyValue = $false + } + @{ + PropertyName = 'Update' + PropertyValue = $false + } + @{ + PropertyName = 'UseSystemEventLog' + PropertyValue = $false + } + @{ + PropertyName = 'WriteThrough' + PropertyValue = $false + } + ) + } - foreach ($key in $testParameters.Keys) - { - if ($key -ne 'DnsServer') - { - $trueTestParameters = $trueParameters.Clone() - - $trueTestParameters.Add($key,$mockGetDnsServerDiagnostics.$key) + It 'Should return $true for property ' -TestCases $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - It "Test method returns true when testing $key" { - $result = Test-TargetResource @trueTestParameters - $result | Should -BeTrue - } - } + $testTargetResourceParameters = @{ + DnsServer = 'dns1.company.local' + $PropertyName = $PropertyValue } + Test-TargetResource @testTargetResourceParameters | Should -BeTrue } } - #endregion Example state 2 - - #region Non-Exported Function Unit Tests + } +} - Describe 'Private functions' { - Context 'Remove-CommonParameters' { - It 'Should not contain any common parameters' { - $removeResults = Remove-CommonParameter $mockParameters +Describe 'DSC_DnsServerDiagnostics\Set-TargetResource' -Tag 'Set' { + BeforeAll { + Mock -CommandName Set-DnsServerDiagnostics + } - foreach ($key in $removeResults.Keys) - { - $commonParameters -notcontains $key | Should -BeTrue - } - } + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParameters = @{ + DnsServer = 'dns1.company.local' + Answers = $true + EnableLogFileRollover = $true + EnableLoggingForLocalLookupEvent = $true + EnableLoggingForPluginDllEvent = $true + EnableLoggingForRecursiveLookupEvent = $true + EnableLoggingForRemoteServerEvent = $true + EnableLoggingForServerStartStopEvent = $true + EnableLoggingForTombstoneEvent = $true + EnableLoggingForZoneDataWriteEvent = $true + EnableLoggingForZoneLoadingEvent = $true + EnableLoggingToFile = $true + EventLogLevel = 4 + FilterIPAddressList = '192.168.1.1', '192.168.1.2' + FullPackets = $true + LogFilePath = 'C:\Windows\System32\DNS\DNSDiagnostics.log' + MaxMBFileSize = 500000000 + Notifications = $true + Queries = $true + QuestionTransactions = $true + ReceivePackets = $true + SaveLogsToPersistentStorage = $true + SendPackets = $true + TcpPackets = $true + UdpPackets = $true + UnmatchedResponse = $true + Update = $true + UseSystemEventLog = $true + WriteThrough = $true } + + Set-TargetResource @testParameters } - #endregion Non-Exported Function Unit Tests + + Should -Invoke -CommandName Set-DnsServerDiagnostics -Times 1 -Exactly } } -finally -{ - Invoke-TestCleanup -} diff --git a/tests/Unit/DSC_DnsServerForwarder.Tests.ps1 b/tests/Unit/DSC_DnsServerForwarder.Tests.ps1 index 74049434..559dd33a 100644 --- a/tests/Unit/DSC_DnsServerForwarder.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerForwarder.Tests.ps1 @@ -1,16 +1,37 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerForwarder' +<# + .SYNOPSIS + Unit test for DSC_DnsServerForwarder DSC resource. +#> -function Invoke-TestSetup -{ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerForwarder' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,33 +40,105 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force + + Remove-Module -Name DnsServer -Force } -Invoke-TestSetup +Describe 'DSC_DnsServerForwarder\Get-TargetResource' -Tag 'Get' { + BeforeAll { + Mock -CommandName Get-DnsServerForwarder -MockWith { + return @{ + IPAddress = $forwarders + UseRootHint = $UseRootHint + Timeout = $timeout + EnableReordering = $reordering + } + } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:defaultParameters = @{ + IsSingleInstance = 'Yes' + IPAddresses = '192.168.0.1', '192.168.0.2' + UseRootHint = $true + Verbose = $false + } + } + } -try -{ - InModuleScope $script:dscResourceName { - $forwarders = '192.168.0.1', '192.168.0.2' - $UseRootHint = $true + BeforeEach { + $script:forwarders = '192.168.0.1', '192.168.0.2' + $script:UseRootHint = $true + $script:timeout = 10 + $script:reordering = $true - $testParams = @{ - IsSingleInstance = 'Yes' - IPAddresses = $forwarders - UseRootHint = $UseRootHint - Verbose = $true + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:mockTestParameters = $defaultParameters.Clone() } + } + + It 'Should return a "System.Collections.Hashtable" object type' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $targetResource = Get-TargetResource -IsSingleInstance $mockTestParameters.IsSingleInstance - $testParamLimited = @{ - IsSingleInstance = 'Yes' - IPAddresses = $forwarders - Verbose = $true + $targetResource | Should -BeOfType [System.Collections.Hashtable] } + } + + It 'Should return the correct values when forwarders exist' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $targetResource = Get-TargetResource -IsSingleInstance $mockTestParameters.IsSingleInstance + + $targetResource.IPAddresses | Should -Be $mockTestParameters.IPAddresses + $targetResource.UseRootHint | Should -Be $mockTestParameters.UseRootHint + $targetResource.TimeOut | Should -Be 10 + $targetResource.EnableReordering | Should -BeTrue + } + } + + It "Should return expected values when forwarders don't exist" { + $script:forwarders = @() + $script:timeout = 4 + $script:reordering = $false + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $targetResource = Get-TargetResource -IsSingleInstance $mockTestParameters.IsSingleInstance + + $targetResource.IPAddresses | Should -BeNullOrEmpty + $targetResource.UseRootHint | Should -BeTrue + $targetResource.Timeout | Should -Be 4 + $targetResource.EnableReordering | Should -BeFalse + } + } +} + +Describe 'DSC_DnsServerForwarder\Test-TargetResource' -Tag 'Test' { + BeforeAll { + $forwarders = '192.168.0.1', '192.168.0.2' + $UseRootHint = $true $fakeDNSForwarder = @{ IPAddress = $forwarders @@ -59,213 +152,336 @@ try UseRootHint = -not $UseRootHint } - Describe 'DSC_DnsServerForwarder\Get-TargetResource' { - It 'Returns a "System.Collections.Hashtable" object type' { - Mock -CommandName Get-DnsServerForwarder -MockWith { return $fakeDNSForwarder } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $targetResource = Get-TargetResource -IsSingleInstance $testParams.IsSingleInstance + $script:defaultParameters = @{ + IsSingleInstance = 'Yes' + IPAddresses = '192.168.0.1', '192.168.0.2' + UseRootHint = $true + Verbose = $false + } - $targetResource | Should -BeOfType [System.Collections.Hashtable] + $script:defaultParamsLimited = @{ + IsSingleInstance = 'Yes' + IPAddresses = '192.168.0.1', '192.168.0.2' + Verbose = $false } + } + } - It "Returns the correct values when forwarders exist" { - Mock -CommandName Get-DnsServerForwarder -MockWith { - return $fakeDNSForwarder - } + BeforeEach { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $targetResource = Get-TargetResource -IsSingleInstance $testParams.IsSingleInstance + $script:mockTestParameters = $defaultParameters.Clone() + $script:mockLimitedTestParameters = $defaultParamsLimited.Clone() + } - $targetResource.IPAddresses | Should -Be $testParams.IPAddresses - $targetResource.UseRootHint | Should -Be $testParams.UseRootHint - $targetResource.TimeOut | Should -Be 10 - $targetResource.EnableReordering | Should -BeTrue - } + } - It "Returns expected values when forwarders don't exist" { + Context 'When the system is in the desired state' { + Context 'When the command completes' { + BeforeAll { Mock -CommandName Get-DnsServerForwarder -MockWith { - return @{ - IPAddress = @() - UseRootHint = $true - Timeout = 4 - EnableReordering = $false - } + return $fakeDNSForwarder } + } + + It 'Should return a "System.Boolean" object type' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $targetResource = Get-TargetResource -IsSingleInstance $testParams.IsSingleInstance + $targetResource = Test-TargetResource @mockTestParameters - $targetResource.IPAddresses | Should -BeNullOrEmpty - $targetResource.UseRootHint | Should -BeTrue - $targetResource.Timeout | Should -Be 4 - $targetResource.EnableReordering | Should -BeFalse + $targetResource | Should -BeOfType [System.Boolean] + } } } - #endregion - Describe 'DSC_DnsServerForwarder\Test-TargetResource' { - It 'Returns a "System.Boolean" object type' { + Context 'When forwarders match' { + BeforeAll { Mock -CommandName Get-DnsServerForwarder -MockWith { return $fakeDNSForwarder } - - $targetResource = Test-TargetResource @testParams - - $targetResource | Should -BeOfType [System.Boolean] } - It 'Passes when forwarders match' { - Mock -CommandName Get-DnsServerForwarder -MockWith { - return $fakeDNSForwarder - } + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Test-TargetResource @testParams | Should -BeTrue + Test-TargetResource @mockTestParameters | Should -BeTrue + } } + } - It 'Passes when forwarders match but root hint do not and are not specified' { + Context 'When forwarders match but root hint do not and are not specified' { + BeforeAll { Mock -CommandName Get-DnsServerForwarder -MockWith { return $fakeUseRootHint } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Test-TargetResource @testParamLimited | Should -BeTrue + Test-TargetResource @mockLimitedTestParameters | Should -BeTrue + } } + } - It "Should return $true when EnableReordering don't match" { + Context 'When EnableReordering does match' { + BeforeAll { Mock -CommandName Get-DnsServerForwarder -MockWith { return @{ EnableReordering = $true } } + } + + It "Should return $true" { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $result = Test-TargetResource -IsSingleInstance 'Yes' -EnableReordering $true + $result = Test-TargetResource -IsSingleInstance 'Yes' -EnableReordering $true - $result | Should -BeTrue + $result | Should -BeTrue + } } + } - It "Should return $true when Timeout don't match" { + Context 'When Timeout does match' { + BeforeAll { Mock -CommandName Get-DnsServerForwarder -MockWith { return @{ Timeout = 4 } } + } - $result = Test-TargetResource -IsSingleInstance 'Yes' -Timeout 4 + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $result | Should -BeTrue + $result = Test-TargetResource -IsSingleInstance 'Yes' -Timeout 4 + + $result | Should -BeTrue + } } + } + } - It "Fails when forwarders don't match" { + Context 'When the system is not in the desired state' { + Context 'When forwarder count do not match' { + BeforeAll { Mock -CommandName Get-DnsServerForwarder -MockWith { return @{ IPAddress = @() UseRootHint = $true } } + } + + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + Test-TargetResource @mockTestParameters | Should -BeFalse + } + } + } + Context 'When forwarder values do not match' { + BeforeAll { + Mock -CommandName Get-DnsServerForwarder -MockWith { + return @{ + IPAddress = '192.168.0.1', '192.168.0.3' + UseRootHint = $true + } + } + } - Test-TargetResource @testParams | Should -BeFalse + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + Test-TargetResource @mockTestParameters | Should -BeFalse + } } + } - It "Fails when UseRootHint don't match" { + Context 'When UseRootHint does not match' { + BeforeAll { Mock -CommandName Get-DnsServerForwarder -MockWith { return @{ - IPAddress = $fakeDNSForwarder.IpAddress + IPAddress = $fakeDNSForwarder.IpAddress UseRootHint = $false } } + } - Test-TargetResource @testParams | Should -BeFalse + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + Test-TargetResource @mockTestParameters | Should -BeFalse + } } + } - It "Should return $false when EnableReordering don't match" { + Context 'When EnableReordering does not match' { + BeforeAll { Mock -CommandName Get-DnsServerForwarder -MockWith { return @{ EnableReordering = $false } } + } - $result = Test-TargetResource -IsSingleInstance 'Yes' -EnableReordering $true + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $result | Should -BeFalse + $result = Test-TargetResource -IsSingleInstance 'Yes' -EnableReordering $true + + $result | Should -BeFalse + } } + } - It "Should return $false when Timeout don't match" { + Context 'When Timeout does not match' { + BeforeAll { Mock -CommandName Get-DnsServerForwarder -MockWith { return @{ Timeout = 10 } } + } - $result = Test-TargetResource -IsSingleInstance 'Yes' -Timeout 4 + It "Should return $false" { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $result | Should -BeFalse + $result = Test-TargetResource -IsSingleInstance 'Yes' -Timeout 4 + + $result | Should -BeFalse + } } } + } +} - Describe 'DSC_DnsServerForwarder\Set-TargetResource' { - It "Calls Set-DnsServerForwarder once" { - Mock -CommandName Set-DnsServerForwarder -MockWith { } - Set-TargetResource @testParams - Assert-MockCalled -CommandName Set-DnsServerForwarder -Times 1 -Exactly -Scope It +Describe 'DSC_DnsServerForwarder\Set-TargetResource' -Tag 'Set' { + BeforeAll { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:testParams = @{ + IsSingleInstance = 'Yes' + IPAddresses = '192.168.0.1', '192.168.0.2' + UseRootHint = $true + Verbose = $false } + } + } - Context 'When removing all forwarders' { - It "Should call the correct mocks" { - Mock -CommandName Set-DnsServerForwarder - Mock -CommandName Remove-DnsServerForwarder - Mock -CommandName Get-DnsServerForwarder -MockWith { - return New-CimInstance -ClassName 'DnsServerForwarder' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ - IPAddress = @('1.1.1.1') - } - } + Context 'When setting forwarders' { + BeforeAll { + Mock -CommandName Set-DnsServerForwarder - Set-TargetResource -IsSingleInstance 'Yes' -IPAddresses @() + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerForwarder -Times 0 -Exactly -Scope It - Assert-MockCalled -CommandName Get-DnsServerForwarder -Times 1 -Exactly -Scope It - Assert-MockCalled -CommandName Remove-DnsServerForwarder -Times 1 -Exactly -Scope It - } + $script:mockSetParameters = $testParams.Clone() } + } - Context 'When enforcing just parameter UseRootHint' { - It "Should call the correct mock with correct parameters" { - Mock -CommandName Set-DnsServerForwarder + It 'Should call Set-DnsServerForwarder once' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Set-TargetResource -IsSingleInstance 'Yes' -UseRootHint $true + Set-TargetResource @mockSetParameters + } - Assert-MockCalled -CommandName Set-DnsServerForwarder -ParameterFilter { - # Only the property UseRootHint should exist in $PSBoundParameters. - -not $PSBoundParameters.ContainsKey('IPAddress') -and $UseRootHint -eq $true - } -Times 1 -Exactly -Scope It + Should -Invoke -CommandName Set-DnsServerForwarder -Times 1 -Exactly -Scope It + } + } + + Context 'When removing all forwarders' { + BeforeAll { + Mock -CommandName Set-DnsServerForwarder + Mock -CommandName Remove-DnsServerForwarder + Mock -CommandName Get-DnsServerForwarder -MockWith { + return New-CimInstance -ClassName 'DnsServerForwarder' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + IPAddress = @('1.1.1.1') } } + } - Context 'When enforcing just parameter EnableReordering' { - It "Should call the correct mock with correct parameters" { - Mock -CommandName Set-DnsServerForwarder + It 'Should call the correct mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Set-TargetResource -IsSingleInstance 'Yes' -EnableReordering $true + Set-TargetResource -IsSingleInstance 'Yes' -IPAddresses @() + } - Assert-MockCalled -CommandName Set-DnsServerForwarder -ParameterFilter { - # Only the property UseRootHint should exist in $PSBoundParameters. - -not $PSBoundParameters.ContainsKey('IPAddress') -and $EnableReordering -eq $true - } -Times 1 -Exactly -Scope It - } + Should -Invoke -CommandName Set-DnsServerForwarder -Times 0 -Exactly -Scope It + Should -Invoke -CommandName Get-DnsServerForwarder -Times 1 -Exactly -Scope It + Should -Invoke -CommandName Remove-DnsServerForwarder -Times 1 -Exactly -Scope It + } + } + + Context 'When enforcing just parameter UseRootHint' { + BeforeAll { + Mock -CommandName Set-DnsServerForwarder + } + + It 'Should call the correct mock with correct parameters' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + Set-TargetResource -IsSingleInstance 'Yes' -UseRootHint $true } - Context 'When enforcing just parameter Timeout' { - It "Should call the correct mock with correct parameters" { - Mock -CommandName Set-DnsServerForwarder + Should -Invoke -CommandName Set-DnsServerForwarder -ParameterFilter { + # Only the property UseRootHint should exist in $PSBoundParameters. + -not $PSBoundParameters.ContainsKey('IPAddress') -and $UseRootHint -eq $true + } -Times 1 -Exactly -Scope It + } + } - Set-TargetResource -IsSingleInstance 'Yes' -Timeout 4 + Context 'When enforcing just parameter EnableReordering' { + BeforeAll { + Mock -CommandName Set-DnsServerForwarder + } - Assert-MockCalled -CommandName Set-DnsServerForwarder -ParameterFilter { - # Only the property UseRootHint should exist in $PSBoundParameters. - -not $PSBoundParameters.ContainsKey('IPAddress') -and $Timeout -eq 4 - } -Times 1 -Exactly -Scope It - } + It 'Should call the correct mock with correct parameters' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + Set-TargetResource -IsSingleInstance 'Yes' -EnableReordering $true } + + Should -Invoke -CommandName Set-DnsServerForwarder -ParameterFilter { + # Only the property UseRootHint should exist in $PSBoundParameters. + -not $PSBoundParameters.ContainsKey('IPAddress') -and $EnableReordering -eq $true + } -Times 1 -Exactly -Scope It } - } #end InModuleScope -} -finally -{ - Invoke-TestCleanup + } + + Context 'When enforcing just parameter Timeout' { + BeforeAll { + Mock -CommandName Set-DnsServerForwarder + } + + It 'Should call the correct mock with correct parameters' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + Set-TargetResource -IsSingleInstance 'Yes' -Timeout 4 + } + + Should -Invoke -CommandName Set-DnsServerForwarder -ParameterFilter { + # Only the property UseRootHint should exist in $PSBoundParameters. + -not $PSBoundParameters.ContainsKey('IPAddress') -and $Timeout -eq 4 + } -Times 1 -Exactly -Scope It + } + } } diff --git a/tests/Unit/DSC_DnsServerPrimaryZone.Tests.ps1 b/tests/Unit/DSC_DnsServerPrimaryZone.Tests.ps1 index 82138fdd..2887bf6b 100644 --- a/tests/Unit/DSC_DnsServerPrimaryZone.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerPrimaryZone.Tests.ps1 @@ -1,16 +1,37 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerPrimaryZone' +<# + .SYNOPSIS + Unit test for DSC_DnsServerPrimaryZone DSC resource. +#> -function Invoke-TestSetup -{ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerPrimaryZone' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,27 +40,32 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force + + Remove-Module -Name DnsServer -Force } -Invoke-TestSetup +Describe 'DSC_DnsServerPrimaryZone\Get-TargetResource' -Tag 'Get' { + BeforeAll { + Mock -CommandName Assert-Module -try -{ - InModuleScope $script:dscResourceName { - #region Pester Test Initialization $testZoneName = 'example.com' $testZoneFile = 'example.com.dns' $testDynamicUpdate = 'None' - $testParams = @{ - Name = $testZoneName - Verbose = $true - } - $fakeDnsFileZone = [PSCustomObject] @{ DistinguishedName = $null ZoneName = $testZoneName @@ -49,129 +75,376 @@ try DirectoryPartitionName = $null ZoneFile = $testZoneFile } - #endregion + } - #region Function Get-TargetResource - Describe 'DSC_DnsServerPrimaryZone\Get-TargetResource' { - Mock -CommandName 'Assert-Module' + BeforeEach { + InModuleScope -Parameters @{ + testZoneName = $testZoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:testParams = @{ + Name = $testZoneName + Verbose = $false + } + } + } + + Context 'When DNS zone exists' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } + } + + It 'Should return a "System.Collections.Hashtable" object type' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + Get-TargetResource @testParams | Should -BeOfType [System.Collections.Hashtable] + } + } + + It 'Should return "Present" when "Ensure" = "Present"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParams += @{ + ZoneFile = 'example.com.dns' + Ensure = 'Present' + } - It 'Returns a "System.Collections.Hashtable" object type' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } $targetResource = Get-TargetResource @testParams - $targetResource -is [System.Collections.Hashtable] | Should Be $true + $targetResource.Ensure | Should -Be 'Present' } + } + + It 'Should return "Present" when "Ensure" = "Absent"' { + Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParams += @{ + ZoneFile = 'example.com.dns' + Ensure = 'Absent' + } - It 'Returns "Present" when DNS zone exists and "Ensure" = "Present"' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - $targetResource = Get-TargetResource @testParams -ZoneFile 'example.com.dns' - $targetResource.Ensure | Should Be 'Present' + $targetResource = Get-TargetResource @testParams + $targetResource.Ensure | Should -Be 'Present' } + } + } - It 'Returns "Absent" when DNS zone does not exists and "Ensure" = "Present"' { - Mock -CommandName Get-DnsServerZone -MockWith { } - $targetResource = Get-TargetResource @testParams -ZoneFile 'example.com.dns' - $targetResource.Ensure | Should Be 'Absent' + Context 'When DNS zone does not exist' { + BeforeAll { + Mock -CommandName Get-DnsServerZone + } + + It 'Should return "Absent" when "Ensure" = "Present"' { + + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParams += @{ + ZoneFile = 'example.com.dns' + } + + $targetResource = Get-TargetResource @testParams + $targetResource.Ensure | Should -Be 'Absent' } + } + + It 'Should return "Absent" when "Ensure" = "Absent"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Returns "Present" when DNS zone exists and "Ensure" = "Absent"' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - $targetResource = Get-TargetResource @testParams -ZoneFile 'example.com.dns' -Ensure Absent - $targetResource.Ensure | Should Be 'Present' + $testParams += @{ + ZoneFile = 'example.com.dns' + Ensure = 'Absent' + } + + $targetResource = Get-TargetResource @testParams + $targetResource.Ensure | Should -Be 'Absent' } + } + } +} + +Describe 'DSC_DnsServerPrimaryZone\Test-TargetResource' -Tag 'Test' { + BeforeAll { + Mock -CommandName Assert-Module - It 'Returns "Absent" when DNS zone does not exist and "Ensure" = "Absent"' { - Mock -CommandName Get-DnsServerZone -MockWith { } - $targetResource = Get-TargetResource @testParams -ZoneFile 'example.com.dns' -Ensure Absent - $targetResource.Ensure | Should Be 'Absent' + $testZoneName = 'example.com' + $testZoneFile = 'example.com.dns' + $testDynamicUpdate = 'None' + $fakeDnsFileZone = [PSCustomObject] @{ + DistinguishedName = $null + ZoneName = $testZoneName + ZoneType = 'Primary' + DynamicUpdate = $testDynamicUpdate + ReplicationScope = 'None' + DirectoryPartitionName = $null + ZoneFile = $testZoneFile + } + } + + BeforeEach { + InModuleScope -Parameters @{ + testZoneName = $testZoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $script:testParams = @{ + Name = $testZoneName + Verbose = $false } } - #endregion + } + + Context 'When the DNS zone exists' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } + } + + Context 'When the zone is in the desired state' { + It 'Should return a "System.Boolean" object type' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + Test-TargetResource @testParams | Should -BeOfType [System.Boolean] + } + } + It 'Should be $true when "Ensure" = "Present"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - #region Function Test-TargetResource - Describe 'DSC_DnsServerPrimaryZone\Test-TargetResource' { - Mock -CommandName 'Assert-Module' + $testParams += @{ + Ensure = 'Present' + } - It 'Returns a "System.Boolean" object type' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - $targetResource = Test-TargetResource @testParams - $targetResource -is [System.Boolean] | Should Be $true + Test-TargetResource @testParams | Should -BeTrue + } } - It 'Passes when DNS zone exists and "Ensure" = "Present"' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - Test-TargetResource @testParams -Ensure Present | Should Be $true + It 'Should be $true "DynamicUpdate" is correct' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParams += @{ + Ensure = 'Present' + DynamicUpdate = 'None' + } + + Test-TargetResource @testParams | Should -BeTrue + } } + } + + Context 'When the zone is not in the desired state' { + It 'Should be $false "Ensure" = "Absent"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Passes when DNS zone does not exist and "Ensure" = "Absent"' { - Mock -CommandName Get-DnsServerZone -MockWith { } - Test-TargetResource @testParams -Ensure Absent | Should Be $true + $testParams += @{ + Ensure = 'Absent' + } + + Test-TargetResource @testParams | Should -BeFalse + } } - It 'Passes when DNS zone "DynamicUpdate" is correct' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - Test-TargetResource @testParams -Ensure Present -DynamicUpdate $testDynamicUpdate | Should Be $true + It 'Should be $false when "DynamicUpdate" is incorrect' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParams += @{ + ZoneFile = 'example.com.dns' + Ensure = 'Present' + DynamicUpdate = 'NonSecureAndSecure' + } + + Test-TargetResource @testParams | Should -BeFalse + } } - It 'Fails when DNS zone exists and "Ensure" = "Absent"' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - Test-TargetResource @testParams -Ensure Absent | Should Be $false + It 'Should be $false when "ZoneFile" is incorrect' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParams += @{ + ZoneFile = 'nonexistent.com.dns' + Ensure = 'Present' + DynamicUpdate = 'None' + } + + Test-TargetResource @testParams | Should -BeFalse + } } + } + } - It 'Fails when DNS zone does not exist and "Ensure" = "Present"' { - Mock -CommandName Get-DnsServerZone -MockWith { } - Test-TargetResource @testParams -Ensure Present | Should Be $false + Context 'When the DNS zone does not exist' { + BeforeAll { + Mock -CommandName Get-DnsServerZone + } + + Context 'When the zone is in the desired state' { + It 'Should be $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParams += @{ + Ensure = 'Absent' + } + + Test-TargetResource @testParams | Should -BeTrue + } } + } - It 'Fails when DNS zone "DynamicUpdate" is incorrect' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - Test-TargetResource @testParams -Ensure Present -DynamicUpdate 'NonSecureAndSecure' -ZoneFile $testZoneFile | Should Be $false + Context 'When the zone is not in the desired state' { + It 'Should be $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParams += @{ + Ensure = 'Present' + } + + Test-TargetResource @testParams | Should -BeFalse + } } + } + } +} + +Describe 'DSC_DnsServerPrimaryZone\Set-TargetResource' -Tag 'Set' { + BeforeAll { + Mock -CommandName 'Assert-Module' + + $testZoneName = 'example.com' + $testZoneFile = 'example.com.dns' + $testDynamicUpdate = 'None' + $fakeDnsFileZone = [PSCustomObject] @{ + DistinguishedName = $null + ZoneName = $testZoneName + ZoneType = 'Primary' + DynamicUpdate = $testDynamicUpdate + ReplicationScope = 'None' + DirectoryPartitionName = $null + ZoneFile = $testZoneFile + } + } + + BeforeEach { + InModuleScope -Parameters @{ + testZoneName = $testZoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Fails when DNS zone "ZoneFile" is incorrect' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - Test-TargetResource @testParams -Ensure Present -DynamicUpdate $testDynamicUpdate -ZoneFile 'nonexistent.com.dns' | Should Be $false + $script:testParams = @{ + Name = $testZoneName + Verbose = $false } } - #endregion + } + + Context 'When the DNS zone does not exist' { + BeforeAll { + Mock -CommandName Get-DnsServerZone + Mock -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } + } + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - #region Function Set-TargetResource - Describe 'DSC_DnsServerPrimaryZone\Set-TargetResource' { - Mock -CommandName 'Assert-Module' + $testParams += @{ + Ensure = 'Present' + DynamicUpdate = 'None' + ZoneFile = 'example.com.dns' + } - It 'Calls "Add-DnsServerPrimaryZone" when DNS zone does not exist and "Ensure" = "Present"' { - Mock -CommandName Get-DnsServerZone -MockWith { } - Mock -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } -MockWith { } - Set-TargetResource @testParams -Ensure Present -DynamicUpdate $testDynamicUpdate -ZoneFile $testZoneFile - Assert-MockCalled -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } -Scope It + Set-TargetResource @testParams } - It 'Calls "Remove-DnsServerZone" when DNS zone does exist and "Ensure" = "Absent"' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - Mock -CommandName Remove-DnsServerZone -MockWith { } - Set-TargetResource @testParams -Ensure Absent -DynamicUpdate $testDynamicUpdate -ZoneFile $testZoneFile - Assert-MockCalled -CommandName Remove-DnsServerZone -Scope It + Should -Invoke -CommandName Add-DnsServerPrimaryZone -ParameterFilter { $Name -eq $testZoneName } -Scope It -Times 1 -Exactly + should -Invoke -CommandName Get-DnsServerZone -Scope It -Times 1 -Exactly + } + } + + Context 'When the DNS zone does exist' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } + Mock -CommandName Remove-DnsServerZone + } + + Context 'When the zone needs creating' { + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParams += @{ + Ensure = 'Absent' + DynamicUpdate = 'None' + ZoneFile = 'example.com.dns' + } + + Set-TargetResource @testParams + } + + Should -Invoke -CommandName Remove-DnsServerZone -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Get-DnsServerZone -Scope It -Times 1 -Exactly } + } + + Context 'When the zone needs updating' { + Context 'when DNS zone "DynamicUpdate" is incorrect' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } + Mock -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DynamicUpdate -eq 'NonSecureAndSecure' } + } + + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Calls "Set-DnsServerPrimaryZone" when DNS zone "DynamicUpdate" is incorrect' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - Mock -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DynamicUpdate -eq 'NonSecureAndSecure' } -MockWith { } - Set-TargetResource @testParams -Ensure Present -DynamicUpdate 'NonSecureAndSecure' -ZoneFile $testZoneFile - Assert-MockCalled -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DynamicUpdate -eq 'NonSecureAndSecure' } -Scope It + $testParams += @{ + Ensure = 'Present' + DynamicUpdate = 'NonSecureAndSecure' + ZoneFile = 'example.com.dns' + } + + Set-TargetResource @testParams + } + + Should -Invoke -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $DynamicUpdate -eq 'NonSecureAndSecure' } -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Get-DnsServerZone -Scope It -Times 1 -Exactly + } } - It 'Calls "Set-DnsServerPrimaryZone" when DNS zone "ZoneFile" is incorrect' { - Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } - Mock -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $ZoneFile -eq 'nonexistent.com.dns' } -MockWith { } - Set-TargetResource @testParams -Ensure Present -DynamicUpdate $testDynamicUpdate -ZoneFile 'nonexistent.com.dns' - Assert-MockCalled -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $ZoneFile -eq 'nonexistent.com.dns' } -Scope It + Context 'When DNS zone "ZoneFile" is incorrect' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { return $fakeDnsFileZone } + Mock -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $ZoneFile -eq 'nonexistent.com.dns' } + } + + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParams += @{ + Ensure = 'Present' + DynamicUpdate = 'None' + ZoneFile = 'nonexistent.com.dns' + } + + Set-TargetResource @testParams + } + + Should -Invoke -CommandName Set-DnsServerPrimaryZone -ParameterFilter { $ZoneFile -eq 'nonexistent.com.dns' } -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Get-DnsServerZone -Scope It -Times 1 -Exactly + } } } - #endregion - } #end InModuleScope -} -finally -{ - Invoke-TestCleanup + } } diff --git a/tests/Unit/DSC_DnsServerRootHint.Tests.ps1 b/tests/Unit/DSC_DnsServerRootHint.Tests.ps1 index 5f8c50d4..d4454ad3 100644 --- a/tests/Unit/DSC_DnsServerRootHint.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerRootHint.Tests.ps1 @@ -1,16 +1,37 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerRootHint' +<# + .SYNOPSIS + Unit test for DSC_DnsServerRootHint DSC resource. +#> -function Invoke-TestSetup -{ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerRootHint' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,19 +40,29 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force + + Remove-Module -Name DnsServer -Force } -Invoke-TestSetup +Describe 'DSC_DnsServerRootHint\Get-TargetResource' { + BeforeAll { + Mock -CommandName Assert-Module -try -{ - InModuleScope $script:dscResourceName { - #region Pester Test Initialization $rootHints = @( [PSCustomObject] @{ NameServer = @{ @@ -45,7 +76,6 @@ try IPAddressToString = [IPAddress] '199.9.14.201' } } - } }, [PSCustomObject] @{ @@ -60,75 +90,250 @@ try IPAddressToString = [IPAddress] '202.12.27.33' } } - } } ) $rootHintsHashtable = Convert-RootHintsToHashtable -RootHints $rootHints $rootHintsCim = ConvertTo-CimInstance -Hashtable $rootHintsHashtable - #endregion + } - #region Function Get-TargetResource - Describe 'DSC_DnsServerRootHint\Get-TargetResource' { - Mock -CommandName Assert-Module + Context 'When command completes' { + BeforeAll { + Mock -CommandName Get-DnsServerRootHint -MockWith { return $rootHints } + } + + It 'Should return a "System.Collections.Hashtable" object type' { + InModuleScope -Parameters @{ + rootHintsCim = $rootHintsCim + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + IsSingleInstance = 'Yes' + NameServer = $rootHintsCim + Verbose = $false + } - It 'Returns a "System.Collections.Hashtable" object type' { - Mock -CommandName Get-DnsServerRootHint -MockWith { return $rootHints } - $targetResource = Get-TargetResource -IsSingleInstance Yes -NameServer $rootHintsCim -Verbose - $targetResource -is [System.Collections.Hashtable] | Should Be $true + Get-TargetResource @params | Should -BeOfType [System.Collections.Hashtable] } + } + } + + Context 'When root hints exist' { + BeforeAll { + Mock -CommandName Get-DnsServerRootHint -MockWith { return $rootHints } + } - It "Returns NameServer = when root hints exist" { - Mock -CommandName Get-DnsServerRootHint -MockWith { return $rootHints } - $targetResource = Get-TargetResource -IsSingleInstance Yes -NameServer $rootHintsCim -Verbose - Test-DscDnsParameterState -CurrentValues $targetResource.NameServer -DesiredValues $rootHintsHashtable | Should -Be $true + It 'Should return NameServer = PredefinedValue' { + InModuleScope -Parameters @{ + rootHintsCim = $rootHintsCim + rootHintsHashtable = $rootHintsHashtable + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + IsSingleInstance = 'Yes' + NameServer = $rootHintsCim + Verbose = $false + } + + $targetResource = Get-TargetResource @params + Test-DscDnsParameterState -CurrentValues $targetResource.NameServer -DesiredValues $rootHintsHashtable | Should -BeTrue } + } + } + + Context 'when root hints do not exist' { + BeforeAll { + Mock -CommandName Get-DnsServerRootHint -MockWith { return @() } + } + + It 'Should return an empty NameServer' { + InModuleScope -Parameters @{ + rootHintsCim = $rootHintsCim + } -ScriptBlock { + Set-StrictMode -Version 1.0 - It "Returns an empty NameServer when root hints don't exist" { - Mock -CommandName Get-DnsServerRootHint -MockWith { return @() } - $targetResource = Get-TargetResource -IsSingleInstance Yes -NameServer $rootHintsCim -Verbose - $targetResource.NameServer.Count | Should Be 0 + $params = @{ + IsSingleInstance = 'Yes' + NameServer = $rootHintsCim + Verbose = $false + } + + $targetResource = Get-TargetResource @params + $targetResource.NameServer.Count | Should -Be 0 } } - #endregion + } +} - #region Function Test-TargetResource - Describe 'DSC_DnsServerRootHint\Test-TargetResource' { - Mock -CommandName Assert-Module +Describe 'DSC_DnsServerRootHint\Test-TargetResource' { + BeforeAll { + Mock -CommandName Assert-Module - It 'Returns a "System.Boolean" object type' { - Mock -CommandName Get-DnsServerRootHint -MockWith { return $rootHints } - $targetResource = Test-TargetResource -IsSingleInstance Yes -NameServer $rootHintsCim -Verbose - $targetResource -is [System.Boolean] | Should Be $true + $rootHints = @( + [PSCustomObject] @{ + NameServer = @{ + RecordData = @{ + NameServer = 'B.ROOT-SERVERS.NET.' + } + } + IPAddress = @{ + RecordData = @{ + IPv4Address = @{ + IPAddressToString = [IPAddress] '199.9.14.201' + } + } + } + }, + [PSCustomObject] @{ + NameServer = @{ + RecordData = @{ + NameServer = 'M.ROOT-SERVERS.NET.' + } + } + IPAddress = @{ + RecordData = @{ + IPv4Address = @{ + IPAddressToString = [IPAddress] '202.12.27.33' + } + } + } } + ) - It 'Passes when forwarders match' { - Mock -CommandName Get-DnsServerRootHint -MockWith { return $rootHints } - Test-TargetResource -IsSingleInstance Yes -NameServer $rootHintsCim -Verbose | Should Be $true + $rootHintsHashtable = Convert-RootHintsToHashtable -RootHints $rootHints + $rootHintsCim = ConvertTo-CimInstance -Hashtable $rootHintsHashtable + } + + Context 'When command completes' { + BeforeAll { + Mock -CommandName Get-DnsServerRootHint -MockWith { return $rootHints } + } + + It 'Should return a "System.Boolean" object type' { + InModuleScope -Parameters @{ + rootHintsCim = $rootHintsCim + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + IsSingleInstance = 'Yes' + NameServer = $rootHintsCim + Verbose = $false + } + + Test-TargetResource @params | Should -BeOfType [System.Boolean] + } + } + } + + Context 'When forwarders match' { + BeforeAll { + Mock -CommandName Get-DnsServerRootHint -MockWith { return $rootHints } + } + + It 'Should be $true' { + InModuleScope -Parameters @{ + rootHintsCim = $rootHintsCim + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + IsSingleInstance = 'Yes' + NameServer = $rootHintsCim + Verbose = $false + } + + Test-TargetResource @params | Should -BeTrue } + } + } - It "Fails when root hints don't match" { - Mock -CommandName Get-DnsServerRootHint -MockWith { return @{ NameServer = @() } } - Test-TargetResource -IsSingleInstance Yes -NameServer $rootHintsCim -Verbose | Should Be $false + Context 'When root hints do not match' { + BeforeAll { + Mock -CommandName Get-DnsServerRootHint -MockWith { + return @{ + NameServer = @() + } } } - #endregion + It 'Should be $false' { + InModuleScope -Parameters @{ + rootHintsCim = $rootHintsCim + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + IsSingleInstance = 'Yes' + NameServer = $rootHintsCim + Verbose = $false + } - #region Function Set-TargetResource - Describe 'DSC_DnsServerRootHint\Set-TargetResource' { - It "Calls Add-DnsServerRootHint 2 times" { - Mock -CommandName Remove-DnsServerRootHint -MockWith { } - Mock -CommandName Add-DnsServerRootHint -MockWith { } - Mock -CommandName Get-DnsServerRootHint -MockWith { } - Set-TargetResource -IsSingleInstance Yes -NameServer $rootHintsCim -Verbose - Assert-MockCalled -CommandName Add-DnsServerRootHint -Times 2 -Exactly -Scope It + Test-TargetResource @params | Should -BeFalse } } - } #end InModuleScope + } } -finally -{ - Invoke-TestCleanup + +Describe 'DSC_DnsServerRootHint\Set-TargetResource' { + BeforeAll { + Mock -CommandName Remove-DnsServerRootHint -MockWith { } + Mock -CommandName Add-DnsServerRootHint -MockWith { } + Mock -CommandName Get-DnsServerRootHint -MockWith { } + + $rootHints = @( + [PSCustomObject] @{ + NameServer = @{ + RecordData = @{ + NameServer = 'B.ROOT-SERVERS.NET.' + } + } + IPAddress = @{ + RecordData = @{ + IPv4Address = @{ + IPAddressToString = [IPAddress] '199.9.14.201' + } + } + } + }, + [PSCustomObject] @{ + NameServer = @{ + RecordData = @{ + NameServer = 'M.ROOT-SERVERS.NET.' + } + } + IPAddress = @{ + RecordData = @{ + IPv4Address = @{ + IPAddressToString = [IPAddress] '202.12.27.33' + } + } + } + } + ) + + $rootHintsHashtable = Convert-RootHintsToHashtable -RootHints $rootHints + $rootHintsCim = ConvertTo-CimInstance -Hashtable $rootHintsHashtable + } + + It 'Should call Add-DnsServerRootHint 2 times' { + InModuleScope -Parameters @{ + rootHintsCim = $rootHintsCim + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + IsSingleInstance = 'Yes' + NameServer = $rootHintsCim + Verbose = $false + } + + Set-TargetResource @params + } + + Should -Invoke -CommandName Add-DnsServerRootHint -Times 2 -Exactly -Scope It + } } diff --git a/tests/Unit/DSC_DnsServerSecondaryZone.Tests.ps1 b/tests/Unit/DSC_DnsServerSecondaryZone.Tests.ps1 new file mode 100644 index 00000000..078d80e6 --- /dev/null +++ b/tests/Unit/DSC_DnsServerSecondaryZone.Tests.ps1 @@ -0,0 +1,502 @@ +<# + .SYNOPSIS + Unit test for DSC_DnsServerSecondaryZone DSC resource. +#> + +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerSecondaryZone' + + $script:testEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:dscModuleName ` + -DSCResourceName $script:dscResourceName ` + -ResourceType 'Mof' ` + -TestType 'Unit' + + Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + Restore-TestEnvironment -TestEnvironment $script:testEnvironment + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force + + Remove-Module -Name DnsServer -Force +} + +Describe 'DSC_DnsServerSecondaryZone\Get-TargetResource' -Tag 'Get' { + BeforeAll { + Mock -CommandName Assert-Module + } + + Context 'When the secondary zone exists' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { + return @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + ZoneType = 'Secondary' + } + } + } + + It 'Should return "Present"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Verbose = $false + } + + $targetResource = Get-TargetResource @params + $targetResource.Ensure | Should -Be 'Present' + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + Should -Invoke -CommandName Assert-Module -Times 1 -Exactly + } + } + + Context 'When the secondary zone does not exist' { + BeforeAll { + Mock -CommandName Get-DnsServerZone + } + + It 'Should return "Absent"' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Verbose = $false + } + + $targetResource = Get-TargetResource @params + $targetResource.Ensure | Should -Be 'Absent' + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + Should -Invoke -CommandName Assert-Module -Times 1 -Exactly + } + } +} + +Describe 'DSC_DnsServerSecondaryZone\Set-TargetResource' -Tag 'Set' { + Context 'When the script runs' { + BeforeAll { + Mock -CommandName Test-ResourceProperties + Mock -CommandName Restart-Service + } + + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Debug = $true + Verbose = $false + } + + Set-TargetResource @params + } + + Should -Invoke -CommandName Test-ResourceProperties -Times 1 -Exactly + Should -Invoke -CommandName Restart-Service -Times 1 -Exactly + + } + } +} + +Describe 'DSC_DnsServerSecondaryZone\Test-TargetResource' -Tag 'Test' { + BeforeAll { + Mock -CommandName Assert-Module + } + + Context 'When the system is in the desired state' { + BeforeAll { + Mock -CommandName Test-ResourceProperties -MockWith { return $true } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Debug = $true + Verbose = $false + } + + Test-TargetResource @params | Should -BeTrue + } + + Should -Invoke -CommandName Test-ResourceProperties -Times 1 -Exactly + Should -Invoke -CommandName Assert-Module -Times 1 -Exactly + } + } + + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Test-ResourceProperties -MockWith { return $false } + } + + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Verbose = $false + } + + Test-TargetResource @params | Should -BeFalse + } + + Should -Invoke -CommandName Test-ResourceProperties -Times 1 -Exactly + Should -Invoke -CommandName Assert-Module -Times 1 -Exactly + } + } +} + +Describe 'DSC_DnsServerSecondaryZone\Test-ResourceProperties' -Tag 'Private' { + Context 'When a zone exists' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { + return @{ + Name = 'example.com' + MasterServers = @( + [System.Net.IPAddress]'192.168.0.2' + [System.Net.IPAddress]'192.168.0.3' + ) + ZoneType = 'Secondary' + } + } + } + + Context 'When Ensure = Present' { + Context 'When the zone is a secondary zone' { + Context 'When MasterServers does not match' { + Context 'When Apply = $true' { + BeforeAll { + Mock -CommandName Set-DnsServerSecondaryZone + } + + It 'Should be $false and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.4' + Ensure = 'Present' + Apply = $true + Verbose = $false + } + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + Should -Invoke -CommandName Set-DnsServerSecondaryZone -Times 1 -Exactly + } + } + + Context 'When Apply = $true' { + It 'Should be $false and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.4' + Ensure = 'Present' + Apply = $false + Verbose = $false + } + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + } + } + } + + Context 'When MasterServers do match' { + Context 'When Apply = $false' { + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Ensure = 'Present' + Apply = $false + Verbose = $false + } + Test-ResourceProperties @params | Should -BeTrue + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + } + } + + Context 'When Apply = $true' { + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Ensure = 'Present' + Apply = $true + Verbose = $false + } + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + } + } + } + } + + Context 'When the zone is not a secondary zone' { + BeforeAll { + Mock -CommandName Get-DnsServerZone -MockWith { + return @{ + Name = 'example.com' + MasterServers = @( + [System.Net.IPAddress]'192.168.0.2' + [System.Net.IPAddress]'192.168.0.3' + ) + ZoneType = 'Primary' + } + } + } + + Context 'When Apply = $true' { + BeforeAll { + Mock -CommandName ConvertTo-DnsServerSecondaryZone + } + + It 'Should be $false transfer and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Ensure = 'Present' + Apply = $true + Verbose = $false + } + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + Should -Invoke -CommandName ConvertTo-DnsServerSecondaryZone -Times 1 -Exactly + } + } + + Context 'When Apply = $false' { + It 'Should be $false and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Ensure = 'Present' + Apply = $false + Verbose = $false + } + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + } + } + } + } + + Context 'When Ensure = Absent' { + Context 'When Apply = $true' { + BeforeAll { + Mock -CommandName Remove-DnsServerZone + } + + It 'Should return $false and remove the zone' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Ensure = 'Absent' + Apply = $true + Verbose = $false + } + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + Should -Invoke -CommandName Remove-DnsServerZone -Times 1 -Exactly + } + } + + Context 'When Apply = $false' { + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Ensure = 'Absent' + Apply = $false + Verbose = $false + } + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + } + } + } + } + + Context 'When the secondary zone does not exist' { + BeforeAll { + Mock -CommandName Get-DnsServerZone + } + + Context 'When Ensure = Present' { + Context 'When Apply = $true' { + BeforeAll { + Mock -CommandName Add-DnsServerSecondaryZone + Mock -CommandName Start-DnsServerZoneTransfer + } + + It 'Should be $false add the zone and transfer' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Ensure = 'Present' + Apply = $true + Verbose = $false + } + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + Should -Invoke -CommandName Add-DnsServerSecondaryZone -Times 1 -Exactly + Should -Invoke -CommandName Start-DnsServerZoneTransfer -Times 1 -Exactly + } + } + + Context 'When Apply = $false' { + It 'Should be $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Apply = $false + Ensure = 'Present' + Verbose = $false + } + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + } + } + } + + Context 'When Ensure = Absent' { + Context 'When Apply is $false' { + It 'Should return $true' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Ensure = 'Absent' + Verbose = $false + } + Test-ResourceProperties @params | Should -BeTrue + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + } + } + + Context 'When Apply is $true' { + It 'Should return $false' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + MasterServers = '192.168.0.2', '192.168.0.3' + Apply = $true + Ensure = 'Absent' + Verbose = $false + } + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-DnsServerZone -Times 1 -Exactly + } + } + } + } +} diff --git a/tests/Unit/DSC_DnsServerSetting.Tests.ps1 b/tests/Unit/DSC_DnsServerSetting.Tests.ps1 index f64b8f2d..6037ccb2 100644 --- a/tests/Unit/DSC_DnsServerSetting.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerSetting.Tests.ps1 @@ -1,16 +1,37 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerSetting' +<# + .SYNOPSIS + Unit test for DSC_DnsServerSetting DSC resource. +#> -function Invoke-TestSetup -{ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerSetting' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,1631 +40,1672 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} -Invoke-TestSetup + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force -try -{ - InModuleScope $script:dscResourceName { - Describe 'DSC_DnsServerSetting\Get-TargetResource' -Tag 'Get' { - BeforeAll { - Mock -CommandName Assert-Module - Mock -CommandName Get-DnsServerSetting -MockWith { - return @{ - DnsServer = 'dns1.company.local' - LocalNetPriority = $false - RoundRobin = $false - RpcProtocol = 1 - NameCheckFlag = 2 - AutoConfigFileZones = 1 - AddressAnswerLimit = 0 - UpdateOptions = 783 - DisableAutoReverseZone = $false - StrictFileParsing = $false - EnableDirectoryPartitions = $false - XfrConnectTimeout = 30 - BootMethod = 3 - AllowUpdate = $true - LooseWildcarding = $false - BindSecondaries = $false - AutoCacheUpdate = $false - EnableDnsSec = $true - SendPort = 0 - WriteAuthorityNS = $false - ListeningIPAddress = @('192.168.1.10', '192.168.2.10') - ForwardDelegations = $false - EnableIPv6 = $true - EnableOnlineSigning = $true - EnableDuplicateQuerySuppression = $true - AllowCnameAtNs = $true - EnableRsoForRodc = $true - OpenAclOnProxyUpdates = $true - NoUpdateDelegations = $false - EnableUpdateForwarding = $false - EnableWinsR = $true - DeleteOutsideGlue = $false - AppendMsZoneTransferTag = $false - AllowReadOnlyZoneTransfer = $false - EnableSendErrorSuppression = $true - SilentlyIgnoreCnameUpdateConflicts = $false - EnableIQueryResponseGeneration = $false - AdminConfigured = $true - PublishAutoNet = $false - ReloadException = $false - IgnoreServerLevelPolicies = $false - IgnoreAllPolicies = $false - EnableVersionQuery = 0 - AutoCreateDelegation = 2 - RemoteIPv4RankBoost = 5 - RemoteIPv6RankBoost = 0 - MaximumRodcRsoQueueLength = 300 - MaximumRodcRsoAttemptsPerCycle = 100 - MaxResourceRecordsInNonSecureUpdate = 30 - LocalNetPriorityMask = 255 - TcpReceivePacketSize = 65536 - SelfTest = 4294967295 - XfrThrottleMultiplier = 10 - SocketPoolSize = 2500 - QuietRecvFaultInterval = 0 - QuietRecvLogInterval = 0 - SyncDsZoneSerial = 2 - ScopeOptionValue = 0 - VirtualizationInstanceOptionValue = 0 - ServerLevelPluginDll = 'C:\dns\plugin.dll' - RootTrustAnchorsURL = 'https://data.iana.org/root-anchors/root-anchors.xml' - SocketPoolExcludedPortRanges = @(5353, 5454) - LameDelegationTTL = New-TimeSpan -Seconds 0 - MaximumSignatureScanPeriod = New-TimeSpan -Days 2 - MaximumTrustAnchorActiveRefreshInterval = New-TimeSpan -Days 15 - ZoneWritebackInterval = New-TimeSpan -Minutes 1 + Remove-Module -Name DnsServer -Force +} - # Read-only properties - DsAvailable = $true - MajorVersion = 10 - MinorVersion = 0 - BuildNumber = 14393 - IsReadOnlyDC = $false - AllIPAddress = @('fe80::e82e:70b7:f1d4:f695', '192.168.1.10', '192.168.2.10') - ForestDirectoryPartitionBaseName = 'ForestDnsZones' - DomainDirectoryPartitionBaseName = 'DomainDnsZones' - MaximumUdpPacketSize = 4000 - } - } +Describe 'DSC_DnsServerSetting\Get-TargetResource' -Tag 'Get' { + BeforeAll { + Mock -CommandName Assert-Module + Mock -CommandName Get-DnsServerSetting -MockWith { + return @{ + DnsServer = 'dns1.company.local' + LocalNetPriority = $false + RoundRobin = $false + RpcProtocol = 1 + NameCheckFlag = 2 + AutoConfigFileZones = 1 + AddressAnswerLimit = 0 + UpdateOptions = 783 + DisableAutoReverseZone = $false + StrictFileParsing = $false + EnableDirectoryPartitions = $false + XfrConnectTimeout = 30 + BootMethod = 3 + AllowUpdate = $true + LooseWildcarding = $false + BindSecondaries = $false + AutoCacheUpdate = $false + EnableDnsSec = $true + SendPort = 0 + WriteAuthorityNS = $false + ListeningIPAddress = @('192.168.1.10', '192.168.2.10') + ForwardDelegations = $false + EnableIPv6 = $true + EnableOnlineSigning = $true + EnableDuplicateQuerySuppression = $true + AllowCnameAtNs = $true + EnableRsoForRodc = $true + OpenAclOnProxyUpdates = $true + NoUpdateDelegations = $false + EnableUpdateForwarding = $false + EnableWinsR = $true + DeleteOutsideGlue = $false + AppendMsZoneTransferTag = $false + AllowReadOnlyZoneTransfer = $false + EnableSendErrorSuppression = $true + SilentlyIgnoreCnameUpdateConflicts = $false + EnableIQueryResponseGeneration = $false + AdminConfigured = $true + PublishAutoNet = $false + ReloadException = $false + IgnoreServerLevelPolicies = $false + IgnoreAllPolicies = $false + EnableVersionQuery = 0 + AutoCreateDelegation = 2 + RemoteIPv4RankBoost = 5 + RemoteIPv6RankBoost = 0 + MaximumRodcRsoQueueLength = 300 + MaximumRodcRsoAttemptsPerCycle = 100 + MaxResourceRecordsInNonSecureUpdate = 30 + LocalNetPriorityMask = 255 + TcpReceivePacketSize = 65536 + SelfTest = 4294967295 + XfrThrottleMultiplier = 10 + SocketPoolSize = 2500 + QuietRecvFaultInterval = 0 + QuietRecvLogInterval = 0 + SyncDsZoneSerial = 2 + ScopeOptionValue = 0 + VirtualizationInstanceOptionValue = 0 + ServerLevelPluginDll = 'C:\dns\plugin.dll' + RootTrustAnchorsURL = 'https://data.iana.org/root-anchors/root-anchors.xml' + SocketPoolExcludedPortRanges = @(5353, 5454) + LameDelegationTTL = New-TimeSpan -Seconds 0 + MaximumSignatureScanPeriod = New-TimeSpan -Days 2 + MaximumTrustAnchorActiveRefreshInterval = New-TimeSpan -Days 15 + ZoneWritebackInterval = New-TimeSpan -Minutes 1 + + # Read-only properties + DsAvailable = $true + MajorVersion = 10 + MinorVersion = 0 + BuildNumber = 14393 + IsReadOnlyDC = $false + AllIPAddress = @('fe80::e82e:70b7:f1d4:f695', '192.168.1.10', '192.168.2.10') + ForestDirectoryPartitionBaseName = 'ForestDnsZones' + DomainDirectoryPartitionBaseName = 'DomainDnsZones' + MaximumUdpPacketSize = 4000 } + } + } - Context 'When the system is in the desired state' { - It "Should return the correct values for each property" { - $getTargetResourceResult = Get-TargetResource -DnsServer 'dns1.company.local' + Context 'When the system is in the desired state' { + It 'Should return the correct values for each property' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - $getTargetResourceResult.LocalNetPriority | Should -BeFalse - $getTargetResourceResult.RoundRobin | Should -BeFalse - $getTargetResourceResult.RpcProtocol | Should -Be 1 + $getTargetResourceResult = Get-TargetResource -DnsServer 'dns1.company.local' - # Read-only properties - $getTargetResourceResult.DsAvailable | Should -BeTrue - $getTargetResourceResult.MajorVersion | Should -Be 10 - $getTargetResourceResult.MinorVersion | Should -Be 0 - $getTargetResourceResult.BuildNumber | Should -Be 14393 - $getTargetResourceResult.IsReadOnlyDC | Should -BeFalse - $getTargetResourceResult.ForestDirectoryPartitionBaseName | Should -Be 'ForestDnsZones' - $getTargetResourceResult.DomainDirectoryPartitionBaseName | Should -Be 'DomainDnsZones' - $getTargetResourceResult.MaximumUdpPacketSize | Should -Be 4000 - $getTargetResourceResult.NameCheckFlag | Should -Be 2 - $getTargetResourceResult.AutoConfigFileZones | Should -Be 1 - $getTargetResourceResult.AddressAnswerLimit | Should -Be 0 - $getTargetResourceResult.UpdateOptions | Should -Be 783 - $getTargetResourceResult.DisableAutoReverseZone | Should -BeFalse - $getTargetResourceResult.StrictFileParsing | Should -BeFalse - $getTargetResourceResult.EnableDirectoryPartitions | Should -BeFalse - $getTargetResourceResult.XfrConnectTimeout | Should -Be 30 - $getTargetResourceResult.BootMethod | Should -Be 3 - $getTargetResourceResult.AllowUpdate | Should -BeTrue - $getTargetResourceResult.LooseWildcarding | Should -BeFalse - $getTargetResourceResult.BindSecondaries | Should -BeFalse - $getTargetResourceResult.AutoCacheUpdate | Should -BeFalse - $getTargetResourceResult.EnableDnsSec | Should -BeTrue - $getTargetResourceResult.SendPort | Should -Be 0 - $getTargetResourceResult.WriteAuthorityNS | Should -BeFalse - $getTargetResourceResult.ForwardDelegations | Should -BeFalse - $getTargetResourceResult.EnableIPv6 | Should -BeTrue - $getTargetResourceResult.EnableOnlineSigning | Should -BeTrue - $getTargetResourceResult.EnableDuplicateQuerySuppression | Should -BeTrue - $getTargetResourceResult.AllowCnameAtNs | Should -BeTrue - $getTargetResourceResult.EnableRsoForRodc | Should -BeTrue - $getTargetResourceResult.OpenAclOnProxyUpdates | Should -BeTrue - $getTargetResourceResult.NoUpdateDelegations | Should -BeFalse - $getTargetResourceResult.EnableUpdateForwarding | Should -BeFalse - $getTargetResourceResult.EnableWinsR | Should -BeTrue - $getTargetResourceResult.DeleteOutsideGlue | Should -BeFalse - $getTargetResourceResult.AppendMsZoneTransferTag | Should -BeFalse - $getTargetResourceResult.AllowReadOnlyZoneTransfer | Should -BeFalse - $getTargetResourceResult.EnableSendErrorSuppression | Should -BeTrue - $getTargetResourceResult.SilentlyIgnoreCnameUpdateConflicts | Should -BeFalse - $getTargetResourceResult.EnableIQueryResponseGeneration | Should -BeFalse - $getTargetResourceResult.AdminConfigured | Should -BeTrue - $getTargetResourceResult.PublishAutoNet | Should -BeFalse - $getTargetResourceResult.ReloadException | Should -BeFalse - $getTargetResourceResult.IgnoreServerLevelPolicies | Should -BeFalse - $getTargetResourceResult.IgnoreAllPolicies | Should -BeFalse - $getTargetResourceResult.EnableVersionQuery | Should -Be 0 - $getTargetResourceResult.AutoCreateDelegation | Should -Be 2 - $getTargetResourceResult.RemoteIPv4RankBoost | Should -Be 5 - $getTargetResourceResult.RemoteIPv6RankBoost | Should -Be 0 - $getTargetResourceResult.MaximumRodcRsoQueueLength | Should -Be 300 - $getTargetResourceResult.MaximumRodcRsoAttemptsPerCycle | Should -Be 100 - $getTargetResourceResult.MaxResourceRecordsInNonSecureUpdate | Should -Be 30 - $getTargetResourceResult.LocalNetPriorityMask | Should -Be 255 - $getTargetResourceResult.TcpReceivePacketSize | Should -Be 65536 - $getTargetResourceResult.SelfTest | Should -Be 4294967295 - $getTargetResourceResult.XfrThrottleMultiplier | Should -Be 10 - $getTargetResourceResult.SocketPoolSize | Should -Be 2500 - $getTargetResourceResult.QuietRecvFaultInterval | Should -Be 0 - $getTargetResourceResult.QuietRecvLogInterval | Should -Be 0 - $getTargetResourceResult.SyncDsZoneSerial | Should -Be 2 - $getTargetResourceResult.ScopeOptionValue | Should -Be 0 - $getTargetResourceResult.VirtualizationInstanceOptionValue | Should -Be 0 - $getTargetResourceResult.ServerLevelPluginDll | Should -Be 'C:\dns\plugin.dll' - $getTargetResourceResult.RootTrustAnchorsURL | Should -Be 'https://data.iana.org/root-anchors/root-anchors.xml' - $getTargetResourceResult.LameDelegationTTL | Should -Be '00:00:00' - $getTargetResourceResult.MaximumSignatureScanPeriod | Should -Be '2.00:00:00' - $getTargetResourceResult.MaximumTrustAnchorActiveRefreshInterval | Should -Be '15.00:00:00' - $getTargetResourceResult.ZoneWritebackInterval | Should -Be '00:01:00' + $getTargetResourceResult.LocalNetPriority | Should -BeFalse + $getTargetResourceResult.RoundRobin | Should -BeFalse + $getTargetResourceResult.RpcProtocol | Should -Be 1 - $getTargetResourceResult.ListeningIPAddress | Should -HaveCount 2 - $getTargetResourceResult.ListeningIPAddress | Should -Contain '192.168.1.10' - $getTargetResourceResult.ListeningIPAddress | Should -Contain '192.168.2.10' + # Read-only properties + $getTargetResourceResult.DsAvailable | Should -BeTrue + $getTargetResourceResult.MajorVersion | Should -Be 10 + $getTargetResourceResult.MinorVersion | Should -Be 0 + $getTargetResourceResult.BuildNumber | Should -Be 14393 + $getTargetResourceResult.IsReadOnlyDC | Should -BeFalse + $getTargetResourceResult.ForestDirectoryPartitionBaseName | Should -Be 'ForestDnsZones' + $getTargetResourceResult.DomainDirectoryPartitionBaseName | Should -Be 'DomainDnsZones' + $getTargetResourceResult.MaximumUdpPacketSize | Should -Be 4000 + $getTargetResourceResult.NameCheckFlag | Should -Be 2 + $getTargetResourceResult.AutoConfigFileZones | Should -Be 1 + $getTargetResourceResult.AddressAnswerLimit | Should -Be 0 + $getTargetResourceResult.UpdateOptions | Should -Be 783 + $getTargetResourceResult.DisableAutoReverseZone | Should -BeFalse + $getTargetResourceResult.StrictFileParsing | Should -BeFalse + $getTargetResourceResult.EnableDirectoryPartitions | Should -BeFalse + $getTargetResourceResult.XfrConnectTimeout | Should -Be 30 + $getTargetResourceResult.BootMethod | Should -Be 3 + $getTargetResourceResult.AllowUpdate | Should -BeTrue + $getTargetResourceResult.LooseWildcarding | Should -BeFalse + $getTargetResourceResult.BindSecondaries | Should -BeFalse + $getTargetResourceResult.AutoCacheUpdate | Should -BeFalse + $getTargetResourceResult.EnableDnsSec | Should -BeTrue + $getTargetResourceResult.SendPort | Should -Be 0 + $getTargetResourceResult.WriteAuthorityNS | Should -BeFalse + $getTargetResourceResult.ForwardDelegations | Should -BeFalse + $getTargetResourceResult.EnableIPv6 | Should -BeTrue + $getTargetResourceResult.EnableOnlineSigning | Should -BeTrue + $getTargetResourceResult.EnableDuplicateQuerySuppression | Should -BeTrue + $getTargetResourceResult.AllowCnameAtNs | Should -BeTrue + $getTargetResourceResult.EnableRsoForRodc | Should -BeTrue + $getTargetResourceResult.OpenAclOnProxyUpdates | Should -BeTrue + $getTargetResourceResult.NoUpdateDelegations | Should -BeFalse + $getTargetResourceResult.EnableUpdateForwarding | Should -BeFalse + $getTargetResourceResult.EnableWinsR | Should -BeTrue + $getTargetResourceResult.DeleteOutsideGlue | Should -BeFalse + $getTargetResourceResult.AppendMsZoneTransferTag | Should -BeFalse + $getTargetResourceResult.AllowReadOnlyZoneTransfer | Should -BeFalse + $getTargetResourceResult.EnableSendErrorSuppression | Should -BeTrue + $getTargetResourceResult.SilentlyIgnoreCnameUpdateConflicts | Should -BeFalse + $getTargetResourceResult.EnableIQueryResponseGeneration | Should -BeFalse + $getTargetResourceResult.AdminConfigured | Should -BeTrue + $getTargetResourceResult.PublishAutoNet | Should -BeFalse + $getTargetResourceResult.ReloadException | Should -BeFalse + $getTargetResourceResult.IgnoreServerLevelPolicies | Should -BeFalse + $getTargetResourceResult.IgnoreAllPolicies | Should -BeFalse + $getTargetResourceResult.EnableVersionQuery | Should -Be 0 + $getTargetResourceResult.AutoCreateDelegation | Should -Be 2 + $getTargetResourceResult.RemoteIPv4RankBoost | Should -Be 5 + $getTargetResourceResult.RemoteIPv6RankBoost | Should -Be 0 + $getTargetResourceResult.MaximumRodcRsoQueueLength | Should -Be 300 + $getTargetResourceResult.MaximumRodcRsoAttemptsPerCycle | Should -Be 100 + $getTargetResourceResult.MaxResourceRecordsInNonSecureUpdate | Should -Be 30 + $getTargetResourceResult.LocalNetPriorityMask | Should -Be 255 + $getTargetResourceResult.TcpReceivePacketSize | Should -Be 65536 + $getTargetResourceResult.SelfTest | Should -Be 4294967295 + $getTargetResourceResult.XfrThrottleMultiplier | Should -Be 10 + $getTargetResourceResult.SocketPoolSize | Should -Be 2500 + $getTargetResourceResult.QuietRecvFaultInterval | Should -Be 0 + $getTargetResourceResult.QuietRecvLogInterval | Should -Be 0 + $getTargetResourceResult.SyncDsZoneSerial | Should -Be 2 + $getTargetResourceResult.ScopeOptionValue | Should -Be 0 + $getTargetResourceResult.VirtualizationInstanceOptionValue | Should -Be 0 + $getTargetResourceResult.ServerLevelPluginDll | Should -Be 'C:\dns\plugin.dll' + $getTargetResourceResult.RootTrustAnchorsURL | Should -Be 'https://data.iana.org/root-anchors/root-anchors.xml' + $getTargetResourceResult.LameDelegationTTL | Should -Be '00:00:00' + $getTargetResourceResult.MaximumSignatureScanPeriod | Should -Be '2.00:00:00' + $getTargetResourceResult.MaximumTrustAnchorActiveRefreshInterval | Should -Be '15.00:00:00' + $getTargetResourceResult.ZoneWritebackInterval | Should -Be '00:01:00' - $getTargetResourceResult.AllIPAddress | Should -HaveCount 3 - $getTargetResourceResult.AllIPAddress | Should -Contain 'fe80::e82e:70b7:f1d4:f695' - $getTargetResourceResult.AllIPAddress | Should -Contain '192.168.1.10' - $getTargetResourceResult.AllIPAddress | Should -Contain '192.168.2.10' + $getTargetResourceResult.ListeningIPAddress | Should -HaveCount 2 + $getTargetResourceResult.ListeningIPAddress | Should -Contain '192.168.1.10' + $getTargetResourceResult.ListeningIPAddress | Should -Contain '192.168.2.10' - $getTargetResourceResult.SocketPoolExcludedPortRanges | Should -HaveCount 2 - $getTargetResourceResult.SocketPoolExcludedPortRanges | Should -Contain 5353 - $getTargetResourceResult.SocketPoolExcludedPortRanges | Should -Contain 5454 + $getTargetResourceResult.AllIPAddress | Should -HaveCount 3 + $getTargetResourceResult.AllIPAddress | Should -Contain 'fe80::e82e:70b7:f1d4:f695' + $getTargetResourceResult.AllIPAddress | Should -Contain '192.168.1.10' + $getTargetResourceResult.AllIPAddress | Should -Contain '192.168.2.10' - } + $getTargetResourceResult.SocketPoolExcludedPortRanges | Should -HaveCount 2 + $getTargetResourceResult.SocketPoolExcludedPortRanges | Should -Contain 5353 + $getTargetResourceResult.SocketPoolExcludedPortRanges | Should -Contain 5454 } } + } +} - Describe 'DSC_DnsServerSetting\Test-TargetResource' -Tag 'Test' { - BeforeAll { - Mock -CommandName Assert-Module - } +Describe 'DSC_DnsServerSetting\Test-TargetResource' -Tag 'Test' { + BeforeAll { + Mock -CommandName Assert-Module + } - Context 'When the system is not in the desired state' { - BeforeAll { - Mock -CommandName Get-TargetResource -MockWith { - return @{ - DnsServer = 'dns1.company.local' - LocalNetPriority = $true - RoundRobin = $true - RpcProtocol = [System.UInt32] 0 - NameCheckFlag = [System.UInt32] 2 - AutoConfigFileZones = [System.UInt32] 1 - AddressAnswerLimit = [System.UInt32] 0 - UpdateOptions = [System.UInt32] 783 - DisableAutoReverseZone = $false - StrictFileParsing = $false - EnableDirectoryPartitions = $false - XfrConnectTimeout = [System.UInt32] 30 - BootMethod = [System.UInt32] 3 - AllowUpdate = $true - LooseWildcarding = $false - BindSecondaries = $false - AutoCacheUpdate = $false - EnableDnsSec = $true - SendPort = [System.UInt32] 0 - WriteAuthorityNS = $false - ListeningIPAddress = [System.String[]] @('192.168.1.10', '192.168.2.10') - ForwardDelegations = $false - EnableIPv6 = $true - EnableOnlineSigning = $true - EnableDuplicateQuerySuppression = $true - AllowCnameAtNs = $true - EnableRsoForRodc = $true - OpenAclOnProxyUpdates = $true - NoUpdateDelegations = $false - EnableUpdateForwarding = $false - EnableWinsR = $true - DeleteOutsideGlue = $false - AppendMsZoneTransferTag = $false - AllowReadOnlyZoneTransfer = $false - EnableSendErrorSuppression = $true - SilentlyIgnoreCnameUpdateConflicts = $false - EnableIQueryResponseGeneration = $false - AdminConfigured = $true - PublishAutoNet = $false - ReloadException = $false - IgnoreServerLevelPolicies = $false - IgnoreAllPolicies = $false - EnableVersionQuery = [System.UInt32] 0 - AutoCreateDelegation = [System.UInt32] 2 - RemoteIPv4RankBoost = [System.UInt32] 5 - RemoteIPv6RankBoost = [System.UInt32] 0 - MaximumRodcRsoQueueLength = [System.UInt32] 300 - MaximumRodcRsoAttemptsPerCycle = [System.UInt32] 100 - MaxResourceRecordsInNonSecureUpdate = [System.UInt32] 30 - LocalNetPriorityMask = [System.UInt32] 255 - TcpReceivePacketSize = [System.UInt32] 65536 - SelfTest = [System.UInt32] 4294967295 - XfrThrottleMultiplier = [System.UInt32] 10 - SocketPoolSize = [System.UInt32] 2500 - QuietRecvFaultInterval = [System.UInt32] 0 - QuietRecvLogInterval = [System.UInt32] 0 - SyncDsZoneSerial = [System.UInt32] 2 - ScopeOptionValue = [System.UInt32] 0 - VirtualizationInstanceOptionValue = [System.UInt32] 0 - ServerLevelPluginDll = 'C:\dns\plugin.dll' - RootTrustAnchorsURL = 'https://data.iana.org/root-anchors/oroot-anchors.xml' - SocketPoolExcludedPortRanges = $null - LameDelegationTTL = '00:00:00' - MaximumSignatureScanPeriod = '2.00:00:00' - MaximumTrustAnchorActiveRefreshInterval = '15.00:00:00' - ZoneWritebackInterval = '00:01:00' - } - } + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { + return @{ + DnsServer = 'dns1.company.local' + LocalNetPriority = $true + RoundRobin = $true + RpcProtocol = [System.UInt32] 0 + NameCheckFlag = [System.UInt32] 2 + AutoConfigFileZones = [System.UInt32] 1 + AddressAnswerLimit = [System.UInt32] 0 + UpdateOptions = [System.UInt32] 783 + DisableAutoReverseZone = $false + StrictFileParsing = $false + EnableDirectoryPartitions = $false + XfrConnectTimeout = [System.UInt32] 30 + BootMethod = [System.UInt32] 3 + AllowUpdate = $true + LooseWildcarding = $false + BindSecondaries = $false + AutoCacheUpdate = $false + EnableDnsSec = $true + SendPort = [System.UInt32] 0 + WriteAuthorityNS = $false + ListeningIPAddress = [System.String[]] @('192.168.1.10', '192.168.2.10') + ForwardDelegations = $false + EnableIPv6 = $true + EnableOnlineSigning = $true + EnableDuplicateQuerySuppression = $true + AllowCnameAtNs = $true + EnableRsoForRodc = $true + OpenAclOnProxyUpdates = $true + NoUpdateDelegations = $false + EnableUpdateForwarding = $false + EnableWinsR = $true + DeleteOutsideGlue = $false + AppendMsZoneTransferTag = $false + AllowReadOnlyZoneTransfer = $false + EnableSendErrorSuppression = $true + SilentlyIgnoreCnameUpdateConflicts = $false + EnableIQueryResponseGeneration = $false + AdminConfigured = $true + PublishAutoNet = $false + ReloadException = $false + IgnoreServerLevelPolicies = $false + IgnoreAllPolicies = $false + EnableVersionQuery = [System.UInt32] 0 + AutoCreateDelegation = [System.UInt32] 2 + RemoteIPv4RankBoost = [System.UInt32] 5 + RemoteIPv6RankBoost = [System.UInt32] 0 + MaximumRodcRsoQueueLength = [System.UInt32] 300 + MaximumRodcRsoAttemptsPerCycle = [System.UInt32] 100 + MaxResourceRecordsInNonSecureUpdate = [System.UInt32] 30 + LocalNetPriorityMask = [System.UInt32] 255 + TcpReceivePacketSize = [System.UInt32] 65536 + SelfTest = [System.UInt32] 4294967295 + XfrThrottleMultiplier = [System.UInt32] 10 + SocketPoolSize = [System.UInt32] 2500 + QuietRecvFaultInterval = [System.UInt32] 0 + QuietRecvLogInterval = [System.UInt32] 0 + SyncDsZoneSerial = [System.UInt32] 2 + ScopeOptionValue = [System.UInt32] 0 + VirtualizationInstanceOptionValue = [System.UInt32] 0 + ServerLevelPluginDll = 'C:\dns\plugin.dll' + RootTrustAnchorsURL = 'https://data.iana.org/root-anchors/oroot-anchors.xml' + SocketPoolExcludedPortRanges = $null + LameDelegationTTL = '00:00:00' + MaximumSignatureScanPeriod = '2.00:00:00' + MaximumTrustAnchorActiveRefreshInterval = '15.00:00:00' + ZoneWritebackInterval = '00:01:00' + } + } + } - $testCases = @( - @{ - PropertyName = 'LocalNetPriority' - PropertyValue = $false - } - @{ - PropertyName = 'RoundRobin' - PropertyValue = $false - } - @{ - PropertyName = 'RpcProtocol' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'NameCheckFlag' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'AutoConfigFileZones' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'AddressAnswerLimit' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'UpdateOptions' - PropertyValue = [System.UInt32] 784 - } - @{ - PropertyName = 'DisableAutoReverseZone' - PropertyValue = $true - } - @{ - PropertyName = 'StrictFileParsing' - PropertyValue = $true - } - @{ - PropertyName = 'EnableDirectoryPartitions' - PropertyValue = $true - } - @{ - PropertyName = 'XfrConnectTimeout' - PropertyValue = [System.UInt32] 40 - } - @{ - PropertyName = 'BootMethod' - PropertyValue = [System.UInt32] 2 - } - @{ - PropertyName = 'AllowUpdate' - PropertyValue = $false - } - @{ - PropertyName = 'LooseWildcarding' - PropertyValue = $true - } - @{ - PropertyName = 'BindSecondaries' - PropertyValue = $true - } - @{ - PropertyName = 'AutoCacheUpdate' - PropertyValue = $true - } - @{ - PropertyName = 'EnableDnsSec' - PropertyValue = $false - } - @{ - PropertyName = 'SendPort' - PropertyValue = [System.UInt32] 100 - } - @{ - PropertyName = 'WriteAuthorityNS' - PropertyValue = $true - } - @{ - PropertyName = 'ForwardDelegations' - PropertyValue = $true - } - @{ - PropertyName = 'ListeningIPAddress' - PropertyValue = [System.String[]] @('fe80::e82e:70b7:f1d4:f695') - } - @{ - PropertyName = 'EnableIPv6' - PropertyValue = $false - } - @{ - PropertyName = 'EnableOnlineSigning' - PropertyValue = $false - } - @{ - PropertyName = 'EnableDuplicateQuerySuppression' - PropertyValue = $false - } - @{ - PropertyName = 'AllowCnameAtNs' - PropertyValue = $false - } - @{ - PropertyName = 'EnableRsoForRodc' - PropertyValue = $false - } - @{ - PropertyName = 'OpenAclOnProxyUpdates' - PropertyValue = $false - } - @{ - PropertyName = 'NoUpdateDelegations' - PropertyValue = $true - } - @{ - PropertyName = 'EnableUpdateForwarding' - PropertyValue = $true - } - @{ - PropertyName = 'EnableWinsR' - PropertyValue = $false - } - @{ - PropertyName = 'DeleteOutsideGlue' - PropertyValue = $true - } - @{ - PropertyName = 'AppendMsZoneTransferTag' - PropertyValue = $true - } - @{ - PropertyName = 'AllowReadOnlyZoneTransfer' - PropertyValue = $true - } - @{ - PropertyName = 'EnableSendErrorSuppression' - PropertyValue = $false - } - @{ - PropertyName = 'SilentlyIgnoreCnameUpdateConflicts' - PropertyValue = $true - } - @{ - PropertyName = 'EnableIQueryResponseGeneration' - PropertyValue = $true - } - @{ - PropertyName = 'AdminConfigured' - PropertyValue = $false - } - @{ - PropertyName = 'PublishAutoNet' - PropertyValue = $true - } - @{ - PropertyName = 'ReloadException' - PropertyValue = $true - } - @{ - PropertyName = 'IgnoreServerLevelPolicies' - PropertyValue = $true - } - @{ - PropertyName = 'IgnoreAllPolicies' - PropertyValue = $true - } - @{ - PropertyName = 'EnableVersionQuery' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'AutoCreateDelegation' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'RemoteIPv4RankBoost' - PropertyValue = [System.UInt32] 4 - } - @{ - PropertyName = 'RemoteIPv6RankBoost' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'MaximumRodcRsoQueueLength' - PropertyValue = [System.UInt32] 350 - } - @{ - PropertyName = 'MaximumRodcRsoAttemptsPerCycle' - PropertyValue = [System.UInt32] 150 - } - @{ - PropertyName = 'MaxResourceRecordsInNonSecureUpdate' - PropertyValue = [System.UInt32] 40 - } - @{ - PropertyName = 'LocalNetPriorityMask' - PropertyValue = [System.UInt32] 254 - } - @{ - PropertyName = 'TcpReceivePacketSize' - PropertyValue = [System.UInt32] 65000 - } - @{ - PropertyName = 'SelfTest' - PropertyValue = [System.UInt32] 4000000000 - } - @{ - PropertyName = 'XfrThrottleMultiplier' - PropertyValue = [System.UInt32] 15 - } - @{ - PropertyName = 'SocketPoolSize' - PropertyValue = [System.UInt32] 3000 - } - @{ - PropertyName = 'QuietRecvFaultInterval' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'QuietRecvLogInterval' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'SyncDsZoneSerial' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'ScopeOptionValue' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'VirtualizationInstanceOptionValue' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'ServerLevelPluginDll' - PropertyValue = 'C:\dns\oldPlugin.dll' - } - @{ - PropertyName = 'RootTrustAnchorsURL' - PropertyValue = 'https://data.iana.org/old-root-anchors/root-anchors.xml' - } - @{ - PropertyName = 'SocketPoolExcludedPortRanges' - PropertyValue = [System.String[]] @(5353, 5454) - } - @{ - PropertyName = 'LameDelegationTTL' - PropertyValue = '00:00:01' - } - @{ - PropertyName = 'MaximumSignatureScanPeriod' - PropertyValue = '3.00:00:00' - } - @{ - PropertyName = 'MaximumTrustAnchorActiveRefreshInterval' - PropertyValue = '20.00:00:00' - } - @{ - PropertyName = 'ZoneWritebackInterval' - PropertyValue = '00:00:30' - } - ) + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'LocalNetPriority' + PropertyValue = $false + } + @{ + PropertyName = 'RoundRobin' + PropertyValue = $false + } + @{ + PropertyName = 'RpcProtocol' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'NameCheckFlag' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'AutoConfigFileZones' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'AddressAnswerLimit' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'UpdateOptions' + PropertyValue = [System.UInt32] 784 + } + @{ + PropertyName = 'DisableAutoReverseZone' + PropertyValue = $true + } + @{ + PropertyName = 'StrictFileParsing' + PropertyValue = $true + } + @{ + PropertyName = 'EnableDirectoryPartitions' + PropertyValue = $true + } + @{ + PropertyName = 'XfrConnectTimeout' + PropertyValue = [System.UInt32] 40 + } + @{ + PropertyName = 'BootMethod' + PropertyValue = [System.UInt32] 2 + } + @{ + PropertyName = 'AllowUpdate' + PropertyValue = $false + } + @{ + PropertyName = 'LooseWildcarding' + PropertyValue = $true + } + @{ + PropertyName = 'BindSecondaries' + PropertyValue = $true + } + @{ + PropertyName = 'AutoCacheUpdate' + PropertyValue = $true + } + @{ + PropertyName = 'EnableDnsSec' + PropertyValue = $false + } + @{ + PropertyName = 'SendPort' + PropertyValue = [System.UInt32] 100 + } + @{ + PropertyName = 'WriteAuthorityNS' + PropertyValue = $true + } + @{ + PropertyName = 'ForwardDelegations' + PropertyValue = $true + } + @{ + PropertyName = 'ListeningIPAddress' + PropertyValue = [System.String[]] @('fe80::e82e:70b7:f1d4:f695') + } + @{ + PropertyName = 'EnableIPv6' + PropertyValue = $false + } + @{ + PropertyName = 'EnableOnlineSigning' + PropertyValue = $false + } + @{ + PropertyName = 'EnableDuplicateQuerySuppression' + PropertyValue = $false + } + @{ + PropertyName = 'AllowCnameAtNs' + PropertyValue = $false + } + @{ + PropertyName = 'EnableRsoForRodc' + PropertyValue = $false + } + @{ + PropertyName = 'OpenAclOnProxyUpdates' + PropertyValue = $false + } + @{ + PropertyName = 'NoUpdateDelegations' + PropertyValue = $true + } + @{ + PropertyName = 'EnableUpdateForwarding' + PropertyValue = $true + } + @{ + PropertyName = 'EnableWinsR' + PropertyValue = $false + } + @{ + PropertyName = 'DeleteOutsideGlue' + PropertyValue = $true + } + @{ + PropertyName = 'AppendMsZoneTransferTag' + PropertyValue = $true + } + @{ + PropertyName = 'AllowReadOnlyZoneTransfer' + PropertyValue = $true + } + @{ + PropertyName = 'EnableSendErrorSuppression' + PropertyValue = $false + } + @{ + PropertyName = 'SilentlyIgnoreCnameUpdateConflicts' + PropertyValue = $true + } + @{ + PropertyName = 'EnableIQueryResponseGeneration' + PropertyValue = $true + } + @{ + PropertyName = 'AdminConfigured' + PropertyValue = $false + } + @{ + PropertyName = 'PublishAutoNet' + PropertyValue = $true + } + @{ + PropertyName = 'ReloadException' + PropertyValue = $true + } + @{ + PropertyName = 'IgnoreServerLevelPolicies' + PropertyValue = $true + } + @{ + PropertyName = 'IgnoreAllPolicies' + PropertyValue = $true + } + @{ + PropertyName = 'EnableVersionQuery' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'AutoCreateDelegation' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'RemoteIPv4RankBoost' + PropertyValue = [System.UInt32] 4 + } + @{ + PropertyName = 'RemoteIPv6RankBoost' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'MaximumRodcRsoQueueLength' + PropertyValue = [System.UInt32] 350 + } + @{ + PropertyName = 'MaximumRodcRsoAttemptsPerCycle' + PropertyValue = [System.UInt32] 150 + } + @{ + PropertyName = 'MaxResourceRecordsInNonSecureUpdate' + PropertyValue = [System.UInt32] 40 + } + @{ + PropertyName = 'LocalNetPriorityMask' + PropertyValue = [System.UInt32] 254 + } + @{ + PropertyName = 'TcpReceivePacketSize' + PropertyValue = [System.UInt32] 65000 + } + @{ + PropertyName = 'SelfTest' + PropertyValue = [System.UInt32] 4000000000 + } + @{ + PropertyName = 'XfrThrottleMultiplier' + PropertyValue = [System.UInt32] 15 + } + @{ + PropertyName = 'SocketPoolSize' + PropertyValue = [System.UInt32] 3000 + } + @{ + PropertyName = 'QuietRecvFaultInterval' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'QuietRecvLogInterval' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'SyncDsZoneSerial' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'ScopeOptionValue' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'VirtualizationInstanceOptionValue' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'ServerLevelPluginDll' + PropertyValue = 'C:\dns\oldPlugin.dll' + } + @{ + PropertyName = 'RootTrustAnchorsURL' + PropertyValue = 'https://data.iana.org/old-root-anchors/root-anchors.xml' } + @{ + PropertyName = 'SocketPoolExcludedPortRanges' + PropertyValue = [System.String[]] @(5353, 5454) + } + @{ + PropertyName = 'LameDelegationTTL' + PropertyValue = '00:00:01' + } + @{ + PropertyName = 'MaximumSignatureScanPeriod' + PropertyValue = '3.00:00:00' + } + @{ + PropertyName = 'MaximumTrustAnchorActiveRefreshInterval' + PropertyValue = '20.00:00:00' + } + @{ + PropertyName = 'ZoneWritebackInterval' + PropertyValue = '00:00:30' + } + ) + } - It 'Should return $false for property ' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + It 'Should return $false for property ' -ForEach $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $testTargetResourceParameters = @{ - DnsServer = 'dns1.company.local' - $PropertyName = $PropertyValue - } + $testTargetResourceParameters = @{ + DnsServer = 'dns1.company.local' + $PropertyName = $PropertyValue + } - Test-TargetResource @testTargetResourceParameters | Should -BeFalse + Test-TargetResource @testTargetResourceParameters | Should -BeFalse + } + } + } + + Context 'When the system is in the desired state' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { + return @{ + DnsServer = 'dns1.company.local' + LocalNetPriority = $true + RoundRobin = $true + RpcProtocol = [System.UInt32] 0 + NameCheckFlag = [System.UInt32] 2 + AutoConfigFileZones = [System.UInt32] 1 + AddressAnswerLimit = [System.UInt32] 0 + UpdateOptions = [System.UInt32] 783 + DisableAutoReverseZone = $false + StrictFileParsing = $false + EnableDirectoryPartitions = $false + XfrConnectTimeout = [System.UInt32] 30 + BootMethod = [System.UInt32] 3 + AllowUpdate = $true + LooseWildcarding = $false + BindSecondaries = $false + AutoCacheUpdate = $false + EnableDnsSec = $true + SendPort = [System.UInt32] 0 + WriteAuthorityNS = $false + ListeningIPAddress = [System.String[]] @('192.168.1.10', '192.168.2.10') + ForwardDelegations = $false + EnableIPv6 = $true + EnableOnlineSigning = $true + EnableDuplicateQuerySuppression = $true + AllowCnameAtNs = $true + EnableRsoForRodc = $true + OpenAclOnProxyUpdates = $true + NoUpdateDelegations = $false + EnableUpdateForwarding = $false + EnableWinsR = $true + DeleteOutsideGlue = $false + AppendMsZoneTransferTag = $false + AllowReadOnlyZoneTransfer = $false + EnableSendErrorSuppression = $true + SilentlyIgnoreCnameUpdateConflicts = $false + EnableIQueryResponseGeneration = $false + AdminConfigured = $true + PublishAutoNet = $false + ReloadException = $false + IgnoreServerLevelPolicies = $false + IgnoreAllPolicies = $false + EnableVersionQuery = [System.UInt32] 0 + AutoCreateDelegation = [System.UInt32] 2 + RemoteIPv4RankBoost = [System.UInt32] 5 + RemoteIPv6RankBoost = [System.UInt32] 0 + MaximumRodcRsoQueueLength = [System.UInt32] 300 + MaximumRodcRsoAttemptsPerCycle = [System.UInt32] 100 + MaxResourceRecordsInNonSecureUpdate = [System.UInt32] 30 + LocalNetPriorityMask = [System.UInt32] 255 + TcpReceivePacketSize = [System.UInt32] 65536 + SelfTest = [System.UInt32] 4294967295 + XfrThrottleMultiplier = [System.UInt32] 10 + SocketPoolSize = [System.UInt32] 2500 + QuietRecvFaultInterval = [System.UInt32] 0 + QuietRecvLogInterval = [System.UInt32] 0 + SyncDsZoneSerial = [System.UInt32] 2 + ScopeOptionValue = [System.UInt32] 0 + VirtualizationInstanceOptionValue = [System.UInt32] 0 + ServerLevelPluginDll = 'C:\dns\plugin.dll' + RootTrustAnchorsURL = 'https://data.iana.org/root-anchors/root-anchors.xml' + SocketPoolExcludedPortRanges = [System.String[]] @(5353, 5454) + LameDelegationTTL = '00:00:00' + MaximumSignatureScanPeriod = '2.00:00:00' + MaximumTrustAnchorActiveRefreshInterval = '15.00:00:00' + ZoneWritebackInterval = '00:01:00' } } + } - Context 'When the system is in the desired state' { - BeforeAll { - Mock -CommandName Get-TargetResource -MockWith { - return @{ - DnsServer = 'dns1.company.local' - LocalNetPriority = $true - RoundRobin = $true - RpcProtocol = [System.UInt32] 0 - NameCheckFlag = [System.UInt32] 2 - AutoConfigFileZones = [System.UInt32] 1 - AddressAnswerLimit = [System.UInt32] 0 - UpdateOptions = [System.UInt32] 783 - DisableAutoReverseZone = $false - StrictFileParsing = $false - EnableDirectoryPartitions = $false - XfrConnectTimeout = [System.UInt32] 30 - BootMethod = [System.UInt32] 3 - AllowUpdate = $true - LooseWildcarding = $false - BindSecondaries = $false - AutoCacheUpdate = $false - EnableDnsSec = $true - SendPort = [System.UInt32] 0 - WriteAuthorityNS = $false - ListeningIPAddress = [System.String[]] @('192.168.1.10', '192.168.2.10') - ForwardDelegations = $false - EnableIPv6 = $true - EnableOnlineSigning = $true - EnableDuplicateQuerySuppression = $true - AllowCnameAtNs = $true - EnableRsoForRodc = $true - OpenAclOnProxyUpdates = $true - NoUpdateDelegations = $false - EnableUpdateForwarding = $false - EnableWinsR = $true - DeleteOutsideGlue = $false - AppendMsZoneTransferTag = $false - AllowReadOnlyZoneTransfer = $false - EnableSendErrorSuppression = $true - SilentlyIgnoreCnameUpdateConflicts = $false - EnableIQueryResponseGeneration = $false - AdminConfigured = $true - PublishAutoNet = $false - ReloadException = $false - IgnoreServerLevelPolicies = $false - IgnoreAllPolicies = $false - EnableVersionQuery = [System.UInt32] 0 - AutoCreateDelegation = [System.UInt32] 2 - RemoteIPv4RankBoost = [System.UInt32] 5 - RemoteIPv6RankBoost = [System.UInt32] 0 - MaximumRodcRsoQueueLength = [System.UInt32] 300 - MaximumRodcRsoAttemptsPerCycle = [System.UInt32] 100 - MaxResourceRecordsInNonSecureUpdate = [System.UInt32] 30 - LocalNetPriorityMask = [System.UInt32] 255 - TcpReceivePacketSize = [System.UInt32] 65536 - SelfTest = [System.UInt32] 4294967295 - XfrThrottleMultiplier = [System.UInt32] 10 - SocketPoolSize = [System.UInt32] 2500 - QuietRecvFaultInterval = [System.UInt32] 0 - QuietRecvLogInterval = [System.UInt32] 0 - SyncDsZoneSerial = [System.UInt32] 2 - ScopeOptionValue = [System.UInt32] 0 - VirtualizationInstanceOptionValue = [System.UInt32] 0 - ServerLevelPluginDll = 'C:\dns\plugin.dll' - RootTrustAnchorsURL = 'https://data.iana.org/root-anchors/root-anchors.xml' - SocketPoolExcludedPortRanges = [System.String[]] @(5353, 5454) - LameDelegationTTL = '00:00:00' - MaximumSignatureScanPeriod = '2.00:00:00' - MaximumTrustAnchorActiveRefreshInterval = '15.00:00:00' - ZoneWritebackInterval = '00:01:00' - } - } + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'LocalNetPriority' + PropertyValue = $true + } + @{ + PropertyName = 'RoundRobin' + PropertyValue = $true + } + @{ + PropertyName = 'RpcProtocol' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'NameCheckFlag' + PropertyValue = [System.UInt32] 2 + } + @{ + PropertyName = 'AutoConfigFileZones' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'AddressAnswerLimit' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'UpdateOptions' + PropertyValue = [System.UInt32] 783 + } + @{ + PropertyName = 'DisableAutoReverseZone' + PropertyValue = $false + } + @{ + PropertyName = 'StrictFileParsing' + PropertyValue = $false + } + @{ + PropertyName = 'EnableDirectoryPartitions' + PropertyValue = $false + } + @{ + PropertyName = 'XfrConnectTimeout' + PropertyValue = [System.UInt32] 30 + } + @{ + PropertyName = 'BootMethod' + PropertyValue = [System.UInt32] 3 + } + @{ + PropertyName = 'AllowUpdate' + PropertyValue = $true + } + @{ + PropertyName = 'LooseWildcarding' + PropertyValue = $false + } + @{ + PropertyName = 'BindSecondaries' + PropertyValue = $false + } + @{ + PropertyName = 'AutoCacheUpdate' + PropertyValue = $false + } + @{ + PropertyName = 'EnableDnsSec' + PropertyValue = $true + } + @{ + PropertyName = 'SendPort' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'WriteAuthorityNS' + PropertyValue = $false + } + @{ + PropertyName = 'ForwardDelegations' + PropertyValue = $false + } + @{ + PropertyName = 'ListeningIPAddress' + PropertyValue = [System.String[]] @('192.168.1.10', '192.168.2.10') + } + @{ + PropertyName = 'EnableIPv6' + PropertyValue = $true + } + @{ + PropertyName = 'EnableOnlineSigning' + PropertyValue = $true + } + @{ + PropertyName = 'EnableDuplicateQuerySuppression' + PropertyValue = $true + } + @{ + PropertyName = 'AllowCnameAtNs' + PropertyValue = $true + } + @{ + PropertyName = 'EnableRsoForRodc' + PropertyValue = $true + } + @{ + PropertyName = 'OpenAclOnProxyUpdates' + PropertyValue = $true + } + @{ + PropertyName = 'NoUpdateDelegations' + PropertyValue = $false + } + @{ + PropertyName = 'EnableUpdateForwarding' + PropertyValue = $false + } + @{ + PropertyName = 'EnableWinsR' + PropertyValue = $true + } + @{ + PropertyName = 'DeleteOutsideGlue' + PropertyValue = $false + } + @{ + PropertyName = 'AppendMsZoneTransferTag' + PropertyValue = $false + } + @{ + PropertyName = 'AllowReadOnlyZoneTransfer' + PropertyValue = $false + } + @{ + PropertyName = 'EnableSendErrorSuppression' + PropertyValue = $true + } + @{ + PropertyName = 'SilentlyIgnoreCnameUpdateConflicts' + PropertyValue = $false + } + @{ + PropertyName = 'EnableIQueryResponseGeneration' + PropertyValue = $false + } + @{ + PropertyName = 'AdminConfigured' + PropertyValue = $true + } + @{ + PropertyName = 'PublishAutoNet' + PropertyValue = $false + } + @{ + PropertyName = 'ReloadException' + PropertyValue = $false + } + @{ + PropertyName = 'IgnoreServerLevelPolicies' + PropertyValue = $false + } + @{ + PropertyName = 'IgnoreAllPolicies' + PropertyValue = $false + } + @{ + PropertyName = 'EnableVersionQuery' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'AutoCreateDelegation' + PropertyValue = [System.UInt32] 2 + } + @{ + PropertyName = 'RemoteIPv4RankBoost' + PropertyValue = [System.UInt32] 5 + } + @{ + PropertyName = 'RemoteIPv6RankBoost' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'MaximumRodcRsoQueueLength' + PropertyValue = [System.UInt32] 300 + } + @{ + PropertyName = 'MaximumRodcRsoAttemptsPerCycle' + PropertyValue = [System.UInt32] 100 + } + @{ + PropertyName = 'MaxResourceRecordsInNonSecureUpdate' + PropertyValue = [System.UInt32] 30 + } + @{ + PropertyName = 'LocalNetPriorityMask' + PropertyValue = [System.UInt32] 255 + } + @{ + PropertyName = 'TcpReceivePacketSize' + PropertyValue = [System.UInt32] 65536 + } + @{ + PropertyName = 'SelfTest' + PropertyValue = [System.UInt32] 4294967295 + } + @{ + PropertyName = 'XfrThrottleMultiplier' + PropertyValue = [System.UInt32] 10 + } + @{ + PropertyName = 'SocketPoolSize' + PropertyValue = [System.UInt32] 2500 + } + @{ + PropertyName = 'QuietRecvFaultInterval' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'QuietRecvLogInterval' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'SyncDsZoneSerial' + PropertyValue = [System.UInt32] 2 + } + @{ + PropertyName = 'ScopeOptionValue' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'VirtualizationInstanceOptionValue' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'ServerLevelPluginDll' + PropertyValue = 'C:\dns\plugin.dll' + } + @{ + PropertyName = 'RootTrustAnchorsURL' + PropertyValue = 'https://data.iana.org/root-anchors/root-anchors.xml' + } + @{ + PropertyName = 'SocketPoolExcludedPortRanges' + PropertyValue = [System.String[]] @(5353, 5454) + } + @{ + PropertyName = 'LameDelegationTTL' + PropertyValue = '00:00:00' + } + @{ + PropertyName = 'MaximumSignatureScanPeriod' + PropertyValue = '2.00:00:00' + } + @{ + PropertyName = 'MaximumTrustAnchorActiveRefreshInterval' + PropertyValue = '15.00:00:00' + } + @{ + PropertyName = 'ZoneWritebackInterval' + PropertyValue = '00:01:00' + } + ) + } - $testCases = @( - @{ - PropertyName = 'LocalNetPriority' - PropertyValue = $true - } - @{ - PropertyName = 'RoundRobin' - PropertyValue = $true - } - @{ - PropertyName = 'RpcProtocol' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'NameCheckFlag' - PropertyValue = [System.UInt32] 2 - } - @{ - PropertyName = 'AutoConfigFileZones' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'AddressAnswerLimit' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'UpdateOptions' - PropertyValue = [System.UInt32] 783 - } - @{ - PropertyName = 'DisableAutoReverseZone' - PropertyValue = $false - } - @{ - PropertyName = 'StrictFileParsing' - PropertyValue = $false - } - @{ - PropertyName = 'EnableDirectoryPartitions' - PropertyValue = $false - } - @{ - PropertyName = 'XfrConnectTimeout' - PropertyValue = [System.UInt32] 30 - } - @{ - PropertyName = 'BootMethod' - PropertyValue = [System.UInt32] 3 - } - @{ - PropertyName = 'AllowUpdate' - PropertyValue = $true - } - @{ - PropertyName = 'LooseWildcarding' - PropertyValue = $false - } - @{ - PropertyName = 'BindSecondaries' - PropertyValue = $false - } - @{ - PropertyName = 'AutoCacheUpdate' - PropertyValue = $false - } - @{ - PropertyName = 'EnableDnsSec' - PropertyValue = $true - } - @{ - PropertyName = 'SendPort' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'WriteAuthorityNS' - PropertyValue = $false - } - @{ - PropertyName = 'ForwardDelegations' - PropertyValue = $false - } - @{ - PropertyName = 'ListeningIPAddress' - PropertyValue = [System.String[]] @('192.168.1.10', '192.168.2.10') - } - @{ - PropertyName = 'EnableIPv6' - PropertyValue = $true - } - @{ - PropertyName = 'EnableOnlineSigning' - PropertyValue = $true - } - @{ - PropertyName = 'EnableDuplicateQuerySuppression' - PropertyValue = $true - } - @{ - PropertyName = 'AllowCnameAtNs' - PropertyValue = $true - } - @{ - PropertyName = 'EnableRsoForRodc' - PropertyValue = $true - } - @{ - PropertyName = 'OpenAclOnProxyUpdates' - PropertyValue = $true - } - @{ - PropertyName = 'NoUpdateDelegations' - PropertyValue = $false - } - @{ - PropertyName = 'EnableUpdateForwarding' - PropertyValue = $false - } - @{ - PropertyName = 'EnableWinsR' - PropertyValue = $true - } - @{ - PropertyName = 'DeleteOutsideGlue' - PropertyValue = $false - } - @{ - PropertyName = 'AppendMsZoneTransferTag' - PropertyValue = $false - } - @{ - PropertyName = 'AllowReadOnlyZoneTransfer' - PropertyValue = $false - } - @{ - PropertyName = 'EnableSendErrorSuppression' - PropertyValue = $true - } - @{ - PropertyName = 'SilentlyIgnoreCnameUpdateConflicts' - PropertyValue = $false - } - @{ - PropertyName = 'EnableIQueryResponseGeneration' - PropertyValue = $false - } - @{ - PropertyName = 'AdminConfigured' - PropertyValue = $true - } - @{ - PropertyName = 'PublishAutoNet' - PropertyValue = $false - } - @{ - PropertyName = 'ReloadException' - PropertyValue = $false - } - @{ - PropertyName = 'IgnoreServerLevelPolicies' - PropertyValue = $false - } - @{ - PropertyName = 'IgnoreAllPolicies' - PropertyValue = $false - } - @{ - PropertyName = 'EnableVersionQuery' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'AutoCreateDelegation' - PropertyValue = [System.UInt32] 2 - } - @{ - PropertyName = 'RemoteIPv4RankBoost' - PropertyValue = [System.UInt32] 5 - } - @{ - PropertyName = 'RemoteIPv6RankBoost' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'MaximumRodcRsoQueueLength' - PropertyValue = [System.UInt32] 300 - } - @{ - PropertyName = 'MaximumRodcRsoAttemptsPerCycle' - PropertyValue = [System.UInt32] 100 - } - @{ - PropertyName = 'MaxResourceRecordsInNonSecureUpdate' - PropertyValue = [System.UInt32] 30 - } - @{ - PropertyName = 'LocalNetPriorityMask' - PropertyValue = [System.UInt32] 255 - } - @{ - PropertyName = 'TcpReceivePacketSize' - PropertyValue = [System.UInt32] 65536 - } - @{ - PropertyName = 'SelfTest' - PropertyValue = [System.UInt32] 4294967295 - } - @{ - PropertyName = 'XfrThrottleMultiplier' - PropertyValue = [System.UInt32] 10 - } - @{ - PropertyName = 'SocketPoolSize' - PropertyValue = [System.UInt32] 2500 - } - @{ - PropertyName = 'QuietRecvFaultInterval' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'QuietRecvLogInterval' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'SyncDsZoneSerial' - PropertyValue = [System.UInt32] 2 - } - @{ - PropertyName = 'ScopeOptionValue' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'VirtualizationInstanceOptionValue' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'ServerLevelPluginDll' - PropertyValue = 'C:\dns\plugin.dll' - } - @{ - PropertyName = 'RootTrustAnchorsURL' - PropertyValue = 'https://data.iana.org/root-anchors/root-anchors.xml' - } - @{ - PropertyName = 'SocketPoolExcludedPortRanges' - PropertyValue = [System.String[]] @(5353, 5454) - } - @{ - PropertyName = 'LameDelegationTTL' - PropertyValue = '00:00:00' - } - @{ - PropertyName = 'MaximumSignatureScanPeriod' - PropertyValue = '2.00:00:00' - } - @{ - PropertyName = 'MaximumTrustAnchorActiveRefreshInterval' - PropertyValue = '15.00:00:00' - } - @{ - PropertyName = 'ZoneWritebackInterval' - PropertyValue = '00:01:00' - } - ) + It 'Should return $true for property ' -ForEach $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testTargetResourceParameters = @{ + DnsServer = 'dns1.company.local' + $PropertyName = $PropertyValue } - It 'Should return $true for property ' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + Test-TargetResource @testTargetResourceParameters | Should -BeTrue + } + } + } +} - $testTargetResourceParameters = @{ - DnsServer = 'dns1.company.local' - $PropertyName = $PropertyValue - } +Describe 'DSC_DnsServerSetting\Set-TargetResource' -Tag 'Set' { + BeforeAll { + Mock -CommandName Assert-Module + Mock -CommandName Set-DnsServerSetting + } - Test-TargetResource @testTargetResourceParameters | Should -BeTrue + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Get-DnsServerSetting -MockWith { + return New-CimInstance -ClassName 'DnsServerSetting' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + DnsServer = 'dns1.company.local' + LocalNetPriority = $true + RoundRobin = $true + RpcProtocol = [System.UInt32] 0 + NameCheckFlag = [System.UInt32] 2 + AutoConfigFileZones = [System.UInt32] 1 + AddressAnswerLimit = [System.UInt32] 0 + UpdateOptions = [System.UInt32] 783 + DisableAutoReverseZone = $false + StrictFileParsing = $false + EnableDirectoryPartitions = $false + XfrConnectTimeout = [System.UInt32] 30 + BootMethod = [System.UInt32] 3 + AllowUpdate = $true + LooseWildcarding = $false + BindSecondaries = $false + AutoCacheUpdate = $false + EnableDnsSec = $true + SendPort = [System.UInt32] 0 + WriteAuthorityNS = $false + ListeningIPAddress = [System.String[]] @('192.168.1.10', '192.168.2.10') + ForwardDelegations = $false + EnableIPv6 = $true + EnableOnlineSigning = $true + EnableDuplicateQuerySuppression = $true + AllowCnameAtNs = $true + EnableRsoForRodc = $true + OpenAclOnProxyUpdates = $true + NoUpdateDelegations = $false + EnableUpdateForwarding = $false + EnableWinsR = $true + DeleteOutsideGlue = $false + AppendMsZoneTransferTag = $false + AllowReadOnlyZoneTransfer = $false + EnableSendErrorSuppression = $true + SilentlyIgnoreCnameUpdateConflicts = $false + EnableIQueryResponseGeneration = $false + AdminConfigured = $true + PublishAutoNet = $false + ReloadException = $false + IgnoreServerLevelPolicies = $false + IgnoreAllPolicies = $false + EnableVersionQuery = [System.UInt32] 0 + AutoCreateDelegation = [System.UInt32] 2 + RemoteIPv4RankBoost = [System.UInt32] 5 + RemoteIPv6RankBoost = [System.UInt32] 0 + MaximumRodcRsoQueueLength = [System.UInt32] 300 + MaximumRodcRsoAttemptsPerCycle = [System.UInt32] 100 + MaxResourceRecordsInNonSecureUpdate = [System.UInt32] 30 + LocalNetPriorityMask = [System.UInt32] 255 + TcpReceivePacketSize = [System.UInt32] 65536 + SelfTest = [System.UInt32] 4294967295 + XfrThrottleMultiplier = [System.UInt32] 10 + SocketPoolSize = [System.UInt32] 2500 + QuietRecvFaultInterval = [System.UInt32] 0 + QuietRecvLogInterval = [System.UInt32] 0 + SyncDsZoneSerial = [System.UInt32] 2 + ScopeOptionValue = [System.UInt32] 0 + VirtualizationInstanceOptionValue = [System.UInt32] 0 + ServerLevelPluginDll = 'C:\dns\plugin.dll' + RootTrustAnchorsURL = 'https://data.iana.org/root-anchors/root-anchors.xml' + SocketPoolExcludedPortRanges = [System.String[]] @() + LameDelegationTTL = New-TimeSpan -Seconds 0 + MaximumSignatureScanPeriod = New-TimeSpan -Days 2 + MaximumTrustAnchorActiveRefreshInterval = New-TimeSpan -Days 15 + ZoneWritebackInterval = New-TimeSpan -Minutes 1 } } } - Describe 'DSC_DnsServerSetting\Set-TargetResource' -Tag 'Set' { - BeforeAll { - Mock -CommandName Assert-Module - Mock -CommandName Set-DnsServerSetting - } + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'LocalNetPriority' + PropertyValue = $false + } + @{ + PropertyName = 'RoundRobin' + PropertyValue = $false + } + @{ + PropertyName = 'RpcProtocol' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'NameCheckFlag' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'AutoConfigFileZones' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'AddressAnswerLimit' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'UpdateOptions' + PropertyValue = [System.UInt32] 784 + } + @{ + PropertyName = 'DisableAutoReverseZone' + PropertyValue = $true + } + @{ + PropertyName = 'StrictFileParsing' + PropertyValue = $true + } + @{ + PropertyName = 'EnableDirectoryPartitions' + PropertyValue = $true + } + @{ + PropertyName = 'XfrConnectTimeout' + PropertyValue = [System.UInt32] 40 + } + @{ + PropertyName = 'BootMethod' + PropertyValue = [System.UInt32] 2 + } + @{ + PropertyName = 'AllowUpdate' + PropertyValue = $false + } + @{ + PropertyName = 'LooseWildcarding' + PropertyValue = $true + } + @{ + PropertyName = 'BindSecondaries' + PropertyValue = $true + } + @{ + PropertyName = 'AutoCacheUpdate' + PropertyValue = $true + } + @{ + PropertyName = 'EnableDnsSec' + PropertyValue = $false + } + @{ + PropertyName = 'SendPort' + PropertyValue = [System.UInt32] 100 + } + @{ + PropertyName = 'WriteAuthorityNS' + PropertyValue = $true + } + @{ + PropertyName = 'ForwardDelegations' + PropertyValue = $true + } + @{ + PropertyName = 'ListeningIPAddress' + PropertyValue = [System.String[]] @('fe80::e82e:70b7:f1d4:f695') + } + @{ + PropertyName = 'EnableIPv6' + PropertyValue = $false + } + @{ + PropertyName = 'EnableOnlineSigning' + PropertyValue = $false + } + @{ + PropertyName = 'EnableDuplicateQuerySuppression' + PropertyValue = $false + } + @{ + PropertyName = 'AllowCnameAtNs' + PropertyValue = $false + } + @{ + PropertyName = 'EnableRsoForRodc' + PropertyValue = $false + } + @{ + PropertyName = 'OpenAclOnProxyUpdates' + PropertyValue = $false + } + @{ + PropertyName = 'NoUpdateDelegations' + PropertyValue = $true + } + @{ + PropertyName = 'EnableUpdateForwarding' + PropertyValue = $true + } + @{ + PropertyName = 'EnableWinsR' + PropertyValue = $false + } + @{ + PropertyName = 'DeleteOutsideGlue' + PropertyValue = $true + } + @{ + PropertyName = 'AppendMsZoneTransferTag' + PropertyValue = $true + } + @{ + PropertyName = 'AllowReadOnlyZoneTransfer' + PropertyValue = $true + } + @{ + PropertyName = 'EnableSendErrorSuppression' + PropertyValue = $false + } + @{ + PropertyName = 'SilentlyIgnoreCnameUpdateConflicts' + PropertyValue = $true + } + @{ + PropertyName = 'EnableIQueryResponseGeneration' + PropertyValue = $true + } + @{ + PropertyName = 'AdminConfigured' + PropertyValue = $false + } + @{ + PropertyName = 'PublishAutoNet' + PropertyValue = $true + } + @{ + PropertyName = 'ReloadException' + PropertyValue = $true + } + @{ + PropertyName = 'IgnoreServerLevelPolicies' + PropertyValue = $true + } + @{ + PropertyName = 'IgnoreAllPolicies' + PropertyValue = $true + } + @{ + PropertyName = 'EnableVersionQuery' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'AutoCreateDelegation' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'RemoteIPv4RankBoost' + PropertyValue = [System.UInt32] 4 + } + @{ + PropertyName = 'RemoteIPv6RankBoost' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'MaximumRodcRsoQueueLength' + PropertyValue = [System.UInt32] 350 + } + @{ + PropertyName = 'MaximumRodcRsoAttemptsPerCycle' + PropertyValue = [System.UInt32] 150 + } + @{ + PropertyName = 'MaxResourceRecordsInNonSecureUpdate' + PropertyValue = [System.UInt32] 40 + } + @{ + PropertyName = 'LocalNetPriorityMask' + PropertyValue = [System.UInt32] 254 + } + @{ + PropertyName = 'TcpReceivePacketSize' + PropertyValue = [System.UInt32] 65000 + } + @{ + PropertyName = 'SelfTest' + PropertyValue = [System.UInt32] 4000000000 + } + @{ + PropertyName = 'XfrThrottleMultiplier' + PropertyValue = [System.UInt32] 15 + } + @{ + PropertyName = 'SocketPoolSize' + PropertyValue = [System.UInt32] 3000 + } + @{ + PropertyName = 'QuietRecvFaultInterval' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'QuietRecvLogInterval' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'SyncDsZoneSerial' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'ScopeOptionValue' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'VirtualizationInstanceOptionValue' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'ServerLevelPluginDll' + PropertyValue = 'C:\dns\oldPlugin.dll' + } + @{ + PropertyName = 'RootTrustAnchorsURL' + PropertyValue = 'https://data.iana.org/old-root-anchors/root-anchors.xml' + } + @{ + PropertyName = 'SocketPoolExcludedPortRanges' + PropertyValue = [System.String[]] @(5353, 5454) + } + @{ + PropertyName = 'LameDelegationTTL' + PropertyValue = '00:00:01' + } + @{ + PropertyName = 'MaximumSignatureScanPeriod' + PropertyValue = '3.00:00:00' + } + @{ + PropertyName = 'MaximumTrustAnchorActiveRefreshInterval' + PropertyValue = '20.00:00:00' + } + @{ + PropertyName = 'ZoneWritebackInterval' + PropertyValue = '00:00:30' + } + ) + } - Context 'When the system is not in the desired state' { - BeforeAll { - Mock -CommandName Get-DnsServerSetting -MockWith { - return New-CimInstance -ClassName 'DnsServerSetting' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ - DnsServer = 'dns1.company.local' - LocalNetPriority = $true - RoundRobin = $true - RpcProtocol = [System.UInt32] 0 - NameCheckFlag = [System.UInt32] 2 - AutoConfigFileZones = [System.UInt32] 1 - AddressAnswerLimit = [System.UInt32] 0 - UpdateOptions = [System.UInt32] 783 - DisableAutoReverseZone = $false - StrictFileParsing = $false - EnableDirectoryPartitions = $false - XfrConnectTimeout = [System.UInt32] 30 - BootMethod = [System.UInt32] 3 - AllowUpdate = $true - LooseWildcarding = $false - BindSecondaries = $false - AutoCacheUpdate = $false - EnableDnsSec = $true - SendPort = [System.UInt32] 0 - WriteAuthorityNS = $false - ListeningIPAddress = [System.String[]] @('192.168.1.10', '192.168.2.10') - ForwardDelegations = $false - EnableIPv6 = $true - EnableOnlineSigning = $true - EnableDuplicateQuerySuppression = $true - AllowCnameAtNs = $true - EnableRsoForRodc = $true - OpenAclOnProxyUpdates = $true - NoUpdateDelegations = $false - EnableUpdateForwarding = $false - EnableWinsR = $true - DeleteOutsideGlue = $false - AppendMsZoneTransferTag = $false - AllowReadOnlyZoneTransfer = $false - EnableSendErrorSuppression = $true - SilentlyIgnoreCnameUpdateConflicts = $false - EnableIQueryResponseGeneration = $false - AdminConfigured = $true - PublishAutoNet = $false - ReloadException = $false - IgnoreServerLevelPolicies = $false - IgnoreAllPolicies = $false - EnableVersionQuery = [System.UInt32] 0 - AutoCreateDelegation = [System.UInt32] 2 - RemoteIPv4RankBoost = [System.UInt32] 5 - RemoteIPv6RankBoost = [System.UInt32] 0 - MaximumRodcRsoQueueLength = [System.UInt32] 300 - MaximumRodcRsoAttemptsPerCycle = [System.UInt32] 100 - MaxResourceRecordsInNonSecureUpdate = [System.UInt32] 30 - LocalNetPriorityMask = [System.UInt32] 255 - TcpReceivePacketSize = [System.UInt32] 65536 - SelfTest = [System.UInt32] 4294967295 - XfrThrottleMultiplier = [System.UInt32] 10 - SocketPoolSize = [System.UInt32] 2500 - QuietRecvFaultInterval = [System.UInt32] 0 - QuietRecvLogInterval = [System.UInt32] 0 - SyncDsZoneSerial = [System.UInt32] 2 - ScopeOptionValue = [System.UInt32] 0 - VirtualizationInstanceOptionValue = [System.UInt32] 0 - ServerLevelPluginDll = 'C:\dns\plugin.dll' - RootTrustAnchorsURL = 'https://data.iana.org/root-anchors/root-anchors.xml' - SocketPoolExcludedPortRanges = [System.String[]] @() - LameDelegationTTL = New-TimeSpan -Seconds 0 - MaximumSignatureScanPeriod = New-TimeSpan -Days 2 - MaximumTrustAnchorActiveRefreshInterval = New-TimeSpan -Days 15 - ZoneWritebackInterval = New-TimeSpan -Minutes 1 - } - } + It 'Should not throw and call the correct mock to set the property ' -TestCases $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'LocalNetPriority' - PropertyValue = $false - } - @{ - PropertyName = 'RoundRobin' - PropertyValue = $false - } - @{ - PropertyName = 'RpcProtocol' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'NameCheckFlag' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'AutoConfigFileZones' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'AddressAnswerLimit' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'UpdateOptions' - PropertyValue = [System.UInt32] 784 - } - @{ - PropertyName = 'DisableAutoReverseZone' - PropertyValue = $true - } - @{ - PropertyName = 'StrictFileParsing' - PropertyValue = $true - } - @{ - PropertyName = 'EnableDirectoryPartitions' - PropertyValue = $true - } - @{ - PropertyName = 'XfrConnectTimeout' - PropertyValue = [System.UInt32] 40 - } - @{ - PropertyName = 'BootMethod' - PropertyValue = [System.UInt32] 2 - } - @{ - PropertyName = 'AllowUpdate' - PropertyValue = $false - } - @{ - PropertyName = 'LooseWildcarding' - PropertyValue = $true - } - @{ - PropertyName = 'BindSecondaries' - PropertyValue = $true - } - @{ - PropertyName = 'AutoCacheUpdate' - PropertyValue = $true - } - @{ - PropertyName = 'EnableDnsSec' - PropertyValue = $false - } - @{ - PropertyName = 'SendPort' - PropertyValue = [System.UInt32] 100 - } - @{ - PropertyName = 'WriteAuthorityNS' - PropertyValue = $true - } - @{ - PropertyName = 'ForwardDelegations' - PropertyValue = $true - } - @{ - PropertyName = 'ListeningIPAddress' - PropertyValue = [System.String[]] @('fe80::e82e:70b7:f1d4:f695') - } - @{ - PropertyName = 'EnableIPv6' - PropertyValue = $false - } - @{ - PropertyName = 'EnableOnlineSigning' - PropertyValue = $false - } - @{ - PropertyName = 'EnableDuplicateQuerySuppression' - PropertyValue = $false - } - @{ - PropertyName = 'AllowCnameAtNs' - PropertyValue = $false - } - @{ - PropertyName = 'EnableRsoForRodc' - PropertyValue = $false - } - @{ - PropertyName = 'OpenAclOnProxyUpdates' - PropertyValue = $false - } - @{ - PropertyName = 'NoUpdateDelegations' - PropertyValue = $true - } - @{ - PropertyName = 'EnableUpdateForwarding' - PropertyValue = $true - } - @{ - PropertyName = 'EnableWinsR' - PropertyValue = $false - } - @{ - PropertyName = 'DeleteOutsideGlue' - PropertyValue = $true - } - @{ - PropertyName = 'AppendMsZoneTransferTag' - PropertyValue = $true - } - @{ - PropertyName = 'AllowReadOnlyZoneTransfer' - PropertyValue = $true - } - @{ - PropertyName = 'EnableSendErrorSuppression' - PropertyValue = $false - } - @{ - PropertyName = 'SilentlyIgnoreCnameUpdateConflicts' - PropertyValue = $true - } - @{ - PropertyName = 'EnableIQueryResponseGeneration' - PropertyValue = $true - } - @{ - PropertyName = 'AdminConfigured' - PropertyValue = $false - } - @{ - PropertyName = 'PublishAutoNet' - PropertyValue = $true - } - @{ - PropertyName = 'ReloadException' - PropertyValue = $true - } - @{ - PropertyName = 'IgnoreServerLevelPolicies' - PropertyValue = $true - } - @{ - PropertyName = 'IgnoreAllPolicies' - PropertyValue = $true - } - @{ - PropertyName = 'EnableVersionQuery' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'AutoCreateDelegation' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'RemoteIPv4RankBoost' - PropertyValue = [System.UInt32] 4 - } - @{ - PropertyName = 'RemoteIPv6RankBoost' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'MaximumRodcRsoQueueLength' - PropertyValue = [System.UInt32] 350 - } - @{ - PropertyName = 'MaximumRodcRsoAttemptsPerCycle' - PropertyValue = [System.UInt32] 150 - } - @{ - PropertyName = 'MaxResourceRecordsInNonSecureUpdate' - PropertyValue = [System.UInt32] 40 - } - @{ - PropertyName = 'LocalNetPriorityMask' - PropertyValue = [System.UInt32] 254 - } - @{ - PropertyName = 'TcpReceivePacketSize' - PropertyValue = [System.UInt32] 65000 - } - @{ - PropertyName = 'SelfTest' - PropertyValue = [System.UInt32] 4000000000 - } - @{ - PropertyName = 'XfrThrottleMultiplier' - PropertyValue = [System.UInt32] 15 - } - @{ - PropertyName = 'SocketPoolSize' - PropertyValue = [System.UInt32] 3000 - } - @{ - PropertyName = 'QuietRecvFaultInterval' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'QuietRecvLogInterval' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'SyncDsZoneSerial' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'ScopeOptionValue' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'VirtualizationInstanceOptionValue' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'ServerLevelPluginDll' - PropertyValue = 'C:\dns\oldPlugin.dll' - } - @{ - PropertyName = 'RootTrustAnchorsURL' - PropertyValue = 'https://data.iana.org/old-root-anchors/root-anchors.xml' - } - @{ - PropertyName = 'SocketPoolExcludedPortRanges' - PropertyValue = [System.String[]] @(5353, 5454) - } - @{ - PropertyName = 'LameDelegationTTL' - PropertyValue = '00:00:01' - } - @{ - PropertyName = 'MaximumSignatureScanPeriod' - PropertyValue = '3.00:00:00' - } - @{ - PropertyName = 'MaximumTrustAnchorActiveRefreshInterval' - PropertyValue = '20.00:00:00' - } - @{ - PropertyName = 'ZoneWritebackInterval' - PropertyValue = '00:00:30' - } - ) + $setTargetResourceParameters = @{ + DnsServer = 'dns1.company.local' + $PropertyName = $PropertyValue } - It 'Should not throw and call the correct mock to set the property ' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) - - $setTargetResourceParameters = @{ - DnsServer = 'dns1.company.local' - $PropertyName = $PropertyValue - } + { Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw + } - { Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw + Should -Invoke -CommandName Set-DnsServerSetting -Exactly -Times 1 -Scope It + } + } - Assert-MockCalled -CommandName Set-DnsServerSetting -Exactly -Times 1 -Scope It + Context 'When the system is in the desired state' { + BeforeAll { + Mock -CommandName Get-DnsServerSetting -MockWith { + return New-CimInstance -ClassName 'DnsServerSetting' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ + DnsServer = 'dns1.company.local' + LocalNetPriority = $true + RoundRobin = $true + RpcProtocol = [System.UInt32] 0 + NameCheckFlag = [System.UInt32] 2 + AutoConfigFileZones = [System.UInt32] 1 + AddressAnswerLimit = [System.UInt32] 0 + UpdateOptions = [System.UInt32] 783 + DisableAutoReverseZone = $false + StrictFileParsing = $false + EnableDirectoryPartitions = $false + XfrConnectTimeout = [System.UInt32] 30 + BootMethod = [System.UInt32] 3 + AllowUpdate = $true + LooseWildcarding = $false + BindSecondaries = $false + AutoCacheUpdate = $false + EnableDnsSec = $true + SendPort = [System.UInt32] 0 + WriteAuthorityNS = $false + ListeningIPAddress = [System.String[]] @('192.168.1.10', '192.168.2.10') + ForwardDelegations = $false + EnableIPv6 = $true + EnableOnlineSigning = $true + EnableDuplicateQuerySuppression = $true + AllowCnameAtNs = $true + EnableRsoForRodc = $true + OpenAclOnProxyUpdates = $true + NoUpdateDelegations = $false + EnableUpdateForwarding = $false + EnableWinsR = $true + DeleteOutsideGlue = $false + AppendMsZoneTransferTag = $false + AllowReadOnlyZoneTransfer = $false + EnableSendErrorSuppression = $true + SilentlyIgnoreCnameUpdateConflicts = $false + EnableIQueryResponseGeneration = $false + AdminConfigured = $true + PublishAutoNet = $false + ReloadException = $false + IgnoreServerLevelPolicies = $false + IgnoreAllPolicies = $false + EnableVersionQuery = [System.UInt32] 0 + AutoCreateDelegation = [System.UInt32] 2 + RemoteIPv4RankBoost = [System.UInt32] 5 + RemoteIPv6RankBoost = [System.UInt32] 0 + MaximumRodcRsoQueueLength = [System.UInt32] 300 + MaximumRodcRsoAttemptsPerCycle = [System.UInt32] 100 + MaxResourceRecordsInNonSecureUpdate = [System.UInt32] 30 + LocalNetPriorityMask = [System.UInt32] 255 + TcpReceivePacketSize = [System.UInt32] 65536 + SelfTest = [System.UInt32] 4294967295 + XfrThrottleMultiplier = [System.UInt32] 10 + SocketPoolSize = [System.UInt32] 2500 + QuietRecvFaultInterval = [System.UInt32] 0 + QuietRecvLogInterval = [System.UInt32] 0 + SyncDsZoneSerial = [System.UInt32] 2 + ScopeOptionValue = [System.UInt32] 0 + VirtualizationInstanceOptionValue = [System.UInt32] 0 + ServerLevelPluginDll = 'C:\dns\plugin.dll' + RootTrustAnchorsURL = 'https://data.iana.org/root-anchors/root-anchors.xml' + SocketPoolExcludedPortRanges = [System.String[]] @(5353, 5454) + LameDelegationTTL = New-TimeSpan -Seconds 0 + MaximumSignatureScanPeriod = New-TimeSpan -Days 2 + MaximumTrustAnchorActiveRefreshInterval = New-TimeSpan -Days 15 + ZoneWritebackInterval = New-TimeSpan -Minutes 1 } } + } - Context 'When the system is in the desired state' { - BeforeAll { - Mock -CommandName Get-DnsServerSetting -MockWith { - return New-CimInstance -ClassName 'DnsServerSetting' -Namespace 'root/Microsoft/Windows/DNS' -ClientOnly -Property @{ - DnsServer = 'dns1.company.local' - LocalNetPriority = $true - RoundRobin = $true - RpcProtocol = [System.UInt32] 0 - NameCheckFlag = [System.UInt32] 2 - AutoConfigFileZones = [System.UInt32] 1 - AddressAnswerLimit = [System.UInt32] 0 - UpdateOptions = [System.UInt32] 783 - DisableAutoReverseZone = $false - StrictFileParsing = $false - EnableDirectoryPartitions = $false - XfrConnectTimeout = [System.UInt32] 30 - BootMethod = [System.UInt32] 3 - AllowUpdate = $true - LooseWildcarding = $false - BindSecondaries = $false - AutoCacheUpdate = $false - EnableDnsSec = $true - SendPort = [System.UInt32] 0 - WriteAuthorityNS = $false - ListeningIPAddress = [System.String[]] @('192.168.1.10', '192.168.2.10') - ForwardDelegations = $false - EnableIPv6 = $true - EnableOnlineSigning = $true - EnableDuplicateQuerySuppression = $true - AllowCnameAtNs = $true - EnableRsoForRodc = $true - OpenAclOnProxyUpdates = $true - NoUpdateDelegations = $false - EnableUpdateForwarding = $false - EnableWinsR = $true - DeleteOutsideGlue = $false - AppendMsZoneTransferTag = $false - AllowReadOnlyZoneTransfer = $false - EnableSendErrorSuppression = $true - SilentlyIgnoreCnameUpdateConflicts = $false - EnableIQueryResponseGeneration = $false - AdminConfigured = $true - PublishAutoNet = $false - ReloadException = $false - IgnoreServerLevelPolicies = $false - IgnoreAllPolicies = $false - EnableVersionQuery = [System.UInt32] 0 - AutoCreateDelegation = [System.UInt32] 2 - RemoteIPv4RankBoost = [System.UInt32] 5 - RemoteIPv6RankBoost = [System.UInt32] 0 - MaximumRodcRsoQueueLength = [System.UInt32] 300 - MaximumRodcRsoAttemptsPerCycle = [System.UInt32] 100 - MaxResourceRecordsInNonSecureUpdate = [System.UInt32] 30 - LocalNetPriorityMask = [System.UInt32] 255 - TcpReceivePacketSize = [System.UInt32] 65536 - SelfTest = [System.UInt32] 4294967295 - XfrThrottleMultiplier = [System.UInt32] 10 - SocketPoolSize = [System.UInt32] 2500 - QuietRecvFaultInterval = [System.UInt32] 0 - QuietRecvLogInterval = [System.UInt32] 0 - SyncDsZoneSerial = [System.UInt32] 2 - ScopeOptionValue = [System.UInt32] 0 - VirtualizationInstanceOptionValue = [System.UInt32] 0 - ServerLevelPluginDll = 'C:\dns\plugin.dll' - RootTrustAnchorsURL = 'https://data.iana.org/root-anchors/root-anchors.xml' - SocketPoolExcludedPortRanges = [System.String[]] @(5353, 5454) - LameDelegationTTL = New-TimeSpan -Seconds 0 - MaximumSignatureScanPeriod = New-TimeSpan -Days 2 - MaximumTrustAnchorActiveRefreshInterval = New-TimeSpan -Days 15 - ZoneWritebackInterval = New-TimeSpan -Minutes 1 - } - } + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'LocalNetPriority' + PropertyValue = $true + } + @{ + PropertyName = 'RoundRobin' + PropertyValue = $true + } + @{ + PropertyName = 'RpcProtocol' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'NameCheckFlag' + PropertyValue = [System.UInt32] 2 + } + @{ + PropertyName = 'AutoConfigFileZones' + PropertyValue = [System.UInt32] 1 + } + @{ + PropertyName = 'AddressAnswerLimit' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'UpdateOptions' + PropertyValue = [System.UInt32] 783 + } + @{ + PropertyName = 'DisableAutoReverseZone' + PropertyValue = $false + } + @{ + PropertyName = 'StrictFileParsing' + PropertyValue = $false + } + @{ + PropertyName = 'EnableDirectoryPartitions' + PropertyValue = $false + } + @{ + PropertyName = 'XfrConnectTimeout' + PropertyValue = [System.UInt32] 30 + } + @{ + PropertyName = 'BootMethod' + PropertyValue = [System.UInt32] 3 + } + @{ + PropertyName = 'AllowUpdate' + PropertyValue = $true + } + @{ + PropertyName = 'LooseWildcarding' + PropertyValue = $false + } + @{ + PropertyName = 'BindSecondaries' + PropertyValue = $false + } + @{ + PropertyName = 'AutoCacheUpdate' + PropertyValue = $false + } + @{ + PropertyName = 'EnableDnsSec' + PropertyValue = $true + } + @{ + PropertyName = 'SendPort' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'WriteAuthorityNS' + PropertyValue = $false + } + @{ + PropertyName = 'ForwardDelegations' + PropertyValue = $false + } + @{ + PropertyName = 'ListeningIPAddress' + PropertyValue = [System.String[]] @('192.168.1.10', '192.168.2.10') + } + @{ + PropertyName = 'EnableIPv6' + PropertyValue = $true + } + @{ + PropertyName = 'EnableOnlineSigning' + PropertyValue = $true + } + @{ + PropertyName = 'EnableDuplicateQuerySuppression' + PropertyValue = $true + } + @{ + PropertyName = 'AllowCnameAtNs' + PropertyValue = $true + } + @{ + PropertyName = 'EnableRsoForRodc' + PropertyValue = $true + } + @{ + PropertyName = 'OpenAclOnProxyUpdates' + PropertyValue = $true + } + @{ + PropertyName = 'NoUpdateDelegations' + PropertyValue = $false + } + @{ + PropertyName = 'EnableUpdateForwarding' + PropertyValue = $false + } + @{ + PropertyName = 'EnableWinsR' + PropertyValue = $true + } + @{ + PropertyName = 'DeleteOutsideGlue' + PropertyValue = $false + } + @{ + PropertyName = 'AppendMsZoneTransferTag' + PropertyValue = $false + } + @{ + PropertyName = 'AllowReadOnlyZoneTransfer' + PropertyValue = $false + } + @{ + PropertyName = 'EnableSendErrorSuppression' + PropertyValue = $true + } + @{ + PropertyName = 'SilentlyIgnoreCnameUpdateConflicts' + PropertyValue = $false + } + @{ + PropertyName = 'EnableIQueryResponseGeneration' + PropertyValue = $false + } + @{ + PropertyName = 'AdminConfigured' + PropertyValue = $true + } + @{ + PropertyName = 'PublishAutoNet' + PropertyValue = $false + } + @{ + PropertyName = 'ReloadException' + PropertyValue = $false + } + @{ + PropertyName = 'IgnoreServerLevelPolicies' + PropertyValue = $false + } + @{ + PropertyName = 'IgnoreAllPolicies' + PropertyValue = $false + } + @{ + PropertyName = 'EnableVersionQuery' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'AutoCreateDelegation' + PropertyValue = [System.UInt32] 2 + } + @{ + PropertyName = 'RemoteIPv4RankBoost' + PropertyValue = [System.UInt32] 5 + } + @{ + PropertyName = 'RemoteIPv6RankBoost' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'MaximumRodcRsoQueueLength' + PropertyValue = [System.UInt32] 300 + } + @{ + PropertyName = 'MaximumRodcRsoAttemptsPerCycle' + PropertyValue = [System.UInt32] 100 + } + @{ + PropertyName = 'MaxResourceRecordsInNonSecureUpdate' + PropertyValue = [System.UInt32] 30 + } + @{ + PropertyName = 'LocalNetPriorityMask' + PropertyValue = [System.UInt32] 255 + } + @{ + PropertyName = 'TcpReceivePacketSize' + PropertyValue = [System.UInt32] 65536 + } + @{ + PropertyName = 'SelfTest' + PropertyValue = [System.UInt32] 4294967295 + } + @{ + PropertyName = 'XfrThrottleMultiplier' + PropertyValue = [System.UInt32] 10 + } + @{ + PropertyName = 'SocketPoolSize' + PropertyValue = [System.UInt32] 2500 + } + @{ + PropertyName = 'QuietRecvFaultInterval' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'QuietRecvLogInterval' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'SyncDsZoneSerial' + PropertyValue = [System.UInt32] 2 + } + @{ + PropertyName = 'ScopeOptionValue' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'VirtualizationInstanceOptionValue' + PropertyValue = [System.UInt32] 0 + } + @{ + PropertyName = 'ServerLevelPluginDll' + PropertyValue = 'C:\dns\plugin.dll' + } + @{ + PropertyName = 'RootTrustAnchorsURL' + PropertyValue = 'https://data.iana.org/root-anchors/root-anchors.xml' + } + @{ + PropertyName = 'SocketPoolExcludedPortRanges' + PropertyValue = [System.String[]] @(5353, 5454) + } + @{ + PropertyName = 'LameDelegationTTL' + PropertyValue = '00:00:00' + } + @{ + PropertyName = 'MaximumSignatureScanPeriod' + PropertyValue = '2.00:00:00' + } + @{ + PropertyName = 'MaximumTrustAnchorActiveRefreshInterval' + PropertyValue = '15.00:00:00' + } + @{ + PropertyName = 'ZoneWritebackInterval' + PropertyValue = '00:01:00' + } + ) + } + It 'Should not throw and should not set the property ' -ForEach $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $testCases = @( - @{ - PropertyName = 'LocalNetPriority' - PropertyValue = $true - } - @{ - PropertyName = 'RoundRobin' - PropertyValue = $true - } - @{ - PropertyName = 'RpcProtocol' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'NameCheckFlag' - PropertyValue = [System.UInt32] 2 - } - @{ - PropertyName = 'AutoConfigFileZones' - PropertyValue = [System.UInt32] 1 - } - @{ - PropertyName = 'AddressAnswerLimit' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'UpdateOptions' - PropertyValue = [System.UInt32] 783 - } - @{ - PropertyName = 'DisableAutoReverseZone' - PropertyValue = $false - } - @{ - PropertyName = 'StrictFileParsing' - PropertyValue = $false - } - @{ - PropertyName = 'EnableDirectoryPartitions' - PropertyValue = $false - } - @{ - PropertyName = 'XfrConnectTimeout' - PropertyValue = [System.UInt32] 30 - } - @{ - PropertyName = 'BootMethod' - PropertyValue = [System.UInt32] 3 - } - @{ - PropertyName = 'AllowUpdate' - PropertyValue = $true - } - @{ - PropertyName = 'LooseWildcarding' - PropertyValue = $false - } - @{ - PropertyName = 'BindSecondaries' - PropertyValue = $false - } - @{ - PropertyName = 'AutoCacheUpdate' - PropertyValue = $false - } - @{ - PropertyName = 'EnableDnsSec' - PropertyValue = $true - } - @{ - PropertyName = 'SendPort' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'WriteAuthorityNS' - PropertyValue = $false - } - @{ - PropertyName = 'ForwardDelegations' - PropertyValue = $false - } - @{ - PropertyName = 'ListeningIPAddress' - PropertyValue = [System.String[]] @('192.168.1.10', '192.168.2.10') - } - @{ - PropertyName = 'EnableIPv6' - PropertyValue = $true - } - @{ - PropertyName = 'EnableOnlineSigning' - PropertyValue = $true - } - @{ - PropertyName = 'EnableDuplicateQuerySuppression' - PropertyValue = $true - } - @{ - PropertyName = 'AllowCnameAtNs' - PropertyValue = $true - } - @{ - PropertyName = 'EnableRsoForRodc' - PropertyValue = $true - } - @{ - PropertyName = 'OpenAclOnProxyUpdates' - PropertyValue = $true - } - @{ - PropertyName = 'NoUpdateDelegations' - PropertyValue = $false - } - @{ - PropertyName = 'EnableUpdateForwarding' - PropertyValue = $false - } - @{ - PropertyName = 'EnableWinsR' - PropertyValue = $true - } - @{ - PropertyName = 'DeleteOutsideGlue' - PropertyValue = $false - } - @{ - PropertyName = 'AppendMsZoneTransferTag' - PropertyValue = $false - } - @{ - PropertyName = 'AllowReadOnlyZoneTransfer' - PropertyValue = $false - } - @{ - PropertyName = 'EnableSendErrorSuppression' - PropertyValue = $true - } - @{ - PropertyName = 'SilentlyIgnoreCnameUpdateConflicts' - PropertyValue = $false - } - @{ - PropertyName = 'EnableIQueryResponseGeneration' - PropertyValue = $false - } - @{ - PropertyName = 'AdminConfigured' - PropertyValue = $true - } - @{ - PropertyName = 'PublishAutoNet' - PropertyValue = $false - } - @{ - PropertyName = 'ReloadException' - PropertyValue = $false - } - @{ - PropertyName = 'IgnoreServerLevelPolicies' - PropertyValue = $false - } - @{ - PropertyName = 'IgnoreAllPolicies' - PropertyValue = $false - } - @{ - PropertyName = 'EnableVersionQuery' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'AutoCreateDelegation' - PropertyValue = [System.UInt32] 2 - } - @{ - PropertyName = 'RemoteIPv4RankBoost' - PropertyValue = [System.UInt32] 5 - } - @{ - PropertyName = 'RemoteIPv6RankBoost' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'MaximumRodcRsoQueueLength' - PropertyValue = [System.UInt32] 300 - } - @{ - PropertyName = 'MaximumRodcRsoAttemptsPerCycle' - PropertyValue = [System.UInt32] 100 - } - @{ - PropertyName = 'MaxResourceRecordsInNonSecureUpdate' - PropertyValue = [System.UInt32] 30 - } - @{ - PropertyName = 'LocalNetPriorityMask' - PropertyValue = [System.UInt32] 255 - } - @{ - PropertyName = 'TcpReceivePacketSize' - PropertyValue = [System.UInt32] 65536 - } - @{ - PropertyName = 'SelfTest' - PropertyValue = [System.UInt32] 4294967295 - } - @{ - PropertyName = 'XfrThrottleMultiplier' - PropertyValue = [System.UInt32] 10 - } - @{ - PropertyName = 'SocketPoolSize' - PropertyValue = [System.UInt32] 2500 - } - @{ - PropertyName = 'QuietRecvFaultInterval' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'QuietRecvLogInterval' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'SyncDsZoneSerial' - PropertyValue = [System.UInt32] 2 - } - @{ - PropertyName = 'ScopeOptionValue' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'VirtualizationInstanceOptionValue' - PropertyValue = [System.UInt32] 0 - } - @{ - PropertyName = 'ServerLevelPluginDll' - PropertyValue = 'C:\dns\plugin.dll' - } - @{ - PropertyName = 'RootTrustAnchorsURL' - PropertyValue = 'https://data.iana.org/root-anchors/root-anchors.xml' - } - @{ - PropertyName = 'SocketPoolExcludedPortRanges' - PropertyValue = [System.String[]] @(5353, 5454) - } - @{ - PropertyName = 'LameDelegationTTL' - PropertyValue = '00:00:00' - } - @{ - PropertyName = 'MaximumSignatureScanPeriod' - PropertyValue = '2.00:00:00' - } - @{ - PropertyName = 'MaximumTrustAnchorActiveRefreshInterval' - PropertyValue = '15.00:00:00' - } - @{ - PropertyName = 'ZoneWritebackInterval' - PropertyValue = '00:01:00' - } - ) + $setTargetResourceParameters = @{ + DnsServer = 'dns1.company.local' + $PropertyName = $PropertyValue } - It 'Should not throw and should not set the property ' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + { Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw + } + + Should -Invoke -CommandName Set-DnsServerSetting -Exactly -Times 0 -Scope It + } + + Context 'When invalid time property is provided' { + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'LameDelegationTTL' + PropertyValue = 'a00:00:00' + } + @{ + PropertyName = 'MaximumSignatureScanPeriod' + PropertyValue = 'b2.00:00:00' + } + @{ + PropertyName = 'MaximumTrustAnchorActiveRefreshInterval' + PropertyValue = 'c15.00:00:00' + } + @{ + PropertyName = 'ZoneWritebackInterval' + PropertyValue = 'd00:01:00' + } + ) + } + + It 'Should throw and exception for ' -ForEach $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 $setTargetResourceParameters = @{ DnsServer = 'dns1.company.local' $PropertyName = $PropertyValue } - { Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw + $errorMessage = $script:localizedData.UnableToParseTimeSpan -f $PropertyValue, $PropertyName - Assert-MockCalled -CommandName Set-DnsServerSetting -Exactly -Times 0 -Scope It + { Set-TargetResource @setTargetResourceParameters } | Should -Throw -ExpectedMessage ('*' + $errorMessage) } } } } } -finally -{ - Invoke-TestCleanup -} diff --git a/tests/Unit/DSC_DnsServerSettingLegacy.Tests.ps1 b/tests/Unit/DSC_DnsServerSettingLegacy.Tests.ps1 index 2541e9d1..94865dcd 100644 --- a/tests/Unit/DSC_DnsServerSettingLegacy.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerSettingLegacy.Tests.ps1 @@ -1,16 +1,37 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerSettingLegacy' +<# + .SYNOPSIS + Unit test for DSC_DnsServerSettingLegacy DSC resource. +#> -function Invoke-TestSetup -{ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerSettingLegacy' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,263 +40,271 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} -Invoke-TestSetup - -try -{ - InModuleScope $script:dscResourceName { - Describe 'DSC_DnsServerSettingLegacy\Get-TargetResource' -Tag 'Get' { - BeforeAll { - Mock -CommandName Assert-Module - Mock -CommandName Get-CimClassMicrosoftDnsServer -MockWith { - return @{ - DnsServer = 'dns1.company.local' - DisjointNets = $false - NoForwarderRecursion = $false - LogLevel = [System.UInt32] 0 - } - } - } + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force - Context 'When the system is in the desired state' { - It "Should return the correct values for each property" { - $getTargetResourceResult = Get-TargetResource -DnsServer 'dns1.company.local' + Remove-Module -Name DnsServer -Force +} - $getTargetResourceResult.DisjointNets | Should -BeFalse - $getTargetResourceResult.NoForwarderRecursion | Should -BeFalse - $getTargetResourceResult.LogLevel | Should -Be 0 - } +Describe 'DSC_DnsServerSettingLegacy\Get-TargetResource' -Tag 'Get' { + BeforeAll { + Mock -CommandName Assert-Module + Mock -CommandName Get-CimClassMicrosoftDnsServer -MockWith { + return @{ + DnsServer = 'dns1.company.local' + DisjointNets = $false + NoForwarderRecursion = $false + LogLevel = [System.UInt32] 0 } } + } - Describe 'DSC_DnsServerSettingLegacy\Test-TargetResource' -Tag 'Test' { - BeforeAll { - Mock -CommandName Assert-Module - } + Context 'When the system is in the desired state' { + It 'Should return the correct values for each property' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When the system is not in the desired state' { - BeforeAll { - Mock -CommandName Get-TargetResource -MockWith { - return @{ - DnsServer = 'dns1.company.local' - DisjointNets = $true - NoForwarderRecursion = $true - LogLevel = [System.UInt32] 5 - } - } - - $testCases = @( - @{ - PropertyName = 'DisjointNets' - PropertyValue = $false - } - @{ - PropertyName = 'NoForwarderRecursion' - PropertyValue = $false - } - @{ - PropertyName = 'LogLevel' - PropertyValue = [System.UInt32] 0 - } - ) - } + $getTargetResourceResult = Get-TargetResource -DnsServer 'dns1.company.local' - It 'Should return $false for property ' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + $getTargetResourceResult.DisjointNets | Should -BeFalse + $getTargetResourceResult.NoForwarderRecursion | Should -BeFalse + $getTargetResourceResult.LogLevel | Should -Be 0 + } + } + } +} - $testTargetResourceParameters = @{ - DnsServer = 'dns1.company.local' - $PropertyName = $PropertyValue - } +Describe 'DSC_DnsServerSettingLegacy\Test-TargetResource' -Tag 'Test' { + BeforeAll { + Mock -CommandName Assert-Module + } - Test-TargetResource @testTargetResourceParameters | Should -BeFalse + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { + return @{ + DnsServer = 'dns1.company.local' + DisjointNets = $true + NoForwarderRecursion = $true + LogLevel = [System.UInt32] 5 } } + } - Context 'When the system is in the desired state' { - BeforeAll { - Mock -CommandName Get-TargetResource -MockWith { - return @{ - DnsServer = 'dns1.company.local' - DisjointNets = $true - NoForwarderRecursion = $true - LogLevel = [System.UInt32] 5 - } - } - - $testCases = @( - @{ - PropertyName = 'DisjointNets' - PropertyValue = $true - } - @{ - PropertyName = 'NoForwarderRecursion' - PropertyValue = $true - } - @{ - PropertyName = 'LogLevel' - PropertyValue = [System.UInt32] 5 - } - ) + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'DisjointNets' + PropertyValue = $false } + @{ + PropertyName = 'NoForwarderRecursion' + PropertyValue = $false + } + @{ + PropertyName = 'LogLevel' + PropertyValue = [System.UInt32] 0 + } + ) + } - It 'Should return $true for property ' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) - - $testTargetResourceParameters = @{ - DnsServer = 'dns1.company.local' - $PropertyName = $PropertyValue - } + It 'Should return $false for property ' -TestCases $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - Test-TargetResource @testTargetResourceParameters | Should -BeTrue + $testTargetResourceParameters = @{ + DnsServer = 'dns1.company.local' + $PropertyName = $PropertyValue } + + Test-TargetResource @testTargetResourceParameters | Should -BeFalse } } + } - Describe 'DSC_DnsServerSettingLegacy\Set-TargetResource' -Tag 'Set' { - BeforeAll { - Mock -CommandName Assert-Module - Mock -CommandName Set-CimInstance - Mock -CommandName Get-CimClassMicrosoftDnsServer -MockWith { - return New-CimInstance -ClassName 'MicrosoftDNS_Server' -Namespace 'root\MicrosoftDNS' -ClientOnly -Property @{ - DisjointNets = $false - NoForwarderRecursion = $false - LogLevel = [System.UInt32] 0 - } + Context 'When the system is in the desired state' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { + return @{ + DnsServer = 'dns1.company.local' + DisjointNets = $true + NoForwarderRecursion = $true + LogLevel = [System.UInt32] 5 } } + } - Context 'When the system is not in the desired state' { - BeforeAll { - Mock -CommandName Get-TargetResource -MockWith { - return @{ - DnsServer = 'dns1.company.local' - DisjointNets = $true - NoForwarderRecursion = $true - LogLevel = [System.UInt32] 5 - } - } - - $testCases = @( - @{ - PropertyName = 'DisjointNets' - PropertyValue = $false - } - @{ - PropertyName = 'NoForwarderRecursion' - PropertyValue = $false - } - @{ - PropertyName = 'LogLevel' - PropertyValue = [System.UInt32] 0 - } - ) + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'DisjointNets' + PropertyValue = $true } + @{ + PropertyName = 'NoForwarderRecursion' + PropertyValue = $true + } + @{ + PropertyName = 'LogLevel' + PropertyValue = [System.UInt32] 5 + } + ) + } - It 'Should not throw and call the correct mock to set the property ' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + It 'Should return $true for property ' -TestCases $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $setTargetResourceParameters = @{ - DnsServer = 'dns1.company.local' - $PropertyName = $PropertyValue - } + $testTargetResourceParameters = @{ + DnsServer = 'dns1.company.local' + $PropertyName = $PropertyValue + } - { Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw + Test-TargetResource @testTargetResourceParameters | Should -BeTrue + } + } + } +} + +Describe 'DSC_DnsServerSettingLegacy\Set-TargetResource' -Tag 'Set' { + BeforeAll { + Mock -CommandName Assert-Module + Mock -CommandName Set-CimInstance + Mock -CommandName Get-CimClassMicrosoftDnsServer -MockWith { + return New-CimInstance -ClassName 'MicrosoftDNS_Server' -Namespace 'root\MicrosoftDNS' -ClientOnly -Property @{ + DisjointNets = $false + NoForwarderRecursion = $false + LogLevel = [System.UInt32] 0 + } + } + } - Assert-MockCalled -CommandName Set-CimInstance -Exactly -Times 1 -Scope It + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { + return @{ + DnsServer = 'dns1.company.local' + DisjointNets = $true + NoForwarderRecursion = $true + LogLevel = [System.UInt32] 5 } } + } - Context 'When the system is in the desired state' { - BeforeAll { - Mock -CommandName Get-TargetResource -MockWith { - return @{ - DnsServer = 'dns1.company.local' - DisjointNets = $true - NoForwarderRecursion = $true - LogLevel = [System.UInt32] 5 - } - } - - $testCases = @( - @{ - PropertyName = 'DisjointNets' - PropertyValue = $true - } - @{ - PropertyName = 'NoForwarderRecursion' - PropertyValue = $true - } - @{ - PropertyName = 'LogLevel' - PropertyValue = [System.UInt32] 5 - } - ) + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'DisjointNets' + PropertyValue = $false + } + @{ + PropertyName = 'NoForwarderRecursion' + PropertyValue = $false } + @{ + PropertyName = 'LogLevel' + PropertyValue = [System.UInt32] 0 + } + ) + } + It 'Should not throw and call the correct mock to set the property ' -TestCases $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should not throw and should not set the property ' -TestCases $testCases { - param - ( - $PropertyName, - $PropertyValue - ) + $setTargetResourceParameters = @{ + DnsServer = 'dns1.company.local' + $PropertyName = $PropertyValue + } - $setTargetResourceParameters = @{ - DnsServer = 'dns1.company.local' - $PropertyName = $PropertyValue - } + { Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw + } - { Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw + Should -Invoke -CommandName Set-CimInstance -Exactly -Times 1 -Scope It + } + } - Assert-MockCalled -CommandName Set-CimInstance -Exactly -Times 0 -Scope It + Context 'When the system is in the desired state' { + BeforeAll { + Mock -CommandName Get-TargetResource -MockWith { + return @{ + DnsServer = 'dns1.company.local' + DisjointNets = $true + NoForwarderRecursion = $true + LogLevel = [System.UInt32] 5 } } } - Describe 'DSC_DnsServerSettingLegacy\Get-CimClassMicrosoftDnsServer' -Tag 'Helper' { - BeforeAll { - Mock -CommandName Get-CimInstance -MockWith { - return New-CimInstance -ClassName 'MicrosoftDNS_Server' -Namespace 'root\MicrosoftDNS' -ClientOnly -Property @{ - DisjointNets = $false - NoForwarderRecursion = $false - LogLevel = [System.UInt32] 0 - } + BeforeDiscovery { + $testCases = @( + @{ + PropertyName = 'DisjointNets' + PropertyValue = $true } - } + @{ + PropertyName = 'NoForwarderRecursion' + PropertyValue = $true + } + @{ + PropertyName = 'LogLevel' + PropertyValue = [System.UInt32] 5 + } + ) + } - Context 'When the system is not in the desired state' { - It 'Should return the correct object' { - $getCimClassMicrosoftDnsServerResult = Get-CimClassMicrosoftDnsServer -DnsServer 'dns1.company.local' + It 'Should not throw and should not set the property ' -TestCases $testCases { + InModuleScope -Parameters $_ -ScriptBlock { + Set-StrictMode -Version 1.0 - $getCimClassMicrosoftDnsServerResult | Should -BeOfType [Microsoft.Management.Infrastructure.CimInstance] - $getCimClassMicrosoftDnsServerResult.DisjointNets | Should -BeFalse - $getCimClassMicrosoftDnsServerResult.NoForwarderRecursion | Should -BeFalse - $getCimClassMicrosoftDnsServerResult.LogLevel | Should -Be 0 + $setTargetResourceParameters = @{ + DnsServer = 'dns1.company.local' + $PropertyName = $PropertyValue } + + { Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw } + + Should -Invoke -CommandName Set-CimInstance -Exactly -Times 0 -Scope It } } } -finally -{ - Invoke-TestCleanup + +Describe 'DSC_DnsServerSettingLegacy\Get-CimClassMicrosoftDnsServer' -Tag 'Helper' { + BeforeAll { + Mock -CommandName Get-CimInstance -MockWith { + return New-CimInstance -ClassName 'MicrosoftDNS_Server' -Namespace 'root\MicrosoftDNS' -ClientOnly -Property @{ + DisjointNets = $false + NoForwarderRecursion = $false + LogLevel = [System.UInt32] 0 + } + } + } + + Context 'When the system is not in the desired state' { + It 'Should return the correct object' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $getCimClassMicrosoftDnsServerResult = Get-CimClassMicrosoftDnsServer -DnsServer 'dns1.company.local' + + $getCimClassMicrosoftDnsServerResult | Should -BeOfType [Microsoft.Management.Infrastructure.CimInstance] + $getCimClassMicrosoftDnsServerResult.DisjointNets | Should -BeFalse + $getCimClassMicrosoftDnsServerResult.NoForwarderRecursion | Should -BeFalse + $getCimClassMicrosoftDnsServerResult.LogLevel | Should -Be 0 + } + } + } } diff --git a/tests/Unit/DSC_DnsServerZoneAging.Tests.ps1 b/tests/Unit/DSC_DnsServerZoneAging.Tests.ps1 index d74690cc..fcaaa380 100644 --- a/tests/Unit/DSC_DnsServerZoneAging.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerZoneAging.Tests.ps1 @@ -1,16 +1,37 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerZoneAging' +<# + .SYNOPSIS + Unit test for DSC_DnsServerZoneAging DSC resource. +#> -function Invoke-TestSetup -{ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerZoneAging' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,234 +40,377 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} -Invoke-TestSetup + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force -try -{ - InModuleScope $script:dscResourceName { - #region Pester Test Initialization - $zoneName = 'contoso.com' + Remove-Module -Name DnsServer -Force +} - $getParameterEnable = @{ - Name = $zoneName - Enabled = $true - Verbose = $true - } +Describe 'DSC_DnsServerZoneAging\Get-TargetResource' { + BeforeAll { + $zoneName = 'get.contoso.com' + } - $getParameterDisable = @{ - Name = $zoneName - Enabled = $false - Verbose = $true - } + Context 'When zone aging is enabled' { + BeforeAll { + $fakeDnsServerZoneAgingEnabled = @{ + ZoneName = $zoneName + AgingEnabled = $true + RefreshInterval = [System.TimeSpan]::FromHours(168) + NoRefreshInterval = [System.TimeSpan]::FromHours(168) + } - $testParameterEnable = @{ - Name = $zoneName - Enabled = $true - RefreshInterval = 168 - NoRefreshInterval = 168 - Verbose = $true + Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingEnabled } } - $testParameterDisable = @{ - Name = $zoneName - Enabled = $false - RefreshInterval = 168 - NoRefreshInterval = 168 - Verbose = $true - } + It 'Should return a "System.Collections.Hashtable" object type' { + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 - $setParameterEnable = @{ - Name = $zoneName - Enabled = $true - Verbose = $true - } + $getParameterDisable = @{ + Name = $zoneName + Enabled = $false + Verbose = $false + } - $setParameterDisable = @{ - Name = $zoneName - Enabled = $false - Verbose = $true + Get-TargetResource @getParameterDisable | Should -BeOfType [System.Collections.Hashtable] + } } - $setParameterRefreshInterval = @{ - Name = $zoneName - Enabled = $true - RefreshInterval = 24 - Verbose = $true - } + It 'Should return valid values when aging is enabled' { + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 - $setParameterNoRefreshInterval = @{ - Name = $zoneName - Enabled = $true - NoRefreshInterval = 36 - Verbose = $true - } + $getParameterEnable = @{ + Name = $zoneName + Enabled = $true + Verbose = $false + } - $setFilterEnable = { - $Name -eq $zoneName -and - $Aging -eq $true - } + $testParameterEnable = @{ + Name = $zoneName + Enabled = $true + RefreshInterval = 168 + NoRefreshInterval = 168 + Verbose = $false + } - $setFilterDisable = { - $Name -eq $zoneName -and - $Aging -eq $false - } + $targetResource = Get-TargetResource @getParameterEnable - $setFilterRefreshInterval = { - $Name -eq $zoneName -and - $RefreshInterval -eq ([System.TimeSpan]::FromHours(24)) - } - $setFilterNoRefreshInterval = { - $Name -eq $zoneName -and - $NoRefreshInterval -eq ([System.TimeSpan]::FromHours(36)) + $targetResource.Name | Should -Be $testParameterEnable.Name + $targetResource.Enabled | Should -Be $testParameterEnable.Enabled + $targetResource.RefreshInterval | Should -Be $testParameterEnable.RefreshInterval + $targetResource.NoRefreshInterval | Should -Be $testParameterEnable.NoRefreshInterval + } } + } - $fakeDnsServerZoneAgingEnabled = @{ - ZoneName = $zoneName - AgingEnabled = $true - RefreshInterval = [System.TimeSpan]::FromHours(168) - NoRefreshInterval = [System.TimeSpan]::FromHours(168) - } + Context 'When zone aging is disabled' { + BeforeAll { + $fakeDnsServerZoneAgingDisabled = @{ + ZoneName = $zoneName + AgingEnabled = $false + RefreshInterval = [System.TimeSpan]::FromHours(168) + NoRefreshInterval = [System.TimeSpan]::FromHours(168) + } - $fakeDnsServerZoneAgingDisabled = @{ - ZoneName = $zoneName - AgingEnabled = $false - RefreshInterval = [System.TimeSpan]::FromHours(168) - NoRefreshInterval = [System.TimeSpan]::FromHours(168) + Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingDisabled } } - #endregion - #region Function Get-TargetResource - Describe 'DSC_DnsServerZoneAging\Get-TargetResource' { - Context "The zone aging on $zoneName is enabled" { - Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingEnabled } + It 'Should return valid values when aging is not enabled' { + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Should return a "System.Collections.Hashtable" object type' { - $targetResource = Get-TargetResource @getParameterDisable + $getParameterDisable = @{ + Name = $zoneName + Enabled = $false + Verbose = $false + } - $targetResource | Should BeOfType [System.Collections.Hashtable] + $testParameterDisable = @{ + Name = $zoneName + Enabled = $false + RefreshInterval = 168 + NoRefreshInterval = 168 + Verbose = $false } - It 'Should return valid values when aging is enabled' { - $targetResource = Get-TargetResource @getParameterEnable + $targetResource = Get-TargetResource @getParameterDisable - $targetResource.Name | Should Be $testParameterEnable.Name - $targetResource.Enabled | Should Be $testParameterEnable.Enabled - $targetResource.RefreshInterval | Should Be $testParameterEnable.RefreshInterval - $targetResource.NoRefreshInterval | Should Be $testParameterEnable.NoRefreshInterval - } + $targetResource.Name | Should -Be $testParameterDisable.Name + $targetResource.Enabled | Should -Be $testParameterDisable.Enabled + $targetResource.RefreshInterval | Should -Be $testParameterDisable.RefreshInterval + $targetResource.NoRefreshInterval | Should -Be $testParameterDisable.NoRefreshInterval } + } + } +} - Context "The zone aging on $zoneName is disabled" { +Describe 'DSC_DnsServerZoneAging\Test-TargetResource' { + BeforeAll { + $zoneName = 'test.contoso.com' + } - Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingDisabled } + Context 'When zone aging is enabled' { + BeforeAll { + $fakeDnsServerZoneAgingEnabled = @{ + ZoneName = $zoneName + AgingEnabled = $true + RefreshInterval = [System.TimeSpan]::FromHours(168) + NoRefreshInterval = [System.TimeSpan]::FromHours(168) + } - It 'Should return valid values when aging is not enabled' { - $targetResource = Get-TargetResource @getParameterDisable + Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingEnabled } + } - $targetResource.Name | Should Be $testParameterDisable.Name - $targetResource.Enabled | Should Be $testParameterDisable.Enabled - $targetResource.RefreshInterval | Should Be $testParameterDisable.RefreshInterval - $targetResource.NoRefreshInterval | Should Be $testParameterDisable.NoRefreshInterval + It 'Should return a "System.Boolean" object type' { + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParameterDisable = @{ + Name = $zoneName + Enabled = $false + RefreshInterval = 168 + NoRefreshInterval = 168 + Verbose = $false } + + Test-TargetResource @testParameterDisable | Should -BeOfType [System.Boolean] } } - #endregion - - #region Function Test-TargetResource - Describe 'DSC_DnsServerZoneAging\Test-TargetResource' { - Context "The zone aging on $zoneName is enabled" { - Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingEnabled } - It 'Should return a "System.Boolean" object type' { - $targetResource = Test-TargetResource @testParameterDisable - - $targetResource | Should BeOfType [System.Boolean] + It 'Should pass when everything matches (enabled)' { + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParameterEnable = @{ + Name = $zoneName + Enabled = $true + RefreshInterval = 168 + NoRefreshInterval = 168 + Verbose = $false } - It 'Should pass when everything matches (enabled)' { - $targetResource = Test-TargetResource @testParameterEnable + Test-TargetResource @testParameterEnable | Should -BeTrue + } + } - $targetResource | Should Be $true + It 'Should fail when everything matches (enabled)' { + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParameterDisable = @{ + Name = $zoneName + Enabled = $false + RefreshInterval = 168 + NoRefreshInterval = 168 + Verbose = $false } - It 'Should fail when everything matches (enabled)' { - $targetResource = Test-TargetResource @testParameterDisable - - $targetResource | Should Be $false - } + Test-TargetResource @testParameterDisable | Should -BeFalse } + } + } - Context "The zone aging on $zoneName is disabled" { - Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingDisabled } + Context 'When zone aging is disabled' { + BeforeAll { + $fakeDnsServerZoneAgingDisabled = @{ + ZoneName = $zoneName + AgingEnabled = $false + RefreshInterval = [System.TimeSpan]::FromHours(168) + NoRefreshInterval = [System.TimeSpan]::FromHours(168) + } - It 'Should pass when everything matches (disabled)' { - $targetResource = Test-TargetResource @testParameterDisable + Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingDisabled } + } - $targetResource | Should Be $true + It 'Should pass when everything matches (disabled)' { + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParameterDisable = @{ + Name = $zoneName + Enabled = $false + RefreshInterval = 168 + NoRefreshInterval = 168 + Verbose = $false } - It 'Should fail when everything matches (disabled)' { - $targetResource = Test-TargetResource @testParameterEnable + Test-TargetResource @testParameterDisable | Should -BeTrue + } + } - $targetResource | Should Be $false + It 'Should fail when everything matches (disabled)' { + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $testParameterEnable = @{ + Name = $zoneName + Enabled = $true + RefreshInterval = 168 + NoRefreshInterval = 168 + Verbose = $false } + + Test-TargetResource @testParameterEnable | Should -BeFalse } } - #endregion + } +} - #region Function Set-TargetResource - Describe 'DSC_DnsServerZoneAging\Set-TargetResource' { - Context "The zone aging on $zoneName is enabled" { - Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingEnabled } +Describe 'DSC_DnsServerZoneAging\Set-TargetResource' { + BeforeAll { + $zoneName = 'set.contoso.com' + } - It 'Should disable the DNS zone aging' { - Mock -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterDisable -Verifiable + Context 'When zone aging is enabled' { + BeforeAll { + $fakeDnsServerZoneAgingEnabled = @{ + ZoneName = $zoneName + AgingEnabled = $true + RefreshInterval = [System.TimeSpan]::FromHours(168) + NoRefreshInterval = [System.TimeSpan]::FromHours(168) + } + $setFilterDisable = { + $Name -eq $zoneName -and + $Aging -eq $false + } + $setFilterRefreshInterval = { + $Name -eq $zoneName -and + $RefreshInterval -eq ([System.TimeSpan]::FromHours(24)) + } + $setFilterNoRefreshInterval = { + $Name -eq $zoneName -and + $NoRefreshInterval -eq ([System.TimeSpan]::FromHours(36)) + } - Set-TargetResource @setParameterDisable + Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingEnabled } + } - Assert-MockCalled -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterDisable -Times 1 -Exactly -Scope It + It 'Should disable the DNS zone aging' { + Mock -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterDisable -Verifiable + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $setParameterDisable = @{ + Name = $zoneName + Enabled = $false + Verbose = $false } - It 'Should set the DNS zone refresh interval' { - Mock -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterRefreshInterval -Verifiable + Set-TargetResource @setParameterDisable + } + + Should -Invoke -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterDisable -Times 1 -Exactly -Scope It + } + + It 'Should set the DNS zone refresh interval' { + Mock -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterRefreshInterval -Verifiable - Set-TargetResource @setParameterRefreshInterval + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterRefreshInterval -Times 1 -Exactly -Scope It + $setParameterRefreshInterval = @{ + Name = $zoneName + Enabled = $true + RefreshInterval = 24 + Verbose = $false } - It 'Should set the DNS zone no refresh interval' { - Mock -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterNoRefreshInterval -Verifiable + Set-TargetResource @setParameterRefreshInterval + } + + Should -Invoke -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterRefreshInterval -Times 1 -Exactly -Scope It + } - Set-TargetResource @setParameterNoRefreshInterval + It 'Should set the DNS zone no refresh interval' { + Mock -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterNoRefreshInterval -Verifiable - Assert-MockCalled -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterNoRefreshInterval -Times 1 -Exactly -Scope It + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $setParameterNoRefreshInterval = @{ + Name = $zoneName + Enabled = $true + NoRefreshInterval = 36 + Verbose = $false } + + Set-TargetResource @setParameterNoRefreshInterval } - Context "The zone aging on $zoneName is disabled" { - Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingDisabled } + Should -Invoke -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterNoRefreshInterval -Times 1 -Exactly -Scope It + } + } - It 'Should enable the DNS zone aging' { - Mock -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterEnable -Verifiable + Context 'When zone aging is disabled' { + BeforeAll { + $fakeDnsServerZoneAgingDisabled = @{ + ZoneName = $zoneName + AgingEnabled = $false + RefreshInterval = [System.TimeSpan]::FromHours(168) + NoRefreshInterval = [System.TimeSpan]::FromHours(168) + } + $setFilterEnable = { + $Name -eq $zoneName -and + $Aging -eq $true + } - Set-TargetResource @setParameterEnable + Mock -CommandName Get-DnsServerZoneAging -MockWith { return $fakeDnsServerZoneAgingDisabled } + } - Assert-MockCalled -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterEnable -Times 1 -Exactly -Scope It + It 'Should enable DNS zone aging' { + Mock -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterEnable -Verifiable + + InModuleScope -Parameters @{ + zoneName = $zoneName + } -ScriptBlock { + Set-StrictMode -Version 1.0 + + $setParameterEnable = @{ + Name = $zoneName + Enabled = $true + Verbose = $false } + Set-TargetResource @setParameterEnable } + + Should -Invoke -CommandName Set-DnsServerZoneAging -ParameterFilter $setFilterEnable -Times 1 -Exactly -Scope It } - #endregion } } -finally -{ - Invoke-TestCleanup -} diff --git a/tests/Unit/DSC_DnsServerZoneScope.Tests.ps1 b/tests/Unit/DSC_DnsServerZoneScope.Tests.ps1 index bc2b92b3..da508d7a 100644 --- a/tests/Unit/DSC_DnsServerZoneScope.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerZoneScope.Tests.ps1 @@ -1,16 +1,37 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerZoneScope' +<# + .SYNOPSIS + Unit test for DSC_DnsServerZoneScope DSC resource. +#> -function Invoke-TestSetup -{ +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerZoneScope' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,133 +40,205 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force + + Remove-Module -Name DnsServer -Force } -Invoke-TestSetup - -try -{ - InModuleScope $script:dscResourceName { - #region Pester Test Initialization - $mocks = @{ - ZoneScopePresent = { - [PSCustomObject]@{ - ZoneName = 'contoso.com' - ZoneScope = 'ZoneScope' - FileName = 'ZoneScope.dns' - } +Describe 'DSC_DnsServerZoneScope\Get-TargetResource' -Tag 'Get' { + BeforeAll { + $ZoneScopePresent = { + [PSCustomObject]@{ + ZoneName = 'contoso.com' + ZoneScope = 'ZoneScope' + FileName = 'ZoneScope.dns' } - Absent = { } } - #endregion + } - #region Function Get-TargetResource - Describe "DSC_DnsServerZoneScope\Get-TargetResource" -Tag 'Get' { - Context 'When the system is in the desired state' { - It 'Should set Ensure to Present when the Zone Scope is Present' { - Mock -CommandName Get-DnsServerZoneScope $mocks.ZoneScopePresent + Context 'When the system is in the desired state' { + BeforeAll { + Mock -CommandName Get-DnsServerZoneScope -MockWith $ZoneScopePresent + } - $getTargetResourceResult = Get-TargetResource -ZoneName 'contoso.com' -Name 'ZoneScope' -Verbose - $getTargetResourceResult.Ensure | Should -Be 'Present' - $getTargetResourceResult.Name | Should -Be 'ZoneScope' - $getTargetResourceResult.ZoneName | Should -Be 'contoso.com' - $getTargetResourceResult.ZoneFile | Should -Be 'ZoneScope.dns' + It 'Should set Ensure to Present when the Zone Scope is Present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + $params = @{ + ZoneName = 'contoso.com' + Name = 'ZoneScope' + Verbose = $false } + + $getTargetResourceResult = Get-TargetResource @params + $getTargetResourceResult.Ensure | Should -Be 'Present' + $getTargetResourceResult.Name | Should -Be 'ZoneScope' + $getTargetResourceResult.ZoneName | Should -Be 'contoso.com' + $getTargetResourceResult.ZoneFile | Should -Be 'ZoneScope.dns' } - Context 'When the system is not in the desired state' { - It 'Should set Ensure to Absent when the Zone Scope is not present' { - Mock -CommandName Get-DnsServerZoneScope $mocks.Absent + Should -Invoke -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + } + } + + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Get-DnsServerZoneScope + } - $getTargetResourceResult = Get-TargetResource -ZoneName 'contoso.com' -Name 'ZoneScope' -Verbose - $getTargetResourceResult.Ensure | Should -Be 'Absent' - $getTargetResourceResult.Name | Should -Be 'ZoneScope' - $getTargetResourceResult.ZoneName | Should -Be 'contoso.com' + It 'Should set Ensure to Absent when the Zone Scope is not present' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Assert-MockCalled -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + $params = @{ + ZoneName = 'contoso.com' + Name = 'ZoneScope' + Verbose = $false } + + $getTargetResourceResult = Get-TargetResource @params + $getTargetResourceResult.Ensure | Should -Be 'Absent' + $getTargetResourceResult.Name | Should -Be 'ZoneScope' + $getTargetResourceResult.ZoneName | Should -Be 'contoso.com' } + + Should -Invoke -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It } - #endregion Function Get-TargetResource - - #region Function Test-TargetResource - Describe "DSC_DnsServerZoneScope\Test-TargetResource" -Tag 'Test' { - Context 'When the system is in the desired state' { - It 'Should return True when the Zone Scope exists' { - Mock -CommandName Get-DnsServerZoneScope $mocks.ZoneScopePresent - $params = @{ - Ensure = 'Present' - ZoneName = 'contoso.com' - Name = 'ZoneScope' - } - Test-TargetResource @params -Verbose | Should -BeTrue - - Assert-MockCalled -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + } +} + +Describe 'DSC_DnsServerZoneScope\Test-TargetResource' -Tag 'Test' { + BeforeAll { + $ZoneScopePresent = { + [PSCustomObject]@{ + ZoneName = 'contoso.com' + ZoneScope = 'ZoneScope' + FileName = 'ZoneScope.dns' + } + } + } + + Context 'When the system is in the desired state' { + BeforeAll { + Mock -CommandName Get-DnsServerZoneScope $ZoneScopePresent + } + + It 'Should return True when the Zone Scope exists' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Ensure = 'Present' + ZoneName = 'contoso.com' + Name = 'ZoneScope' + Verbose = $false } + Test-TargetResource @params | Should -BeTrue } - Context 'When the system is not in the desired state' { - It 'Should return False when the Ensure doesnt match' { - Mock -CommandName Get-DnsServerZoneScope $mocks.Absent - $params = @{ - Ensure = 'Present' - ZoneName = 'contoso.com' - Name = 'ZoneScope' - } - Test-TargetResource @params -Verbose | Should -BeFalse - - Assert-MockCalled -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + Should -Invoke -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + } + } + + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Get-DnsServerZoneScope + } + + It 'Should return False when the Ensure doesnt match' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Ensure = 'Present' + ZoneName = 'contoso.com' + Name = 'ZoneScope' + Verbose = $false } + Test-TargetResource @params | Should -BeFalse } - } - #endregion - - #region Function Set-TargetResource - Describe "DSC_DnsServerZoneScope\Set-TargetResource" -Tag 'Set' { - Context 'When configuring DNS Server Zone Scopes' { - It 'Calls Add-DnsServerZoneScope in the set method when the subnet does not exist' { - Mock -CommandName Get-DnsServerZoneScope - Mock -CommandName Add-DnsServerZoneScope - - $params = @{ - Ensure = 'Present' - ZoneName = 'contoso.com' - Name = 'ZoneScope' - } - - Set-TargetResource @params -Verbose - - Assert-MockCalled Add-DnsServerZoneScope -Scope It -ParameterFilter { - $Name -eq 'ZoneScope' -and $ZoneName -eq 'contoso.com' - } + + Should -Invoke -CommandName Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + } + } +} + +Describe 'DSC_DnsServerZoneScope\Set-TargetResource' -Tag 'Set' { + BeforeAll { + $ZoneScopePresent = { + [PSCustomObject]@{ + ZoneName = 'contoso.com' + ZoneScope = 'ZoneScope' + FileName = 'ZoneScope.dns' + } + } + } + + Context 'When the subnet does not exist' { + BeforeAll { + Mock -CommandName Get-DnsServerZoneScope + Mock -CommandName Add-DnsServerZoneScope + } + + It 'Should call Add-DnsServerZoneScope in the set method' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Ensure = 'Present' + ZoneName = 'contoso.com' + Name = 'ZoneScope' + Verbose = $false } - It 'Calls Remove-DnsServerZoneScope in the set method when Ensure is Absent' { - Mock -CommandName Remove-DnsServerZoneScope - Mock -CommandName Get-DnsServerZoneScope { return $mocks.ZoneScopePresent } - $params = @{ - Ensure = 'Absent' - ZoneName = 'contoso.com' - Name = 'ZoneScope' - } + Set-TargetResource @params + } + + Should -Invoke Add-DnsServerZoneScope -Scope It -ParameterFilter { + $Name -eq 'ZoneScope' -and $ZoneName -eq 'contoso.com' + } - Set-TargetResource @params -Verbose + Should -Invoke Get-DnsServerZoneScope -Exactly -Times 1 -Scope It + } + } - Assert-MockCalled Remove-DnsServerZoneScope -Scope It + Context 'When Ensure is Absent' { + BeforeAll { + Mock -CommandName Remove-DnsServerZoneScope + Mock -CommandName Get-DnsServerZoneScope -MockWith { return $ZoneScopePresent } + } + + It 'Should call Remove-DnsServerZoneScope in the set method' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Ensure = 'Absent' + ZoneName = 'contoso.com' + Name = 'ZoneScope' + Verbose = $false } + + Set-TargetResource @params } + + Should -Invoke Remove-DnsServerZoneScope -Exactly -Times 1 -Scope It + Should -Invoke Get-DnsServerZoneScope -Exactly -Times 1 -Scope It } - #endregion - } #end InModuleScope -} -finally -{ - Invoke-TestCleanup + } } diff --git a/tests/Unit/DSC_DnsServerZoneTransfer.Tests.ps1 b/tests/Unit/DSC_DnsServerZoneTransfer.Tests.ps1 index b8924493..84a8ecab 100644 --- a/tests/Unit/DSC_DnsServerZoneTransfer.Tests.ps1 +++ b/tests/Unit/DSC_DnsServerZoneTransfer.Tests.ps1 @@ -1,16 +1,39 @@ -$script:dscModuleName = 'DnsServerDsc' -$script:dscResourceName = 'DSC_DnsServerZoneTransfer' +# TODO: This is not testing one level of indirection. Also no tests for the Test-ResourceProperties rewrite -function Invoke-TestSetup -{ +<# + .SYNOPSIS + Unit test for DSC_DnsServerZoneTransfer DSC resource. +#> + +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { try { - Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } } catch [System.IO.FileNotFoundException] { - throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:dscResourceName = 'DSC_DnsServerZoneTransfer' $script:testEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` @@ -19,159 +42,299 @@ function Invoke-TestSetup -TestType 'Unit' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs\DnsServer.psm1') -Force + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscResourceName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscResourceName } -function Invoke-TestCleanup -{ +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + Restore-TestEnvironment -TestEnvironment $script:testEnvironment -} -Invoke-TestSetup + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscResourceName -All | Remove-Module -Force -try -{ - InModuleScope $script:dscResourceName { - #region Pester Test Initialization - $testName = 'example.com' - $testType = 'Any' - $testSecondaryServer = '192.168.0.1', '192.168.0.2' + Remove-Module -Name DnsServer -Force +} - $testParams = @{ - Name = $testName - Type = $testType - Verbose = $true - } +Describe 'DSC_DnsServerZoneTransfer\Get-TargetResource' -Tag 'Get' { + Context 'When command is invoked' { + BeforeAll { + $XferId2Name = @('Any', 'Named', 'Specific', 'None') - $testParamsAny = @{ - Name = $testName - Type = 'Any' - SecondaryServer = '' - Verbose = $true + Mock -CommandName Assert-Module + Mock -CommandName Get-CimInstance -MockWith { return @{ + Name = 'example.com' + SecureSecondaries = $XferId2Name.IndexOf('Any') + SecondaryServers = '' + } + } } - $testParamsSpecific = @{ - Name = $testName - Type = 'Specific' - SecondaryServer = $testSecondaryServer - Verbose = $true - } + It 'Should return the expected values' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Type = 'Any' + } - $testParamsSpecificDifferent = @{ - Name = $testName - Type = 'Specific' - SecondaryServer = '192.168.0.1', '192.168.0.2', '192.168.0.3' - Verbose = $true + $targetResource = Get-TargetResource @params + $targetResource | Should -BeOfType [System.Collections.Hashtable] + $targetResource.Name | Should -Be 'example.com' + $targetResource.Type | Should -Be 'Any' + $targetResource.SecondaryServer | Should -Be '' + } } + } +} + +Describe 'DSC_DnsServerZoneTransfer\Test-TargetResource' -Tag 'Test' { + Context 'When command is invoked' { + Context 'When the system is in the desired state' { + BeforeAll { + Mock -CommandName Assert-Module + Mock -CommandName Test-ResourceProperties -MockWith { return $true } + } - $fakeCimInstanceAny = @{ - Name = $testName - SecureSecondaries = $XferId2Name.IndexOf('Any') - SecondaryServers = '' + It 'Should return $true and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Type = 'None' + Debug = $false + Verbose = $false + } + + Test-TargetResource @params | Should -BeTrue + } + + Should -Invoke -CommandName Assert-Module -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Test-ResourceProperties -Scope It -Times 1 -Exactly + } } - $fakeCimInstanceNamed = @{ - Name = $testName - SecureSecondaries = $XferId2Name.IndexOf('Named') - SecondaryServers = '' + Context 'When the system is not in the desired state' { + BeforeAll { + Mock -CommandName Assert-Module + Mock -CommandName Test-ResourceProperties + } + + It 'Should return $false and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Type = 'None' + Debug = $false + Verbose = $false + } + + Test-TargetResource @params | Should -BeFalse + } + + Should -Invoke -CommandName Assert-Module -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Test-ResourceProperties -Scope It -Times 1 -Exactly + } } + } +} - $fakeCimInstanceSpecific = @{ - Name = $testName - SecureSecondaries = $XferId2Name.IndexOf('Specific') - SecondaryServers = $testSecondaryServer +Describe 'DSC_DnsServerZoneTransfer\Set-TargetResource' -Tag 'Set' { + Context 'When command is invoked' { + BeforeAll { + Mock -CommandName Test-ResourceProperties + Mock -CommandName Restart-Service } - #endregion - #region Function Get-TargetResource - Describe 'DSC_DnsServerZoneTransfer\Get-TargetResource' { - Mock -CommandName Assert-Module + It 'Should call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Returns a "System.Collections.Hashtable" object type' { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceAny } - $targetResource = Get-TargetResource @testParams - $targetResource -is [System.Collections.Hashtable] | Should Be $true + $params = @{ + Name = 'example.com' + Type = 'Any' + Verbose = $false + Debug = $false + } + Set-TargetResource @params } - It "Returns SecondaryServer = $($testParams.SecondaryServer) when zone transfers set to specific" { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceSpecific } - $targetResource = Get-TargetResource @testParams - $targetResource.SecondaryServers | Should Be $testParams.SecondaryServers - } + Should -Invoke Test-ResourceProperties -Scope It -Times 1 -Exactly + Should -Invoke Restart-Service -Scope It -Times 1 -Exactly } - #endregion + } +} - #region Function Test-TargetResource - Describe 'DSC_DnsServerZoneTransfer\Test-TargetResource' { - Mock -CommandName Assert-Module +Describe 'DSC_DnsServerZoneTransfer\Test-TargetResourceProperties' -Tag 'Private' { + BeforeAll { + $XferId2Name = @('Any', 'Named', 'Specific', 'None') + } - It 'Returns a "System.Boolean" object type' { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceAny } - $targetResource = Test-TargetResource @testParamsAny - $targetResource -is [System.Boolean] | Should Be $true + Context 'When ZoneTransfer value does match' { + Context 'When ZoneTransfer is "Specific or 2" and SecondaryServer does not match' { + BeforeAll { + Mock -CommandName Get-CimInstance -MockWith { return @{ + Name = 'example.com' + SecureSecondaries = $XferId2Name.IndexOf('Specific') + SecondaryServers = '192.168.20.1' + } + } } - It 'Passes when Zone Transfer Type matches' { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceAny } - Test-TargetResource @testParamsAny | Should Be $true - } + Context 'When Apply = $true' { + BeforeAll { + Mock -CommandName Invoke-CimMethod -RemoveParameterType InputObject + } - It "Fails when Zone Transfer Type does not match" { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceNamed } - Test-TargetResource @testParamsAny | Should Be $false - } + It 'Should return $false and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It 'Passes when Zone Transfer Secondaries matches' { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceSpecific } - Test-TargetResource @testParamsSpecific | Should Be $true + $params = @{ + Name = 'example.com' + Type = 'Specific' + SecondaryServer = '192.168.20.2' + Apply = $true + Verbose = $false + } + + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-CimInstance -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Invoke-CimMethod -Scope It -Times 1 -Exactly + } } - It 'Passes when Zone Transfer Secondaries does not match' { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceSpecific } - Test-TargetResource @testParamsSpecificDifferent | Should Be $false + Context 'When Apply = $false' { + It 'Should return $false and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Type = 'Specific' + SecondaryServer = '192.168.20.2' + Apply = $false + Verbose = $false + } + + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-CimInstance -Scope It -Times 1 -Exactly + } } } - #endregion - #region Function Set-TargetResource - Describe 'DSC_DnsServerZoneTransfer\Set-TargetResource' { - Mock -CommandName Assert-Module + Context 'When ZoneTransfer is not "Specific or 2"' { + BeforeAll { + Mock -CommandName Get-CimInstance -MockWith { return @{ + Name = 'example.com' + SecureSecondaries = $XferId2Name.IndexOf('None') + } + } + } - function Invoke-CimMethod - { - [CmdletBinding()] - param ( $InputObject, $MethodName, $Arguments ) + Context 'When Apply = $false' { + It 'Should return $true and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Type = 'None' + Apply = $false + Verbose = $false + } + + Test-ResourceProperties @params | Should -BeTrue + } + + Should -Invoke -CommandName Get-CimInstance -Scope It -Times 1 -Exactly + } } - Mock -CommandName Invoke-CimMethod - Mock -CommandName Restart-Service + Context 'When Apply = $true' { + It 'Should return $true and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - It "Calls Invoke-CimMethod not called when Zone Transfer Type matches" { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceAny } - Set-TargetResource @testParamsAny - Assert-MockCalled -CommandName Invoke-CimMethod -Times 0 -Exactly -Scope It + $params = @{ + Name = 'example.com' + Type = 'None' + Apply = $true + Verbose = $false + } + + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-CimInstance -Scope It -Times 1 -Exactly + } } + } - It "Calls Invoke-CimMethod called once when Zone Transfer Type does not match" { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceNamed } - Set-TargetResource @testParamsAny - Assert-MockCalled -CommandName Invoke-CimMethod -Times 1 -Exactly -Scope It + Context 'When ZoneTransfer value does not match' { + BeforeAll { + Mock -CommandName Get-CimInstance -MockWith { return @{ + Name = 'example.com' + SecureSecondaries = $XferId2Name.IndexOf('None') + } + } } - It "Calls Invoke-CimMethod not called when Zone Transfer Secondaries matches" { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceSpecific } - Set-TargetResource @testParamsSpecific - Assert-MockCalled -CommandName Invoke-CimMethod -Times 0 -Exactly -Scope It + Context 'When Apply = $true' { + BeforeAll { + Mock -CommandName Invoke-CimMethod -RemoveParameterType InputObject + } + + It 'Should return $false and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Type = 'Any' + Apply = $true + Verbose = $false + } + + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-CimInstance -Scope It -Times 1 -Exactly + Should -Invoke -CommandName Invoke-CimMethod -Scope It -Times 1 -Exactly + } } - It "Calls Invoke-CimMethod called once when Zone Transfer Secondaries does not match" { - Mock -CommandName Get-CimInstance -MockWith { return $fakeCimInstanceSpecific } - Set-TargetResource @testParamsSpecificDifferent - Assert-MockCalled -CommandName Invoke-CimMethod -Times 1 -Exactly -Scope It + Context 'When Apply = $false' { + It 'Should return $false and call expected mocks' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 + + $params = @{ + Name = 'example.com' + Type = 'Named' + Apply = $false + Verbose = $false + } + + Test-ResourceProperties @params | Should -BeFalse + } + + Should -Invoke -CommandName Get-CimInstance -Scope It -Times 1 -Exactly + } } } - } #end InModuleScope -} -finally -{ - Invoke-TestCleanup + } } diff --git a/tests/Unit/DnsServerDsc.Common.Tests.ps1 b/tests/Unit/DnsServerDsc.Common.Tests.ps1 index dec86be9..c6f6e268 100644 --- a/tests/Unit/DnsServerDsc.Common.Tests.ps1 +++ b/tests/Unit/DnsServerDsc.Common.Tests.ps1 @@ -1,111 +1,148 @@ -#region HEADER -$script:projectPath = "$PSScriptRoot\..\.." | Convert-Path -$script:projectName = (Get-ChildItem -Path "$script:projectPath\*\*.psd1" | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try { Test-ModuleManifest -Path $_.FullName -ErrorAction Stop } catch { $false }) - }).BaseName - -$script:parentModule = Get-Module -Name $script:projectName -ListAvailable | Select-Object -First 1 -$script:subModulesFolder = Join-Path -Path $script:parentModule.ModuleBase -ChildPath 'Modules' -Remove-Module -Name $script:parentModule -Force -ErrorAction 'SilentlyContinue' - -$script:subModuleName = (Split-Path -Path $PSCommandPath -Leaf) -replace '\.Tests.ps1' -$script:subModuleFile = Join-Path -Path $script:subModulesFolder -ChildPath "$($script:subModuleName)" - -Import-Module $script:subModuleFile -Force -ErrorAction 'Stop' -#endregion HEADER - -InModuleScope $script:subModuleName { - Describe 'DnsServerDsc.Common\ConvertTo-FollowRfc1034' { - BeforeAll { - $hostname = 'mail.contoso.com' - $convertedHostname = 'mail.contoso.com.' - } +<# + .SYNOPSIS + Unit test for DnsServerDsc.Common. +#> - Context 'The hostname is not converted' { - It 'Should not throw exception' { - { $script:result = $hostname | ConvertTo-FollowRfc1034 -Verbose } | Should -Not -Throw - } +# Suppressing this rule because Script Analyzer does not understand Pester's syntax. +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () - It 'Should end in a .' { - $script:result | Should -Be "$hostname." +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} - Context 'The hostname is already converted' { - It 'Should return the same as the input string' { - $convertedHostname | ConvertTo-FollowRfc1034 -Verbose | Should -Be $convertedHostname - } +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + $script:subModuleName = 'DnsServerDsc.Common' + + $script:parentModule = Get-Module -Name $script:dscModuleName -ListAvailable | Select-Object -First 1 + $script:subModulesFolder = Join-Path -Path $script:parentModule.ModuleBase -ChildPath 'Modules' + + $script:subModulePath = Join-Path -Path $script:subModulesFolder -ChildPath $script:subModuleName + + Import-Module -Name $script:subModulePath -Force -ErrorAction 'Stop' + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:subModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:subModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:subModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:subModuleName -All | Remove-Module -Force +} + +Describe 'DnsServerDsc.Common\ConvertTo-FollowRfc1034' -Tag 'ConvertTo-FollowRfc1034' { + BeforeAll { + $hostname = 'mail.contoso.com' + $convertedHostname = 'mail.contoso.com.' + } + + Context 'When the hostname is not converted' { + It 'Should not throw exception' { + { $script:result = $hostname | ConvertTo-FollowRfc1034 -Verbose } | Should -Not -Throw + } + + It 'Should end in a .' { + $script:result | Should -Be "$hostname." } } - Describe 'Convert-RootHintsToHashtable' { - BeforeAll { - $emptyRootHints = @() - $rootHintWithoutIP = @( - @{ - NameServer = @{ - RecordData = @{ - NameServer = 'ns1' - } + Context 'When the hostname is already converted' { + It 'Should return the same as the input string' { + $convertedHostname | ConvertTo-FollowRfc1034 -Verbose | Should -Be $convertedHostname + } + } +} + +Describe 'DnsServerDsc.Common\Convert-RootHintsToHashtable' -Tag 'Convert-RootHintsToHashtable' { + BeforeAll { + $emptyRootHints = @() + $rootHintWithoutIP = @( + @{ + NameServer = @{ + RecordData = @{ + NameServer = 'ns1' } - IPAddress = $null } - ) - $rootHintWithIPv4 = @( - @{ - NameServer = @{ - RecordData = @{ - NameServer = 'ns2' - } + IPAddress = $null + } + ) + $rootHintWithIPv4 = @( + @{ + NameServer = @{ + RecordData = @{ + NameServer = 'ns2' } - IPAddress = @{ - RecordData = @{ - IPv6Address = @{ - IPAddressToString = '192.0.2.1' - } + } + IPAddress = @{ + RecordData = @{ + IPv6Address = @{ + IPAddressToString = '192.0.2.1' } } } - ) - $rootHintWithIPv6 = @( - @{ - NameServer = @{ - RecordData = @{ - NameServer = 'ns3' - } + } + ) + $rootHintWithIPv6 = @( + @{ + NameServer = @{ + RecordData = @{ + NameServer = 'ns3' } - IPAddress = @{ - RecordData = @{ - IPv6Address = @{ - IPAddressToString = '2001:db8::1' - } + } + IPAddress = @{ + RecordData = @{ + IPv6Address = @{ + IPAddressToString = '2001:db8::1' } } } - ) - } + } + ) + } - It 'Returns an empty hashtable when the input array is empty' { - $result = Convert-RootHintsToHashtable -RootHints $emptyRootHints - $result.Count | Should -Be 0 - } + It 'Should return an empty hashtable when the input array is empty' { + $result = Convert-RootHintsToHashtable -RootHints $emptyRootHints + $result.Count | Should -Be 0 + } - It 'Correctly skips elements without an IPAddress' { - $result = Convert-RootHintsToHashtable -RootHints $rootHintWithoutIP - $result.Count | Should -Be 0 - } + It 'Should correctly skip elements without an IPAddress' { + $result = Convert-RootHintsToHashtable -RootHints $rootHintWithoutIP + $result.Count | Should -Be 0 + } - It 'Correctly handles elements with an IPv4 address' { - $result = Convert-RootHintsToHashtable -RootHints $rootHintWithIPv4 - $result.Count | Should -Be 1 - $result.ns2 | Should -Be '192.0.2.1' - } + It 'Should correctly handle elements with an IPv4 address' { + $result = Convert-RootHintsToHashtable -RootHints $rootHintWithIPv4 + $result.Count | Should -Be 1 + $result.ns2 | Should -Be '192.0.2.1' + } - It 'Correctly handles elements with an IPv6 address' { - $result = Convert-RootHintsToHashtable -RootHints $rootHintWithIPv6 - $result.Count | Should -Be 1 - $result.ns3 | Should -Be '2001:db8::1' - } + It 'Should correctly handle elements with an IPv6 address' { + $result = Convert-RootHintsToHashtable -RootHints $rootHintWithIPv6 + $result.Count | Should -Be 1 + $result.ns3 | Should -Be '2001:db8::1' } } diff --git a/tests/Unit/Private/Assert-TimeSpan.Tests.ps1 b/tests/Unit/Private/Assert-TimeSpan.Tests.ps1 index 79fce733..0dab9596 100644 --- a/tests/Unit/Private/Assert-TimeSpan.Tests.ps1 +++ b/tests/Unit/Private/Assert-TimeSpan.Tests.ps1 @@ -1,55 +1,102 @@ -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName -Force + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force +} + +Describe 'Assert-TimeSpan' -Tag 'Private' { + Context 'When asserting a valid time' { + Context 'When passing value with named parameter' { + It 'Should not throw an exception' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -InModuleScope $ProjectName { - Describe 'Assert-TimeSpan' -Tag 'Private' { - Context 'When asserting a valid time' { - Context 'When passing value with named parameter' { - It 'Should not throw an exception' { { Assert-TimeSpan -PropertyName 'MyProperty' -Value '1.00:00:00' } | Should -Not -Throw } } + } + + Context 'When passing value in pipeline' { + It 'Should not throw an exception' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When passing value in pipeline' { - It 'Should not throw an exception' { { '1.00:00:00' | Assert-TimeSpan -PropertyName 'MyProperty' } | Should -Not -Throw } } } + } - Context 'When asserting a invalid string' { - It 'Should throw the correct error message' { - $mockExpectedErrorMessage = $script:localizedData.PropertyHasWrongFormat -f 'MyProperty', 'a.00:00:00' + Context 'When asserting a invalid string' { + It 'Should throw the correct error message' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - { 'a.00:00:00' | Assert-TimeSpan -PropertyName 'MyProperty' } | Should -Throw $mockExpectedErrorMessage + $mockErrorMessage = $script:localizedData.PropertyHasWrongFormat -f 'MyProperty', 'a.00:00:00' + + { 'a.00:00:00' | Assert-TimeSpan -PropertyName 'MyProperty' } | Should -Throw -ExpectedMessage ('*' + $mockErrorMessage) } } + } + + Context 'When time is above maximum allowed value' { + It 'Should throw the correct error message' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When time is above maximum allowed value' { - It 'Should throw the correct error message' { - $mockExpectedErrorMessage = $script:localizedData.TimeSpanExceedMaximumValue -f 'MyProperty', '1.00:00:00', '00:30:00' + $mockErrorMessage = $script:localizedData.TimeSpanExceedMaximumValue -f 'MyProperty', '1.00:00:00', '00:30:00' - { '1.00:00:00' | Assert-TimeSpan -PropertyName 'MyProperty' -Maximum '0.00:30:00' } | Should -Throw $mockExpectedErrorMessage + { '1.00:00:00' | Assert-TimeSpan -PropertyName 'MyProperty' -Maximum '0.00:30:00' } | Should -Throw -ExpectedMessage ('*' + $mockErrorMessage) } } + } + + Context 'When time is below minimum allowed value' { + It 'Should throw the correct error message' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When time is below minimum allowed value' { - It 'Should throw the correct error message' { - $mockExpectedErrorMessage = $script:localizedData.TimeSpanBelowMinimumValue -f 'MyProperty', '1.00:00:00', '2.00:00:00' + $mockErrorMessage = $script:localizedData.TimeSpanBelowMinimumValue -f 'MyProperty', '1.00:00:00', '2.00:00:00' - { '1.00:00:00' | Assert-TimeSpan -PropertyName 'MyProperty' -Minimum '2.00:00:00' } | Should -Throw $mockExpectedErrorMessage + { '1.00:00:00' | Assert-TimeSpan -PropertyName 'MyProperty' -Minimum '2.00:00:00' } | Should -Throw -ExpectedMessage ('*' + $mockErrorMessage) } } } diff --git a/tests/Unit/Private/ConvertTo-TimeSpan.Tests.ps1 b/tests/Unit/Private/ConvertTo-TimeSpan.Tests.ps1 index b6182621..d1913f40 100644 --- a/tests/Unit/Private/ConvertTo-TimeSpan.Tests.ps1 +++ b/tests/Unit/Private/ConvertTo-TimeSpan.Tests.ps1 @@ -1,40 +1,79 @@ -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) { - Test-ModuleManifest $_.FullName -ErrorAction Stop + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null } - catch - { - $false - }) } -).BaseName -Import-Module $ProjectName + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'DnsServerDsc' + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force +} + +Describe 'ConvertTo-TimeSpan' -Tag 'Private' { + Context 'When converting a valid time' { + Context 'When passing value with named parameter' { + It 'Should return the correct value' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 -InModuleScope $ProjectName { - Describe 'ConvertTo-TimeSpan' -Tag 'Private' { - Context 'When converting a valid time' { - Context 'When passing value with named parameter' { - It 'Should return the correct value' { $result = ConvertTo-TimeSpan -Value '234' $result | Should -BeOfType [System.TimeSpan] $result.Days | Should -Be '234' } } + } + + Context 'When passing value in pipeline' { + It 'Should return the correct value' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When passing value in pipeline' { - It 'Should return the correct value' { $result = '234' | ConvertTo-TimeSpan $result | Should -BeOfType [System.TimeSpan] $result.Days | Should -Be '234' } } } + } + + Context 'When converting a invalid string' { + It 'Should return $null' { + InModuleScope -ScriptBlock { + Set-StrictMode -Version 1.0 - Context 'When converting a invalid string' { - It 'Should return $null' { $result = ConvertTo-TimeSpan -Value '234a' $result | Should -BeNullOrEmpty } diff --git a/tests/Unit/Private/Get-ClassName.Tests.ps1 b/tests/Unit/Private/Get-ClassName.Tests.ps1 deleted file mode 100644 index 8d65afc1..00000000 --- a/tests/Unit/Private/Get-ClassName.Tests.ps1 +++ /dev/null @@ -1,78 +0,0 @@ -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try - { - Test-ModuleManifest $_.FullName -ErrorAction Stop - } - catch - { - $false - }) } -).BaseName - -Import-Module $ProjectName - -InModuleScope $ProjectName { - Describe 'Get-ClassName' -Tag 'Private' { - BeforeAll { - [System.UInt32] $mockObject = 3 - } - - Context 'When getting the class name' { - Context 'When passing value with named parameter' { - It 'Should return the correct value' { - $result = Get-ClassName -InputObject $mockObject - - $result.GetType().FullName | Should -Be 'System.Object[]' - - $result | Should -HaveCount 1 - $result | Should -Contain 'System.UInt32' - } - } - - Context 'When passing value in pipeline' { - It 'Should return the correct value' { - $result = $mockObject | Get-ClassName - - $result.GetType().FullName | Should -Be 'System.Object[]' - - $result | Should -HaveCount 1 - $result | Should -Contain 'System.UInt32' - } - } - } - - Context 'When getting the class name and all inherited class names (base classes)' { - Context 'When passing value with named parameter' { - It 'Should return the correct value' { - $result = Get-ClassName -InputObject $mockObject -Recurse - - $result.GetType().FullName | Should -Be 'System.Object[]' - - $result | Should -HaveCount 2 - $result | Should -Contain 'System.UInt32' - $result | Should -Contain 'System.ValueType' - - $result[0] | Should -Be 'System.UInt32' - $result[1] | Should -Be 'System.ValueType' - } - } - - Context 'When passing value in pipeline' { - It 'Should return the correct value' { - $result = $mockObject | Get-ClassName -Recurse - - $result.GetType().FullName | Should -Be 'System.Object[]' - - $result | Should -HaveCount 2 - $result | Should -Contain 'System.UInt32' - $result | Should -Contain 'System.ValueType' - - $result[0] | Should -Be 'System.UInt32' - $result[1] | Should -Be 'System.ValueType' - } - } - } - } -} diff --git a/tests/Unit/Private/Get-LocalizedDataRecursive.Tests.ps1 b/tests/Unit/Private/Get-LocalizedDataRecursive.Tests.ps1 deleted file mode 100644 index faa12242..00000000 --- a/tests/Unit/Private/Get-LocalizedDataRecursive.Tests.ps1 +++ /dev/null @@ -1,122 +0,0 @@ -$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path -$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { - ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and - $(try - { - Test-ModuleManifest $_.FullName -ErrorAction Stop - } - catch - { - $false - }) } -).BaseName - -Import-Module $ProjectName -Force - -InModuleScope $ProjectName { - Describe 'Get-LocalizedDataRecursive' -Tag 'Private' { - BeforeAll { - $getLocalizedData_ParameterFilter_Class = { - $FileName -eq 'MyClassResource.strings.psd1' - } - - $getLocalizedData_ParameterFilter_Base = { - $FileName -eq 'MyBaseClass.strings.psd1' - } - - Mock -CommandName Get-LocalizedData -MockWith { - return @{ - ClassStringKey = 'My class string' - } - } -ParameterFilter $getLocalizedData_ParameterFilter_Class - - Mock -CommandName Get-LocalizedData -MockWith { - return @{ - BaseStringKey = 'My base string' - } - } -ParameterFilter $getLocalizedData_ParameterFilter_Base - } - - Context 'When getting localization string for class name' { - Context 'When passing value with named parameter' { - It 'Should return the correct localization strings' { - $result = Get-LocalizedDataRecursive -ClassName 'MyClassResource' - - $result.Keys | Should -HaveCount 1 - $result.Keys | Should -Contain 'ClassStringKey' - - Assert-MockCalled -CommandName Get-LocalizedData -ParameterFilter $getLocalizedData_ParameterFilter_Class -Exactly -Times 1 -Scope It - } - } - - Context 'When passing value in pipeline' { - It 'Should return the correct localization strings' { - $result = 'MyClassResource' | Get-LocalizedDataRecursive - - $result.Keys | Should -HaveCount 1 - $result.Keys | Should -Contain 'ClassStringKey' - - Assert-MockCalled -CommandName Get-LocalizedData -ParameterFilter $getLocalizedData_ParameterFilter_Class -Exactly -Times 1 -Scope It - } - } - } - - Context 'When getting localization string for class and base name' { - Context 'When passing value with named parameter' { - It 'Should return the correct localization strings' { - $result = Get-LocalizedDataRecursive -ClassName @('MyClassResource','MyBaseClass') - - $result.Keys | Should -HaveCount 2 - $result.Keys | Should -Contain 'ClassStringKey' - $result.Keys | Should -Contain 'BaseStringKey' - - Assert-MockCalled -CommandName Get-LocalizedData -ParameterFilter $getLocalizedData_ParameterFilter_Class -Exactly -Times 1 -Scope It - } - } - - Context 'When passing value in pipeline' { - It 'Should return the correct localization strings' { - $result = @('MyClassResource','MyBaseClass') | Get-LocalizedDataRecursive - - $result.Keys | Should -HaveCount 2 - $result.Keys | Should -Contain 'ClassStringKey' - $result.Keys | Should -Contain 'BaseStringKey' - - Assert-MockCalled -CommandName Get-LocalizedData -ParameterFilter $getLocalizedData_ParameterFilter_Class -Exactly -Times 1 -Scope It - } - } - } - - Context 'When getting localization string for class and base file name' { - Context 'When passing value with named parameter' { - It 'Should return the correct localization strings' { - $result = Get-LocalizedDataRecursive -ClassName @( - 'MyClassResource.strings.psd1' - 'MyBaseClass.strings.psd1' - ) - - $result.Keys | Should -HaveCount 2 - $result.Keys | Should -Contain 'ClassStringKey' - $result.Keys | Should -Contain 'BaseStringKey' - - Assert-MockCalled -CommandName Get-LocalizedData -ParameterFilter $getLocalizedData_ParameterFilter_Class -Exactly -Times 1 -Scope It - } - } - - Context 'When passing value in pipeline' { - It 'Should return the correct localization strings' { - $result = @( - 'MyClassResource.strings.psd1' - 'MyBaseClass.strings.psd1' - ) | Get-LocalizedDataRecursive - - $result.Keys | Should -HaveCount 2 - $result.Keys | Should -Contain 'ClassStringKey' - $result.Keys | Should -Contain 'BaseStringKey' - - Assert-MockCalled -CommandName Get-LocalizedData -ParameterFilter $getLocalizedData_ParameterFilter_Class -Exactly -Times 1 -Scope It - } - } - } - } -}