tests/Unit/Public/ErrorPathHardening.Tests.ps1
|
#Requires -Modules Pester <# .SYNOPSIS Fehlerpfade, die frueher in leeren catch-Bloecken verschwanden. .DESCRIPTION Jeder Test loest den Fehler aus, der vorher verschluckt wurde, und prueft die Meldung. Invoke-DbaQuery wirft ohne -EnableException bei SQL-Fehlern nicht (es liefert 0 Zeilen, live geprueft mit dbatools 2.9.0). Die Mocks werfen deshalb nur mit -EnableException; ein Mock, der immer wirft, wuerde einen catch testen, den das echte dbatools nie erreicht. #> BeforeAll { . "$PSScriptRoot\..\..\..\tests\TestHelpers.ps1" Import-sqmTestModule InModuleScope sqmSQLTool { $script:dbatoolsAvailable = $true } $script:TestDir = New-TempTestDirectory } AfterAll { if ($script:TestDir -and (Test-Path $script:TestDir)) { Remove-Item $script:TestDir -Recurse -Force } if (Get-Module sqmSQLTool) { Remove-Module sqmSQLTool -Force } $env:MSSQLTOOLS_SKIP_AUTO_UPDATE = $null } Describe 'Get-sqmCertificateReport - Endpoint-/TDE-Zuordnung nicht ermittelbar' { BeforeEach { $script:Out = Join-Path $script:TestDir ([guid]::NewGuid().ToString('N')) Mock -ModuleName sqmSQLTool Invoke-sqmLogging { } Mock -ModuleName sqmSQLTool Copy-sqmToCentralPath { } Mock -ModuleName sqmSQLTool Connect-DbaInstance { [pscustomobject]@{ Name = 'SQL01'; VersionMajor = 16 } } Mock -ModuleName sqmSQLTool Get-DbaDatabase { } Mock -ModuleName sqmSQLTool Invoke-DbaQuery { } -ParameterFilter { $Query -like '*symmetric_keys*' -or $Query -like '*master_key*' } Mock -ModuleName sqmSQLTool Invoke-DbaQuery { [pscustomobject]@{ CertificateName = 'TDE_Cert'; certificate_id = 256; PrivateKeyEncryption = 'ENCRYPTED_BY_MASTER_KEY' IsActiveForDialog = $false; IssuerName = 'TDE_Cert'; Subject = 'TDE_Cert' ValidFrom = (Get-Date).AddYears(-1); ExpiryDate = (Get-Date).AddYears(5) Thumbprint = [byte[]](1, 2, 3); AttestedBy = $null; HasControl = 1; HasPrivateKey = 1 } } -ParameterFilter { $Query -like '*pvt_key_encryption_type_desc*' } Mock -ModuleName sqmSQLTool Invoke-DbaQuery { if ($EnableException) { throw 'VIEW SERVER STATE verweigert' } } -ParameterFilter { $Query -like '*dm_database_encryption_keys*' -or $Query -like '*sys.endpoints*' } } It 'meldet beide fehlenden Zuordnungen im Ergebnis statt sie zu verschweigen' { $r = Get-sqmCertificateReport -SqlInstance 'SQL01' -OutputPath $script:Out -NoOpen -Confirm:$false @($r.PurposeWarnings).Count | Should -Be 2 ($r.PurposeWarnings -join ' ') | Should -Match 'TDE-Zuordnung nicht ermittelbar.*VIEW SERVER STATE' ($r.PurposeWarnings -join ' ') | Should -Match 'Endpoint-Zuordnung nicht ermittelbar' } It 'schreibt den Hinweis in Text- und HTML-Bericht' { Get-sqmCertificateReport -SqlInstance 'SQL01' -OutputPath $script:Out -NoOpen -Confirm:$false | Out-Null $txt = Get-ChildItem $script:Out -Filter '*.txt' -Recurse | Select-Object -First 1 $html = Get-ChildItem $script:Out -Filter '*.html' -Recurse | Select-Object -First 1 Get-Content $txt.FullName -Raw | Should -Match 'HINWEIS: TDE-Zuordnung nicht ermittelbar' Get-Content $html.FullName -Raw | Should -Match 'HINWEIS: TDE-Zuordnung nicht ermittelbar' } It 'ohne Fehler keine Hinweise' { Mock -ModuleName sqmSQLTool Invoke-DbaQuery { } -ParameterFilter { $Query -like '*dm_database_encryption_keys*' -or $Query -like '*sys.endpoints*' } $r = Get-sqmCertificateReport -SqlInstance 'SQL01' -OutputPath $script:Out -NoOpen -Confirm:$false @($r.PurposeWarnings).Count | Should -Be 0 } } Describe 'Enable-sqmServiceBroker - Rollback auf MULTI_USER scheitert' { BeforeEach { $script:Out = Join-Path $script:TestDir ([guid]::NewGuid().ToString('N')) Mock -ModuleName sqmSQLTool Invoke-sqmLogging { } $global:SqmBrokerQueries = [System.Collections.Generic.List[string]]::new() Mock -ModuleName sqmSQLTool Connect-DbaInstance { $srv = [pscustomobject]@{ Name = 'SQL01' } $srv | Add-Member -MemberType ScriptMethod -Name Query -Value { $global:SqmBrokerQueries.Add($args[0]) if ($args[0] -like '*ENABLE_BROKER*') { throw 'Broker-Fehler' } if ($args[0] -like '*SET MULTI_USER*') { throw 'Sperre' } } $srv } } AfterEach { Remove-Variable -Name SqmBrokerQueries -Scope Global -ErrorAction SilentlyContinue } It 'nennt SINGLE_USER und den manuellen Befehl in der Fehlermeldung' { { Enable-sqmServiceBroker -SqlInstance 'SQL01' -DatabaseName 'App' -OutputPath $script:Out -Force -EnableException -Confirm:$false } | Should -Throw -ExpectedMessage '*Broker-Fehler*steht noch in SINGLE_USER*ALTER DATABASE `[App`] SET MULTI_USER*' } It 'wirft weiter den Broker-Fehler, wenn das Rollback klappt' { Mock -ModuleName sqmSQLTool Connect-DbaInstance { $srv = [pscustomobject]@{ Name = 'SQL01' } $srv | Add-Member -MemberType ScriptMethod -Name Query -Value { if ($args[0] -like '*ENABLE_BROKER*') { throw 'Broker-Fehler' } } $srv } { Enable-sqmServiceBroker -SqlInstance 'SQL01' -DatabaseName 'App' -OutputPath $script:Out -Force -EnableException -Confirm:$false } | Should -Throw -ExpectedMessage '*Broker-Fehler*' try { Enable-sqmServiceBroker -SqlInstance 'SQL01' -DatabaseName 'App' -OutputPath $script:Out -Force -EnableException -Confirm:$false } catch { "$_" | Should -Not -Match 'SINGLE_USER' } } } Describe 'Invoke-sqmSetupReport - sysadmin-Mitglieder nicht ermittelbar' { BeforeEach { $script:Out = Join-Path $script:TestDir ([guid]::NewGuid().ToString('N')) Mock -ModuleName sqmSQLTool Invoke-sqmLogging { } Mock -ModuleName sqmSQLTool Copy-sqmToCentralPath { } Mock -ModuleName sqmSQLTool Get-WmiObject { [pscustomobject]@{ TotalPhysicalMemory = 8GB } } # Ein String bindet an DbaInstanceParameter; Server-Eigenschaften sind dann leer, das reicht hier Mock -ModuleName sqmSQLTool Connect-DbaInstance { 'SQL01' } # Splunk- und Monitoring-Abschnitte greifen per WinRM auf den Host zu; im Test abgeschaltet foreach ($cmd in 'Get-DbaLogin', 'Get-DbaAgentJob', 'Get-DbaDatabase', 'Get-DbaService', 'Get-sqmDatabaseTrustIsolationMap', 'Get-sqmSpnReport', 'Invoke-sqmSplunkConfiguration', 'Invoke-sqmMonitoringKey') { Mock -ModuleName sqmSQLTool $cmd { } } Mock -ModuleName sqmSQLTool Invoke-DbaQuery { } Mock -ModuleName sqmSQLTool Invoke-DbaQuery { if ($EnableException) { throw 'kein VIEW SERVER STATE' } } -ParameterFilter { $Query -like "*r.name = N'sysadmin'*" } Mock -ModuleName sqmSQLTool Get-DbaServerRoleMember { if ($EnableException) { throw 'kein Zugriff' } } } It 'zeigt im Bericht "nicht ermittelbar" und eine Fehlermeldung statt "None"' { $file = Invoke-sqmSetupReport -SqlInstance 'SQL01' -OutputPath $script:Out -NoOpen $html = Get-Content (Get-ChildItem $script:Out -Filter '*.html' -Recurse | Select-Object -First 1).FullName -Raw $html | Should -Match '\(nicht ermittelbar\)' $html | Should -Match 'FEHLER: sysadmin-Mitglieder nicht ermittelbar, BUILTIN-Pruefung nicht durchgefuehrt \(kein Zugriff\)' Should -Invoke -ModuleName sqmSQLTool Invoke-sqmLogging -ParameterFilter { $Level -eq 'WARNING' -and $Message -like '*sysadmin-Mitglieder nicht ermittelbar*' } } } |