From 6514924b2d3b4a3e337cb94d76599f4a1ec34786 Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Thu, 14 Oct 2021 04:01:54 +0300 Subject: [PATCH] change method spelling in order to sort method correctly we are going to use the following namiing schema: {subject}_{action}_{details} This schema still have some exceptions, e.g. single word methods, bool methods (is_) and getters in case if they are singular (i.e. there is no any other method with this subject) --- src/ahriman/application/application.py | 2 +- src/ahriman/application/handlers/handler.py | 50 ++--- .../application/handlers/key_import.py | 2 +- src/ahriman/application/handlers/setup.py | 20 +- src/ahriman/application/handlers/user.py | 82 ++++---- src/ahriman/core/repository/executor.py | 2 +- src/ahriman/core/sign/gpg.py | 10 +- .../application/handlers/test_handler.py | 84 ++++---- .../handlers/test_handler_key_import.py | 2 +- .../handlers/test_handler_setup.py | 34 +-- .../application/handlers/test_handler_user.py | 198 +++++++++--------- tests/ahriman/application/test_application.py | 4 +- .../ahriman/core/repository/test_executor.py | 2 +- tests/ahriman/core/sign/test_gpg.py | 62 +++--- 14 files changed, 277 insertions(+), 277 deletions(-) diff --git a/src/ahriman/application/application.py b/src/ahriman/application/application.py index 1dcb2711..08a6e6cc 100644 --- a/src/ahriman/application/application.py +++ b/src/ahriman/application/application.py @@ -208,7 +208,7 @@ class Application: # run generic update function self.update([]) # sign repository database if set - self.repository.sign.sign_repository(self.repository.repo.repo_path) + self.repository.sign.process_sign_repository(self.repository.repo.repo_path) self._finalize([]) def sync(self, target: Iterable[str], built_packages: Iterable[Package]) -> None: diff --git a/src/ahriman/application/handlers/handler.py b/src/ahriman/application/handlers/handler.py index 6a38e87f..a749524e 100644 --- a/src/ahriman/application/handlers/handler.py +++ b/src/ahriman/application/handlers/handler.py @@ -41,6 +41,30 @@ class Handler: ALLOW_AUTO_ARCHITECTURE_RUN = True ALLOW_MULTI_ARCHITECTURE_RUN = True + @classmethod + def architectures_extract(cls: Type[Handler], args: argparse.Namespace) -> Set[str]: + """ + get known architectures + :param args: command line args + :return: list of architectures for which tree is created + """ + if not cls.ALLOW_AUTO_ARCHITECTURE_RUN and args.architecture is None: + # for some parsers (e.g. config) we need to run with specific architecture + # for those cases architecture must be set explicitly + raise MissingArchitecture(args.command) + if args.architecture: # architecture is specified explicitly + return set(args.architecture) + + config = Configuration() + config.load(args.configuration) + # wtf??? + root = config.getpath("repository", "root") # pylint: disable=assignment-from-no-return + architectures = RepositoryPaths.known_architectures(root) + + if not architectures: # well we did not find anything + raise MissingArchitecture(args.command) + return architectures + @classmethod def call(cls: Type[Handler], args: argparse.Namespace, architecture: str) -> bool: """ @@ -66,7 +90,7 @@ class Handler: :param args: command line args :return: 0 on success, 1 otherwise """ - architectures = cls.extract_architectures(args) + architectures = cls.architectures_extract(args) # actually we do not have to spawn another process if it is single-process application, do we? if len(architectures) > 1: @@ -81,30 +105,6 @@ class Handler: return 0 if all(result) else 1 - @classmethod - def extract_architectures(cls: Type[Handler], args: argparse.Namespace) -> Set[str]: - """ - get known architectures - :param args: command line args - :return: list of architectures for which tree is created - """ - if not cls.ALLOW_AUTO_ARCHITECTURE_RUN and args.architecture is None: - # for some parsers (e.g. config) we need to run with specific architecture - # for those cases architecture must be set explicitly - raise MissingArchitecture(args.command) - if args.architecture: # architecture is specified explicitly - return set(args.architecture) - - config = Configuration() - config.load(args.configuration) - # wtf??? - root = config.getpath("repository", "root") # pylint: disable=assignment-from-no-return - architectures = RepositoryPaths.known_architectures(root) - - if not architectures: # well we did not find anything - raise MissingArchitecture(args.command) - return architectures - @classmethod def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, no_report: bool) -> None: diff --git a/src/ahriman/application/handlers/key_import.py b/src/ahriman/application/handlers/key_import.py index 03644480..9aa343e5 100644 --- a/src/ahriman/application/handlers/key_import.py +++ b/src/ahriman/application/handlers/key_import.py @@ -43,4 +43,4 @@ class KeyImport(Handler): :param configuration: configuration instance :param no_report: force disable reporting """ - Application(architecture, configuration, no_report).repository.sign.import_key(args.key_server, args.key) + Application(architecture, configuration, no_report).repository.sign.key_import(args.key_server, args.key) diff --git a/src/ahriman/application/handlers/setup.py b/src/ahriman/application/handlers/setup.py index d8e7c709..89d0aa1b 100644 --- a/src/ahriman/application/handlers/setup.py +++ b/src/ahriman/application/handlers/setup.py @@ -55,12 +55,12 @@ class Setup(Handler): :param no_report: force disable reporting """ application = Application(architecture, configuration, no_report) - Setup.create_makepkg_configuration(args.packager, application.repository.paths) - Setup.create_executable(args.build_command, architecture) - Setup.create_devtools_configuration(args.build_command, architecture, args.from_configuration, + Setup.configuration_create_makepkg(args.packager, application.repository.paths) + Setup.executable_create(args.build_command, architecture) + Setup.configuration_create_devtools(args.build_command, architecture, args.from_configuration, args.no_multilib, args.repository, application.repository.paths) - Setup.create_ahriman_configuration(args, architecture, args.repository, configuration.include) - Setup.create_sudo_configuration(args.build_command, architecture) + Setup.configuration_create_ahriman(args, architecture, args.repository, configuration.include) + Setup.configuration_create_sudo(args.build_command, architecture) @staticmethod def build_command(prefix: str, architecture: str) -> Path: @@ -73,7 +73,7 @@ class Setup(Handler): return Setup.BIN_DIR_PATH / f"{prefix}-{architecture}-build" @staticmethod - def create_ahriman_configuration(args: argparse.Namespace, architecture: str, repository: str, + def configuration_create_ahriman(args: argparse.Namespace, architecture: str, repository: str, include_path: Path) -> None: """ create service specific configuration @@ -102,7 +102,7 @@ class Setup(Handler): configuration.write(ahriman_configuration) @staticmethod - def create_devtools_configuration(prefix: str, architecture: str, source: Path, + def configuration_create_devtools(prefix: str, architecture: str, source: Path, no_multilib: bool, repository: str, paths: RepositoryPaths) -> None: """ create configuration for devtools based on `source` configuration @@ -138,7 +138,7 @@ class Setup(Handler): configuration.write(devtools_configuration) @staticmethod - def create_makepkg_configuration(packager: str, paths: RepositoryPaths) -> None: + def configuration_create_makepkg(packager: str, paths: RepositoryPaths) -> None: """ create configuration for makepkg :param packager: packager identifier (e.g. name, email) @@ -147,7 +147,7 @@ class Setup(Handler): (paths.root / ".makepkg.conf").write_text(f"PACKAGER='{packager}'\n") @staticmethod - def create_sudo_configuration(prefix: str, architecture: str) -> None: + def configuration_create_sudo(prefix: str, architecture: str) -> None: """ create configuration to run build command with sudo without password :param prefix: command prefix in {prefix}-{architecture}-build @@ -158,7 +158,7 @@ class Setup(Handler): Setup.SUDOERS_PATH.chmod(0o400) # security! @staticmethod - def create_executable(prefix: str, architecture: str) -> None: + def executable_create(prefix: str, architecture: str) -> None: """ create executable for the service :param prefix: command prefix in {prefix}-{architecture}-build diff --git a/src/ahriman/application/handlers/user.py b/src/ahriman/application/handlers/user.py index 97246de6..c1768624 100644 --- a/src/ahriman/application/handlers/user.py +++ b/src/ahriman/application/handlers/user.py @@ -49,33 +49,20 @@ class User(Handler): :param no_report: force disable reporting """ salt = User.get_salt(configuration) - user = User.create_user(args) - auth_configuration = User.get_auth_configuration(configuration.include) + user = User.user_create(args) + auth_configuration = User.configuration_get(configuration.include) - User.clear_user(auth_configuration, user) + User.user_clear(auth_configuration, user) if args.action == Action.Update: - User.create_configuration(auth_configuration, user, salt, args.as_service) - User.write_configuration(auth_configuration, args.secure) + User.configuration_create(auth_configuration, user, salt, args.as_service) + User.configuration_write(auth_configuration, args.secure) if not args.no_reload: client = Application(architecture, configuration, no_report=False).repository.reporter client.reload_auth() @staticmethod - def clear_user(configuration: Configuration, user: MUser) -> None: - """ - remove user user from configuration file in case if it exists - :param configuration: configuration instance - :param user: user descriptor - """ - for role in UserAccess: - section = Configuration.section_name("auth", role.value) - if not configuration.has_option(section, user.username): - continue - configuration.remove_option(section, user.username) - - @staticmethod - def create_configuration(configuration: Configuration, user: MUser, salt: str, as_service_user: bool) -> None: + def configuration_create(configuration: Configuration, user: MUser, salt: str, as_service_user: bool) -> None: """ put new user to configuration :param configuration: configuration instance @@ -92,19 +79,7 @@ class User(Handler): configuration.set_option("web", "password", user.password) @staticmethod - def create_user(args: argparse.Namespace) -> MUser: - """ - create user descriptor from arguments - :param args: command line args - :return: built user descriptor - """ - user = MUser(args.username, args.password, args.role) - if user.password is None: - user.password = getpass.getpass() - return user - - @staticmethod - def get_auth_configuration(include_path: Path) -> Configuration: + def configuration_get(include_path: Path) -> Configuration: """ create configuration instance :param include_path: path to directory with configuration includes @@ -116,6 +91,20 @@ class User(Handler): return configuration + @staticmethod + def configuration_write(configuration: Configuration, secure: bool) -> None: + """ + write configuration file + :param configuration: configuration instance + :param secure: if true then set file permissions to 0o600 + """ + if configuration.path is None: + return # should never happen actually + with configuration.path.open("w") as ahriman_configuration: + configuration.write(ahriman_configuration) + if secure: + configuration.path.chmod(0o600) + @staticmethod def get_salt(configuration: Configuration, salt_length: int = 20) -> str: """ @@ -130,15 +119,26 @@ class User(Handler): return MUser.generate_password(salt_length) @staticmethod - def write_configuration(configuration: Configuration, secure: bool) -> None: + def user_clear(configuration: Configuration, user: MUser) -> None: """ - write configuration file + remove user user from configuration file in case if it exists :param configuration: configuration instance - :param secure: if true then set file permissions to 0o600 + :param user: user descriptor """ - if configuration.path is None: - return # should never happen actually - with configuration.path.open("w") as ahriman_configuration: - configuration.write(ahriman_configuration) - if secure: - configuration.path.chmod(0o600) + for role in UserAccess: + section = Configuration.section_name("auth", role.value) + if not configuration.has_option(section, user.username): + continue + configuration.remove_option(section, user.username) + + @staticmethod + def user_create(args: argparse.Namespace) -> MUser: + """ + create user descriptor from arguments + :param args: command line args + :return: built user descriptor + """ + user = MUser(args.username, args.password, args.role) + if user.password is None: + user.password = getpass.getpass() + return user diff --git a/src/ahriman/core/repository/executor.py b/src/ahriman/core/repository/executor.py index c698743d..ac67c399 100644 --- a/src/ahriman/core/repository/executor.py +++ b/src/ahriman/core/repository/executor.py @@ -144,7 +144,7 @@ class Executor(Cleaner): return # suppress type checking, it never can be none actually # in theory it might be NOT packages directory, but we suppose it is full_path = self.paths.packages / fn - files = self.sign.sign_package(full_path, base) + files = self.sign.process_sign_package(full_path, base) for src in files: dst = self.paths.repository / src.name shutil.move(src, dst) diff --git a/src/ahriman/core/sign/gpg.py b/src/ahriman/core/sign/gpg.py index 6aa444b6..746b764f 100644 --- a/src/ahriman/core/sign/gpg.py +++ b/src/ahriman/core/sign/gpg.py @@ -88,7 +88,7 @@ class GPG: default_key = configuration.get("sign", "key") if targets else None return targets, default_key - def download_key(self, server: str, key: str) -> str: + def key_download(self, server: str, key: str) -> str: """ download key from public PGP server :param server: public PGP server which will be used to download the key @@ -108,13 +108,13 @@ class GPG: raise return response.text - def import_key(self, server: str, key: str) -> None: + def key_import(self, server: str, key: str) -> None: """ import key to current user and sign it locally :param server: public PGP server which will be used to download the key :param key: key ID to import """ - key_body = self.download_key(server, key) + key_body = self.key_download(server, key) GPG._check_output("gpg", "--import", input_data=key_body, exception=None, logger=self.logger) GPG._check_output("gpg", "--quick-lsign-key", key, exception=None, logger=self.logger) @@ -131,7 +131,7 @@ class GPG: logger=self.logger) return [path, path.parent / f"{path.name}.sig"] - def sign_package(self, path: Path, base: str) -> List[Path]: + def process_sign_package(self, path: Path, base: str) -> List[Path]: """ sign package if required by configuration :param path: path to file to sign @@ -146,7 +146,7 @@ class GPG: return [path] return self.process(path, key) - def sign_repository(self, path: Path) -> List[Path]: + def process_sign_repository(self, path: Path) -> List[Path]: """ sign repository if required by configuration :note: more likely you just want to pass `repository_sign_args` to repo wrapper diff --git a/tests/ahriman/application/handlers/test_handler.py b/tests/ahriman/application/handlers/test_handler.py index 00820b78..7fbdf4a1 100644 --- a/tests/ahriman/application/handlers/test_handler.py +++ b/tests/ahriman/application/handlers/test_handler.py @@ -9,6 +9,48 @@ from ahriman.core.configuration import Configuration from ahriman.core.exceptions import MissingArchitecture, MultipleArchitecture +def test_architectures_extract(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: + """ + must generate list of available architectures + """ + args.configuration = configuration.path + known_architectures_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures") + + Handler.architectures_extract(args) + known_architectures_mock.assert_called_once() + + +def test_architectures_extract_empty(args: argparse.Namespace, configuration: Configuration, + mocker: MockerFixture) -> None: + """ + must raise exception if no available architectures found + """ + args.command = "config" + args.configuration = configuration.path + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures", return_value=set()) + + with pytest.raises(MissingArchitecture): + Handler.architectures_extract(args) + + +def test_architectures_extract_exception(args: argparse.Namespace, mocker: MockerFixture) -> None: + """ + must raise exception on missing architectures + """ + args.command = "config" + mocker.patch.object(Handler, "ALLOW_AUTO_ARCHITECTURE_RUN", False) + with pytest.raises(MissingArchitecture): + Handler.architectures_extract(args) + + +def test_architectures_extract_specified(args: argparse.Namespace) -> None: + """ + must return architecture list if it has been specified + """ + architectures = args.architecture = ["i686", "x86_64"] + assert Handler.architectures_extract(args) == set(architectures) + + def test_call(args: argparse.Namespace, mocker: MockerFixture) -> None: """ must call inside lock @@ -67,48 +109,6 @@ def test_execute_single(args: argparse.Namespace, mocker: MockerFixture) -> None starmap_mock.assert_not_called() -def test_extract_architectures(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: - """ - must generate list of available architectures - """ - args.configuration = configuration.path - known_architectures_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures") - - Handler.extract_architectures(args) - known_architectures_mock.assert_called_once() - - -def test_extract_architectures_empty(args: argparse.Namespace, configuration: Configuration, - mocker: MockerFixture) -> None: - """ - must raise exception if no available architectures found - """ - args.command = "config" - args.configuration = configuration.path - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures", return_value=set()) - - with pytest.raises(MissingArchitecture): - Handler.extract_architectures(args) - - -def test_extract_architectures_exception(args: argparse.Namespace, mocker: MockerFixture) -> None: - """ - must raise exception on missing architectures - """ - args.command = "config" - mocker.patch.object(Handler, "ALLOW_AUTO_ARCHITECTURE_RUN", False) - with pytest.raises(MissingArchitecture): - Handler.extract_architectures(args) - - -def test_extract_architectures_specified(args: argparse.Namespace) -> None: - """ - must return architecture list if it has been specified - """ - architectures = args.architecture = ["i686", "x86_64"] - assert Handler.extract_architectures(args) == set(architectures) - - def test_run(args: argparse.Namespace, configuration: Configuration) -> None: """ must raise NotImplemented for missing method diff --git a/tests/ahriman/application/handlers/test_handler_key_import.py b/tests/ahriman/application/handlers/test_handler_key_import.py index 4b75b734..5cde92c6 100644 --- a/tests/ahriman/application/handlers/test_handler_key_import.py +++ b/tests/ahriman/application/handlers/test_handler_key_import.py @@ -23,7 +23,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc """ args = _default_args(args) mocker.patch("pathlib.Path.mkdir") - application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.import_key") + application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_import") KeyImport.run(args, "x86_64", configuration, True) application_mock.assert_called_once() diff --git a/tests/ahriman/application/handlers/test_handler_setup.py b/tests/ahriman/application/handlers/test_handler_setup.py index 4db81edc..76dd923b 100644 --- a/tests/ahriman/application/handlers/test_handler_setup.py +++ b/tests/ahriman/application/handlers/test_handler_setup.py @@ -33,11 +33,11 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc """ args = _default_args(args) mocker.patch("pathlib.Path.mkdir") - ahriman_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_ahriman_configuration") - devtools_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_devtools_configuration") - makepkg_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_makepkg_configuration") - sudo_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_sudo_configuration") - executable_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_executable") + ahriman_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_ahriman") + devtools_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_devtools") + makepkg_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_makepkg") + sudo_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_sudo") + executable_mock = mocker.patch("ahriman.application.handlers.setup.Setup.executable_create") Setup.run(args, "x86_64", configuration, True) ahriman_configuration_mock.assert_called_once() @@ -55,7 +55,7 @@ def test_build_command(args: argparse.Namespace) -> None: assert Setup.build_command(args.build_command, "x86_64").name == f"{args.build_command}-x86_64-build" -def test_create_ahriman_configuration(args: argparse.Namespace, configuration: Configuration, +def test_configuration_create_ahriman(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: """ must create configuration for the service @@ -66,7 +66,7 @@ def test_create_ahriman_configuration(args: argparse.Namespace, configuration: C write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") command = Setup.build_command(args.build_command, "x86_64") - Setup.create_ahriman_configuration(args, "x86_64", args.repository, configuration.include) + Setup.configuration_create_ahriman(args, "x86_64", args.repository, configuration.include) set_option_mock.assert_has_calls([ mock.call(Configuration.section_name("build", "x86_64"), "build_command", str(command)), mock.call("repository", "name", args.repository), @@ -78,7 +78,7 @@ def test_create_ahriman_configuration(args: argparse.Namespace, configuration: C write_mock.assert_called_once() -def test_create_devtools_configuration(args: argparse.Namespace, repository_paths: RepositoryPaths, +def test_configuration_create_devtools(args: argparse.Namespace, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None: """ must create configuration for the devtools @@ -89,7 +89,7 @@ def test_create_devtools_configuration(args: argparse.Namespace, repository_path add_section_mock = mocker.patch("ahriman.core.configuration.Configuration.add_section") write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") - Setup.create_devtools_configuration(args.build_command, "x86_64", args.from_configuration, + Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration, args.no_multilib, args.repository, repository_paths) add_section_mock.assert_has_calls([ mock.call("multilib"), @@ -98,7 +98,7 @@ def test_create_devtools_configuration(args: argparse.Namespace, repository_path write_mock.assert_called_once() -def test_create_devtools_configuration_no_multilib(args: argparse.Namespace, repository_paths: RepositoryPaths, +def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None: """ must create configuration for the devtools without multilib @@ -108,12 +108,12 @@ def test_create_devtools_configuration_no_multilib(args: argparse.Namespace, rep mocker.patch("ahriman.core.configuration.Configuration.set") write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") - Setup.create_devtools_configuration(args.build_command, "x86_64", args.from_configuration, + Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration, True, args.repository, repository_paths) write_mock.assert_called_once() -def test_create_makepkg_configuration(args: argparse.Namespace, repository_paths: RepositoryPaths, +def test_configuration_create_makepkg(args: argparse.Namespace, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None: """ must create makepkg configuration @@ -121,11 +121,11 @@ def test_create_makepkg_configuration(args: argparse.Namespace, repository_paths args = _default_args(args) write_text_mock = mocker.patch("pathlib.Path.write_text") - Setup.create_makepkg_configuration(args.packager, repository_paths) + Setup.configuration_create_makepkg(args.packager, repository_paths) write_text_mock.assert_called_once() -def test_create_sudo_configuration(args: argparse.Namespace, mocker: MockerFixture) -> None: +def test_configuration_create_sudo(args: argparse.Namespace, mocker: MockerFixture) -> None: """ must create sudo configuration """ @@ -133,12 +133,12 @@ def test_create_sudo_configuration(args: argparse.Namespace, mocker: MockerFixtu chmod_text_mock = mocker.patch("pathlib.Path.chmod") write_text_mock = mocker.patch("pathlib.Path.write_text") - Setup.create_sudo_configuration(args.build_command, "x86_64") + Setup.configuration_create_sudo(args.build_command, "x86_64") chmod_text_mock.assert_called_once_with(0o400) write_text_mock.assert_called_once() -def test_create_executable(args: argparse.Namespace, mocker: MockerFixture) -> None: +def test_executable_create(args: argparse.Namespace, mocker: MockerFixture) -> None: """ must create executable """ @@ -146,7 +146,7 @@ def test_create_executable(args: argparse.Namespace, mocker: MockerFixture) -> N symlink_text_mock = mocker.patch("pathlib.Path.symlink_to") unlink_text_mock = mocker.patch("pathlib.Path.unlink") - Setup.create_executable(args.build_command, "x86_64") + Setup.executable_create(args.build_command, "x86_64") symlink_text_mock.assert_called_once() unlink_text_mock.assert_called_once() diff --git a/tests/ahriman/application/handlers/test_handler_user.py b/tests/ahriman/application/handlers/test_handler_user.py index 1c67c2aa..8bb214d4 100644 --- a/tests/ahriman/application/handlers/test_handler_user.py +++ b/tests/ahriman/application/handlers/test_handler_user.py @@ -34,17 +34,17 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc """ args = _default_args(args) mocker.patch("pathlib.Path.mkdir") - get_auth_configuration_mock = mocker.patch("ahriman.application.handlers.User.get_auth_configuration") - create_configuration_mock = mocker.patch("ahriman.application.handlers.User.create_configuration") - write_configuration_mock = mocker.patch("ahriman.application.handlers.User.write_configuration") - create_user = mocker.patch("ahriman.application.handlers.User.create_user") + get_auth_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_get") + create_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_create") + write_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_write") + create_user_mock = mocker.patch("ahriman.application.handlers.User.user_create") get_salt_mock = mocker.patch("ahriman.application.handlers.User.get_salt") reload_mock = mocker.patch("ahriman.core.status.client.Client.reload_auth") User.run(args, "x86_64", configuration, True) get_auth_configuration_mock.assert_called_once() create_configuration_mock.assert_called_once() - create_user.assert_called_once() + create_user_mock.assert_called_once() get_salt_mock.assert_called_once() write_configuration_mock.assert_called_once() reload_mock.assert_called_once() @@ -57,9 +57,9 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, mock args = _default_args(args) args.action = Action.Remove mocker.patch("pathlib.Path.mkdir") - get_auth_configuration_mock = mocker.patch("ahriman.application.handlers.User.get_auth_configuration") - create_configuration_mock = mocker.patch("ahriman.application.handlers.User.create_configuration") - write_configuration_mock = mocker.patch("ahriman.application.handlers.User.write_configuration") + get_auth_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_get") + create_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_create") + write_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_write") reload_mock = mocker.patch("ahriman.core.status.client.Client.reload_auth") User.run(args, "x86_64", configuration, True) @@ -75,41 +75,16 @@ def test_run_no_reload(args: argparse.Namespace, configuration: Configuration, m """ args = _default_args(args) args.no_reload = True - mocker.patch("ahriman.application.handlers.User.get_auth_configuration") - mocker.patch("ahriman.application.handlers.User.create_configuration") - mocker.patch("ahriman.application.handlers.User.write_configuration") + mocker.patch("ahriman.application.handlers.User.configuration_get") + mocker.patch("ahriman.application.handlers.User.configuration_create") + mocker.patch("ahriman.application.handlers.User.configuration_write") reload_mock = mocker.patch("ahriman.core.status.client.Client.reload_auth") User.run(args, "x86_64", configuration, True) reload_mock.assert_not_called() -def test_clear_user(configuration: Configuration, user: MUser) -> None: - """ - must clear user from configuration - """ - section = Configuration.section_name("auth", user.access.value) - configuration.set_option(section, user.username, user.password) - - User.clear_user(configuration, user) - assert configuration.get(section, user.username, fallback=None) is None - - -def test_clear_user_multiple_sections(configuration: Configuration, user: MUser) -> None: - """ - must clear user from configuration from all sections - """ - for role in UserAccess: - section = Configuration.section_name("auth", role.value) - configuration.set_option(section, user.username, user.password) - - User.clear_user(configuration, user) - for role in UserAccess: - section = Configuration.section_name("auth", role.value) - assert configuration.get(section, user.username, fallback=None) is None - - -def test_create_configuration(configuration: Configuration, user: MUser, mocker: MockerFixture) -> None: +def test_configuration_create(configuration: Configuration, user: MUser, mocker: MockerFixture) -> None: """ must correctly create configuration file """ @@ -117,14 +92,14 @@ def test_create_configuration(configuration: Configuration, user: MUser, mocker: mocker.patch("pathlib.Path.open") set_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option") - User.create_configuration(configuration, user, "salt", False) + User.configuration_create(configuration, user, "salt", False) set_mock.assert_has_calls([ mock.call("auth", "salt", pytest.helpers.anyvar(str)), mock.call(section, user.username, pytest.helpers.anyvar(str)) ]) -def test_create_configuration_user_exists(configuration: Configuration, user: MUser, mocker: MockerFixture) -> None: +def test_configuration_create_user_exists(configuration: Configuration, user: MUser, mocker: MockerFixture) -> None: """ must correctly update configuration file if user already exists """ @@ -132,12 +107,12 @@ def test_create_configuration_user_exists(configuration: Configuration, user: MU configuration.set_option(section, user.username, "") mocker.patch("pathlib.Path.open") - User.create_configuration(configuration, user, "salt", False) + User.configuration_create(configuration, user, "salt", False) generated = MUser.from_option(user.username, configuration.get(section, user.username)) assert generated.check_credentials(user.password, configuration.get("auth", "salt")) -def test_create_configuration_with_plain_password( +def test_configuration_create_with_plain_password( configuration: Configuration, user: MUser, mocker: MockerFixture) -> None: @@ -147,7 +122,7 @@ def test_create_configuration_with_plain_password( section = Configuration.section_name("auth", user.access.value) mocker.patch("pathlib.Path.open") - User.create_configuration(configuration, user, "salt", True) + User.configuration_create(configuration, user, "salt", True) generated = MUser.from_option(user.username, configuration.get(section, user.username)) service = MUser.from_option(configuration.get("web", "username"), configuration.get("web", "password")) @@ -155,28 +130,67 @@ def test_create_configuration_with_plain_password( assert generated.check_credentials(service.password, configuration.get("auth", "salt")) -def test_create_user(args: argparse.Namespace, user: MUser) -> None: +def test_configuration_get_exists(mocker: MockerFixture) -> None: """ - must create user + must load configuration from filesystem """ - args = _default_args(args) - generated = User.create_user(args) - assert generated.username == user.username - assert generated.access == user.access + mocker.patch("pathlib.Path.open") + mocker.patch("pathlib.Path.is_file", return_value=True) + read_mock = mocker.patch("ahriman.core.configuration.Configuration.read") + + assert User.configuration_get(Path("path")) + read_mock.assert_called_once() -def test_create_user_getpass(args: argparse.Namespace, mocker: MockerFixture) -> None: +def test_configuration_get_not_exists(mocker: MockerFixture) -> None: """ - must create user and get password from command line + must try to load configuration from filesystem """ - args = _default_args(args) - args.password = None + mocker.patch("pathlib.Path.open") + mocker.patch("pathlib.Path.is_file", return_value=False) + read_mock = mocker.patch("ahriman.core.configuration.Configuration.read") - getpass_mock = mocker.patch("getpass.getpass", return_value="password") - generated = User.create_user(args) + assert User.configuration_get(Path("path")) + read_mock.assert_called_once() - getpass_mock.assert_called_once() - assert generated.password == "password" + +def test_configuration_write(configuration: Configuration, mocker: MockerFixture) -> None: + """ + must write configuration + """ + mocker.patch("pathlib.Path.open") + write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") + chmod_mock = mocker.patch("pathlib.Path.chmod") + + User.configuration_write(configuration, secure=True) + write_mock.assert_called_once() + chmod_mock.assert_called_once() + + +def test_configuration_write_insecure(configuration: Configuration, mocker: MockerFixture) -> None: + """ + must write configuration without setting file permissions + """ + mocker.patch("pathlib.Path.open") + mocker.patch("ahriman.core.configuration.Configuration.write") + chmod_mock = mocker.patch("pathlib.Path.chmod") + + User.configuration_write(configuration, secure=False) + chmod_mock.assert_not_called() + + +def test_configuration_write_not_loaded(configuration: Configuration, mocker: MockerFixture) -> None: + """ + must do nothing in case if configuration is not loaded + """ + configuration.path = None + mocker.patch("pathlib.Path.open") + write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") + chmod_mock = mocker.patch("pathlib.Path.chmod") + + User.configuration_write(configuration, secure=True) + write_mock.assert_not_called() + chmod_mock.assert_not_called() def test_get_salt_read(configuration: Configuration) -> None: @@ -197,67 +211,53 @@ def test_get_salt_generate(configuration: Configuration) -> None: assert len(salt) == 16 -def test_get_auth_configuration_exists(mocker: MockerFixture) -> None: +def test_user_clear(configuration: Configuration, user: MUser) -> None: """ - must load configuration from filesystem + must clear user from configuration """ - mocker.patch("pathlib.Path.open") - mocker.patch("pathlib.Path.is_file", return_value=True) - read_mock = mocker.patch("ahriman.core.configuration.Configuration.read") + section = Configuration.section_name("auth", user.access.value) + configuration.set_option(section, user.username, user.password) - assert User.get_auth_configuration(Path("path")) - read_mock.assert_called_once() + User.user_clear(configuration, user) + assert configuration.get(section, user.username, fallback=None) is None -def test_get_auth_configuration_not_exists(mocker: MockerFixture) -> None: +def test_user_clear_multiple_sections(configuration: Configuration, user: MUser) -> None: """ - must try to load configuration from filesystem + must clear user from configuration from all sections """ - mocker.patch("pathlib.Path.open") - mocker.patch("pathlib.Path.is_file", return_value=False) - read_mock = mocker.patch("ahriman.core.configuration.Configuration.read") + for role in UserAccess: + section = Configuration.section_name("auth", role.value) + configuration.set_option(section, user.username, user.password) - assert User.get_auth_configuration(Path("path")) - read_mock.assert_called_once() + User.user_clear(configuration, user) + for role in UserAccess: + section = Configuration.section_name("auth", role.value) + assert configuration.get(section, user.username, fallback=None) is None -def test_write_configuration(configuration: Configuration, mocker: MockerFixture) -> None: +def test_user_create(args: argparse.Namespace, user: MUser) -> None: """ - must write configuration + must create user """ - mocker.patch("pathlib.Path.open") - write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") - chmod_mock = mocker.patch("pathlib.Path.chmod") - - User.write_configuration(configuration, secure=True) - write_mock.assert_called_once() - chmod_mock.assert_called_once() + args = _default_args(args) + generated = User.user_create(args) + assert generated.username == user.username + assert generated.access == user.access -def test_write_configuration_insecure(configuration: Configuration, mocker: MockerFixture) -> None: +def test_user_create_getpass(args: argparse.Namespace, mocker: MockerFixture) -> None: """ - must write configuration without setting file permissions + must create user and get password from command line """ - mocker.patch("pathlib.Path.open") - mocker.patch("ahriman.core.configuration.Configuration.write") - chmod_mock = mocker.patch("pathlib.Path.chmod") + args = _default_args(args) + args.password = None - User.write_configuration(configuration, secure=False) - chmod_mock.assert_not_called() + getpass_mock = mocker.patch("getpass.getpass", return_value="password") + generated = User.user_create(args) - -def test_write_configuration_not_loaded(configuration: Configuration, mocker: MockerFixture) -> None: - """ - must do nothing in case if configuration is not loaded - """ - configuration.path = None - mocker.patch("pathlib.Path.open") - write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") - chmod_mock = mocker.patch("pathlib.Path.chmod") - - User.write_configuration(configuration, secure=True) - write_mock.assert_not_called() - chmod_mock.assert_not_called() + getpass_mock.assert_called_once() + assert generated.password == "password" def test_disallow_auto_architecture_run() -> None: diff --git a/tests/ahriman/application/test_application.py b/tests/ahriman/application/test_application.py index d9f25ae0..13917017 100644 --- a/tests/ahriman/application/test_application.py +++ b/tests/ahriman/application/test_application.py @@ -263,7 +263,7 @@ def test_sign(application: Application, package_ahriman: Package, package_python return_value=[package_ahriman, package_python_schedule]) copy_mock = mocker.patch("shutil.copy") update_mock = mocker.patch("ahriman.application.application.Application.update") - sign_repository_mock = mocker.patch("ahriman.core.sign.gpg.GPG.sign_repository") + sign_repository_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process_sign_repository") finalize_mock = mocker.patch("ahriman.application.application.Application._finalize") application.sign([]) @@ -296,7 +296,7 @@ def test_sign_specific(application: Application, package_ahriman: Package, packa return_value=[package_ahriman, package_python_schedule]) copy_mock = mocker.patch("shutil.copy") update_mock = mocker.patch("ahriman.application.application.Application.update") - sign_repository_mock = mocker.patch("ahriman.core.sign.gpg.GPG.sign_repository") + sign_repository_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process_sign_repository") finalize_mock = mocker.patch("ahriman.application.application.Application._finalize") application.sign([package_ahriman.base]) diff --git a/tests/ahriman/core/repository/test_executor.py b/tests/ahriman/core/repository/test_executor.py index b9b48c89..70df7403 100644 --- a/tests/ahriman/core/repository/test_executor.py +++ b/tests/ahriman/core/repository/test_executor.py @@ -185,7 +185,7 @@ def test_process_update(executor: Executor, package_ahriman: Package, mocker: Mo mocker.patch("ahriman.models.package.Package.load", return_value=package_ahriman) move_mock = mocker.patch("shutil.move") repo_add_mock = mocker.patch("ahriman.core.alpm.repo.Repo.add") - sign_package_mock = mocker.patch("ahriman.core.sign.gpg.GPG.sign_package", side_effect=lambda fn, _: [fn]) + sign_package_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process_sign_package", side_effect=lambda fn, _: [fn]) status_client_mock = mocker.patch("ahriman.core.status.client.Client.set_success") # must return complete diff --git a/tests/ahriman/core/sign/test_gpg.py b/tests/ahriman/core/sign/test_gpg.py index 11a5496f..66cabada 100644 --- a/tests/ahriman/core/sign/test_gpg.py +++ b/tests/ahriman/core/sign/test_gpg.py @@ -64,32 +64,32 @@ def test_sign_command(gpg_with_key: GPG) -> None: assert gpg_with_key.sign_command(Path("a"), gpg_with_key.default_key) -def test_download_key(gpg: GPG, mocker: MockerFixture) -> None: +def test_key_download(gpg: GPG, mocker: MockerFixture) -> None: """ must download the key from public server """ requests_mock = mocker.patch("requests.get") - gpg.download_key("pgp.mit.edu", "0xE989490C") + gpg.key_download("pgp.mit.edu", "0xE989490C") requests_mock.assert_called_once() -def test_download_key_failure(gpg: GPG, mocker: MockerFixture) -> None: +def test_key_download_failure(gpg: GPG, mocker: MockerFixture) -> None: """ must download the key from public server and log error if any (and raise it again) """ mocker.patch("requests.get", side_effect=requests.exceptions.HTTPError()) with pytest.raises(requests.exceptions.HTTPError): - gpg.download_key("pgp.mit.edu", "0xE989490C") + gpg.key_download("pgp.mit.edu", "0xE989490C") -def test_import_key(gpg: GPG, mocker: MockerFixture) -> None: +def test_key_import(gpg: GPG, mocker: MockerFixture) -> None: """ must import PGP key from the server """ - mocker.patch("ahriman.core.sign.gpg.GPG.download_key", return_value="key") + mocker.patch("ahriman.core.sign.gpg.GPG.key_download", return_value="key") check_output_mock = mocker.patch("ahriman.core.sign.gpg.GPG._check_output") - gpg.import_key("pgp.mit.edu", "0xE989490C") + gpg.key_import("pgp.mit.edu", "0xE989490C") check_output_mock.assert_has_calls([ mock.call("gpg", "--import", input_data="key", exception=None, logger=pytest.helpers.anyvar(int)), mock.call("gpg", "--quick-lsign-key", "0xE989490C", exception=None, logger=pytest.helpers.anyvar(int)) @@ -107,7 +107,7 @@ def test_process(gpg_with_key: GPG, mocker: MockerFixture) -> None: check_output_mock.assert_called() -def test_sign_package_1(gpg_with_key: GPG, mocker: MockerFixture) -> None: +def test_process_sign_package_1(gpg_with_key: GPG, mocker: MockerFixture) -> None: """ must sign package """ @@ -115,11 +115,11 @@ def test_sign_package_1(gpg_with_key: GPG, mocker: MockerFixture) -> None: process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process", return_value=result) gpg_with_key.targets = {SignSettings.Packages} - assert gpg_with_key.sign_package(Path("a"), "a") == result + assert gpg_with_key.process_sign_package(Path("a"), "a") == result process_mock.assert_called_once() -def test_sign_package_2(gpg_with_key: GPG, mocker: MockerFixture) -> None: +def test_process_sign_package_2(gpg_with_key: GPG, mocker: MockerFixture) -> None: """ must sign package """ @@ -127,51 +127,51 @@ def test_sign_package_2(gpg_with_key: GPG, mocker: MockerFixture) -> None: process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process", return_value=result) gpg_with_key.targets = {SignSettings.Packages, SignSettings.Repository} - assert gpg_with_key.sign_package(Path("a"), "a") == result + assert gpg_with_key.process_sign_package(Path("a"), "a") == result process_mock.assert_called_once() -def test_sign_package_skip_1(gpg_with_key: GPG, mocker: MockerFixture) -> None: +def test_process_sign_package_skip_1(gpg_with_key: GPG, mocker: MockerFixture) -> None: """ must not sign package if it is not set """ process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process") gpg_with_key.targets = {} - gpg_with_key.sign_package(Path("a"), "a") + gpg_with_key.process_sign_package(Path("a"), "a") process_mock.assert_not_called() -def test_sign_package_skip_2(gpg_with_key: GPG, mocker: MockerFixture) -> None: +def test_process_sign_package_skip_2(gpg_with_key: GPG, mocker: MockerFixture) -> None: """ must not sign package if it is not set """ process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process") gpg_with_key.targets = {SignSettings.Repository} - gpg_with_key.sign_package(Path("a"), "a") + gpg_with_key.process_sign_package(Path("a"), "a") process_mock.assert_not_called() -def test_sign_package_skip_3(gpg: GPG, mocker: MockerFixture) -> None: +def test_process_sign_package_skip_3(gpg: GPG, mocker: MockerFixture) -> None: """ must not sign package if it is not set """ process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process") gpg.targets = {SignSettings.Packages} - gpg.sign_package(Path("a"), "a") + gpg.process_sign_package(Path("a"), "a") process_mock.assert_not_called() -def test_sign_package_skip_4(gpg: GPG, mocker: MockerFixture) -> None: +def test_process_sign_package_skip_4(gpg: GPG, mocker: MockerFixture) -> None: """ must not sign package if it is not set """ process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process") gpg.targets = {SignSettings.Packages, SignSettings.Repository} - gpg.sign_package(Path("a"), "a") + gpg.process_sign_package(Path("a"), "a") process_mock.assert_not_called() -def test_sign_repository_1(gpg_with_key: GPG, mocker: MockerFixture) -> None: +def test_process_sign_repository_1(gpg_with_key: GPG, mocker: MockerFixture) -> None: """ must sign repository """ @@ -179,11 +179,11 @@ def test_sign_repository_1(gpg_with_key: GPG, mocker: MockerFixture) -> None: process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process", return_value=result) gpg_with_key.targets = {SignSettings.Repository} - assert gpg_with_key.sign_repository(Path("a")) == result + assert gpg_with_key.process_sign_repository(Path("a")) == result process_mock.assert_called_once() -def test_sign_repository_2(gpg_with_key: GPG, mocker: MockerFixture) -> None: +def test_process_sign_repository_2(gpg_with_key: GPG, mocker: MockerFixture) -> None: """ must sign repository """ @@ -191,45 +191,45 @@ def test_sign_repository_2(gpg_with_key: GPG, mocker: MockerFixture) -> None: process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process", return_value=result) gpg_with_key.targets = {SignSettings.Packages, SignSettings.Repository} - assert gpg_with_key.sign_repository(Path("a")) == result + assert gpg_with_key.process_sign_repository(Path("a")) == result process_mock.assert_called_once() -def test_sign_repository_skip_1(gpg_with_key: GPG, mocker: MockerFixture) -> None: +def test_process_sign_repository_skip_1(gpg_with_key: GPG, mocker: MockerFixture) -> None: """ must not sign repository if it is not set """ process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process") gpg_with_key.targets = {} - gpg_with_key.sign_repository(Path("a")) + gpg_with_key.process_sign_repository(Path("a")) process_mock.assert_not_called() -def test_sign_repository_skip_2(gpg_with_key: GPG, mocker: MockerFixture) -> None: +def test_process_sign_repository_skip_2(gpg_with_key: GPG, mocker: MockerFixture) -> None: """ must not sign repository if it is not set """ process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process") gpg_with_key.targets = {SignSettings.Packages} - gpg_with_key.sign_repository(Path("a")) + gpg_with_key.process_sign_repository(Path("a")) process_mock.assert_not_called() -def test_sign_repository_skip_3(gpg: GPG, mocker: MockerFixture) -> None: +def test_process_sign_repository_skip_3(gpg: GPG, mocker: MockerFixture) -> None: """ must not sign repository if it is not set """ process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process") gpg.targets = {SignSettings.Repository} - gpg.sign_repository(Path("a")) + gpg.process_sign_repository(Path("a")) process_mock.assert_not_called() -def test_sign_repository_skip_4(gpg: GPG, mocker: MockerFixture) -> None: +def test_process_sign_repository_skip_4(gpg: GPG, mocker: MockerFixture) -> None: """ must not sign repository if it is not set """ process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process") gpg.targets = {SignSettings.Packages, SignSettings.Repository} - gpg.sign_repository(Path("a")) + gpg.process_sign_repository(Path("a")) process_mock.assert_not_called()