-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Parametrize
test_priority.py
(#12895)
- Loading branch information
1 parent
0ce7863
commit 14d611a
Showing
1 changed file
with
46 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,110 +1,56 @@ | ||
# Copyright (C) 2012 Anaconda, Inc | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
import json | ||
import re | ||
|
||
import pytest | ||
from pytest import MonkeyPatch | ||
|
||
from conda.base.context import conda_tests_ctxt_mgmt_def_pol, context | ||
from conda.common.io import env_var | ||
from conda.base.context import context, reset_context | ||
from conda.core.prefix_data import PrefixData | ||
from conda.testing.integration import ( | ||
Commands, | ||
make_temp_env, | ||
package_is_installed, | ||
run_command, | ||
) | ||
from conda.testing import CondaCLIFixture, TmpEnvFixture | ||
|
||
|
||
@pytest.mark.integration | ||
def test_channel_order_channel_priority_true(): | ||
# This is broken, make_temp_env will reset the context. We get away with it, but really | ||
# we need a function that does both these at the same time. | ||
with env_var( | ||
"CONDA_PINNED_PACKAGES", | ||
"python=3.8", | ||
stack_callback=conda_tests_ctxt_mgmt_def_pol, | ||
): | ||
with make_temp_env("pycosat=0.6.3") as prefix: | ||
assert package_is_installed(prefix, "python=3.8") | ||
assert package_is_installed(prefix, "pycosat") | ||
|
||
payload, _, _ = run_command( | ||
Commands.CONFIG, prefix, "--get", "channels", "--json" | ||
) | ||
default_channels = json.loads(payload)["get"].get("channels") | ||
if default_channels: | ||
run_command(Commands.CONFIG, prefix, "--remove-key", "channels") | ||
|
||
# add conda-forge channel | ||
o, e, _ = run_command( | ||
Commands.CONFIG, | ||
prefix, | ||
"--prepend", | ||
"channels", | ||
"conda-forge", | ||
"--json", | ||
) | ||
assert context.channels == ("conda-forge", "defaults"), o + e | ||
# update --all | ||
update_stdout, _, _ = run_command(Commands.UPDATE, prefix, "--all") | ||
|
||
# this assertion works with the pinned_packages config to make sure | ||
# conda update --all still respects the pinned python version | ||
assert package_is_installed(prefix, "python=3.8") | ||
|
||
# pycosat should be in the SUPERSEDED list | ||
# after the 4.4 solver work, looks like it's in the DOWNGRADED list | ||
# This language needs changed anyway here. | ||
# For packages that CHANGE because they're being moved to a higher-priority channel | ||
# the message should be | ||
# | ||
# The following packages will be UPDATED to a higher-priority channel: | ||
# | ||
installed_str, x = update_stdout.split("UPDATED") | ||
assert re.search( | ||
r"pkgs/main::pycosat-0.6.3-py38h[^\s]+ --> conda-forge::pycosat", x | ||
) | ||
|
||
# python sys.version should show conda-forge python | ||
assert PrefixData(prefix).get("python").channel.name == "conda-forge" | ||
|
||
# conda list should show pycosat coming from conda-forge | ||
assert PrefixData(prefix).get("pycosat").channel.name == "conda-forge" | ||
|
||
|
||
@pytest.mark.integration | ||
def test_channel_priority_update(): | ||
"""This case will fail now.""" | ||
with make_temp_env("python=3.8", "pycosat") as prefix: | ||
assert package_is_installed(prefix, "python") | ||
|
||
# clear channels config first to not assume default is defaults | ||
payload, _, _ = run_command( | ||
Commands.CONFIG, prefix, "--get", "channels", "--json" | ||
) | ||
default_channels = json.loads(payload)["get"].get("channels") | ||
if default_channels: | ||
run_command(Commands.CONFIG, prefix, "--remove-key", "channels") | ||
|
||
# add conda-forge channel | ||
o, e, _ = run_command( | ||
Commands.CONFIG, | ||
prefix, | ||
"--prepend", | ||
"channels", | ||
"conda-forge", | ||
"--json", | ||
@pytest.mark.parametrize( | ||
"pinned_package", | ||
[ | ||
pytest.param(True, id="with pinned_package"), | ||
pytest.param(False, id="without pinned_package"), | ||
], | ||
) | ||
def test_reorder_channel_priority( | ||
tmp_env: TmpEnvFixture, | ||
monkeypatch: MonkeyPatch, | ||
conda_cli: CondaCLIFixture, | ||
pinned_package: bool, | ||
): | ||
# use "cheap" packages with no dependencies | ||
package1 = "zlib" | ||
package2 = "ca-certificates" | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
# set pinned package | ||
if pinned_package: | ||
monkeypatch.setenv("CONDA_PINNED_PACKAGES", package1) | ||
This comment has been minimized.
Sorry, something went wrong.
jaimergp
Contributor
|
||
|
||
# create environment with package1 and package2 | ||
with tmp_env( | ||
"--override-channels", "--channel=defaults", package1, package2 | ||
) as prefix: | ||
# check both packages are installed from defaults | ||
PrefixData._cache_.clear() | ||
assert PrefixData(prefix).get(package1).channel.name == "pkgs/main" | ||
assert PrefixData(prefix).get(package2).channel.name == "pkgs/main" | ||
|
||
# update --all | ||
conda_cli( | ||
"update", | ||
f"--prefix={prefix}", | ||
"--override-channels", | ||
"--channel=conda-forge", | ||
"--all", | ||
"--yes", | ||
) | ||
assert context.channels == ("conda-forge", "defaults"), o + e | ||
|
||
# update python | ||
update_stdout, _, _ = run_command(Commands.UPDATE, prefix, "python") | ||
|
||
# pycosat should be in the SUPERSEDED list | ||
superceded_split = update_stdout.split("UPDATED") | ||
assert len(superceded_split) == 2 | ||
assert "conda-forge" in superceded_split[1] | ||
|
||
# python sys.version should show conda-forge python | ||
assert PrefixData(prefix).get("python").channel.name == "conda-forge" | ||
# check pinned package is unchanged but unpinned packages are updated from conda-forge | ||
PrefixData._cache_.clear() | ||
expected_channel = "pkgs/main" if pinned_package else "conda-forge" | ||
assert PrefixData(prefix).get(package1).channel.name == expected_channel | ||
assert PrefixData(prefix).get(package2).channel.name == "conda-forge" |
After taking a look at why this test fails in libmamba, I am questioning whether I understand conda pins. According to the docs, a pin will constrain which packages are allowed to be in the environment (sort of like a
run_constrained
for the env). However, this test seems to assume that a pin is actually a lock, where if the spec in the pin matches the installed record, then it freezes it.If the former is true, a pinned spec with no version attached to it is a no-op, since it doesn't impose any restraints. If we mean to pin the channel, then the pin should be
defaults::zlib
, not onlyzlib
.If the latter is true, then I think many of the assumptions in the solver logic are wrong.
There's a third scenario, where a bare-name spec is assumed to mean "check if this matches any installed records and freeze it", but if the spec has version constraints, then it acts like a
run_constrained
entry.What is it then?
cc @jezdez @kenodegard