Tests/Unit/MSFT_xVMSwitch_Id.Tests.ps1
#region HEADER $script:DSCModuleName = 'xHyper-V' $script:DSCResourceName = 'MSFT_xVMSwitch' # Unit Test Template Version: 1.2.4 $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 ` -ResourceType 'Mof' ` -TestType Unit #endregion HEADER function Invoke-TestSetup { } function Invoke-TestCleanup { Restore-TestEnvironment -TestEnvironment $TestEnvironment } # Begin Testing try { Invoke-TestSetup InModuleScope $script:DSCResourceName { # A helper function to create a exception object for testing output exceptions function Get-InvalidArgumentError { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $ErrorId, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $ErrorMessage ) $exception = New-Object -TypeName System.ArgumentException ` -ArgumentList $ErrorMessage $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidArgument $errorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord ` -ArgumentList $exception, $ErrorId, $errorCategory, $null return $errorRecord } # A helper function to mock a VMSwitch function New-MockedVMSwitch { param ( [Parameter(Mandatory = $true)] [String] $Name, [Parameter()] [ValidateNotNullOrEmpty()] [Guid] $Id ) $mockedVMSwitch = @{ Name = $Name SwitchType = 'External' AllowManagementOS = $true EmbeddedTeamingEnabled = $true LoadBalancingAlgorithm = 'HyperVPort' BandwidthReservationMode = 'Default' NetAdapterInterfaceDescriptions = @("Microsoft Network Adapter Multiplexor Driver #1", "Microsoft Network Adapter Multiplexor Driver #2") } if ($PSBoundParameters.ContainsKey('Id')) { $mockedVMSwitch['Id'] = $Id } else { $mockedVMSwitch['Id'] = New-Guid } return [PsObject]$mockedVMSwitch } # Mocks "Get-Module -Name Hyper-V" so that the DSC resource thinks the Hyper-V module is on the test system Mock -CommandName Get-Module -ParameterFilter { ($Name -eq 'Hyper-V') -and ($ListAvailable -eq $true) } -MockWith { return $true } function Get-VMSwitch { } Mock -CommandName Get-VMSwitch -MockWith { return $Global:MockedVMSwitch } function Get-NetAdapter { } Mock -CommandName Get-NetAdapter -MockWith { return @( [PSCustomObject]@{ Name = 'NIC1' InterfaceDescription = 'Microsoft Network Adapter Multiplexor Driver #1' } [PSCustomObject]@{ Name = 'NIC2' InterfaceDescription = 'Microsoft Network Adapter Multiplexor Driver #2' } ) } function Get-VMSwitchTeam { } Mock -CommandName Get-VMSwitchTeam -MockWith { return [PSCustomObject]@{ Name = 'TestTeam' Id = New-Guid NetAdapterInterfaceDescription = @("Microsoft Network Adapter Multiplexor Driver #1", "Microsoft Network Adapter Multiplexor Driver #2") TeamingMode = 'SwitchIndependent' LoadBalancingAlgorithm = 'HyperVPort' } } function Remove-VMSwitch {} Mock -CommandName Remove-VMSwitch -MockWith { $Global:mockedVMSwitch = $null } function New-VMSwitch {} Mock -CommandName New-VMSwitch -MockWith { Param( [Parameter()] [String] $Name, [Parameter()] [String[]] $NetAdapterName, [Parameter()] [String] $MinimumBandwidthMode, [Parameter()] [bool] $AllowManagementOS, [Parameter()] [String] $SwitchType, [Parameter()] [bool] $EnableEmbeddedTeaming, [Parameter()] [Guid] $Id ) if($PSBoundParameters.ContainsKey('Id')) { $Global:MockedVMSwitch = New-MockedVMSwitch -Name $Name -Id $id } else { $Global:MockedVMSwitch = New-MockedVMSwitch -Name $Name } } function Get-OSVersion { } Mock -CommandName Get-OSVersion -MockWith { [PSCustomObject]@{ Major = 10 Minor = 0 Build = 14393 Revision = 0 MajorRevision = 0 MinorRevision = 0 } } Describe 'MSFT_xVMSwitch\Get-TargetResource' -Tag 'Get' { Context 'When the system is in the desired state (VMSwitch has the desired Id)' { $Global:MockedVMSwitch = New-MockedVMSwitch -Name 'TestSwitch' It 'Should return "present"' { (Get-TargetResource -Name 'TestSwitch' -Type 'External').Ensure | Should Be 'Present' Assert-MockCalled -CommandName "Get-VMSwitch" -Times 1 Assert-MockCalled -CommandName "Get-VMSwitchTeam" -Times 1 } } Context 'When the system is not in the desired state (VMSwitch has not the desired Id)' { $Global:mockedVMSwitch = $null It 'Should return "absent"' { (Get-TargetResource -Name 'TestSwitch' -Type 'External').Ensure | Should Be 'Absent' Assert-MockCalled -CommandName "Get-VMSwitch" -Times 1 Assert-MockCalled -CommandName "Get-VMSwitchTeam" -Times 0 } } } Describe 'MSFT_xVMSwitch\Set-TargetResource' -Tag 'Set' { Context 'When the system is in the desired state (VMSwitch has the desired Id)' { $desiredVMSwitchID = New-Guid $Global:mockedVMSwitch = New-MockedVMSwitch -Name 'TestSwitch' -Id $desiredVMSwitchID $testParams = @{ Name = 'TestSwitch' Type = 'External' NetAdapterName = @('NIC1', 'NIC2') AllowManagementOS = $true EnableEmbeddedTeaming = $true Ensure = 'Present' Id = $desiredVMSwitchID } It 'Should run without without exceptions' { {Set-TargetResource @testParams} | Should -Not -Throw Assert-MockCalled -CommandName "Get-VMSwitch" -Times 1 Assert-MockCalled -CommandName 'Get-NetAdapter' -Times 1 } } Context 'When the system is not in the desired state (VMSwitch has not the desired Id)' { $Global:mockedVMSwitch = New-MockedVMSwitch -Name 'TestSwitch' $testParams = @{ Name = 'TestSwitch' Type = 'External' NetAdapterName = @('NIC1', 'NIC2') AllowManagementOS = $true EnableEmbeddedTeaming = $true Ensure = 'Present' Id = New-Guid } It 'Should run without exception while re-creating the VMSwitch' { {Set-TargetResource @testParams} | Should -Not -Throw Assert-MockCalled -CommandName "Get-VMSwitch" -Times 1 Assert-MockCalled -CommandName 'Get-NetAdapter' -Times 1 Assert-MockCalled -CommandName 'Remove-VMSwitch' -Times 1 Assert-MockCalled -CommandName 'New-VMSwitch' -Times 1 } } Context 'When the specified value for Id parameter is not a GUID' { $Global:mockedVMSwitch = New-MockedVMSwitch -Name 'TestSwitch' $testParams = @{ Name = 'TestSwitch' Type = 'External' NetAdapterName = @('NIC1', 'NIC2') AllowManagementOS = $true EnableEmbeddedTeaming = $true Ensure = 'Present' Id = '123' } It 'Should throw "The VMSwitch Id must be in GUID format!"' { {Set-TargetResource @testParams} | Should -Throw 'The VMSwitch Id must be in GUID format!' } } Context 'When the system is not running Server 2016' { $desiredVMSwitchID = New-Guid $Global:mockedVMSwitch = New-MockedVMSwitch -Name 'TestSwitch' -Id $desiredVMSwitchID $testParams = @{ Name = 'TestSwitch' Type = 'External' NetAdapterName = 'NIC1' AllowManagementOS = $true EnableEmbeddedTeaming = $false Ensure = 'Present' Id = $desiredVMSwitchID } Mock -CommandName Get-OSVersion -MockWith { return [Version]::Parse('6.3.9600') } $errorRecord = Get-InvalidArgumentError ` -ErrorId 'VMSwitchIDServer2016Error' ` -ErrorMessage $LocalizedData.VMSwitchIDServer2016Error It 'Should throw "VMSwitchIDServer2016Error"' { {Set-TargetResource @testParams} | Should -Throw $errorRecord } } } Describe 'MSFT_xVMSwitch\Test-TargetResource' -Tag 'Test' { Context 'When the system is in the desired state (VMSwitch has the desired Id)' { $desiredVMSwitchID = New-Guid $Global:mockedVMSwitch = New-MockedVMSwitch -Name 'TestSwitch' -Id $desiredVMSwitchID $testParams = @{ Name = 'TestSwitch' Type = 'External' NetAdapterName = @('NIC1', 'NIC2') AllowManagementOS = $true EnableEmbeddedTeaming = $true Ensure = 'Present' Id = $desiredVMSwitchID } It 'Should return $true' { {Test-TargetResource @testParams} | Should -Not -Throw Assert-MockCalled -CommandName "Get-VMSwitch" -Times 1 Assert-MockCalled -CommandName 'Get-NetAdapter' -Times 1 } } Context 'When the system is not in the desired state (VMSwitch has not the desired Id)' { $Global:mockedVMSwitch = New-MockedVMSwitch -Name 'TestSwitch' $testParams = @{ Name = 'TestSwitch' Type = 'External' NetAdapterName = @('NIC1', 'NIC2') AllowManagementOS = $true EnableEmbeddedTeaming = $true Ensure = 'Present' Id = New-Guid } It 'Should return $false' { {Test-TargetResource @testParams} | Should -Not -Throw Assert-MockCalled -CommandName "Get-VMSwitch" -Times 1 Assert-MockCalled -CommandName 'Get-NetAdapter' -Times 1 } } Context 'When the specified value for Id parameter is not a GUID' { $Global:mockedVMSwitch = New-MockedVMSwitch -Name 'TestSwitch' $testParams = @{ Name = 'TestSwitch' Type = 'External' NetAdapterName = @('NIC1', 'NIC2') AllowManagementOS = $true EnableEmbeddedTeaming = $true Ensure = 'Present' Id = '123' } It 'Should throw "The VMSwitch Id must be in GUID format!"' { {Test-TargetResource @testParams} | Should -Throw 'The VMSwitch Id must be in GUID format!' } } Context 'When the system is not running Server 2016' { $desiredVMSwitchID = New-Guid $Global:mockedVMSwitch = New-MockedVMSwitch -Name 'TestSwitch' -Id $desiredVMSwitchID $testParams = @{ Name = 'TestSwitch' Type = 'External' NetAdapterName = 'NIC1' AllowManagementOS = $true EnableEmbeddedTeaming = $false Ensure = 'Present' Id = $desiredVMSwitchID } Mock -CommandName Get-OSVersion -MockWith { return [Version]::Parse('6.3.9600') } $errorRecord = Get-InvalidArgumentError ` -ErrorId 'VMSwitchIDServer2016Error' ` -ErrorMessage $LocalizedData.VMSwitchIDServer2016Error It 'Should throw "VMSwitchIDServer2016Error"' { {Test-TargetResource @testParams} | Should -Throw $errorRecord } } } } } finally { Invoke-TestCleanup } |