Tests/Unit/HyperVCommon.tests.ps1
$script:DSCModuleName = 'xHyper-V' $script:DSCResourceName = 'HyperVCommon' #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 # Begin Testing try { #region Pester Tests $LocalizedData = InModuleScope $script:DSCResourceName { $LocalizedData } InModuleScope $script:DSCResourceName { Describe 'HyperVCommon\Set-VMProperty' { function Get-VM { param ( [System.String] $Name ) } function Get-VMProcessor { param ( [System.String] $VMName ) } function Set-VMProcessor { param ( [System.String] $VMName ) } # Guard mocks Mock Get-VM { } Mock Set-VMState { } Mock Get-VMProcessor { } Mock Set-VMProcessor { } It "Should throw if VM is running and 'RestartIfNeeded' is False" { Mock Get-VM { return @{ State = 'Running' } } $setVMPropertyParams = @{ VMName = 'Test'; VMCommand = 'Set-VMProcessor'; ChangeProperty = @{ ResourcePoolName = 'Dummy' } } { Set-VMProperty @setVMPropertyParams } | Should Throw 'RestartIfNeeded' } It "Should stop and restart VM when running and 'RestartIfNeeded' is True" { Mock Get-VM { return @{ State = 'Running' } } $setVMPropertyParams = @{ VMName = 'Test'; VMCommand = 'Set-VMProcessor'; ChangeProperty = @{ ResourcePoolName = 'Dummy' } RestartIfNeeded = $true; } Set-VMProperty @setVMPropertyParams Assert-MockCalled Set-VMState -ParameterFilter { $State -eq 'Off' } -Scope It Assert-MockCalled Set-VMState -ParameterFilter { $State -eq 'Running' } -Scope It } } Describe 'HyperVCommon\Set-VMState' { function Get-VM { param ( [System.String] $Name ) } function Resume-VM { param ( [System.String] $Name ) } function Start-VM { param ( [System.String] $Name ) } function Stop-VM { param ( [System.String] $Name ) } function Suspend-VM { param ( [System.String] $Name ) } # Guard mocks Mock Resume-VM { } Mock Start-VM { } Mock Stop-VM { } Mock Suspend-VM { } Mock Wait-VMIPAddress { } It 'Should resume VM when current "State" is "Paused" and target state is "Running"' { Mock Get-VM { return @{ State = 'Paused' } } Set-VMState -Name 'TestVM' -State 'Running' Assert-MockCalled Resume-VM -Scope It Assert-MockCalled Wait-VMIPAddress -Scope It -Exactly 0 } It 'Should resume VM and wait when current "State" is "Paused" and target state is "Running"' { Mock Get-VM { return @{ State = 'Paused' } } Set-VMState -Name 'TestVM' -State 'Running' -WaitForIP $true Assert-MockCalled Resume-VM -Scope It Assert-MockCalled Wait-VMIPAddress -Scope It } It 'Should start VM when current "State" is "Off" and target state is "Running"' { Mock Get-VM { return @{ State = 'Off' } } Set-VMState -Name 'TestVM' -State 'Running' Assert-MockCalled Start-VM -Scope It Assert-MockCalled Wait-VMIPAddress -Scope It -Exactly 0 } It 'Should start VM and wait when current "State" is "Off" and target state is "Running"' { Mock Get-VM { return @{ State = 'Off' } } Set-VMState -Name 'TestVM' -State 'Running' -WaitForIP $true Assert-MockCalled Start-VM -Scope It Assert-MockCalled Wait-VMIPAddress -Scope It } It 'Should suspend VM when current "State" is "Running" and target state is "Paused"' { Mock Get-VM { return @{ State = 'Running' } } Set-VMState -Name 'TestVM' -State 'Paused' Assert-MockCalled Suspend-VM -Scope It } It 'Should stop VM when current "State" is "Running" and target state is "Off"' { Mock Get-VM { return @{ State = 'Running' } } Set-VMState -Name 'TestVM' -State 'Off' Assert-MockCalled Stop-VM -Scope It } It 'Should stop VM when current "State" is "Paused" and target state is "Off"' { Mock Get-VM { return @{ State = 'Paused' } } Set-VMState -Name 'TestVM' -State 'Off' Assert-MockCalled Stop-VM -Scope It } } # describe HyperVCommon\Set-VMState } Describe 'HyperVCommon\Wait-VMIPAddress' { function Get-VMNetworkAdapter { param ( [System.String] $VMName ) } # Guard mocks Mock Get-VMNetworkAdapter -ModuleName $script:DSCResourceName { } It 'Should return when VM network adapter reports 2 IP addresses' { Mock Get-VMNetworkAdapter -ModuleName $script:DSCResourceName { return @{ IpAddresses = @('192.168.0.1','172.16.0.1') } } $result = Wait-VMIPAddress -Name 'Test' $result | Should BeNullOrEmpty } It 'Should throw when after timeout is exceeded' { Mock Get-VMNetworkAdapter -ModuleName $script:DSCResourceName { return $null } { Wait-VMIPAddress -Name 'Test' -Timeout 2 } | Should Throw 'timed out' } } # describe HyperVCommon\WaitVMIPAddress Describe 'HyperVCommon\ConvertTo-TimeSpan' { It 'Should convert 60 seconds to "System.TimeSpan" of 1 minute' { $testSeconds = 60 $result = ConvertTo-TimeSpan -TimeInterval $testSeconds -TimeIntervalType Seconds $result.TotalMinutes | Should Be 1 } It 'Should convert 60 minutes to "System.TimeSpan" of 60 minutes' { $testMinutes = 60 $result = ConvertTo-TimeSpan -TimeInterval $testMinutes -TimeIntervalType Minutes $result.TotalHours | Should Be 1 } It 'Should convert 48 hours to "System.TimeSpan" of 2 days' { $testHours = 48 $result = ConvertTo-TimeSpan -TimeInterval $testHours -TimeIntervalType Hours $result.TotalDays | Should Be 2 } } # describe HyperVCommon\ConvertTo-TimeSpan Describe 'HyperVCommon\ConvertFrom-TimeSpan' { It 'Should convert a "System.TimeSpan" of 1 minute to 60 seconds' { $testTimeSpan = New-TimeSpan -Minutes 1 $result = ConvertFrom-TimeSpan -TimeSpan $testTimeSpan -TimeSpanType Seconds $result | Should Be 60 } It 'Should convert a "System.TimeSpan" of 1 hour to 60 minutes' { $testTimeSpan = New-TimeSpan -Hours 1 $result = ConvertFrom-TimeSpan -TimeSpan $testTimeSpan -TimeSpanType Minutes $result | Should Be 60 } It 'Should convert a "System.TimeSpan" of 2 dayes to 48 hours' { $testTimeSpan = New-TimeSpan -Days 2 $result = ConvertFrom-TimeSpan -TimeSpan $testTimeSpan -TimeSpanType Hours $result | Should Be 48 } } # describe HyperVCommon\ConvertFrom-TimeSpan Describe 'HyperVCommon\Get-VMHyperV' { function Get-VM { [CmdletBinding()] param ( $Name ) } # Guard mocks Mock Get-VM -ModuleName $script:DSCResourceName { } It 'Should not throw when no VM is found' { Mock Get-VM -ModuleName $script:DSCResourceName { } $testVMName = 'TestVM' $result = Get-VMHyperV -VMName $testVMName $result | Should BeNullOrEmpty } It 'Should not throw when one VM is found' { Mock Get-VM -ModuleName $script:DSCResourceName { Write-Output -InputObject ([PSCustomObject] @{ Name = $VMName }) } $testVMName = 'TestVM' $result = Get-VMHyperV -VMName $testVMName $result.Name | Should Be $testVMName } It 'Should throw when more than one VM is found' { Mock Get-VM -ModuleName $script:DSCResourceName { Write-Output -InputObject ([PSCustomObject] @{ Name = $VMName }) Write-Output -InputObject ([PSCustomObject] @{ Name = $VMName }) } $testVMName = 'TestVM' { Get-VMHyperV -VMName $testVMName } | Should Throw 'More than one VM' } } # describe HyperVCommon\Get-VMHyperV } finally { #region FOOTER Restore-TestEnvironment -TestEnvironment $TestEnvironment #endregion } |