Blame tests/support.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 contextlib
Packit Service 21c75c
import logging
Packit Service 21c75c
import os
Packit Service 21c75c
import re
Packit Service 21c75c
import shutil
Packit Service 21c75c
import sys
Packit Service 21c75c
import tempfile
Packit Service 21c75c
import unittest
Packit Service 21c75c
from functools import reduce
Packit Service 21c75c
Packit Service 21c75c
import hawkey
Packit Service 21c75c
import hawkey.test
Packit Service 21c75c
import libdnf.transaction
Packit Service 21c75c
Packit Service 21c75c
import dnf
Packit Service 21c75c
import dnf.conf
Packit Service 21c75c
import dnf.cli.cli
Packit Service 21c75c
import dnf.cli.demand
Packit Service 21c75c
import dnf.cli.option_parser
Packit Service 21c75c
import dnf.comps
Packit Service 21c75c
import dnf.exceptions
Packit Service 21c75c
import dnf.goal
Packit Service 21c75c
import dnf.i18n
Packit Service 21c75c
import dnf.package
Packit Service 21c75c
import dnf.persistor
Packit Service 21c75c
import dnf.pycomp
Packit Service 21c75c
import dnf.repo
Packit Service 21c75c
import dnf.sack
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
if dnf.pycomp.PY3:
Packit Service 21c75c
    from unittest import mock
Packit Service 21c75c
    from unittest.mock import MagicMock, mock_open
Packit Service 21c75c
else:
Packit Service 21c75c
    from tests import mock
Packit Service 21c75c
    from tests.mock import MagicMock
Packit Service 21c75c
Packit Service 21c75c
    def mock_open(mock=None, data=None):
Packit Service 21c75c
        if mock is None:
Packit Service 21c75c
            mock = MagicMock(spec=file)
Packit Service 21c75c
Packit Service 21c75c
        handle = MagicMock(spec=file)
Packit Service 21c75c
        handle.write.return_value = None
Packit Service 21c75c
        if data is None:
Packit Service 21c75c
            handle.__enter__.return_value = handle
Packit Service 21c75c
        else:
Packit Service 21c75c
            handle.__enter__.return_value = data
Packit Service 21c75c
        mock.return_value = handle
Packit Service 21c75c
        return mock
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
logger = logging.getLogger('dnf')
Packit Service 21c75c
skip = unittest.skip
Packit Service 21c75c
Packit Service 21c75c
TRACEBACK_RE = re.compile(
Packit Service 21c75c
    r'(Traceback \(most recent call last\):\n'
Packit Service 21c75c
    r'(?:  File "[^"\n]+", line \d+, in \w+\n'
Packit Service 21c75c
    r'(?:    .+\n)?)+'
Packit Service 21c75c
    r'\S.*\n)')
Packit Service 21c75c
REASONS = {
Packit Service 21c75c
    'hole': 'group',
Packit Service 21c75c
    'pepper': 'group',
Packit Service 21c75c
    'right': 'dep',
Packit Service 21c75c
    'tour': 'group',
Packit Service 21c75c
    'trampoline': 'group',
Packit Service 21c75c
}
Packit Service 21c75c
# @System.repo doesn't provide sha1header/pkgid
Packit Service 21c75c
# the checksum is computed from an empty string
Packit Service 21c75c
RPMDB_CHECKSUM = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
Packit Service 21c75c
TOTAL_RPMDB_COUNT = 10
Packit Service 21c75c
SYSTEM_NSOLVABLES = TOTAL_RPMDB_COUNT
Packit Service 21c75c
MAIN_NSOLVABLES = 9
Packit Service 21c75c
UPDATES_NSOLVABLES = 4
Packit Service 21c75c
AVAILABLE_NSOLVABLES = MAIN_NSOLVABLES + UPDATES_NSOLVABLES
Packit Service 21c75c
TOTAL_GROUPS = 5
Packit Service 21c75c
TOTAL_NSOLVABLES = SYSTEM_NSOLVABLES + AVAILABLE_NSOLVABLES
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
# testing infrastructure
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def dnf_toplevel():
Packit Service 21c75c
    return os.path.normpath(os.path.join(__file__, '../../'))
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def repo(reponame):
Packit Service 21c75c
    return os.path.join(REPO_DIR, reponame)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def resource_path(path):
Packit Service 21c75c
    this_dir = os.path.dirname(__file__)
Packit Service 21c75c
    return os.path.join(this_dir, path)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
REPO_DIR = resource_path('repos')
Packit Service 21c75c
COMPS_PATH = os.path.join(REPO_DIR, 'main_comps.xml')
Packit Service 21c75c
NONEXISTENT_FILE = resource_path('does-not/exist')
Packit Service 21c75c
TOUR_44_PKG_PATH = resource_path('repos/rpm/tour-4-4.noarch.rpm')
Packit Service 21c75c
TOUR_50_PKG_PATH = resource_path('repos/rpm/tour-5-0.noarch.rpm')
Packit Service 21c75c
TOUR_51_PKG_PATH = resource_path('repos/rpm/tour-5-1.noarch.rpm')
Packit Service 21c75c
USER_RUNDIR = '/tmp/dnf-user-rundir'
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
# often used query
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def installed_but(sack, *args):
Packit Service 21c75c
    q = sack.query().filter(reponame__eq=hawkey.SYSTEM_REPO_NAME)
Packit Service 21c75c
    return reduce(lambda query, name: query.filter(name__neq=name), args, q)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
# patching the stdout
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
@contextlib.contextmanager
Packit Service 21c75c
def patch_std_streams():
Packit Service 21c75c
    with mock.patch('sys.stdout', new_callable=dnf.pycomp.StringIO) as stdout, \
Packit Service 21c75c
            mock.patch('sys.stderr', new_callable=dnf.pycomp.StringIO) as stderr:
Packit Service 21c75c
        yield (stdout, stderr)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
@contextlib.contextmanager
Packit Service 21c75c
def wiretap_logs(logger_name, level, stream):
Packit Service 21c75c
    """Record *logger_name* logs of at least *level* into the *stream*."""
Packit Service 21c75c
    logger = logging.getLogger(logger_name)
Packit Service 21c75c
Packit Service 21c75c
    orig_level = logger.level
Packit Service 21c75c
    logger.setLevel(level)
Packit Service 21c75c
Packit Service 21c75c
    handler = logging.StreamHandler(stream)
Packit Service 21c75c
    orig_handlers = logger.handlers
Packit Service 21c75c
    logger.handlers = []
Packit Service 21c75c
    logger.addHandler(handler)
Packit Service 21c75c
Packit Service 21c75c
    try:
Packit Service 21c75c
        yield stream
Packit Service 21c75c
    finally:
Packit Service 21c75c
        logger.removeHandler(handler)
Packit Service 21c75c
        logger.setLevel(orig_level)
Packit Service 21c75c
        logger.handlers = orig_handlers
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def command_configure(cmd, args):
Packit Service 21c75c
    parser = dnf.cli.option_parser.OptionParser()
Packit Service 21c75c
    args = [cmd._basecmd] + args
Packit Service 21c75c
    parser.parse_main_args(args)
Packit Service 21c75c
    parser.parse_command_args(cmd, args)
Packit Service 21c75c
    return cmd.configure()
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def command_run(cmd, args):
Packit Service 21c75c
    command_configure(cmd, args)
Packit Service 21c75c
    return cmd.run()
Packit Service 21c75c
Packit Service 21c75c
class Base(dnf.Base):
Packit Service 21c75c
    def __init__(self, *args, **kwargs):
Packit Service 21c75c
        with mock.patch('dnf.rpm.detect_releasever', return_value=69):
Packit Service 21c75c
            super(Base, self).__init__(*args, **kwargs)
Packit Service 21c75c
Packit Service 21c75c
# mock objects
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def mock_comps(history, seed_history):
Packit Service 21c75c
    comps = dnf.comps.Comps()
Packit Service 21c75c
    comps._add_from_xml_filename(COMPS_PATH)
Packit Service 21c75c
Packit Service 21c75c
    if seed_history:
Packit Service 21c75c
        name = 'Peppers'
Packit Service 21c75c
        pkg_types = dnf.comps.MANDATORY
Packit Service 21c75c
        swdb_group = history.group.new(name, name, name, pkg_types)
Packit Service 21c75c
        for pkg_name in ['hole', 'lotus']:
Packit Service 21c75c
            swdb_group.addPackage(pkg_name, True, dnf.comps.MANDATORY)
Packit Service 21c75c
        history.group.install(swdb_group)
Packit Service 21c75c
Packit Service 21c75c
        name = 'somerset'
Packit Service 21c75c
        pkg_types = dnf.comps.MANDATORY
Packit Service 21c75c
        swdb_group = history.group.new(name, name, name, pkg_types)
Packit Service 21c75c
        for pkg_name in ['pepper', 'trampoline', 'lotus']:
Packit Service 21c75c
            swdb_group.addPackage(pkg_name, True, dnf.comps.MANDATORY)
Packit Service 21c75c
        history.group.install(swdb_group)
Packit Service 21c75c
Packit Service 21c75c
        name = 'sugar-desktop-environment'
Packit Service 21c75c
        pkg_types = dnf.comps.ALL_TYPES
Packit Service 21c75c
        swdb_env = history.env.new(name, name, name, pkg_types)
Packit Service 21c75c
        for group_id in ['Peppers', 'somerset']:
Packit Service 21c75c
            swdb_env.addGroup(group_id, True, dnf.comps.MANDATORY)
Packit Service 21c75c
        history.env.install(swdb_env)
Packit Service 21c75c
    return comps
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def mock_logger():
Packit Service 21c75c
    return mock.create_autospec(logger)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class _BaseStubMixin(object):
Packit Service 21c75c
    """A reusable class for creating `dnf.Base` stubs.
Packit Service 21c75c
Packit Service 21c75c
    See also: hawkey/test/python/__init__.py.
Packit Service 21c75c
Packit Service 21c75c
    Note that currently the used TestSack has always architecture set to
Packit Service 21c75c
    "x86_64". This is to get the same behavior when running unit tests on
Packit Service 21c75c
    different arches.
Packit Service 21c75c
Packit Service 21c75c
    """
Packit Service 21c75c
    def __init__(self, *extra_repos, **config_opts):
Packit Service 21c75c
        super(_BaseStubMixin, self).__init__(FakeConf(**config_opts))
Packit Service 21c75c
        for r in extra_repos:
Packit Service 21c75c
            repo = MockRepo(r, self.conf)
Packit Service 21c75c
            repo.enable()
Packit Service 21c75c
            self._repos.add(repo)
Packit Service 21c75c
Packit Service 21c75c
        self._repo_persistor = FakePersistor()
Packit Service 21c75c
        self._ds_callback = mock.Mock()
Packit Service 21c75c
        self._history = None
Packit Service 21c75c
        self._closed = False
Packit Service 21c75c
        self._closing = False
Packit Service 21c75c
Packit Service 21c75c
    def add_test_dir_repo(self, id_, cachedir):
Packit Service 21c75c
        """Add a repository located in a directory in the tests."""
Packit Service 21c75c
        repo = dnf.repo.Repo(id_, cachedir)
Packit Service 21c75c
        repo.baseurl = ['file://%s/%s' % (REPO_DIR, repo.id)]
Packit Service 21c75c
        self.repos.add(repo)
Packit Service 21c75c
        return repo
Packit Service 21c75c
Packit Service 21c75c
    def close(self):
Packit Service 21c75c
        self._closing = True
Packit Service 21c75c
        super(_BaseStubMixin, self).close()
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def history(self):
Packit Service 21c75c
        if self._history:
Packit Service 21c75c
            return self._history
Packit Service 21c75c
        else:
Packit Service 21c75c
            self._history = super(_BaseStubMixin, self).history
Packit Service 21c75c
            if not self._closing:
Packit Service 21c75c
                # don't reset db on close, it causes several tests to fail
Packit Service 21c75c
                self._history.reset_db()
Packit Service 21c75c
            return self._history
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def sack(self):
Packit Service 21c75c
        if self._sack:
Packit Service 21c75c
            return self._sack
Packit Service 21c75c
        return self.init_sack()
Packit Service 21c75c
Packit Service 21c75c
    def _build_comps_solver(self):
Packit Service 21c75c
        return dnf.comps.Solver(self.history, self._comps,
Packit Service 21c75c
                                REASONS.get)
Packit Service 21c75c
Packit Service 21c75c
    def _activate_persistor(self):
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    def init_sack(self):
Packit Service 21c75c
        # Create the Sack, tell it how to build packages, passing in the Package
Packit Service 21c75c
        # class and a Base reference.
Packit Service 21c75c
        self._sack = TestSack(REPO_DIR, self)
Packit Service 21c75c
        self._sack.load_system_repo()
Packit Service 21c75c
        for repo in self.repos.iter_enabled():
Packit Service 21c75c
            if repo.__class__ is dnf.repo.Repo:
Packit Service 21c75c
                self._add_repo_to_sack(repo)
Packit Service 21c75c
            else:
Packit Service 21c75c
                fn = "%s.repo" % repo.id
Packit Service 21c75c
                self._sack.load_test_repo(repo.id, fn)
Packit Service 21c75c
Packit Service 21c75c
        self._sack._configure(self.conf.installonlypkgs)
Packit Service 21c75c
        self._goal = dnf.goal.Goal(self._sack)
Packit Service 21c75c
        self._goal.protect_running_kernel = self.conf.protect_running_kernel
Packit Service 21c75c
        return self._sack
Packit Service 21c75c
Packit Service 21c75c
    def mock_cli(self):
Packit Service 21c75c
        stream = dnf.pycomp.StringIO()
Packit Service 21c75c
        logger = logging.getLogger('test')
Packit Service 21c75c
        logger.setLevel(logging.DEBUG)
Packit Service 21c75c
        logger.addHandler(logging.StreamHandler(stream))
Packit Service 21c75c
        return mock.Mock(base=self, log_stream=stream, logger=logger,
Packit Service 21c75c
                         demands=dnf.cli.demand.DemandSheet())
Packit Service 21c75c
Packit Service 21c75c
    def read_mock_comps(self, seed_history=True):
Packit Service 21c75c
        self._comps = mock_comps(self.history, seed_history)
Packit Service 21c75c
        return self._comps
Packit Service 21c75c
Packit Service 21c75c
    def read_all_repos(self, opts=None):
Packit Service 21c75c
        for repo in self.repos.values():
Packit Service 21c75c
            repo._configure_from_options(opts)
Packit Service 21c75c
Packit Service 21c75c
    def set_debuglevel(self, level):
Packit Service 21c75c
        self.conf._set_value('debuglevel', level, dnf.conf.PRIO_RUNTIME)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class BaseCliStub(_BaseStubMixin, dnf.cli.cli.BaseCli):
Packit Service 21c75c
    """A class mocking `dnf.cli.cli.BaseCli`."""
Packit Service 21c75c
Packit Service 21c75c
    def __init__(self, *extra_repos, **config_opts):
Packit Service 21c75c
        """Initialize the base."""
Packit Service 21c75c
        super(BaseCliStub, self).__init__(*extra_repos, **config_opts)
Packit Service 21c75c
        self.output.term = MockTerminal()
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class DemandsStub(object):
Packit Service 21c75c
    pass
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class CliStub(object):
Packit Service 21c75c
    """A class mocking `dnf.cli.Cli`."""
Packit Service 21c75c
Packit Service 21c75c
    def __init__(self, base):
Packit Service 21c75c
        """Initialize the CLI."""
Packit Service 21c75c
        self.base = base
Packit Service 21c75c
        self.cli_commands = {}
Packit Service 21c75c
        self.demands = DemandsStub()
Packit Service 21c75c
        self.logger = logging.getLogger()
Packit Service 21c75c
        self.register_command(dnf.cli.commands.HelpCommand)
Packit Service 21c75c
Packit Service 21c75c
    def redirect_logger(self, stdout=None, stderr=None):
Packit Service 21c75c
        return
Packit Service 21c75c
Packit Service 21c75c
    def redirect_repo_progress(self, fo=sys.stderr):
Packit Service 21c75c
        return
Packit Service 21c75c
Packit Service 21c75c
    def register_command(self, command):
Packit Service 21c75c
        """Register given *command*."""
Packit Service 21c75c
        self.cli_commands.update({alias: command for alias in command.aliases})
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class MockOutput(object):
Packit Service 21c75c
    def __init__(self):
Packit Service 21c75c
        self.term = MockTerminal()
Packit Service 21c75c
Packit Service 21c75c
    def setup_progress_callbacks(self):
Packit Service 21c75c
        return (None, None)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class MockPackage(object):
Packit Service 21c75c
    def __init__(self, nevra, repo=None):
Packit Service 21c75c
        self.baseurl = None
Packit Service 21c75c
        self._chksum = (None, None)
Packit Service 21c75c
        self.downloadsize = None
Packit Service 21c75c
        self._header = None
Packit Service 21c75c
        self.location = '%s.rpm' % nevra
Packit Service 21c75c
        self.repo = repo
Packit Service 21c75c
        self.reponame = None if repo is None else repo.id
Packit Service 21c75c
        self.str = nevra
Packit Service 21c75c
        self.buildtime = 0
Packit Service 21c75c
        nevra = hawkey.split_nevra(nevra)
Packit Service 21c75c
        self.name = nevra.name
Packit Service 21c75c
        self.epoch = nevra.epoch
Packit Service 21c75c
        self.version = nevra.version
Packit Service 21c75c
        self.release = nevra.release
Packit Service 21c75c
        self.arch = nevra.arch
Packit Service 21c75c
        self.evr = '%(epoch)d:%(version)s-%(release)s' % vars(self)
Packit Service 21c75c
        self.pkgtup = (self.name, self.arch, str(self.epoch), self.version,
Packit Service 21c75c
                       self.release)
Packit Service 21c75c
Packit Service 21c75c
    def __str__(self):
Packit Service 21c75c
        return self.str
Packit Service 21c75c
Packit Service 21c75c
    def localPkg(self):
Packit Service 21c75c
        return os.path.join(self.repo.pkgdir, os.path.basename(self.location))
Packit Service 21c75c
Packit Service 21c75c
    def returnIdSum(self):
Packit Service 21c75c
        return self._chksum
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class MockRepo(dnf.repo.Repo):
Packit Service 21c75c
    def _valid(self):
Packit Service 21c75c
        return None
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class MockQuery(dnf.query.Query):
Packit Service 21c75c
    def __init__(self, query):
Packit Service 21c75c
        self.pkgs = [MockPackage(str(p)) for p in query.run()]
Packit Service 21c75c
        self.i = 0
Packit Service 21c75c
        self.n = len(self.pkgs)
Packit Service 21c75c
Packit Service 21c75c
    def __getitem__(self, key):
Packit Service 21c75c
        if key < self.n:
Packit Service 21c75c
            return self.pkgs[key]
Packit Service 21c75c
        else:
Packit Service 21c75c
            raise KeyError()
Packit Service 21c75c
Packit Service 21c75c
    def __iter__(self):
Packit Service 21c75c
        return self
Packit Service 21c75c
Packit Service 21c75c
    def __len__(self):
Packit Service 21c75c
        return self.n
Packit Service 21c75c
Packit Service 21c75c
    def filter(self, pkg):
Packit Service 21c75c
        self.pkgs = []
Packit Service 21c75c
        self.pkgs.extend(pkg)
Packit Service 21c75c
        self.n = len(self.pkgs)
Packit Service 21c75c
        return self
Packit Service 21c75c
Packit Service 21c75c
    def next(self):
Packit Service 21c75c
        return self.__next__()
Packit Service 21c75c
Packit Service 21c75c
    def __next__(self):
Packit Service 21c75c
        if self.i < self.n:
Packit Service 21c75c
            i = self.i
Packit Service 21c75c
            self.i += 1
Packit Service 21c75c
            return self.pkgs[i]
Packit Service 21c75c
        else:
Packit Service 21c75c
            raise StopIteration()
Packit Service 21c75c
Packit Service 21c75c
    def run(self):
Packit Service 21c75c
        return self.pkgs
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class MockTerminal(object):
Packit Service 21c75c
    def __init__(self):
Packit Service 21c75c
        self.MODE = {'bold': '', 'normal': ''}
Packit Service 21c75c
        self.columns = 80
Packit Service 21c75c
        self.real_columns = 80
Packit Service 21c75c
        self.reinit = mock.Mock()
Packit Service 21c75c
Packit Service 21c75c
    def bold(self, s):
Packit Service 21c75c
        return s
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class TestSack(hawkey.test.TestSackMixin, dnf.sack.Sack):
Packit Service 21c75c
    def __init__(self, repo_dir, base):
Packit Service 21c75c
        hawkey.test.TestSackMixin.__init__(self, repo_dir)
Packit Service 21c75c
        dnf.sack.Sack.__init__(self,
Packit Service 21c75c
                               arch=hawkey.test.FIXED_ARCH,
Packit Service 21c75c
                               pkgcls=dnf.package.Package,
Packit Service 21c75c
                               pkginitval=base,
Packit Service 21c75c
                               make_cache_dir=True)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class MockBase(_BaseStubMixin, Base):
Packit Service 21c75c
    """A class mocking `dnf.Base`."""
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def mock_sack(*extra_repos):
Packit Service 21c75c
    return MockBase(*extra_repos).sack
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class FakeConf(dnf.conf.Conf):
Packit Service 21c75c
    def __init__(self, **kwargs):
Packit Service 21c75c
        super(FakeConf, self).__init__()
Packit Service 21c75c
        self.substitutions['releasever'] = 'Fedora69'
Packit Service 21c75c
        options = [
Packit Service 21c75c
            ('assumeyes', None),
Packit Service 21c75c
            ('best', False),
Packit Service 21c75c
            ('cachedir', dnf.const.TMPDIR),
Packit Service 21c75c
            ('clean_requirements_on_remove', False),
Packit Service 21c75c
            ('color', 'never'),
Packit Service 21c75c
            ('color_update_installed', 'normal'),
Packit Service 21c75c
            ('color_update_remote', 'normal'),
Packit Service 21c75c
            ('color_list_available_downgrade', 'dim'),
Packit Service 21c75c
            ('color_list_available_install', 'normal'),
Packit Service 21c75c
            ('color_list_available_reinstall', 'bold'),
Packit Service 21c75c
            ('color_list_available_upgrade', 'bold'),
Packit Service 21c75c
            ('color_list_installed_extra', 'bold'),
Packit Service 21c75c
            ('color_list_installed_newer', 'bold'),
Packit Service 21c75c
            ('color_list_installed_older', 'bold'),
Packit Service 21c75c
            ('color_list_installed_reinstall', 'normal'),
Packit Service 21c75c
            ('color_update_local', 'bold'),
Packit Service 21c75c
            ('debug_solver', False),
Packit Service 21c75c
            ('debuglevel', 2),
Packit Service 21c75c
            ('defaultyes', False),
Packit Service 21c75c
            ('disable_excludes', []),
Packit Service 21c75c
            ('diskspacecheck', True),
Packit Service 21c75c
            ('exclude', []),
Packit Service 21c75c
            ('includepkgs', []),
Packit Service 21c75c
            ('install_weak_deps', True),
Packit Service 21c75c
            ('history_record', False),
Packit Service 21c75c
            ('installonly_limit', 0),
Packit Service 21c75c
            ('installonlypkgs', ['kernel']),
Packit Service 21c75c
            ('installroot', '/tmp/dnf-test-installroot/'),
Packit Service 21c75c
            ('ip_resolve', None),
Packit Service 21c75c
            ('multilib_policy', 'best'),
Packit Service 21c75c
            ('obsoletes', True),
Packit Service 21c75c
            ('persistdir', dnf.const.PERSISTDIR),
Packit Service 21c75c
            ('transformdb', False),
Packit Service 21c75c
            ('protected_packages', ["dnf"]),
Packit Service 21c75c
            ('protect_running_kernel', True),
Packit Service 21c75c
            ('plugins', False),
Packit Service 21c75c
            ('showdupesfromrepos', False),
Packit Service 21c75c
            ('tsflags', []),
Packit Service 21c75c
            ('strict', True),
Packit Service 21c75c
        ] + list(kwargs.items())
Packit Service 21c75c
        for optname, val in options:
Packit Service 21c75c
            self._set_value(optname, val, dnf.conf.PRIO_DEFAULT)
Packit Service 21c75c
Packit Service 21c75c
        # TODO: consolidate with dnf.cli.Cli._read_conf_file()
Packit Service 21c75c
        for opt in ('cachedir', 'logdir', 'persistdir'):
Packit Service 21c75c
            # don't prepend installroot if option was specified by user
Packit Service 21c75c
            # TODO: is this desired? ^^^ (tests won't pass without it ATM)
Packit Service 21c75c
            if opt in kwargs:
Packit Service 21c75c
                continue
Packit Service 21c75c
            self.prepend_installroot(opt)
Packit Service 21c75c
Packit Service 21c75c
        try:
Packit Service 21c75c
            os.makedirs(self.persistdir)
Packit Service 21c75c
        except:
Packit Service 21c75c
            pass
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def releasever(self):
Packit Service 21c75c
        return self.substitutions['releasever']
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class FakePersistor(object):
Packit Service 21c75c
    reset_last_makecache = False
Packit Service 21c75c
    expired_to_add = set()
Packit Service 21c75c
Packit Service 21c75c
    def get_expired_repos(self):
Packit Service 21c75c
        return set()
Packit Service 21c75c
Packit Service 21c75c
    def since_last_makecache(self):
Packit Service 21c75c
        return None
Packit Service 21c75c
Packit Service 21c75c
    def save(self):
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
# object matchers for asserts
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class ObjectMatcher(object):
Packit Service 21c75c
    """Class allowing partial matching of objects."""
Packit Service 21c75c
Packit Service 21c75c
    def __init__(self, type_=None, attrs=None):
Packit Service 21c75c
        """Initialize a matcher instance."""
Packit Service 21c75c
        self._type = type_
Packit Service 21c75c
        self._attrs = attrs
Packit Service 21c75c
Packit Service 21c75c
    def __eq__(self, other):
Packit Service 21c75c
        """Test whether this object is equal to the *other* one."""
Packit Service 21c75c
        if self._type is not None:
Packit Service 21c75c
            if type(other) is not self._type:
Packit Service 21c75c
                return False
Packit Service 21c75c
Packit Service 21c75c
        if self._attrs:
Packit Service 21c75c
            for attr, value in self._attrs.items():
Packit Service 21c75c
                if value != getattr(other, attr):
Packit Service 21c75c
                    return False
Packit Service 21c75c
        return True
Packit Service 21c75c
Packit Service 21c75c
    def __ne__(self, other):
Packit Service 21c75c
        """Test whether this object is not equal to the *other* one."""
Packit Service 21c75c
        return not self == other
Packit Service 21c75c
Packit Service 21c75c
    def __repr__(self):
Packit Service 21c75c
        """Compute the "official" string representation of this object."""
Packit Service 21c75c
        args_strs = []
Packit Service 21c75c
Packit Service 21c75c
        if self._type is not None:
Packit Service 21c75c
            args_strs.append('type_=%s' % repr(self._type))
Packit Service 21c75c
Packit Service 21c75c
        if self._attrs:
Packit Service 21c75c
            attrs_str = ', '.join('%s: %s' % (dnf.i18n.ucd(attr), repr(value))
Packit Service 21c75c
                                  for attr, value in self._attrs.items())
Packit Service 21c75c
            args_strs.append('attrs={%s}' % attrs_str)
Packit Service 21c75c
Packit Service 21c75c
        return '%s(%s)' % (type(self).__name__, ", ".join(args_strs))
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
# test cases:
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class TestCase(unittest.TestCase):
Packit Service 21c75c
Packit Service 21c75c
    if not dnf.pycomp.PY3:
Packit Service 21c75c
        assertCountEqual = unittest.TestCase.assertItemsEqual
Packit Service 21c75c
        assertRegex = unittest.TestCase.assertRegexpMatches
Packit Service 21c75c
Packit Service 21c75c
    def assertEmpty(self, collection):
Packit Service 21c75c
        return self.assertEqual(len(collection), 0)
Packit Service 21c75c
Packit Service 21c75c
    def assertFile(self, path):
Packit Service 21c75c
        """Assert the given path is a file."""
Packit Service 21c75c
        return self.assertTrue(os.path.isfile(path))
Packit Service 21c75c
Packit Service 21c75c
    def assertLength(self, collection, length):
Packit Service 21c75c
        return self.assertEqual(len(collection), length)
Packit Service 21c75c
Packit Service 21c75c
    def assertPathDoesNotExist(self, path):
Packit Service 21c75c
        return self.assertFalse(os.access(path, os.F_OK))
Packit Service 21c75c
Packit Service 21c75c
    def assertStartsWith(self, string, what):
Packit Service 21c75c
        return self.assertTrue(string.startswith(what))
Packit Service 21c75c
Packit Service 21c75c
    def assertTracebackIn(self, end, string):
Packit Service 21c75c
        """Test that a traceback ending with line *end* is in the *string*."""
Packit Service 21c75c
        traces = (match.group() for match in TRACEBACK_RE.finditer(string))
Packit Service 21c75c
        self.assertTrue(any(trace.endswith(end) for trace in traces))
Packit Service 21c75c
Packit Service 21c75c
    def assertTransEqual(self, trans_pkgs, list):
Packit Service 21c75c
        return self.assertCountEqual([pkg.name for pkg in trans_pkgs], list)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class DnfBaseTestCase(TestCase):
Packit Service 21c75c
Packit Service 21c75c
    # create base with specified test repos
Packit Service 21c75c
    REPOS = []
Packit Service 21c75c
Packit Service 21c75c
    # initialize mock sack
Packit Service 21c75c
    INIT_SACK = False
Packit Service 21c75c
Packit Service 21c75c
    # initialize self.base._transaction
Packit Service 21c75c
    INIT_TRANSACTION = False
Packit Service 21c75c
Packit Service 21c75c
    # False: self.base = MockBase()
Packit Service 21c75c
    # True: self.base = BaseCliStub()
Packit Service 21c75c
    BASE_CLI = False
Packit Service 21c75c
Packit Service 21c75c
    # None: self.cli = None
Packit Service 21c75c
    # "init": self.cli = dnf.cli.cli.Cli(self.base)
Packit Service 21c75c
    # "mock": self.cli = self.base.mock_cli()
Packit Service 21c75c
    # "stub": self.cli = StubCli(self.base)
Packit Service 21c75c
    CLI = None
Packit Service 21c75c
Packit Service 21c75c
    COMPS = False
Packit Service 21c75c
    COMPS_SEED_HISTORY = False
Packit Service 21c75c
    COMPS_SOLVER = False
Packit Service 21c75c
Packit Service 21c75c
    def setUp(self):
Packit Service 21c75c
        self._installroot = tempfile.mkdtemp(prefix="dnf_test_installroot_")
Packit Service 21c75c
Packit Service 21c75c
        if self.BASE_CLI:
Packit Service 21c75c
            self.base = BaseCliStub(*self.REPOS, installroot=self._installroot)
Packit Service 21c75c
        else:
Packit Service 21c75c
            self.base = MockBase(*self.REPOS, installroot=self._installroot)
Packit Service 21c75c
Packit Service 21c75c
        if self.CLI is None:
Packit Service 21c75c
            self.cli = None
Packit Service 21c75c
        elif self.CLI == "init":
Packit Service 21c75c
            self.cli = dnf.cli.cli.Cli(self.base)
Packit Service 21c75c
        elif self.CLI == "mock":
Packit Service 21c75c
            self.cli = self.base.mock_cli()
Packit Service 21c75c
        elif self.CLI == "stub":
Packit Service 21c75c
            self.cli = CliStub(self.base)
Packit Service 21c75c
        else:
Packit Service 21c75c
            raise ValueError("Invalid CLI value: {}".format(self.CLI))
Packit Service 21c75c
Packit Service 21c75c
        if self.COMPS:
Packit Service 21c75c
            self.base.read_mock_comps(seed_history=self.COMPS_SEED_HISTORY)
Packit Service 21c75c
Packit Service 21c75c
        if self.INIT_SACK:
Packit Service 21c75c
            self.base.init_sack()
Packit Service 21c75c
Packit Service 21c75c
        if self.INIT_TRANSACTION:
Packit Service 21c75c
            self.base._transaction = self.base.history.rpm
Packit Service 21c75c
Packit Service 21c75c
        if self.COMPS_SOLVER:
Packit Service 21c75c
            self.solver = dnf.comps.Solver(self.history, self.comps, REASONS.get)
Packit Service 21c75c
        else:
Packit Service 21c75c
            self.solver = None
Packit Service 21c75c
Packit Service 21c75c
    def tearDown(self):
Packit Service 21c75c
        self.base.close()
Packit Service 21c75c
        if self._installroot.startswith("/tmp/"):
Packit Service 21c75c
            shutil.rmtree(self._installroot)
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def comps(self):
Packit Service 21c75c
        return self.base.comps
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def goal(self):
Packit Service 21c75c
        return self.base._goal
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def history(self):
Packit Service 21c75c
        return self.base.history
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def sack(self):
Packit Service 21c75c
        return self.base.sack
Packit Service 21c75c
Packit Service 21c75c
    def _swdb_begin(self, tsis=None):
Packit Service 21c75c
        # history.beg() replaces persistor.commit()
Packit Service 21c75c
        tsis = tsis or []
Packit Service 21c75c
        self.history.beg("", [], tsis)
Packit Service 21c75c
Packit Service 21c75c
    def _swdb_end(self, tsis=None):
Packit Service 21c75c
        for tsi in self.history._swdb.getItems():
Packit Service 21c75c
            if tsi.getState() == libdnf.transaction.TransactionItemState_UNKNOWN:
Packit Service 21c75c
                tsi.setState(libdnf.transaction.TransactionItemState_DONE)
Packit Service 21c75c
        self.history.end("")
Packit Service 21c75c
        self.history.close()
Packit Service 21c75c
Packit Service 21c75c
    def _swdb_commit(self, tsis=None):
Packit Service 21c75c
        self._swdb_begin(tsis)
Packit Service 21c75c
        self._swdb_end()
Packit Service 21c75c
        self.history.close()
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class ResultTestCase(DnfBaseTestCase):
Packit Service 21c75c
Packit Service 21c75c
    allow_erasing = False
Packit Service 21c75c
Packit Service 21c75c
    def _get_installed(self, base):
Packit Service 21c75c
        try:
Packit Service 21c75c
            base.resolve(self.allow_erasing)
Packit Service 21c75c
        except dnf.exceptions.DepsolveError:
Packit Service 21c75c
            self.fail()
Packit Service 21c75c
Packit Service 21c75c
        installed = set(base.sack.query().installed())
Packit Service 21c75c
        for r in base._transaction.remove_set:
Packit Service 21c75c
            installed.remove(r)
Packit Service 21c75c
        installed.update(base._transaction.install_set)
Packit Service 21c75c
        return installed
Packit Service 21c75c
Packit Service 21c75c
    def assertResult(self, base, pkgs):
Packit Service 21c75c
        """Check whether the system contains the given pkgs.
Packit Service 21c75c
Packit Service 21c75c
        pkgs must be present. Any other pkgs result in an error. Pkgs are
Packit Service 21c75c
        present if they are in the rpmdb and are not REMOVEd or they are
Packit Service 21c75c
        INSTALLed.
Packit Service 21c75c
        """
Packit Service 21c75c
Packit Service 21c75c
        self.assertCountEqual(self._get_installed(base), pkgs)
Packit Service 21c75c
Packit Service 21c75c
    def installed_removed(self, base):
Packit Service 21c75c
        try:
Packit Service 21c75c
            base.resolve(self.allow_erasing)
Packit Service 21c75c
        except dnf.exceptions.DepsolveError:
Packit Service 21c75c
            self.fail()
Packit Service 21c75c
Packit Service 21c75c
        installed = base._transaction.install_set
Packit Service 21c75c
        removed = base._transaction.remove_set
Packit Service 21c75c
        return installed, removed