Mock Channel Server#
The mock channel server is a local HTTP server that serves a conda channel with pre-packaged test data. This allows tests to run offline without requiring network access to conda-forge or PyPI.
Overview#
The mock channel server is located in tests/conda_local_channel/ and provides:
Conda packages: Pre-built
.condapackages for common dependenciesRepodata: Channel metadata in
repodata.jsonand/orrepodata.json.zstformatsMultiple platforms: Support for
linux-64,osx-arm64, andnoarchsubdirectories
Directory Structure#
tests/conda_local_channel/
├── channeldata.json # Channel-level metadata
├── index.html # Human-readable channel index
├── linux-64/ # Linux x86_64 packages
│ ├── python-*.conda
│ ├── *.conda # Other conda packages
│ ├── repodata.json # Package index
│ └── repodata.json.zst # Compressed index
├── osx-arm64/ # macOS ARM64 packages
│ ├── python-*.conda
│ ├── *.conda
│ ├── repodata.json
│ └── repodata.json.zst
└── noarch/ # Platform-independent packages
├── *.whl # Python wheels
├── repodata.json
└── repodata.json.zst
Using the Mock Channel Server#
In Tests#
The mock channel server is available as a pytest fixture:
def test_with_mock_channel(conda_local_channel):
"""Test using the mock conda channel."""
# conda_local_channel is a URL like "http://localhost:8037"
# Use it in your test
channel_url = conda_local_channel
# ... test code that uses the channel
The fixture automatically:
Starts an HTTP server on a port automatically
Serves the
tests/conda_local_channel/directoryReturns the server URL
Cleans up the server after the test completes
Example: Testing Package Installation#
from conda.cli.main import main_subshell
def test_install_from_mock_channel(conda_local_channel, tmp_path):
"""Test installing a package from the mock channel."""
env_prefix = tmp_path / "test_env"
result = main_subshell(
"create",
"--prefix",
str(env_prefix),
"--channel",
conda_local_channel,
"--override-channels",
"python=3.12",
"requests",
)
assert result == 0
assert (env_prefix / "bin" / "python").exists()
Example: Testing Dependency Resolution#
def test_dependency_resolution(conda_local_channel):
"""Test that dependencies resolve correctly from mock channel."""
from conda_pypi.convert_tree import ConvertTree
# ConvertTree can use the mock channel for dependency resolution
# This allows testing without network access
pass
Adding Packages to the Mock Channel#
Adding Conda Packages#
To add new .conda packages to the mock channel:
Place the
.condafile in the appropriate subdirectory (linux-64,osx-arm64, ornoarch)Update the channel index using
conda-index
# From the project root
pixi run conda-index tests/conda_local_channel/
Or if you have conda-index available:
conda-index tests/conda_local_channel/
Adding Wheel Files#
The mock channel supports serving wheel files from pypi. To add a wheel
you’ll need to update the repodata in order to include the new wheels
you with to support. This is done by using the tests/conda_local_channel/generate_noarch_wheel_repodata.py script. Note, this script is designed for generating test repodata for
conda-pypi only.
Update the list of wheels in tests/conda_local_channel/wheel_packages.txt. Add your package in the same form as a
requirements.txtdependency,<name>==<version>, for example
abstractcp==1.0.0
Regenerate the index:
pixi run python tests/conda_local_channel/generate_noarch_wheel_repodata.py
Current Test Packages#
The mock channel currently includes:
Platform Packages (linux-64, osx-arm64):
Python 3.12
Core dependencies:
bzip2,libexpat,libffi,libsqlite,libzlib,ncurses,openssl,readline,tk,tzdataPython tools:
pip,setuptools,wheel
Noarch Wheels:
requests: HTTP library for testing network-dependent codefastapi: Web framework for testing API conversionspydantic: Data validation for testing metadataabqpy: Package with specific dependency requirementsAnd more…
Implementation Details#
Wheel Support in Repodata#
conda-pypi extends conda’s repodata format to support wheel files. The repodata includes a packages.whl section alongside the standard packages and packages.conda sections:
{
"info": {
"subdir": "noarch"
},
"packages": {},
"packages.conda": {},
"packages.whl": {
"package-name.whl": { ... }
}
}
This allows the conda solver to consider wheels during dependency resolution.
Maintenance#
Updating Packages#
When updating test packages:
Update the package files: Replace or add new
.condaor.whlfilesRegenerate indexes: Run
conda-indexon the channel directoryVerify tests pass: Run the test suite to ensure nothing broke
Commit changes: Include both the package files and updated repodata
Keeping Packages Small#
To keep the test suite fast and the repository small:
Use minimal packages when possible
Consider using package “stubs” with minimal actual content
Compress large packages
Only include packages that are actually used in tests
Platform Considerations#
The mock channel includes packages for multiple platforms:
linux-64: Used in CI and Linux development
osx-arm64: Used for Apple Silicon development
noarch: Platform-independent packages (wheels and pure Python)
Ensure packages exist for the platforms where tests will run, or make tests platform-conditional.
Troubleshooting#
Package Not Found#
Problem: Tests fail because a package can’t be found in the mock channel
Solution:
Verify the package exists in the appropriate subdirectory
Check that
repodata.jsonincludes the packageRegenerate the index with
conda-indexEnsure the test is using
--override-channelsto force using the mock channel
Metadata Mismatch#
Problem: Package installs but with wrong dependencies
Solution:
Verify the
repodata.jsonhas correct dependency informationCheck that the package metadata matches the actual package contents
Regenerate the index to ensure consistency
Best Practices#
Keep it minimal: Only add packages that are actually needed for tests
Document additions: When adding packages, document why they’re needed
Regenerate indexes: Always run
conda-indexafter modifying packagesTest offline: Ensure tests can run without network access
Version pin sparingly: Only pin versions when necessary for test stability