Tests/Unit/MSFT_xVMScsiController.Tests.ps1
$script:DSCModuleName = 'xHyper-V' $script:DSCResourceName = 'MSFT_xVMScsiController' #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_xVMScsiController\Get-TargetResource' { $stubScsiController = @{ VMName = $testVMName ControllerNumber = 0 } # Guard mocks Mock Assert-Module { } function Get-VMScsiController { [CmdletBinding()] param ( [System.String] $VMName, [System.Int32] $ControllerNumber ) } It 'Should return a [System.Collections.Hashtable] object type' { Mock Get-VMScsiController { return $stubScsiController } $result = Get-TargetResource -VMName $testVMName -ControllerNumber 0 $result -is [System.Collections.Hashtable] | Should Be $true } It 'Should return "Present" when controller is attached' { Mock Get-VMScsiController { return $stubScsiController } $result = Get-TargetResource -VMName $testVMName -ControllerNumber 0 $result.Ensure | Should Be 'Present' } It 'Should return "Absent" when controller is not attached' { Mock Get-VMScsiController { } $result = Get-TargetResource -VMName $testVMName -ControllerNumber 0 $result.Ensure | Should Be 'Absent' } It 'Should assert Hyper-V module is installed' { Mock Assert-Module { } Mock Get-VMScsiController { } $null = Get-TargetResource -VMName $testVMName -ControllerNumber 0 Assert-MockCalled Assert-Module -ParameterFilter { $Name -eq 'Hyper-V' } -Scope It } } # descrive Get-TargetResource Describe 'MSFT_xVMScsiController\Test-TargetResource' { # Guard mocks Mock Assert-Module { } $stubTargetResource = @{ VMName = $testVMName ControllerNumber = 0 Ensure = 'Present' } It 'Should return a [System.Boolean] object type' { Mock Get-TargetResource { return $stubTargetResource } $testTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 } $result = Test-TargetResource @testTargetResourceParams $result -is [System.Boolean] | Should Be $true } It "Should pass when parameter 'Ensure' is correct" { Mock Get-TargetResource { return $stubTargetResource } $testTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 Ensure = $stubTargetResource['Ensure'] } $result = Test-TargetResource @testTargetResourceParams $result | Should Be $true } It "Should fail when parameter 'Ensure' is incorrect" { Mock Get-TargetResource { return $stubTargetResource } $testTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 Ensure = 'Absent' } $result = Test-TargetResource @testTargetResourceParams $result | Should Be $false } } # describe Test-TargetResource Describe 'MSFT_xVMScsiController\Set-TargetResource' { function Get-VMScsiController { param ( [System.String] $VMName ) } function Add-VMScsiController { param ( [System.String] $VMName ) } function Remove-VMScsiController { param ( [System.String] $VMName ) } function Remove-VMHardDiskDrive { param ( [System.Object] $VMHardDiskDrive ) } # Guard mocks Mock Assert-Module { } Mock Get-VMScsiController { } Mock Add-VMScsiController { } Mock Remove-VMScsiController { } Mock Remove-VMHardDiskDrive { } Mock Set-VMState { } It 'Should assert Hyper-V module is installed' { Mock Get-VMHyperV { return @{ State = 'Running' } } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 RestartIfNeeded = $true } $null = Set-TargetResource @setTargetResourceParams Assert-MockCalled Assert-Module } It 'Should throw if "RestartIfNeeded" is not specified and VM is "Running"' { Mock Get-VMHyperV { return @{ State = 'Running' } } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 } { Set-TargetResource @setTargetResourceParams } | Should Throw 'RestartIfNeeded' } It 'Should not throw if "RestartIfNeeded" is not specified and VM is "Off"' { Mock Get-VMHyperV { return @{ State = 'Off' } } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 } { Set-TargetResource @setTargetResourceParams } | Should Not Throw } It 'Should call "Set-VMState" to stop running VM' { Mock Get-VMHyperV { return @{ State = 'Running' } } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 RestartIfNeeded = $true } $null = Set-TargetResource @setTargetResourceParams Assert-MockCalled Set-VMState -ParameterFilter { $State -eq 'Off' } -Scope It } It 'Should call "Set-VMState" to restore VM to its previous state' { $testVMState = 'Paused' Mock Get-VMHyperV { return @{ State = $testVMState } } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 RestartIfNeeded = $true } $null = Set-TargetResource @setTargetResourceParams Assert-MockCalled Set-VMState -ParameterFilter { $State -eq $testVMState } -Scope It } It 'Should add single controller when it does not exist' { Mock Get-VMHyperV { return @{ State = 'Running' } } Mock Get-VMScsiController { } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 RestartIfNeeded = $true } $null = Set-TargetResource @setTargetResourceParams Assert-MockCalled Add-VMScsiController -Scope It -Exactly 1 } It 'Should add single controller when one already exists' { Mock Get-VMHyperV { return @{ State = 'Running' } } $fakeVMScsiController = [PSCustomObject] @{ ControllerNumber = 0 } Mock Get-VMScsiController { return $fakeVMScsiController } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 1 RestartIfNeeded = $true } $null = Set-TargetResource @setTargetResourceParams Assert-MockCalled Add-VMScsiController -Scope It -Exactly 1 } It 'Should throw when adding controller when intermediate controller(s) do not exist' { Mock Get-VMHyperV { return @{ State = 'Running' } } Mock Get-VMScsiController { } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 1 RestartIfNeeded = $true } { Set-TargetResource @setTargetResourceParams } | Should Throw 'Cannot add controller' } It 'Should remove controller when Ensure = "Absent"' { Mock Get-VMHyperV { return @{ State = 'Running' } } $fakeVMScsiControllers = @( [PSCustomObject] @{ ControllerNumber = 0 } [PSCustomObject] @{ ControllerNumber = 1 } ) Mock Get-VMScsiController { return $fakeVMScsiControllers } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 1 RestartIfNeeded = $true Ensure = 'Absent' } $null = Set-TargetResource @setTargetResourceParams -WarningAction SilentlyContinue Assert-MockCalled Remove-VMScsiController -Scope It } It 'Should remove all attached disks when Ensure = "Absent"' { Mock Get-VMHyperV { return @{ State = 'Running' } } $fakeVMScsiController = [PSCustomObject] @{ ControllerNumber = 0 Drives = @( [PSCustomObject] @{ Name = 'Hard Drive on SCSI controller number 0 at location 0' } [PSCustomObject] @{ Name = 'Hard Drive on SCSI controller number 0 at location 1' } ) } Mock Get-VMScsiController { return $fakeVMScsiController } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 RestartIfNeeded = $true Ensure = 'Absent' } $null = Set-TargetResource @setTargetResourceParams -WarningAction SilentlyContinue Assert-MockCalled Remove-VMHardDiskDrive -Scope It -Exactly ($fakeVMScsiController.Drives.Count) } It 'Should throw removing a controller when additional/subsequent controller(s) exist' { Mock Get-VMHyperV { return @{ State = 'Running' } } $fakeVMScsiControllers = @( [PSCustomObject] @{ ControllerNumber = 0 } [PSCustomObject] @{ ControllerNumber = 1 } ) Mock Get-VMScsiController { return $fakeVMScsiControllers } $setTargetResourceParams = @{ VMName = $testVMName ControllerNumber = 0 RestartIfNeeded = $true Ensure = 'Absent' } { Set-TargetResource @setTargetResourceParams } | Should Throw 'Cannot remove controller' } } # describe Set-TargetResource } # InModuleScope } finally { Invoke-TestCleanup } |