Add test environment cloning optimization for faster CI - #15677
Conversation
f05403b to
333f1ef
Compare
8e2e64e to
b8930ef
Compare
Merging this PR will degrade performance by 96.67%
Performance Changes
Comparing Footnotes
|
b8930ef to
1db1f08
Compare
Add TemplateEnvManager that creates and caches template environments on demand for different Python versions and package combinations. Key features: - Multiple Python version templates (3.10, 3.11, 3.12, 3.13) created on demand - Python + pip templates for common test scenarios - "Clone + install delta" strategy: clone Python template, install extras - Platform-specific fast copy methods: - macOS (APFS): cp -c for copy-on-write (~1.8s vs ~10s for conda create) - Linux: cp --reflink=auto for reflinks on btrfs/xfs - Windows: robocopy for multi-threaded copy, falls back to shutil.copytree Analysis of test suite showed: - 76 calls (34%) create empty environments - already fast - 23 calls (10%) create Python environments - can benefit from cloning - Many tests use specific Python versions (3.10, 3.11, 3.12, 3.13) The tmp_env fixture now automatically uses the template manager when creating Python environments, significantly reducing test setup time. Based on optimizations from conda-build PR #5904 and conda-pypi PR #236.
1db1f08 to
b944a12
Compare
Replace complex multi-version template management with a simpler approach: - Create ONE template (python + pip) at session start - Use can_satisfy() to check if template has all required packages by name - Clone if satisfied, fall back to conda create otherwise This removes ~200 lines of complexity (parse_python_spec, find_matching_template, delta package installation) while still benefiting the majority of tests that only need "python" or "python" + "pip".
Specs like "python=3.10" were incorrectly matching the template because we only checked package names. This caused tests to get cloned environments with the wrong Python version. Now can_satisfy() rejects specs with ANY version constraint, ensuring we only clone when the template definitely satisfies the test requirements.
can_satisfy() now matches specs WITH version constraints if the template's installed version satisfies them: - "python=3.10" matches if template has Python 3.10.x - "python>=3.9" matches if template has Python >= 3.9 This significantly increases the number of tests that can benefit from cloning when CI runs with a specific Python version. For example, when CI matrix runs with Python 3.10: - "python" specs: 6 tests (clone) - "python=3.10" specs: ~6 tests (clone) - "python=3.10", "pip" specs: 4 tests (clone) Total: ~16 tests benefit vs only 6 with conservative approach
Closing this PRAfter thorough analysis, the optimization provides minimal benefit for the complexity added. Analysis Results
Why It Doesn't Help More
Root CauseThe conda test suite wasn't designed with environment reuse in mind. Tests request diverse, specific requirements that a single (or even multiple) template(s) can't efficiently satisfy. The conda-build implementation (#5904) worked because their test patterns were different - more tests used generic Python specs. Better Alternatives to Explore
I'll explore these alternatives in a separate effort. |
Summary
This PR adds test environment cloning optimization to speed up CI tests that create Python environments. Instead of running
conda createfor each test (~10s+), eligible tests can now clone from a session-scoped template environment (~2s).Analysis of Current Test Environment Creation
Key Findings
python=3.10specs to clone when CI runs with 3.10Optimization Strategy
This PR implements version-aware template cloning:
python+pippython=3.10match if template has Python 3.10.xconda createwhen version constraints don't match or packages missingHow Version Matching Works
Expected Impact
The impact varies by CI matrix:
python=3.10clone ✓pythonspecs cloneImplementation Details
TemplateEnvManagerpackage_versionsdict (name → version) from templatecan_satisfy(specs)checks:VersionSpecfor proper version matchingtemplate_env_managerfixturepython+pip(versions from CI matrix)tmp_envfixture behaviortemplate_manager.can_satisfy(args)returns Trueconda create --clone {template}(~2s)conda create {args}(~10s+)References
Based on optimizations from:
Test Plan