From cca74aa238415935f4564a3cdb337050764dc713 Mon Sep 17 00:00:00 2001 From: Maksym Kucherov Date: Fri, 9 Oct 2026 10:29:14 +0200 Subject: [PATCH] CI: Add `WMIC` on Windows to bypass mvn fork ping timeout. --- ci/README.md | 4 +++ ci/install-wmic.ps1 | 63 ++++++++++++++++++++++++++++++++++++++++ ci/setup-environment.ps1 | 4 +++ 3 files changed, 71 insertions(+) create mode 100644 ci/install-wmic.ps1 diff --git a/ci/README.md b/ci/README.md index e6e97784..a61a0738 100644 --- a/ci/README.md +++ b/ci/README.md @@ -25,6 +25,10 @@ The following secrets are optional: * `IPI_DATA_FILE_URL` - URL for downloading the enterprise IPI data file * Default: the 51Degrees Distributor URL using the `DEVICE_DETECTION_KEY` license key +## Environment + +On Windows, [setup-environment.ps1](setup-environment.ps1) installs WMIC if the runner does not have it. Maven Surefire needs it to check that Maven is still alive, and without it can end a long running test that had not failed. The reasoning is in [install-wmic.ps1](install-wmic.ps1). + ## Integration Tests The integration testing approach differs from the 'general' inversion of control approach outlined in the [Design.md](https://github.com/51Degrees/common-ci/blob/gh-refact/design.md) as the it cannot be generic. diff --git a/ci/install-wmic.ps1 b/ci/install-wmic.ps1 new file mode 100644 index 00000000..51d4b0b3 --- /dev/null +++ b/ci/install-wmic.ps1 @@ -0,0 +1,63 @@ +# Makes sure WMIC is installed on Windows, so that a forked test JVM can tell +# whether Maven is still alive by looking at the Maven process. +# +# Maven Surefire runs the tests in a forked JVM. The fork has to notice when +# Maven has died so that it does not run on forever. On Windows it does that by +# asking WMIC for the start time of the Maven process. Recent Windows images do +# not include WMIC. Without it Surefire writes "Cannot use PPID ... Going to +# use NOOP events" to its dump file and falls back to expecting a message from +# Maven at least every 30 seconds. That limit is fixed in Surefire and cannot +# be configured. +# +# IPIntelligenceTests copies and loads the Enterprise data file, which is +# several GB, ten times over. On Windows that keeps the machine busy for about +# twenty minutes, long enough for those messages to be delayed. The fork then +# ends itself with exit code 1 and Maven reports "The forked VM terminated +# without properly saying goodbye" for a test that had not failed. +# +# Installing WMIC is a precaution, so a failure to install it is reported as a +# warning and never fails the job. The tests then run as they did before. + +# A failing installer must reach the check below rather than throw here, as +# the caller turns native command failures into errors. +$PSNativeCommandUseErrorActionPreference = $false + +# Surefire runs this exact path, so WMIC being somewhere else on the PATH +# would not help. +$WmicPath = "$env:SystemRoot\System32\Wbem\wmic.exe" + +if ($IsWindows -eq $false) { + # Surefire only uses WMIC on Windows. Elsewhere it uses ps, which is + # always there. + return +} + +if ((Test-Path -Path $WmicPath) -eq $true) { + Write-Host "WMIC found at '$WmicPath', nothing to install." + return +} + +Write-Host "WMIC not found at '$WmicPath', installing it." +$installed = $false +try { + dism.exe /Online /Add-Capability /CapabilityName:WMIC~~~~ /NoRestart | + Out-Host + $installed = $LASTEXITCODE -eq 0 +} +catch { + Write-Host "Installing WMIC threw: $($_.Exception.Message)" +} +finally { + # The common-ci step runner fails the step if a non zero exit code is + # left behind, and a failure here has been dealt with. + $global:LASTEXITCODE = 0 +} + +if ($installed -eq $true -and (Test-Path -Path $WmicPath) -eq $true) { + Write-Host "WMIC installed at '$WmicPath'." +} +else { + Write-Host ("$($env:CI -eq 'true' ? '::warning::' : '')" + + "WMIC could not be installed at '$WmicPath'. Maven Surefire will " + + "fall back to its 30 second ping, which long running tests can miss.") +} diff --git a/ci/setup-environment.ps1 b/ci/setup-environment.ps1 index ac5324e3..97ebcc79 100644 --- a/ci/setup-environment.ps1 +++ b/ci/setup-environment.ps1 @@ -7,6 +7,10 @@ $PSNativeCommandUseErrorActionPreference = $true ./java/setup-enviroment.ps1 @PSBoundParameters +# Without WMIC a forked test JVM on Windows can end itself part way through +# the long running data file tests. The script explains why. +& "$PSScriptRoot/install-wmic.ps1" + if ($IsLinux -or $IsMacOS) { Write-Host "Marking PreBuild.sh as executable..." chmod +x "$RepoName/ip-intelligence.engine.on-premise/src/main/cxx/PreBuild.sh"