modules/Azure/Discovery/Tests/Unit/DiscoverySchemaIdempotency.Tests.ps1
|
BeforeAll { Remove-Module Devolutions.CIEM -Force -ErrorAction SilentlyContinue Import-Module (Join-Path $PSScriptRoot '..' '..' '..' '..' '..' 'Devolutions.CIEM.psd1') Mock -ModuleName Devolutions.CIEM Write-CIEMLog {} $script:azureSchemaPath = Join-Path $PSScriptRoot '..' '..' '..' 'Infrastructure' 'Data' 'azure_schema.sql' $script:discoverySchemaPath = Join-Path $PSScriptRoot '..' '..' 'Data' 'discovery_schema.sql' # Apply the discovery schema without swallowing any errors. A well-formed # idempotent schema MUST apply cleanly whether the target DB is empty or # already has the schema applied. function Invoke-Schema { param([string]$Path) foreach ($statement in ((Get-Content $Path -Raw) -split ';\s*\n' | Where-Object { $_.Trim() })) { Invoke-CIEMQuery -Query $statement.Trim() -AsNonQuery | Out-Null } } } Describe 'discovery_schema.sql idempotency' { Context 'when applied to a fresh database' { BeforeAll { New-CIEMDatabase -Path "$TestDrive/fresh.db" InModuleScope Devolutions.CIEM { $script:DatabasePath = "$TestDrive/fresh.db" } Invoke-Schema -Path $script:azureSchemaPath } It 'applies without throwing on the first run' { { Invoke-Schema -Path $script:discoverySchemaPath } | Should -Not -Throw } It 'creates the last_seen index on azure_arm_resources' { $idx = Invoke-CIEMQuery -Query "SELECT name FROM sqlite_master WHERE type='index' AND name='idx_arm_resources_last_seen'" $idx | Should -Not -BeNullOrEmpty } It 'creates the last_seen index on azure_entra_resources' { $idx = Invoke-CIEMQuery -Query "SELECT name FROM sqlite_master WHERE type='index' AND name='idx_entra_resources_last_seen'" $idx | Should -Not -BeNullOrEmpty } } Context 'when re-applied to an already-initialized database' { BeforeAll { New-CIEMDatabase -Path "$TestDrive/reapply.db" InModuleScope Devolutions.CIEM { $script:DatabasePath = "$TestDrive/reapply.db" } Invoke-Schema -Path $script:azureSchemaPath Invoke-Schema -Path $script:discoverySchemaPath } It 'does not throw on the second run (idempotent)' { { Invoke-Schema -Path $script:discoverySchemaPath } | Should -Not -Throw } } } Describe 'base schema.sql idempotency' { BeforeAll { $script:baseSchemaPath = Join-Path $PSScriptRoot '..' '..' '..' '..' '..' 'Data' 'schema.sql' } Context 'when applied via raw SQL to a fresh SQLite file (no catch-swallow)' { BeforeAll { $script:basePath = "$TestDrive/base.db" $conn = Open-PSUSQLiteConnection -Database $script:basePath try { foreach ($statement in ((Get-Content $script:baseSchemaPath -Raw) -split ';\s*\n' | Where-Object { $_.Trim() })) { $script:firstApplyError = $null try { Invoke-PSUSQLiteQuery -Connection $conn -Query $statement.Trim() -AsNonQuery | Out-Null } catch { $script:firstApplyError = $_; break } } } finally { $conn.Dispose() } } It 'does not throw any SQLite errors (every ALTER must be idempotent or removed)' { $script:firstApplyError | Should -BeNullOrEmpty } } } |