mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-07-15 15:05:48 +00:00
complete core tests
This commit is contained in:
@ -6,6 +6,7 @@ from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.alpm.repo import Repo
|
||||
from ahriman.core.build_tools.task import Task
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.tree import Leaf
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
@ -16,6 +17,16 @@ def configuration(resource_path_root: Path) -> Configuration:
|
||||
return Configuration.from_path(path=path, logfile=False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def leaf_ahriman(package_ahriman: Package) -> Leaf:
|
||||
return Leaf(package_ahriman, set())
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def leaf_python_schedule(package_python_schedule: Package) -> Leaf:
|
||||
return Leaf(package_python_schedule, set())
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def pacman(configuration: Configuration) -> Pacman:
|
||||
return Pacman(configuration)
|
||||
|
127
tests/ahriman/core/test_configuration.py
Normal file
127
tests/ahriman/core/test_configuration.py
Normal file
@ -0,0 +1,127 @@
|
||||
from pathlib import Path
|
||||
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
|
||||
|
||||
def test_from_path(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must load configuration
|
||||
"""
|
||||
read_mock = mocker.patch("configparser.RawConfigParser.read")
|
||||
load_includes_mock = mocker.patch("ahriman.core.configuration.Configuration.load_includes")
|
||||
load_logging_mock = mocker.patch("ahriman.core.configuration.Configuration.load_logging")
|
||||
path = Path("path")
|
||||
|
||||
config = Configuration.from_path(path, True)
|
||||
assert config.path == path
|
||||
read_mock.assert_called_with(path)
|
||||
load_includes_mock.assert_called_once()
|
||||
load_logging_mock.assert_called_once()
|
||||
|
||||
|
||||
def test_absolute_path_for_absolute(configuration: Configuration) -> None:
|
||||
"""
|
||||
must not change path for absolute path in settings
|
||||
"""
|
||||
path = Path("/a/b/c")
|
||||
assert configuration.absolute_path_for(path) == path
|
||||
|
||||
|
||||
def test_absolute_path_for_relative(configuration: Configuration) -> None:
|
||||
"""
|
||||
must prepend root path to relative path
|
||||
"""
|
||||
path = Path("a")
|
||||
result = configuration.absolute_path_for(path)
|
||||
assert result.is_absolute()
|
||||
assert result.parent == configuration.path.parent
|
||||
assert result.name == path.name
|
||||
|
||||
|
||||
def test_dump(configuration: Configuration) -> None:
|
||||
"""
|
||||
dump must not be empty
|
||||
"""
|
||||
assert configuration.dump("x86_64")
|
||||
|
||||
|
||||
def test_dump_architecture_specific(configuration: Configuration) -> None:
|
||||
"""
|
||||
dump must contain architecture specific settings
|
||||
"""
|
||||
configuration.add_section("build_x86_64")
|
||||
configuration.set("build_x86_64", "archbuild_flags", "")
|
||||
|
||||
dump = configuration.dump("x86_64")
|
||||
assert dump
|
||||
assert "build" not in dump
|
||||
assert "build_x86_64" in dump
|
||||
|
||||
|
||||
def test_getlist(configuration: Configuration) -> None:
|
||||
"""
|
||||
must return list of string correctly
|
||||
"""
|
||||
configuration.set("build", "test_list", "a b c")
|
||||
assert configuration.getlist("build", "test_list") == ["a", "b", "c"]
|
||||
|
||||
|
||||
def test_getlist_empty(configuration: Configuration) -> None:
|
||||
"""
|
||||
must return list of string correctly for non-existing option
|
||||
"""
|
||||
assert configuration.getlist("build", "test_list") == []
|
||||
configuration.set("build", "test_list", "")
|
||||
assert configuration.getlist("build", "test_list") == []
|
||||
|
||||
|
||||
def test_getlist_single(configuration: Configuration) -> None:
|
||||
"""
|
||||
must return list of strings for single string
|
||||
"""
|
||||
configuration.set("build", "test_list", "a")
|
||||
assert configuration.getlist("build", "test_list") == ["a"]
|
||||
|
||||
|
||||
def test_get_section_name(configuration: Configuration) -> None:
|
||||
"""
|
||||
must return architecture specific group
|
||||
"""
|
||||
configuration.add_section("build_x86_64")
|
||||
configuration.set("build_x86_64", "archbuild_flags", "")
|
||||
assert configuration.get_section_name("build", "x86_64") == "build_x86_64"
|
||||
|
||||
|
||||
def test_get_section_name_missing(configuration: Configuration) -> None:
|
||||
"""
|
||||
must return default group if architecture depending group does not exist
|
||||
"""
|
||||
assert configuration.get_section_name("prefix", "suffix") == "prefix"
|
||||
assert configuration.get_section_name("build", "x86_64") == "build"
|
||||
|
||||
|
||||
def test_load_includes_missing(configuration: Configuration) -> None:
|
||||
"""
|
||||
must not fail if not include directory found
|
||||
"""
|
||||
configuration.set("settings", "include", "path")
|
||||
configuration.load_includes()
|
||||
|
||||
|
||||
def test_load_logging_fallback(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must fallback to stderr without errors
|
||||
"""
|
||||
mocker.patch("logging.config.fileConfig", side_effect=PermissionError())
|
||||
configuration.load_logging(True)
|
||||
|
||||
|
||||
def test_load_logging_stderr(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must use stderr if flag set
|
||||
"""
|
||||
logging_mock = mocker.patch("logging.config.fileConfig")
|
||||
configuration.load_logging(False)
|
||||
logging_mock.assert_not_called()
|
78
tests/ahriman/core/test_tree.py
Normal file
78
tests/ahriman/core/test_tree.py
Normal file
@ -0,0 +1,78 @@
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.core.tree import Leaf, Tree
|
||||
from ahriman.models.package import Package
|
||||
|
||||
|
||||
def test_leaf_is_root_empty(leaf_ahriman: Leaf) -> None:
|
||||
"""
|
||||
must be root for empty packages list
|
||||
"""
|
||||
assert leaf_ahriman.is_root([])
|
||||
|
||||
|
||||
def test_leaf_is_root_false(leaf_ahriman: Leaf, leaf_python_schedule: Leaf) -> None:
|
||||
"""
|
||||
must be root for empty dependencies list or if does not depend on packages
|
||||
"""
|
||||
assert leaf_ahriman.is_root([leaf_python_schedule])
|
||||
leaf_ahriman.dependencies = {"ahriman-dependency"}
|
||||
assert leaf_ahriman.is_root([leaf_python_schedule])
|
||||
|
||||
|
||||
def test_leaf_is_root_true(leaf_ahriman: Leaf, leaf_python_schedule: Leaf) -> None:
|
||||
"""
|
||||
must not be root if depends on packages
|
||||
"""
|
||||
leaf_ahriman.dependencies = {"python-schedule"}
|
||||
assert not leaf_ahriman.is_root([leaf_python_schedule])
|
||||
|
||||
leaf_ahriman.dependencies = {"python2-schedule"}
|
||||
assert not leaf_ahriman.is_root([leaf_python_schedule])
|
||||
|
||||
leaf_ahriman.dependencies = set(leaf_python_schedule.package.packages.keys())
|
||||
assert not leaf_ahriman.is_root([leaf_python_schedule])
|
||||
|
||||
|
||||
def test_leaf_load(package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must load with dependencies
|
||||
"""
|
||||
tempdir_mock = mocker.patch("tempfile.mkdtemp")
|
||||
fetch_mock = mocker.patch("ahriman.core.build_tools.task.Task.fetch")
|
||||
dependencies_mock = mocker.patch("ahriman.models.package.Package.dependencies", return_value={"ahriman-dependency"})
|
||||
rmtree_mock = mocker.patch("shutil.rmtree")
|
||||
|
||||
leaf = Leaf.load(package_ahriman)
|
||||
assert leaf.package == package_ahriman
|
||||
assert leaf.dependencies == {"ahriman-dependency"}
|
||||
tempdir_mock.assert_called_once()
|
||||
fetch_mock.assert_called_once()
|
||||
dependencies_mock.assert_called_once()
|
||||
rmtree_mock.assert_called_once()
|
||||
|
||||
|
||||
def test_tree_levels(leaf_ahriman: Leaf, leaf_python_schedule: Leaf, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must generate correct levels in the simples case
|
||||
"""
|
||||
leaf_ahriman.dependencies = set(leaf_python_schedule.package.packages.keys())
|
||||
|
||||
tree = Tree([leaf_ahriman, leaf_python_schedule])
|
||||
assert len(tree.levels()) == 2
|
||||
first, second = tree.levels()
|
||||
assert first == [leaf_python_schedule.package]
|
||||
assert second == [leaf_ahriman.package]
|
||||
|
||||
|
||||
def test_tree_load(package_ahriman: Package, package_python_schedule: Package, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must package list
|
||||
"""
|
||||
mocker.patch("tempfile.mkdtemp")
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.fetch")
|
||||
mocker.patch("ahriman.models.package.Package.dependencies")
|
||||
mocker.patch("shutil.rmtree")
|
||||
|
||||
tree = Tree.load([package_ahriman, package_python_schedule])
|
||||
assert len(tree.leaves) == 2
|
131
tests/ahriman/core/test_util.py
Normal file
131
tests/ahriman/core/test_util.py
Normal file
@ -0,0 +1,131 @@
|
||||
import logging
|
||||
import pytest
|
||||
import subprocess
|
||||
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.core.util import check_output, package_like, pretty_datetime, pretty_size
|
||||
from ahriman.models.package import Package
|
||||
|
||||
|
||||
def test_check_output(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must run command and log result
|
||||
"""
|
||||
logger_mock = mocker.patch("logging.Logger.debug")
|
||||
|
||||
assert check_output("echo", "hello", exception=None) == "hello"
|
||||
logger_mock.assert_not_called()
|
||||
|
||||
assert check_output("echo", "hello", exception=None, logger=logging.getLogger("")) == "hello"
|
||||
logger_mock.assert_called_once()
|
||||
|
||||
|
||||
def test_check_output_failure(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must process exception correctly
|
||||
"""
|
||||
logger_mock = mocker.patch("logging.Logger.debug")
|
||||
mocker.patch("subprocess.check_output", side_effect=subprocess.CalledProcessError(1, "echo"))
|
||||
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
check_output("echo", "hello", exception=None)
|
||||
logger_mock.assert_not_called()
|
||||
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
check_output("echo", "hello", exception=None, logger=logging.getLogger(""))
|
||||
logger_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_check_output_failure_log(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must process exception correctly and log it
|
||||
"""
|
||||
logger_mock = mocker.patch("logging.Logger.debug")
|
||||
mocker.patch("subprocess.check_output", side_effect=subprocess.CalledProcessError(1, "echo", output=b"result"))
|
||||
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
check_output("echo", "hello", exception=None, logger=logging.getLogger(""))
|
||||
logger_mock.assert_called_once()
|
||||
|
||||
|
||||
def test_package_like(package_ahriman: Package) -> None:
|
||||
"""
|
||||
package_like must return true for archives
|
||||
"""
|
||||
assert package_like(package_ahriman.packages[package_ahriman.base].filepath)
|
||||
|
||||
|
||||
def test_package_like_sig(package_ahriman: Package) -> None:
|
||||
"""
|
||||
package_like must return false for signature files
|
||||
"""
|
||||
package_file = package_ahriman.packages[package_ahriman.base].filepath
|
||||
sig_file = package_file.parent / f"{package_file.name}.sig"
|
||||
assert not package_like(sig_file)
|
||||
|
||||
|
||||
def test_pretty_datetime() -> None:
|
||||
"""
|
||||
must generate string from timestamp value
|
||||
"""
|
||||
assert pretty_datetime(0) == "1970-01-01 00:00:00"
|
||||
|
||||
|
||||
def test_pretty_datetime_empty() -> None:
|
||||
"""
|
||||
must generate empty string from None timestamp
|
||||
"""
|
||||
assert pretty_datetime(None) == ""
|
||||
|
||||
|
||||
def test_pretty_size_bytes() -> None:
|
||||
"""
|
||||
must generate bytes string for bytes value
|
||||
"""
|
||||
value, abbrev = pretty_size(42).split()
|
||||
assert value == "42.0"
|
||||
assert abbrev == "B"
|
||||
|
||||
|
||||
def test_pretty_size_kbytes() -> None:
|
||||
"""
|
||||
must generate kibibytes string for kibibytes value
|
||||
"""
|
||||
value, abbrev = pretty_size(42 * 1024).split()
|
||||
assert value == "42.0"
|
||||
assert abbrev == "KiB"
|
||||
|
||||
|
||||
def test_pretty_size_mbytes() -> None:
|
||||
"""
|
||||
must generate mebibytes string for mebibytes value
|
||||
"""
|
||||
value, abbrev = pretty_size(42 * 1024 * 1024).split()
|
||||
assert value == "42.0"
|
||||
assert abbrev == "MiB"
|
||||
|
||||
|
||||
def test_pretty_size_gbytes() -> None:
|
||||
"""
|
||||
must generate gibibytes string for gibibytes value
|
||||
"""
|
||||
value, abbrev = pretty_size(42 * 1024 * 1024 * 1024).split()
|
||||
assert value == "42.0"
|
||||
assert abbrev == "GiB"
|
||||
|
||||
|
||||
def test_pretty_size_pbytes() -> None:
|
||||
"""
|
||||
must generate pebibytes string for pebibytes value
|
||||
"""
|
||||
value, abbrev = pretty_size(42 * 1024 * 1024 * 1024 * 1024).split()
|
||||
assert value == "43008.0"
|
||||
assert abbrev == "GiB"
|
||||
|
||||
|
||||
def test_pretty_size_empty() -> None:
|
||||
"""
|
||||
must generate empty string for None value
|
||||
"""
|
||||
assert pretty_size(None) == ""
|
@ -0,0 +1,17 @@
|
||||
from ahriman.models.package_desciption import PackageDescription
|
||||
|
||||
|
||||
def test_filepath(package_description_ahriman: PackageDescription) -> None:
|
||||
"""
|
||||
must generate correct filepath if set
|
||||
"""
|
||||
assert package_description_ahriman.filepath is not None
|
||||
assert package_description_ahriman.filepath.name == package_description_ahriman.filename
|
||||
|
||||
|
||||
def test_filepath_empty(package_description_ahriman: PackageDescription) -> None:
|
||||
"""
|
||||
must return None for missing filename
|
||||
"""
|
||||
package_description_ahriman.filename = None
|
||||
assert package_description_ahriman.filepath is None
|
||||
|
Reference in New Issue
Block a user