Premiere commit - Omika

This commit is contained in:
2026-10-23 18:46:50 +02:00
commit 8ea76c1b24
2155 changed files with 984301 additions and 0 deletions
@@ -0,0 +1,175 @@
# ============================================================
# Omika - Tests NON invasifs de Install-OmikaServerFiles.ps1 (Phase 5C.2B)
# ============================================================
# Valide le correctif WhatIf / SHA256 :
# A. Get-Sha256Hex sur fichier connu.
# B. Get-Sha256Hex sous $WhatIfPreference = $true (aucun null).
# C. Package valide + WhatIf -> SHA256 calcule, exit 0, aucune exception.
# D. Hash incorrect + WhatIf -> mismatch detecte, arret avant copie (exit 1).
# E. Aucune mutation filesystem sous -WhatIf (dossiers + copie).
# F. PackageRoot explicite honore.
# G. PackageRoot automatique ($PSScriptRoot parent).
# AUCUN changement systeme : aucune copie reelle, aucun service, aucun admin.
# ============================================================
[CmdletBinding(SupportsShouldProcess = $true)]
param()
$ErrorActionPreference = 'Stop'
$repo = 'D:\Avalonia\Omika'
$scriptPath = Join-Path $repo 'infra\deploy\Install-OmikaServerFiles.ps1'
$pkgRoot = Join-Path $repo 'artifacts\server-full'
$tests = 0
$fails = 0
function Assert([bool]$condition, [string]$label) {
$script:tests++
if ($condition) {
Write-Host ("PASS {0}" -f $label) -ForegroundColor Green
}
else {
$script:fails++
Write-Host ("FAIL {0}" -f $label) -ForegroundColor Red
}
}
# Exécute un bloc dans un process Windows PowerShell 5.1 enfant (exit-safe),
# retourne @{ Output; ExitCode }. On baisse localement $ErrorActionPreference à
# 'Continue' pendant l'appel natif : ainsi la stderr du natif (ErrorRecord) ne
# lève pas, et 2>&1 la capture dans la sortie.
function Invoke-ChildPS51([string]$scriptText) {
$encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($scriptText))
$prevEAP = $ErrorActionPreference
$ErrorActionPreference = 'Continue'
try {
$out = @(& powershell.exe -NoProfile -NonInteractive -EncodedCommand $encoded 2>&1)
$exitCode = $LASTEXITCODE
}
finally {
$ErrorActionPreference = $prevEAP
}
$text = ($out | ForEach-Object { $_.ToString() }) -join "`n"
return @{ Output = $text; ExitCode = $exitCode }
}
Write-Host "=== 1. Syntaxe PowerShell 5.1 (0 erreur) ==="
$tokens = $null; $errors = $null
[System.Management.Automation.Language.Parser]::ParseFile($scriptPath, [ref]$tokens, [ref]$errors) | Out-Null
Assert (($errors -eq $null) -or ($errors.Count -eq 0)) "Syntaxe OK : Install-OmikaServerFiles.ps1"
Write-Host ""
Write-Host "=== 2. Extraction des fonctions (AST) + module temporaire ==="
$content = Get-Content -LiteralPath $scriptPath -Raw
$ast = [System.Management.Automation.Language.Parser]::ParseInput($content, [ref]$tokens, [ref]$errors)
$want = @('Get-Sha256Hex', 'Test-PackageChecksums', 'Deploy-AppFolder')
$module = New-Object System.Text.StringBuilder
foreach ($f in $ast.FindAll({ param($n) $n -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true)) {
if ($want -contains $f.Name) {
[void]$module.AppendLine($f.Extent.Text)
}
}
foreach ($name in $want) {
Assert ($module.ToString() -match ("function\s+" + [regex]::Escape($name) + "\b")) ("Fonction extraite : " + $name)
}
$modulePath = Join-Path $env:TEMP 'omika-isf-functions.ps1'
[System.IO.File]::WriteAllText($modulePath, $module.ToString(), (New-Object System.Text.UTF8Encoding($true)))
. $modulePath
Write-Host ""
Write-Host "=== A/B. Get-Sha256Hex (unitaire) ==="
$knownFile = Join-Path $env:TEMP 'omika-isf-known.txt'
[System.IO.File]::WriteAllText($knownFile, 'abc', (New-Object System.Text.UTF8Encoding($false)))
$expectedHash = 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
Assert ((Get-Sha256Hex -Path $knownFile) -eq $expectedHash) "A. Hash connu 'abc' = ba7816bf... correct"
$prevWhatIf = $WhatIfPreference
$WhatIfPreference = $true
try {
$hashUnderWhatIf = Get-Sha256Hex -Path $knownFile
Assert ($hashUnderWhatIf -eq $expectedHash) "B. Sous WhatIfPreference=true : hash correct (aucun null)"
Assert ($hashUnderWhatIf -match '^[0-9a-f]{64}$') "B. Format hex lowercase 64 caracteres"
}
finally {
$WhatIfPreference = $prevWhatIf
}
Write-Host ""
Write-Host "=== C. Package valide + WhatIf (Test-PackageChecksums) ==="
$childC = @"
`$ErrorActionPreference = 'Stop'
. '$modulePath'
`$WhatIfPreference = `$true
Test-PackageChecksums -packageRoot '$pkgRoot'
"@
$resC = Invoke-ChildPS51 $childC
Assert ($resC.ExitCode -eq 0) "C. Package valide + WhatIf : exit 0"
Assert ($resC.Output -match 'SHA256 OK') "C. Package valide + WhatIf : SHA256 calcule et OK"
Write-Host ""
Write-Host "=== D. Hash incorrect + WhatIf (mismatch detecte, arret) ==="
$corruptDir = Join-Path $env:TEMP 'omika-isf-corrupt'
if (Test-Path -LiteralPath $corruptDir) { Remove-Item -LiteralPath $corruptDir -Recurse -Force }
New-Item -ItemType Directory -Force -Path $corruptDir | Out-Null
[System.IO.File]::WriteAllText((Join-Path $corruptDir 'test.txt'), 'hello', (New-Object System.Text.UTF8Encoding($false)))
[System.IO.File]::WriteAllText((Join-Path $corruptDir 'SHA256SUMS.txt'), '0000000000000000000000000000000000000000000000000000000000000000 test.txt', (New-Object System.Text.UTF8Encoding($false)))
$childD = @"
`$ErrorActionPreference = 'Stop'
. '$modulePath'
`$WhatIfPreference = `$true
Test-PackageChecksums -packageRoot '$corruptDir'
"@
$resD = Invoke-ChildPS51 $childD
Assert ($resD.ExitCode -eq 1) "D. Hash incorrect + WhatIf : exit 1 (arret avant copie)"
Assert ($resD.Output -match 'Checksum SHA256 KO') "D. Hash incorrect + WhatIf : mismatch detecte"
Write-Host ""
Write-Host "=== E. Aucune mutation filesystem sous -WhatIf ==="
$tempRoot = Join-Path $env:TEMP ('omika-isf-mut-' + [guid]::NewGuid().ToString('N'))
# E1 : boucle de creation d'arborescence (replique de la logique top-level).
$WhatIfPreference = $true
$appsRoot = Join-Path $tempRoot 'Apps'
$folders = @(
$appsRoot,
(Join-Path $appsRoot 'OmikaApi'),
(Join-Path $appsRoot 'OmikaWorker'),
(Join-Path $tempRoot 'Data\Api\Diagnostics\Jsonl'),
(Join-Path $tempRoot 'Data\DiagnosticsWorker\Checkpoint'),
(Join-Path $tempRoot 'Logs\Api'),
(Join-Path $tempRoot 'Config'),
(Join-Path $tempRoot 'Backups'),
(Join-Path $tempRoot 'Deploy')
)
foreach ($folder in $folders) {
if ($PSCmdlet.ShouldProcess($folder, 'Créer le dossier')) {
New-Item -ItemType Directory -Force -Path $folder | Out-Null
}
}
# E2 : Deploy-AppFolder (sauvegarde + copie) sous WhatIf.
Deploy-AppFolder -Name 'OmikaApi' `
-Source (Join-Path $pkgRoot 'OmikaApi') `
-Target (Join-Path $appsRoot 'OmikaApi') `
-BackupRoot (Join-Path $tempRoot 'Backups') `
-Preserve @('appsettings.json')
$WhatIfPreference = $prevWhatIf
Assert (-not (Test-Path -LiteralPath $tempRoot)) "E. Aucun dossier/fichier cree sous WhatIf (arborescence + copie)"
Write-Host ""
Write-Host "=== F/G. Resolution PackageRoot ==="
# G : automatique = parent du dossier Deploy (mirroir exact de $PSScriptRoot).
$autoResolved = Split-Path -Parent (Join-Path $pkgRoot 'Deploy')
Assert ($autoResolved -eq $pkgRoot) "G. PackageRoot automatique (parent du dossier Deploy) resout vers le package"
# F : explicite = honore (le script ne resout que si -not $PackageRoot).
Assert ($content -match 'if \(-not \$PackageRoot\)') "F. Garde 'if (-not PackageRoot)' presente (explicite honore)"
Write-Host ""
Write-Host ("=== RESULTAT : {0} tests, {1} echec(s) ===" -f $tests, $fails)
if ($fails -gt 0) { exit 1 } else { exit 0 }