Skip to content

Commit

Permalink
Parametrize test_priority.py (#12895)
Browse files Browse the repository at this point in the history
  • Loading branch information
kenodegard committed Jul 24, 2023
1 parent 0ce7863 commit 14d611a
Showing 1 changed file with 46 additions and 100 deletions.
146 changes: 46 additions & 100 deletions tests/test_priority.py
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.

Copy link
@jaimergp

jaimergp Aug 25, 2023

Contributor

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 only zlib.

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


# set pinned package
if pinned_package:
monkeypatch.setenv("CONDA_PINNED_PACKAGES", package1)

This comment has been minimized.

Copy link
@jaimergp

jaimergp Aug 25, 2023

Contributor
-        monkeypatch.setenv("CONDA_PINNED_PACKAGES", package1)
+        monkeypatch.setenv("CONDA_PINNED_PACKAGES", f"defaults::{package1}")

fixes this in libmamba.


# 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"

0 comments on commit 14d611a

Please sign in to comment.