Blame tests/test_groups.py

Packit Service 21c75c
# -*- coding: utf-8 -*-
Packit Service 21c75c
Packit Service 21c75c
# Copyright (C) 2012-2018 Red Hat, Inc.
Packit Service 21c75c
#
Packit Service 21c75c
# This copyrighted material is made available to anyone wishing to use,
Packit Service 21c75c
# modify, copy, or redistribute it subject to the terms and conditions of
Packit Service 21c75c
# the GNU General Public License v.2, or (at your option) any later version.
Packit Service 21c75c
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit Service 21c75c
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit Service 21c75c
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit Service 21c75c
# Public License for more details.  You should have received a copy of the
Packit Service 21c75c
# GNU General Public License along with this program; if not, write to the
Packit Service 21c75c
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 21c75c
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
Packit Service 21c75c
# source code or documentation are not subject to the GNU General Public
Packit Service 21c75c
# License and may only be used or replicated with the express permission of
Packit Service 21c75c
# Red Hat, Inc.
Packit Service 21c75c
#
Packit Service 21c75c
Packit Service 21c75c
from __future__ import absolute_import
Packit Service 21c75c
from __future__ import unicode_literals
Packit Service 21c75c
Packit Service 21c75c
import operator
Packit Service 21c75c
Packit Service 21c75c
import libdnf.transaction
Packit Service 21c75c
Packit Service 21c75c
import dnf.comps
Packit Service 21c75c
import dnf.util
Packit Service 21c75c
Packit Service 21c75c
import tests.support
Packit Service 21c75c
from tests.support import mock
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class EmptyPersistorTest(tests.support.ResultTestCase):
Packit Service 21c75c
    """Test group operations with empty persistor."""
Packit Service 21c75c
Packit Service 21c75c
    REPOS = ['main']
Packit Service 21c75c
    COMPS = True
Packit Service 21c75c
Packit Service 21c75c
    @mock.patch('locale.getlocale', return_value=('cs_CZ', 'UTF-8'))
Packit Service 21c75c
    def test_group_install_locale(self, _unused):
Packit Service 21c75c
        grp = self.comps.group_by_pattern('Kritick\xe1 cesta (Z\xe1klad)')
Packit Service 21c75c
        cnt = self.base.group_install(grp.id, ('mandatory',))
Packit Service 21c75c
        self.assertEqual(cnt, 2)
Packit Service 21c75c
Packit Service 21c75c
    def test_finalize_comps_trans(self):
Packit Service 21c75c
        trans = dnf.comps.TransactionBunch()
Packit Service 21c75c
        trans.install = ('trampoline',)
Packit Service 21c75c
        self.assertGreater(self.base._add_comps_trans(trans), 0)
Packit Service 21c75c
        self.base._finalize_comps_trans()
Packit Service 21c75c
        self.assertIn('trampoline', self.base._goal.group_members)
Packit Service 21c75c
        (installed, removed) = self.installed_removed(self.base)
Packit Service 21c75c
        self.assertCountEqual(map(str, installed), ('trampoline-2.1-1.noarch',))
Packit Service 21c75c
        self.assertEmpty(removed)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class PresetPersistorTest(tests.support.ResultTestCase):
Packit Service 21c75c
    """Test group operations with some data in the persistor."""
Packit Service 21c75c
Packit Service 21c75c
    REPOS = ['main']
Packit Service 21c75c
    COMPS = True
Packit Service 21c75c
    COMPS_SEED_HISTORY = True
Packit Service 21c75c
Packit Service 21c75c
    def _install_test_env(self):
Packit Service 21c75c
        """Env installation itself does not handle packages. We need to handle
Packit Service 21c75c
           them manually for proper functionality of env remove"""
Packit Service 21c75c
Packit Service 21c75c
        env_id = 'sugar-desktop-environment'
Packit Service 21c75c
        comps_env = self.comps._environment_by_id(env_id)
Packit Service 21c75c
        self.base.environment_install(comps_env.id, ('mandatory',))
Packit Service 21c75c
        self._swdb_commit()
Packit Service 21c75c
Packit Service 21c75c
        swdb_env = self.history.env.get(comps_env.id)
Packit Service 21c75c
        self.assertIsNotNone(swdb_env)
Packit Service 21c75c
Packit Service 21c75c
        for comps_group in comps_env.mandatory_groups:
Packit Service 21c75c
            swdb_group = self.history.group.get(comps_group.id)
Packit Service 21c75c
            self.assertIsNotNone(swdb_group)
Packit Service 21c75c
Packit Service 21c75c
        tsis = []
Packit Service 21c75c
        seen_pkgs = set()
Packit Service 21c75c
        for swdb_env_group in swdb_env.getGroups():
Packit Service 21c75c
            swdb_group = self.history.group.get(swdb_env_group.getGroupId())
Packit Service 21c75c
            if not swdb_group:
Packit Service 21c75c
                continue
Packit Service 21c75c
            for swdb_pkg in swdb_group.getPackages():
Packit Service 21c75c
                swdb_pkg.setInstalled(True)
Packit Service 21c75c
                pkgs = self.base.sack.query().filter(name=swdb_pkg.getName(), arch="x86_64").run()
Packit Service 21c75c
                if not pkgs:
Packit Service 21c75c
                    continue
Packit Service 21c75c
                pkg = pkgs[0]
Packit Service 21c75c
                if pkg in seen_pkgs:
Packit Service 21c75c
                    # prevent RPMs from being twice in a transaction and triggering unique constraint error
Packit Service 21c75c
                    continue
Packit Service 21c75c
                seen_pkgs.add(pkg)
Packit Service 21c75c
                pkg._force_swdb_repoid = "main"
Packit Service 21c75c
                self.history.rpm.add_install(pkg, reason=libdnf.transaction.TransactionItemReason_GROUP)
Packit Service 21c75c
#                tsi = dnf.transaction.TransactionItem(
Packit Service 21c75c
#                    dnf.transaction.INSTALL,
Packit Service 21c75c
#                    installed=pkg,
Packit Service 21c75c
#                    reason=libdnf.transaction.TransactionItemReason_GROUP
Packit Service 21c75c
#                )
Packit Service 21c75c
#                tsis.append(tsi)
Packit Service 21c75c
Packit Service 21c75c
        self._swdb_commit(tsis)
Packit Service 21c75c
Packit Service 21c75c
    def _install_test_group(self):
Packit Service 21c75c
        """Group installation itself does not handle packages. We need to
Packit Service 21c75c
           handle them manually for proper functionality of group remove"""
Packit Service 21c75c
        group_id = 'somerset'
Packit Service 21c75c
        self.base.group_install(group_id, ('mandatory',))
Packit Service 21c75c
        swdb_group = self.history.group._installed[group_id]
Packit Service 21c75c
        tsis = []
Packit Service 21c75c
        for swdb_pkg in swdb_group.getPackages():
Packit Service 21c75c
            swdb_pkg.setInstalled(True)
Packit Service 21c75c
            pkgs = self.base.sack.query().filter(name=swdb_pkg.getName(), arch="x86_64").run()
Packit Service 21c75c
            if not pkgs:
Packit Service 21c75c
                continue
Packit Service 21c75c
            pkg = pkgs[0]
Packit Service 21c75c
            pkg._force_swdb_repoid = "main"
Packit Service 21c75c
            self.history.rpm.add_install(pkg, reason=libdnf.transaction.TransactionItemReason_GROUP)
Packit Service 21c75c
#            tsi = dnf.transaction.TransactionItem(
Packit Service 21c75c
#                dnf.transaction.INSTALL,
Packit Service 21c75c
#                installed=pkg,
Packit Service 21c75c
#                reason=libdnf.transaction.TransactionItemReason_GROUP
Packit Service 21c75c
#            )
Packit Service 21c75c
#            tsis.append(tsi)
Packit Service 21c75c
Packit Service 21c75c
        self._swdb_commit(tsis)
Packit Service 21c75c
        self.base.reset(goal=True)
Packit Service 21c75c
Packit Service 21c75c
    def test_env_group_remove(self):
Packit Service 21c75c
        self._install_test_env()
Packit Service 21c75c
        env_id = 'sugar-desktop-environment'
Packit Service 21c75c
        pkg_count = self.base.env_group_remove([env_id])
Packit Service 21c75c
        self._swdb_commit()
Packit Service 21c75c
        self.assertEqual(3, pkg_count)
Packit Service 21c75c
        with tests.support.mock.patch('logging.Logger.error'):
Packit Service 21c75c
            self.assertRaises(dnf.exceptions.Error,
Packit Service 21c75c
                              self.base.env_group_remove,
Packit Service 21c75c
                              ['nonexistent'])
Packit Service 21c75c
Packit Service 21c75c
    def test_environment_remove(self):
Packit Service 21c75c
        self._install_test_env()
Packit Service 21c75c
        env_id = 'sugar-desktop-environment'
Packit Service 21c75c
        swdb_env = self.history.env.get(env_id)
Packit Service 21c75c
        self.assertIsNotNone(swdb_env)
Packit Service 21c75c
        self.assertEqual(swdb_env.getEnvironmentId(), 'sugar-desktop-environment')
Packit Service 21c75c
Packit Service 21c75c
        removed_pkg_count = self.base.environment_remove(env_id)
Packit Service 21c75c
        self.assertGreater(removed_pkg_count, 0)
Packit Service 21c75c
        self._swdb_commit()
Packit Service 21c75c
Packit Service 21c75c
        swdb_env = self.history.env.get(env_id)
Packit Service 21c75c
        self.assertIsNone(swdb_env)
Packit Service 21c75c
Packit Service 21c75c
        peppers = self.history.group.get('Peppers')
Packit Service 21c75c
        self.assertIsNone(peppers)
Packit Service 21c75c
Packit Service 21c75c
        somerset = self.history.group.get('somerset')
Packit Service 21c75c
        self.assertIsNone(somerset)
Packit Service 21c75c
Packit Service 21c75c
    def test_env_upgrade(self):
Packit Service 21c75c
        self._install_test_env()
Packit Service 21c75c
        cnt = self.base.environment_upgrade("sugar-desktop-environment")
Packit Service 21c75c
        self.assertEqual(5, cnt)
Packit Service 21c75c
Packit Service 21c75c
        peppers = self.history.group.get('Peppers')
Packit Service 21c75c
        self.assertIsNotNone(peppers)
Packit Service 21c75c
Packit Service 21c75c
        somerset = self.history.group.get('somerset')
Packit Service 21c75c
        self.assertIsNotNone(somerset)
Packit Service 21c75c
Packit Service 21c75c
    def test_group_install(self):
Packit Service 21c75c
        comps_group = self.base.comps.group_by_pattern('Base')
Packit Service 21c75c
        pkg_count = self.base.group_install(comps_group.id, ('mandatory',))
Packit Service 21c75c
        self.assertEqual(pkg_count, 2)
Packit Service 21c75c
        self._swdb_commit()
Packit Service 21c75c
Packit Service 21c75c
        installed, removed = self.installed_removed(self.base)
Packit Service 21c75c
        self.assertEmpty(installed)
Packit Service 21c75c
        self.assertEmpty(removed)
Packit Service 21c75c
        swdb_group = self.history.group.get(comps_group.id)
Packit Service 21c75c
        self.assertIsNotNone(swdb_group)
Packit Service 21c75c
Packit Service 21c75c
    def test_group_remove(self):
Packit Service 21c75c
        self._install_test_group()
Packit Service 21c75c
        group_id = 'somerset'
Packit Service 21c75c
Packit Service 21c75c
        pkgs_removed = self.base.group_remove(group_id)
Packit Service 21c75c
        self.assertGreater(pkgs_removed, 0)
Packit Service 21c75c
Packit Service 21c75c
        self._swdb_begin()
Packit Service 21c75c
        installed, removed = self.installed_removed(self.base)
Packit Service 21c75c
        self.assertEmpty(installed)
Packit Service 21c75c
        self.assertCountEqual([pkg.name for pkg in removed], ('pepper',))
Packit Service 21c75c
        self._swdb_end()
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class ProblemGroupTest(tests.support.ResultTestCase):
Packit Service 21c75c
    """Test some cases involving problems in groups: packages that
Packit Service 21c75c
    don't exist, and packages that exist but cannot be installed. The
Packit Service 21c75c
    "broken" group lists three packages. "meaning-of-life", explicitly
Packit Service 21c75c
    'default', does not exist. "lotus", implicitly 'mandatory' (no
Packit Service 21c75c
    explicit type), exists and is installable. "brokendeps",
Packit Service 21c75c
    explicitly 'optional', exists but has broken dependencies. See
Packit Service 21c75c
    https://bugzilla.redhat.com/show_bug.cgi?id=1292892,
Packit Service 21c75c
    https://bugzilla.redhat.com/show_bug.cgi?id=1337731,
Packit Service 21c75c
    https://bugzilla.redhat.com/show_bug.cgi?id=1427365, and
Packit Service 21c75c
    https://bugzilla.redhat.com/show_bug.cgi?id=1461539 for some of
Packit Service 21c75c
    the background on this.
Packit Service 21c75c
    """
Packit Service 21c75c
Packit Service 21c75c
    REPOS = ['main', 'broken_group']
Packit Service 21c75c
    COMPS = True
Packit Service 21c75c
    COMPS_SEED_PERSISTOR = True
Packit Service 21c75c
Packit Service 21c75c
    def test_group_install_broken_mandatory(self):
Packit Service 21c75c
        """Here we will test installing the group with only mandatory
Packit Service 21c75c
        packages. We expect this to succeed, leaving out the
Packit Service 21c75c
        non-existent 'meaning-of-life': it should also log a warning,
Packit Service 21c75c
        but we don't test that.
Packit Service 21c75c
        """
Packit Service 21c75c
        comps_group = self.base.comps.group_by_pattern('Broken Group')
Packit Service 21c75c
        swdb_group = self.history.group.get(comps_group.id)
Packit Service 21c75c
        self.assertIsNone(swdb_group)
Packit Service 21c75c
Packit Service 21c75c
        cnt = self.base.group_install(comps_group.id, ('mandatory',))
Packit Service 21c75c
        self._swdb_commit()
Packit Service 21c75c
        self.base.resolve()
Packit Service 21c75c
        # this counts packages *listed* in the group, so 2
Packit Service 21c75c
        self.assertEqual(cnt, 2)
Packit Service 21c75c
Packit Service 21c75c
        inst, removed = self.installed_removed(self.base)
Packit Service 21c75c
        # the above should work, but only 'lotus' actually installed
Packit Service 21c75c
        self.assertLength(inst, 1)
Packit Service 21c75c
        self.assertEmpty(removed)
Packit Service 21c75c
Packit Service 21c75c
    def test_group_install_broken_default(self):
Packit Service 21c75c
        """Here we will test installing the group with only mandatory
Packit Service 21c75c
        and default packages. Again we expect this to succeed: the new
Packit Service 21c75c
        factor is an entry pulling in librita if no-such-package is
Packit Service 21c75c
        also included or installed. We expect this not to actually
Packit Service 21c75c
        pull in librita (as no-such-package obviously *isn't* there),
Packit Service 21c75c
        but also not to cause a fatal error.
Packit Service 21c75c
        """
Packit Service 21c75c
        comps_group = self.base.comps.group_by_pattern('Broken Group')
Packit Service 21c75c
        swdb_group = self.history.group.get(comps_group.id)
Packit Service 21c75c
        self.assertIsNone(swdb_group)
Packit Service 21c75c
Packit Service 21c75c
        cnt = self.base.group_install(comps_group.id, ('mandatory', 'default'))
Packit Service 21c75c
        self._swdb_commit()
Packit Service 21c75c
        self.base.resolve()
Packit Service 21c75c
        # this counts packages *listed* in the group, so 3
Packit Service 21c75c
        self.assertEqual(cnt, 3)
Packit Service 21c75c
Packit Service 21c75c
        inst, removed = self.installed_removed(self.base)
Packit Service 21c75c
        # the above should work, but only 'lotus' actually installed
Packit Service 21c75c
        self.assertLength(inst, 1)
Packit Service 21c75c
        self.assertEmpty(removed)
Packit Service 21c75c
Packit Service 21c75c
    def test_group_install_broken_optional(self):
Packit Service 21c75c
        """Here we test installing the group with optional packages
Packit Service 21c75c
        included. We expect this to fail, as a package that exists but
Packit Service 21c75c
        has broken dependencies is now included.
Packit Service 21c75c
        """
Packit Service 21c75c
        comps_group = self.base.comps.group_by_pattern('Broken Group')
Packit Service 21c75c
        swdb_group = self.history.group.get(comps_group.id)
Packit Service 21c75c
        self.assertIsNone(swdb_group)
Packit Service 21c75c
Packit Service 21c75c
        cnt = self.base.group_install(comps_group.id, ('mandatory', 'default', 'optional'))
Packit Service 21c75c
        self.assertEqual(cnt, 4)
Packit Service 21c75c
Packit Service 21c75c
        self._swdb_commit()
Packit Service 21c75c
        # this should fail, as optional 'brokendeps' is now pulled in
Packit Service 21c75c
        self.assertRaises(dnf.exceptions.DepsolveError, self.base.resolve)
Packit Service 21c75c
Packit Service 21c75c
    def test_group_install_broken_optional_nonstrict(self):
Packit Service 21c75c
        """Here we test installing the group with optional packages
Packit Service 21c75c
        included, but with strict=False. We expect this to succeed,
Packit Service 21c75c
        skipping the package with broken dependencies.
Packit Service 21c75c
        """
Packit Service 21c75c
        comps_group = self.base.comps.group_by_pattern('Broken Group')
Packit Service 21c75c
        swdb_group = self.history.group.get(comps_group.id)
Packit Service 21c75c
        self.assertIsNone(swdb_group)
Packit Service 21c75c
Packit Service 21c75c
        cnt = self.base.group_install(comps_group.id, ('mandatory', 'default', 'optional'),
Packit Service 21c75c
                                      strict=False)
Packit Service 21c75c
        self._swdb_commit()
Packit Service 21c75c
        self.base.resolve()
Packit Service 21c75c
        self.assertEqual(cnt, 4)
Packit Service 21c75c
Packit Service 21c75c
        inst, removed = self.installed_removed(self.base)
Packit Service 21c75c
        # the above should work, but only 'lotus' actually installed
Packit Service 21c75c
        self.assertLength(inst, 1)
Packit Service 21c75c
        self.assertEmpty(removed)
Packit Service 21c75c
Packit Service 21c75c
    def test_group_install_missing_name(self):
Packit Service 21c75c
        comps_group = self.base.comps.group_by_pattern('missing-name-group')
Packit Service 21c75c
Packit Service 21c75c
        cnt = self.base.group_install(comps_group.id, ('mandatory', 'default', 'optional'),
Packit Service 21c75c
                                      strict=False)
Packit Service 21c75c
        self._swdb_commit()
Packit Service 21c75c
        self.base.resolve()
Packit Service 21c75c
        self.assertEqual(cnt, 1)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class EnvironmentInstallTest(tests.support.ResultTestCase):
Packit Service 21c75c
    """Set up a test where sugar is considered not installed."""
Packit Service 21c75c
Packit Service 21c75c
    REPOS = ['main']
Packit Service 21c75c
    COMPS = True
Packit Service 21c75c
    COMPS_SEED_HISTORY = True
Packit Service 21c75c
Packit Service 21c75c
    def test_environment_install(self):
Packit Service 21c75c
        env_id = 'sugar-desktop-environment'
Packit Service 21c75c
        comps_env = self.comps.environment_by_pattern(env_id)
Packit Service 21c75c
        self.base.environment_install(comps_env.id, ('mandatory',))
Packit Service 21c75c
        self._swdb_commit()
Packit Service 21c75c
Packit Service 21c75c
        installed, _ = self.installed_removed(self.base)
Packit Service 21c75c
        self.assertCountEqual(map(operator.attrgetter('name'), installed),
Packit Service 21c75c
                              ('trampoline', 'lotus'))
Packit Service 21c75c
Packit Service 21c75c
        swdb_env = self.history.env.get(env_id)
Packit Service 21c75c
        self.assertCountEqual([i.getGroupId() for i in swdb_env.getGroups()], ('somerset', 'Peppers', 'base'))
Packit Service 21c75c
Packit Service 21c75c
        peppers = self.history.group.get('Peppers')
Packit Service 21c75c
        self.assertIsNotNone(peppers)
Packit Service 21c75c
Packit Service 21c75c
        somerset = self.history.group.get('somerset')
Packit Service 21c75c
        self.assertIsNotNone(somerset)
Packit Service 21c75c
Packit Service 21c75c
        base = self.history.group.get('base')
Packit Service 21c75c
        self.assertIsNone(base)