Add Windows CI testing#1935
Conversation
- Add Windows 2022 Evergreen build variants for server 8.2 across all topologies to enable Windows CI coverage - Add EnvironmentProvider class to centralize all System.getenv() calls, replacing the reflection-based env var override hack that fails on Windows due to JDK's ProcessEnvironment dual-map architecture - Fix SSL keystore/truststore paths in Evergreen scripts to use native Windows paths via cygpath - Fix JSON test file path separator handling and mongocryptd temp directory for Windows compatibility - Skip Unix-domain-socket test on Windows JAVA-6057
There was a problem hiding this comment.
Pull request overview
Adds Windows CI coverage and improves Windows compatibility across tests and Evergreen configuration by standardizing environment-variable access and fixing platform-specific path handling.
Changes:
- Add Windows 2022 Evergreen build variants (server 8.2) and Windows-specific path handling in Evergreen scripts.
- Introduce
EnvironmentProviderto centralize env var access and enable test-time overrides without reflection hacks. - Fix Windows compatibility issues in tests (temp dirs, path separators) and skip a non-portable socket test on Windows.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| driver-sync/src/test/functional/com/mongodb/client/AbstractSessionsProseTest.java | Write mongocryptd logs to Java temp dir for cross-platform support. |
| driver-sync/src/test/functional/com/mongodb/client/AbstractMicrometerProseTest.java | Replace reflective env-var mutation with EnvironmentProvider overrides in micrometer prose tests. |
| driver-core/src/test/unit/com/mongodb/internal/EnvironmentProviderTest.java | Add unit tests for env lookup/override behavior. |
| driver-core/src/test/functional/com/mongodb/internal/connection/SocketStreamHelperSpecification.groovy | Skip a socket configuration test on Windows. |
| driver-core/src/test/functional/com/mongodb/internal/connection/FaasEnvironmentAccessor.java | Remove test-only accessor for env overrides (superseded by EnvironmentProvider). |
| driver-core/src/test/functional/com/mongodb/internal/connection/ClientMetadataTest.java | Update .dockerenv path to match production logic and be OS-correct. |
| driver-core/src/test/functional/com/mongodb/client/WithWrapper.java | Switch env-var test wrapper to EnvironmentProvider.envOverride(). |
| driver-core/src/main/com/mongodb/internal/observability/micrometer/TracingManager.java | Use EnvironmentProvider.getEnv for observability env vars. |
| driver-core/src/main/com/mongodb/internal/observability/micrometer/MicrometerTracer.java | Use EnvironmentProvider.getEnv for query text length env var. |
| driver-core/src/main/com/mongodb/internal/EnvironmentProvider.java | New centralized env var provider + override mechanism for tests. |
| driver-core/src/main/com/mongodb/internal/connection/OidcAuthenticator.java | Read OIDC-related env vars via EnvironmentProvider. |
| driver-core/src/main/com/mongodb/internal/connection/FaasEnvironment.java | Delegate env var reads to EnvironmentProvider (removing test override map). |
| driver-core/src/main/com/mongodb/internal/authentication/BuiltInAwsCredentialSupplier.java | Read AWS env vars via EnvironmentProvider. |
| bson/src/test/unit/util/JsonPoweredTestHelper.java | Normalize path separators to reliably locate JSON spec files on Windows. |
| .evergreen/setup-env.bash | Add Windows-specific JDK paths for Evergreen. |
| .evergreen/run-tests.sh | Use native Windows paths for SSL keystore/truststore and log Windows version. |
| .evergreen/run-csfle-tests-with-mongocryptd.sh | Use native Windows paths for SSL keystore/truststore. |
| .evergreen/.evg.yml | Add Windows axes/buildvariants and introduce MongoDB 8.2 for Windows coverage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
# Conflicts: # driver-core/src/main/com/mongodb/internal/observability/micrometer/TracingManager.java # driver-sync/src/test/functional/com/mongodb/client/AbstractMicrometerProseTest.java
| tags: [ "tests-variant" ] | ||
| tasks: | ||
| - name: "test-sync-task" | ||
| exec_timeout_secs: 7200 |
There was a problem hiding this comment.
Tests run longer on Windows ~1h 30min - 1h 40 min, so it is bumped to 2 hours.
| * | ||
| * <p>Tests can override values via {@link #envOverride()}.</p> | ||
| */ | ||
| public final class EnvironmentProvider { |
There was a problem hiding this comment.
Why this PR introduces EnvironmentProvider (and consolidates env handling)
We previously used a reflection-based test helper in AbstractMucromiterProseTests to override environment variables. That approach broke on Windows due to differences in the JDK’s ProcessEnvironment implementation.
What worked on Linux/macOS
ProcessEnvironment effectively exposes a single backing map. The reflection helper mutates that map, and System.getenv() / System.getenv("KEY") read from the same data, thus overrides are visible.
What breaks on Windows
The JDK maintains two maps:
- theEnvironment (HashMap): backs System.getenv() (returns the full map)
- theCaseInsensitiveEnvironment (TreeMap, without case-insensitive comparator): backs System.getenv(String key) (single-key lookup)
The reflection helper only updated theEnvironment. Our production code uses System.getenv("OBSERVABILITY_MONGODB_ENABLED"), which reads from theCaseInsensitiveEnvironment, so the override was invisible on Windows, thus Micrometer tests failed.
What this PR changes
Introduces EnvironmentProvider to avoid reflection/JDK internals entirely. Production code calls EnvironmentProvider.getEnv() instead of System.getenv().
Tests override the provider via envOverride(...) (swapping the underlying supplier/lambda), which behaves consistently across platforms.
EnviromentOverride is AutoCloseable, so tests can use try-with-resources and avoid boilerplate while keeping overrides scoped and explicit.
Changes in this PR:
JAVA-6057
Checklist
AI Usage & Effectiveness
What Claude (Opus 4.6) did (mostly boilerplate/mechanical refactoring):
EnvironmentProviderclass (after the author, without Claude, designed a detailed plan using the lambda-based approach)System.getenv()call sites toEnvironmentProvider.getEnv()(FaasEnvironment,OidcAuthenticator,BuiltInAwsCredentialSupplier,TracingManager,MicrometerTracer)FaasEnvironmentAccessorand the reflection hack fromAbstractMicrometerProseTestWithWrapperclass to use the new patternmongocryptd /tmp/path for WindowsWhat Claude (Opus 4.6) suggestions were rejected:
EnvironmentProvider(volatile,ConcurrentHashMap,override(Map)constructor)What was done manually:
EnvironmentProviderapproach (lambda field, novolatile, noConcurrentHashMap)SERVER-116018)