You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ansible/test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml

340 lines
10 KiB
YAML

# Tests for skip_broken and allowerasing
# (and a bit of nobest because the test case is too good to pass up)
#
# There are a lot of fairly complex, corner cases we test here especially towards the end.
#
# The test repo is generated from the "skip-broken" repo in this repository:
# https://github.com/relrod/ansible-ci-contrived-yum-repos
#
# It is laid out like this:
#
# There are three packages, `broken-a`, `broken-b`, `broken-c`.
#
# * broken-a has three versions: 1.2.3, 1.2.3.4, 1.2.4, 2.0.0.
# * 1.2.3 and 1.2.4 have no dependencies
# * 1.2.3.4 and 2.0.0 both depend on a non-existent package (to break depsolving)
#
# * broken-b depends on broken-a-1.2.3
# * broken-c depends on broken-a-1.2.4
# * broken-d depends on broken-a (no version constraint)
#
# This allows us to test various upgrades, downgrades, and installs with broken dependencies.
# skip_broken should usually be successful in the upgrade/downgrade case, it will just do nothing.
#
# There is a nobest testcase or two thrown in, simply because this organization provides a very
# good test case for that behavior as well. For example, just installing "broken-a" with no version
# will try to install 2.0.0 which is broken. With nobest=true, it will fall back to 1.2.4. Similar
# for upgrading.
- block:
- name: Set up test yum repo
yum_repository:
name: skip-broken
description: ansible-test skip-broken test repo
baseurl: "{{ skip_broken_repo_baseurl }}"
gpgcheck: no
repo_gpgcheck: no
- name: Install two packages
dnf:
name:
- broken-a-1.2.3
- broken-b
# This will fail. We have broken-a-1.2.3, and broken-b with a strong
# dependency on it. broken-c has a strong dependency on broken-a-1.2.4.
# Since installing that would break broken-b, we get a conflict.
- name: Try installing a third package, intentionally broken
dnf:
name:
- broken-c
ignore_errors: true
register: dnf_fail
- assert:
that:
- dnf_fail is failed
- "'Depsolve Error' in dnf_fail.msg"
# skip_broken should still install nothing because the conflict is
# still an issue. But it should skip over the broken packages and not
# fail.
- name: Try installing it with skip_broken
dnf:
name:
- broken-c
skip_broken: true
register: skip_broken_res
- name: Assert that nothing got installed
assert:
that:
- skip_broken_res.msg == 'Nothing to do'
- skip_broken_res.rc == 0
- skip_broken_res.results == []
- name: Remove all test packages
dnf:
name:
- broken-*
state: absent
# broken-d depends on (unversioned) broken-a.
# broken-a-2.0.0 has a broken dependency that doesn't exist.
# skip_broken should cause us to skip our explicit broken-a-2.0.0
# and bring in broken-a-1.2.4 as a dep of broken-d.
- name: Ensure proper failure with explicit broken version
dnf:
name:
- broken-a-2.0.0
- broken-d
ignore_errors: true
register: dnf_fail
- name: Assert that nothing got installed
assert:
that:
- dnf_fail is failed
- "'Depsolve Error' in dnf_fail.msg"
- name: skip_broken with explicit version
dnf:
name:
- broken-a-2.0.0
- broken-d
skip_broken: true
register: skip_broken_res
- name: Assert that the right things got installed
assert:
that:
- skip_broken_res.rc == 0
- skip_broken_res.results|length == 2
- res.results|select("contains", "Installed: broken-a-1.2.4")|length > 0
- res.results|select("contains", "Installed: broken-d-1.2.5")|length > 0
- name: Remove all test packages
dnf:
name:
- broken-*
state: absent
# Walk the logic of _mark_package_install() here
# We need to use a full-ish NVR/wildcard. _is_newer_version_installed()
# will be false otherwise, no matter what. This might be a bug.
# Relatedly, the real "Case 1" in the code seemingly can't be reached:
# _is_newer_version_installed wants NVR, _is_installed wants name.
# Both can't be true at the same time given one pkg_spec. Thus, we start
# at "Case 2"
# prereq
- name: Install broken-a-1.2.4
dnf:
name:
- broken-a-1.2.4
state: present
# Case 2: newer version is installed, allow_downgrade is true,
# is_installed is false since we gave full NVR.
# "upgrade" to broken-a-1.2.3, allow_downgrade=true
- name: Do an "upgrade" to an older version of broken-a, allow_downgrade=true
dnf:
name:
- broken-a-1.2.3-1*
state: latest
allow_downgrade: true
check_mode: true
register: res
- assert:
that:
- res is changed
- res.results|select("contains", "Installed: broken-a-1.2.3")|length > 0
# Still case 2, but with broken package to test skip_broken
# skip_broken: false
- name: Do an "upgrade" to an older known broken version of broken-a, allow_downgrade=true, skip_broken=false
dnf:
name:
- broken-a-1.2.3.4-1*
state: latest
allow_downgrade: true
check_mode: true
ignore_errors: true
register: res
- assert:
that:
# 1.2.3.4 has non-existent dep. Fail without skip_broken.
- res is failed
- "'Depsolve Error' in res.msg"
# skip_broken: true
- name: Do an "upgrade" to an older known broken version of broken-a, allow_downgrade=true, skip_broken=true
dnf:
name:
- broken-a-1.2.3.4-1*
state: latest
allow_downgrade: true
skip_broken: true
check_mode: true
register: res
- assert:
that:
- res is not changed
- res.rc == 0
- res.msg == "Nothing to do"
# Case 3: newer version installed, allow_downgrade=true, but
# upgrade=false (i.e., state: present or installed)
- name: Install an older version of broken-a than currently installed
dnf:
name:
- broken-a-1.2.3-1*
state: present
allow_downgrade: true
check_mode: true
register: res
- assert:
that:
- res is changed
- res.results|select("contains", "Installed: broken-a-1.2.3")|length > 0
# Case 3 still, with broken package and skip_broken tests like above.
- name: Install an older known broken version of broken-a, allow_downgrade=true, skip_broken=false
dnf:
name:
- broken-a-1.2.3.4-1*
state: present
allow_downgrade: true
check_mode: true
ignore_errors: true
register: res
- assert:
that:
# 1.2.3.4 has non-existent dep. Fail without skip_broken.
- res is failed
- "'Depsolve Error' in res.msg"
# skip_broken: true
- name: Install an older known broken version of broken-a, allow_downgrade=true, skip_broken=true
dnf:
name:
- broken-a-1.2.3.4-1*
state: present
allow_downgrade: true
skip_broken: true
check_mode: true
register: res
- assert:
that:
- res is not changed
- res.rc == 0
- res.msg == "Nothing to do"
# Case 4: "upgrade" to broken-a-1.2.3, allow_downgrade=false
# is_newer_version_installed is true, allow_downgrade is false
- name: Do an "upgrade" to an older version of broken-a, allow_downgrade=false
dnf:
name:
#- broken-a-1.2.3-1*
- broken-a-1.2.3-1.el7.x86_64
state: latest
allow_downgrade: false
check_mode: true
register: res
- assert:
that:
- res is not changed
- res.rc == 0
- res.msg == "Nothing to do"
# skip_broken doesn't apply to case 5 or 6 (older version installed).
# base.upgrade doesn't allow a strict= kwarg. However, nobest works here.
# Case 5: older version of package is installed, we specify name, no version
# otherwise we'd land in an earlier case. At this point, 1.2.4 is installed.
# broken-a-2.0.0 is available as an update but has a broken dependency.
- name: Update broken-a without nobest=true
dnf:
name:
- broken-a
state: latest
ignore_errors: true
register: dnf_fail
- assert:
that:
- dnf_fail is failed
- "'Depsolve Error' in dnf_fail.msg"
# With nobest: true, we will be "successful" but not actually perform
# any upgrade. That is, we are content not having the "best"/latest
# version.
- name: Update broken-a with nobest=true
dnf:
name:
- broken-a
state: latest
nobest: true
register: nobest
- assert:
that:
- nobest.rc == 0
- nobest.results == []
# Case 6: Current or older version already installed (no version specified
# in our pkg_spec) and we're requesting present, not latest.
#
# This isn't really relevant to skip_broken or nobest, but let's test it
# anyway since we're already walking the logic of the method.
- name: Install broken-a (even though it is already installed)
dnf:
name:
- broken-a
state: present
register: res
- assert:
that:
- res is not changed
# Case 7 is already tested quite extensively above in the earlier tests.
# ######################################################################
- block:
- name: Test available package is installed while unavailable one is skipped due to skip_broken=true
dnf:
name:
- dinginessentail
- not-in-repo
skip_broken: true
register: res
- assert:
that:
- res is changed
# There is a change in dnf5 that splits skip_broken into two options:
# skip_broken and skip_unavailable.
# TODO: for this test to pass on dnf5 the skip_unavailable option would have to be
# added to the dnf5 module and used here instead of skip_broken.
when: not dnf5|default(false)
always:
- name: Remove test yum repo
yum_repository:
name: skip-broken
state: absent
- name: Remove all test packages installed
dnf:
name:
- broken-*
- dinginessentail
state: absent