Tests/Unit/MSFT_xSQLAOGroupEnsure.Tests.ps1
# Suppressing this rule because PlainText is required for one of the functions used in this test [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] param () $script:DSCModuleName = 'xSQLServer' $script:DSCResourceName = 'MSFT_xSQLAOGroupEnsure' #region HEADER # Unit Test Template Version: 1.1.0 [String] $script:moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) if ( (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) { & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $script:moduleRoot -ChildPath '\DSCResource.Tests\')) } Import-Module (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force $TestEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:DSCModuleName ` -DSCResourceName $script:DSCResourceName ` -TestType Unit #endregion HEADER try { #region Pester Test Initialization # Loading mocked classes Add-Type -Path (Join-Path -Path $script:moduleRoot -ChildPath 'Tests\Unit\Stubs\SMO.cs') $mockpassword = "dummyPassw0rd" | ConvertTo-SecureString -asPlainText -Force $mockusername = "dba" $mockcredential = New-Object System.Management.Automation.PSCredential($mockusername,$mockpassword) #endregion Pester Test Initialization #region Get-TargetResource Describe 'Get-TargetResource' { Mock -CommandName Connect-SQL -MockWith { # build a custom object to return which is close to the real SMO object $smoObj = [PSCustomObject] @{ SQLServer = 'Node01' SQLInstanceName = 'Prd01' ClusterName = 'Clust01' } # add the AvailabilityGroups entry as this is an ArrayList and allows us the functionality later $smoObj | Add-Member -MemberType NoteProperty -Name 'AvailabilityGroups' -Value @{ 'AG01' = @{ AvailabilityGroupListeners = @{ name = 'AgList01' availabilitygrouplisteneripaddresses = [System.Collections.ArrayList] @(@{IpAddress = '192.168.0.1'; SubnetMask = '255.255.255.0'}) portnumber = 5022 } AvailabilityDatabases = @( @{ name='AdventureWorks' } ) } } $smoObj.AvailabilityGroups['AG01'] | Add-Member -MemberType NoteProperty -Name Name -Value 'AG01' -Force $smoObj.AvailabilityGroups | Add-Member -MemberType ScriptMethod -Name 'Add' -Value { return $true } -Force $smoObj.AvailabilityGroups['AG01'] | Add-Member -MemberType ScriptMethod -Name ToString -Value { return 'AG01' } -Force $smoObj.AvailabilityGroups['AG01'] | Add-Member -MemberType ScriptMethod -Name Drop -Value { return $true } -Force return $smoObj } -ModuleName $script:DSCResourceName Context "When the system is in the desired state" { $SqlAOGroup = Get-TargetResource -Ensure 'Present' -AvailabilityGroupName 'AG01' -SQLServer 'localhost' -SQLInstanceName 'MSSQLSERVER' -SetupCredential $mockcredential It 'Should return hashtable with Ensure = $true'{ $SqlAOGroup.Ensure | Should Be $true } } Context "When the system is not in the desired state" { $SqlAOGroup = Get-TargetResource -Ensure 'Absent' -AvailabilityGroupName 'AG01' -SQLServer 'localhost' -SQLInstanceName 'MSSQLSERVER' -SetupCredential $mockcredential It 'Should return hashtable with Ensure = $false' { $SqlAOGroup.Ensure | Should Be $false } } } #endregion Get-TargetResource #region Test-TargetResource Describe 'Test-TargetResource' { Mock -CommandName Connect-SQL -MockWith { # build a custom object to return which is close to the real SMO object $smoObj = [PSCustomObject] @{ SQLServer = 'Node01' SQLInstanceName = 'Prd01' ClusterName = 'Clust01' } # add the AvailabilityGroups entry as this is an ArrayList and allows us the functionality later $smoObj | Add-Member -MemberType NoteProperty -Name 'AvailabilityGroups' -Value @{ 'AG01' = @{ AvailabilityGroupListeners = @{ name = 'AgList01' availabilitygrouplisteneripaddresses = [System.Collections.ArrayList] @(@{IpAddress = '192.168.0.1'; SubnetMask = '255.255.255.0'}) portnumber = 5022 } AvailabilityDatabases = @( @{ name='AdventureWorks' } ) } } $smoObj.AvailabilityGroups['AG01'] | Add-Member -MemberType NoteProperty -Name Name -Value 'AG01' -Force $smoObj.AvailabilityGroups | Add-Member -MemberType ScriptMethod -Name 'Add' -Value { return $true } -Force $smoObj.AvailabilityGroups['AG01'] | Add-Member -MemberType ScriptMethod -Name ToString -Value { return 'AG01' } -Force $smoObj.AvailabilityGroups['AG01'] | Add-Member -MemberType ScriptMethod -Name Drop -Value { return $true } -Force return $smoObj } -ModuleName $script:DSCResourceName Context "When the system is in the desired state" { $SqlAOGroupTest = Test-TargetResource -Ensure 'Present' -AvailabilityGroupName 'AG01' -SQLServer 'localhost' -SQLInstanceName 'MSSQLSERVER' -SetupCredential $mockcredential It 'Should return $true'{ $SqlAOGroupTest | Should Be $true } } Context "When the system is not in the desired state" { $SqlAOGroupTest = Test-TargetResource -Ensure 'Absent' -AvailabilityGroupName 'AG01' -SQLServer 'localhost' -SQLInstanceName 'MSSQLSERVER' -SetupCredential $mockcredential It 'Should return $false' { $SqlAOGroupTest | Should Be $false } } } #endregion Test-TargetResource Describe 'Set-TargetResource' { # Mocking the module FailoverCluster, to be able to mock the function Get-ClusterNode Get-Module -Name FailoverClusters | Remove-Module New-Module -Name FailoverClusters -ScriptBlock { # This was generated by Write-ModuleStubFile function from the folder Tests\Unit\Stubs function Get-ClusterNode { [CmdletBinding(DefaultParameterSetName='InputObject', HelpUri='http://go.microsoft.com/fwlink/?LinkId=216215')] param( [Parameter(Position=0)] [ValidateNotNullOrEmpty()] [System.Collections.Specialized.StringCollection] ${Name}, [Parameter(ParameterSetName='InputObject', ValueFromPipeline=$true)] [ValidateNotNull()] [psobject] ${InputObject}, [ValidateNotNullOrEmpty()] [string] ${Cluster} ) throw '{0}: StubNotImplemented' -f $MyInvocation.MyCommand } Export-ModuleMember -Function *-Cluster* } | Import-Module -Force Mock Grant-ServerPerms -MockWith {} -ModuleName $script:DSCResourceName -Verifiable Mock New-ListenerADObject -MockWith {} -ModuleName $script:DSCResourceName -Verifiable Mock Get-ClusterNode -MockWith { $clusterNode = @( [PSCustomObject] @{ Name = 'Node01' }, [PSCustomObject] @{ Name = 'Node02' }, [PSCustomObject] @{ Name = 'Node03' }, [PSCustomObject] @{ Name = 'Node04' } ) return $clusterNode } -ModuleName $script:DSCResourceName -Verifiable Mock Connect-SQL -MockWith { # build a custom object to return which is close to the real SMO object $smoObj = [PSCustomObject] @{ SQLServer = 'Node01' SQLInstanceName = 'Prd01' ClusterName = 'Clust01' } # add the AvailabilityGroups entry as this is an ArrayList and allows us the functionality later $smoObj | Add-Member -MemberType NoteProperty -Name 'AvailabilityGroups' -Value @{ 'AG01' = @{ AvailabilityGroupListeners = @{ name = 'AgList01' availabilitygrouplisteneripaddresses = [System.Collections.ArrayList] @(@{IpAddress = '192.168.0.1'; SubnetMask = '255.255.255.0'}) portnumber = 5022 } AvailabilityDatabases = @( @{ name='AdventureWorks' } ) } } $smoObj.AvailabilityGroups | Add-Member -MemberType ScriptMethod -Name 'Add' -Value {return $true} -Force $smoObj.AvailabilityGroups['AG01'] | Add-Member -MemberType NoteProperty -Name Name -Value 'AG01' -Force $smoObj.AvailabilityGroups['AG01'] | Add-Member -MemberType ScriptMethod -Name ToString -Value {return 'AG01'} -Force $smoObj.AvailabilityGroups['AG01'] | Add-Member -MemberType ScriptMethod -Name Drop -Value {return $true} -Force return $smoObj } -ModuleName $script:DSCResourceName -Verifiable Mock New-Object -MockWith { Param($TypeName) Switch ($TypeName) { 'Microsoft.SqlServer.Management.Smo.AvailabilityGroup' { $object = [PSCustomObject] @{ Name = "MockedObject" AutomatedBackupPreference = '' FailureConditionLevel = '' HealthCheckTimeout = '' AvailabilityReplicas = [System.Collections.ArrayList] @() AvailabilityGroupListeners = [System.Collections.ArrayList] @() } $object | Add-Member -MemberType ScriptMethod -Name Create -Value {return $true} } 'Microsoft.SqlServer.Management.Smo.AvailabilityReplica' { $object = [PSCustomObject] @{ Name = "MockedObject" EndpointUrl = '' FailoverMode = '' AvailabilityMode = '' BackupPriority = 0 ConnectionModeInPrimaryRole = '' ConnectionModeInSecondaryRole = '' } } 'Microsoft.SqlServer.Management.Smo.AvailabilityGroupListener' { $object = [PSCustomObject] @{ Name = "MockedObject" PortNumber = '' AvailabilityGroupListenerIPAddresses = [System.Collections.ArrayList] @() } } 'Microsoft.SqlServer.Management.Smo.AvailabilityGroupListenerIPAddress' { $object = [PSCustomObject] @{ Name = "MockedObject" IsDHCP = '' IPAddress = '' SubnetMask = '' } } Default { $object = [PSCustomObject] @{ Name = "MockedObject" } } } return $object } -ModuleName $script:DSCResourceName -Verifiable Context "When the system is not in the desired state" { $params = @{ Ensure = 'Present' AvailabilityGroupName = 'AG01' AvailabilityGroupNameListener = 'AgList01' AvailabilityGroupNameIP = '192.168.0.1' AvailabilityGroupSubMask = '255.255.255.0' AvailabilityGroupPort = 1433 ReadableSecondary = 'ReadOnly' AutoBackupPreference = 'Primary' SQLServer = 'localhost' SQLInstanceName = 'MSSQLSERVER' SetupCredential = $mockcredential } It 'Should not throw when calling Set-method' { { Set-TargetResource @Params } | Should Not Throw } } } } finally { #region FOOTER Restore-TestEnvironment -TestEnvironment $TestEnvironment #endregion } |