Tests/Unit/MSFT_xVMHost.tests.ps1
$script:DSCModuleName = 'xHyper-V' $script:DSCResourceName = 'MSFT_xVMHost' #region HEADER # Unit Test Template Version: 1.2.0 $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 -Name (Join-Path -Path $script:moduleRoot -ChildPath (Join-Path -Path 'DSCResource.Tests' -ChildPath 'TestHelper.psm1')) -Force $TestEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:DSCModuleName ` -DSCResourceName $script:DSCResourceName ` -TestType Unit #endregion HEADER function Invoke-TestSetup { } function Invoke-TestCleanup { Restore-TestEnvironment -TestEnvironment $TestEnvironment } # Begin Testing try { Invoke-TestSetup InModuleScope $script:DSCResourceName { $testVMName = 'UnitTestVM' Describe 'MSFT_xVMHost\Get-TargetResource' { $fakeVMHost = @{ ResourceMeteringSaveInterval = 60; } # Guard mocks function Get-VMHost { } It 'Should return a [System.Collections.Hashtable] object type' { Mock Assert-Module { } Mock Get-VMHost { return $fakeVMHost } $result = Get-TargetResource -IsSingleInstance 'Yes' $result -is [System.Collections.Hashtable] | Should Be $true } It 'Should assert Hyper-V module is installed' { Mock Assert-Module { } Mock Get-VMHost { return $fakeVMHost } $result = Get-TargetResource -IsSingleInstance 'Yes' Assert-MockCalled Assert-Module -ParameterFilter { $Name -eq 'Hyper-V' } -Scope It } } # describe Get-TargetResource Describe 'MSFT_xVMHost\Test-TargetResource' { # Guard mocks Mock Assert-Module { } function Get-VMHost { } $fakeTargetResource = @{ IsSingleInstance = 'Yes'; EnableEnhancedSessionMode = $true; FibreChannelWwnn = 'C003FF0000FFFF00'; FibreChannelWwpnMaximum = 'C003FFFBEAE1FFFF'; FibreChannelWwpnMinimum = 'C003FFFBEAE10000'; MacAddressMinimum = '00155D327500'; MacAddressMaximum = '00155D3275FF'; MaximumStorageMigrations = 2; MaximumVirtualMachineMigrations = 2; NumaSpanningEnabled = $true; ResourceMeteringSaveIntervalMinute = 60; UseAnyNetworkForMigration = $false; VirtualMachinePath ='C:\ProgramData\Microsoft\Windows\Hyper-V'; VirtualMachineMigrationAuthenticationType = 'CredSSP'; VirtualMachineMigrationPerformanceOption = 'TCPIP'; VirtualHardDiskPath = 'C:\Users\Public\Documents\Hyper-V\Virtual Hard Disks'; VirtualMachineMigrationEnabled = $true } It 'Should return a [System.Boolean] object type' { Mock Get-TargetResource { return $fakeTargetResource } $testTargetResourceParams = @{ IsSingleInstance = 'Yes'; EnableEnhancedSessionMode = $fakeTargetResource.EnableEnhancedSessionMode; VirtualMachineMigrationEnabled = $fakeTargetResource.VirtualMachineMigrationEnabled } $result = Test-TargetResource @testTargetResourceParams $result -is [System.Boolean] | Should Be $true } It 'Should assert Hyper-V module is installed' { Mock Get-TargetResource { return $fakeTargetResource } $testTargetResourceParams = @{ IsSingleInstance = 'Yes'; EnableEnhancedSessionMode = $fakeTargetResource.EnableEnhancedSessionMode; } $result = Test-TargetResource @testTargetResourceParams Assert-MockCalled Assert-Module -ParameterFilter { $Name -eq 'Hyper-V' } -Scope It } $parameterNames = @( 'EnableEnhancedSessionMode', 'FibreChannelWwnn', 'FibreChannelWwpnMaximum', 'FibreChannelWwpnMinimum', 'MacAddressMaximum', 'MacAddressMinimum', 'MaximumStorageMigrations', 'MaximumVirtualMachineMigrations', 'NumaSpanningEnabled', 'ResourceMeteringSaveIntervalMinute', 'UseAnyNetworkForMigration', 'VirtualHardDiskPath', 'VirtualMachinePath', 'VirtualMachineMigrationEnabled' ) # Test each individual parameter value separately foreach ($parameterName in $parameterNames) { $parameterValue = $fakeTargetResource[$parameterName]; $testTargetResourceParams = @{ IsSingleInstance = 'Yes'; } # Pass value verbatim so it should always pass first It "Should pass when parameter '$parameterName' is correct" { $testTargetResourceParams[$parameterName] = $parameterValue $result = Test-TargetResource @testTargetResourceParams; $result | Should Be $true; } if ($parameterValue -is [System.Boolean]) { # Invert parameter value to cause a test failure $testTargetResourceParams[$parameterName] = -not $parameterValue } elseif ($parameterValue -is [System.String]) { # Repeat string to cause a test failure $testTargetResourceParams[$parameterName] = "$parameterValue$parameterValue" } elseif ($parameterValue -is [System.Int32] -or $parameterValue -is [System.Int64]) { # Add one to cause a test failure $testTargetResourceParams[$parameterName] = $parameterValue + 1 } It "Should fail when parameter '$parameterName' is incorrect" { $result = Test-TargetResource @testTargetResourceParams; $result | Should Be $false; } } It "Should pass when parameter <Parameter> is correct" -TestCases @( @{ Parameter = 'VirtualMachineMigrationAuthenticationType'; Value = $fakeTargetResource.VirtualMachineMigrationAuthenticationType; Expected = $true; } @{ Parameter = 'VirtualMachineMigrationPerformanceOption'; Value = $fakeTargetResource.VirtualMachineMigrationPerformanceOption; Expected = $true; } @{ Parameter = 'VirtualMachineMigrationEnabled'; Value = $fakeTargetResource.VirtualMachineMigrationEnabled; Expected = $true; } ) -Test { param ( [System.String] $Parameter, [System.Object] $Value, [System.Boolean] $Expected ) $testTargetResourceParams = @{ IsSingleInstance = 'Yes'; $Parameter = $Value; } $result = Test-TargetResource @testTargetResourceParams | Should Be $Expected; } It "Should fail when parameter <Parameter> is incorrect" -TestCases @( @{ Parameter = 'VirtualMachineMigrationAuthenticationType'; Value = 'Kerberos'; Expected = $false; } @{ Parameter = 'VirtualMachineMigrationPerformanceOption'; Value = 'Compression'; Expected = $false; } @{ Parameter = 'VirtualMachineMigrationEnabled'; Value = $true; Expected = $true; } ) -Test { param ( [System.String] $Parameter, [System.Object] $Value, [System.Boolean] $Expected ) $testTargetResourceParams = @{ IsSingleInstance = 'Yes'; $Parameter = $Value; } $result = Test-TargetResource @testTargetResourceParams | Should Be $Expected; } } # describe Test-TargetResource Describe 'MSFT_xVMHost\Set-TargetResource' { function Get-VMHost { } function Set-VMHost { param ($ResourceMeteringSaveInterval) } function Enable-VMMigration { } function Disable-VMMigration { } # Guard mocks Mock Assert-Module { } Mock Get-VMHost { } Mock Set-VMHost { } Mock Enable-VMMigration { } Mock Disable-VMMigration { } It 'Should assert Hyper-V module is installed' { $setTargetResourceParams = @{ IsSingleInstance = 'Yes'; } $result = Set-TargetResource @setTargetResourceParams Assert-MockCalled Assert-Module -ParameterFilter { $Name -eq 'Hyper-V' } -Scope It } It 'Should call "Set-VMHost" with [System.TimeSpan] object when "ResourceMeteringSaveIntervalMinute" specified' { $setTargetResourceParams = @{ IsSingleInstance = 'Yes'; ResourceMeteringSaveIntervalMinute = 60; } $result = Set-TargetResource @setTargetResourceParams Assert-MockCalled Set-VMHost -ParameterFilter { $ResourceMeteringSaveInterval -is [System.TimeSpan] } } It 'Should call "Enable-VMMigration" when "VirtualMachineMigrationEnabled" is set to true and computer is domain joined' { Mock -CommandName 'Get-CimInstance' -MockWith { [pscustomobject]@{ PartOfDomain = $true } } Mock -CommandName 'Write-Error' $setTargetResourceParams = @{ IsSingleInstance = 'Yes' VirtualMachineMigrationEnabled = $true } $result = Set-TargetResource @setTargetResourceParams Assert-MockCalled -CommandName Write-Error -Times 0 -Exactly -Scope it Assert-MockCalled -CommandName Enable-VMMigration -Times 1 -Exactly -Scope it Assert-MockCalled -CommandName Disable-VMMigration -Times 0 -Exactly -Scope it } It 'Should not call "Enable-VMMigration" and should throw when "VirtualMachineMigrationEnabled" is set to true and computer is not domain joined' { Mock -CommandName 'Get-CimInstance' -MockWith { [pscustomobject]@{ PartOfDomain = $false } } $setTargetResourceParams = @{ IsSingleInstance = 'Yes' VirtualMachineMigrationEnabled = $true } { Set-TargetResource @setTargetResourceParams } | Should -Throw Assert-MockCalled -CommandName Enable-VMMigration -Times 0 -Exactly -Scope it Assert-MockCalled -CommandName Disable-VMMigration -Times 0 -Exactly -Scope it } It 'Should call "Disable-VMMigration" when "VirtualMachineMigrationEnabled" is set to false' { $setTargetResourceParams = @{ IsSingleInstance = 'Yes' VirtualMachineMigrationEnabled = $false } $result = Set-TargetResource @setTargetResourceParams Assert-MockCalled -CommandName Enable-VMMigration -Times 0 -Exactly -Scope it Assert-MockCalled -CommandName Disable-VMMigration -Times 1 -Exactly -Scope it } It 'Should not call "Disable-VMMigration" or "Enable-VMMigration" when "VirtualMachineMigrationEnabled" is not set' { $setTargetResourceParams = @{ IsSingleInstance = 'Yes' } $result = Set-TargetResource @setTargetResourceParams Assert-MockCalled -CommandName Enable-VMMigration -Times 0 -Exactly -Scope it Assert-MockCalled -CommandName Disable-VMMigration -Times 0 -Exactly -Scope it } It 'Should not call "Set-VMHost" when only "VirtualMachineMigrationEnabled" is set' { $setTargetResourceParams = @{ IsSingleInstance = 'Yes' VirtualMachineMigrationEnabled = $false Verbose = $true } $result = Set-TargetResource @setTargetResourceParams Assert-MockCalled -CommandName Enable-VMMigration -Times 0 -Exactly -Scope it Assert-MockCalled -CommandName Disable-VMMigration -Times 1 -Exactly -Scope it Assert-MockCalled -CommandName Set-VMHost -Times 0 -Exactly -Scope it } } # describe Set-TargetResource } # InModuleScope } finally { Invoke-TestCleanup } |