public/Invoke-PhpSmokeTests.ps1
|
function Invoke-PhpSmokeTests { <# .SYNOPSIS Run smoke tests for PHP build artifacts. .PARAMETER ArtifactsDirectory Directory containing PHP build zip artifacts. .PARAMETER Arch PHP architecture filter. .PARAMETER Ts PHP thread safety filter. #> [OutputType()] param ( [Parameter(Mandatory = $true, Position=0, HelpMessage='Artifacts directory')] [ValidateNotNull()] [ValidateLength(1, [int]::MaxValue)] [string] $ArtifactsDirectory, [Parameter(Mandatory = $true, Position=1, HelpMessage='PHP Architecture')] [ValidateSet('x86', 'x64')] [string] $Arch, [Parameter(Mandatory = $true, Position=2, HelpMessage='PHP Build Type')] [ValidateSet('nts', 'ts')] [string] $Ts ) begin { } process { $artifactsPath = (Resolve-Path $ArtifactsDirectory).Path $tempRoot = Join-Path $env:TEMP ("php-smoke-" + [System.Guid]::NewGuid().ToString()) New-Item -Path $tempRoot -ItemType "directory" -Force > $null 2>&1 $requiredPhpModulesConfig = Join-Path $PSScriptRoot '..\config\smoke_test_modules' $requiredPhpModules = @( Get-Content -Path $requiredPhpModulesConfig | ForEach-Object { "$_".Trim() } | Where-Object { $_ -and -not $_.StartsWith('#') } ) if(-not $requiredPhpModules) { throw "No smoke test modules configured in $requiredPhpModulesConfig" } $zipPattern = "php-*-$Arch.zip" $zipRegex = if($Ts -eq 'nts') { "^php-[^-]+-nts-Win32-vs\d+-${Arch}\.zip$" } else { "^php-[^-]+-Win32-vs\d+-${Arch}\.zip$" } $zipMatches = @( Get-ChildItem -Path $artifactsPath -Filter $zipPattern -File | Where-Object { $_.Name -match $zipRegex } | Sort-Object Name ) if(-not $zipMatches) { throw "No PHP build archive matched regex '$zipRegex' in $artifactsPath" } if($zipMatches.Count -ne 1) { throw "Expected exactly one PHP build archive for arch=$Arch ts=$Ts, found $($zipMatches.Count): $($zipMatches.Name -join ', ')" } $zip = $zipMatches[0] $extractPath = Join-Path $tempRoot $zip.BaseName New-Item -Path $extractPath -ItemType "directory" -Force > $null 2>&1 try { Expand-Archive -Path $zip.FullName -DestinationPath $extractPath -Force } catch { 7z x $zip.FullName "-o$extractPath" -y | Out-Null } $phpExe = Join-Path $extractPath 'php.exe' if(-not(Test-Path $phpExe)) { throw "php.exe not found in $($zip.Name)" } $extDir = Join-Path $extractPath 'ext' if(-not(Test-Path $extDir)) { throw "Extension directory not found for $($zip.Name) at $extDir" } $iniPath = Join-Path $extractPath 'php.ini' Set-Content -Path $iniPath -Value @( ('extension_dir="{0}"' -f $extDir) ) -Encoding ascii Get-ChildItem -Path $extDir -Filter 'php_*.dll' -File | Sort-Object Name | ForEach-Object { if( $_.Name -in @('php_pdo_firebird.dll', 'php_snmp.dll', 'php_pdo_oci.dll') -or $_.Name -like 'php_oci8*.dll' ) { Write-Host "Skipping $($_.Name) in smoke tests" } elseif($_.Name -eq 'php_opcache.dll') { Add-Content -Path $iniPath -Value ('zend_extension={0}' -f $_.Name) -Encoding ascii } else { Add-Content -Path $iniPath -Value ('extension={0}' -f $_.Name) -Encoding ascii } } Write-Host "Running smoke tests for $($zip.Name)" Push-Location $extractPath try { & .\php.exe -c $iniPath -v if(-not $?) { throw "php -v failed for $($zip.Name)" } $phpModulesOutput = & .\php.exe -c $iniPath -m if(-not $?) { throw "php -m failed for $($zip.Name)" } $phpModulesOutput | ForEach-Object { Write-Host $_ } # Validate the modules that PHP actually loaded, not just DLL files present on disk. $loadedPhpModules = @( $phpModulesOutput | ForEach-Object { "$_".Trim() } | Where-Object { $_ -and $_ -notmatch '^\[.*\]$' } ) $loadedPhpModulesLookup = @{} foreach($moduleName in $loadedPhpModules) { $loadedPhpModulesLookup[$moduleName.ToLowerInvariant()] = $true } $missingPhpModules = @() foreach($requiredModule in $requiredPhpModules) { if(-not $loadedPhpModulesLookup.ContainsKey($requiredModule.ToLowerInvariant())) { $missingPhpModules += $requiredModule } } if($missingPhpModules) { throw "php -m missing required modules for $($zip.Name): $($missingPhpModules -join ', ')" } & .\php.exe -c $iniPath -i if(-not $?) { throw "php -i failed for $($zip.Name)" } } finally { Pop-Location } } end { } } |