mirror of
https://github.com/jupyterhub/the-littlest-jupyterhub.git
synced 2025-12-18 21:54:05 +08:00
test ensure_user_environment
verify behavior for: - current version (no change) - old, supported version (upgrade, but not too far) - too old, re-run installer - directory exists, no conda
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
"""
|
||||
Unit test functions in installer.py
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
from unittest import mock
|
||||
from subprocess import run, PIPE
|
||||
|
||||
import pytest
|
||||
|
||||
from tljh import conda
|
||||
from tljh import installer
|
||||
from tljh.utils import parse_version as V
|
||||
from tljh.yaml import yaml
|
||||
|
||||
|
||||
@@ -36,3 +42,111 @@ def test_ensure_admins(tljh_dir, admins, expected_config):
|
||||
|
||||
# verify the list was flattened
|
||||
assert config["users"]["admin"] == expected_config
|
||||
|
||||
|
||||
def setup_conda(distro, version, prefix):
|
||||
"""Install mambaforge or miniconda in a prefix"""
|
||||
if distro == "mambaforge":
|
||||
installer_url, _ = installer._mambaforge_url(version)
|
||||
elif distro == "miniconda":
|
||||
arch = os.uname().machine
|
||||
installer_url = (
|
||||
f"https://repo.anaconda.com/miniconda/Miniconda3-{version}-Linux-{arch}.sh"
|
||||
)
|
||||
else:
|
||||
raise ValueError(f"{distro=} must be 'miniconda' or 'mambaforge'")
|
||||
with conda.download_miniconda_installer(installer_url, None) as installer_path:
|
||||
conda.install_miniconda(installer_path, str(prefix))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def user_env_prefix(tmp_path):
|
||||
user_env_prefix = tmp_path / "user_env"
|
||||
with mock.patch.object(installer, "USER_ENV_PREFIX", str(user_env_prefix)):
|
||||
yield user_env_prefix
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"distro, version, conda_version, mamba_version",
|
||||
[
|
||||
(
|
||||
None,
|
||||
None,
|
||||
installer.MAMBAFORGE_CONDA_VERSION,
|
||||
installer.MAMBAFORGE_MAMBA_VERSION,
|
||||
),
|
||||
(
|
||||
"exists",
|
||||
None,
|
||||
installer.MAMBAFORGE_CONDA_VERSION,
|
||||
installer.MAMBAFORGE_MAMBA_VERSION,
|
||||
),
|
||||
(
|
||||
"mambaforge",
|
||||
"22.11.1-4",
|
||||
installer.MAMBAFORGE_CONDA_VERSION,
|
||||
installer.MAMBAFORGE_MAMBA_VERSION,
|
||||
),
|
||||
("mambaforge", "4.10.3-7", "4.10.3", "0.16.0"),
|
||||
(
|
||||
"miniconda",
|
||||
"4.7.10",
|
||||
installer.MAMBAFORGE_CONDA_VERSION,
|
||||
installer.MAMBAFORGE_MAMBA_VERSION,
|
||||
),
|
||||
(
|
||||
"miniconda",
|
||||
"4.5.1",
|
||||
installer.MAMBAFORGE_CONDA_VERSION,
|
||||
installer.MAMBAFORGE_MAMBA_VERSION,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_ensure_user_environment(
|
||||
user_env_prefix,
|
||||
distro,
|
||||
version,
|
||||
conda_version,
|
||||
mamba_version,
|
||||
):
|
||||
if version and V(version) < V("4.10.1") and os.uname().machine == "aarch64":
|
||||
pytest.skip(f"Miniconda {version} not available for aarch64")
|
||||
canary_file = user_env_prefix / "test-file.txt"
|
||||
canary_package = "types-backports_abc"
|
||||
if distro:
|
||||
if distro == "exists":
|
||||
user_env_prefix.mkdir()
|
||||
else:
|
||||
setup_conda(distro, version, user_env_prefix)
|
||||
# install a noarch: python package that won't be used otherwise
|
||||
# should depend on Python, so it will interact with possible upgrades
|
||||
run(
|
||||
[str(user_env_prefix / "bin/conda"), "install", "-y", canary_package],
|
||||
input="",
|
||||
check=True,
|
||||
)
|
||||
|
||||
# make a file not managed by conda, to check for wipeouts
|
||||
with canary_file.open("w") as f:
|
||||
f.write("I'm here\n")
|
||||
|
||||
installer.ensure_user_environment("")
|
||||
p = run(
|
||||
[str(user_env_prefix / "bin/conda"), "list", "--json"],
|
||||
stdout=PIPE,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
package_list = json.loads(p.stdout)
|
||||
packages = {package["name"]: package for package in package_list}
|
||||
if distro:
|
||||
# make sure we didn't wipe out files
|
||||
assert canary_file.exists()
|
||||
if distro != "exists":
|
||||
# make sure we didn't delete the installed package
|
||||
assert canary_package in packages
|
||||
|
||||
assert "conda" in packages
|
||||
assert packages["conda"]["version"] == conda_version
|
||||
assert "mamba" in packages
|
||||
assert packages["mamba"]["version"] == mamba_version
|
||||
|
||||
@@ -96,7 +96,7 @@ def download_miniconda_installer(installer_url, sha256sum):
|
||||
t = time.perf_counter() - tic
|
||||
logger.info(f"Downloaded conda installer {installer_url} in {t:.1f}s")
|
||||
|
||||
if sha256_file(f.name) != sha256sum:
|
||||
if sha256sum and sha256_file(f.name) != sha256sum:
|
||||
raise Exception("sha256sum hash mismatch! Downloaded file corrupted")
|
||||
|
||||
yield f.name
|
||||
|
||||
@@ -224,7 +224,7 @@ def ensure_user_environment(user_requirements_txt_file):
|
||||
if not found_conda:
|
||||
if os.path.exists(USER_ENV_PREFIX):
|
||||
logger.warning(
|
||||
f"Found prefix at {USER_ENV_PREFIX}, but too old or missing conda/mamba ({have_versions}). Rebuilding env from scratch!!"
|
||||
f"Found prefix at {USER_ENV_PREFIX}, but too old or missing conda/mamba ({have_versions}). Upgrading from mambaforge."
|
||||
)
|
||||
# FIXME: should this fail? I'm not sure how destructive it is
|
||||
logger.info("Downloading & setting up user environment...")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
Miscellaneous functions useful in at least two places unrelated to each other
|
||||
"""
|
||||
import logging
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
# Copied into bootstrap/bootstrap.py. Make sure these two copies are exactly the same!
|
||||
@@ -67,4 +68,6 @@ def parse_version(version_string):
|
||||
Finds all numbers and returns a tuple of ints
|
||||
_very_ loose version parsing, like the old distutils.version.LooseVersion
|
||||
"""
|
||||
return tuple(int(part) for part in version_string.split("."))
|
||||
# return a tuple of all the numbers in the version string
|
||||
# always succeeds, even if passed nonsense
|
||||
return tuple(int(part) for part in re.findall(r"\d+", version_string))
|
||||
|
||||
Reference in New Issue
Block a user