Skip to content

CAMEL-24829: WebsiteInstallerFixture - isolate PSModulePath for install.ps1 on Windows - #26609

Merged
davsclaus merged 5 commits into
apache:mainfrom
ammachado:CAMEL-24829
Sep 19, 2026
Merged

davsclaus merged 5 commits into
apache:mainfrom
ammachado:CAMEL-24829

Conversation

@ammachado

@ammachado ammachado commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Description

Follow-up to CAMEL-24485 (#26568). Fixes CAMEL-24829.

#26568 stopped windows-validator from killing slow-but-passing runs, but the suite stayed slow: on that PR's own run it took 1206 s. The per-process timing lines #26568 added put 99% of it in install.ps1 (46 launches, median 25.4 s each), while the powershell -Command helpers the tests also start took about 0.24 s each.

Root cause

WebsiteInstallerFixture.run() clears the child environment before launching install.ps1. In that environment, Windows PowerShell's first cmdlet call (Join-Path, line 29 of install.ps1) takes about 18 s on windows-latest, while powershell.exe itself starts in 0.1 s. The value of PSModulePath decides it.

Three temporary diagnostic rounds on this PR (each case run twice). Rounds 1 and 2 launched the probe from a pwsh step:

Join-Path probe Pass 1 Pass 2
full env, real home 2.9 s 0.2 s
full env, fresh home 0.2 s 0.2 s
cleared env (the fixture's baseline) 39.3 s 17.7 s
cleared + PSModulePath (as pwsh sees it) 0.2 s 0.2 s
cleared + shared PSModuleAnalysisCachePath 17.6 s 18.0 s
cleared + real LOCALAPPDATA 17.8 s 17.6 s
cleared + real USERPROFILE/HOME 19.0 s 18.1 s
cleared + ProgramFiles/ProgramData vars 17.8 s 18.2 s
cleared + windir/SystemDrive/APPDATA/etc. 18.1 s 17.4 s

Round 1 (run 35414270738) ruled out the test-only CA / Add-Type block in install.ps1: install.ps1 -Version 1.2.3-SNAPSHOT took 0.2-0.5 s in the full environment with or without CAMEL_INSTALL_CA_CERT, and 17.6-17.9 s in the cleared one, again with or without it. Round 2 is run 35416424791.

Two fix attempts did not help. Passing the runner's PSModulePath through (run 35416880642) left install.ps1 launches at a median of 19.7 s (suite 934 s), and pinning it to System32\WindowsPowerShell\v1.0\Modules (run 35418075426) at 19.5 s (suite 901 s). The round 2 probe ran under pwsh, which prepends its own module directories to PSModulePath at startup; the tests run from bash, whose value lacks them. Round 3, in that same run, launched the probe the way the fixture does, with only PSModulePath varied:

PSModulePath for the Join-Path probe Pass 1 Pass 2
unset (fixture before this PR) 28.9 s 17.5 s
bash's value (attempt 1) 17.4 s 18.2 s
System32\WindowsPowerShell\v1.0\Modules only (attempt 2) 17.5 s 18.3 s
Program Files\WindowsPowerShell\Modules only 17.5 s 17.6 s
pwsh's value 0.2 s 0.2 s
C:\Modules\az_15.6.1 only 0.2 s 0.2 s
a nonexistent user module directory only 0.2 s 0.2 s
SQL Server's module directory only 0.8 s 0.2 s

Join-Path resolves in every case. On windows-latest, Program Files\WindowsPowerShell\Modules holds AWSPowerShell, Microsoft.Graph (40+ modules) and SqlServer.

Changes

  • WebsiteInstallerFixture.run() sets the child's PSModulePath on Windows to the per-test home's own user module directory (<USERPROFILE>\Documents\WindowsPowerShell\Modules, which does not exist), matching the "nonexistent user module directory" row above. This also keeps the suite independent of whatever the runner has installed. The per-test HOME/USERPROFILE/LOCALAPPDATA isolation is unchanged.
  • Drops the PSModuleAnalysisCachePath setting that CAMEL-24485: windows-validator - stop killing slow-but-passing PowerShell suite runs #26568 added: round 2 shows it has no effect.
  • The temporary diagnostic steps are gone; relative to main, the PR only touches WebsiteInstallerFixture.java.

Production is unaffected: SelfUpdateCommand only clears the installer's environment under its test-only installerEnvironmentOverride, so a real camel self-update inherits the user's environment.

Testing

  • macOS, locally: WebsiteInstallerFixtureTest (5) passes. The Windows code path is not exercised off Windows.
  • Windows, run 35419316415: all 38 WebsiteInstallTest$WindowsPowerShell tests pass. The suite took 90 s (was 901-1206 s), install.ps1 launches a median of 1.96 s each (was 19.5-25.4 s), and the whole windows-validator job 5 min 13 s.
before (#26568's run) this PR
WindowsPowerShell suite 1206 s 90 s
install.ps1 launches (46), median 25.4 s 1.96 s (max 7.5 s)
powershell -Command helpers (43), median 0.24 s 0.24 s

The 2700 s fork timeout and 60-minute job cap from #26568 are left as they are; with the suite at 90 s they only bound a genuine hang.

rejectsUnknownParameter passing for the wrong reason (described in CAMEL-24829) is not addressed here.

🤖 Generated with Claude Code on behalf of Adriano Machado (@ammachado)

This was generated by an AI agent and may contain inaccuracies. Please verify before relying on it.

…stall.ps1 launch cost

Every install.ps1 launch in WebsiteInstallTest$WindowsPowerShell pays ~24s
before doing any work (46 launches = 99% of the 1206s suite on PR apache#26568),
while powershell.exe itself starts in ~0.24s. The prime suspect is the
test-only CA block's Add-Type (csc.exe) compile; the second is the
environment WebsiteInstallerFixture.run() clears.

Add a temporary, continue-on-error step that times, twice each: bare
startup and a bare Add-Type (full vs cleared env), and
install.ps1 -Version 1.2.3-SNAPSHOT (rejected before any network I/O)
across full/cleared env x with/without CAMEL_INSTALL_CA_CERT. The step is
to be removed once the cause is confirmed and fixed.

_Claude Code on behalf of Adriano Machado (@ammachado)_

_This was generated by an AI agent and may contain inaccuracies.
Please verify before relying on it._
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

…stall.ps1 launch cost

Round 1 of the diagnostic ruled out the suspected CA seam: install.ps1
-Version 1.2.3-SNAPSHOT takes 0.2-0.5s in the runner's full environment
with or without CAMEL_INSTALL_CA_CERT, but 17.6-17.9s in the cleared
environment WebsiteInstallerFixture.run() uses, again with or without the
CA. A bare powershell.exe start is 0.1s in both; the first cmdlet call
(Join-Path, Add-Type) is what costs ~18-24s in the cleared environment.

Replace the step with a bisection: a Join-Path probe in the cleared
environment with one thing restored at a time (PSModulePath, a shared
PSModuleAnalysisCachePath, real LOCALAPPDATA, real USERPROFILE/HOME,
ProgramFiles/ProgramData variables, windir/SystemDrive/APPDATA and
friends), plus full-environment controls with a real and a fresh home.
Still temporary; removed once the cause is fixed.

_Claude Code on behalf of Adriano Machado (@ammachado)_

_This was generated by an AI agent and may contain inaccuracies.
Please verify before relying on it._
…s1 on Windows

WebsiteInstallerFixture.run() clears the child environment. Without
PSModulePath, Windows PowerShell's first cmdlet call (install.ps1's
Join-Path on line 29) spends ~18s in command discovery on windows-latest,
so every install.ps1 run in WebsiteInstallTest$WindowsPowerShell cost
~25s and the suite took 10-20 minutes.

Two diagnostic CI rounds on this PR pinned it down: a Join-Path probe in
the fixture's cleared environment took 17.7s, and 0.2s with only
PSModulePath restored; restoring LOCALAPPDATA, USERPROFILE/HOME,
ProgramFiles/ProgramData, windir/SystemDrive/APPDATA or a shared
PSModuleAnalysisCachePath each left it at ~18s. The test-only CA
Add-Type block added under 0.2s. The per-test HOME/USERPROFILE/
LOCALAPPDATA isolation is unaffected (full env + fresh home: 0.2s).

Drop the PSModuleAnalysisCachePath setting added by CAMEL-24485, which
the same measurement showed has no effect, and remove the temporary
diagnostic step. Production is unaffected: SelfUpdateCommand only
clears the installer's environment under its test override.

_Claude Code on behalf of Adriano Machado (@ammachado)_

_This was generated by an AI agent and may contain inaccuracies.
Please verify before relying on it._
@github-actions github-actions Bot added the dsl label Sep 19, 2026
@ammachado ammachado changed the title CAMEL-24829: windows-validator - find and remove the ~24s install.ps1 test launch cost CAMEL-24829: WebsiteInstallerFixture - pass PSModulePath to install.ps1 on Windows Sep 19, 2026
@github-actions

github-actions Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • dsl/camel-jbang/camel-launcher

🔬 Scalpel shadow comparison — Scalpel: 0 of 692 tested, 0 compile-only — current: 1 all tested

Maveniverse Scalpel detected 1 affected modules (current approach: 1).

Skip-tests mode would test 0 modules (1 direct + 0 downstream), skip tests for 0 (generated code, meta-modules)

⚠️ Modules only in Scalpel (1)
  • camel-launcher
Modules only in current approach (1)
  • camel-launcher-container
Modules Scalpel would test (0)
  • camel-launcher ← dsl/camel-jbang/camel-launcher/src/test/java/org/apache/camel/dsl/jbang/launcher/WebsiteInstallerFixture.java

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

💡 Manual integration tests recommended:

You modified dsl/camel-jbang/camel-launcher. The related integration tests in dsl/camel-jbang/camel-jbang-it are excluded from CI. Consider running them manually:

mvn verify -f dsl/camel-jbang/camel-jbang-it -Djbang-it-test
All tested modules (2 modules, 44.6s total)

Total reactor time: 44.6s

Module Duration Status
Camel :: Launcher 43.7s SUCCESS
Camel :: Launcher :: Container 0.9s SUCCESS

Top 20 slowest modules:

  • Camel :: Launcher (43.7s)
  • Camel :: Launcher :: Container (0.9s)

⚙️ View full build and test results

…werShell's built-in modules

Passing the runner's PSModulePath through did not help: install.ps1 runs
in the suite still took ~19.7s (median of 46). The round 2 probe that
restored PSModulePath ran under pwsh, which prepends its own module
directories to PSModulePath at startup; the tests run from bash, whose
PSModulePath does not have them.

Set the child's PSModulePath to %SystemRoot%\System32\WindowsPowerShell\v1.0\Modules
instead, which holds every cmdlet install.ps1 uses and keeps the
suite independent of whatever the runner has installed. A temporary
round 3 diagnostic step compares the values on CI.

_Claude Code on behalf of Adriano Machado (@ammachado)_

_This was generated by an AI agent and may contain inaccuracies.
Please verify before relying on it._
@ammachado ammachado changed the title CAMEL-24829: WebsiteInstallerFixture - pass PSModulePath to install.ps1 on Windows CAMEL-24829: WebsiteInstallerFixture - pin PSModulePath for install.ps1 on Windows Sep 19, 2026
… home's user module directory

Round 3 of the diagnostic (run 35418075426), a Join-Path probe in the
fixture's cleared environment, launched from bash like the tests:

- PSModulePath unset, bash's value, System32 modules only, Program Files
  modules only, Program Files + System32: 17.4-28.9s
- pwsh's value (pwsh's own module directories come first): 0.2s
- a single directory without Windows PowerShell's own modules (the Az
  directory, a nonexistent user directory, the SQL Server directory):
  0.2-0.8s, and Join-Path still resolves

So the previous commit's System32-only value did not help either
(install.ps1 median 19.5s, suite 901s). Program Files\WindowsPowerShell\Modules
on windows-latest holds AWSPowerShell, Microsoft.Graph and SqlServer.

Point PSModulePath at <per-test USERPROFILE>\Documents\WindowsPowerShell\Modules,
the isolated home's own user module directory, which does not exist.
Remove the temporary diagnostic steps.

_Claude Code on behalf of Adriano Machado (@ammachado)_

_This was generated by an AI agent and may contain inaccuracies.
Please verify before relying on it._
@ammachado ammachado changed the title CAMEL-24829: WebsiteInstallerFixture - pin PSModulePath for install.ps1 on Windows CAMEL-24829: WebsiteInstallerFixture - isolate PSModulePath for install.ps1 on Windows Sep 19, 2026
@ammachado
ammachado marked this pull request as ready for review September 19, 2026 05:50

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix is empirically sound and well-documented.

The root cause (PSModulePath absent → Windows PowerShell scans all installed modules in Program Files\WindowsPowerShell\Modules including Microsoft.Graph/AWSPowerShell on the first cmdlet call) is accurately identified and validated with three rounds of CI diagnostics. Pointing the child environment at a per-test, nonexistent user module directory is the minimal effective fix — it avoids the scan without affecting correctness, since built-in cmdlets are resolved from $PSHome\Modules regardless of PSModulePath. The 13× speedup (1206s → 90s) on the Windows CI run confirms it.

Ordering of pb.environment().put("PSModulePath", ...) after pb.environment().putAll(env) is correct — ensures the isolation override wins over anything the caller might pass.

Dropping PSModuleAnalysisCachePath is justified by the round-2 measurements (no effect); the constant removal is clean.

This review was generated by an AI agent, Hermès on behalf of @gnodet.

@davsclaus davsclaus added this to the 4.23.0 milestone Sep 19, 2026
@davsclaus davsclaus added the test label Sep 19, 2026
@davsclaus
davsclaus merged commit d1d54fb into apache:main Sep 19, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants