ps/Modules/Alkami.DevOps.SystemEngineering/Public/Get-TerminatedComputersReport.tests.ps1

202 lines
11 KiB
PowerShell
Raw Normal View History

2023-05-30 22:51:22 -07:00
. $PSScriptRoot\..\..\Load-PesterModules.ps1
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.tests\.', '.'
$functionPath = Join-Path -Path $here -ChildPath $sut
Write-Host "Overriding SUT: $functionPath"
Import-Module $functionPath -Force
$moduleForMock = ""
# We need to use their stupid [Amazon.EC2.Model.Tag], so we have to import their module.
Import-Module AWSPowerShell
Mock -CommandName Get-LogLeadName -ModuleName $moduleForMock -MockWith { return 'Get-TerminatedComputersReport.tests' }
Mock -CommandName Write-Progress -ModuleName $moduleForMock -MockWith {}
Mock -CommandName Import-Module -ModuleName $moduleForMock -MockWith {}
Mock -CommandName Get-Date -ModuleName $moduleForMock -MockWith {return ([datetime]::Now)}
Mock -CommandName Write-Error -ModuleName $moduleForMock -MockWith {}
Mock -CommandName Test-IsTeamCityProcess -ModuleName $moduleForMock -MockWith { return $false }
$credential = ([pscredential]::new("test",("test1" | ConvertTo-SecureString -AsPlainText -Force)))
Describe "Get-TerminatedComputersReport" {
Context "When a parameter value is not valid or missing" {
It "Throws an exception if Credential parameter is blank" {
{ Get-TerminatedComputersReport -Credential -Domain fh.local } | Should -Throw
}
It "Throws an exception if Domain parameter is blank" {
{ Get-TerminatedComputersReport -Credential $credential -Domain } | Should -Throw
}
It "Throws an exception if OU is not provided a value" {
{ Get-TerminatedComputersReport -OU } | Should -Throw
}
It "Throws an exception if NumberOfDays is not provided a value" {
{ Get-TerminatedComputersReport -NumberOfDays } | Should -Throw
}
It "Throws an exception if NumberOfDays is outside of the valid range" {
{ Get-TerminatedComputersReport -NumberOfDays 366 } | Should -Throw
}
}
Context "Error Handling"{
It "Writes an error if AWSPowerShell cannot be loaded" {
Mock -CommandName Get-Module -ModuleName $moduleForMock -MockWith {[pscustomobject]@{"Name" = "NotAWSPowerShell"}}
Mock -CommandName Import-Module -ModuleName $moduleForMock -MockWith { throw "Module not found."}
Get-TerminatedComputersReport -CheckAWS
Assert-MockCalled -CommandName Write-Error -Times 1 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*Unable to load the AWSPowerShell module*"}
}
It "Writes an error if DNS for the domain cannot be resolved" {
Mock -CommandName Resolve-DnsName -ModuleName $moduleForMock -MockWith { throw "It's always DNS."}
Get-TerminatedComputersReport -Credential $credential -Domain fh.local
Assert-MockCalled -CommandName Write-Error -Times 1 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*Error when resolving DNS for*"}
}
It "Writes an error if bad credentials are supplied" {
Mock -CommandName Resolve-DnsName -ModuleName $moduleForMock -MockWith { return [pscustomobject]@{"IPAddress"="10.0.0.1"} }
Mock -CommandName Test-Connection -ModuleName $moduleForMock -MockWith { return [pscustomobject]@{"Address"="10.0.0.1";"ResponseTime" = 25} }
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith { throw [System.Security.Authentication.AuthenticationException]::new("The server has rejected the client credentials.") }
Get-TerminatedComputersReport -Credential $credential -Domain fh.local
Assert-MockCalled -CommandName Write-Error -Times 1 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*Unable to connect to the target domain, invalid credentials*"}
}
It "Writes an error if unable to retrieve AD Computer objects" {
Mock -CommandName Resolve-DnsName -ModuleName $moduleForMock -MockWith { return [pscustomobject]@{"IPAddress"="10.0.0.1"} }
Mock -CommandName Test-Connection -ModuleName $moduleForMock -MockWith { return [pscustomobject]@{"Address"="10.0.0.1";"ResponseTime" = 25} }
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith { throw "Something bad happened"}
Get-TerminatedComputersReport -Credential $credential -Domain fh.local
Assert-MockCalled -CommandName Write-Error -Times 1 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*Unable to retrieve Computer objects from AD*"}
}
It "Writes an error if unable to retrieve EC2 instances from us-east-1" {
Mock -CommandName Get-Module -ModuleName $moduleForMock -MockWith {[pscustomobject]@{"Name" = "AWSPowerShell"}}
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith {}
Mock -CommandName Get-EC2Instance -ModuleName $moduleForMock -ParameterFilter { $Region -eq "us-east-1"} -MockWith {throw "Error getting EC2 in us-east-1"}
Get-TerminatedComputersReport -CheckAWS
Assert-MockCalled -CommandName Write-Error -Times 4 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*An error occurred while retrieving EC2 instances in us-east-1*"}
}
It "Writes an error if unable to retrieve EC2 instances from us-west-2"{
Mock -CommandName Get-Module -ModuleName $moduleForMock -MockWith {[pscustomobject]@{"Name" = "AWSPowerShell"}}
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith {}
Mock -CommandName Get-EC2Instance -ModuleName $moduleForMock -ParameterFilter { $Region -eq "us-east-1"} -MockWith {}
Mock -CommandName Get-EC2Instance -ModuleName $moduleForMock -ParameterFilter { $Region -eq "us-west-2"} -MockWith {throw "Error getting EC2 in us-west-2"}
Get-TerminatedComputersReport -CheckAWS
Assert-MockCalled -CommandName Get-EC2Instance -Times 5 -Exactly -ModuleName $moduleForMock -Scope It
Assert-MockCalled -CommandName Write-Error -Times 1 -Exactly -ModuleName $moduleForMock -Scope It -ParameterFilter { $Message -like "*An error occurred while retrieving EC2 instances in us-west-2*"}
}
}
Context "Returns results" {
$testDate = Get-Date
It "Returns results without comparing to AWS" {
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith {
return (
[pscustomobject]@{
"Name" = "TestComputerName"
"Enabled" = $true
"IPv4Address" = "10.0.0.2"
"lastLogonDate" = $testDate
"PasswordLastSet" = $testDate
"SID" = "The-Sloth"
}
)
}
$adOnlyTest = Get-TerminatedComputersReport
$expected = [pscustomobject]@{
"ADName" = "TestComputerName"
"IsEnabled" = $true
"ADIPv4Address" = "10.0.0.2"
"LastLogon" = $testDate
"PasswordLastSet" = $testDate
"SID" = "The-Sloth"
"TerminationConfidence" = [byte](($testDate) -lt ($testDate).AddDays(-90))
}
(($adOnlyTest).ADName -eq ($expected).ADName) | Should -BeTrue
(($adOnlyTest).IsEnabled -eq ($expected).IsEnabled) | Should -BeTrue
(($adOnlyTest).ADIPv4Address -eq ($expected).ADIPv4Address) | Should -BeTrue
(($adOnlyTest).LastLogon -eq ($expected).LastLogon) | Should -BeTrue
(($adOnlyTest).PasswordLastSet -eq ($expected).PasswordLastSet) | Should -BeTrue
(($adOnlyTest).SID -eq ($expected).SID) | Should -BeTrue
(($adOnlyTest).TerminationConfidence -eq ($expected).TerminationConfidence) | Should -BeTrue
}
It "Returns results comparing to AWS" {
Mock -CommandName Get-Module -ModuleName $moduleForMock -MockWith {[pscustomobject]@{"Name" = "AWSPowerShell"}}
$script:mockCalled = 0
$getEC2InstanceMock = {
$script:mockCalled++
if($script:mockCalled -eq 1){
# This is a hot mess, but we are trying to replicate the blackmagic that AWS has created when returning these objects
return (
@{"Instances"=[pscustomobject]@{
"InstanceId" = "i-AmTheSloth"
"PrivateIPAddress" = "10.0.0.2"
"tags" = @([Amazon.EC2.Model.Tag]::new("alk:hostname","TestComputerName"),[Amazon.EC2.Model.Tag]::new("alk:designation","1000"))
}
}
)
} else {
return $null
}
}
Mock -CommandName Get-ADComputer -ModuleName $moduleForMock -MockWith {
return (
[pscustomobject]@{
"Name" = "TestComputerName"
"Enabled" = $true
"IPv4Address" = "10.0.0.2"
"lastLogonDate" = $testDate
"PasswordLastSet" = $testDate
"SID" = "The-Sloth"
}
)
}
Mock -CommandName Get-EC2Instance -ModuleName $moduleForMock -MockWith $getEC2InstanceMock
$awsTest = Get-TerminatedComputersReport -CheckAWS
$expected = [pscustomobject]@{
"ADName" = "TestComputerName"
"IsEnabled" = $true
"ADIPv4Address" = "10.0.0.2"
"LastLogon" = $testDate
"PasswordLastSet" = $testDate
"SID" = "The-Sloth"
"InstanceIdByIP" = "i-AmTheSloth"
"InstanceIdByName" = "i-AmTheSloth"
"DoesInstanceMatch" = $true
"Designation" = "1000"
"TerminationConfidence" = 0
}
(($awsTest).ADName -eq ($expected).ADName) | Should -BeTrue
(($awsTest).IsEnabled -eq ($expected).IsEnabled) | Should -BeTrue
(($awsTest).ADIPv4Address -eq ($expected).ADIPv4Address) | Should -BeTrue
(($awsTest).LastLogon -eq ($expected).LastLogon) | Should -BeTrue
(($awsTest).PasswordLastSet -eq ($expected).PasswordLastSet) | Should -BeTrue
(($awsTest).SID -eq ($expected).SID) | Should -BeTrue
(($awsTest).InstanceIdByIP -eq ($expected).InstanceIdByIP) | Should -BeTrue
(($awsTest).InstanceIdByName -eq ($expected).InstanceIdByName) | Should -BeTrue
(($awsTest).DoesInstanceMatch -eq ($expected).DoesInstanceMatch) | Should -BeTrue
(($awsTest).Designation -eq ($expected).Designation) | Should -BeTrue
(($awsTest).TerminationConfidence -eq ($expected).TerminationConfidence) | Should -BeTrue
}
}
}