Tests/Unit/MSFT_xVMSwitch_EnableEmbeddedTeaming.Tests.ps1
#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 'xHyper-V' ` -DSCResourceName 'MSFT_xVMSwitch' ` -TestType Unit #endregion HEADER function Invoke-TestSetup { } function Invoke-TestCleanup { Restore-TestEnvironment -TestEnvironment $TestEnvironment } # Begin Testing try { Invoke-TestSetup InModuleScope 'MSFT_xVMSwitch' { # 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 } # end function Get-InvalidArgumentError # A helper function to mock a VMSwitch function New-MockedVMSwitch { param ( [Parameter(Mandatory = $true)] [string] $Name, [Parameter(Mandatory = $true)] [ValidateSet('Default', 'Weight', 'Absolute', 'None', 'NA')] [string] $BandwidthReservationMode, [parameter()] [ValidateSet('Dynamic','HyperVPort')] [String] $LoadBalancingAlgorithm, [Parameter()] [bool] $AllowManagementOS = $false ) $mockedVMSwitch = @{ Name = $Name SwitchType = 'External' AllowManagementOS = $AllowManagementOS NetAdapterInterfaceDescription = 'Microsoft Network Adapter Multiplexor Driver' } if ($BandwidthReservationMode -ne 'NA') { $mockedVMSwitch['BandwidthReservationMode'] = $BandwidthReservationMode } if($PSBoundParameters.ContainsKey('LoadBalancingAlgorithm')) { $mockedVMSwitch['LoadBalancingAlgorithm'] = $LoadBalancingAlgorithm } return [PsObject]$mockedVMSwitch } Describe "MSFT_xVMSwitch" { # Create empty functions to be able to mock the missing Hyper-V cmdlet function Get-VMSwitch { } function New-VMSwitch { } function Set-VMSwitch { } function Remove-VMSwitch { } function Get-VMSwitchTeam { } function Set-VMSwitchTeam { } <# Mocks Get-VMSwitch and will return $global:mockedVMSwitch which is a variable that is created during most It statements to mock a VMSwitch #> Mock -CommandName Get-VMSwitch -MockWith { param ( [string] $Name, [string] $SwitchType, [string] $ErrorAction ) if ($ErrorAction -eq 'Stop' -and $global:mockedVMSwitch -eq $null) { throw [System.Management.Automation.ActionPreferenceStopException]'No switch can be found by given criteria.' } return $global:mockedVMSwitch } <# Mocks New-VMSwitch and will assign a mocked switch to $global:mockedVMSwitch. This returns $global:mockedVMSwitch which is a variable that is created during most It statements to mock a VMSwitch #> Mock -CommandName New-VMSwitch -MockWith { param ( [string] $Name, [string[]] $NetAdapterName, [string] $MinimumBandwidthMode = 'NA', [bool] $EnableEmbeddedTeaming, [bool] $AllowManagementOS ) $global:mockedVMSwitch = New-MockedVMSwitch -Name $Name -BandwidthReservationMode $MinimumBandwidthMode -AllowManagementOS $AllowManagementOS #is SET is enabled mok a VMSwitchTeam if($EnableEmbeddedTeaming){ $global:mockedVMSwitchTeam = [PSCustomObject]@{ Name = "TestSwitch" Id = [Guid]::NewGuid() TeamingMode = 'SwitchIndependent' LoadBalancingAlgorithm = 'Dynamic' } } return $global:mockedVMSwitch } Mock -CommandName Get-OSVersion -MockWith { return @{ Major = 10 } } <# Mocks Set-VMSwitch and will modify $global:mockedVMSwitch which is a variable that is created during most It statements to mock a VMSwitch #> Mock -CommandName Set-VMSwitch -MockWith { param ( [bool] $AllowManagementOS ) if ($AllowManagementOS) { $global:mockedVMSwitch['AllowManagementOS'] = $AllowManagementOS } } <# Mocks Remove-VMSwitch and will remove the variable $global:mockedVMSwitch which is a variable that is created during most It statements to mock a VMSwitch #> Mock -CommandName Remove-VMSwitch -MockWith { $global:mockedVMSwitch = $null } <# Mocks Get-VMSwitchTeam and will return a moked VMSwitchTeam #> Mock -CommandName Get-VMSwitchTeam -MockWith { return $global:mockedVMSwitchTeam } <# Mocks Set-VMSwitchTeam and will return a moked VMSwitchTeam #> Mock -CommandName Set-VMSwitchTeam -MockWith { param ( [parameter(Mandatory=$true)] [ValidateSet('Dynamic','HyperVPort')] [String] $LoadBalancingAlgorithm, [String] $Name ) $global:mockedVMSwitchTeam.LoadBalancingAlgorithm = $LoadBalancingAlgorithm } # Mocks Get-NetAdapter which returns a simplified network adapter 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' } ) } # 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 } Context "A virtual switch with embedded teaming does not exist but should" { $global:mockedVMSwitch = $null $testParams = @{ Name = "TestSwitch" Type = "External" NetAdapterName = @("NIC1", "NIC2") AllowManagementOS = $true EnableEmbeddedTeaming = $true BandwidthReservationMode = "NA" Ensure = "Present" } It "Should return absent in the get method" { (Get-TargetResource -Name $testParams.Name -Type $testParams.Type).Ensure | Should Be "Absent" } It "Should return false in the test method" { Test-TargetResource @testParams | Should Be $false } It "Should run the set method without exceptions" { Set-TargetResource @testParams Assert-MockCalled -CommandName "New-VMSwitch" -Times 1 } } Context "A virtual switch with embedded teaming exists and should" { $global:mockedVMSwitch = @{ Name = "TestSwitch" SwitchType = "External" AllowManagementOS = $true EmbeddedTeamingEnabled = $true Id = [Guid]::NewGuid() NetAdapterInterfaceDescriptions = @("Microsoft Network Adapter Multiplexor Driver #1", "Microsoft Network Adapter Multiplexor Driver #2") } $testParams = @{ Name = "TestSwitch" Type = "External" NetAdapterName = @("NIC1", "NIC2") AllowManagementOS = $true EnableEmbeddedTeaming = $true BandwidthReservationMode = "NA" Ensure = "Present" } It "Should return present in the get method" { (Get-TargetResource -Name $testParams.Name -Type $testParams.Type).Ensure | Should Be "Present" } It "Should return true in the test method" { Test-TargetResource @testParams | Should Be $true } } Context "A virtual switch with embedded teaming exists but does not refer to the correct adapters" { $global:mockedVMSwitch = @{ Name = "TestSwitch" SwitchType = "External" AllowManagementOS = $true EmbeddedTeamingEnabled = $true Id = [Guid]::NewGuid() NetAdapterInterfaceDescriptions = @("Wrong adapter", "Microsoft Network Adapter Multiplexor Driver #2") } Mock -CommandName Get-NetAdapter -MockWith { return @( [PSCustomObject]@{ Name = 'WrongNic' InterfaceDescription = 'Wrong adapter' } [PSCustomObject]@{ Name = 'NIC2' InterfaceDescription = 'Microsoft Network Adapter Multiplexor Driver #2' } ) } $testParams = @{ Name = "TestSwitch" Type = "External" NetAdapterName = @("NIC1", "NIC2") AllowManagementOS = $true EnableEmbeddedTeaming = $true BandwidthReservationMode = "NA" Ensure = "Present" } It "Should return present in the get method" { (Get-TargetResource -Name $testParams.Name -Type $testParams.Type).Ensure | Should Be "Present" } It "Should return false in the test method" { Test-TargetResource @testParams | Should Be $false } It "Should run the set method without exceptions" { Set-TargetResource @testParams Assert-MockCalled -CommandName "Remove-VMSwitch" -Times 1 Assert-MockCalled -CommandName "New-VMSwitch" -Times 1 } } Context "A virtual switch with embedded teaming exists but does not use the correct LB algorithm" { $global:mockedVMSwitch = @{ Name = "TestSwitch" SwitchType = "External" AllowManagementOS = $true EmbeddedTeamingEnabled = $true LoadBalancingAlgorithm = 'Dynamic' Id = [Guid]::NewGuid() NetAdapterInterfaceDescriptions = @("Microsoft Network Adapter Multiplexor Driver #1", "Microsoft Network Adapter Multiplexor Driver #2") } Mock -CommandName Get-NetAdapter -MockWith { return @( [PSCustomObject]@{ Name = 'NIC01' InterfaceDescription = "Microsoft Network Adapter Multiplexor Driver #1" } [PSCustomObject]@{ Name = 'NIC2' InterfaceDescription = 'Microsoft Network Adapter Multiplexor Driver #2' } ) } $testParams = @{ Name = "TestSwitch" Type = "External" NetAdapterName = @("NIC1", "NIC2") AllowManagementOS = $true EnableEmbeddedTeaming = $true LoadBalancingAlgorithm = 'HyperVPort' Ensure = "Present" } It "Should return present in the get method" { (Get-TargetResource -Name $testParams.Name -Type $testParams.Type).Ensure | Should Be "Present" } It "Should return false in the test method" { Test-TargetResource @testParams | Should Be $false } It "Should run the set method without exceptions" { Set-TargetResource @testParams Assert-MockCalled -CommandName "Remove-VMSwitch" -Times 1 Assert-MockCalled -CommandName "New-VMSwitch" -Times 1 } } Context "A virtual switch without embedded teaming exists but should use embedded teaming" { $global:mockedVMSwitch = @{ Name = "TestSwitch" SwitchType = "External" AllowManagementOS = $true EmbeddedTeamingEnabled = $false Id = [Guid]::NewGuid() NetAdapterInterfaceDescription = "Microsoft Network Adapter Multiplexor Driver #1" } $testParams = @{ Name = "TestSwitch" Type = "External" NetAdapterName = @("NIC1", "NIC2") AllowManagementOS = $true EnableEmbeddedTeaming = $true BandwidthReservationMode = "NA" Ensure = "Present" } It "Should return present in the get method" { (Get-TargetResource -Name $testParams.Name -Type $testParams.Type).Ensure | Should Be "Present" } It "Should return false in the test method" { Test-TargetResource @testParams | Should Be $false } It "Should run the set method without exceptions" { Set-TargetResource @testParams Assert-MockCalled -CommandName "Remove-VMSwitch" -Times 1 Assert-MockCalled -CommandName "New-VMSwitch" -Times 1 } } Context "A virtual switch with embedded teaming exists but shouldn't" { $global:mockedVMSwitch = @{ Name = "TestSwitch" SwitchType = "External" AllowManagementOS = $true EmbeddedTeamingEnabled = $true Id = [Guid]::NewGuid() NetAdapterInterfaceDescriptions = @("Microsoft Network Adapter Multiplexor Driver #1", "Microsoft Network Adapter Multiplexor Driver #2") } $testParams = @{ Name = "TestSwitch" Type = "Internal" Ensure = "Absent" } It "Should return present in the get method" { (Get-TargetResource -Name $testParams.Name -Type $testParams.Type).Ensure | Should Be "Present" } It "Should return false in the test method" { Test-TargetResource @testParams | Should Be $false } It "Should run the set method without exceptions" { Set-TargetResource @testParams Assert-MockCalled -CommandName "Remove-VMSwitch" -Times 1 } } Context "A virtual switch with embedded teaming does not exist and shouldn't" { $global:mockedVMSwitch = $null $testParams = @{ Name = "TestSwitch" Type = "Internal" Ensure = "Absent" } It "Should return absent in the get method" { (Get-TargetResource -Name $testParams.Name -Type $testParams.Type).Ensure | Should Be "Absent" } It "Should return true in the test method" { Test-TargetResource @testParams | Should Be $true } } Context "A server is not running Server 2016 and attempts to use embedded teaming" { $global:mockedVMSwitch = $null $testParams = @{ Name = "TestSwitch" Type = "External" NetAdapterName = @("NIC1", "NIC2") AllowManagementOS = $true EnableEmbeddedTeaming = $true BandwidthReservationMode = "NA" Ensure = "Present" } Mock -CommandName Get-OSVersion -MockWith { return [Version]::Parse('6.3.9600') } It "Should return absent in the get method" { (Get-TargetResource -Name $testParams.Name -Type $testParams.Type).Ensure | Should Be "Absent" } It "Should throw an error in the test method" { $errorRecord = Get-InvalidArgumentError ` -ErrorId 'SETServer2016Error' ` -ErrorMessage $LocalizedData.SETServer2016Error {Test-TargetResource @testParams} | Should Throw $errorRecord } It "Should throw an error in the set method" { $errorRecord = Get-InvalidArgumentError ` -ErrorId 'SETServer2016Error' ` -ErrorMessage $LocalizedData.SETServer2016Error {Set-TargetResource @testParams} | Should Throw $errorRecord } } } } } finally { Invoke-TestCleanup } |