Skip to content

Commit

Permalink
[RHELC-828] Add missing integration tests for single yum transaction (#…
Browse files Browse the repository at this point in the history
…677)

* Add missing integration tests for single yum transaction

While testing convert2rhel manually in a vagrant box, we've bumped into a
traceback when the conversion stopped in the yum transaction validation
phase and no rollback happened.

Since the transaction validation is supposed to trigger the rollback in case of
any failures, it was strange that the tool was not behaving the way it should.

As part of #674 that introduced a fix for that, we left out the integration test
that was supposed to cover this scenario.

Signed-off-by: Rodolfo Olivieri <[email protected]>
Co-authored-by: Michal Bocek <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Feb 16, 2023
1 parent a0b292f commit b90f5bb
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 19 deletions.
37 changes: 21 additions & 16 deletions convert2rhel/pkgmanager/handlers/yum/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@ def _set_up_base(self):
self._base.conf.yumvar["releasever"] = system_info.releasever

def _enable_repos(self):
"""Enable a list of required repositories."""
"""Enable a list of required repositories.
:raises SystemInfo: If there is no way to connect to the mirrors in the
repos.
"""
self._base.repos.disableRepo("*")
# Set the download progress display
self._base.repos.setProgressBar(PackageDownloadCallback())
Expand All @@ -149,22 +153,23 @@ def _perform_operations(self):

loggerinst.info("Adding %s packages to the yum transaction set.", system_info.name)

for pkg in original_os_pkgs:
self._base.update(pattern=pkg)
try:
self._base.reinstall(pattern=pkg)
except (
pkgmanager.Errors.ReinstallInstallError,
pkgmanager.Errors.ReinstallRemoveError,
):
try:
for pkg in original_os_pkgs:
self._base.update(pattern=pkg)
try:
self._base.downgrade(pattern=pkg)
except (
pkgmanager.Errors.ReinstallInstallError,
pkgmanager.Errors.ReinstallRemoveError,
pkgmanager.Errors.DowngradeError,
):
loggerinst.warning("Package %s not available in RHEL repositories.", pkg)
self._base.reinstall(pattern=pkg)
except (pkgmanager.Errors.ReinstallInstallError, pkgmanager.Errors.ReinstallRemoveError):
try:
self._base.downgrade(pattern=pkg)
except (
pkgmanager.Errors.ReinstallInstallError,
pkgmanager.Errors.ReinstallRemoveError,
pkgmanager.Errors.DowngradeError,
):
loggerinst.warning("Package %s not available in RHEL repositories.", pkg)
except pkgmanager.Errors.NoMoreMirrorsRepoError as e:
loggerinst.debug("Got the following exception message: %s", e)
loggerinst.critical("There are no suitable mirrors available for the loaded repositories.")

def _resolve_dependencies(self, validate_transaction):
"""Try to resolve the transaction dependencies.
Expand Down
9 changes: 9 additions & 0 deletions convert2rhel/unit_tests/pkgmanager/handlers/yum/yum_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,15 @@ def test_perform_operations_downgrade_exception(
assert pkgmanager.YumBase.downgrade.call_count == len(system_packages)
assert "not available in RHEL repositories." in caplog.records[-1].message

@centos7
def test_perform_operations_no_more_mirrors_repo_exception(self, pretend_os, _mock_yum_api_calls, monkeypatch):
monkeypatch.setattr(pkgmanager.handlers.yum, "get_system_packages_for_replacement", lambda: ["pkg-1"])
pkgmanager.YumBase.update.side_effect = pkgmanager.Errors.NoMoreMirrorsRepoError
instance = YumTransactionHandler()

with pytest.raises(SystemExit, match="There are no suitable mirrors available for the loaded repositories."):
instance._perform_operations()

@centos7
@pytest.mark.parametrize(
("ret_code", "message", "validate_transaction", "expected"),
Expand Down
4 changes: 4 additions & 0 deletions plans/tier0.fmf
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,7 @@
/log_command_verification:
discover+:
test: log-command

/single_yum_transaction_validation:
discover+:
test: single-yum-transaction-validation
33 changes: 33 additions & 0 deletions tests/integration/tier0/single-yum-transaction-validation/main.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
summary: Verify single yum transaction validation

description: >
Verify that we are doing a proper rollback during the validation phase in
our transactions.

If any errors occurs during the transaction resolution, either by
downloading a package, dependency resolver and etc... A rollback should
start and revert the changes to the system.

link: https://issues.redhat.com/browse/RHELC-576

tier: 0

tag+:
- yum
- dnf
- transaction

/transaction_validation_error:
adjust+:
- enabled: false
when: distro == centos-8 or distro == oraclelinux-8
tag+:
- transaction-validation-error
test: |
pytest -svv -m transaction_validation_error

/package_download_error:
tag+:
- package-download-error
test: |
pytest -svv -m package_download_error
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import os
import shutil

import pytest

from conftest import SYSTEM_RELEASE_ENV
from envparse import env


PKI_ENTITLEMENT_CERTS_PATH = "/etc/pki/entitlement"


def remove_entitlement_certs():
"""
Utility function to remove the entitlement certificate as soon as we
notice it in the `PKI_ENTITLEMENT_CERTS_PATH`.
We don't need to back it up and then restore it because the PKI_ENTITLEMENT_CERTS_PATH folder is only created during
the conversion when the subscription-manager package is installed. And the .pem certificate is being generated by
subscription-manager in the folder during the system registration. So to have the test system clean after the test
finishes the certs shouldn't be present.
"""
for cert_filename in os.listdir(PKI_ENTITLEMENT_CERTS_PATH):
cert_path = os.path.join(PKI_ENTITLEMENT_CERTS_PATH, cert_filename)
try:
os.unlink(cert_path)
except Exception as e:
print("Failed to delete %s. Reason: %s" % (cert_path, e))


@pytest.mark.package_download_error
def test_package_download_error(convert2rhel):
"""
Remove the entitlement certs found at /etc/pki/entitlement during package
download phase for both yum and dnf transactions.
This will run the conversion up to the point where we valiate the
transaction, when it reaches a specific point of the validation, we remove
the entitlement certs found in /etc/pki/entitlement/*.pem to ensure that the
tool is doing a proper rollback when there is any failure during the package
download.
The package download happens in different phases for yum and dnf, yum
download the packages during the `processTransaction` method call, while dnf
has a specific method that process and download the packages in the
transaction.
"""

server_sub = "CentOS Linux"
pkgmanager = "yum"
final_message = "There are no suitable mirrors available for the loaded repositories."

if "oracle" in SYSTEM_RELEASE_ENV:
server_sub = "Oracle Linux Server"

if "8" in SYSTEM_RELEASE_ENV:
pkgmanager = "dnf"
final_message = "Failed to download the transaction packages."

with convert2rhel(
"-y --no-rpm-va --serverurl {} --username {} --password {} --pool {} --debug".format(
env.str("RHSM_SERVER_URL"),
env.str("RHSM_USERNAME"),
env.str("RHSM_PASSWORD"),
env.str("RHSM_POOL"),
)
) as c2r:
c2r.expect("Adding {} packages to the {} transaction set.".format(server_sub, pkgmanager))
remove_entitlement_certs()
assert c2r.expect_exact(final_message, timeout=600) == 0

assert c2r.exitstatus == 1


@pytest.mark.transaction_validation_error
def test_transaction_validation_error(convert2rhel):
"""
Remove the entitlement certs found at /etc/pki/entitlement during transaction
processing to throw the following yum error: pkgmanager.Errors.YumDownloadError
This will run the conversion up to the point where we valiate the
transaction, when it reaches a specific point of the validation, we remove
the entitlement certs found in /etc/pki/entitlement/*.pem to ensure that the
tool is doing a proper rollback when the transaction is being processed.
"""
with convert2rhel(
"-y --no-rpm-va --serverurl {} --username {} --password {} --pool {} --debug".format(
env.str("RHSM_SERVER_URL"),
env.str("RHSM_USERNAME"),
env.str("RHSM_PASSWORD"),
env.str("RHSM_POOL"),
)
) as c2r:
c2r.expect(
"Downloading and validating the yum transaction set, no modifications to the system will happen this time."
)
remove_entitlement_certs()
assert c2r.expect_exact("Failed to validate the yum transaction.", timeout=600) == 0

assert c2r.exitstatus == 1
7 changes: 4 additions & 3 deletions tests/integration/tier1/single-yum-transaction/main.fmf
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
summary: Single yum transaction
summary: Verify the single yum transaction

description: |
Handle the unified yum transactions so that it handles packages without error. Previous iterations used a lot of
different steps, whereas now it is one transaction that can be rolled back more easily.
Handle the unified yum transactions so that it handles packages without
error. Previous iterations used a lot of different steps, whereas now it is
one transaction that can be rolled back more easily.

link: https://issues.redhat.com/browse/RHELC-576

Expand Down

0 comments on commit b90f5bb

Please sign in to comment.