feat: allow to use single web instance for all repositories (#114)

* Allow to use single web instance for any repository

* some improvements

* drop includes from user home directory, introduce new variables to docker

The old solution didn't actually work as expected, because devtools
configuration belongs to filesystem (as well as sudo one), so it was
still required to run setup command.

In order to handle additional repositories, the POSTSETUP and PRESETUP
commands variables have been introduced. FAQ has been updated as well

* raise 404 in case if repository is unknown
This commit is contained in:
2023-10-17 03:53:33 +03:00
parent 4eb187aead
commit 6bd1636bfa
141 changed files with 2037 additions and 917 deletions

View File

@ -99,8 +99,8 @@ def test_with_dependencies(application: Application, package_ahriman: Package, p
result = application.with_dependencies([package_ahriman], process_dependencies=True)
assert {package.base: package for package in result} == packages
package_aur_mock.assert_has_calls([
MockCall(package_python_schedule.base, application.repository.pacman, package_ahriman.packager),
MockCall("python-installer", application.repository.pacman, package_ahriman.packager),
MockCall(package_python_schedule.base, package_ahriman.packager),
MockCall("python-installer", package_ahriman.packager),
], any_order=True)
package_local_mock.assert_has_calls([
MockCall(application.repository.paths.cache_for("python"), "x86_64", package_ahriman.packager),

View File

@ -30,7 +30,12 @@ def test_call(args: argparse.Namespace, configuration: Configuration, mocker: Mo
assert Handler.call(args, repository_id)
configuration_mock.assert_called_once_with(args.configuration, repository_id)
log_handler_mock.assert_called_once_with(args.log_handler)
log_load_mock.assert_called_once_with(configuration, args.log_handler, quiet=args.quiet, report=args.report)
log_load_mock.assert_called_once_with(
repository_id,
configuration,
args.log_handler,
quiet=args.quiet,
report=args.report)
enter_mock.assert_called_once_with()
exit_mock.assert_called_once_with(None, None, None)
@ -115,13 +120,24 @@ def test_run(args: argparse.Namespace, configuration: Configuration) -> None:
Handler.run(args, repository_id, configuration, report=True)
def test_check_if_empty() -> None:
"""
must raise exception in case if predicate is True and enabled
"""
Handler.check_if_empty(False, False)
Handler.check_if_empty(True, False)
Handler.check_if_empty(False, True)
with pytest.raises(ExitCode):
Handler.check_if_empty(True, True)
def test_repositories_extract(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must generate list of available repositories based on flags
"""
args.architecture = ["arch"]
args.architecture = "arch"
args.configuration = configuration.path
args.repository = ["repo"]
args.repository = "repo"
known_architectures_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures")
known_repositories_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_repositories")
@ -135,7 +151,7 @@ def test_repositories_extract_repository(args: argparse.Namespace, configuration
"""
must generate list of available repositories based on flags and tree
"""
args.architecture = ["arch"]
args.architecture = "arch"
args.configuration = configuration.path
known_architectures_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures")
known_repositories_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_repositories",
@ -151,7 +167,7 @@ def test_repositories_extract_repository_legacy(args: argparse.Namespace, config
"""
must generate list of available repositories based on flags and tree
"""
args.architecture = ["arch"]
args.architecture = "arch"
args.configuration = configuration.path
known_architectures_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures")
known_repositories_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_repositories",
@ -168,7 +184,7 @@ def test_repositories_extract_architecture(args: argparse.Namespace, configurati
must read repository name from config
"""
args.configuration = configuration.path
args.repository = ["repo"]
args.repository = "repo"
known_architectures_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures",
return_value={"arch"})
known_repositories_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_repositories")
@ -207,6 +223,21 @@ def test_repositories_extract_systemd(args: argparse.Namespace, configuration: C
known_repositories_mock.assert_not_called()
def test_repositories_extract_systemd_with_dash(args: argparse.Namespace, configuration: Configuration,
mocker: MockerFixture) -> None:
"""
must extract repository list by using dash separated identifier
"""
args.configuration = configuration.path
args.repository_id = "i686-some-repo-name"
known_architectures_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures")
known_repositories_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_repositories")
assert Handler.repositories_extract(args) == [RepositoryId("i686", "some-repo-name")]
known_architectures_mock.assert_not_called()
known_repositories_mock.assert_not_called()
def test_repositories_extract_systemd_legacy(args: argparse.Namespace, configuration: Configuration,
mocker: MockerFixture) -> None:
"""
@ -221,14 +252,3 @@ def test_repositories_extract_systemd_legacy(args: argparse.Namespace, configura
assert Handler.repositories_extract(args) == [RepositoryId("i686", "aur-clone")]
known_architectures_mock.assert_not_called()
known_repositories_mock.assert_called_once_with(configuration.repository_paths.root)
def test_check_if_empty() -> None:
"""
must raise exception in case if predicate is True and enabled
"""
Handler.check_if_empty(False, False)
Handler.check_if_empty(True, False)
Handler.check_if_empty(False, True)
with pytest.raises(ExitCode):
Handler.check_if_empty(True, True)

View File

@ -1,4 +1,5 @@
import argparse
import pytest
from pytest_mock import MockerFixture
@ -16,6 +17,9 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
Returns:
argparse.Namespace: generated arguments for these test cases
"""
args.info = False
args.key = None
args.section = None
args.secure = True
return args
@ -35,6 +39,48 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
print_mock.assert_called()
def test_run_info(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run command with info
"""
args = _default_args(args)
args.info = True
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
_, repository_id = configuration.check_loaded()
Dump.run(args, repository_id, configuration, report=False)
print_mock.assert_called()
def test_run_section(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run command with filter by section
"""
args = _default_args(args)
args.section = "settings"
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
_, repository_id = configuration.check_loaded()
Dump.run(args, repository_id, configuration, report=False)
print_mock.assert_called_once_with(verbose=False, log_fn=pytest.helpers.anyvar(int), separator=" = ")
def test_run_section_key(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run command with filter by section and key
"""
args = _default_args(args)
args.section = "settings"
args.key = "include"
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump")
_, repository_id = configuration.check_loaded()
Dump.run(args, repository_id, configuration, report=False)
application_mock.assert_not_called()
print_mock.assert_called_once_with(verbose=False, log_fn=pytest.helpers.anyvar(int), separator=": ")
def test_disallow_multi_architecture_run() -> None:
"""
must not allow multi architecture run

View File

@ -0,0 +1,37 @@
import argparse
import pytest
from pytest_mock import MockerFixture
from ahriman.application.handlers import Repositories
from ahriman.core.configuration import Configuration
def _default_args(args: argparse.Namespace) -> argparse.Namespace:
"""
default arguments for these test cases
Args:
args(argparse.Namespace): command line arguments fixture
Returns:
argparse.Namespace: generated arguments for these test cases
"""
args.configuration = None # doesn't matter actually
args.id_only = False
return args
def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run command
"""
args = _default_args(args)
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
_, repository_id = configuration.check_loaded()
application_mock = mocker.patch("ahriman.application.handlers.Handler.repositories_extract",
return_value=[repository_id])
Repositories.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(pytest.helpers.anyvar(int))
print_mock.assert_called_once_with(verbose=not args.id_only, log_fn=pytest.helpers.anyvar(int), separator=": ")

View File

@ -44,8 +44,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
_, repository_id = configuration.check_loaded()
Search.run(args, repository_id, configuration, report=False)
aur_search_mock.assert_called_once_with("ahriman", pacman=pytest.helpers.anyvar(int))
official_search_mock.assert_called_once_with("ahriman", pacman=pytest.helpers.anyvar(int))
aur_search_mock.assert_called_once_with("ahriman")
official_search_mock.assert_called_once_with("ahriman")
check_mock.assert_called_once_with(False, False)
print_mock.assert_has_calls([
MockCall(verbose=False, log_fn=pytest.helpers.anyvar(int), separator=": "),

View File

@ -38,7 +38,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
_, repository_id = configuration.check_loaded()
ServiceUpdates.run(args, repository_id, configuration, report=False)
package_mock.assert_called_once_with(package_ahriman.base, repository.pacman, None)
package_mock.assert_called_once_with(package_ahriman.base, None)
application_mock.assert_called_once_with(verbose=True, log_fn=pytest.helpers.anyvar(int), separator=" -> ")
check_mock.assert_called_once_with(args.exit_code, True)

View File

@ -25,7 +25,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
Returns:
argparse.Namespace: generated arguments for these test cases
"""
args.architecture = ["x86_64"]
args.architecture = "x86_64"
args.build_as_user = "ahriman"
args.from_configuration = Path("/usr/share/devtools/pacman.conf.d/extra.conf")
args.generate_salt = True
@ -33,7 +33,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
args.mirror = "mirror"
args.multilib = True
args.packager = "John Doe <john@doe.com>"
args.repository = ["aur-clone"]
args.repository = "aur-clone"
args.server = None
args.sign_key = "key"
args.sign_target = [SignSettings.Packages]
@ -127,6 +127,7 @@ def test_configuration_create_ahriman(args: argparse.Namespace, configuration: C
mocker.patch("pathlib.Path.open")
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
remove_mock = mocker.patch("pathlib.Path.unlink", autospec=True)
_, repository_id = configuration.check_loaded()
command = Setup.build_command(repository_paths.root, repository_id)
@ -143,13 +144,12 @@ def test_configuration_create_ahriman(args: argparse.Namespace, configuration: C
" ".join([target.name.lower() for target in args.sign_target])),
MockCall(Configuration.section_name("sign", repository_id.name, repository_id.architecture), "key",
args.sign_key),
MockCall(Configuration.section_name("web", repository_id.name, repository_id.architecture), "port",
str(args.web_port)),
MockCall(Configuration.section_name("web", repository_id.name, repository_id.architecture), "unix_socket",
str(args.web_unix_socket)),
MockCall("web", "port", str(args.web_port)),
MockCall("web", "unix_socket", str(args.web_unix_socket)),
MockCall("auth", "salt", pytest.helpers.anyvar(str, strict=True)),
])
write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
remove_mock.assert_called_once_with(configuration.include / "00-setup-overrides.ini", missing_ok=True)
def test_configuration_create_ahriman_no_multilib(args: argparse.Namespace, configuration: Configuration,

View File

@ -47,13 +47,16 @@ def test_run_packages(args: argparse.Namespace, configuration: Configuration, re
must run command with specified packages
"""
args = _default_args(args)
args.package = [package_ahriman.base]
args.package = [package_ahriman.base, "package"]
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
mocker.patch("ahriman.core.repository.repository.Repository.packages", return_value=[package_ahriman])
add_mock = mocker.patch("ahriman.core.status.client.Client.package_add")
update_mock = mocker.patch("ahriman.core.status.client.Client.package_update")
_, repository_id = configuration.check_loaded()
StatusUpdate.run(args, repository_id, configuration, report=False)
update_mock.assert_called_once_with(package_ahriman.base, args.status)
add_mock.assert_called_once_with(package_ahriman, args.status)
update_mock.assert_called_once_with("package", args.status)
def test_run_remove(args: argparse.Namespace, configuration: Configuration, repository: Repository,

View File

@ -20,6 +20,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
argparse.Namespace: generated arguments for these test cases
"""
args.parser = lambda: True
args.configuration = None # doesn't matter actually
args.force = False
args.log_handler = None
args.report = True
@ -35,15 +36,16 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
"""
args = _default_args(args)
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
setup_mock = mocker.patch("ahriman.web.web.setup_service")
setup_mock = mocker.patch("ahriman.web.web.setup_server")
run_mock = mocker.patch("ahriman.web.web.run_server")
start_mock = mocker.patch("ahriman.core.spawn.Spawn.start")
stop_mock = mocker.patch("ahriman.core.spawn.Spawn.stop")
join_mock = mocker.patch("ahriman.core.spawn.Spawn.join")
_, repository_id = configuration.check_loaded()
mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=[repository_id])
Web.run(args, repository_id, configuration, report=False)
setup_mock.assert_called_once_with(repository_id, configuration, pytest.helpers.anyvar(int))
setup_mock.assert_called_once_with(configuration, pytest.helpers.anyvar(int), [repository_id])
run_mock.assert_called_once_with(pytest.helpers.anyvar(int))
start_mock.assert_called_once_with()
stop_mock.assert_called_once_with()
@ -54,35 +56,32 @@ def test_extract_arguments(args: argparse.Namespace, configuration: Configuratio
"""
must extract correct args
"""
_, repository_id = configuration.check_loaded()
expected = [
"--architecture", repository_id.architecture,
"--repository", repository_id.name,
"--configuration", str(configuration.path),
]
probe = _default_args(args)
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
assert list(Web.extract_arguments(probe, configuration)) == expected
probe.force = True
expected.extend(["--force"])
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
assert list(Web.extract_arguments(probe, configuration)) == expected
probe.log_handler = LogHandler.Console
expected.extend(["--log-handler", probe.log_handler.value])
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
assert list(Web.extract_arguments(probe, configuration)) == expected
probe.quiet = True
expected.extend(["--quiet"])
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
assert list(Web.extract_arguments(probe, configuration)) == expected
probe.unsafe = True
expected.extend(["--unsafe"])
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
assert list(Web.extract_arguments(probe, configuration)) == expected
configuration.set_option("web", "wait_timeout", "60")
expected.extend(["--wait-timeout", "60"])
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
assert list(Web.extract_arguments(probe, configuration)) == expected
def test_extract_arguments_full(parser: argparse.ArgumentParser, configuration: Configuration):
@ -104,10 +103,7 @@ def test_extract_arguments_full(parser: argparse.ArgumentParser, configuration:
value = action.type(value)
setattr(args, action.dest, value)
_, repository_id = configuration.check_loaded()
assert list(Web.extract_arguments(args, repository_id, configuration)) == [
"--architecture", repository_id.architecture,
"--repository", repository_id.name,
assert list(Web.extract_arguments(args, configuration)) == [
"--configuration", str(configuration.path),
"--force",
"--log-handler", "console",

View File

@ -67,14 +67,6 @@ def test_parser_option_architecture_empty(parser: argparse.ArgumentParser) -> No
assert args.architecture is None
def test_parser_option_architecture_multiple(parser: argparse.ArgumentParser) -> None:
"""
must accept multiple architectures
"""
args = parser.parse_args(["-a", "x86_64", "-a", "i686", "service-config"])
assert args.architecture == ["x86_64", "i686"]
def test_parser_option_repository_empty(parser: argparse.ArgumentParser) -> None:
"""
must parse empty repository list as None
@ -83,24 +75,16 @@ def test_parser_option_repository_empty(parser: argparse.ArgumentParser) -> None
assert args.repository is None
def test_parser_option_repository_multiple(parser: argparse.ArgumentParser) -> None:
"""
must accept multiple architectures
"""
args = parser.parse_args(["-r", "repo1", "-r", "repo2", "service-config"])
assert args.repository == ["repo1", "repo2"]
def test_subparsers_aur_search(parser: argparse.ArgumentParser) -> None:
"""
aur-search command must imply architecture list, lock, quiet, report, repository and unsafe
"""
args = parser.parse_args(["aur-search", "ahriman"])
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == [""]
assert args.repository == ""
assert args.unsafe
@ -109,7 +93,7 @@ def test_subparsers_aur_search_option_architecture(parser: argparse.ArgumentPars
aur-search command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "aur-search", "ahriman"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_aur_search_option_repository(parser: argparse.ArgumentParser) -> None:
@ -117,7 +101,7 @@ def test_subparsers_aur_search_option_repository(parser: argparse.ArgumentParser
aur-search command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "aur-search", "ahriman"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_help(parser: argparse.ArgumentParser) -> None:
@ -125,11 +109,11 @@ def test_subparsers_help(parser: argparse.ArgumentParser) -> None:
help command must imply architecture list, lock, quiet, report, repository, unsafe and parser
"""
args = parser.parse_args(["help"])
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == [""]
assert args.repository == ""
assert args.unsafe
assert args.parser is not None and args.parser()
@ -139,7 +123,7 @@ def test_subparsers_help_option_architecture(parser: argparse.ArgumentParser) ->
help command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "help"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_help_option_repository(parser: argparse.ArgumentParser) -> None:
@ -147,7 +131,7 @@ def test_subparsers_help_option_repository(parser: argparse.ArgumentParser) -> N
help command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "help"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_help_commands_unsafe(parser: argparse.ArgumentParser) -> None:
@ -155,11 +139,11 @@ def test_subparsers_help_commands_unsafe(parser: argparse.ArgumentParser) -> Non
help-commands-unsafe command must imply architecture list, lock, quiet, report, repository, unsafe and parser
"""
args = parser.parse_args(["help-commands-unsafe"])
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == [""]
assert args.repository == ""
assert args.unsafe
assert args.parser is not None and args.parser()
@ -169,7 +153,7 @@ def test_subparsers_help_commands_unsafe_option_architecture(parser: argparse.Ar
help-commands-unsafe command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "help-commands-unsafe"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_help_commands_unsafe_option_repository(parser: argparse.ArgumentParser) -> None:
@ -177,7 +161,7 @@ def test_subparsers_help_commands_unsafe_option_repository(parser: argparse.Argu
help-commands-unsafe command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "help-commands-unsafe"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_help_updates(parser: argparse.ArgumentParser) -> None:
@ -185,11 +169,11 @@ def test_subparsers_help_updates(parser: argparse.ArgumentParser) -> None:
help-updates command must imply architecture list, lock, quiet, report, repository, and unsafe
"""
args = parser.parse_args(["help-updates"])
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == [""]
assert args.repository == ""
assert args.unsafe
@ -198,7 +182,7 @@ def test_subparsers_help_updates_option_architecture(parser: argparse.ArgumentPa
help-updates command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "help-updates"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_help_updates_option_repository(parser: argparse.ArgumentParser) -> None:
@ -206,7 +190,7 @@ def test_subparsers_help_updates_option_repository(parser: argparse.ArgumentPars
help-updates command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "help-updates"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_help_version(parser: argparse.ArgumentParser) -> None:
@ -214,11 +198,11 @@ def test_subparsers_help_version(parser: argparse.ArgumentParser) -> None:
help-version command must imply architecture, lock, quiet, report, repository and unsafe
"""
args = parser.parse_args(["help-version"])
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == [""]
assert args.repository == ""
assert args.unsafe
@ -227,7 +211,7 @@ def test_subparsers_help_version_option_architecture(parser: argparse.ArgumentPa
help-version command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "help-version"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_help_version_option_repository(parser: argparse.ArgumentParser) -> None:
@ -235,7 +219,7 @@ def test_subparsers_help_version_option_repository(parser: argparse.ArgumentPars
help-version command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "help-version"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_package_add_option_architecture(parser: argparse.ArgumentParser) -> None:
@ -245,7 +229,7 @@ def test_subparsers_package_add_option_architecture(parser: argparse.ArgumentPar
args = parser.parse_args(["package-add", "ahriman"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "package-add", "ahriman"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_package_add_option_repository(parser: argparse.ArgumentParser) -> None:
@ -255,7 +239,7 @@ def test_subparsers_package_add_option_repository(parser: argparse.ArgumentParse
args = parser.parse_args(["package-add", "ahriman"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "package-add", "ahriman"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_package_add_option_refresh(parser: argparse.ArgumentParser) -> None:
@ -277,7 +261,7 @@ def test_subparsers_package_remove_option_architecture(parser: argparse.Argument
args = parser.parse_args(["package-remove", "ahriman"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "package-remove", "ahriman"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_package_remove_option_repository(parser: argparse.ArgumentParser) -> None:
@ -287,7 +271,7 @@ def test_subparsers_package_remove_option_repository(parser: argparse.ArgumentPa
args = parser.parse_args(["package-remove", "ahriman"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "package-remove", "ahriman"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_package_status(parser: argparse.ArgumentParser) -> None:
@ -295,11 +279,11 @@ def test_subparsers_package_status(parser: argparse.ArgumentParser) -> None:
package-status command must imply lock, quiet, report and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "package-status"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == ["repo"]
assert args.repository == "repo"
assert args.unsafe
@ -308,12 +292,12 @@ def test_subparsers_package_status_remove(parser: argparse.ArgumentParser) -> No
package-status-remove command must imply action, lock, quiet, report and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "package-status-remove", "ahriman"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
assert args.action == Action.Remove
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == ["repo"]
assert args.repository == "repo"
assert args.unsafe
@ -322,12 +306,12 @@ def test_subparsers_package_status_update(parser: argparse.ArgumentParser) -> No
package-status-update command must imply action, lock, quiet, report and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "package-status-update"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
assert args.action == Action.Update
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == ["repo"]
assert args.repository == "repo"
assert args.unsafe
@ -347,10 +331,10 @@ def test_subparsers_patch_add(parser: argparse.ArgumentParser) -> None:
"""
args = parser.parse_args(["patch-add", "ahriman", "version"])
assert args.action == Action.Update
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert not args.report
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_patch_add_option_architecture(parser: argparse.ArgumentParser) -> None:
@ -358,7 +342,7 @@ def test_subparsers_patch_add_option_architecture(parser: argparse.ArgumentParse
patch-add command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "patch-add", "ahriman", "version"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_patch_add_option_repository(parser: argparse.ArgumentParser) -> None:
@ -366,7 +350,7 @@ def test_subparsers_patch_add_option_repository(parser: argparse.ArgumentParser)
patch-add command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "patch-add", "ahriman", "version"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_patch_list(parser: argparse.ArgumentParser) -> None:
@ -375,10 +359,10 @@ def test_subparsers_patch_list(parser: argparse.ArgumentParser) -> None:
"""
args = parser.parse_args(["patch-list", "ahriman"])
assert args.action == Action.List
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert not args.report
assert args.repository == [""]
assert args.repository == ""
assert args.unsafe
@ -387,7 +371,7 @@ def test_subparsers_patch_list_option_architecture(parser: argparse.ArgumentPars
patch-list command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "patch-list", "ahriman"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_patch_list_option_repository(parser: argparse.ArgumentParser) -> None:
@ -395,7 +379,7 @@ def test_subparsers_patch_list_option_repository(parser: argparse.ArgumentParser
patch-list command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "patch-list", "ahriman"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_patch_list_option_variable_empty(parser: argparse.ArgumentParser) -> None:
@ -420,10 +404,10 @@ def test_subparsers_patch_remove(parser: argparse.ArgumentParser) -> None:
"""
args = parser.parse_args(["patch-remove", "ahriman"])
assert args.action == Action.Remove
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert not args.report
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_patch_remove_option_architecture(parser: argparse.ArgumentParser) -> None:
@ -431,7 +415,7 @@ def test_subparsers_patch_remove_option_architecture(parser: argparse.ArgumentPa
patch-remove command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "patch-remove", "ahriman"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_patch_remove_option_repository(parser: argparse.ArgumentParser) -> None:
@ -439,7 +423,7 @@ def test_subparsers_patch_remove_option_repository(parser: argparse.ArgumentPars
patch-remove command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "patch-remove", "ahriman"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_patch_remove_option_variable_empty(parser: argparse.ArgumentParser) -> None:
@ -464,10 +448,10 @@ def test_subparsers_patch_set_add(parser: argparse.ArgumentParser) -> None:
"""
args = parser.parse_args(["patch-set-add", "ahriman"])
assert args.action == Action.Update
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert not args.report
assert args.repository == [""]
assert args.repository == ""
assert args.variable is None
@ -476,7 +460,7 @@ def test_subparsers_patch_set_add_option_architecture(parser: argparse.ArgumentP
patch-set-add command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "patch-set-add", "ahriman"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_patch_set_add_option_package(parser: argparse.ArgumentParser) -> None:
@ -492,7 +476,7 @@ def test_subparsers_patch_set_add_option_repository(parser: argparse.ArgumentPar
patch-set-add command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "patch-set-add", "ahriman"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_patch_set_add_option_track(parser: argparse.ArgumentParser) -> None:
@ -508,10 +492,10 @@ def test_subparsers_repo_backup(parser: argparse.ArgumentParser) -> None:
repo-backup command must imply architecture list, lock, report, repository and unsafe
"""
args = parser.parse_args(["repo-backup", "output.zip"])
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert not args.report
assert args.repository == [""]
assert args.repository == ""
assert args.unsafe
@ -520,7 +504,7 @@ def test_subparsers_repo_backup_option_architecture(parser: argparse.ArgumentPar
repo-backup command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "repo-backup", "output.zip"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_repo_backup_option_repository(parser: argparse.ArgumentParser) -> None:
@ -528,7 +512,7 @@ def test_subparsers_repo_backup_option_repository(parser: argparse.ArgumentParse
repo-backup command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "repo-backup", "output.zip"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_repo_check(parser: argparse.ArgumentParser) -> None:
@ -550,7 +534,7 @@ def test_subparsers_repo_check_option_architecture(parser: argparse.ArgumentPars
args = parser.parse_args(["repo-check"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-check"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_check_option_repository(parser: argparse.ArgumentParser) -> None:
@ -560,7 +544,7 @@ def test_subparsers_repo_check_option_repository(parser: argparse.ArgumentParser
args = parser.parse_args(["repo-check"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-check"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_check_option_refresh(parser: argparse.ArgumentParser) -> None:
@ -590,7 +574,7 @@ def test_subparsers_repo_create_keyring_option_architecture(parser: argparse.Arg
args = parser.parse_args(["repo-create-keyring"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-create-keyring"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_create_keyring_option_repository(parser: argparse.ArgumentParser) -> None:
@ -600,7 +584,7 @@ def test_subparsers_repo_create_keyring_option_repository(parser: argparse.Argum
args = parser.parse_args(["repo-create-keyring"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-create-keyring"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_create_mirrorlist(parser: argparse.ArgumentParser) -> None:
@ -618,7 +602,7 @@ def test_subparsers_repo_create_mirrorlist_option_architecture(parser: argparse.
args = parser.parse_args(["repo-create-mirrorlist"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-create-mirrorlist"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_create_mirrorlist_option_repository(parser: argparse.ArgumentParser) -> None:
@ -628,7 +612,7 @@ def test_subparsers_repo_create_mirrorlist_option_repository(parser: argparse.Ar
args = parser.parse_args(["repo-create-mirrorlist"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-create-mirrorlist"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_daemon(parser: argparse.ArgumentParser) -> None:
@ -670,7 +654,7 @@ def test_subparsers_repo_rebuild_option_architecture(parser: argparse.ArgumentPa
args = parser.parse_args(["repo-rebuild"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-rebuild"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_rebuild_option_repository(parser: argparse.ArgumentParser) -> None:
@ -680,7 +664,7 @@ def test_subparsers_repo_rebuild_option_repository(parser: argparse.ArgumentPars
args = parser.parse_args(["repo-rebuild"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-rebuild"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_rebuild_option_depends_on_empty(parser: argparse.ArgumentParser) -> None:
@ -714,7 +698,7 @@ def test_subparsers_repo_remove_unknown_option_architecture(parser: argparse.Arg
args = parser.parse_args(["repo-remove-unknown"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-remove-unknown"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_remove_unknown_option_repository(parser: argparse.ArgumentParser) -> None:
@ -724,7 +708,7 @@ def test_subparsers_repo_remove_unknown_option_repository(parser: argparse.Argum
args = parser.parse_args(["repo-remove-unknown"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-remove-unknown"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_report(parser: argparse.ArgumentParser) -> None:
@ -742,7 +726,7 @@ def test_subparsers_repo_report_option_architecture(parser: argparse.ArgumentPar
args = parser.parse_args(["repo-report"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-report"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_report_option_repository(parser: argparse.ArgumentParser) -> None:
@ -752,7 +736,7 @@ def test_subparsers_repo_report_option_repository(parser: argparse.ArgumentParse
args = parser.parse_args(["repo-report"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-report"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_restore(parser: argparse.ArgumentParser) -> None:
@ -760,10 +744,10 @@ def test_subparsers_repo_restore(parser: argparse.ArgumentParser) -> None:
repo-restore command must imply architecture list, lock, report, repository and unsafe
"""
args = parser.parse_args(["repo-restore", "output.zip"])
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert not args.report
assert args.repository == [""]
assert args.repository == ""
assert args.unsafe
@ -772,7 +756,7 @@ def test_subparsers_repo_restore_option_architecture(parser: argparse.ArgumentPa
repo-restore command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "repo-restore", "output.zip"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_repo_restore_option_repository(parser: argparse.ArgumentParser) -> None:
@ -780,7 +764,7 @@ def test_subparsers_repo_restore_option_repository(parser: argparse.ArgumentPars
repo-restore command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "repo-restore", "output.zip"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_repo_sign_option_architecture(parser: argparse.ArgumentParser) -> None:
@ -790,7 +774,7 @@ def test_subparsers_repo_sign_option_architecture(parser: argparse.ArgumentParse
args = parser.parse_args(["repo-sign"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-sign"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_sign_option_repository(parser: argparse.ArgumentParser) -> None:
@ -800,7 +784,7 @@ def test_subparsers_repo_sign_option_repository(parser: argparse.ArgumentParser)
args = parser.parse_args(["repo-sign"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-sign"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_status_update(parser: argparse.ArgumentParser) -> None:
@ -808,12 +792,12 @@ def test_subparsers_repo_status_update(parser: argparse.ArgumentParser) -> None:
re[p-status-update command must imply action, lock, quiet, report, package and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "package-status-update"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
assert args.action == Action.Update
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == ["repo"]
assert args.repository == "repo"
assert not args.package
assert args.unsafe
@ -843,7 +827,7 @@ def test_subparsers_repo_sync_option_architecture(parser: argparse.ArgumentParse
args = parser.parse_args(["repo-sync"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-sync"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_sync_option_repository(parser: argparse.ArgumentParser) -> None:
@ -853,7 +837,7 @@ def test_subparsers_repo_sync_option_repository(parser: argparse.ArgumentParser)
args = parser.parse_args(["repo-sync"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-sync"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_tree(parser: argparse.ArgumentParser) -> None:
@ -874,7 +858,7 @@ def test_subparsers_repo_tree_option_architecture(parser: argparse.ArgumentParse
args = parser.parse_args(["repo-tree"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-tree"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_tree_option_repository(parser: argparse.ArgumentParser) -> None:
@ -884,7 +868,7 @@ def test_subparsers_repo_tree_option_repository(parser: argparse.ArgumentParser)
args = parser.parse_args(["repo-tree"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-tree"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_tree_option_partitions(parser: argparse.ArgumentParser) -> None:
@ -904,7 +888,7 @@ def test_subparsers_repo_triggers_option_architecture(parser: argparse.ArgumentP
args = parser.parse_args(["repo-triggers"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-triggers"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_triggers_option_repository(parser: argparse.ArgumentParser) -> None:
@ -914,7 +898,7 @@ def test_subparsers_repo_triggers_option_repository(parser: argparse.ArgumentPar
args = parser.parse_args(["repo-triggers"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-triggers"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_update_option_architecture(parser: argparse.ArgumentParser) -> None:
@ -924,7 +908,7 @@ def test_subparsers_repo_update_option_architecture(parser: argparse.ArgumentPar
args = parser.parse_args(["repo-update"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-update"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_repo_update_option_repository(parser: argparse.ArgumentParser) -> None:
@ -934,7 +918,7 @@ def test_subparsers_repo_update_option_repository(parser: argparse.ArgumentParse
args = parser.parse_args(["repo-update"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "repo-update"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_repo_update_option_refresh(parser: argparse.ArgumentParser) -> None:
@ -965,7 +949,7 @@ def test_subparsers_service_clean_option_architecture(parser: argparse.ArgumentP
args = parser.parse_args(["service-clean"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "service-clean"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
def test_subparsers_service_clean_option_repository(parser: argparse.ArgumentParser) -> None:
@ -975,7 +959,7 @@ def test_subparsers_service_clean_option_repository(parser: argparse.ArgumentPar
args = parser.parse_args(["service-clean"])
assert args.repository is None
args = parser.parse_args(["-r", "repo", "service-clean"])
assert args.repository == ["repo"]
assert args.repository == "repo"
def test_subparsers_service_config(parser: argparse.ArgumentParser) -> None:
@ -983,24 +967,41 @@ def test_subparsers_service_config(parser: argparse.ArgumentParser) -> None:
service-config command must imply lock, quiet, report and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "service-config"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == ["repo"]
assert args.repository == "repo"
assert args.unsafe
def test_subparsers_service_config_option_section_key(parser: argparse.ArgumentParser) -> None:
"""
service-config command must parse optional section and key arguments
"""
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "service-config"])
assert args.section is None
assert args.key is None
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "service-config", "section"])
assert args.section == "section"
assert args.key is None
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "service-config", "section", "key"])
assert args.section == "section"
assert args.key == "key"
def test_subparsers_service_config_validate(parser: argparse.ArgumentParser) -> None:
"""
service-config-validate command must imply lock, quiet, report and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "service-config-validate"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == ["repo"]
assert args.repository == "repo"
assert args.unsafe
@ -1009,10 +1010,10 @@ def test_subparsers_service_key_import(parser: argparse.ArgumentParser) -> None:
service-key-import command must imply architecture list, lock, report and repository
"""
args = parser.parse_args(["service-key-import", "key"])
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert not args.report
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_service_key_import_option_architecture(parser: argparse.ArgumentParser) -> None:
@ -1020,7 +1021,7 @@ def test_subparsers_service_key_import_option_architecture(parser: argparse.Argu
service-key-import command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "service-key-import", "key"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_service_key_import_option_repository(parser: argparse.ArgumentParser) -> None:
@ -1028,7 +1029,35 @@ def test_subparsers_service_key_import_option_repository(parser: argparse.Argume
service-key-import command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "service-key-import", "key"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_service_repositories(parser: argparse.ArgumentParser) -> None:
"""
service-repositories command must imply architecture, lock, report, repository and unsafe
"""
args = parser.parse_args(["service-repositories"])
assert args.architecture == ""
assert args.lock is None
assert not args.report
assert args.repository == ""
assert args.unsafe
def test_subparsers_service_repositories_option_architecture(parser: argparse.ArgumentParser) -> None:
"""
service-repositories command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "service-repositories"])
assert args.architecture == ""
def test_subparsers_service_repositories_option_repository(parser: argparse.ArgumentParser) -> None:
"""
service-repositories command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "service-repositories"])
assert args.repository == ""
def test_subparsers_service_setup(parser: argparse.ArgumentParser) -> None:
@ -1036,11 +1065,11 @@ def test_subparsers_service_setup(parser: argparse.ArgumentParser) -> None:
service-setup command must imply lock, quiet, report and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "service-setup", "--packager", "John Doe <john@doe.com>"])
assert args.architecture == ["x86_64"]
assert args.architecture == "x86_64"
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == ["repo"]
assert args.repository == "repo"
assert args.unsafe
@ -1107,11 +1136,11 @@ def test_subparsers_user_add(parser: argparse.ArgumentParser) -> None:
"""
args = parser.parse_args(["user-add", "username"])
assert args.action == Action.Update
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_user_add_option_architecture(parser: argparse.ArgumentParser) -> None:
@ -1119,7 +1148,7 @@ def test_subparsers_user_add_option_architecture(parser: argparse.ArgumentParser
user-add command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "user-add", "username"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_user_add_option_repository(parser: argparse.ArgumentParser) -> None:
@ -1127,7 +1156,7 @@ def test_subparsers_user_add_option_repository(parser: argparse.ArgumentParser)
user-add command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "user-add", "username"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_user_add_option_role(parser: argparse.ArgumentParser) -> None:
@ -1146,11 +1175,11 @@ def test_subparsers_user_list(parser: argparse.ArgumentParser) -> None:
"""
args = parser.parse_args(["user-list"])
assert args.action == Action.List
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == [""]
assert args.repository == ""
assert args.unsafe
@ -1159,7 +1188,7 @@ def test_subparsers_user_list_option_architecture(parser: argparse.ArgumentParse
user-list command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "user-list"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_user_list_option_repository(parser: argparse.ArgumentParser) -> None:
@ -1167,7 +1196,7 @@ def test_subparsers_user_list_option_repository(parser: argparse.ArgumentParser)
user-list command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "user-list"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_user_list_option_role(parser: argparse.ArgumentParser) -> None:
@ -1184,11 +1213,11 @@ def test_subparsers_user_remove(parser: argparse.ArgumentParser) -> None:
"""
args = parser.parse_args(["user-remove", "username"])
assert args.action == Action.Remove
assert args.architecture == [""]
assert args.architecture == ""
assert args.lock is None
assert args.quiet
assert not args.report
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_user_remove_option_architecture(parser: argparse.ArgumentParser) -> None:
@ -1196,7 +1225,7 @@ def test_subparsers_user_remove_option_architecture(parser: argparse.ArgumentPar
user-remove command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "user-remove", "username"])
assert args.architecture == [""]
assert args.architecture == ""
def test_subparsers_user_remove_option_repository(parser: argparse.ArgumentParser) -> None:
@ -1204,20 +1233,36 @@ def test_subparsers_user_remove_option_repository(parser: argparse.ArgumentParse
user-remove command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "user-remove", "username"])
assert args.repository == [""]
assert args.repository == ""
def test_subparsers_web(parser: argparse.ArgumentParser) -> None:
"""
web command must imply report and parser
web command must imply architecture, report, repository and parser
"""
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "web"])
assert args.architecture == ["x86_64"]
args = parser.parse_args(["web"])
assert args.architecture == ""
assert not args.report
assert args.repository == ["repo"]
assert args.repository == ""
assert args.parser is not None and args.parser()
def test_subparsers_web_option_architecture(parser: argparse.ArgumentParser) -> None:
"""
web command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "web"])
assert args.architecture == ""
def test_subparsers_web_option_repository(parser: argparse.ArgumentParser) -> None:
"""
web command must correctly parse repository list
"""
args = parser.parse_args(["-r", "repo", "web"])
assert args.repository == ""
def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
application must be run

View File

@ -23,7 +23,7 @@ def test_path(args: argparse.Namespace, configuration: Configuration) -> None:
assert Lock(args, repository_id, configuration).path is None
args.lock = Path("/run/ahriman.lock")
assert Lock(args, repository_id, configuration).path == Path("/run/ahriman_aur-clone_x86_64.lock")
assert Lock(args, repository_id, configuration).path == Path("/run/ahriman_x86_64-aur-clone.lock")
with pytest.raises(ValueError):
args.lock = Path("/")

View File

@ -541,10 +541,7 @@ def spawner(configuration: Configuration) -> Spawn:
Returns:
Spawn: spawner fixture
"""
_, repository_id = configuration.check_loaded()
return Spawn(MagicMock(), repository_id, [
"--architecture", "x86_64",
"--repository", repository_id.name,
return Spawn(MagicMock(), [
"--configuration", str(configuration.path),
])
@ -561,19 +558,15 @@ def user() -> User:
@pytest.fixture
def watcher(configuration: Configuration, database: SQLite, repository: Repository, mocker: MockerFixture) -> Watcher:
def watcher(repository_id: RepositoryId, database: SQLite, repository: Repository) -> Watcher:
"""
package status watcher fixture
Args:
configuration(Configuration): configuration fixture
repository_id(RepositoryId): repository identifier fixture
database(SQLite): database fixture
repository(Repository): repository fixture
mocker(MockerFixture): mocker object
Returns:
Watcher: package status watcher test instance
"""
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
_, repository_id = configuration.check_loaded()
return Watcher(repository_id, configuration, database)
return Watcher(repository_id, database)

View File

@ -6,7 +6,6 @@ from pathlib import Path
from pytest_mock import MockerFixture
from unittest.mock import MagicMock
from ahriman.core.alpm.pacman import Pacman
from ahriman.core.alpm.remote import AUR
from ahriman.core.exceptions import PackageInfoError, UnknownPackageError
from ahriman.models.aur_package import AURPackage
@ -129,29 +128,28 @@ def test_aur_request_failed_http_error(aur: AUR, mocker: MockerFixture) -> None:
aur.aur_request("info", "ahriman")
def test_package_info(aur: AUR, aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
def test_package_info(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
"""
must make request for info
"""
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.aur_request", return_value=[aur_package_ahriman])
assert aur.package_info(aur_package_ahriman.name, pacman=pacman) == aur_package_ahriman
assert aur.package_info(aur_package_ahriman.name, pacman=None) == aur_package_ahriman
request_mock.assert_called_once_with("info", aur_package_ahriman.name)
def test_package_info_not_found(aur: AUR, aur_package_ahriman: AURPackage, pacman: Pacman,
mocker: MockerFixture) -> None:
def test_package_info_not_found(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
"""
must raise UnknownPackage exception in case if no package was found
"""
mocker.patch("ahriman.core.alpm.remote.AUR.aur_request", return_value=[])
with pytest.raises(UnknownPackageError, match=aur_package_ahriman.name):
assert aur.package_info(aur_package_ahriman.name, pacman=pacman)
assert aur.package_info(aur_package_ahriman.name, pacman=None)
def test_package_search(aur: AUR, aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
def test_package_search(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
"""
must make request for search
"""
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.aur_request", return_value=[aur_package_ahriman])
assert aur.package_search(aur_package_ahriman.name, pacman=pacman) == [aur_package_ahriman]
assert aur.package_search(aur_package_ahriman.name, pacman=None) == [aur_package_ahriman]
request_mock.assert_called_once_with("search", aur_package_ahriman.name, by="name-desc")

View File

@ -6,7 +6,6 @@ from pathlib import Path
from pytest_mock import MockerFixture
from unittest.mock import MagicMock
from ahriman.core.alpm.pacman import Pacman
from ahriman.core.alpm.remote import Official
from ahriman.core.exceptions import PackageInfoError, UnknownPackageError
from ahriman.models.aur_package import AURPackage
@ -95,33 +94,30 @@ def test_arch_request_failed_http_error(official: Official, mocker: MockerFixtur
official.arch_request("akonadi", by="q")
def test_package_info(official: Official, aur_package_akonadi: AURPackage, pacman: Pacman,
mocker: MockerFixture) -> None:
def test_package_info(official: Official, aur_package_akonadi: AURPackage, mocker: MockerFixture) -> None:
"""
must make request for info
"""
request_mock = mocker.patch("ahriman.core.alpm.remote.Official.arch_request",
return_value=[aur_package_akonadi])
assert official.package_info(aur_package_akonadi.name, pacman=pacman) == aur_package_akonadi
assert official.package_info(aur_package_akonadi.name, pacman=None) == aur_package_akonadi
request_mock.assert_called_once_with(aur_package_akonadi.name, by="name")
def test_package_info_not_found(official: Official, aur_package_ahriman: AURPackage, pacman: Pacman,
mocker: MockerFixture) -> None:
def test_package_info_not_found(official: Official, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
"""
must raise UnknownPackage exception in case if no package was found
"""
mocker.patch("ahriman.core.alpm.remote.Official.arch_request", return_value=[])
with pytest.raises(UnknownPackageError, match=aur_package_ahriman.name):
assert official.package_info(aur_package_ahriman.name, pacman=pacman)
assert official.package_info(aur_package_ahriman.name, pacman=None)
def test_package_search(official: Official, aur_package_akonadi: AURPackage, pacman: Pacman,
mocker: MockerFixture) -> None:
def test_package_search(official: Official, aur_package_akonadi: AURPackage, mocker: MockerFixture) -> None:
"""
must make request for search
"""
request_mock = mocker.patch("ahriman.core.alpm.remote.Official.arch_request",
return_value=[aur_package_akonadi])
assert official.package_search(aur_package_akonadi.name, pacman=pacman) == [aur_package_akonadi]
assert official.package_search(aur_package_akonadi.name, pacman=None) == [aur_package_akonadi]
request_mock.assert_called_once_with(aur_package_akonadi.name, by="q")

View File

@ -21,6 +21,17 @@ def test_package_info(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURP
assert package == aur_package_akonadi
def test_package_info_no_pacman(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURPackage,
mocker: MockerFixture) -> None:
"""
must raise UnknownPackageError if no pacman set
"""
mocker.patch("ahriman.core.alpm.pacman.Pacman.package_get", return_value=[aur_package_akonadi])
with pytest.raises(UnknownPackageError, match=aur_package_akonadi.name):
official_syncdb.package_info(aur_package_akonadi.name, pacman=None)
def test_package_info_not_found(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURPackage, pacman: Pacman,
mocker: MockerFixture) -> None:
"""

View File

@ -37,6 +37,7 @@ def test_from_path(repository_id: RepositoryId, mocker: MockerFixture) -> None:
must load configuration
"""
mocker.patch("pathlib.Path.is_file", return_value=True)
mocker.patch("ahriman.core.configuration.Configuration.get", return_value="ahriman.ini.d")
read_mock = mocker.patch("ahriman.core.configuration.Configuration.read")
load_includes_mock = mocker.patch("ahriman.core.configuration.Configuration.load_includes")
path = Path("path")
@ -53,6 +54,7 @@ def test_from_path_file_missing(repository_id: RepositoryId, mocker: MockerFixtu
"""
mocker.patch("pathlib.Path.is_file", return_value=False)
mocker.patch("ahriman.core.configuration.Configuration.load_includes")
mocker.patch("ahriman.core.configuration.Configuration.get", return_value="ahriman.ini.d")
read_mock = mocker.patch("ahriman.core.configuration.Configuration.read")
configuration = Configuration.from_path(Path("path"), repository_id)
@ -288,30 +290,58 @@ def test_gettype_from_section_no_section(configuration: Configuration) -> None:
configuration.gettype("rsync:x86_64", configuration.repository_id)
def test_load_includes_missing(configuration: Configuration) -> None:
def test_load_includes(mocker: MockerFixture) -> None:
"""
must load includes
"""
mocker.patch.object(Configuration, "logging_path", Path("logging"))
read_mock = mocker.patch("ahriman.core.configuration.Configuration.read")
glob_mock = mocker.patch("pathlib.Path.glob", autospec=True, return_value=[Path("include"), Path("logging")])
configuration = Configuration()
configuration.load_includes(Path("path"))
glob_mock.assert_called_once_with(Path("path"), "*.ini")
read_mock.assert_called_once_with(Path("include"))
assert configuration.includes == [Path("include")]
def test_load_includes_missing() -> None:
"""
must not fail if not include directory found
"""
configuration = Configuration()
configuration.set_option("settings", "include", "path")
configuration.load_includes()
def test_load_includes_no_option(configuration: Configuration) -> None:
def test_load_includes_no_option() -> None:
"""
must not fail if no option set
"""
configuration.remove_option("settings", "include")
configuration = Configuration()
configuration.set_option("settings", "key", "value")
configuration.load_includes()
def test_load_includes_no_section(configuration: Configuration) -> None:
def test_load_includes_no_section() -> None:
"""
must not fail if no section set
"""
configuration.remove_section("settings")
configuration = Configuration()
configuration.load_includes()
def test_load_includes_default_path(mocker: MockerFixture) -> None:
"""
must load includes from default path
"""
mocker.patch.object(Configuration, "include", Path("path"))
glob_mock = mocker.patch("pathlib.Path.glob", autospec=True, return_value=[])
Configuration().load_includes()
glob_mock.assert_called_once_with(Path("path"), "*.ini")
def test_merge_sections_missing(configuration: Configuration) -> None:
"""
must merge create section if not exists

View File

@ -19,11 +19,11 @@ def test_build_queue_insert_clear_multi(database: SQLite, package_ahriman: Packa
must clear all packages from queue for specific repository
"""
database.build_queue_insert(package_ahriman)
database.repository_id = RepositoryId("i686", database.repository_id.name)
database._repository_id = RepositoryId("i686", database._repository_id.name)
database.build_queue_insert(package_ahriman)
database.build_queue_clear(None)
database.repository_id = RepositoryId("x86_64", database.repository_id.name)
database._repository_id = RepositoryId("x86_64", database._repository_id.name)
assert database.build_queue_get() == [package_ahriman]
@ -68,19 +68,19 @@ def test_build_queue_insert_multi(database: SQLite, package_ahriman: Package) ->
assert database.build_queue_get() == [package_ahriman]
package_ahriman.version = "2"
database.repository_id = RepositoryId("i686", database.repository_id.name)
database._repository_id = RepositoryId("i686", database._repository_id.name)
database.build_queue_insert(package_ahriman)
assert database.build_queue_get() == [package_ahriman]
package_ahriman.version = "1"
database.repository_id = RepositoryId("x86_64", database.repository_id.name)
database._repository_id = RepositoryId("x86_64", database._repository_id.name)
assert database.build_queue_get() == [package_ahriman]
package_ahriman.version = "3"
database.repository_id = RepositoryId(database.repository_id.architecture, "repo")
database._repository_id = RepositoryId(database._repository_id.architecture, "repo")
database.build_queue_insert(package_ahriman)
assert database.build_queue_get() == [package_ahriman]
package_ahriman.version = "1"
database.repository_id = RepositoryId(database.repository_id.architecture, "aur-clone")
database._repository_id = RepositoryId(database._repository_id.architecture, "aur-clone")
assert database.build_queue_get() == [package_ahriman]

View File

@ -23,12 +23,11 @@ def test_logs_insert_remove_multi(database: SQLite, package_ahriman: Package) ->
must clear logs for specified repository
"""
database.logs_insert(LogRecordId(package_ahriman.base, "1"), 42.0, "message 1")
database.repository_id = RepositoryId("i686", database.repository_id.name)
database.logs_insert(LogRecordId(package_ahriman.base, "1"), 43.0, "message 2")
database.logs_insert(LogRecordId(package_ahriman.base, "1"), 43.0, "message 2",
RepositoryId("i686", database._repository_id.name))
database.logs_remove(package_ahriman.base, None)
assert not database.logs_get(package_ahriman.base)
database.repository_id = RepositoryId("x86_64", database.repository_id.name)
database.logs_remove(package_ahriman.base, None, RepositoryId("i686", database._repository_id.name))
assert not database.logs_get(package_ahriman.base, repository_id=RepositoryId("i686", database._repository_id.name))
assert database.logs_get(package_ahriman.base) == [(42.0, "message 1")]
@ -68,9 +67,9 @@ def test_logs_insert_get_multi(database: SQLite, package_ahriman: Package) -> No
must insert and get package logs for multiple repositories
"""
database.logs_insert(LogRecordId(package_ahriman.base, "1"), 42.0, "message 1")
database.repository_id = RepositoryId("i686", database.repository_id.name)
database.logs_insert(LogRecordId(package_ahriman.base, "1"), 43.0, "message 2")
database.logs_insert(LogRecordId(package_ahriman.base, "1"), 43.0, "message 2",
RepositoryId("i686", database._repository_id.name))
assert database.logs_get(package_ahriman.base) == [(43.0, "message 2")]
database.repository_id = RepositoryId("x86_64", database.repository_id.name)
assert database.logs_get(package_ahriman.base,
repository_id=RepositoryId("i686", database._repository_id.name)) == [(43.0, "message 2")]
assert database.logs_get(package_ahriman.base) == [(42.0, "message 1")]

View File

@ -15,10 +15,10 @@ def test_package_remove_package_base(database: SQLite, connection: Connection) -
"""
must remove package base
"""
database._package_remove_package_base(connection, "package")
database._package_remove_package_base(connection, "package", database._repository_id)
args = {
"package_base": "package",
"repository": database.repository_id.id,
"repository": database._repository_id.id,
}
connection.execute.assert_has_calls([
MockCall(pytest.helpers.anyvar(str, strict=True), args),
@ -30,11 +30,12 @@ def test_package_remove_packages(database: SQLite, connection: Connection, packa
"""
must remove packages belong to base
"""
database._package_remove_packages(connection, package_ahriman.base, package_ahriman.packages.keys())
database._package_remove_packages(connection, package_ahriman.base, package_ahriman.packages.keys(),
database._repository_id)
connection.execute.assert_called_once_with(
pytest.helpers.anyvar(str, strict=True), {
"package_base": package_ahriman.base,
"repository": database.repository_id.id,
"repository": database._repository_id.id,
})
connection.executemany.assert_called_once_with(pytest.helpers.anyvar(str, strict=True), [])
@ -43,7 +44,7 @@ def test_package_update_insert_base(database: SQLite, connection: Connection, pa
"""
must insert base package
"""
database._package_update_insert_base(connection, package_ahriman)
database._package_update_insert_base(connection, package_ahriman, database._repository_id)
connection.execute.assert_called_once_with(pytest.helpers.anyvar(str, strict=True), pytest.helpers.anyvar(int))
@ -51,7 +52,7 @@ def test_package_update_insert_packages(database: SQLite, connection: Connection
"""
must insert single packages
"""
database._package_update_insert_packages(connection, package_ahriman)
database._package_update_insert_packages(connection, package_ahriman, database._repository_id)
connection.executemany(pytest.helpers.anyvar(str, strict=True), pytest.helpers.anyvar(int))
@ -61,7 +62,7 @@ def test_package_update_insert_packages_no_arch(database: SQLite, connection: Co
must skip package insertion if no package architecture set
"""
package_ahriman.packages[package_ahriman.base].architecture = None
database._package_update_insert_packages(connection, package_ahriman)
database._package_update_insert_packages(connection, package_ahriman, database._repository_id)
connection.executemany(pytest.helpers.anyvar(str, strict=True), [])
@ -69,7 +70,7 @@ def test_package_update_insert_status(database: SQLite, connection: Connection,
"""
must insert single package status
"""
database._package_update_insert_status(connection, package_ahriman.base, BuildStatus())
database._package_update_insert_status(connection, package_ahriman.base, BuildStatus(), database._repository_id)
connection.execute(pytest.helpers.anyvar(str, strict=True), pytest.helpers.anyvar(int))
@ -77,7 +78,7 @@ def test_packages_get_select_package_bases(database: SQLite, connection: Connect
"""
must select all bases
"""
database._packages_get_select_package_bases(connection)
database._packages_get_select_package_bases(connection, database._repository_id)
connection.execute(pytest.helpers.anyvar(str, strict=True))
@ -85,7 +86,8 @@ def test_packages_get_select_packages(database: SQLite, connection: Connection,
"""
must select all packages
"""
database._packages_get_select_packages(connection, {package_ahriman.base: package_ahriman})
database._packages_get_select_packages(connection, {package_ahriman.base: package_ahriman},
database._repository_id)
connection.execute(pytest.helpers.anyvar(str, strict=True))
@ -99,14 +101,15 @@ def test_packages_get_select_packages_skip(database: SQLite, connection: Connect
view.update(properties.view())
connection.execute.return_value = [{"package_base": "random name"}, view]
database._packages_get_select_packages(connection, {package_ahriman.base: package_ahriman})
database._packages_get_select_packages(connection, {package_ahriman.base: package_ahriman},
database._repository_id)
def test_packages_get_select_statuses(database: SQLite, connection: Connection) -> None:
"""
must select all statuses
"""
database._packages_get_select_statuses(connection)
database._packages_get_select_statuses(connection, database._repository_id)
connection.execute(pytest.helpers.anyvar(str, strict=True))
@ -118,8 +121,10 @@ def test_package_remove(database: SQLite, package_ahriman: Package, mocker: Mock
remove_packages_mock = mocker.patch("ahriman.core.database.SQLite._package_remove_packages")
database.package_remove(package_ahriman.base)
remove_package_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman.base)
remove_packages_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman.base, [])
remove_package_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman.base,
database._repository_id)
remove_packages_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman.base, [],
database._repository_id)
def test_package_update(database: SQLite, package_ahriman: Package, mocker: MockerFixture):
@ -133,11 +138,13 @@ def test_package_update(database: SQLite, package_ahriman: Package, mocker: Mock
remove_packages_mock = mocker.patch("ahriman.core.database.SQLite._package_remove_packages")
database.package_update(package_ahriman, status)
insert_base_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman)
insert_status_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman.base, status)
insert_packages_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman)
remove_packages_mock.assert_called_once_with(
pytest.helpers.anyvar(int), package_ahriman.base, package_ahriman.packages.keys())
insert_base_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman, database._repository_id)
insert_status_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman.base, status,
database._repository_id)
insert_packages_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman,
database._repository_id)
remove_packages_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman.base,
package_ahriman.packages.keys(), database._repository_id)
def test_packages_get(database: SQLite, package_ahriman: Package, mocker: MockerFixture) -> None:
@ -150,9 +157,10 @@ def test_packages_get(database: SQLite, package_ahriman: Package, mocker: Mocker
select_statuses_mock = mocker.patch("ahriman.core.database.SQLite._packages_get_select_statuses")
database.packages_get()
select_bases_mock.assert_called_once_with(pytest.helpers.anyvar(int))
select_statuses_mock.assert_called_once_with(pytest.helpers.anyvar(int))
select_packages_mock.assert_called_once_with(pytest.helpers.anyvar(int), {package_ahriman.base: package_ahriman})
select_bases_mock.assert_called_once_with(pytest.helpers.anyvar(int), database._repository_id)
select_statuses_mock.assert_called_once_with(pytest.helpers.anyvar(int), database._repository_id)
select_packages_mock.assert_called_once_with(pytest.helpers.anyvar(int), {package_ahriman.base: package_ahriman},
database._repository_id)
def test_package_update_get(database: SQLite, package_ahriman: Package) -> None:

View File

@ -3,12 +3,13 @@ import pytest
from pathlib import Path
from ahriman.core.formatters import AurPrinter, ConfigurationPrinter, ConfigurationPathsPrinter, PackagePrinter, \
PatchPrinter, StatusPrinter, StringPrinter, TreePrinter, UpdatePrinter, UserPrinter, ValidationPrinter, \
VersionPrinter
PatchPrinter, RepositoryPrinter, StatusPrinter, StringPrinter, TreePrinter, UpdatePrinter, UserPrinter, \
ValidationPrinter, VersionPrinter
from ahriman.models.aur_package import AURPackage
from ahriman.models.build_status import BuildStatus
from ahriman.models.package import Package
from ahriman.models.pkgbuild_patch import PkgbuildPatch
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user import User
@ -76,6 +77,17 @@ def patch_printer(package_ahriman: Package) -> PatchPrinter:
return PatchPrinter(package_ahriman.base, [PkgbuildPatch("key", "value")])
@pytest.fixture
def repository_printer(repository_id: RepositoryId) -> RepositoryPrinter:
"""
fixture for repository printer
Returns:
RepositoryPrinter: repository printer test instance
"""
return RepositoryPrinter(repository_id)
@pytest.fixture
def status_printer() -> StatusPrinter:
"""

View File

@ -0,0 +1,15 @@
from ahriman.core.formatters import RepositoryPrinter
def test_properties(repository_printer: RepositoryPrinter) -> None:
"""
must return empty properties list
"""
assert repository_printer.properties()
def test_title(repository_printer: RepositoryPrinter) -> None:
"""
must return non-empty title
"""
assert repository_printer.title() is not None

View File

@ -20,18 +20,20 @@ def test_load(configuration: Configuration, mocker: MockerFixture) -> None:
add_mock = mocker.patch("logging.Logger.addHandler")
load_mock = mocker.patch("ahriman.core.status.client.Client.load")
handler = HttpLogHandler.load(configuration, report=False)
_, repository_id = configuration.check_loaded()
handler = HttpLogHandler.load(repository_id, configuration, report=False)
assert handler
add_mock.assert_called_once_with(handler)
load_mock.assert_called_once_with(configuration, report=False)
load_mock.assert_called_once_with(repository_id, configuration, report=False)
def test_load_exist(configuration: Configuration) -> None:
"""
must not load handler if already set
"""
handler = HttpLogHandler.load(configuration, report=False)
new_handler = HttpLogHandler.load(configuration, report=False)
_, repository_id = configuration.check_loaded()
handler = HttpLogHandler.load(repository_id, configuration, report=False)
new_handler = HttpLogHandler.load(repository_id, configuration, report=False)
assert handler is new_handler
@ -43,7 +45,8 @@ def test_emit(configuration: Configuration, log_record: logging.LogRecord, packa
log_record_id = log_record.package_id = LogRecordId(package_ahriman.base, package_ahriman.version)
log_mock = mocker.patch("ahriman.core.status.client.Client.package_logs")
handler = HttpLogHandler(configuration, report=False, suppress_errors=False)
_, repository_id = configuration.check_loaded()
handler = HttpLogHandler(repository_id, configuration, report=False, suppress_errors=False)
handler.emit(log_record)
log_mock.assert_called_once_with(log_record_id, log_record)
@ -57,7 +60,8 @@ def test_emit_failed(configuration: Configuration, log_record: logging.LogRecord
log_record.package_id = LogRecordId(package_ahriman.base, package_ahriman.version)
mocker.patch("ahriman.core.status.client.Client.package_logs", side_effect=Exception())
handle_error_mock = mocker.patch("logging.Handler.handleError")
handler = HttpLogHandler(configuration, report=False, suppress_errors=False)
_, repository_id = configuration.check_loaded()
handler = HttpLogHandler(repository_id, configuration, report=False, suppress_errors=False)
handler.emit(log_record)
handle_error_mock.assert_called_once_with(log_record)
@ -71,7 +75,8 @@ def test_emit_suppress_failed(configuration: Configuration, log_record: logging.
log_record.package_id = LogRecordId(package_ahriman.base, package_ahriman.version)
mocker.patch("ahriman.core.status.client.Client.package_logs", side_effect=Exception())
handle_error_mock = mocker.patch("logging.Handler.handleError")
handler = HttpLogHandler(configuration, report=False, suppress_errors=True)
_, repository_id = configuration.check_loaded()
handler = HttpLogHandler(repository_id, configuration, report=False, suppress_errors=True)
handler.emit(log_record)
handle_error_mock.assert_not_called()
@ -82,7 +87,9 @@ def test_emit_skip(configuration: Configuration, log_record: logging.LogRecord,
must skip log record posting if no package base set
"""
log_mock = mocker.patch("ahriman.core.status.client.Client.package_logs")
handler = HttpLogHandler(configuration, report=False, suppress_errors=False)
_, repository_id = configuration.check_loaded()
handler = HttpLogHandler(repository_id, configuration, report=False, suppress_errors=False)
handler.emit(log_record)
log_mock.assert_not_called()

View File

@ -50,9 +50,10 @@ def test_load(configuration: Configuration, mocker: MockerFixture) -> None:
logging_mock = mocker.patch("ahriman.core.log.log_loader.fileConfig", side_effect=fileConfig)
http_log_mock = mocker.patch("ahriman.core.log.http_log_handler.HttpLogHandler.load")
LogLoader.load(configuration, LogHandler.Journald, quiet=False, report=False)
_, repository_id = configuration.check_loaded()
LogLoader.load(repository_id, configuration, LogHandler.Journald, quiet=False, report=False)
logging_mock.assert_called_once_with(pytest.helpers.anyvar(int), disable_existing_loggers=True)
http_log_mock.assert_called_once_with(configuration, report=False)
http_log_mock.assert_called_once_with(repository_id, configuration, report=False)
assert all(isinstance(handler, JournalHandler) for handler in logging.getLogger().handlers)
@ -61,7 +62,8 @@ def test_load_fallback(configuration: Configuration, mocker: MockerFixture) -> N
must fall back to stderr without errors
"""
mocker.patch("ahriman.core.log.log_loader.fileConfig", side_effect=PermissionError())
LogLoader.load(configuration, LogHandler.Journald, quiet=False, report=False)
_, repository_id = configuration.check_loaded()
LogLoader.load(repository_id, configuration, LogHandler.Journald, quiet=False, report=False)
def test_load_quiet(configuration: Configuration, mocker: MockerFixture) -> None:
@ -69,5 +71,7 @@ def test_load_quiet(configuration: Configuration, mocker: MockerFixture) -> None
must disable logging in case if quiet flag set
"""
disable_mock = mocker.patch("logging.disable")
LogLoader.load(configuration, LogHandler.Journald, quiet=True, report=False)
_, repository_id = configuration.check_loaded()
LogLoader.load(repository_id, configuration, LogHandler.Journald, quiet=True, report=False)
disable_mock.assert_called_once_with(logging.WARNING)

View File

@ -79,11 +79,13 @@ def test_remote_update(remote_call: RemoteCall, mocker: MockerFixture) -> None:
request_mock = mocker.patch("ahriman.core.status.web_client.WebClient.make_request", return_value=response_obj)
assert remote_call.remote_update() == "id"
request_mock.assert_called_once_with("POST", "/api/v1/service/update", json={
"aur": False,
"local": False,
"manual": True,
})
request_mock.assert_called_once_with("POST", "/api/v1/service/update",
params=remote_call.repository_id.query(),
json={
"aur": False,
"local": False,
"manual": True,
})
def test_remote_wait(remote_call: RemoteCall, mocker: MockerFixture) -> None:

View File

@ -89,7 +89,7 @@ def test_updates_aur_filter(update_handler: UpdateHandler, package_ahriman: Pack
package_load_mock = mocker.patch("ahriman.models.package.Package.from_aur", return_value=package_ahriman)
assert update_handler.updates_aur([package_ahriman.base], vcs=True) == [package_ahriman]
package_load_mock.assert_called_once_with(package_ahriman.base, update_handler.pacman, None)
package_load_mock.assert_called_once_with(package_ahriman.base, None)
def test_updates_aur_ignore(update_handler: UpdateHandler, package_ahriman: Package,

View File

@ -28,4 +28,5 @@ def web_client(configuration: Configuration) -> WebClient:
WebClient: web client test instance
"""
configuration.set("web", "port", "8080")
return WebClient(configuration)
_, repository_id = configuration.check_loaded()
return WebClient(repository_id, configuration)

View File

@ -15,7 +15,8 @@ def test_load_dummy_client(configuration: Configuration) -> None:
"""
must load dummy client if no settings set
"""
assert not isinstance(Client.load(configuration, report=True), WebClient)
_, repository_id = configuration.check_loaded()
assert not isinstance(Client.load(repository_id, configuration, report=True), WebClient)
def test_load_dummy_client_disabled(configuration: Configuration) -> None:
@ -24,7 +25,9 @@ def test_load_dummy_client_disabled(configuration: Configuration) -> None:
"""
configuration.set_option("web", "host", "localhost")
configuration.set_option("web", "port", "8080")
assert not isinstance(Client.load(configuration, report=False), WebClient)
_, repository_id = configuration.check_loaded()
assert not isinstance(Client.load(repository_id, configuration, report=False), WebClient)
def test_load_full_client(configuration: Configuration) -> None:
@ -33,7 +36,9 @@ def test_load_full_client(configuration: Configuration) -> None:
"""
configuration.set_option("web", "host", "localhost")
configuration.set_option("web", "port", "8080")
assert isinstance(Client.load(configuration, report=True), WebClient)
_, repository_id = configuration.check_loaded()
assert isinstance(Client.load(repository_id, configuration, report=True), WebClient)
def test_load_full_client_from_address(configuration: Configuration) -> None:
@ -41,7 +46,8 @@ def test_load_full_client_from_address(configuration: Configuration) -> None:
must load full client by using address
"""
configuration.set_option("web", "address", "http://localhost:8080")
assert isinstance(Client.load(configuration, report=True), WebClient)
_, repository_id = configuration.check_loaded()
assert isinstance(Client.load(repository_id, configuration, report=True), WebClient)
def test_load_full_client_from_unix_socket(configuration: Configuration) -> None:
@ -49,7 +55,8 @@ def test_load_full_client_from_unix_socket(configuration: Configuration) -> None
must load full client by using unix socket
"""
configuration.set_option("web", "unix_socket", "/var/lib/ahriman/ahriman-web.sock")
assert isinstance(Client.load(configuration, report=True), WebClient)
_, repository_id = configuration.check_loaded()
assert isinstance(Client.load(repository_id, configuration, report=True), WebClient)
def test_package_add(client: Client, package_ahriman: Package) -> None:

View File

@ -2,8 +2,6 @@ import pytest
from pytest_mock import MockerFixture
from ahriman.core.configuration import Configuration
from ahriman.core.database import SQLite
from ahriman.core.exceptions import UnknownPackageError
from ahriman.core.status.watcher import Watcher
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
@ -11,27 +9,15 @@ from ahriman.models.log_record_id import LogRecordId
from ahriman.models.package import Package
def test_force_no_report(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> None:
"""
must force dummy report client
"""
configuration.set_option("web", "port", "8080")
load_mock = mocker.patch("ahriman.core.repository.Repository.load")
_, repository_id = configuration.check_loaded()
Watcher(repository_id, configuration, database)
load_mock.assert_called_once_with(repository_id, configuration, database, report=False)
def test_load(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must correctly load packages
"""
mocker.patch("ahriman.core.repository.repository.Repository.packages", return_value=[package_ahriman])
cache_mock = mocker.patch("ahriman.core.database.SQLite.packages_get")
cache_mock = mocker.patch("ahriman.core.database.SQLite.packages_get",
return_value=[(package_ahriman, BuildStatus())])
watcher.load()
cache_mock.assert_called_once_with()
cache_mock.assert_called_once_with(watcher.repository_id)
package, status = watcher.known[package_ahriman.base]
assert package == package_ahriman
assert status.status == BuildStatusEnum.Unknown
@ -42,7 +28,6 @@ def test_load_known(watcher: Watcher, package_ahriman: Package, mocker: MockerFi
must correctly load packages with known statuses
"""
status = BuildStatus(BuildStatusEnum.Success)
mocker.patch("ahriman.core.repository.repository.Repository.packages", return_value=[package_ahriman])
mocker.patch("ahriman.core.database.SQLite.packages_get", return_value=[(package_ahriman, status)])
watcher.known = {package_ahriman.base: (package_ahriman, status)}
@ -57,7 +42,7 @@ def test_logs_get(watcher: Watcher, package_ahriman: Package, mocker: MockerFixt
"""
logs_mock = mocker.patch("ahriman.core.database.SQLite.logs_get")
watcher.logs_get(package_ahriman.base, 1, 2)
logs_mock.assert_called_once_with(package_ahriman.base, 1, 2)
logs_mock.assert_called_once_with(package_ahriman.base, 1, 2, watcher.repository_id)
def test_logs_remove(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
@ -66,7 +51,7 @@ def test_logs_remove(watcher: Watcher, package_ahriman: Package, mocker: MockerF
"""
logs_mock = mocker.patch("ahriman.core.database.SQLite.logs_remove")
watcher.logs_remove(package_ahriman.base, "42")
logs_mock.assert_called_once_with(package_ahriman.base, "42")
logs_mock.assert_called_once_with(package_ahriman.base, "42", watcher.repository_id)
def test_logs_update_new(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
@ -81,7 +66,7 @@ def test_logs_update_new(watcher: Watcher, package_ahriman: Package, mocker: Moc
watcher.logs_update(log_record_id, 42.01, "log record")
delete_mock.assert_called_once_with(package_ahriman.base, log_record_id.version)
insert_mock.assert_called_once_with(log_record_id, 42.01, "log record")
insert_mock.assert_called_once_with(log_record_id, 42.01, "log record", watcher.repository_id)
assert watcher._last_log_record_id == log_record_id
@ -98,7 +83,7 @@ def test_logs_update_update(watcher: Watcher, package_ahriman: Package, mocker:
watcher.logs_update(log_record_id, 42.01, "log record")
delete_mock.assert_not_called()
insert_mock.assert_called_once_with(log_record_id, 42.01, "log record")
insert_mock.assert_called_once_with(log_record_id, 42.01, "log record", watcher.repository_id)
def test_package_get(watcher: Watcher, package_ahriman: Package) -> None:
@ -129,7 +114,7 @@ def test_package_remove(watcher: Watcher, package_ahriman: Package, mocker: Mock
watcher.package_remove(package_ahriman.base)
assert not watcher.known
cache_mock.assert_called_once_with(package_ahriman.base)
cache_mock.assert_called_once_with(package_ahriman.base, watcher.repository_id)
logs_mock.assert_called_once_with(package_ahriman.base, None)
@ -140,7 +125,7 @@ def test_package_remove_unknown(watcher: Watcher, package_ahriman: Package, mock
cache_mock = mocker.patch("ahriman.core.database.SQLite.package_remove")
watcher.package_remove(package_ahriman.base)
cache_mock.assert_called_once_with(package_ahriman.base)
cache_mock.assert_called_once_with(package_ahriman.base, watcher.repository_id)
def test_package_update(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
@ -150,7 +135,7 @@ def test_package_update(watcher: Watcher, package_ahriman: Package, mocker: Mock
cache_mock = mocker.patch("ahriman.core.database.SQLite.package_update")
watcher.package_update(package_ahriman.base, BuildStatusEnum.Unknown, package_ahriman)
cache_mock.assert_called_once_with(package_ahriman, pytest.helpers.anyvar(int))
cache_mock.assert_called_once_with(package_ahriman, pytest.helpers.anyvar(int), watcher.repository_id)
package, status = watcher.known[package_ahriman.base]
assert package == package_ahriman
assert status.status == BuildStatusEnum.Unknown
@ -164,7 +149,7 @@ def test_package_update_ping(watcher: Watcher, package_ahriman: Package, mocker:
watcher.known = {package_ahriman.base: (package_ahriman, BuildStatus())}
watcher.package_update(package_ahriman.base, BuildStatusEnum.Success, None)
cache_mock.assert_called_once_with(package_ahriman, pytest.helpers.anyvar(int))
cache_mock.assert_called_once_with(package_ahriman, pytest.helpers.anyvar(int), watcher.repository_id)
package, status = watcher.known[package_ahriman.base]
assert package == package_ahriman
assert status.status == BuildStatusEnum.Success

View File

@ -139,7 +139,8 @@ def test_package_add(web_client: WebClient, package_ahriman: Package, mocker: Mo
payload = pytest.helpers.get_package_status(package_ahriman)
web_client.package_add(package_ahriman, BuildStatusEnum.Unknown)
requests_mock.assert_called_once_with("POST", pytest.helpers.anyvar(str, True), json=payload)
requests_mock.assert_called_once_with("POST", pytest.helpers.anyvar(str, True),
params=web_client.repository_id.query(), json=payload)
def test_package_add_failed(web_client: WebClient, package_ahriman: Package, mocker: MockerFixture) -> None:
@ -196,7 +197,7 @@ def test_package_get_all(web_client: WebClient, package_ahriman: Package, mocker
return_value=response_obj)
result = web_client.package_get(None)
requests_mock.assert_called_once_with("GET", web_client._package_url())
requests_mock.assert_called_once_with("GET", web_client._package_url(), params=web_client.repository_id.query())
assert len(result) == len(response)
assert (package_ahriman, BuildStatusEnum.Unknown) in [(package, status.status) for package, status in result]
@ -230,7 +231,8 @@ def test_package_get_single(web_client: WebClient, package_ahriman: Package, moc
return_value=response_obj)
result = web_client.package_get(package_ahriman.base)
requests_mock.assert_called_once_with("GET", web_client._package_url(package_ahriman.base))
requests_mock.assert_called_once_with("GET", web_client._package_url(package_ahriman.base),
params=web_client.repository_id.query())
assert len(result) == len(response)
assert (package_ahriman, BuildStatusEnum.Unknown) in [(package, status.status) for package, status in result]
@ -248,8 +250,8 @@ def test_package_logs(web_client: WebClient, log_record: logging.LogRecord, pack
}
web_client.package_logs(LogRecordId(package_ahriman.base, package_ahriman.version), log_record)
requests_mock.assert_called_once_with("POST", pytest.helpers.anyvar(str, True), json=payload,
suppress_errors=True)
requests_mock.assert_called_once_with("POST", pytest.helpers.anyvar(str, True),
params=web_client.repository_id.query(), json=payload, suppress_errors=True)
def test_package_logs_failed(web_client: WebClient, log_record: logging.LogRecord, package_ahriman: Package,
@ -281,7 +283,8 @@ def test_package_remove(web_client: WebClient, package_ahriman: Package, mocker:
requests_mock = mocker.patch("ahriman.core.status.web_client.WebClient.make_request")
web_client.package_remove(package_ahriman.base)
requests_mock.assert_called_once_with("DELETE", pytest.helpers.anyvar(str, True))
requests_mock.assert_called_once_with("DELETE", pytest.helpers.anyvar(str, True),
params=web_client.repository_id.query())
def test_package_remove_failed(web_client: WebClient, package_ahriman: Package, mocker: MockerFixture) -> None:
@ -308,8 +311,10 @@ def test_package_update(web_client: WebClient, package_ahriman: Package, mocker:
requests_mock = mocker.patch("ahriman.core.status.web_client.WebClient.make_request")
web_client.package_update(package_ahriman.base, BuildStatusEnum.Unknown)
requests_mock.assert_called_once_with("POST", pytest.helpers.anyvar(str, True), json={
"status": BuildStatusEnum.Unknown.value
requests_mock.assert_called_once_with("POST", pytest.helpers.anyvar(str, True),
params=web_client.repository_id.query(),
json={
"status": BuildStatusEnum.Unknown.value,
})
@ -343,7 +348,7 @@ def test_status_get(web_client: WebClient, mocker: MockerFixture) -> None:
return_value=response_obj)
result = web_client.status_get()
requests_mock.assert_called_once_with("GET", web_client._status_url())
requests_mock.assert_called_once_with("GET", web_client._status_url(), params=web_client.repository_id.query())
assert result.architecture == "x86_64"
@ -370,8 +375,10 @@ def test_status_update(web_client: WebClient, mocker: MockerFixture) -> None:
requests_mock = mocker.patch("ahriman.core.status.web_client.WebClient.make_request")
web_client.status_update(BuildStatusEnum.Unknown)
requests_mock.assert_called_once_with("POST", pytest.helpers.anyvar(str, True), json={
"status": BuildStatusEnum.Unknown.value
requests_mock.assert_called_once_with("POST", pytest.helpers.anyvar(str, True),
params=web_client.repository_id.query(),
json={
"status": BuildStatusEnum.Unknown.value,
})

View File

@ -1,7 +1,11 @@
import pytest
from pytest_mock import MockerFixture
from unittest.mock import MagicMock, call as MockCall
from unittest.mock import MagicMock
from ahriman.core.spawn import Spawn
from ahriman.models.process_status import ProcessStatus
from ahriman.models.repository_id import RepositoryId
def test_boolean_action_argument() -> None:
@ -12,7 +16,7 @@ def test_boolean_action_argument() -> None:
assert Spawn.boolean_action_argument("option", False) == "no-option"
def test_process(spawner: Spawn) -> None:
def test_process(spawner: Spawn, repository_id: RepositoryId) -> None:
"""
must process external process run correctly
"""
@ -20,39 +24,39 @@ def test_process(spawner: Spawn) -> None:
callback = MagicMock()
callback.return_value = True
spawner.process(callback, args, spawner.repository_id, "id", spawner.queue)
spawner.process(callback, args, repository_id, "id", spawner.queue)
callback.assert_called_once_with(args, spawner.repository_id)
(uuid, status, time) = spawner.queue.get()
assert uuid == "id"
assert status
assert time >= 0
callback.assert_called_once_with(args, repository_id)
status = spawner.queue.get()
assert status.process_id == "id"
assert status.status
assert status.consumed_time >= 0
assert spawner.queue.empty()
def test_process_error(spawner: Spawn) -> None:
def test_process_error(spawner: Spawn, repository_id: RepositoryId) -> None:
"""
must process external run with error correctly
"""
callback = MagicMock()
callback.return_value = False
spawner.process(callback, MagicMock(), spawner.repository_id, "id", spawner.queue)
spawner.process(callback, MagicMock(), repository_id, "id", spawner.queue)
(uuid, status, time) = spawner.queue.get()
assert uuid == "id"
assert not status
assert time >= 0
status = spawner.queue.get()
assert status.process_id == "id"
assert not status.status
assert status.consumed_time >= 0
assert spawner.queue.empty()
def test_spawn_process(spawner: Spawn, mocker: MockerFixture) -> None:
def test_spawn_process(spawner: Spawn, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must correctly spawn child process
"""
start_mock = mocker.patch("multiprocessing.Process.start")
assert spawner._spawn_process("add", "ahriman", now="", maybe="?", none=None)
assert spawner._spawn_process(repository_id, "add", "ahriman", now="", maybe="?", none=None)
start_mock.assert_called_once_with()
spawner.args_parser.parse_args.assert_called_once_with(
spawner.command_arguments + [
@ -77,7 +81,7 @@ def test_key_import(spawner: Spawn, mocker: MockerFixture) -> None:
"""
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
assert spawner.key_import("0xdeadbeaf", None)
spawn_mock.assert_called_once_with("service-key-import", "0xdeadbeaf")
spawn_mock.assert_called_once_with(pytest.helpers.anyvar(int), "service-key-import", "0xdeadbeaf")
def test_key_import_with_server(spawner: Spawn, mocker: MockerFixture) -> None:
@ -86,78 +90,80 @@ def test_key_import_with_server(spawner: Spawn, mocker: MockerFixture) -> None:
"""
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
assert spawner.key_import("0xdeadbeaf", "keyserver.ubuntu.com")
spawn_mock.assert_called_once_with("service-key-import", "0xdeadbeaf", **{"key-server": "keyserver.ubuntu.com"})
spawn_mock.assert_called_once_with(pytest.helpers.anyvar(int), "service-key-import", "0xdeadbeaf",
**{"key-server": "keyserver.ubuntu.com"})
def test_packages_add(spawner: Spawn, mocker: MockerFixture) -> None:
def test_packages_add(spawner: Spawn, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call package addition
"""
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
assert spawner.packages_add(["ahriman", "linux"], None, now=False)
spawn_mock.assert_called_once_with("package-add", "ahriman", "linux", username=None)
assert spawner.packages_add(repository_id, ["ahriman", "linux"], None, now=False)
spawn_mock.assert_called_once_with(repository_id, "package-add", "ahriman", "linux", username=None)
def test_packages_add_with_build(spawner: Spawn, mocker: MockerFixture) -> None:
def test_packages_add_with_build(spawner: Spawn, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call package addition with update
"""
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
assert spawner.packages_add(["ahriman", "linux"], None, now=True)
spawn_mock.assert_called_once_with("package-add", "ahriman", "linux", username=None, now="")
assert spawner.packages_add(repository_id, ["ahriman", "linux"], None, now=True)
spawn_mock.assert_called_once_with(repository_id, "package-add", "ahriman", "linux", username=None, now="")
def test_packages_add_with_username(spawner: Spawn, mocker: MockerFixture) -> None:
def test_packages_add_with_username(spawner: Spawn, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call package addition with username
"""
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
assert spawner.packages_add(["ahriman", "linux"], "username", now=False)
spawn_mock.assert_called_once_with("package-add", "ahriman", "linux", username="username")
assert spawner.packages_add(repository_id, ["ahriman", "linux"], "username", now=False)
spawn_mock.assert_called_once_with(repository_id, "package-add", "ahriman", "linux", username="username")
def test_packages_rebuild(spawner: Spawn, mocker: MockerFixture) -> None:
def test_packages_rebuild(spawner: Spawn, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call package rebuild
"""
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
assert spawner.packages_rebuild("python", "packager")
spawn_mock.assert_called_once_with("repo-rebuild", **{"depends-on": "python", "username": "packager"})
assert spawner.packages_rebuild(repository_id, "python", "packager")
spawn_mock.assert_called_once_with(repository_id, "repo-rebuild",
**{"depends-on": "python", "username": "packager"})
def test_packages_remove(spawner: Spawn, mocker: MockerFixture) -> None:
def test_packages_remove(spawner: Spawn, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call package removal
"""
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
assert spawner.packages_remove(["ahriman", "linux"])
spawn_mock.assert_called_once_with("package-remove", "ahriman", "linux")
assert spawner.packages_remove(repository_id, ["ahriman", "linux"])
spawn_mock.assert_called_once_with(repository_id, "package-remove", "ahriman", "linux")
def test_packages_update(spawner: Spawn, mocker: MockerFixture) -> None:
def test_packages_update(spawner: Spawn, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call repo update
"""
spawn_mock = mocker.patch("ahriman.core.spawn.Spawn._spawn_process")
assert spawner.packages_update("packager", aur=True, local=True, manual=True)
assert spawner.packages_update(repository_id, "packager", aur=True, local=True, manual=True)
args = {"username": "packager", "aur": "", "local": "", "manual": ""}
spawn_mock.assert_called_once_with("repo-update", **args)
spawn_mock.assert_called_once_with(repository_id, "repo-update", **args)
spawn_mock.reset_mock()
assert spawner.packages_update("packager", aur=False, local=True, manual=True)
assert spawner.packages_update(repository_id, "packager", aur=False, local=True, manual=True)
args = {"username": "packager", "no-aur": "", "local": "", "manual": ""}
spawn_mock.assert_called_once_with("repo-update", **args)
spawn_mock.assert_called_once_with(repository_id, "repo-update", **args)
spawn_mock.reset_mock()
assert spawner.packages_update("packager", aur=True, local=False, manual=True)
assert spawner.packages_update(repository_id, "packager", aur=True, local=False, manual=True)
args = {"username": "packager", "aur": "", "no-local": "", "manual": ""}
spawn_mock.assert_called_once_with("repo-update", **args)
spawn_mock.assert_called_once_with(repository_id, "repo-update", **args)
spawn_mock.reset_mock()
assert spawner.packages_update("packager", aur=True, local=True, manual=False)
assert spawner.packages_update(repository_id, "packager", aur=True, local=True, manual=False)
args = {"username": "packager", "aur": "", "local": "", "no-manual": ""}
spawn_mock.assert_called_once_with("repo-update", **args)
spawn_mock.assert_called_once_with(repository_id, "repo-update", **args)
spawn_mock.reset_mock()
@ -167,8 +173,8 @@ def test_run(spawner: Spawn, mocker: MockerFixture) -> None:
"""
logging_mock = mocker.patch("logging.Logger.info")
spawner.queue.put(("1", False, 1))
spawner.queue.put(("2", True, 1))
spawner.queue.put(ProcessStatus("1", False, 1))
spawner.queue.put(ProcessStatus("2", True, 1))
spawner.queue.put(None) # terminate
spawner.run()
@ -182,8 +188,8 @@ def test_run_pop(spawner: Spawn) -> None:
first = spawner.active["1"] = MagicMock()
second = spawner.active["2"] = MagicMock()
spawner.queue.put(("1", False, 1))
spawner.queue.put(("2", True, 1))
spawner.queue.put(ProcessStatus("1", False, 1))
spawner.queue.put(ProcessStatus("2", True, 1))
spawner.queue.put(None) # terminate
spawner.run()

View File

@ -478,6 +478,7 @@ def test_walk(resource_path_root: Path) -> None:
resource_path_root / "web" / "templates" / "build-status" / "package-rebuild-modal.jinja2",
resource_path_root / "web" / "templates" / "build-status" / "table.jinja2",
resource_path_root / "web" / "templates" / "static" / "favicon.ico",
resource_path_root / "web" / "templates" / "static" / "logo.svg",
resource_path_root / "web" / "templates" / "utils" / "bootstrap-scripts.jinja2",
resource_path_root / "web" / "templates" / "utils" / "style.jinja2",
resource_path_root / "web" / "templates" / "api.jinja2",

View File

@ -30,9 +30,13 @@ def test_package_upload(remote_service: RemoteService, package_ahriman: Package,
remote_service.sync(Path("local"), [package_ahriman])
open_mock.assert_called_once_with("rb")
file_mock.close.assert_called_once()
upload_mock.assert_called_once_with("POST", f"{remote_service.client.address}/api/v1/service/upload", files={
"package": (filename, pytest.helpers.anyvar(int), "application/octet-stream", {})
})
upload_mock.assert_called_once_with(
"POST", f"{remote_service.client.address}/api/v1/service/upload",
params=remote_service.repository_id.query(),
files={
"package": (filename, pytest.helpers.anyvar(int), "application/octet-stream", {}),
},
)
def test_package_upload_with_signature(remote_service: RemoteService, package_ahriman: Package,
@ -50,10 +54,12 @@ def test_package_upload_with_signature(remote_service: RemoteService, package_ah
open_mock.assert_has_calls([MockCall("rb"), MockCall("rb")])
file_mock.close.assert_has_calls([MockCall(), MockCall()])
upload_mock.assert_called_once_with(
"POST", f"{remote_service.client.address}/api/v1/service/upload", files={
"POST", f"{remote_service.client.address}/api/v1/service/upload",
params=remote_service.repository_id.query(),
files={
"package": (filename, pytest.helpers.anyvar(int), "application/octet-stream", {}),
"signature": (f"{filename}.sig", pytest.helpers.anyvar(int), "application/octet-stream", {})
}
"signature": (f"{filename}.sig", pytest.helpers.anyvar(int), "application/octet-stream", {}),
},
)

View File

@ -1,34 +0,0 @@
import pytest
from pytest_mock import MockerFixture
from ahriman.core.exceptions import MigrationError
from ahriman.models.migration_result import MigrationResult
def test_is_outdated() -> None:
"""
must return False for outdated schema
"""
assert MigrationResult(old_version=0, new_version=1).is_outdated
assert not MigrationResult(old_version=1, new_version=1).is_outdated
def test_is_outdated_validation(mocker: MockerFixture) -> None:
"""
must call validation before version check
"""
validate_mock = mocker.patch("ahriman.models.migration_result.MigrationResult.validate")
assert MigrationResult(old_version=0, new_version=1).is_outdated
validate_mock.assert_called_once_with()
def test_validate() -> None:
"""
must raise exception on invalid migration versions
"""
with pytest.raises(MigrationError):
MigrationResult(old_version=-1, new_version=0).validate()
with pytest.raises(MigrationError):
MigrationResult(old_version=1, new_version=0).validate()

View File

@ -0,0 +1,34 @@
import pytest
from pytest_mock import MockerFixture
from ahriman.core.exceptions import MigrationError
from ahriman.models.migration_result import MigrationResult
def test_is_outdated() -> None:
"""
must return False for outdated schema
"""
assert MigrationResult(old_version=0, new_version=1).is_outdated
assert not MigrationResult(old_version=1, new_version=1).is_outdated
def test_is_outdated_validation(mocker: MockerFixture) -> None:
"""
must call validation before version check
"""
validate_mock = mocker.patch("ahriman.models.migration_result.MigrationResult.validate")
assert MigrationResult(old_version=0, new_version=1).is_outdated
validate_mock.assert_called_once_with()
def test_validate() -> None:
"""
must raise exception on invalid migration versions
"""
with pytest.raises(MigrationError):
MigrationResult(old_version=-1, new_version=0).validate()
with pytest.raises(MigrationError):
MigrationResult(old_version=1, new_version=0).validate()

View File

@ -164,14 +164,13 @@ def test_from_archive(package_ahriman: Package, pyalpm_handle: MagicMock, mocker
assert generated == package_ahriman
def test_from_aur(package_ahriman: Package, aur_package_ahriman: AURPackage, pacman: Pacman,
mocker: MockerFixture) -> None:
def test_from_aur(package_ahriman: Package, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
"""
must construct package from aur
"""
mocker.patch("ahriman.core.alpm.remote.AUR.info", return_value=aur_package_ahriman)
package = Package.from_aur(package_ahriman.base, pacman, package_ahriman.packager)
package = Package.from_aur(package_ahriman.base, package_ahriman.packager)
assert package_ahriman.base == package.base
assert package_ahriman.version == package.version
assert package_ahriman.packages.keys() == package.packages.keys()

View File

@ -21,6 +21,29 @@ def test_id() -> None:
assert RepositoryId("arch", "repo").id == "arch-repo"
def test_query() -> None:
"""
must generate query request parameters
"""
assert RepositoryId("x86_64", "a").query() == [("architecture", "x86_64"), ("repository", "a")]
assert RepositoryId("i686", "a").query() == [("architecture", "i686"), ("repository", "a")]
assert RepositoryId("x86_64", "b").query() == [("architecture", "x86_64"), ("repository", "b")]
def test_view() -> None:
"""
must generate json view
"""
repository_id = RepositoryId("x86_64", "a")
assert repository_id.view() == {"architecture": repository_id.architecture, "repository": repository_id.name}
repository_id = RepositoryId("x86_64", "b")
assert repository_id.view() == {"architecture": repository_id.architecture, "repository": repository_id.name}
repository_id = RepositoryId("i686", "a")
assert repository_id.view() == {"architecture": repository_id.architecture, "repository": repository_id.name}
def test_lt() -> None:
"""
must correctly compare instances

View File

@ -14,10 +14,9 @@ import ahriman.core.auth.helpers
from ahriman.core.auth.oauth import OAuth
from ahriman.core.configuration import Configuration
from ahriman.core.database import SQLite
from ahriman.core.repository import Repository
from ahriman.core.spawn import Spawn
from ahriman.models.user import User
from ahriman.web.web import setup_service
from ahriman.web.web import setup_server
@pytest.helpers.register
@ -114,8 +113,7 @@ def schema_response(handler: Callable[..., Awaitable[Any]], *, code: int = 200)
@pytest.fixture
def application(configuration: Configuration, spawner: Spawn, database: SQLite, repository: Repository,
mocker: MockerFixture) -> Application:
def application(configuration: Configuration, spawner: Spawn, database: SQLite, mocker: MockerFixture) -> Application:
"""
application fixture
@ -123,7 +121,6 @@ def application(configuration: Configuration, spawner: Spawn, database: SQLite,
configuration(Configuration): configuration fixture
spawner(Spawn): spawner fixture
database(SQLite): database fixture
repository(Repository): repository fixture
mocker(MockerFixture): mocker object
Returns:
@ -131,17 +128,16 @@ def application(configuration: Configuration, spawner: Spawn, database: SQLite,
"""
configuration.set_option("web", "port", "8080")
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
mocker.patch("aiohttp_apispec.setup_aiohttp_apispec")
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False)
_, repository_id = configuration.check_loaded()
return setup_service(repository_id, configuration, spawner)
return setup_server(configuration, spawner, [repository_id])
@pytest.fixture
def application_with_auth(configuration: Configuration, user: User, spawner: Spawn, database: SQLite,
repository: Repository, mocker: MockerFixture) -> Application:
mocker: MockerFixture) -> Application:
"""
application fixture with auth enabled
@ -150,7 +146,6 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa
user(User): user descriptor fixture
spawner(Spawn): spawner fixture
database(SQLite): database fixture
repository(Repository): repository fixture
mocker(MockerFixture): mocker object
Returns:
@ -159,11 +154,10 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa
configuration.set_option("auth", "target", "configuration")
configuration.set_option("web", "port", "8080")
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
mocker.patch("aiohttp_apispec.setup_aiohttp_apispec")
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", True)
_, repository_id = configuration.check_loaded()
application = setup_service(repository_id, configuration, spawner)
application = setup_server(configuration, spawner, [repository_id])
generated = user.hash_password(application["validator"].salt)
mocker.patch("ahriman.core.database.SQLite.user_get", return_value=generated)
@ -173,7 +167,7 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa
@pytest.fixture
def application_with_debug(configuration: Configuration, user: User, spawner: Spawn, database: SQLite,
repository: Repository, mocker: MockerFixture) -> Application:
mocker: MockerFixture) -> Application:
"""
application fixture with debug enabled
@ -182,7 +176,6 @@ def application_with_debug(configuration: Configuration, user: User, spawner: Sp
user(User): user descriptor fixture
spawner(Spawn): spawner fixture
database(SQLite): database fixture
repository(Repository): repository fixture
mocker(MockerFixture): mocker object
Returns:
@ -191,17 +184,16 @@ def application_with_debug(configuration: Configuration, user: User, spawner: Sp
configuration.set_option("web", "debug", "yes")
configuration.set_option("web", "port", "8080")
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
mocker.patch("aiohttp_apispec.setup_aiohttp_apispec")
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False)
_, repository_id = configuration.check_loaded()
return setup_service(repository_id, configuration, spawner)
return setup_server(configuration, spawner, [repository_id])
@pytest.fixture
def client(application: Application, event_loop: BaseEventLoop,
aiohttp_client: Any, mocker: MockerFixture) -> TestClient:
def client(application: Application, event_loop: BaseEventLoop, aiohttp_client: Any,
mocker: MockerFixture) -> TestClient:
"""
web client fixture
@ -219,8 +211,8 @@ def client(application: Application, event_loop: BaseEventLoop,
@pytest.fixture
def client_with_auth(application_with_auth: Application, event_loop: BaseEventLoop,
aiohttp_client: Any, mocker: MockerFixture) -> TestClient:
def client_with_auth(application_with_auth: Application, event_loop: BaseEventLoop, aiohttp_client: Any,
mocker: MockerFixture) -> TestClient:
"""
web client fixture with full authorization functions
@ -238,8 +230,8 @@ def client_with_auth(application_with_auth: Application, event_loop: BaseEventLo
@pytest.fixture
def client_with_oauth_auth(application_with_auth: Application, event_loop: BaseEventLoop,
aiohttp_client: Any, mocker: MockerFixture) -> TestClient:
def client_with_oauth_auth(application_with_auth: Application, event_loop: BaseEventLoop, aiohttp_client: Any,
mocker: MockerFixture) -> TestClient:
"""
web client fixture with full authorization functions

View File

@ -0,0 +1 @@
# schema testing goes in view class tests

View File

@ -5,10 +5,12 @@ from aiohttp.web import Application
from pytest_mock import MockerFixture
from unittest.mock import call as MockCall
from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import InitializeError
from ahriman.core.log.filtered_access_logger import FilteredAccessLogger
from ahriman.core.spawn import Spawn
from ahriman.core.status.watcher import Watcher
from ahriman.web.web import _create_socket, _on_shutdown, _on_startup, run_server
from ahriman.web.web import _create_socket, _on_shutdown, _on_startup, run_server, setup_server
async def test_create_socket(application: Application, mocker: MockerFixture) -> None:
@ -72,7 +74,7 @@ async def test_on_startup(application: Application, watcher: Watcher, mocker: Mo
"""
must call load method
"""
mocker.patch("aiohttp.web.Application.__getitem__", return_value=watcher)
mocker.patch("aiohttp.web.Application.__getitem__", return_value={"": watcher})
load_mock = mocker.patch("ahriman.core.status.watcher.Watcher.load")
await _on_startup(application)
@ -83,7 +85,7 @@ async def test_on_startup_exception(application: Application, watcher: Watcher,
"""
must throw exception on load error
"""
mocker.patch("aiohttp.web.Application.__getitem__", return_value=watcher)
mocker.patch("aiohttp.web.Application.__getitem__", return_value={"": watcher})
mocker.patch("ahriman.core.status.watcher.Watcher.load", side_effect=Exception())
with pytest.raises(InitializeError):
@ -151,3 +153,11 @@ def test_run_with_socket(application: Application, mocker: MockerFixture) -> Non
application, host="127.0.0.1", port=port, sock=42, handle_signals=True,
access_log=pytest.helpers.anyvar(int), access_log_class=FilteredAccessLogger
)
def test_setup_no_repositories(configuration: Configuration, spawner: Spawn) -> None:
"""
must raise InitializeError if no repositories set
"""
with pytest.raises(InitializeError):
setup_server(configuration, spawner, [])

View File

@ -2,10 +2,11 @@ import pytest
from multidict import MultiDict
from aiohttp.test_utils import TestClient
from aiohttp.web import HTTPBadRequest
from aiohttp.web import HTTPBadRequest, HTTPNotFound
from pytest_mock import MockerFixture
from unittest.mock import AsyncMock
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user_access import UserAccess
from ahriman.web.views.base import BaseView
@ -24,11 +25,18 @@ def test_configuration(base: BaseView) -> None:
assert base.configuration
def test_service(base: BaseView) -> None:
def test_services(base: BaseView) -> None:
"""
must return service
must return services
"""
assert base.service
assert base.services
def test_sign(base: BaseView) -> None:
"""
must return GPP wrapper instance
"""
assert base.sign
def test_spawn(base: BaseView) -> None:
@ -193,6 +201,53 @@ def test_page_bad_request(base: BaseView) -> None:
base.page()
def test_repository_id(base: BaseView, repository_id: RepositoryId) -> None:
"""
must repository identifier from parameters
"""
base._request = pytest.helpers.request(base.request.app, "", "",
params=MultiDict(architecture="i686", repository="repo"))
assert base.repository_id() == RepositoryId("i686", "repo")
base._request = pytest.helpers.request(base.request.app, "", "", params=MultiDict(architecture="i686"))
assert base.repository_id() == repository_id
base._request = pytest.helpers.request(base.request.app, "", "", params=MultiDict(repository="repo"))
assert base.repository_id() == repository_id
base._request = pytest.helpers.request(base.request.app, "", "", params=MultiDict())
assert base.repository_id() == repository_id
def test_service(base: BaseView) -> None:
"""
must return service for repository
"""
repository_id = RepositoryId("i686", "repo")
base.request.app["watcher"] = {
repository_id: watcher
for watcher in base.request.app["watcher"].values()
}
assert base.service(repository_id) == base.services[repository_id]
def test_service_auto(base: BaseView, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must return service for repository if no parameters set
"""
mocker.patch("ahriman.web.views.base.BaseView.repository_id", return_value=repository_id)
assert base.service() == base.services[repository_id]
def test_service_not_found(base: BaseView) -> None:
"""
must raise HTTPNotFound if no repository found
"""
with pytest.raises(HTTPNotFound):
base.service(RepositoryId("", ""))
async def test_username(base: BaseView, mocker: MockerFixture) -> None:
"""
must return identity of logged-in user

View File

@ -4,6 +4,7 @@ from aiohttp.test_utils import TestClient
from pytest_mock import MockerFixture
from unittest.mock import AsyncMock
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user_access import UserAccess
from ahriman.web.views.v1.service.add import AddView
@ -24,7 +25,7 @@ def test_routes() -> None:
assert AddView.ROUTES == ["/api/v1/service/add"]
async def test_post(client: TestClient, mocker: MockerFixture) -> None:
async def test_post(client: TestClient, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call post request correctly
"""
@ -39,7 +40,7 @@ async def test_post(client: TestClient, mocker: MockerFixture) -> None:
assert not request_schema.validate(payload)
response = await client.post("/api/v1/service/add", json=payload)
assert response.ok
add_mock.assert_called_once_with(["ahriman"], "username", now=True)
add_mock.assert_called_once_with(repository_id, ["ahriman"], "username", now=True)
json = await response.json()
assert json["process_id"] == "abc"

View File

@ -4,6 +4,7 @@ from aiohttp.test_utils import TestClient
from pytest_mock import MockerFixture
from unittest.mock import AsyncMock
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user_access import UserAccess
from ahriman.web.views.v1.service.rebuild import RebuildView
@ -24,7 +25,7 @@ def test_routes() -> None:
assert RebuildView.ROUTES == ["/api/v1/service/rebuild"]
async def test_post(client: TestClient, mocker: MockerFixture) -> None:
async def test_post(client: TestClient, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call post request correctly
"""
@ -39,7 +40,7 @@ async def test_post(client: TestClient, mocker: MockerFixture) -> None:
assert not request_schema.validate(payload)
response = await client.post("/api/v1/service/rebuild", json=payload)
assert response.ok
rebuild_mock.assert_called_once_with("python", "username")
rebuild_mock.assert_called_once_with(repository_id, "python", "username")
json = await response.json()
assert json["process_id"] == "abc"

View File

@ -3,6 +3,7 @@ import pytest
from aiohttp.test_utils import TestClient
from pytest_mock import MockerFixture
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user_access import UserAccess
from ahriman.web.views.v1.service.remove import RemoveView
@ -23,7 +24,7 @@ def test_routes() -> None:
assert RemoveView.ROUTES == ["/api/v1/service/remove"]
async def test_post(client: TestClient, mocker: MockerFixture) -> None:
async def test_post(client: TestClient, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call post request correctly
"""
@ -35,7 +36,7 @@ async def test_post(client: TestClient, mocker: MockerFixture) -> None:
assert not request_schema.validate(payload)
response = await client.post("/api/v1/service/remove", json=payload)
assert response.ok
remove_mock.assert_called_once_with(["ahriman"])
remove_mock.assert_called_once_with(repository_id, ["ahriman"])
json = await response.json()
assert json["process_id"] == "abc"

View File

@ -4,6 +4,7 @@ from aiohttp.test_utils import TestClient
from pytest_mock import MockerFixture
from unittest.mock import AsyncMock
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user_access import UserAccess
from ahriman.web.views.v1.service.request import RequestView
@ -24,7 +25,7 @@ def test_routes() -> None:
assert RequestView.ROUTES == ["/api/v1/service/request"]
async def test_post(client: TestClient, mocker: MockerFixture) -> None:
async def test_post(client: TestClient, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call post request correctly
"""
@ -39,7 +40,7 @@ async def test_post(client: TestClient, mocker: MockerFixture) -> None:
assert not request_schema.validate(payload)
response = await client.post("/api/v1/service/request", json=payload)
assert response.ok
add_mock.assert_called_once_with(["ahriman"], "username", now=False)
add_mock.assert_called_once_with(repository_id, ["ahriman"], "username", now=False)
json = await response.json()
assert json["process_id"] == "abc"

View File

@ -77,4 +77,4 @@ async def test_get_join(client: TestClient, mocker: MockerFixture) -> None:
assert not request_schema.validate(payload)
response = await client.get("/api/v1/service/search", params=payload)
assert response.ok
search_mock.assert_called_once_with("ahriman", "maybe", pacman=pytest.helpers.anyvar(int))
search_mock.assert_called_once_with("ahriman", "maybe")

View File

@ -4,6 +4,7 @@ from aiohttp.test_utils import TestClient
from pytest_mock import MockerFixture
from unittest.mock import AsyncMock
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user_access import UserAccess
from ahriman.web.views.v1.service.update import UpdateView
@ -24,7 +25,7 @@ def test_routes() -> None:
assert UpdateView.ROUTES == ["/api/v1/service/update"]
async def test_post(client: TestClient, mocker: MockerFixture) -> None:
async def test_post(client: TestClient, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must call post request correctly for alias
"""
@ -50,7 +51,7 @@ async def test_post(client: TestClient, mocker: MockerFixture) -> None:
assert not request_schema.validate(payload)
response = await client.post("/api/v1/service/update", json=payload)
assert response.ok
update_mock.assert_called_once_with("username", **(defaults | payload))
update_mock.assert_called_once_with(repository_id, "username", **(defaults | payload))
update_mock.reset_mock()
json = await response.json()

View File

@ -4,6 +4,7 @@ from aiohttp.test_utils import TestClient
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
from ahriman.models.package import Package
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user_access import UserAccess
from ahriman.web.views.v1.status.package import PackageView
@ -94,13 +95,17 @@ async def test_get_not_found(client: TestClient, package_ahriman: Package) -> No
assert not response_schema.validate(await response.json())
async def test_post(client: TestClient, package_ahriman: Package) -> None:
async def test_post(client: TestClient, package_ahriman: Package, repository_id: RepositoryId) -> None:
"""
must update package status
"""
request_schema = pytest.helpers.schema_request(PackageView.post)
payload = {"status": BuildStatusEnum.Success.value, "package": package_ahriman.view()}
payload = {
"status": BuildStatusEnum.Success.value,
"package": package_ahriman.view(),
"repository": repository_id.view(),
}
assert not request_schema.validate(payload)
response = await client.post(f"/api/v1/packages/{package_ahriman.base}", json=payload)
assert response.status == 204
@ -120,18 +125,25 @@ async def test_post_exception(client: TestClient, package_ahriman: Package) -> N
assert not response_schema.validate(await response.json())
async def test_post_light(client: TestClient, package_ahriman: Package) -> None:
async def test_post_light(client: TestClient, package_ahriman: Package, repository_id: RepositoryId) -> None:
"""
must update package status only
"""
request_schema = pytest.helpers.schema_request(PackageView.post)
payload = {"status": BuildStatusEnum.Unknown.value, "package": package_ahriman.view()}
payload = {
"status": BuildStatusEnum.Success.value,
"package": package_ahriman.view(),
"repository": repository_id.view(),
}
assert not request_schema.validate(payload)
response = await client.post(f"/api/v1/packages/{package_ahriman.base}", json=payload)
assert response.status == 204
payload = {"status": BuildStatusEnum.Success.value}
payload = {
"status": BuildStatusEnum.Success.value,
"repository": repository_id.view(),
}
assert not request_schema.validate(payload)
response = await client.post(f"/api/v1/packages/{package_ahriman.base}", json=payload)
assert response.status == 204
@ -145,14 +157,17 @@ async def test_post_light(client: TestClient, package_ahriman: Package) -> None:
assert statuses[package_ahriman.base].status == BuildStatusEnum.Success
async def test_post_not_found(client: TestClient, package_ahriman: Package) -> None:
async def test_post_not_found(client: TestClient, package_ahriman: Package, repository_id: RepositoryId) -> None:
"""
must raise exception on status update for unknown package
"""
request_schema = pytest.helpers.schema_request(PackageView.post)
response_schema = pytest.helpers.schema_response(PackageView.post, code=400)
payload = {"status": BuildStatusEnum.Success.value}
payload = {
"status": BuildStatusEnum.Success.value,
"repository": repository_id.view(),
}
assert not request_schema.validate(payload)
response = await client.post(f"/api/v1/packages/{package_ahriman.base}", json=payload)
assert response.status == 400

View File

@ -0,0 +1,37 @@
import pytest
from aiohttp.test_utils import TestClient
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user_access import UserAccess
from ahriman.web.views.v1.status.repositories import RepositoriesView
async def test_get_permission() -> None:
"""
must return correct permission for the request
"""
for method in ("GET",):
request = pytest.helpers.request("", "", method)
assert await RepositoriesView.get_permission(request) == UserAccess.Read
def test_routes() -> None:
"""
must return correct routes
"""
assert RepositoriesView.ROUTES == ["/api/v1/repositories"]
async def test_get(client: TestClient, repository_id: RepositoryId) -> None:
"""
must return status for specific package
"""
response_schema = pytest.helpers.schema_response(RepositoriesView.get)
response = await client.get(f"/api/v1/repositories")
assert response.ok
json = await response.json()
assert not response_schema.validate(json, many=True)
assert json == [repository_id.view()]