From b1c4950261a7fed9fe35c62d488367083b6cc9bf Mon Sep 17 00:00:00 2001 From: Hind-M <70631848+Hind-M@users.noreply.github.com> Date: Tue, 3 Oct 2023 10:51:16 +0200 Subject: [PATCH] [Micromamba] Add mamba tests (#2877) * Add mamba `test_api` tests to umamba * Add more tests --- .../tests/channel_a/linux-64/repodata.json | 53 ++++++ .../tests/channel_a/linux-64/repodata.tar.bz2 | Bin 0 -> 522 bytes .../tests/channel_a/linux-64/repodata.tpl | 55 ++++++ .../noarch/_r-mutex-1.0.1-anacondar_1.tar.bz2 | Bin 0 -> 3566 bytes .../tests/channel_a/noarch/repodata.json | 40 +++++ .../tests/channel_a/win-64/repodata.json | 53 ++++++ .../tests/channel_a/win-64/repodata.tar.bz2 | Bin 0 -> 507 bytes .../tests/channel_a/win-64/repodata.tpl | 55 ++++++ .../tests/channel_b/linux-64/repodata.json | 23 +++ .../tests/channel_b/noarch/repodata.json | 1 + .../tests/channel_b/win-64/repodata.json | 23 +++ micromamba/tests/conftest.py | 47 +++++ micromamba/tests/helpers.py | 16 ++ micromamba/tests/test_create.py | 167 ++++++++++++++++++ micromamba/tests/test_install.py | 102 +++++++++++ micromamba/tests/test_repoquery.py | 73 +++++++- 16 files changed, 699 insertions(+), 9 deletions(-) create mode 100644 micromamba/tests/channel_a/linux-64/repodata.json create mode 100644 micromamba/tests/channel_a/linux-64/repodata.tar.bz2 create mode 100644 micromamba/tests/channel_a/linux-64/repodata.tpl create mode 100644 micromamba/tests/channel_a/noarch/_r-mutex-1.0.1-anacondar_1.tar.bz2 create mode 100644 micromamba/tests/channel_a/noarch/repodata.json create mode 100644 micromamba/tests/channel_a/win-64/repodata.json create mode 100644 micromamba/tests/channel_a/win-64/repodata.tar.bz2 create mode 100644 micromamba/tests/channel_a/win-64/repodata.tpl create mode 100644 micromamba/tests/channel_b/linux-64/repodata.json create mode 100644 micromamba/tests/channel_b/noarch/repodata.json create mode 100644 micromamba/tests/channel_b/win-64/repodata.json diff --git a/micromamba/tests/channel_a/linux-64/repodata.json b/micromamba/tests/channel_a/linux-64/repodata.json new file mode 100644 index 0000000000..7766241e09 --- /dev/null +++ b/micromamba/tests/channel_a/linux-64/repodata.json @@ -0,0 +1,53 @@ +{ + "info": { + "subdir": "linux-64" + }, + "packages": { + "A_0.1.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "a", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "linux-64", + "timestamp": 1578950023135, + "version": "0.1.0" + }, + "A_0.2.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "a", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "linux-64", + "timestamp": 1578950023135, + "version": "0.2.0" + }, + "B_0.1.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [ + "a" + ], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "b", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "linux-64", + "timestamp": 1578950023135, + "version": "0.1.0" + } + }, + "removed": [], + "repodata_version": 1 +} diff --git a/micromamba/tests/channel_a/linux-64/repodata.tar.bz2 b/micromamba/tests/channel_a/linux-64/repodata.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..573cf8494de6780730669de70402047d8d668329 GIT binary patch literal 522 zcmV+l0`>huT4*^jL0KkKS%oymbpQhCe~j2L0Dw>jfABN_2nzrI-}(dq00969Kmt4f z0AMr#05kvq000aIfB*)700001fY1N{&;S4c01-$@fK32}KPdG^o>OVGrjJw9ZzP`G zG5pRIY^g*ka6zwBiWCSCAOw}YyJkjj&P>n=6P(#oZMK3w&?12bP~F zn91it_HAfxc|4z}^?cn+qx@=p+N0mI&jWD_5b;7FU?5?Elp)-AydO47_^|70DcCoh z;EM-q>n9sRNAS(O=tNDRbj^`lE7_#q39$5dH^XRiYi!uvCbkMccBeyig>I(CA3aW0 zxW27zY@RMJt6+WGcR8{wV0AV$ZDGNNtBo5R8%G8~Q=yxaHl`Ze0#jp0@)tJ!9oA&z z-sZ!h$jQ>p$5w{MOx)OYIWly%x|ujNyPVrlUE{CBcZVm^enz(!b)S!CgTbCpm;3d2 zwJqgt_Xl&-DD`k3lXDLyr~VsyyMAuQw)dOKsjc)faSg4HN27?;-qH7y^mM!5Khf?U z_GQhX_{p)w@q8b%lSf|TzwGU1JckG5_fRSgfem|k4}n;cZe-rghZt%~Gid{*kY~W` zVL;3*u`ZxVlRt=}X}ya2LJ#7 literal 0 HcmV?d00001 diff --git a/micromamba/tests/channel_a/linux-64/repodata.tpl b/micromamba/tests/channel_a/linux-64/repodata.tpl new file mode 100644 index 0000000000..3358560093 --- /dev/null +++ b/micromamba/tests/channel_a/linux-64/repodata.tpl @@ -0,0 +1,55 @@ +{ + "info": { + "subdir": "linux-64" + }, + "packages": { + "A_0.1.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [ + ], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "a", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "linux-64", + "timestamp": 1578950023135, + "version": "0.1.0" + }, + "A_0.2.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [ + ], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "a", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "linux-64", + "timestamp": 1578950023135, + "version": "0.2.0" + }, + "B_0.1.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [ + "a"GLIBC_PLACEHOLDER + ], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "b", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "linux-64", + "timestamp": 1578950023135, + "version": "0.1.0" + } + }, + "removed": [], + "repodata_version": 1 +} diff --git a/micromamba/tests/channel_a/noarch/_r-mutex-1.0.1-anacondar_1.tar.bz2 b/micromamba/tests/channel_a/noarch/_r-mutex-1.0.1-anacondar_1.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..1da51e0c52b32a7a4b4288ab3d4ee878e8ad63b9 GIT binary patch literal 3566 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 literal 0 HcmV?d00001 diff --git a/micromamba/tests/channel_a/win-64/repodata.tpl b/micromamba/tests/channel_a/win-64/repodata.tpl new file mode 100644 index 0000000000..f51e3e8d13 --- /dev/null +++ b/micromamba/tests/channel_a/win-64/repodata.tpl @@ -0,0 +1,55 @@ +{ + "info": { + "subdir": "win-64" + }, + "packages": { + "A_0.1.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [ + ], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "a", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "win-64", + "timestamp": 1578950023135, + "version": "0.1.0" + }, + "A_0.2.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [ + ], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "a", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "win-64", + "timestamp": 1578950023135, + "version": "0.2.0" + }, + "B_0.1.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [ + "a"GLIBC_PLACEHOLDER + ], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "b", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "win-64", + "timestamp": 1578950023135, + "version": "0.1.0" + } + }, + "removed": [], + "repodata_version": 1 +} diff --git a/micromamba/tests/channel_b/linux-64/repodata.json b/micromamba/tests/channel_b/linux-64/repodata.json new file mode 100644 index 0000000000..c28d1f38c8 --- /dev/null +++ b/micromamba/tests/channel_b/linux-64/repodata.json @@ -0,0 +1,23 @@ +{ + "info": { + "subdir": "linux-64" + }, + "packages": { + "A_0.1.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "a", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "linux-64", + "timestamp": 1578950023135, + "version": "0.1.0" + } + }, + "removed": [], + "repodata_version": 1 +} diff --git a/micromamba/tests/channel_b/noarch/repodata.json b/micromamba/tests/channel_b/noarch/repodata.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/micromamba/tests/channel_b/noarch/repodata.json @@ -0,0 +1 @@ +{} diff --git a/micromamba/tests/channel_b/win-64/repodata.json b/micromamba/tests/channel_b/win-64/repodata.json new file mode 100644 index 0000000000..ee93a3ac35 --- /dev/null +++ b/micromamba/tests/channel_b/win-64/repodata.json @@ -0,0 +1,23 @@ +{ + "info": { + "subdir": "win-64" + }, + "packages": { + "A_0.1.0.tar.bz2": { + "build": "abc", + "build_number": 0, + "depends": [], + "license": "BSD", + "license_family": "BSD", + "md5": "85107fc10154734ef34a5a75685be684", + "name": "a", + "sha256": "398831eff682d2c975b360d64656d8f475cbc1f1b6d0ee33d86285190e7ee4d1", + "size": 222503, + "subdir": "win-64", + "timestamp": 1578950023135, + "version": "0.1.0" + } + }, + "removed": [], + "repodata_version": 1 +} diff --git a/micromamba/tests/conftest.py b/micromamba/tests/conftest.py index 3a30ffca12..9195e5640a 100644 --- a/micromamba/tests/conftest.py +++ b/micromamba/tests/conftest.py @@ -229,3 +229,50 @@ def user_cache_dir(tmp_home: pathlib.Path) -> Generator[pathlib.Path, None, None yield pathlib.Path(os.environ["LOCALAPPDATA"]) / "mamba" else: raise RuntimeError(f"Unsupported system {system}") + + +def get_glibc_version(): + try: + output = subprocess.check_output(["ldd", "--version"]) + except: + return + output.splitlines() + version = output.splitlines()[0].split()[-1] + return version.decode("ascii") + + +@pytest.fixture +def add_glibc_virtual_package(): + version = get_glibc_version() + here = os.path.dirname(os.path.abspath(__file__)) + with open(os.path.join(here, "channel_a/linux-64/repodata.tpl")) as f: + repodata = f.read() + with open(os.path.join(here, "channel_a/linux-64/repodata.json"), "w") as f: + if version is not None: + glibc_placeholder = ', "__glibc=' + version + '"' + else: + glibc_placeholder = "" + repodata = repodata.replace("GLIBC_PLACEHOLDER", glibc_placeholder) + f.write(repodata) + + +@pytest.fixture +def copy_channels_osx(): + import shutil + + here = os.path.dirname(os.path.abspath(__file__)) + for channel in ["a", "b"]: + if not os.path.exists(os.path.join(here, f"channel_{channel}/osx-64")): + shutil.copytree( + os.path.join(here, f"channel_{channel}/linux-64"), + os.path.join(here, f"channel_{channel}/osx-64"), + ) + with open( + os.path.join(here, f"channel_{channel}/osx-64/repodata.json") + ) as f: + repodata = f.read() + with open( + os.path.join(here, f"channel_{channel}/osx-64/repodata.json"), "w" + ) as f: + repodata = repodata.replace("linux", "osx") + f.write(repodata) diff --git a/micromamba/tests/helpers.py b/micromamba/tests/helpers.py index a77c975fd6..9ef2169f25 100644 --- a/micromamba/tests/helpers.py +++ b/micromamba/tests/helpers.py @@ -505,3 +505,19 @@ def get_fake_activate(prefix): env["PATH"] = os.pathsep.join([str(x) for x in addpath + curpath]) env["CONDA_PREFIX"] = str(prefix) return env + + +def create_with_chan_pkg(env_name, channels, package): + cmd = [ + "-n", + env_name, + "--override-channels", + "--strict-channel-priority", + "--dry-run", + "--json", + ] + for channel in channels: + cmd += ["-c", os.path.abspath(os.path.join(*channel))] + cmd.append(package) + + return create(*cmd, default_channel=False, no_rc=False) diff --git a/micromamba/tests/test_create.py b/micromamba/tests/test_create.py index f6ac1cb95d..b6f12ace83 100644 --- a/micromamba/tests/test_create.py +++ b/micromamba/tests/test_create.py @@ -797,6 +797,22 @@ def test_pyc_compilation(tmp_home, tmp_root_prefix, version, build, cache_tag): assert pyc_fn.name in six_meta +def test_create_check_dirs(tmp_home, tmp_root_prefix): + env_name = "myenv" + env_prefix = tmp_root_prefix / "envs" / env_name + cmd = ["-n", env_name, "python=3.8", "traitlets"] + helpers.create(*cmd) + + assert os.path.isdir(env_prefix) + + if platform.system() == "Windows": + assert os.path.isdir(env_prefix / "lib" / "site-packages" / "traitlets") + else: + assert os.path.isdir( + env_prefix / "lib" / "python3.8" / "site-packages" / "traitlets" + ) + + @pytest.mark.parametrize("shared_pkgs_dirs", [True], indirect=True) @pytest.mark.parametrize("env_file", env_files) def test_requires_pip_install(tmp_home, tmp_root_prefix, env_file): @@ -921,3 +937,154 @@ def test_long_path_support(tmp_home, tmp_root_prefix): """Create an environment with a long name.""" res = helpers.create("-n", "long_prefix_" * 20, "--json") assert res["success"] + + +def test_dummy_create( + add_glibc_virtual_package, copy_channels_osx, tmp_home, tmp_root_prefix +): + env_name = "myenv" + + channels = [ + (".", "micromamba", "tests", "channel_b"), + (".", "micromamba", "tests", "channel_a"), + ] + package = "a" + res = helpers.create_with_chan_pkg(env_name, channels, package) + + for link in res["actions"]["LINK"]: + assert link["name"] == "a" + assert link["build"] == "abc" + assert "channel_b" in link["channel"] + + package = "b" + res = helpers.create_with_chan_pkg(env_name, channels, package) + + assert any( + link["name"] == "b" and "channel_a" in link["channel"] + for link in res["actions"]["LINK"] + ) + + channels = channels[::-1] + res = helpers.create_with_chan_pkg(env_name, channels, package) + + +@pytest.mark.parametrize("use_json", [True, False]) +def test_create_dry_run(tmp_home, tmp_root_prefix, use_json): + env_name = "myenv" + env_prefix = tmp_root_prefix / "envs" / env_name + + cmd = ["-n", env_name, "--dry-run", "python=3.8"] + + if use_json: + cmd += ["--json"] + + res = helpers.create(*cmd) + + if not use_json: + # Assert the non-JSON output is in the terminal. + assert "Total download" in res + + # dry-run, shouldn't create an environment + assert not os.path.isdir(env_prefix) + + +def test_create_with_non_existing_subdir(tmp_home, tmp_root_prefix, tmp_path): + env_prefix = tmp_path / "myprefix" + with pytest.raises(subprocess.CalledProcessError) as e: + helpers.create( + "-p", env_prefix, "--dry-run", "--json", f"conda-forge/noarch::xtensor" + ) + + +def test_create_with_multiple_files(tmp_home, tmp_root_prefix, tmpdir): + env_name = "myenv" + env_prefix = tmp_root_prefix / "envs" / env_name + + # Check that multiple --file arguments are considered + (tmpdir / "file_a.txt").write(b"a") + (tmpdir / "file_b.txt").write(b"b") + + res = helpers.create( + "-n", + env_name, + "--json", + "--override-channels", + "--strict-channel-priority", + "--dry-run", + "-c", + "./micromamba/tests/channel_b", + "-c", + "./micromamba/tests/channel_a", + "--file", + str(tmpdir / "file_a.txt"), + "--file", + str(tmpdir / "file_b.txt"), + default_channel=False, + no_rc=False, + ) + + names = {x["name"] for x in res["actions"]["FETCH"]} + assert names == {"a", "b"} + + +multichannel_config = { + "channels": ["conda-forge"], + "custom_multichannels": {"conda-forge2": ["conda-forge"]}, +} + + +def test_create_with_multi_channels(tmp_home, tmp_root_prefix, tmp_path): + env_name = "myenv" + env_prefix = tmp_root_prefix / "envs" / env_name + + rc_file = tmp_path / "config.yaml" + rc_file.write_text(yaml.dump(multichannel_config)) + + res = helpers.create( + "-n", + env_name, + "conda-forge2::xtensor", + "--dry-run", + "--json", + f"--rc-file={rc_file}", + default_channel=False, + no_rc=False, + ) + + for pkg in res["actions"]["FETCH"]: + assert pkg["channel"].startswith("https://conda.anaconda.org/conda-forge/") + for pkg in res["actions"]["LINK"]: + assert pkg["url"].startswith("https://conda.anaconda.org/conda-forge/") + + +def test_create_with_multi_channels_and_non_existing_subdir( + tmp_home, tmp_root_prefix, tmp_path +): + env_name = "myenv" + env_prefix = tmp_root_prefix / "envs" / env_name + + rc_file = tmp_path / "config.yaml" + rc_file.write_text(yaml.dump(multichannel_config)) + + with pytest.raises(subprocess.CalledProcessError) as e: + res = helpers.create( + "-n", + env_name, + "conda-forge2/noarch::xtensor", + "--dry-run", + "--json", + f"--rc-file={rc_file}", + default_channel=False, + no_rc=False, + ) + + +def test_create_with_unicode(tmp_home, tmp_root_prefix): + env_name = "320 áγђß家固êôōçñ한" + env_prefix = tmp_root_prefix / "envs" / env_name + + res = helpers.create("-n", env_name, "--json", "xtensor", no_rc=False) + + assert res["actions"]["PREFIX"] == str(env_prefix) + assert any(pkg["name"] == "xtensor" for pkg in res["actions"]["FETCH"]) + assert any(pkg["name"] == "xtl" for pkg in res["actions"]["FETCH"]) diff --git a/micromamba/tests/test_install.py b/micromamba/tests/test_install.py index e707540f75..870c447cad 100644 --- a/micromamba/tests/test_install.py +++ b/micromamba/tests/test_install.py @@ -569,3 +569,105 @@ def test_force_reinstall_not_installed(self, existing_cache): """Force reinstall on non-installed packages is valid.""" reinstall_res = install("xtensor", "--force-reinstall", "--json") assert "xtensor" in {pkg["name"] for pkg in reinstall_res["actions"]["LINK"]} + + +def test_install_check_dirs(tmp_home, tmp_root_prefix): + env_name = "myenv" + env_prefix = tmp_root_prefix / "envs" / env_name + + create("-n", env_name, "python=3.8") + res = install("-n", env_name, "nodejs", "--json") + + assert os.path.isdir(env_prefix) + assert "nodejs" in {pkg["name"] for pkg in res["actions"]["LINK"]} + + if platform.system() == "Windows": + assert os.path.isdir(env_prefix / "lib" / "site-packages") + else: + assert os.path.isdir(env_prefix / "lib" / "python3.8" / "site-packages") + + +def test_track_features(tmp_home, tmp_root_prefix): + env_name = "myenv" + env_prefix = tmp_root_prefix / "envs" / env_name + + # should install CPython since PyPy has track features + version = "3.7.9" + create("-n", env_name, default_channel=False, no_rc=False) + install( + "-n", + env_name, + "-q", + f"python={version}", + "--strict-channel-priority", + no_rc=False, + ) + res = umamba_run("-n", env_name, "python", "-c", "import sys; print(sys.version)") + if platform.system() == "Windows": + assert res.strip().startswith(version) + assert "[MSC v." in res.strip() + elif platform.system() == "Linux": + assert res.strip().startswith(version) + assert "[GCC" in res.strip() + else: + assert res.strip().startswith(version) + assert "[Clang" in res.strip() + + if platform.system() == "Linux": + # now force PyPy install + install( + "-n", + env_name, + "-q", + f"python={version}=*pypy", + "--strict-channel-priority", + no_rc=False, + ) + res = umamba_run( + "-n", env_name, "python", "-c", "import sys; print(sys.version)" + ) + + assert res.strip().startswith(version) + assert "[PyPy" in res.strip() + + +def test_reinstall_with_new_version(tmp_home, tmp_root_prefix): + env_name = "myenv" + env_prefix = tmp_root_prefix / "envs" / env_name + + version = "3.8" + create("-n", env_name, default_channel=False, no_rc=False) + install( + "-n", + env_name, + "-q", + f"python={version}", + "pip", + no_rc=False, + ) + + res = umamba_run("-n", env_name, "python", "-c", "import sys; print(sys.version)") + assert version in res + + res = umamba_run( + "-n", env_name, "python", "-c", "import pip; print(pip.__version__)" + ) + assert len(res) + + # Update python version + version = "3.9" + install( + "-n", + env_name, + "-q", + f"python={version}", + no_rc=False, + ) + + res = umamba_run("-n", env_name, "python", "-c", "import sys; print(sys.version)") + assert version in res + + res = umamba_run( + "-n", env_name, "python", "-c", "import pip; print(pip.__version__)" + ) + assert len(res) diff --git a/micromamba/tests/test_repoquery.py b/micromamba/tests/test_repoquery.py index 775a3dfa72..f923cbd4b7 100644 --- a/micromamba/tests/test_repoquery.py +++ b/micromamba/tests/test_repoquery.py @@ -49,10 +49,23 @@ def test_depends_not_installed(yaml_env: Path): @pytest.mark.parametrize("shared_pkgs_dirs", [True], indirect=True) -def test_depends_not_installed_with_channel(yaml_env: Path): - res = helpers.umamba_repoquery( - "depends", "-c", "conda-forge", "xtensor=0.24.5", "--json" - ) +@pytest.mark.parametrize("with_platform", (False, True)) +def test_depends_not_installed_with_channel(yaml_env: Path, with_platform): + if with_platform: + res = helpers.umamba_repoquery( + "depends", + "-c", + "conda-forge", + "xtensor=0.24.5", + "--platform", + "win-64", + "--json", + ) + assert res["result"]["pkgs"][0]["subdir"] == "win-64" + else: + res = helpers.umamba_repoquery( + "depends", "-c", "conda-forge", "xtensor=0.24.5", "--json" + ) assert res["query"]["query"] == "xtensor =0.24.5*" assert res["query"]["type"] == "depends" @@ -65,7 +78,7 @@ def test_depends_not_installed_with_channel(yaml_env: Path): assert any(x["name"] == "xtensor" for x in pkgs) assert any(x["name"] == "xtl" for x in pkgs) - if platform.system() == "Linux": + if not with_platform and platform.system() == "Linux": assert any(x["name"] == "libgcc-ng" for x in pkgs) assert any(x["name"] == "libstdcxx-ng" for x in pkgs) @@ -124,10 +137,23 @@ def test_whoneeds_not_installed(yaml_env: Path): @pytest.mark.parametrize("shared_pkgs_dirs", [True], indirect=True) -def test_whoneeds_not_installed_with_channel(yaml_env: Path): - res = helpers.umamba_repoquery( - "whoneeds", "-c", "conda-forge", "xtensor=0.24.5", "--json" - ) +@pytest.mark.parametrize("with_platform", (False, True)) +def test_whoneeds_not_installed_with_channel(yaml_env: Path, with_platform): + if with_platform: + res = helpers.umamba_repoquery( + "whoneeds", + "-c", + "conda-forge", + "xtensor=0.24.5", + "--platform", + "osx-64", + "--json", + ) + assert res["result"]["pkgs"][0]["subdir"] == "osx-64" + else: + res = helpers.umamba_repoquery( + "whoneeds", "-c", "conda-forge", "xtensor=0.24.5", "--json" + ) assert res["query"]["query"] == "xtensor =0.24.5*" assert res["query"]["type"] == "whoneeds" @@ -150,6 +176,35 @@ def test_whoneeds_tree(yaml_env: Path): assert "qpot" in res +@pytest.mark.parametrize("shared_pkgs_dirs", [True], indirect=True) +@pytest.mark.parametrize("with_platform", (False, True)) +def test_search(yaml_env: Path, with_platform): + if with_platform: + res = helpers.umamba_repoquery( + "search", + "-c", + "conda-forge", + "xtensor*", + "--platform", + "linux-64", + "--json", + ) + assert res["result"]["pkgs"][0]["subdir"] == "linux-64" + else: + res = helpers.umamba_repoquery( + "search", "-c", "conda-forge", "xtensor*", "--json" + ) + + assert res["query"]["query"] == "xtensor*" + assert res["query"]["type"] == "search" + + pkgs = res["result"]["pkgs"] + assert all("conda-forge" in x["channel"] for x in pkgs) + assert any(x["name"] == "xtensor-blas" for x in pkgs) + assert any(x["name"] == "xtensor" for x in pkgs) + assert any(x["name"] == "xtensor-io" for x in pkgs) + + @pytest.mark.parametrize("shared_pkgs_dirs", [True], indirect=True) def test_remote_search_installed_pkg(yaml_env: Path): res = helpers.umamba_repoquery("search", "yaml")