tests/Collect.OperationalCollectorEnrichment.Tests.ps1
|
#Requires -Version 7.0 #Requires -Modules Pester BeforeAll { $script:Root = Split-Path -Parent $PSScriptRoot . "$script:Root/src/collect/Get-ScoutOperationalCollectorEnrichment.ps1" $script:Calls = [System.Collections.Generic.List[string]]::new() $script:Resources = @( [pscustomobject]@{ id='/subscriptions/sub-1/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/vm-1'; type='microsoft.compute/virtualmachines'; name='vm-1'; subscriptionId='sub-1'; resourceGroup='rg' }, [pscustomobject]@{ id='/subscriptions/sub-1/resourceGroups/rg/providers/Microsoft.HybridCompute/machines/arc-1'; type='microsoft.hybridcompute/machines'; name='arc-1'; subscriptionId='sub-1'; resourceGroup='rg' }, [pscustomobject]@{ id='/subscriptions/sub-1/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/store-1'; type='microsoft.storage/storageaccounts'; name='store-1'; subscriptionId='sub-1'; resourceGroup='rg' }, [pscustomobject]@{ id='/subscriptions/sub-1/resourceGroups/rg-rg'; type='microsoft.resources/subscriptions/resourcegroups'; name='rg-rg'; subscriptionId='sub-1'; resourceGroup='rg-rg' } ) function Initialize-OperationalStubs { $script:Calls.Clear() function global:Invoke-AzRestMethod { param($Path,$Method,$Payload,$ErrorAction) $null=$Method,$Payload,$ErrorAction; $script:Calls.Add($Path); [pscustomobject]@{StatusCode=200;Content='{"value":[]}' } } function global:Get-AzStorageBlobServiceProperty { param($ResourceGroupName,$Name,$ErrorAction) $null=$ResourceGroupName,$ErrorAction; [pscustomobject]@{ Name=$Name; DeleteRetentionPolicy=[pscustomobject]@{Enabled=$true} } } function global:Get-AzStorageFileServiceProperty { param($ResourceGroupName,$Name,$ErrorAction) $null=$ResourceGroupName,$ErrorAction; [pscustomobject]@{ Name=$Name; ShareDeleteRetentionPolicy=[pscustomobject]@{Enabled=$true} } } function global:Search-AzGraph { param($Query,$First,$ErrorAction) $null=$Query,$First,$ErrorAction; [pscustomobject]@{subscriptionId='sub-1';mgChain=@([pscustomobject]@{displayName='Platform'},[pscustomobject]@{displayName='Root'})} } } function Clear-OperationalStubs { foreach($Name in 'Invoke-AzRestMethod','Get-AzStorageBlobServiceProperty','Get-AzStorageFileServiceProperty','Search-AzGraph'){ Remove-Item "Function:\$Name" -Force -ErrorAction SilentlyContinue } } } Describe 'Get-ScoutOperationalCollectorEnrichment' { BeforeEach { Initialize-OperationalStubs } AfterEach { Clear-OperationalStubs } It 'returns stable envelopes for all six live-access collector contracts' { $Rows=@(Get-ScoutOperationalCollectorEnrichment -Resources $script:Resources -Subscriptions @([pscustomobject]@{Id='sub-1';Name='Subscription One'})) $Rows.type | Should -Be @('AZSC/Operational/VirtualMachine','AZSC/Operational/VMOperationalData','AZSC/Operational/ArcServerOperationalData','AZSC/Operational/ARCServers','AZSC/Operational/StorageAccount','AZSC/Management/SubscriptionEnrichment') ($Rows | Where-Object type -eq 'AZSC/Management/SubscriptionEnrichment').properties.ManagementGroupPath | Should -Be 'Root / Platform' ($Rows | Where-Object type -eq 'AZSC/Management/SubscriptionEnrichment').properties.ResourceCount | Should -Be 4 } It 'uses parent-scoped REST/cmdlet calls and preserves their raw payloads' { $Rows=@(Get-ScoutOperationalCollectorEnrichment -Resources $script:Resources -Subscriptions @()) ($script:Calls -join "`n") | Should -Match '/virtualMachines/vm-1/providers/microsoft.insights/metrics' ($script:Calls -join "`n") | Should -Match '/virtualMachines/vm-1/assessPatches' ($script:Calls -join "`n") | Should -Match '/machines/arc-1/assessPatches' ($Rows | Where-Object type -eq 'AZSC/Operational/StorageAccount').properties.BlobService.Name | Should -Be 'store-1' ($Rows | Where-Object type -eq 'AZSC/Operational/StorageAccount').properties.FileService.Name | Should -Be 'store-1' } It 'contains a failed parent request while producing other envelopes' { function global:Invoke-AzRestMethod { param($Path,$Method,$Payload,$ErrorAction) $null=$Method,$Payload,$ErrorAction; if($Path -match 'vm-1/assessPatches'){throw 'patch denied'}; [pscustomobject]@{StatusCode=200;Content='{}'} } $Rows=@(Get-ScoutOperationalCollectorEnrichment -Resources $script:Resources -Subscriptions @() -WarningVariable Warnings) ($Rows | Where-Object type -eq 'AZSC/Operational/VMOperationalData').properties.PatchAssessment.__AZSCError | Should -Be 'patch denied' ($Rows | Where-Object type -eq 'AZSC/Operational/ARCServers') | Should -Not -BeNullOrEmpty ($Warnings -join "`n") | Should -Match 'VMOperationalData.PatchAssessment' } It 'returns no envelopes and does not call Azure for empty inputs' { $Rows=@(Get-ScoutOperationalCollectorEnrichment -Resources @() -Subscriptions @()) $Rows | Should -BeNullOrEmpty $script:Calls.Count | Should -Be 0 } } |