ps/Modules/Alkami.PowerShell.Choco/Public/Get-PackageInstallationData.Tests.ps1
2023-05-30 22:51:22 -07:00

294 lines
14 KiB
PowerShell

. $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 = ""
# These are (currently) all integration tests due to various unmocked calls
# It is also weird (in a testing context) to use the same function to mock data that is used to test that data
# It creates a greater sense of safety than is actual
# Use this in the mocks to ensure we're getting the top level context.
$global:globalRoot = $PSScriptRoot
Describe "Get-PackageInstallationData-V2" {
# Global Mocks
Mock Set-ChocoPackageSourceFeeds -ModuleName $moduleForMock -MockWith {}
Mock -CommandName Write-Host -ModuleName $moduleForMock -MockWith {}
Mock -CommandName Write-Warning -ModuleName $moduleForMock -MockWith {}
Mock -CommandName Write-Host -ModuleName "Alkami.PowerShell.Choco" -MockWith {}
Mock -CommandName Write-Warning -ModuleName "Alkami.PowerShell.Choco" -MockWith {}
#region this seems broken because of invoke-parallel
# TODO: @Tom - Does this even get executed since the only use-case is inside the Invoke-Parallel script? I don't think so. - Cole
$TestIsPackageMicroserviceSB = {
param($NuspecXmlObject,$Package)
return ($Package.Name -like "*.MicroServices.*") -or ($Package.Name -like "*.MS.*") -or ($Package.Name -like "*.Services.*")
}
Mock Test-IsPackageMicroserviceV2 -ModuleName "Alkami.PowerShell.Choco" -MockWith $TestIsPackageMicroserviceSB
Mock Test-IsPackageMicroserviceV2 -ModuleName $moduleForMock -MockWith $TestIsPackageMicroserviceSB
#endregion this seems broken because of invoke-parallel
Mock Test-IsPackageInFeed -ModuleName $moduleForMock -MockWith {return $true}
Mock Test-PackageHasAlkamiManifestV2 -ModuleName $moduleForMock -MockWith { return $false }
# this long magic string is a barebones package folder with no useful contents. Just the basic nuget structure and a choco install file set
Mock Get-PackageFileListV2 -ModuleName $moduleForMock -MockWith { return (ConvertFrom-Json '[{"fullPath":"package/services/metadata/core-properties/","parentFullPath":"package/services/metadata/","name":"core-properties","isDirectory":true},{"fullPath":"package/services/metadata/","parentFullPath":"package/services/","name":"metadata","isDirectory":true},{"fullPath":"package/services/","parentFullPath":"package/","name":"services","isDirectory":true},{"fullPath":"package/","parentFullPath":"/","name":"package","isDirectory":true},{"fullPath":"package/services/metadata/core-properties/629d5521ad934906a0d3c36051d35320.psmdcp","parentFullPath":"package/services/metadata/core-properties/","name":"629d5521ad934906a0d3c36051d35320.psmdcp","isDirectory":false},{"fullPath":"lib/net472/","parentFullPath":"lib/","name":"net472","isDirectory":true},{"fullPath":"lib/","parentFullPath":"/","name":"lib","isDirectory":true},{"fullPath":"_rels/","parentFullPath":"/","name":"_rels","isDirectory":true},{"fullPath":"_rels/.rels","parentFullPath":"_rels/","name":".rels","isDirectory":false},{"fullPath":"tools/","parentFullPath":"/","name":"tools","isDirectory":true},{"fullPath":"tools/chocolateyInstall.ps1","parentFullPath":"tools/","name":"chocolateyInstall.ps1","isDirectory":false},{"fullPath":"tools/chocolateyUninstall.ps1","parentFullPath":"tools/","name":"chocolateyUninstall.ps1","isDirectory":false},{"fullPath":"[Content_Types].xml","parentFullPath":"/","name":"[Content_Types].xml","isDirectory":false}]')}
$invokeParallelScript = {
# This is what comes from Get-PackageInstallationData when it calls the invoke-parallel
param($objects)
$newPackages = @()
foreach ($package in $objects) {
$packageInfoPath = "$global:globalRoot\..\TestFiles\PackageObjects\$($package.Name).json"
if (Test-Path $packageInfoPath) {
$packageInfo = Get-Content $packageInfoPath | ConvertFrom-Json
$newPackages += @{
ValidPackage = $true
Package = $packageInfo
}
}
}
return @($newPackages)
}
Mock Invoke-Parallel -ModuleName $moduleForMock -MockWith $invokeParallelScript
Mock -CommandName Invoke-Parallel -ModuleName "Alkami.PowerShell.Choco" -MockWith $invokeParallelScript
# Define a good testable spread of packages.
# This is the list of packages that will be built based on the json files in \TestFiles\PackageObjects
# If you add a new package to the list, you need a new object there. See \TestFiles\readme.md for additional details.
$packageText = @"
# Installers
Alkami.MicroServices.Choco.Installer.Database 2.4.6
Alkami.MicroServices.Choco.Installer.Logic 2.4.6
Alkami.MicroServices.Choco.Installer.MasterDatabase 2.4.6
Alkami.Installer.Provider 3.0.6
Alkami.Installer.WebExtension 3.0.1
Alkami.Installer.Widget 3.0.2
# Infrastructure
Alkami.MicroServices.Broker.Host 2.8.1
Alkami.Services.Subscriptions.Host 3.5.2
# Providers
Alkami.App.Nag.Providers 1.1.4
Alkami.App.Processor.Wire.FedwireOutput 1.2.3
Alkami.App.Providers.CheckImaging.CorporateOne 1.0.1
Alkami.App.Providers.Multiplexer.Client 1.0.4
Alkami.App.Providers.Radium.BillPay 1.1.0
# Tier 1 Microservices
Alkami.MicroServices.Forms.Service.Host 1.1.1
Alkami.MicroServices.Authorization.Service.Host 1.4.3
Alkami.MicroServices.Security.Service.Host 2.17.2
Alkami.MicroServices.UserInterface.Service.Host 1.17.0
Alkami.MicroServices.Audit.Service.Host 6.11.0
Alkami.MicroServices.Contacts.Service.Host 2.4.8
Alkami.MicroServices.Holidays.Service.Host 2.1.12
Alkami.MicroServices.Images.Service.Host 3.1.14
Alkami.MicroServices.Notifications.Service.Host 1.6.12
Alkami.MicroServices.Settings.Service.Host 4.4.0
Alkami.MicroServices.SiteText.Service.Host 1.1.17
Alkami.MicroServices.Transactions.Service.Host 1.7.1
Alkami.MicroServices.EventManagement.Service.Host 3.4.9
# Tier 2 Microservices
Alkami.MicroServices.QuickApply.Service.Host 9.0.0
Alkami.MicroServices.Registration.Service.Host 2.5.1
Alkami.MicroServices.RemoteDeposit.Service.Host 2.4.1
Alkami.MicroServices.CardManagementProviders.SymConnect.Host 3.7.1
# Powershell Modules
Alkami.Ops.Common 3.0.3
Alkami.PowerShell.Choco 3.5.4
Alkami.PowerShell.Common 3.2.6
# SDK
DS.AccountService.MS.Service.Host 1.0.9
DS.BranchService.MS.Service.Host 1.0.10
DS.CMN.MS.Service.Host 1.0.8
DS.CopyRequestService.MS.Host 1.0.1
DS.CoreService.MS.Service.Host 2.0.5
DS.EStatements.MS.Service.Host 1.0.7
DS.MarketingEmailService.MS.Host 1.0.7
DS.MicroService.ContentService.Service.Host 2.0.4
DS.SecureMessage.MS.Service.Host 1.0.10
DS.Settings.MS.Service.Host 1.0.8
DS.SkipAPayService.MS.Host 1.0.8
# Symitar
Alkami.MicroServices.AutoBiller.Symitar.Service.Host 2.1.4
Alkami.MicroServices.RDCoreDeposit.Symitar.Service.Host 1.1.3
Alkami.MicroServices.SymConnectMultiplexer.Service.Host 2.1.2
Alkami.Providers.FakeSymitarProvider 1.2.3
"@
Write-Host "format-parsing"
# Strip out the comment lines and parse the packages out into package objects.
$packageText = ($packageText -split "`r`n") | Where-Object { $_ -notlike "*#*" }
$packages = Format-ParseChocoPackages -text $packageText -delimiter " "
# Define a fake feed URL
$fakeFeed = "https://packagerepo.orb.alkamitech.com/nuget/fake.feed"
# Attach fake source feeds onto each package, since we don't want to run this test against real nuget feeds.
foreach ($package in $packages) {
$feedMap = @{
Source = $fakeFeed
IsSdk = $package.Name -like "DS.*" # Mark the desert schools packages as SDK.
}
$package.Feed = New-Object PSObject -Property $feedMap
}
# Define fake PSCredential user.
$user = 'AlkamiFakeUser'
$pass = Get-SecureString 'abc123'
$credential = New-Object System.Management.Automation.PSCredential($user, $pass)
# Define fake server lists.
$serversNonFabEnvironment = @("APP1234","APP1235","MIC1234","MIC1235","WEB1234","WEB1235")
# Clone packages into $packages2 as a complete copy.
$ms = New-Object System.IO.MemoryStream
$bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
$bf.Serialize($ms, $packages)
$ms.Position = 0
# Deep Copy Data
$packages2 = $bf.Deserialize($ms)
$ms.Close()
Write-Host "get the dataaaaa"
# Run classification functions to be re-used for every test.
$nonFabPackageData = Get-PackageInstallationData -ChocoPackages $packages2 -Servers $serversNonFabEnvironment -NugetCredential $credential -UseV2PackageMetadata
Write-Host "did the dataaaaa"
Context "Tier Assignment" {
It "Correctly Assigns Installer Packages to Tier 0" {
# All 6 installer packages defined above should be in tier 0
$installers = $nonFabPackageData | Where-Object { $_.IsInstaller -and ($_.Tier -eq 0)}
$installers.Count | Should -Be 6
}
It "Correctly Assigns Infrastructure Packages to Tier 0" {
# Both infrastructure packages defined above should be in tier 0
$installers = $nonFabPackageData | Where-Object { $_.IsInfrastructure -and ($_.Tier -eq 0)}
$installers.Count | Should -Be 2
}
# All packages assigned tiers
It "Assigns Tiers to Every Package" {
$badTierAssignments = $nonFabPackageData | Where-Object { ($null -eq $_.Tier) -or ($_.Tier -lt 0) }
$badTierAssignments.Count | Should -Be 0
}
It "Returns Packages Ordered by Tier" {
# Sweep through all of the packages, and make sure that the tier always increases & never decreases.
$lastPackage = $nonFabPackageData[0]
$isTierOrderingValid = $true
foreach ($package in $nonFabPackageData) {
$isTierOrderingValid = $isTierOrderingValid -and ($package.Tier -ge $lastPackage.Tier)
$lastPackage = $package
}
$isTierOrderingValid | Should -Be $true
}
}
Context "Test with PackageToServers non null" {
$servers = $serversNonFabEnvironment
$micServers = Get-ServerByType -Type Mic -Server $servers
$appServers = Get-ServerByType -Type App -Server $servers
# Dynamically generate some packaages with all and some packages without some servers
# Calculate the number of servers removed from the generated list
# Compare to the number of servers found missing from
function Get-RandomServerList {
[CmdletBinding()]
param (
$Servers
)
if ($Servers.IndexOf(',') -gt -1) {
$Servers = $Servers -split ','
}
if (Test-IsCollectionNullOrEmpty -Collection $servers) {
return $Servers
}
if ($Servers.Count -eq 1) {
return $Servers
}
return ($Servers | Sort-Object { Get-Random } | Select-Object -First (Get-Random -Minimum ($Servers.Count - 1) -Maximum ($Servers.Count + 1)) | Sort-Object)
}
$packageMap = @{}
$removedPackageCount = 0
# todo: build a packagemap from the packages so we can sort what isn't on a server
foreach ($package in $packages2) {
$removedCount = 0
$packageLower = $package.Name.ToLower()
if ($packageLower -match "installer") {
$packageMap.$packageLower = $servers
}
elseif ($packageLower -match "fake") {
# fakes get ignored
}
elseif ($packageLower -match "powershell" -or $packageLower -match "\.ops\.") {
$packageMap.$packageLower = $servers
}
elseif ($packageLower -match "processor" -or $packageLower -match "\.providers") {
$serversCalculated = @(Get-RandomServerList $appServers)
$packageMap.$packageLower = $serversCalculated
$removedCount = $appServers.Count - $serversCalculated.Count
}
elseif ($packageLower -match "DS\.") {
$serversCalculated = @(Get-RandomServerList $micServers)
$packageMap.$packageLower = $serversCalculated
$removedCount = $micServers.Count - $serversCalculated.Count
}
elseif ($packageLower -eq "Alkami.MicroServices.Broker.Host" -or $packageLower -eq "Alkami.Services.Subscriptions.Host" -or $packageLower -eq "Alkami.MicroServices.Authorization.Service.Host") {
$serversCalculated = $servers
$packageMap.$packageLower = $serversCalculated
$removedCount = $servers.Count - $serversCalculated.Count
}
else {
$serversCalculated = @(Get-RandomServerList $micServers)
$packageMap.$packageLower = $serversCalculated
$removedCount = $micServers.Count - $serversCalculated.Count
}
if ($removedCount -gt 0) {
# Write-Host "$($package.Name) - $removedCount"
$removedPackageCount += $removedCount
}
}
# Run classification functions to be re-used for every test.
$packageMapTestData = Get-PackageInstallationData -ChocoPackages $packages2 -Servers $serversNonFabEnvironment -NugetCredential $credential -UseV2PackageMetadata -PackageToServerMap $packageMap
It "Got some results for missing server packages" {
$packageMapTestData.IsMissingFromServers -eq $true | Should -Not -BeNullOrEmpty
}
It "Should have removed as many servers as we expected" {
$missingCount = 0
foreach ($package in $packageMapTestData) {
if ($package.MissingFromServers.Count -gt 0) {
# Write-Host "$($package.Name) - $($package.MissingFromServers.Count)"
$missingCount += $package.MissingFromServers.Count
}
}
$missingCount | Should -Be $removedPackageCount
}
}
}