update tests

This commit is contained in:
Evgenii Alekseev 2023-08-29 04:48:41 +03:00
parent 32b00de42c
commit 812bf07803
90 changed files with 1172 additions and 581 deletions

View File

@ -36,9 +36,9 @@ systemd-machine-id-setup
# initial setup command as root # initial setup command as root
[[ -z $MINIMAL_INSTALL ]] && WEB_ARGS=("--web-port" "8080") [[ -z $MINIMAL_INSTALL ]] && WEB_ARGS=("--web-port" "8080")
ahriman -a x86_64 service-setup --packager "ahriman bot <ahriman@example.com>" --repository "github" "${WEB_ARGS[@]}" ahriman -a x86_64 -r "github" service-setup --packager "ahriman bot <ahriman@example.com>" "${WEB_ARGS[@]}"
# validate configuration # validate configuration
ahriman -a x86_64 service-config-validate --exit-code ahriman -a x86_64 -r "github" service-config-validate --exit-code
# enable services # enable services
systemctl enable ahriman-web@x86_64 systemctl enable ahriman-web@x86_64
systemctl enable ahriman@x86_64.timer systemctl enable ahriman@x86_64.timer
@ -48,9 +48,9 @@ if [[ -z $MINIMAL_INSTALL ]]; then
WEB_PID=$! WEB_PID=$!
fi fi
# add the first package # add the first package
sudo -u ahriman -- ahriman package-add --now yay sudo -u ahriman -- ahriman package-add --now ahriman
# check if package was actually installed # check if package was actually installed
test -n "$(find "/var/lib/ahriman/repository/x86_64" -name "yay*pkg*")" test -n "$(find "/var/lib/ahriman/repository/github/x86_64" -name "ahriman*pkg*")"
# run package check # run package check
sudo -u ahriman -- ahriman repo-update sudo -u ahriman -- ahriman repo-update
# stop web service lol # stop web service lol

View File

@ -25,7 +25,7 @@ from multiprocessing import Pool
from ahriman.application.lock import Lock from ahriman.application.lock import Lock
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import ExitCode, MissingArchitectureError, MultipleArchitecturesError from ahriman.core.exceptions import ExitCode, MissingArchitectureError, MultipleArchitecturesError
from ahriman.core.log.log_loader import LogLoader from ahriman.core.log import Log
from ahriman.models.repository_id import RepositoryId from ahriman.models.repository_id import RepositoryId
from ahriman.models.repository_paths import RepositoryPaths from ahriman.models.repository_paths import RepositoryPaths
@ -65,8 +65,8 @@ class Handler:
try: try:
configuration = Configuration.from_path(args.configuration, repository_id) configuration = Configuration.from_path(args.configuration, repository_id)
log_handler = LogLoader.handler(args.log_handler) log_handler = Log.handler(args.log_handler)
LogLoader.load(configuration, log_handler, quiet=args.quiet, report=args.report) Log.load(configuration, log_handler, quiet=args.quiet, report=args.report)
with Lock(args, repository_id, configuration): with Lock(args, repository_id, configuration):
cls.run(args, repository_id, configuration, report=args.report) cls.run(args, repository_id, configuration, report=args.report)
@ -116,7 +116,7 @@ class Handler:
args(argparse.Namespace): command line args args(argparse.Namespace): command line args
Returns: Returns:
tuple[str | None, str]: list of repository names and architectures for which tree is created list[RepositoryId]: list of repository names and architectures for which tree is created
Raises: Raises:
MissingArchitectureError: if no architecture set and automatic detection is not allowed or failed MissingArchitectureError: if no architecture set and automatic detection is not allowed or failed

View File

@ -66,8 +66,8 @@ class Setup(Handler):
Setup.configuration_create_makepkg(args.packager, args.makeflags_jobs, application.repository.paths) Setup.configuration_create_makepkg(args.packager, args.makeflags_jobs, application.repository.paths)
Setup.executable_create(application.repository.paths, repository_id) Setup.executable_create(application.repository.paths, repository_id)
repository_server = f"file://{application.repository.paths.repository}" if args.server is None else args.server repository_server = f"file://{application.repository.paths.repository}" if args.server is None else args.server
Setup.configuration_create_devtools(repository_id, args.from_configuration, args.mirror, args.multilib, Setup.configuration_create_devtools(
repository_server) repository_id, args.from_configuration, args.mirror, args.multilib, repository_server)
Setup.configuration_create_sudo(application.repository.paths, repository_id) Setup.configuration_create_sudo(application.repository.paths, repository_id)
application.repository.repo.init() application.repository.repo.init()

View File

@ -77,7 +77,6 @@ class Web(Handler):
""" """
# read architecture from the same argument list # read architecture from the same argument list
yield from ["--architecture", repository_id.architecture] yield from ["--architecture", repository_id.architecture]
if repository_id.name is not None:
yield from ["--repository", repository_id.name] yield from ["--repository", repository_id.name]
# read configuration path from current settings # read configuration path from current settings
if (configuration_path := configuration.path) is not None: if (configuration_path := configuration.path) is not None:

View File

@ -70,7 +70,7 @@ class Lock(LazyLogging):
repository_id(RepositoryId): repository unique identifier repository_id(RepositoryId): repository unique identifier
configuration(Configuration): configuration instance configuration(Configuration): configuration instance
""" """
lock_suffix = f"{repository_id.name}_{repository_id.architecture}" if repository_id.name is not None else repository_id.architecture lock_suffix = f"{repository_id.name}_{repository_id.architecture}"
self.path: Path | None = \ self.path: Path | None = \
args.lock.with_stem(f"{args.lock.stem}_{lock_suffix}") if args.lock is not None else None args.lock.with_stem(f"{args.lock.stem}_{lock_suffix}") if args.lock is not None else None

View File

@ -89,6 +89,17 @@ class Configuration(configparser.RawConfigParser):
self.path: Path | None = None self.path: Path | None = None
self.includes: list[Path] = [] self.includes: list[Path] = []
@property
def architecture(self) -> str:
"""
repository architecture for backward compatibility
Returns:
str: repository architecture
"""
_, repository_id = self.check_loaded()
return repository_id.architecture
@property @property
def include(self) -> Path: def include(self) -> Path:
""" """
@ -163,23 +174,23 @@ class Configuration(configparser.RawConfigParser):
# the valid order is global < per architecture < per repository < per repository and architecture # the valid order is global < per architecture < per repository < per repository and architecture
return [ return [
Configuration.section_name(section, repository_id.architecture), # architecture specific override Configuration.section_name(section, repository_id.architecture), # architecture specific override
Configuration.section_name(section, repository_id.name), Configuration.section_name(section, repository_id.name), # override with repository name
Configuration.section_name(section, repository_id.name, repository_id.architecture), Configuration.section_name(section, repository_id.name, repository_id.architecture), # both
] ]
@staticmethod @staticmethod
def section_name(section: str, *suffixes: str) -> str: def section_name(section: str, *suffixes: str | None) -> str:
""" """
generate section name for sections which depends on context generate section name for sections which depends on context
Args: Args:
section(str): section name section(str): section name
*suffixes(str): session suffix, e.g. repository architecture *suffixes(str | None): session suffix, e.g. repository architecture
Returns: Returns:
str: correct section name for repository specific section str: correct section name for repository specific section
""" """
for suffix in suffixes: for suffix in filter(bool, suffixes):
section = f"{section}:{suffix}" section = f"{section}:{suffix}"
return section return section

View File

@ -80,7 +80,7 @@ def migrate_package_remotes(connection: Connection, paths: RepositoryPaths) -> N
version=row["version"], version=row["version"],
remote=RemoteSource.from_json(row), remote=RemoteSource.from_json(row),
packages={}, packages={},
packager=row["packager"] or None, packager=row.get("packager") or None,
) for row in connection.execute("""select * from package_bases""") ) for row in connection.execute("""select * from package_bases""")
} }

View File

@ -51,6 +51,9 @@ steps = [
alter table build_queue add column repository text not null default '' alter table build_queue add column repository text not null default ''
""", """,
""" """
alter table build_queue add column architecture text not null default ''
""",
"""
alter table build_queue rename to build_queue_ alter table build_queue rename to build_queue_
""", """,
""" """
@ -58,7 +61,8 @@ steps = [
package_base text not null, package_base text not null,
properties json not null, properties json not null,
repository text not null, repository text not null,
primary key (package_base, repository) architecture text not null,
unique (package_base, architecture, repository)
) )
""", """,
""" """
@ -72,6 +76,9 @@ steps = [
alter table package_bases add column repository text not null default '' alter table package_bases add column repository text not null default ''
""", """,
""" """
alter table package_bases add column architecture text not null default ''
""",
"""
alter table package_bases rename to package_bases_ alter table package_bases rename to package_bases_
""", """,
""" """
@ -85,7 +92,8 @@ steps = [
source text, source text,
packager text, packager text,
repository text not null, repository text not null,
primary key (package_base, repository) architecture text not null,
unique (package_base, architecture, repository)
) )
""", """,
""" """
@ -99,6 +107,9 @@ steps = [
alter table package_statuses add column repository text not null default '' alter table package_statuses add column repository text not null default ''
""", """,
""" """
alter table package_statuses add column architecture text not null default ''
""",
"""
alter table package_statuses rename to package_statuses_ alter table package_statuses rename to package_statuses_
""", """,
""" """
@ -107,7 +118,8 @@ steps = [
status text not null, status text not null,
last_updated integer, last_updated integer,
repository text not null, repository text not null,
primary key (package_base, repository) architecture text not null,
unique (package_base, architecture, repository)
) )
""", """,
""" """
@ -142,7 +154,7 @@ steps = [
opt_depends json, opt_depends json,
check_depends json, check_depends json,
repository text not null, repository text not null,
primary key (package, architecture, repository) unique (package, architecture, repository)
) )
""", """,
""" """
@ -151,39 +163,14 @@ steps = [
""" """
drop table packages_ drop table packages_
""", """,
# patches
"""
alter table patches add column repository text not null default ''
""",
"""
drop index patches_package_base_variable
""",
"""
alter table patches rename to patches_
""",
"""
create table patches (
package_base text not null,
variable text,
patch blob not null,
repository text not null
)
""",
"""
create unique index patches_package_base_variable_repository
on patches (package_base, coalesce(variable, ''), repository)
""",
"""
insert into patches select * from patches_
""",
"""
drop table patches_
""",
# logs # logs
""" """
alter table logs add column repository text not null default '' alter table logs add column repository text not null default ''
""", """,
""" """
alter table logs add column architecture text not null default ''
""",
"""
drop index logs_package_base_version drop index logs_package_base_version
""", """,
""" """
@ -195,14 +182,16 @@ steps = [
created real not null, created real not null,
record text, record text,
version text not null, version text not null,
repository text not null repository text not null,
architecture text not null
) )
""", """,
""" """
insert into logs select * from logs_ insert into logs select * from logs_
""", """,
""" """
create index logs_package_base_version on logs (package_base, version) create index logs_package_base_version_architecture_repository
on logs (package_base, version, architecture, repository)
""", """,
""" """
drop table logs_ drop table logs_
@ -231,15 +220,13 @@ def migrate_package_repository(connection: Connection, configuration: Configurat
""" """
_, repository_id = configuration.check_loaded() _, repository_id = configuration.check_loaded()
connection.execute("""update build_queue set repository = :repository""", connection.execute("""update build_queue set repository = :repository, architecture = :architecture""",
{"repository": repository_id.name, }) {"repository": repository_id.name, "architecture": repository_id.architecture})
connection.execute("""update package_bases set repository = :repository""", connection.execute("""update package_bases set repository = :repository, architecture = :architecture""",
{"repository": repository_id.name, }) {"repository": repository_id.name, "architecture": repository_id.architecture})
connection.execute("""update package_statuses set repository = :repository""", connection.execute("""update package_statuses set repository = :repository, architecture = :architecture""",
{"repository": repository_id.name, }) {"repository": repository_id.name, "architecture": repository_id.architecture})
connection.execute("""update packages set repository = :repository""", connection.execute("""update packages set repository = :repository""",
{"repository": repository_id.name, }) {"repository": repository_id.name})
connection.execute("""update patches set repository = :repository""", connection.execute("""update logs set repository = :repository, architecture = :architecture""",
{"repository": repository_id.name, }) {"repository": repository_id.name, "architecture": repository_id.architecture})
connection.execute("""update logs set repository = :repository""",
{"repository": repository_id.name, })

View File

@ -39,9 +39,14 @@ class BuildOperations(Operations):
connection.execute( connection.execute(
""" """
delete from build_queue delete from build_queue
where (:package_base is null or package_base = :package_base) and repository = :repository where (:package_base is null or package_base = :package_base)
and repository = :repository and architecture = :architecture
""", """,
{"package_base": package_base, "repository": self.repository_id.name}) {
"package_base": package_base,
"repository": self.repository_id.name,
"architecture": self.repository_id.architecture,
})
return self.with_connection(run, commit=True) return self.with_connection(run, commit=True)
@ -56,8 +61,11 @@ class BuildOperations(Operations):
return [ return [
Package.from_json(row["properties"]) Package.from_json(row["properties"])
for row in connection.execute( for row in connection.execute(
"""select properties from build_queue where repository = :repository""", """
{"repository": self.repository_id.name} select properties from build_queue
where repository = :repository and architecture = :architecture
""",
{"repository": self.repository_id.name, "architecture": self.repository_id.architecture}
) )
] ]
@ -74,12 +82,17 @@ class BuildOperations(Operations):
connection.execute( connection.execute(
""" """
insert into build_queue insert into build_queue
(package_base, properties, repository) (package_base, properties, repository, architecture)
values values
(:package_base, :properties, :repository) (:package_base, :properties, :repository, :architecture)
on conflict (package_base, repository) do update set on conflict (package_base, architecture, repository) do update set
properties = :properties properties = :properties
""", """,
{"package_base": package.base, "properties": package.view(), "repository": self.repository_id.name}) {
"package_base": package.base,
"properties": package.view(),
"repository": self.repository_id.name,
"architecture": self.repository_id.architecture,
})
return self.with_connection(run, commit=True) return self.with_connection(run, commit=True)

View File

@ -46,10 +46,16 @@ class LogsOperations(Operations):
for row in connection.execute( for row in connection.execute(
""" """
select created, record from logs select created, record from logs
where package_base = :package_base and repository = :repository where package_base = :package_base and repository = :repository and architecture = :architecture
order by created limit :limit offset :offset order by created limit :limit offset :offset
""", """,
{"package_base": package_base, "repository": self.repository_id.name, "limit": limit, "offset": offset}) {
"package_base": package_base,
"repository": self.repository_id.name,
"architecture": self.repository_id.architecture,
"limit": limit,
"offset": offset,
})
] ]
return self.with_connection(run) return self.with_connection(run)
@ -67,9 +73,9 @@ class LogsOperations(Operations):
connection.execute( connection.execute(
""" """
insert into logs insert into logs
(package_base, version, created, record, repository) (package_base, version, created, record, repository, architecture)
values values
(:package_base, :version, :created, :record, :repository) (:package_base, :version, :created, :record, :repository, :architecture)
""", """,
{ {
"package_base": log_record_id.package_base, "package_base": log_record_id.package_base,
@ -77,6 +83,7 @@ class LogsOperations(Operations):
"created": created, "created": created,
"record": record, "record": record,
"repository": self.repository_id.name, "repository": self.repository_id.name,
"architecture": self.repository_id.architecture,
} }
) )
@ -95,10 +102,15 @@ class LogsOperations(Operations):
connection.execute( connection.execute(
""" """
delete from logs delete from logs
where package_base = :package_base and repository = :repository where package_base = :package_base and repository = :repository and architecture = :architecture
and (:version is null or version <> :version) and (:version is null or version <> :version)
""", """,
{"package_base": package_base, "version": version, "repository": self.repository_id.name} {
"package_base": package_base,
"version": version,
"repository": self.repository_id.name,
"architecture": self.repository_id.architecture,
}
) )
return self.with_connection(run, commit=True) return self.with_connection(run, commit=True)

View File

@ -43,14 +43,23 @@ class PackageOperations(Operations):
connection.execute( connection.execute(
""" """
delete from package_statuses delete from package_statuses
where package_base = :package_base and repository = :repository where package_base = :package_base and repository = :repository and architecture = :architecture
""", """,
{"package_base": package_base, "repository": self.repository_id.name}) {
"package_base": package_base,
"repository": self.repository_id.name,
"architecture": self.repository_id.architecture,
})
connection.execute( connection.execute(
""" """
delete from package_bases delete from package_bases
where package_base = :package_base and repository = :repository""", where package_base = :package_base and repository = :repository and architecture = :architecture
{"package_base": package_base, "repository": self.repository_id.name}) """,
{
"package_base": package_base,
"repository": self.repository_id.name,
"architecture": self.repository_id.architecture,
})
def _package_remove_packages(self, connection: Connection, package_base: str, def _package_remove_packages(self, connection: Connection, package_base: str,
current_packages: Iterable[str]) -> None: current_packages: Iterable[str]) -> None:
@ -66,15 +75,19 @@ class PackageOperations(Operations):
package package
for package in connection.execute( for package in connection.execute(
""" """
select package, repository from packages select package, repository, architecture from packages
where package_base = :package_base and repository = :repository""", where package_base = :package_base and repository = :repository and architecture = :architecture""",
{"package_base": package_base, "repository": self.repository_id.name}) {
"package_base": package_base,
"repository": self.repository_id.name,
"architecture": self.repository_id.architecture,
})
if package["package"] not in current_packages if package["package"] not in current_packages
] ]
connection.executemany( connection.executemany(
""" """
delete from packages delete from packages
where package = :package and repository = :repository where package = :package and repository = :repository and architecture = :architecture
""", """,
packages) packages)
@ -89,10 +102,12 @@ class PackageOperations(Operations):
connection.execute( connection.execute(
""" """
insert into package_bases insert into package_bases
(package_base, version, source, branch, git_url, path, web_url, packager, repository) (package_base, version, source, branch, git_url, path, web_url, packager,
repository, architecture)
values values
(:package_base, :version, :source, :branch, :git_url, :path, :web_url, :packager, :repository) (:package_base, :version, :source, :branch, :git_url, :path, :web_url, :packager,
on conflict (package_base, repository) do update set :repository, :architecture)
on conflict (package_base, architecture, repository) do update set
version = :version, branch = :branch, git_url = :git_url, path = :path, web_url = :web_url, version = :version, branch = :branch, git_url = :git_url, path = :path, web_url = :web_url,
source = :source, packager = :packager source = :source, packager = :packager
""", """,
@ -106,6 +121,7 @@ class PackageOperations(Operations):
"source": package.remote.source.value, "source": package.remote.source.value,
"packager": package.packager, "packager": package.packager,
"repository": self.repository_id.name, "repository": self.repository_id.name,
"architecture": self.repository_id.architecture,
} }
) )
@ -161,10 +177,10 @@ class PackageOperations(Operations):
connection.execute( connection.execute(
""" """
insert into package_statuses insert into package_statuses
(package_base, status, last_updated, repository) (package_base, status, last_updated, repository, architecture)
values values
(:package_base, :status, :last_updated, :repository) (:package_base, :status, :last_updated, :repository, :architecture)
on conflict (package_base, repository) do update set on conflict (package_base, architecture, repository) do update set
status = :status, last_updated = :last_updated status = :status, last_updated = :last_updated
""", """,
{ {
@ -172,6 +188,7 @@ class PackageOperations(Operations):
"status": status.status.value, "status": status.status.value,
"last_updated": status.timestamp, "last_updated": status.timestamp,
"repository": self.repository_id.name, "repository": self.repository_id.name,
"architecture": self.repository_id.architecture,
}) })
def _packages_get_select_package_bases(self, connection: Connection) -> dict[str, Package]: def _packages_get_select_package_bases(self, connection: Connection) -> dict[str, Package]:
@ -192,8 +209,8 @@ class PackageOperations(Operations):
packages={}, packages={},
packager=row["packager"] or None, packager=row["packager"] or None,
) for row in connection.execute( ) for row in connection.execute(
"""select * from package_bases where repository = :repository""", """select * from package_bases where repository = :repository and architecture = :architecture""",
{"repository": self.repository_id.name} {"repository": self.repository_id.name, "architecture": self.repository_id.architecture}
) )
} }
@ -209,8 +226,9 @@ class PackageOperations(Operations):
dict[str, Package]: map of the package base to its descriptor including individual packages dict[str, Package]: map of the package base to its descriptor including individual packages
""" """
for row in connection.execute( for row in connection.execute(
"""select * from packages where repository = :repository""", """select * from packages where repository = :repository and architecture = :architecture""",
{"repository": self.repository_id.name}): {"repository": self.repository_id.name, "architecture": self.repository_id.architecture}
):
if row["package_base"] not in packages: if row["package_base"] not in packages:
continue # normally must never happen though continue # normally must never happen though
packages[row["package_base"]].packages[row["package"]] = PackageDescription.from_json(row) packages[row["package_base"]].packages[row["package"]] = PackageDescription.from_json(row)
@ -229,8 +247,8 @@ class PackageOperations(Operations):
return { return {
row["package_base"]: BuildStatus.from_json({"status": row["status"], "timestamp": row["last_updated"]}) row["package_base"]: BuildStatus.from_json({"status": row["status"], "timestamp": row["last_updated"]})
for row in connection.execute( for row in connection.execute(
"""select * from package_statuses where repository = :repository""", """select * from package_statuses where repository = :repository and architecture = :architecture""",
{"repository": self.repository_id.name} {"repository": self.repository_id.name, "architecture": self.repository_id.architecture}
) )
} }

View File

@ -54,19 +54,13 @@ class PatchOperations(Operations):
connection.execute( connection.execute(
""" """
insert into patches insert into patches
(package_base, variable, patch, repository) (package_base, variable, patch)
values values
(:package_base, :variable, :patch, :repository) (:package_base, :variable, :patch)
on conflict (package_base, coalesce(variable, ''), repository) do update set on conflict (package_base, coalesce(variable, '')) do update set
patch = :patch patch = :patch
""", """,
{ {"package_base": package_base, "variable": patch.key, "patch": patch.value})
"package_base": package_base,
"variable": patch.key,
"patch": patch.value,
"repository": self.repository_id.name,
}
)
return self.with_connection(run, commit=True) return self.with_connection(run, commit=True)
@ -85,10 +79,8 @@ class PatchOperations(Operations):
return [ return [
(row["package_base"], PkgbuildPatch(row["variable"], row["patch"])) (row["package_base"], PkgbuildPatch(row["variable"], row["patch"]))
for row in connection.execute( for row in connection.execute(
""" """select * from patches where :package_base is null or package_base = :package_base""",
select * from patches {"package_base": package_base})
where (:package_base is null or package_base = :package_base) and repository = :repository""",
{"package_base": package_base, "repository": self.repository_id.name})
] ]
# we could use itertools & operator but why? # we could use itertools & operator but why?
@ -109,23 +101,13 @@ class PatchOperations(Operations):
""" """
def run_many(connection: Connection) -> None: def run_many(connection: Connection) -> None:
connection.executemany( connection.executemany(
""" """delete from patches where package_base = :package_base and variable = :variable""",
delete from patches [{"package_base": package_base, "variable": variable} for variable in variables])
where package_base = :package_base and variable = :variable and repository = :repository
""",
[
{
"package_base": package_base,
"variable": variable,
"repository": self.repository_id.name,
} for variable in variables
]
)
def run(connection: Connection) -> None: def run(connection: Connection) -> None:
connection.execute( connection.execute(
"""delete from patches where package_base = :package_base and repository = :repository""", """delete from patches where package_base = :package_base""",
{"package_base": package_base, "repository": self.repository_id.name}) {"package_base": package_base})
if variables: if variables:
return self.with_connection(run_many, commit=True) return self.with_connection(run_many, commit=True)

View File

@ -18,3 +18,4 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
from ahriman.core.log.lazy_logging import LazyLogging from ahriman.core.log.lazy_logging import LazyLogging
from ahriman.core.log.log import Log

View File

@ -27,7 +27,7 @@ from ahriman.core.log.http_log_handler import HttpLogHandler
from ahriman.models.log_handler import LogHandler from ahriman.models.log_handler import LogHandler
class LogLoader: class Log:
""" """
simple static method class which setups application loggers simple static method class which setups application loggers
@ -63,7 +63,7 @@ class LogLoader:
del JournalHandler del JournalHandler
return LogHandler.Journald # journald import was found return LogHandler.Journald # journald import was found
except ImportError: except ImportError:
if LogLoader.DEFAULT_SYSLOG_DEVICE.exists(): if Log.DEFAULT_SYSLOG_DEVICE.exists():
return LogHandler.Syslog return LogHandler.Syslog
return LogHandler.Console return LogHandler.Console
@ -94,7 +94,7 @@ class LogLoader:
fileConfig(log_configuration, disable_existing_loggers=True) fileConfig(log_configuration, disable_existing_loggers=True)
logging.debug("using %s logger", default_handler) logging.debug("using %s logger", default_handler)
except Exception: except Exception:
logging.basicConfig(filename=None, format=LogLoader.DEFAULT_LOG_FORMAT, level=LogLoader.DEFAULT_LOG_LEVEL) logging.basicConfig(filename=None, format=Log.DEFAULT_LOG_FORMAT, level=Log.DEFAULT_LOG_LEVEL)
logging.exception("could not load logging from configuration, fallback to stderr") logging.exception("could not load logging from configuration, fallback to stderr")
HttpLogHandler.load(configuration, report=report) HttpLogHandler.load(configuration, report=report)

View File

@ -132,7 +132,7 @@ class S3(Upload):
continue continue
local_path = path / local_file local_path = path / local_file
remote_path = self.remote_root / local_file remote_path = self.remote_root / local_file.name
(mime, _) = mimetypes.guess_type(local_path) (mime, _) = mimetypes.guess_type(local_path)
extra_args = {"ContentType": mime} if mime is not None else None extra_args = {"ContentType": mime} if mime is not None else None

View File

@ -62,4 +62,4 @@ class RepositoryId:
if not isinstance(other, RepositoryId): if not isinstance(other, RepositoryId):
raise ValueError(f"'<' not supported between instances of '{type(self)}' and '{type(other)}'") raise ValueError(f"'<' not supported between instances of '{type(self)}' and '{type(other)}'")
return self.name <= other.name and self.architecture < other.architecture return (self.name, self.architecture) < (other.name, other.architecture)

View File

@ -26,12 +26,11 @@ from functools import cached_property
from pathlib import Path from pathlib import Path
from ahriman.core.exceptions import PathError from ahriman.core.exceptions import PathError
from ahriman.core.log import LazyLogging
from ahriman.models.repository_id import RepositoryId from ahriman.models.repository_id import RepositoryId
@dataclass(frozen=True) @dataclass(frozen=True)
class RepositoryPaths(LazyLogging): class RepositoryPaths:
""" """
repository paths holder. For the most operations with paths you want to use this object repository paths holder. For the most operations with paths you want to use this object
@ -57,6 +56,16 @@ class RepositoryPaths(LazyLogging):
root: Path root: Path
repository_id: RepositoryId repository_id: RepositoryId
@property
def _repository_root(self) -> Path:
"""
repository root which can be used for invalid (not fully loaded instances)
Returns:
Path: root path to repositories
"""
return self.root / "repository"
@cached_property @cached_property
def _suffix(self) -> Path: def _suffix(self) -> Path:
""" """
@ -66,8 +75,7 @@ class RepositoryPaths(LazyLogging):
Path: relative path which contains only architecture segment in case if legacy tree is used and repository Path: relative path which contains only architecture segment in case if legacy tree is used and repository
name and architecture otherwise name and architecture otherwise
""" """
if (self.root / "repository" / self.repository_id.architecture).is_dir(): if (self._repository_root / self.repository_id.architecture).is_dir():
self.logger.warning("legacy single repository tree has been found")
return Path(self.repository_id.architecture) return Path(self.repository_id.architecture)
return Path(self.repository_id.name) / self.repository_id.architecture return Path(self.repository_id.name) / self.repository_id.architecture
@ -120,7 +128,7 @@ class RepositoryPaths(LazyLogging):
Returns: Returns:
Path: full path to the repository directory Path: full path to the repository directory
""" """
return self.root / "repository" / self._suffix return self._repository_root / self._suffix
@property @property
def root_owner(self) -> tuple[int, int]: def root_owner(self) -> tuple[int, int]:
@ -148,13 +156,15 @@ class RepositoryPaths(LazyLogging):
for architecture in filter(lambda path: path.is_dir(), repository_path.iterdir()): for architecture in filter(lambda path: path.is_dir(), repository_path.iterdir()):
yield RepositoryId(architecture.name, repository_name) yield RepositoryId(architecture.name, repository_name)
def walk_with_name(paths: RepositoryPaths) -> Generator[RepositoryId, None, None]: def walk_root(paths: RepositoryPaths) -> Generator[RepositoryId, None, None]:
for repository in filter(lambda path: path.is_dir(), paths.repository.iterdir()): # pylint: disable=protected-access
for repository in filter(lambda path: path.is_dir(), paths._repository_root.iterdir()):
print(repository)
yield from walk(repository, repository.name) yield from walk(repository, repository.name)
instance = cls(root, RepositoryId("", "")) instance = cls(root, RepositoryId("", root.name)) # suppress initialization error
# try to get list per repository first and then fallback to old schema if nothing found # try to get list per repository first and then fallback to old schema if nothing found
return set(walk_with_name(instance)) or set(walk(instance.repository, name)) return set(walk_root(instance)) or set(walk(instance._repository_root, name))
@staticmethod @staticmethod
def owner(path: Path) -> tuple[int, int]: def owner(path: Path) -> tuple[int, int]:

View File

@ -6,3 +6,10 @@ def test_create_tree(application_properties: ApplicationProperties) -> None:
must have repository attribute must have repository attribute
""" """
assert application_properties.repository assert application_properties.repository
def test_architecture(application_properties: ApplicationProperties) -> None:
"""
must return repository architecture
"""
assert application_properties.architecture == application_properties.repository_id.architecture

View File

@ -8,48 +8,7 @@ from ahriman.application.handlers import Handler
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import ExitCode, MissingArchitectureError, MultipleArchitecturesError from ahriman.core.exceptions import ExitCode, MissingArchitectureError, MultipleArchitecturesError
from ahriman.models.log_handler import LogHandler from ahriman.models.log_handler import LogHandler
from ahriman.models.repository_id import RepositoryId
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_with(configuration.getpath("repository", "root"))
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(MissingArchitectureError):
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(MissingArchitectureError):
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) == sorted(set(architectures))
def test_call(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: def test_call(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
@ -67,15 +26,16 @@ def test_call(args: argparse.Namespace, configuration: Configuration, mocker: Mo
enter_mock = mocker.patch("ahriman.application.lock.Lock.__enter__") enter_mock = mocker.patch("ahriman.application.lock.Lock.__enter__")
exit_mock = mocker.patch("ahriman.application.lock.Lock.__exit__") exit_mock = mocker.patch("ahriman.application.lock.Lock.__exit__")
assert Handler.call(args, "x86_64") _, repository_id = configuration.check_loaded()
configuration_mock.assert_called_once_with(args.configuration, "x86_64") 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_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(configuration, args.log_handler, quiet=args.quiet, report=args.report)
enter_mock.assert_called_once_with() enter_mock.assert_called_once_with()
exit_mock.assert_called_once_with(None, None, None) exit_mock.assert_called_once_with(None, None, None)
def test_call_exception(args: argparse.Namespace, mocker: MockerFixture) -> None: def test_call_exception(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
""" """
must process exception must process exception
""" """
@ -84,11 +44,12 @@ def test_call_exception(args: argparse.Namespace, mocker: MockerFixture) -> None
mocker.patch("ahriman.core.configuration.Configuration.from_path", side_effect=Exception()) mocker.patch("ahriman.core.configuration.Configuration.from_path", side_effect=Exception())
logging_mock = mocker.patch("logging.Logger.exception") logging_mock = mocker.patch("logging.Logger.exception")
assert not Handler.call(args, "x86_64") _, repository_id = configuration.check_loaded()
assert not Handler.call(args, repository_id)
logging_mock.assert_called_once_with(pytest.helpers.anyvar(str, strict=True)) logging_mock.assert_called_once_with(pytest.helpers.anyvar(str, strict=True))
def test_call_exit_code(args: argparse.Namespace, mocker: MockerFixture) -> None: def test_call_exit_code(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
""" """
must process exitcode exception must process exitcode exception
""" """
@ -97,7 +58,8 @@ def test_call_exit_code(args: argparse.Namespace, mocker: MockerFixture) -> None
mocker.patch("ahriman.core.configuration.Configuration.from_path", side_effect=ExitCode()) mocker.patch("ahriman.core.configuration.Configuration.from_path", side_effect=ExitCode())
logging_mock = mocker.patch("logging.Logger.exception") logging_mock = mocker.patch("logging.Logger.exception")
assert not Handler.call(args, "x86_64") _, repository_id = configuration.check_loaded()
assert not Handler.call(args, repository_id)
logging_mock.assert_not_called() logging_mock.assert_not_called()
@ -105,33 +67,39 @@ def test_execute(args: argparse.Namespace, mocker: MockerFixture) -> None:
""" """
must run execution in multiple processes must run execution in multiple processes
""" """
args.architecture = ["i686", "x86_64"] ids = [
RepositoryId("i686", "aur-clone"),
RepositoryId("x86_64", "aur-clone"),
]
mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=ids)
starmap_mock = mocker.patch("multiprocessing.pool.Pool.starmap") starmap_mock = mocker.patch("multiprocessing.pool.Pool.starmap")
Handler.execute(args) Handler.execute(args)
starmap_mock.assert_called_once_with(Handler.call, [(args, architecture) for architecture in args.architecture]) starmap_mock.assert_called_once_with(Handler.call, [(args, repository_id) for repository_id in ids])
def test_execute_multiple_not_supported(args: argparse.Namespace, mocker: MockerFixture) -> None: def test_execute_multiple_not_supported(args: argparse.Namespace, mocker: MockerFixture) -> None:
""" """
must raise an exception if multiple architectures are not supported by the handler must raise an exception if multiple architectures are not supported by the handler
""" """
args.architecture = ["i686", "x86_64"]
args.command = "web" args.command = "web"
mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=[
RepositoryId("i686", "aur-clone"),
RepositoryId("x86_64", "aur-clone"),
])
mocker.patch.object(Handler, "ALLOW_MULTI_ARCHITECTURE_RUN", False) mocker.patch.object(Handler, "ALLOW_MULTI_ARCHITECTURE_RUN", False)
with pytest.raises(MultipleArchitecturesError): with pytest.raises(MultipleArchitecturesError):
Handler.execute(args) Handler.execute(args)
def test_execute_single(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: def test_execute_single(args: argparse.Namespace, mocker: MockerFixture) -> None:
""" """
must run execution in current process if only one architecture supplied must run execution in current process if only one architecture supplied
""" """
args.architecture = ["x86_64"] mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=[
args.configuration = Path("") RepositoryId("x86_64", "aur-clone"),
args.quiet = False ])
mocker.patch("ahriman.core.configuration.Configuration.from_path", return_value=configuration)
starmap_mock = mocker.patch("multiprocessing.pool.Pool.starmap") starmap_mock = mocker.patch("multiprocessing.pool.Pool.starmap")
Handler.execute(args) Handler.execute(args)
@ -142,8 +110,73 @@ def test_run(args: argparse.Namespace, configuration: Configuration) -> None:
""" """
must raise NotImplemented for missing method must raise NotImplemented for missing method
""" """
_, repository_id = configuration.check_loaded()
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):
Handler.run(args, "x86_64", configuration, report=True) Handler.run(args, repository_id, configuration, report=True)
def test_repositories_extract(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must generate list of available architectures
"""
args.configuration = configuration.path
_, repository_id = configuration.check_loaded()
known_architectures_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures")
Handler.repositories_extract(args)
known_architectures_mock.assert_called_once_with(configuration.getpath("repository", "root"), repository_id.name)
def test_repositories_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(MissingArchitectureError):
Handler.repositories_extract(args)
def test_repositories_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(MissingArchitectureError):
Handler.repositories_extract(args)
def test_repositories_extract_specified(args: argparse.Namespace, configuration: Configuration) -> None:
"""
must return architecture list if it has been specified
"""
args.configuration = configuration.path
args.architecture = ["i686", "x86_64"]
args.repository = []
_, repository_id = configuration.check_loaded()
ids = [RepositoryId(architecture, repository_id.name) for architecture in args.architecture]
assert Handler.repositories_extract(args) == sorted(set(ids))
def test_repositories_extract_specified_with_repository(args: argparse.Namespace, configuration: Configuration) -> None:
"""
must return architecture list if it has been specified together with repositories
"""
args.configuration = configuration.path
args.architecture = ["i686", "x86_64"]
args.repository = ["repo1", "repo2"]
ids = [
RepositoryId(architecture, name)
for architecture in args.architecture
for name in args.repository
]
assert Handler.repositories_extract(args) == sorted(set(ids))
def test_check_if_empty() -> None: def test_check_if_empty() -> None:

View File

@ -44,7 +44,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
dependencies_mock = mocker.patch("ahriman.application.application.Application.with_dependencies") dependencies_mock = mocker.patch("ahriman.application.application.Application.with_dependencies")
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
Add.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Add.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(args.package, args.source, args.username) application_mock.assert_called_once_with(args.package, args.source, args.username)
dependencies_mock.assert_not_called() dependencies_mock.assert_not_called()
on_start_mock.assert_called_once_with() on_start_mock.assert_called_once_with()
@ -68,7 +69,8 @@ def test_run_with_updates(args: argparse.Namespace, configuration: Configuration
return_value=[package_ahriman]) return_value=[package_ahriman])
print_mock = mocker.patch("ahriman.application.application.Application.print_updates") print_mock = mocker.patch("ahriman.application.application.Application.print_updates")
Add.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Add.run(args, repository_id, configuration, report=False)
updates_mock.assert_called_once_with(args.package, aur=False, local=False, manual=True, vcs=False) updates_mock.assert_called_once_with(args.package, aur=False, local=False, manual=True, vcs=False)
application_mock.assert_called_once_with([package_ahriman], application_mock.assert_called_once_with([package_ahriman],
Packagers(args.username, {package_ahriman.base: "packager"}), Packagers(args.username, {package_ahriman.base: "packager"}),
@ -94,5 +96,6 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
mocker.patch("ahriman.application.application.Application.print_updates") mocker.patch("ahriman.application.application.Application.print_updates")
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
Add.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Add.run(args, repository_id, configuration, report=False)
check_mock.assert_called_once_with(True, True) check_mock.assert_called_once_with(True, True)

View File

@ -33,7 +33,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
add_mock = tarfile.__enter__.return_value = MagicMock() add_mock = tarfile.__enter__.return_value = MagicMock()
mocker.patch("tarfile.TarFile.__new__", return_value=tarfile) mocker.patch("tarfile.TarFile.__new__", return_value=tarfile)
Backup.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Backup.run(args, repository_id, configuration, report=False)
add_mock.add.assert_called_once_with(Path("path")) add_mock.add.assert_called_once_with(Path("path"))

View File

@ -35,6 +35,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
application_mock = mocker.patch("ahriman.application.application.Application.clean") application_mock = mocker.patch("ahriman.application.application.Application.clean")
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
Clean.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Clean.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(cache=False, chroot=False, manual=False, packages=False, pacman=False) application_mock.assert_called_once_with(cache=False, chroot=False, manual=False, packages=False, pacman=False)
on_start_mock.assert_called_once_with() on_start_mock.assert_called_once_with()

View File

@ -33,7 +33,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
start_mock = mocker.patch("threading.Timer.start") start_mock = mocker.patch("threading.Timer.start")
join_mock = mocker.patch("threading.Timer.join") join_mock = mocker.patch("threading.Timer.join")
Daemon.run(args, "x86_64", configuration, report=True) _, repository_id = configuration.check_loaded()
run_mock.assert_called_once_with(args, "x86_64", configuration, report=True) Daemon.run(args, repository_id, configuration, report=True)
run_mock.assert_called_once_with(args, repository_id, configuration, report=True)
start_mock.assert_called_once_with() start_mock.assert_called_once_with()
join_mock.assert_called_once_with() join_mock.assert_called_once_with()

View File

@ -29,7 +29,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump", application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump",
return_value=configuration.dump()) return_value=configuration.dump())
Dump.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Dump.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with() application_mock.assert_called_once_with()
print_mock.assert_called() print_mock.assert_called()

View File

@ -29,7 +29,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
args = _default_args(args) args = _default_args(args)
parse_mock = mocker.patch("argparse.ArgumentParser.parse_args") parse_mock = mocker.patch("argparse.ArgumentParser.parse_args")
Help.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Help.run(args, repository_id, configuration, report=False)
parse_mock.assert_called_once_with(["--help"]) parse_mock.assert_called_once_with(["--help"])
@ -41,7 +42,8 @@ def test_run_command(args: argparse.Namespace, configuration: Configuration, moc
args.command = "aur-search" args.command = "aur-search"
parse_mock = mocker.patch("argparse.ArgumentParser.parse_args") parse_mock = mocker.patch("argparse.ArgumentParser.parse_args")
Help.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Help.run(args, repository_id, configuration, report=False)
parse_mock.assert_called_once_with(["aur-search", "--help"]) parse_mock.assert_called_once_with(["aur-search", "--help"])

View File

@ -31,7 +31,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_import") application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_import")
KeyImport.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
KeyImport.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(args.key_server, args.key) application_mock.assert_called_once_with(args.key_server, args.key)

View File

@ -44,8 +44,9 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
return_value=(args.package, PkgbuildPatch(None, "patch"))) return_value=(args.package, PkgbuildPatch(None, "patch")))
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create") application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create")
Patch.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
patch_mock.assert_called_once_with(args.package, "x86_64", args.track) Patch.run(args, repository_id, configuration, report=False)
patch_mock.assert_called_once_with(args.package, repository_id.architecture, args.track)
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, PkgbuildPatch(None, "patch")) application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, PkgbuildPatch(None, "patch"))
@ -63,7 +64,8 @@ def test_run_function(args: argparse.Namespace, configuration: Configuration, re
patch_mock = mocker.patch("ahriman.application.handlers.Patch.patch_create_from_function", return_value=patch) patch_mock = mocker.patch("ahriman.application.handlers.Patch.patch_create_from_function", return_value=patch)
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create") application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create")
Patch.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Patch.run(args, repository_id, configuration, report=False)
patch_mock.assert_called_once_with(args.variable, args.patch) patch_mock.assert_called_once_with(args.variable, args.patch)
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, patch) application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, patch)
@ -79,7 +81,8 @@ def test_run_list(args: argparse.Namespace, configuration: Configuration, reposi
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_list") application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_list")
Patch.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Patch.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, ["version"], False) application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, ["version"], False)
@ -94,11 +97,12 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, repo
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_remove") application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_remove")
Patch.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Patch.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, ["version"]) application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, ["version"])
def test_patch_create_from_diff(package_ahriman: Package, mocker: MockerFixture) -> None: def test_patch_create_from_diff(package_ahriman: Package, configuration: Configuration, mocker: MockerFixture) -> None:
""" """
must create patch from directory tree diff must create patch from directory tree diff
""" """
@ -108,8 +112,9 @@ def test_patch_create_from_diff(package_ahriman: Package, mocker: MockerFixture)
package_mock = mocker.patch("ahriman.models.package.Package.from_build", return_value=package_ahriman) package_mock = mocker.patch("ahriman.models.package.Package.from_build", return_value=package_ahriman)
sources_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.patch_create", return_value=patch.value) sources_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.patch_create", return_value=patch.value)
assert Patch.patch_create_from_diff(path, "x86_64", ["*.diff"]) == (package_ahriman.base, patch) _, repository_id = configuration.check_loaded()
package_mock.assert_called_once_with(path, "x86_64", None) assert Patch.patch_create_from_diff(path, repository_id.architecture, ["*.diff"]) == (package_ahriman.base, patch)
package_mock.assert_called_once_with(path, repository_id.architecture, None)
sources_mock.assert_called_once_with(path, "*.diff") sources_mock.assert_called_once_with(path, "*.diff")

View File

@ -49,7 +49,8 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
Rebuild.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Rebuild.run(args, repository_id, configuration, report=False)
extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.status, from_database=args.from_database) extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.status, from_database=args.from_database)
application_packages_mock.assert_called_once_with([package_ahriman], None) application_packages_mock.assert_called_once_with([package_ahriman], None)
application_mock.assert_called_once_with([package_ahriman], args.username, bump_pkgrel=args.increment) application_mock.assert_called_once_with([package_ahriman], args.username, bump_pkgrel=args.increment)
@ -70,7 +71,8 @@ def test_run_extract_packages(args: argparse.Namespace, configuration: Configura
mocker.patch("ahriman.application.application.Application.print_updates") mocker.patch("ahriman.application.application.Application.print_updates")
extract_mock = mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[]) extract_mock = mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[])
Rebuild.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Rebuild.run(args, repository_id, configuration, report=False)
extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.status, from_database=args.from_database) extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.status, from_database=args.from_database)
@ -87,7 +89,8 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, rep
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
print_mock = mocker.patch("ahriman.application.application.Application.print_updates") print_mock = mocker.patch("ahriman.application.application.Application.print_updates")
Rebuild.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Rebuild.run(args, repository_id, configuration, report=False)
application_mock.assert_not_called() application_mock.assert_not_called()
check_mock.assert_called_once_with(False, False) check_mock.assert_called_once_with(False, False)
print_mock.assert_called_once_with([package_ahriman], log_fn=pytest.helpers.anyvar(int)) print_mock.assert_called_once_with([package_ahriman], log_fn=pytest.helpers.anyvar(int))
@ -105,7 +108,8 @@ def test_run_filter(args: argparse.Namespace, configuration: Configuration, repo
mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[]) mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[])
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on") application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on")
Rebuild.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Rebuild.run(args, repository_id, configuration, report=False)
application_packages_mock.assert_called_once_with([], ["python-aur"]) application_packages_mock.assert_called_once_with([], ["python-aur"])
@ -120,7 +124,8 @@ def test_run_without_filter(args: argparse.Namespace, configuration: Configurati
mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[]) mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[])
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on") application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on")
Rebuild.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Rebuild.run(args, repository_id, configuration, report=False)
application_packages_mock.assert_called_once_with([], None) application_packages_mock.assert_called_once_with([], None)
@ -138,7 +143,8 @@ def test_run_update_empty_exception(args: argparse.Namespace, configuration: Con
mocker.patch("ahriman.application.application.Application.print_updates") mocker.patch("ahriman.application.application.Application.print_updates")
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
Rebuild.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Rebuild.run(args, repository_id, configuration, report=False)
check_mock.assert_called_once_with(True, True) check_mock.assert_called_once_with(True, True)
@ -155,7 +161,8 @@ def test_run_build_empty_exception(args: argparse.Namespace, configuration: Conf
mocker.patch("ahriman.application.application.Application.update", return_value=Result()) mocker.patch("ahriman.application.application.Application.update", return_value=Result())
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
Rebuild.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Rebuild.run(args, repository_id, configuration, report=False)
check_mock.assert_has_calls([MockCall(True, False), MockCall(True, True)]) check_mock.assert_has_calls([MockCall(True, False), MockCall(True, True)])

View File

@ -31,6 +31,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
application_mock = mocker.patch("ahriman.application.application.Application.remove") application_mock = mocker.patch("ahriman.application.application.Application.remove")
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
Remove.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Remove.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with([]) application_mock.assert_called_once_with([])
on_start_mock.assert_called_once_with() on_start_mock.assert_called_once_with()

View File

@ -34,7 +34,8 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
remove_mock = mocker.patch("ahriman.application.application.Application.remove") remove_mock = mocker.patch("ahriman.application.application.Application.remove")
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
RemoveUnknown.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
RemoveUnknown.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with() application_mock.assert_called_once_with()
remove_mock.assert_called_once_with([package_ahriman]) remove_mock.assert_called_once_with([package_ahriman])
on_start_mock.assert_called_once_with() on_start_mock.assert_called_once_with()
@ -53,7 +54,8 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, rep
remove_mock = mocker.patch("ahriman.application.application.Application.remove") remove_mock = mocker.patch("ahriman.application.application.Application.remove")
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
RemoveUnknown.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
RemoveUnknown.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with() application_mock.assert_called_once_with()
remove_mock.assert_not_called() remove_mock.assert_not_called()
print_mock.assert_called_once_with(verbose=False) print_mock.assert_called_once_with(verbose=False)

View File

@ -32,7 +32,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
extract_mock = tarfile.__enter__.return_value = MagicMock() extract_mock = tarfile.__enter__.return_value = MagicMock()
mocker.patch("tarfile.TarFile.__new__", return_value=tarfile) mocker.patch("tarfile.TarFile.__new__", return_value=tarfile)
Restore.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Restore.run(args, repository_id, configuration, report=False)
extract_mock.extractall.assert_called_once_with(path=args.output) extract_mock.extractall.assert_called_once_with(path=args.output)

View File

@ -42,7 +42,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
Search.run(args, "x86_64", configuration, report=False) _, 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)) 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)) official_search_mock.assert_called_once_with("ahriman", pacman=pytest.helpers.anyvar(int))
check_mock.assert_called_once_with(False, False) check_mock.assert_called_once_with(False, False)
@ -62,7 +63,8 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
Search.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Search.run(args, repository_id, configuration, report=False)
check_mock.assert_called_once_with(True, True) check_mock.assert_called_once_with(True, True)
@ -77,7 +79,8 @@ def test_run_sort(args: argparse.Namespace, configuration: Configuration, reposi
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
sort_mock = mocker.patch("ahriman.application.handlers.Search.sort") sort_mock = mocker.patch("ahriman.application.handlers.Search.sort")
Search.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Search.run(args, repository_id, configuration, report=False)
sort_mock.assert_has_calls([ sort_mock.assert_has_calls([
MockCall([], "name"), MockCall().__iter__(), MockCall([], "name"), MockCall().__iter__(),
MockCall([aur_package_ahriman], "name"), MockCall().__iter__() MockCall([aur_package_ahriman], "name"), MockCall().__iter__()
@ -96,7 +99,8 @@ def test_run_sort_by(args: argparse.Namespace, configuration: Configuration, rep
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
sort_mock = mocker.patch("ahriman.application.handlers.Search.sort") sort_mock = mocker.patch("ahriman.application.handlers.Search.sort")
Search.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Search.run(args, repository_id, configuration, report=False)
sort_mock.assert_has_calls([ sort_mock.assert_has_calls([
MockCall([], "field"), MockCall().__iter__(), MockCall([], "field"), MockCall().__iter__(),
MockCall([aur_package_ahriman], "field"), MockCall().__iter__() MockCall([aur_package_ahriman], "field"), MockCall().__iter__()

View File

@ -35,7 +35,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
application_mock = mocker.patch("ahriman.core.formatters.Printer.print") application_mock = mocker.patch("ahriman.core.formatters.Printer.print")
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
ServiceUpdates.run(args, "x86_64", configuration, report=False) _, 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, repository.pacman, None)
application_mock.assert_called_once_with(verbose=True, separator=" -> ") application_mock.assert_called_once_with(verbose=True, separator=" -> ")
check_mock.assert_called_once_with(args.exit_code, True) check_mock.assert_called_once_with(args.exit_code, True)
@ -53,6 +54,7 @@ def test_run_skip(args: argparse.Namespace, configuration: Configuration, reposi
application_mock = mocker.patch("ahriman.core.formatters.Printer.print") application_mock = mocker.patch("ahriman.core.formatters.Printer.print")
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
ServiceUpdates.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
ServiceUpdates.run(args, repository_id, configuration, report=False)
application_mock.assert_not_called() application_mock.assert_not_called()
check_mock.assert_not_called() check_mock.assert_not_called()

View File

@ -9,6 +9,7 @@ from unittest.mock import call as MockCall
from ahriman.application.handlers import Setup from ahriman.application.handlers import Setup
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.repository import Repository from ahriman.core.repository import Repository
from ahriman.models.repository_id import RepositoryId
from ahriman.models.repository_paths import RepositoryPaths from ahriman.models.repository_paths import RepositoryPaths
from ahriman.models.sign_settings import SignSettings from ahriman.models.sign_settings import SignSettings
@ -24,14 +25,12 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
argparse.Namespace: generated arguments for these test cases argparse.Namespace: generated arguments for these test cases
""" """
args.build_as_user = "ahriman" args.build_as_user = "ahriman"
args.build_command = "ahriman"
args.from_configuration = Path("/usr/share/devtools/pacman.conf.d/extra.conf") args.from_configuration = Path("/usr/share/devtools/pacman.conf.d/extra.conf")
args.generate_salt = True args.generate_salt = True
args.makeflags_jobs = True args.makeflags_jobs = True
args.mirror = "mirror" args.mirror = "mirror"
args.multilib = True args.multilib = True
args.packager = "John Doe <john@doe.com>" args.packager = "John Doe <john@doe.com>"
args.repository = "aur-clone"
args.server = None args.server = None
args.sign_key = "key" args.sign_key = "key"
args.sign_target = [SignSettings.Packages] args.sign_target = [SignSettings.Packages]
@ -54,14 +53,14 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
executable_mock = mocker.patch("ahriman.application.handlers.Setup.executable_create") executable_mock = mocker.patch("ahriman.application.handlers.Setup.executable_create")
init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init") init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init")
Setup.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
ahriman_configuration_mock.assert_called_once_with(args, "x86_64", args.repository, configuration) Setup.run(args, repository_id, configuration, report=False)
ahriman_configuration_mock.assert_called_once_with(args, repository_id, configuration)
devtools_configuration_mock.assert_called_once_with( devtools_configuration_mock.assert_called_once_with(
args.build_command, "x86_64", args.from_configuration, args.mirror, args.multilib, args.repository, repository_id, args.from_configuration, args.mirror, args.multilib, f"file://{repository_paths.repository}")
f"file://{repository_paths.repository}")
makepkg_configuration_mock.assert_called_once_with(args.packager, args.makeflags_jobs, repository_paths) makepkg_configuration_mock.assert_called_once_with(args.packager, args.makeflags_jobs, repository_paths)
sudo_configuration_mock.assert_called_once_with(repository_paths, args.build_command, "x86_64") sudo_configuration_mock.assert_called_once_with(repository_paths, repository_id)
executable_mock.assert_called_once_with(repository_paths, args.build_command, "x86_64") executable_mock.assert_called_once_with(repository_paths, repository_id)
init_mock.assert_called_once_with() init_mock.assert_called_once_with()
@ -80,21 +79,20 @@ def test_run_with_server(args: argparse.Namespace, configuration: Configuration,
mocker.patch("ahriman.core.alpm.repo.Repo.init") mocker.patch("ahriman.core.alpm.repo.Repo.init")
devtools_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_devtools") devtools_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_devtools")
Setup.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Setup.run(args, repository_id, configuration, report=False)
devtools_configuration_mock.assert_called_once_with( devtools_configuration_mock.assert_called_once_with(
args.build_command, "x86_64", args.from_configuration, args.mirror, args.multilib, args.repository, repository_id, args.from_configuration, args.mirror, args.multilib, "server")
"server")
def test_build_command(args: argparse.Namespace) -> None: def test_build_command(repository_id: RepositoryId) -> None:
""" """
must generate correct build command name must generate correct build command name
""" """
args = _default_args(args)
path = Path("local") path = Path("local")
build_command = Setup.build_command(path, args.build_command, "x86_64") build_command = Setup.build_command(path, repository_id)
assert build_command.name == f"{args.build_command}-x86_64-build" assert build_command.name == f"{repository_id.name}-{repository_id.architecture}-build"
assert build_command.parent == path assert build_command.parent == path
@ -107,19 +105,26 @@ def test_configuration_create_ahriman(args: argparse.Namespace, configuration: C
mocker.patch("pathlib.Path.open") mocker.patch("pathlib.Path.open")
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option") set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
command = Setup.build_command(repository_paths.root, args.build_command, "x86_64") _, repository_id = configuration.check_loaded()
command = Setup.build_command(repository_paths.root, repository_id)
Setup.configuration_create_ahriman(args, "x86_64", args.repository, configuration) Setup.configuration_create_ahriman(args, repository_id, configuration)
set_option_mock.assert_has_calls([ set_option_mock.assert_has_calls([
MockCall(Configuration.section_name("build", "x86_64"), "build_command", str(command)), MockCall(Configuration.section_name("build", repository_id.name, repository_id.architecture), "build_command",
MockCall("repository", "name", args.repository), str(command)),
MockCall(Configuration.section_name("build", "x86_64"), "makechrootpkg_flags", f"-U {args.build_as_user}"), MockCall("repository", "name", repository_id.name),
MockCall(Configuration.section_name("alpm", "x86_64"), "mirror", args.mirror), MockCall(Configuration.section_name("build", repository_id.name, repository_id.architecture),
MockCall(Configuration.section_name("sign", "x86_64"), "target", "makechrootpkg_flags", f"-U {args.build_as_user}"),
MockCall(Configuration.section_name(
"alpm", repository_id.name, repository_id.architecture), "mirror", args.mirror),
MockCall(Configuration.section_name("sign", repository_id.name, repository_id.architecture), "target",
" ".join([target.name.lower() for target in args.sign_target])), " ".join([target.name.lower() for target in args.sign_target])),
MockCall(Configuration.section_name("sign", "x86_64"), "key", args.sign_key), MockCall(Configuration.section_name("sign", repository_id.name, repository_id.architecture), "key",
MockCall(Configuration.section_name("web", "x86_64"), "port", str(args.web_port)), args.sign_key),
MockCall(Configuration.section_name("web", "x86_64"), "unix_socket", str(args.web_unix_socket)), 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("auth", "salt", pytest.helpers.anyvar(str, strict=True)), MockCall("auth", "salt", pytest.helpers.anyvar(str, strict=True)),
]) ])
write_mock.assert_called_once_with(pytest.helpers.anyvar(int)) write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
@ -136,13 +141,16 @@ def test_configuration_create_ahriman_no_multilib(args: argparse.Namespace, conf
mocker.patch("ahriman.core.configuration.Configuration.write") mocker.patch("ahriman.core.configuration.Configuration.write")
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option") set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
Setup.configuration_create_ahriman(args, "x86_64", args.repository, configuration) _, repository_id = configuration.check_loaded()
Setup.configuration_create_ahriman(args, repository_id, configuration)
set_option_mock.assert_has_calls([ set_option_mock.assert_has_calls([
MockCall(Configuration.section_name("alpm", "x86_64"), "mirror", args.mirror), MockCall(Configuration.section_name("alpm", repository_id.name, repository_id.architecture), "mirror",
args.mirror),
]) # non-strict check called intentionally ]) # non-strict check called intentionally
def test_configuration_create_devtools(args: argparse.Namespace, mocker: MockerFixture) -> None: def test_configuration_create_devtools(args: argparse.Namespace, configuration: Configuration,
mocker: MockerFixture) -> None:
""" """
must create configuration for the devtools must create configuration for the devtools
""" """
@ -152,13 +160,14 @@ def test_configuration_create_devtools(args: argparse.Namespace, mocker: MockerF
add_section_mock = mocker.patch("ahriman.core.configuration.Configuration.add_section") add_section_mock = mocker.patch("ahriman.core.configuration.Configuration.add_section")
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration, _, repository_id = configuration.check_loaded()
None, args.multilib, args.repository, "server") Setup.configuration_create_devtools(repository_id, args.from_configuration, None, args.multilib, "server")
add_section_mock.assert_has_calls([MockCall("multilib"), MockCall(args.repository)]) add_section_mock.assert_has_calls([MockCall("multilib"), MockCall(repository_id.name)])
write_mock.assert_called_once_with(pytest.helpers.anyvar(int)) write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
def test_configuration_create_devtools_mirror(args: argparse.Namespace, mocker: MockerFixture) -> None: def test_configuration_create_devtools_mirror(args: argparse.Namespace, configuration: Configuration,
mocker: MockerFixture) -> None:
""" """
must create configuration for the devtools with mirror set explicitly must create configuration for the devtools with mirror set explicitly
""" """
@ -176,14 +185,15 @@ def test_configuration_create_devtools_mirror(args: argparse.Namespace, mocker:
remove_option_mock = mocker.patch("ahriman.core.configuration.Configuration.remove_option") remove_option_mock = mocker.patch("ahriman.core.configuration.Configuration.remove_option")
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option") set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration, _, repository_id = configuration.check_loaded()
args.mirror, False, args.repository, "server") Setup.configuration_create_devtools(repository_id, args.from_configuration, args.mirror, args.multilib, "server")
get_mock.assert_has_calls([MockCall("core", "Include", fallback=None), MockCall("extra", "Include", fallback=None)]) get_mock.assert_has_calls([MockCall("core", "Include", fallback=None), MockCall("extra", "Include", fallback=None)])
remove_option_mock.assert_called_once_with("core", "Include") remove_option_mock.assert_called_once_with("core", "Include")
set_option_mock.assert_has_calls([MockCall("core", "Server", args.mirror)]) # non-strict check called intentionally set_option_mock.assert_has_calls([MockCall("core", "Server", args.mirror)]) # non-strict check called intentionally
def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, mocker: MockerFixture) -> None: def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, configuration: Configuration,
mocker: MockerFixture) -> None:
""" """
must create configuration for the devtools without multilib must create configuration for the devtools without multilib
""" """
@ -192,8 +202,8 @@ def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, moc
mocker.patch("ahriman.core.configuration.Configuration.set") mocker.patch("ahriman.core.configuration.Configuration.set")
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration, _, repository_id = configuration.check_loaded()
None, False, args.repository, "server") Setup.configuration_create_devtools(repository_id, args.from_configuration, args.mirror, False, "server")
write_mock.assert_called_once_with(pytest.helpers.anyvar(int)) write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
@ -211,31 +221,32 @@ def test_configuration_create_makepkg(args: argparse.Namespace, repository_paths
Path("home") / ".makepkg.conf", pytest.helpers.anyvar(str, True), encoding="utf8") Path("home") / ".makepkg.conf", pytest.helpers.anyvar(str, True), encoding="utf8")
def test_configuration_create_sudo(args: argparse.Namespace, repository_paths: RepositoryPaths, def test_configuration_create_sudo(configuration: Configuration, repository_paths: RepositoryPaths,
mocker: MockerFixture) -> None: mocker: MockerFixture) -> None:
""" """
must create sudo configuration must create sudo configuration
""" """
args = _default_args(args)
chmod_text_mock = mocker.patch("pathlib.Path.chmod") chmod_text_mock = mocker.patch("pathlib.Path.chmod")
write_text_mock = mocker.patch("pathlib.Path.write_text") write_text_mock = mocker.patch("pathlib.Path.write_text")
Setup.configuration_create_sudo(repository_paths, args.build_command, "x86_64") _, repository_id = configuration.check_loaded()
Setup.configuration_create_sudo(repository_paths, repository_id)
chmod_text_mock.assert_called_once_with(0o400) chmod_text_mock.assert_called_once_with(0o400)
write_text_mock.assert_called_once_with(pytest.helpers.anyvar(str, True), encoding="utf8") write_text_mock.assert_called_once_with(pytest.helpers.anyvar(str, True), encoding="utf8")
def test_executable_create(args: argparse.Namespace, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None: def test_executable_create(configuration: Configuration, repository_paths: RepositoryPaths,
mocker: MockerFixture) -> None:
""" """
must create executable must create executable
""" """
args = _default_args(args)
chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.chown") chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.chown")
symlink_mock = mocker.patch("pathlib.Path.symlink_to") symlink_mock = mocker.patch("pathlib.Path.symlink_to")
unlink_mock = mocker.patch("pathlib.Path.unlink") unlink_mock = mocker.patch("pathlib.Path.unlink")
Setup.executable_create(repository_paths, args.build_command, "x86_64") _, repository_id = configuration.check_loaded()
chown_mock.assert_called_once_with(Setup.build_command(repository_paths.root, args.build_command, "x86_64")) Setup.executable_create(repository_paths, repository_id)
chown_mock.assert_called_once_with(Setup.build_command(repository_paths.root, repository_id))
symlink_mock.assert_called_once_with(Setup.ARCHBUILD_COMMAND_PATH) symlink_mock.assert_called_once_with(Setup.ARCHBUILD_COMMAND_PATH)
unlink_mock.assert_called_once_with(missing_ok=True) unlink_mock.assert_called_once_with(missing_ok=True)

View File

@ -32,7 +32,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
application_mock = mocker.patch("code.interact") application_mock = mocker.patch("code.interact")
Shell.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Shell.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(local=pytest.helpers.anyvar(int)) application_mock.assert_called_once_with(local=pytest.helpers.anyvar(int))
@ -46,7 +47,8 @@ def test_run_eval(args: argparse.Namespace, configuration: Configuration, reposi
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
application_mock = mocker.patch("code.InteractiveConsole.runcode") application_mock = mocker.patch("code.InteractiveConsole.runcode")
Shell.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Shell.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(args.code) application_mock.assert_called_once_with(args.code)
@ -62,7 +64,8 @@ def test_run_verbose(args: argparse.Namespace, configuration: Configuration, rep
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
application_mock = mocker.patch("code.interact") application_mock = mocker.patch("code.interact")
Shell.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Shell.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(local=pytest.helpers.anyvar(int)) application_mock.assert_called_once_with(local=pytest.helpers.anyvar(int))
read_mock.assert_called_once_with(encoding="utf8") read_mock.assert_called_once_with(encoding="utf8")
print_mock.assert_called_once_with(verbose=False) print_mock.assert_called_once_with(verbose=False)

View File

@ -30,5 +30,6 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
application_mock = mocker.patch("ahriman.application.application.Application.sign") application_mock = mocker.patch("ahriman.application.application.Application.sign")
Sign.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Sign.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with([]) application_mock.assert_called_once_with([])

View File

@ -43,7 +43,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
Status.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Status.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with() application_mock.assert_called_once_with()
packages_mock.assert_called_once_with(None) packages_mock.assert_called_once_with(None)
check_mock.assert_called_once_with(False, False) check_mock.assert_called_once_with(False, False)
@ -62,7 +63,8 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
mocker.patch("ahriman.core.status.client.Client.package_get", return_value=[]) mocker.patch("ahriman.core.status.client.Client.package_get", return_value=[])
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
Status.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Status.run(args, repository_id, configuration, report=False)
check_mock.assert_called_once_with(True, True) check_mock.assert_called_once_with(True, True)
@ -78,7 +80,8 @@ def test_run_verbose(args: argparse.Namespace, configuration: Configuration, rep
return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))]) return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))])
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
Status.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Status.run(args, repository_id, configuration, report=False)
print_mock.assert_has_calls([MockCall(verbose=True) for _ in range(2)]) print_mock.assert_has_calls([MockCall(verbose=True) for _ in range(2)])
@ -93,7 +96,8 @@ def test_run_with_package_filter(args: argparse.Namespace, configuration: Config
packages_mock = mocker.patch("ahriman.core.status.client.Client.package_get", packages_mock = mocker.patch("ahriman.core.status.client.Client.package_get",
return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))]) return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))])
Status.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Status.run(args, repository_id, configuration, report=False)
packages_mock.assert_called_once_with(package_ahriman.base) packages_mock.assert_called_once_with(package_ahriman.base)
@ -110,7 +114,8 @@ def test_run_by_status(args: argparse.Namespace, configuration: Configuration, r
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
Status.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Status.run(args, repository_id, configuration, report=False)
print_mock.assert_has_calls([MockCall(verbose=False) for _ in range(2)]) print_mock.assert_has_calls([MockCall(verbose=False) for _ in range(2)])
@ -123,8 +128,9 @@ def test_imply_with_report(args: argparse.Namespace, configuration: Configuratio
mocker.patch("ahriman.core.database.SQLite.load", return_value=database) mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
load_mock = mocker.patch("ahriman.core.repository.Repository.load") load_mock = mocker.patch("ahriman.core.repository.Repository.load")
Status.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
load_mock.assert_called_once_with("x86_64", configuration, database, report=True, refresh_pacman_database=0) Status.run(args, repository_id, configuration, report=False)
load_mock.assert_called_once_with(repository_id, configuration, database, report=True, refresh_pacman_database=0)
def test_disallow_auto_architecture_run() -> None: def test_disallow_auto_architecture_run() -> None:

View File

@ -36,7 +36,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
update_self_mock = mocker.patch("ahriman.core.status.client.Client.status_update") update_self_mock = mocker.patch("ahriman.core.status.client.Client.status_update")
StatusUpdate.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
StatusUpdate.run(args, repository_id, configuration, report=False)
update_self_mock.assert_called_once_with(args.status) update_self_mock.assert_called_once_with(args.status)
@ -50,7 +51,8 @@ def test_run_packages(args: argparse.Namespace, configuration: Configuration, re
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
update_mock = mocker.patch("ahriman.core.status.client.Client.package_update") update_mock = mocker.patch("ahriman.core.status.client.Client.package_update")
StatusUpdate.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
StatusUpdate.run(args, repository_id, configuration, report=False)
update_mock.assert_called_once_with(package_ahriman.base, args.status) update_mock.assert_called_once_with(package_ahriman.base, args.status)
@ -65,7 +67,8 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, repo
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
update_mock = mocker.patch("ahriman.core.status.client.Client.package_remove") update_mock = mocker.patch("ahriman.core.status.client.Client.package_remove")
StatusUpdate.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
StatusUpdate.run(args, repository_id, configuration, report=False)
update_mock.assert_called_once_with(package_ahriman.base) update_mock.assert_called_once_with(package_ahriman.base)
@ -78,8 +81,9 @@ def test_imply_with_report(args: argparse.Namespace, configuration: Configuratio
mocker.patch("ahriman.core.database.SQLite.load", return_value=database) mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
load_mock = mocker.patch("ahriman.core.repository.Repository.load") load_mock = mocker.patch("ahriman.core.repository.Repository.load")
StatusUpdate.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
load_mock.assert_called_once_with("x86_64", configuration, database, report=True, refresh_pacman_database=0) StatusUpdate.run(args, repository_id, configuration, report=False)
load_mock.assert_called_once_with(repository_id, configuration, database, report=True, refresh_pacman_database=0)
def test_disallow_auto_architecture_run() -> None: def test_disallow_auto_architecture_run() -> None:

View File

@ -35,7 +35,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
application_mock = mocker.patch("ahriman.core.tree.Tree.resolve", return_value=[[package_ahriman]]) application_mock = mocker.patch("ahriman.core.tree.Tree.resolve", return_value=[[package_ahriman]])
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
Structure.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Structure.run(args, repository_id, configuration, report=False)
packages_mock.assert_called_once_with([package_ahriman], count=args.partitions) packages_mock.assert_called_once_with([package_ahriman], count=args.partitions)
application_mock.assert_called_once_with([package_ahriman]) application_mock.assert_called_once_with([package_ahriman])
print_mock.assert_has_calls([ print_mock.assert_has_calls([

View File

@ -33,7 +33,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
application_mock = mocker.patch("ahriman.application.application.Application.on_result") application_mock = mocker.patch("ahriman.application.application.Application.on_result")
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
Triggers.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Triggers.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(Result()) application_mock.assert_called_once_with(Result())
on_start_mock.assert_called_once_with() on_start_mock.assert_called_once_with()
@ -50,6 +51,7 @@ def test_run_trigger(args: argparse.Namespace, configuration: Configuration, rep
report_mock = mocker.patch("ahriman.core.report.ReportTrigger.on_result") report_mock = mocker.patch("ahriman.core.report.ReportTrigger.on_result")
upload_mock = mocker.patch("ahriman.core.upload.UploadTrigger.on_result") upload_mock = mocker.patch("ahriman.core.upload.UploadTrigger.on_result")
Triggers.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Triggers.run(args, repository_id, configuration, report=False)
report_mock.assert_called_once_with(Result(), [package_ahriman]) report_mock.assert_called_once_with(Result(), [package_ahriman])
upload_mock.assert_not_called() upload_mock.assert_not_called()

View File

@ -32,7 +32,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
return_value=["command"]) return_value=["command"])
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
UnsafeCommands.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
UnsafeCommands.run(args, repository_id, configuration, report=False)
commands_mock.assert_called_once_with(pytest.helpers.anyvar(int)) commands_mock.assert_called_once_with(pytest.helpers.anyvar(int))
print_mock.assert_called_once_with(verbose=True) print_mock.assert_called_once_with(verbose=True)
@ -47,7 +48,8 @@ def test_run_check(args: argparse.Namespace, configuration: Configuration, mocke
return_value=["command"]) return_value=["command"])
check_mock = mocker.patch("ahriman.application.handlers.UnsafeCommands.check_unsafe") check_mock = mocker.patch("ahriman.application.handlers.UnsafeCommands.check_unsafe")
UnsafeCommands.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
UnsafeCommands.run(args, repository_id, configuration, report=False)
commands_mock.assert_called_once_with(pytest.helpers.anyvar(int)) commands_mock.assert_called_once_with(pytest.helpers.anyvar(int))
check_mock.assert_called_once_with(["clean"], ["command"], pytest.helpers.anyvar(int)) check_mock.assert_called_once_with(["clean"], ["command"], pytest.helpers.anyvar(int))

View File

@ -54,7 +54,8 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
print_mock = mocker.patch("ahriman.application.application.Application.print_updates") print_mock = mocker.patch("ahriman.application.application.Application.print_updates")
Update.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Update.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with([package_ahriman], application_mock.assert_called_once_with([package_ahriman],
Packagers(args.username, {package_ahriman.base: "packager"}), Packagers(args.username, {package_ahriman.base: "packager"}),
bump_pkgrel=args.increment) bump_pkgrel=args.increment)
@ -77,7 +78,8 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
mocker.patch("ahriman.application.application.Application.updates", return_value=[]) mocker.patch("ahriman.application.application.Application.updates", return_value=[])
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
Update.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Update.run(args, repository_id, configuration, report=False)
check_mock.assert_called_once_with(True, True) check_mock.assert_called_once_with(True, True)
@ -95,7 +97,8 @@ def test_run_update_empty_exception(args: argparse.Namespace, package_ahriman: P
mocker.patch("ahriman.application.application.Application.print_updates") mocker.patch("ahriman.application.application.Application.print_updates")
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
Update.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Update.run(args, repository_id, configuration, report=False)
check_mock.assert_has_calls([MockCall(True, False), MockCall(True, True)]) check_mock.assert_has_calls([MockCall(True, False), MockCall(True, True)])
@ -111,7 +114,8 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, rep
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
updates_mock = mocker.patch("ahriman.application.application.Application.updates") updates_mock = mocker.patch("ahriman.application.application.Application.updates")
Update.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Update.run(args, repository_id, configuration, report=False)
updates_mock.assert_called_once_with(args.package, aur=args.aur, local=args.local, manual=args.manual, vcs=args.vcs) updates_mock.assert_called_once_with(args.package, aur=args.aur, local=args.local, manual=args.manual, vcs=args.vcs)
application_mock.assert_not_called() application_mock.assert_not_called()
check_mock.assert_called_once_with(False, pytest.helpers.anyvar(int)) check_mock.assert_called_once_with(False, pytest.helpers.anyvar(int))

View File

@ -47,7 +47,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, database: S
create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user) create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user)
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update") update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
Users.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Users.run(args, repository_id, configuration, report=False)
create_user_mock.assert_called_once_with(args) create_user_mock.assert_called_once_with(args)
update_mock.assert_called_once_with(user) update_mock.assert_called_once_with(user)
@ -64,7 +65,8 @@ def test_run_empty_salt(args: argparse.Namespace, configuration: Configuration,
create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user) create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user)
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update") update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
Users.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Users.run(args, repository_id, configuration, report=False)
create_user_mock.assert_called_once_with(args) create_user_mock.assert_called_once_with(args)
update_mock.assert_called_once_with(user) update_mock.assert_called_once_with(user)
@ -83,7 +85,8 @@ def test_run_empty_salt_without_password(args: argparse.Namespace, configuration
create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user) create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user)
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update") update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
Users.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Users.run(args, repository_id, configuration, report=False)
create_user_mock.assert_called_once_with(args) create_user_mock.assert_called_once_with(args)
update_mock.assert_called_once_with(user) update_mock.assert_called_once_with(user)
@ -99,7 +102,8 @@ def test_run_list(args: argparse.Namespace, configuration: Configuration, databa
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
list_mock = mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[user]) list_mock = mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[user])
Users.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Users.run(args, repository_id, configuration, report=False)
list_mock.assert_called_once_with("user", args.role) list_mock.assert_called_once_with("user", args.role)
check_mock.assert_called_once_with(False, False) check_mock.assert_called_once_with(False, False)
@ -116,7 +120,8 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[]) mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[])
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
Users.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Users.run(args, repository_id, configuration, report=False)
check_mock.assert_called_once_with(True, True) check_mock.assert_called_once_with(True, True)
@ -130,7 +135,8 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, data
mocker.patch("ahriman.core.database.SQLite.load", return_value=database) mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
remove_mock = mocker.patch("ahriman.core.database.SQLite.user_remove") remove_mock = mocker.patch("ahriman.core.database.SQLite.user_remove")
Users.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Users.run(args, repository_id, configuration, report=False)
remove_mock.assert_called_once_with(args.username) remove_mock.assert_called_once_with(args.username)

View File

@ -33,8 +33,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
application_mock = mocker.patch("ahriman.core.configuration.validator.Validator.validate", return_value=False) application_mock = mocker.patch("ahriman.core.configuration.validator.Validator.validate", return_value=False)
Validate.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Validate.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with(configuration.dump()) application_mock.assert_called_once_with(configuration.dump())
print_mock.assert_called_once_with(verbose=True) print_mock.assert_called_once_with(verbose=True)
@ -47,7 +47,8 @@ def test_run_skip(args: argparse.Namespace, configuration: Configuration, mocker
mocker.patch("ahriman.core.configuration.validator.Validator.validate", return_value=True) mocker.patch("ahriman.core.configuration.validator.Validator.validate", return_value=True)
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
Validate.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Validate.run(args, repository_id, configuration, report=False)
print_mock.assert_not_called() print_mock.assert_not_called()
@ -55,7 +56,8 @@ def test_schema(configuration: Configuration) -> None:
""" """
must generate full schema correctly must generate full schema correctly
""" """
schema = Validate.schema("x86_64", configuration) _, repository_id = configuration.check_loaded()
schema = Validate.schema(repository_id, configuration)
# defaults # defaults
assert schema.pop("console") assert schema.pop("console")
@ -86,7 +88,9 @@ def test_schema_invalid_trigger(configuration: Configuration) -> None:
""" """
configuration.set_option("build", "triggers", "some.invalid.trigger.path.Trigger") configuration.set_option("build", "triggers", "some.invalid.trigger.path.Trigger")
configuration.remove_option("build", "triggers_known") configuration.remove_option("build", "triggers_known")
assert Validate.schema("x86_64", configuration) == CONFIGURATION_SCHEMA _, repository_id = configuration.check_loaded()
assert Validate.schema(repository_id, configuration) == CONFIGURATION_SCHEMA
def test_schema_erase_required() -> None: def test_schema_erase_required() -> None:

View File

@ -14,7 +14,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
application_mock = mocker.patch("ahriman.application.handlers.Versions.package_dependencies") application_mock = mocker.patch("ahriman.application.handlers.Versions.package_dependencies")
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
Versions.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
Versions.run(args, repository_id, configuration, report=False)
application_mock.assert_called_once_with("ahriman") application_mock.assert_called_once_with("ahriman")
print_mock.assert_has_calls([MockCall(verbose=False, separator=" "), MockCall(verbose=False, separator=" ")]) print_mock.assert_has_calls([MockCall(verbose=False, separator=" "), MockCall(verbose=False, separator=" ")])

View File

@ -41,8 +41,9 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
stop_mock = mocker.patch("ahriman.core.spawn.Spawn.stop") stop_mock = mocker.patch("ahriman.core.spawn.Spawn.stop")
join_mock = mocker.patch("ahriman.core.spawn.Spawn.join") join_mock = mocker.patch("ahriman.core.spawn.Spawn.join")
Web.run(args, "x86_64", configuration, report=False) _, repository_id = configuration.check_loaded()
setup_mock.assert_called_once_with("x86_64", configuration, pytest.helpers.anyvar(int)) Web.run(args, repository_id, configuration, report=False)
setup_mock.assert_called_once_with(repository_id, configuration, pytest.helpers.anyvar(int))
run_mock.assert_called_once_with(pytest.helpers.anyvar(int)) run_mock.assert_called_once_with(pytest.helpers.anyvar(int))
start_mock.assert_called_once_with() start_mock.assert_called_once_with()
stop_mock.assert_called_once_with() stop_mock.assert_called_once_with()
@ -53,33 +54,35 @@ def test_extract_arguments(args: argparse.Namespace, configuration: Configuratio
""" """
must extract correct args must extract correct args
""" """
_, repository_id = configuration.check_loaded()
expected = [ expected = [
"--architecture", "x86_64", "--architecture", repository_id.architecture,
"--repository", repository_id.name,
"--configuration", str(configuration.path), "--configuration", str(configuration.path),
] ]
probe = _default_args(args) probe = _default_args(args)
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
probe.force = True probe.force = True
expected.extend(["--force"]) expected.extend(["--force"])
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
probe.log_handler = LogHandler.Console probe.log_handler = LogHandler.Console
expected.extend(["--log-handler", probe.log_handler.value]) expected.extend(["--log-handler", probe.log_handler.value])
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
probe.quiet = True probe.quiet = True
expected.extend(["--quiet"]) expected.extend(["--quiet"])
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
probe.unsafe = True probe.unsafe = True
expected.extend(["--unsafe"]) expected.extend(["--unsafe"])
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
configuration.set_option("web", "wait_timeout", "60") configuration.set_option("web", "wait_timeout", "60")
expected.extend(["--wait-timeout", "60"]) expected.extend(["--wait-timeout", "60"])
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
def test_extract_arguments_full(parser: argparse.ArgumentParser, configuration: Configuration): def test_extract_arguments_full(parser: argparse.ArgumentParser, configuration: Configuration):
@ -101,8 +104,10 @@ def test_extract_arguments_full(parser: argparse.ArgumentParser, configuration:
value = action.type(value) value = action.type(value)
setattr(args, action.dest, value) setattr(args, action.dest, value)
assert list(Web.extract_arguments(args, "x86_64", configuration)) == [ _, repository_id = configuration.check_loaded()
"--architecture", "x86_64", assert list(Web.extract_arguments(args, repository_id, configuration)) == [
"--architecture", repository_id.architecture,
"--repository", repository_id.name,
"--configuration", str(configuration.path), "--configuration", str(configuration.path),
"--force", "--force",
"--log-handler", "console", "--log-handler", "console",

View File

@ -6,6 +6,7 @@ from pytest_mock import MockerFixture
from ahriman.application import ahriman from ahriman.application import ahriman
from ahriman.application.handlers import Handler from ahriman.application.handlers import Handler
from ahriman.core.configuration import Configuration
from ahriman.models.action import Action from ahriman.models.action import Action
from ahriman.models.build_status import BuildStatusEnum from ahriman.models.build_status import BuildStatusEnum
from ahriman.models.log_handler import LogHandler from ahriman.models.log_handler import LogHandler
@ -66,6 +67,14 @@ def test_multiple_architectures(parser: argparse.ArgumentParser) -> None:
assert args.architecture == ["x86_64", "i686"] assert args.architecture == ["x86_64", "i686"]
def test_multiple_repositories(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: def test_subparsers_aur_search(parser: argparse.ArgumentParser) -> None:
""" """
aur-search command must imply architecture list, lock, report, quiet and unsafe aur-search command must imply architecture list, lock, report, quiet and unsafe
@ -708,8 +717,7 @@ def test_subparsers_service_setup(parser: argparse.ArgumentParser) -> None:
""" """
service-setup command must imply lock, report, quiet and unsafe service-setup command must imply lock, report, quiet and unsafe
""" """
args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>", args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>"])
"--repository", "aur-clone"])
assert args.architecture == ["x86_64"] assert args.architecture == ["x86_64"]
assert args.lock is None assert args.lock is None
assert not args.report assert not args.report
@ -721,11 +729,10 @@ def test_subparsers_service_setup_option_from_configuration(parser: argparse.Arg
""" """
service-setup command must convert from-configuration option to path instance service-setup command must convert from-configuration option to path instance
""" """
args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>", args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>"])
"--repository", "aur-clone"])
assert isinstance(args.from_configuration, Path) assert isinstance(args.from_configuration, Path)
args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>", args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>",
"--repository", "aur-clone", "--from-configuration", "path"]) "--from-configuration", "path"])
assert isinstance(args.from_configuration, Path) assert isinstance(args.from_configuration, Path)
@ -734,7 +741,7 @@ def test_subparsers_service_setup_option_sign_target(parser: argparse.ArgumentPa
service-setup command must convert sign-target option to SignSettings instance service-setup command must convert sign-target option to SignSettings instance
""" """
args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>", args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>",
"--repository", "aur-clone", "--sign-target", "packages"]) "--sign-target", "packages"])
assert args.sign_target assert args.sign_target
assert all(isinstance(target, SignSettings) for target in args.sign_target) assert all(isinstance(target, SignSettings) for target in args.sign_target)
@ -837,11 +844,15 @@ def test_subparsers_web(parser: argparse.ArgumentParser) -> None:
assert args.parser is not None and args.parser() assert args.parser is not None and args.parser()
def test_run(args: argparse.Namespace, mocker: MockerFixture) -> None: def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
""" """
application must be run application must be run
""" """
args.architecture = "x86_64" path, repository_id = configuration.check_loaded()
args.architecture = repository_id.architecture
args.repository = repository_id.name
args.configuration = path
args.command = "" args.command = ""
args.handler = Handler args.handler = Handler

View File

@ -18,14 +18,16 @@ def test_path(args: argparse.Namespace, configuration: Configuration) -> None:
""" """
must create path variable correctly must create path variable correctly
""" """
assert Lock(args, "x86_64", configuration).path is None _, repository_id = configuration.check_loaded()
assert Lock(args, repository_id, configuration).path is None
args.lock = Path("/run/ahriman.lock") args.lock = Path("/run/ahriman.lock")
assert Lock(args, "x86_64", configuration).path == Path("/run/ahriman_x86_64.lock") assert Lock(args, repository_id, configuration).path == Path("/run/ahriman_aur-clone_x86_64.lock")
with pytest.raises(ValueError): with pytest.raises(ValueError):
args.lock = Path("/") args.lock = Path("/")
Lock(args, "x86_64", configuration).path # special case Lock(args, repository_id, configuration).path # special case
def test_check_version(lock: Lock, mocker: MockerFixture) -> None: def test_check_version(lock: Lock, mocker: MockerFixture) -> None:

View File

@ -19,12 +19,13 @@ def test_init_with_local_cache(configuration: Configuration, mocker: MockerFixtu
mocker.patch("ahriman.core.alpm.pacman.Pacman.database_copy") mocker.patch("ahriman.core.alpm.pacman.Pacman.database_copy")
sync_mock = mocker.patch("ahriman.core.alpm.pacman.Pacman.database_sync") sync_mock = mocker.patch("ahriman.core.alpm.pacman.Pacman.database_sync")
configuration.set_option("alpm", "use_ahriman_cache", "yes") configuration.set_option("alpm", "use_ahriman_cache", "yes")
_, repository_id = configuration.check_loaded()
# pyalpm.Handle is trying to reach the directory we've asked, thus we need to patch it a bit # pyalpm.Handle is trying to reach the directory we've asked, thus we need to patch it a bit
with TemporaryDirectory(ignore_cleanup_errors=True) as pacman_root: with TemporaryDirectory(ignore_cleanup_errors=True) as pacman_root:
mocker.patch.object(RepositoryPaths, "pacman", Path(pacman_root)) mocker.patch.object(RepositoryPaths, "pacman", Path(pacman_root))
# during the creation pyalpm.Handle will create also version file which we would like to remove later # during the creation pyalpm.Handle will create also version file which we would like to remove later
pacman = Pacman("x86_64", configuration, refresh_database=PacmanSynchronization.Enabled) pacman = Pacman(repository_id, configuration, refresh_database=PacmanSynchronization.Enabled)
assert pacman.handle assert pacman.handle
sync_mock.assert_called_once_with(pytest.helpers.anyvar(int), force=False) sync_mock.assert_called_once_with(pytest.helpers.anyvar(int), force=False)
@ -36,12 +37,13 @@ def test_init_with_local_cache_forced(configuration: Configuration, mocker: Mock
mocker.patch("ahriman.core.alpm.pacman.Pacman.database_copy") mocker.patch("ahriman.core.alpm.pacman.Pacman.database_copy")
sync_mock = mocker.patch("ahriman.core.alpm.pacman.Pacman.database_sync") sync_mock = mocker.patch("ahriman.core.alpm.pacman.Pacman.database_sync")
configuration.set_option("alpm", "use_ahriman_cache", "yes") configuration.set_option("alpm", "use_ahriman_cache", "yes")
_, repository_id = configuration.check_loaded()
# pyalpm.Handle is trying to reach the directory we've asked, thus we need to patch it a bit # pyalpm.Handle is trying to reach the directory we've asked, thus we need to patch it a bit
with TemporaryDirectory(ignore_cleanup_errors=True) as pacman_root: with TemporaryDirectory(ignore_cleanup_errors=True) as pacman_root:
mocker.patch.object(RepositoryPaths, "pacman", Path(pacman_root)) mocker.patch.object(RepositoryPaths, "pacman", Path(pacman_root))
# during the creation pyalpm.Handle will create also version file which we would like to remove later # during the creation pyalpm.Handle will create also version file which we would like to remove later
pacman = Pacman("x86_64", configuration, refresh_database=PacmanSynchronization.Force) pacman = Pacman(repository_id, configuration, refresh_database=PacmanSynchronization.Force)
assert pacman.handle assert pacman.handle
sync_mock.assert_called_once_with(pytest.helpers.anyvar(int), force=True) sync_mock.assert_called_once_with(pytest.helpers.anyvar(int), force=True)
@ -128,8 +130,8 @@ def test_database_init(pacman: Pacman, configuration: Configuration) -> None:
must init database with settings must init database with settings
""" """
mirror = configuration.get("alpm", "mirror") mirror = configuration.get("alpm", "mirror")
database = pacman.database_init(pacman.handle, "test", mirror, "x86_64") database = pacman.database_init(pacman.handle, "testing", mirror, "x86_64")
assert len(database.servers) == 1 assert database.servers == ["https://geo.mirror.pkgbuild.com/testing/os/x86_64"]
def test_database_sync(pacman: Pacman) -> None: def test_database_sync(pacman: Pacman) -> None:

View File

@ -177,7 +177,7 @@ def test_load(package_ahriman: Package, repository_paths: RepositoryPaths, mocke
Sources.load(path, package_ahriman, [patch], repository_paths) Sources.load(path, package_ahriman, [patch], repository_paths)
fetch_mock.assert_called_once_with(path, package_ahriman.remote) fetch_mock.assert_called_once_with(path, package_ahriman.remote)
patch_mock.assert_called_once_with(path, patch) patch_mock.assert_called_once_with(path, patch)
architectures_mock.assert_called_once_with(path, repository_paths.architecture) architectures_mock.assert_called_once_with(path, repository_paths.repository_id.architecture)
def test_load_no_patch(package_ahriman: Package, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None: def test_load_no_patch(package_ahriman: Package, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:

View File

@ -7,9 +7,17 @@ from unittest.mock import call as MockCall
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import InitializeError from ahriman.core.exceptions import InitializeError
from ahriman.models.repository_id import RepositoryId
from ahriman.models.repository_paths import RepositoryPaths from ahriman.models.repository_paths import RepositoryPaths
def test_architecture(configuration: Configuration) -> None:
"""
must return valid repository architecture
"""
assert configuration.architecture == "x86_64"
def test_repository_name(configuration: Configuration) -> None: def test_repository_name(configuration: Configuration) -> None:
""" """
must return valid repository name must return valid repository name
@ -24,7 +32,7 @@ def test_repository_paths(configuration: Configuration, repository_paths: Reposi
assert configuration.repository_paths == repository_paths assert configuration.repository_paths == repository_paths
def test_from_path(mocker: MockerFixture) -> None: def test_from_path(repository_id: RepositoryId, mocker: MockerFixture) -> None:
""" """
must load configuration must load configuration
""" """
@ -33,13 +41,13 @@ def test_from_path(mocker: MockerFixture) -> None:
load_includes_mock = mocker.patch("ahriman.core.configuration.Configuration.load_includes") load_includes_mock = mocker.patch("ahriman.core.configuration.Configuration.load_includes")
path = Path("path") path = Path("path")
configuration = Configuration.from_path(path, "x86_64") configuration = Configuration.from_path(path, repository_id)
assert configuration.path == path assert configuration.path == path
read_mock.assert_called_once_with(path) read_mock.assert_called_once_with(path)
load_includes_mock.assert_called_once_with() load_includes_mock.assert_called_once_with()
def test_from_path_file_missing(mocker: MockerFixture) -> None: def test_from_path_file_missing(repository_id: RepositoryId, mocker: MockerFixture) -> None:
""" """
must load configuration based on package files must load configuration based on package files
""" """
@ -47,17 +55,40 @@ def test_from_path_file_missing(mocker: MockerFixture) -> None:
mocker.patch("ahriman.core.configuration.Configuration.load_includes") mocker.patch("ahriman.core.configuration.Configuration.load_includes")
read_mock = mocker.patch("ahriman.core.configuration.Configuration.read") read_mock = mocker.patch("ahriman.core.configuration.Configuration.read")
configuration = Configuration.from_path(Path("path"), "x86_64") configuration = Configuration.from_path(Path("path"), repository_id)
read_mock.assert_called_once_with(configuration.SYSTEM_CONFIGURATION_PATH) read_mock.assert_called_once_with(configuration.SYSTEM_CONFIGURATION_PATH)
def test_override_sections(repository_id: RepositoryId) -> None:
"""
must correctly generate override section names
"""
assert Configuration.override_sections("build", repository_id) == [
"build:x86_64",
"build:aur-clone",
"build:aur-clone:x86_64",
]
def test_section_name(configuration: Configuration) -> None:
"""
must return architecture specific group
"""
assert configuration.section_name("build") == "build"
assert configuration.section_name("build", None) == "build"
assert configuration.section_name("build", "x86_64") == "build:x86_64"
assert configuration.section_name("build", "aur-clone", "x86_64") == "build:aur-clone:x86_64"
assert configuration.section_name("build", "aur-clone", None) == "build:aur-clone"
assert configuration.section_name("build", None, "x86_64") == "build:x86_64"
def test_check_loaded(configuration: Configuration) -> None: def test_check_loaded(configuration: Configuration) -> None:
""" """
must return valid path and architecture must return valid path and architecture
""" """
path, architecture = configuration.check_loaded() path, repository_id = configuration.check_loaded()
assert path == configuration.path assert path == configuration.path
assert architecture == configuration.architecture assert repository_id == configuration.repository_id
def test_check_loaded_path(configuration: Configuration) -> None: def test_check_loaded_path(configuration: Configuration) -> None:
@ -73,7 +104,7 @@ def test_check_loaded_architecture(configuration: Configuration) -> None:
""" """
must raise exception if architecture is none must raise exception if architecture is none
""" """
configuration.architecture = None configuration.repository_id = None
with pytest.raises(InitializeError): with pytest.raises(InitializeError):
configuration.check_loaded() configuration.check_loaded()
@ -89,9 +120,9 @@ def test_dump_architecture_specific(configuration: Configuration) -> None:
""" """
dump must contain architecture specific settings dump must contain architecture specific settings
""" """
section = configuration.section_name("build", "x86_64") section = configuration.section_name("build", configuration.architecture)
configuration.set_option(section, "archbuild_flags", "hello flag") configuration.set_option(section, "archbuild_flags", "hello flag")
configuration.merge_sections("x86_64") configuration.merge_sections(configuration.repository_id)
dump = configuration.dump() dump = configuration.dump()
assert dump assert dump
@ -100,13 +131,6 @@ def test_dump_architecture_specific(configuration: Configuration) -> None:
assert dump["build"]["archbuild_flags"] == "hello flag" assert dump["build"]["archbuild_flags"] == "hello flag"
def test_section_name(configuration: Configuration) -> None:
"""
must return architecture specific group
"""
assert configuration.section_name("build", "x86_64") == "build:x86_64"
def test_getlist(configuration: Configuration) -> None: def test_getlist(configuration: Configuration) -> None:
""" """
must return list of string correctly must return list of string correctly
@ -209,7 +233,7 @@ def test_gettype(configuration: Configuration) -> None:
""" """
must extract type from variable must extract type from variable
""" """
section, provider = configuration.gettype("customs3", "x86_64") section, provider = configuration.gettype("customs3", configuration.repository_id)
assert section == "customs3" assert section == "customs3"
assert provider == "s3" assert provider == "s3"
@ -218,7 +242,7 @@ def test_gettype_with_fallback(configuration: Configuration) -> None:
""" """
must return same provider name as in fallback must return same provider name as in fallback
""" """
section, provider = configuration.gettype("rsync", "x86_64", fallback="abracadabra") section, provider = configuration.gettype("rsync", configuration.repository_id, fallback="abracadabra")
assert section == "rsync" assert section == "rsync"
assert provider == "abracadabra" assert provider == "abracadabra"
@ -227,7 +251,7 @@ def test_gettype_from_section(configuration: Configuration) -> None:
""" """
must extract type from section name must extract type from section name
""" """
section, provider = configuration.gettype("rsync", "x86_64") section, provider = configuration.gettype("rsync", configuration.repository_id)
assert section == "rsync" assert section == "rsync"
assert provider == "rsync" assert provider == "rsync"
@ -236,7 +260,7 @@ def test_gettype_from_section_with_architecture(configuration: Configuration) ->
""" """
must extract type from section name with architecture must extract type from section name with architecture
""" """
section, provider = configuration.gettype("github", "x86_64") section, provider = configuration.gettype("github", configuration.repository_id)
assert section == "github:x86_64" assert section == "github:x86_64"
assert provider == "github" assert provider == "github"
@ -248,7 +272,7 @@ def test_gettype_from_section_no_section(configuration: Configuration) -> None:
# technically rsync:x86_64 is valid section # technically rsync:x86_64 is valid section
# but in current configuration it must be considered as missing section # but in current configuration it must be considered as missing section
with pytest.raises(configparser.NoSectionError): with pytest.raises(configparser.NoSectionError):
configuration.gettype("rsync:x86_64", "x86_64") configuration.gettype("rsync:x86_64", configuration.repository_id)
def test_load_includes_missing(configuration: Configuration) -> None: def test_load_includes_missing(configuration: Configuration) -> None:
@ -279,14 +303,44 @@ def test_merge_sections_missing(configuration: Configuration) -> None:
""" """
must merge create section if not exists must merge create section if not exists
""" """
section = configuration.section_name("build", "x86_64") section = configuration.section_name("build", configuration.architecture)
configuration.remove_section("build") configuration.remove_section("build")
configuration.set_option(section, "key", "value") configuration.set_option(section, "key", "value")
configuration.merge_sections("x86_64") configuration.merge_sections(configuration.repository_id)
assert configuration.get("build", "key") == "value" assert configuration.get("build", "key") == "value"
def test_merge_sections_priority(configuration: Configuration) -> None:
"""
must merge sections in valid order
"""
empty = "build"
arch = configuration.section_name(empty, configuration.architecture)
repo = configuration.section_name(empty, configuration.repository_name)
repo_arch = configuration.section_name(empty, configuration.repository_name, configuration.architecture)
configuration.set_option(empty, "key1", "key1_value1")
configuration.set_option(arch, "key1", "key1_value2")
configuration.set_option(repo, "key1", "key1_value3")
configuration.set_option(repo_arch, "key1", "key1_value4")
configuration.set_option(empty, "key2", "key2_value1")
configuration.set_option(arch, "key2", "key2_value2")
configuration.set_option(repo, "key2", "key2_value3")
configuration.set_option(empty, "key3", "key3_value1")
configuration.set_option(arch, "key3", "key3_value2")
configuration.set_option(empty, "key4", "key4_value1")
configuration.merge_sections(configuration.repository_id)
assert configuration.get("build", "key1") == "key1_value4"
assert configuration.get("build", "key2") == "key2_value3"
assert configuration.get("build", "key3") == "key3_value2"
assert configuration.get("build", "key4") == "key4_value1"
def test_reload(configuration: Configuration, mocker: MockerFixture) -> None: def test_reload(configuration: Configuration, mocker: MockerFixture) -> None:
""" """
must reload configuration must reload configuration
@ -296,7 +350,7 @@ def test_reload(configuration: Configuration, mocker: MockerFixture) -> None:
configuration.reload() configuration.reload()
load_mock.assert_called_once_with(configuration.path) load_mock.assert_called_once_with(configuration.path)
merge_mock.assert_called_once_with(configuration.architecture) merge_mock.assert_called_once_with(configuration.repository_id)
def test_reload_clear(configuration: Configuration, mocker: MockerFixture) -> None: def test_reload_clear(configuration: Configuration, mocker: MockerFixture) -> None:
@ -314,7 +368,7 @@ def test_reload_no_architecture(configuration: Configuration) -> None:
""" """
must raise exception on reload if no architecture set must raise exception on reload if no architecture set
""" """
configuration.architecture = None configuration.repository_id = None
with pytest.raises(InitializeError): with pytest.raises(InitializeError):
configuration.reload() configuration.reload()

View File

@ -2,10 +2,12 @@ import pytest
from sqlite3 import Connection from sqlite3 import Connection
from pytest_mock import MockerFixture from pytest_mock import MockerFixture
from unittest.mock import call as MockCall
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.database.migrations.m001_package_source import migrate_data, migrate_package_remotes, steps from ahriman.core.database.migrations.m001_package_source import migrate_data, migrate_package_remotes, steps
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.package_source import PackageSource
from ahriman.models.repository_paths import RepositoryPaths from ahriman.models.repository_paths import RepositoryPaths
@ -30,13 +32,18 @@ def test_migrate_package_remotes(package_ahriman: Package, connection: Connectio
""" """
must put package remotes to database must put package remotes to database
""" """
mocker.patch( connection.execute.return_value = [{
"ahriman.core.database.operations.PackageOperations._packages_get_select_package_bases", "package_base": package_ahriman.base,
return_value={package_ahriman.base: package_ahriman}) "version": package_ahriman.version,
"source": PackageSource.AUR,
}]
mocker.patch("pathlib.Path.exists", return_value=False) mocker.patch("pathlib.Path.exists", return_value=False)
migrate_package_remotes(connection, repository_paths) migrate_package_remotes(connection, repository_paths)
connection.execute.assert_called_once_with(pytest.helpers.anyvar(str, strict=True), pytest.helpers.anyvar(int)) connection.execute.assert_has_calls([
MockCall(pytest.helpers.anyvar(str, strict=True)),
MockCall(pytest.helpers.anyvar(str, strict=True), pytest.helpers.anyvar(int)),
])
def test_migrate_package_remotes_has_local(package_ahriman: Package, connection: Connection, def test_migrate_package_remotes_has_local(package_ahriman: Package, connection: Connection,
@ -44,13 +51,15 @@ def test_migrate_package_remotes_has_local(package_ahriman: Package, connection:
""" """
must skip processing for packages which have local cache must skip processing for packages which have local cache
""" """
mocker.patch( connection.execute.return_value = [{
"ahriman.core.database.operations.PackageOperations._packages_get_select_package_bases", "package_base": package_ahriman.base,
return_value={package_ahriman.base: package_ahriman}) "version": package_ahriman.version,
"source": PackageSource.AUR,
}]
mocker.patch("pathlib.Path.exists", return_value=True) mocker.patch("pathlib.Path.exists", return_value=True)
migrate_package_remotes(connection, repository_paths) migrate_package_remotes(connection, repository_paths)
connection.execute.assert_not_called() connection.execute.assert_called_once_with(pytest.helpers.anyvar(str, strict=True))
def test_migrate_package_remotes_vcs(package_ahriman: Package, connection: Connection, def test_migrate_package_remotes_vcs(package_ahriman: Package, connection: Connection,
@ -58,11 +67,16 @@ def test_migrate_package_remotes_vcs(package_ahriman: Package, connection: Conne
""" """
must process VCS packages with local cache must process VCS packages with local cache
""" """
mocker.patch( connection.execute.return_value = [{
"ahriman.core.database.operations.PackageOperations._packages_get_select_package_bases", "package_base": package_ahriman.base,
return_value={package_ahriman.base: package_ahriman}) "version": package_ahriman.version,
"source": PackageSource.AUR,
}]
mocker.patch("pathlib.Path.exists", return_value=True) mocker.patch("pathlib.Path.exists", return_value=True)
mocker.patch.object(Package, "is_vcs", True) mocker.patch.object(Package, "is_vcs", True)
migrate_package_remotes(connection, repository_paths) migrate_package_remotes(connection, repository_paths)
connection.execute.assert_called_once_with(pytest.helpers.anyvar(str, strict=True), pytest.helpers.anyvar(int)) connection.execute.assert_has_calls([
MockCall(pytest.helpers.anyvar(str, strict=True)),
MockCall(pytest.helpers.anyvar(str, strict=True), pytest.helpers.anyvar(int)),
])

View File

@ -0,0 +1,43 @@
import pytest
from pytest_mock import MockerFixture
from sqlite3 import Connection
from unittest.mock import call as MockCall
from ahriman.core.configuration import Configuration
from ahriman.core.database.migrations.m011_repository_name import migrate_data, migrate_package_repository, steps
def test_migration_check_depends() -> None:
"""
migration must not be empty
"""
assert steps
def test_migrate_data(connection: Connection, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must perform data migration
"""
repository_mock = mocker.patch("ahriman.core.database.migrations.m011_repository_name.migrate_package_repository")
migrate_data(connection, configuration)
repository_mock.assert_called_once_with(connection, configuration)
def test_migrate_package_repository(connection: Connection, configuration: Configuration) -> None:
"""
must correctly set repository and architecture
"""
migrate_package_repository(connection, configuration)
connection.execute.assert_has_calls([
MockCall(pytest.helpers.anyvar(str, strict=True),
{"repository": configuration.repository_name, "architecture": configuration.architecture}),
MockCall(pytest.helpers.anyvar(str, strict=True),
{"repository": configuration.repository_name, "architecture": configuration.architecture}),
MockCall(pytest.helpers.anyvar(str, strict=True),
{"repository": configuration.repository_name, "architecture": configuration.architecture}),
MockCall(pytest.helpers.anyvar(str, strict=True), {"repository": configuration.repository_name}),
MockCall(pytest.helpers.anyvar(str, strict=True),
{"repository": configuration.repository_name, "architecture": configuration.architecture}),
])

View File

@ -1,5 +1,6 @@
from ahriman.core.database import SQLite from ahriman.core.database import SQLite
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.repository_id import RepositoryId
def test_build_queue_insert_clear(database: SQLite, package_ahriman: Package, package_python_schedule: Package) -> None: def test_build_queue_insert_clear(database: SQLite, package_ahriman: Package, package_python_schedule: Package) -> None:
@ -13,6 +14,19 @@ def test_build_queue_insert_clear(database: SQLite, package_ahriman: Package, pa
assert not database.build_queue_get() assert not database.build_queue_get()
def test_build_queue_insert_clear_multi(database: SQLite, package_ahriman: Package) -> None:
"""
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.build_queue_insert(package_ahriman)
database.build_queue_clear(None)
database.repository_id = RepositoryId("x86_64", database.repository_id.name)
assert database.build_queue_get() == [package_ahriman]
def test_build_queue_insert_clear_specific(database: SQLite, package_ahriman: Package, def test_build_queue_insert_clear_specific(database: SQLite, package_ahriman: Package,
package_python_schedule: Package) -> None: package_python_schedule: Package) -> None:
""" """
@ -43,3 +57,30 @@ def test_build_queue_insert(database: SQLite, package_ahriman: Package) -> None:
package_ahriman.version = "42" package_ahriman.version = "42"
database.build_queue_insert(package_ahriman) database.build_queue_insert(package_ahriman)
assert database.build_queue_get() == [package_ahriman] assert database.build_queue_get() == [package_ahriman]
def test_build_queue_insert_multi(database: SQLite, package_ahriman: Package) -> None:
"""
must update build queue in the database for multiple architectures and repositories
"""
package_ahriman.version = "1"
database.build_queue_insert(package_ahriman)
assert database.build_queue_get() == [package_ahriman]
package_ahriman.version = "2"
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)
assert database.build_queue_get() == [package_ahriman]
package_ahriman.version = "3"
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")
assert database.build_queue_get() == [package_ahriman]

View File

@ -1,12 +1,13 @@
from ahriman.core.database import SQLite from ahriman.core.database import SQLite
from ahriman.models.log_record_id import LogRecordId from ahriman.models.log_record_id import LogRecordId
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.repository_id import RepositoryId
def test_logs_insert_remove_process(database: SQLite, package_ahriman: Package, def test_logs_insert_remove_version(database: SQLite, package_ahriman: Package,
package_python_schedule: Package) -> None: package_python_schedule: Package) -> None:
""" """
must clear process specific package logs must clear version specific package logs
""" """
database.logs_insert(LogRecordId(package_ahriman.base, "1"), 42.0, "message 1") database.logs_insert(LogRecordId(package_ahriman.base, "1"), 42.0, "message 1")
database.logs_insert(LogRecordId(package_ahriman.base, "2"), 43.0, "message 2") database.logs_insert(LogRecordId(package_ahriman.base, "2"), 43.0, "message 2")
@ -17,6 +18,20 @@ def test_logs_insert_remove_process(database: SQLite, package_ahriman: Package,
assert database.logs_get(package_python_schedule.base) == [(42.0, "message 3")] assert database.logs_get(package_python_schedule.base) == [(42.0, "message 3")]
def test_logs_insert_remove_multi(database: SQLite, package_ahriman: Package) -> None:
"""
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_remove(package_ahriman.base, None)
assert not database.logs_get(package_ahriman.base)
database.repository_id = RepositoryId("x86_64", database.repository_id.name)
assert database.logs_get(package_ahriman.base) == "[1970-01-01 00:00:42] message 1"
def test_logs_insert_remove_full(database: SQLite, package_ahriman: Package, package_python_schedule: Package) -> None: def test_logs_insert_remove_full(database: SQLite, package_ahriman: Package, package_python_schedule: Package) -> None:
""" """
must clear full package logs must clear full package logs
@ -46,3 +61,16 @@ def test_logs_insert_get_pagination(database: SQLite, package_ahriman: Package)
database.logs_insert(LogRecordId(package_ahriman.base, "1"), 42.0, "message 1") database.logs_insert(LogRecordId(package_ahriman.base, "1"), 42.0, "message 1")
database.logs_insert(LogRecordId(package_ahriman.base, "1"), 43.0, "message 2") database.logs_insert(LogRecordId(package_ahriman.base, "1"), 43.0, "message 2")
assert database.logs_get(package_ahriman.base, 1, 1) == [(43.0, "message 2")] assert database.logs_get(package_ahriman.base, 1, 1) == [(43.0, "message 2")]
def test_logs_insert_get_multi(database: SQLite, package_ahriman: Package) -> None:
"""
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")
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) == [(42.0, "message 1")]

View File

@ -16,9 +16,14 @@ def test_package_remove_package_base(database: SQLite, connection: Connection) -
must remove package base must remove package base
""" """
database._package_remove_package_base(connection, "package") database._package_remove_package_base(connection, "package")
args = {
"package_base": "package",
"repository": database.repository_id.name,
"architecture": database.repository_id.architecture,
}
connection.execute.assert_has_calls([ connection.execute.assert_has_calls([
MockCall(pytest.helpers.anyvar(str, strict=True), {"package_base": "package"}), MockCall(pytest.helpers.anyvar(str, strict=True), args),
MockCall(pytest.helpers.anyvar(str, strict=True), {"package_base": "package"}), MockCall(pytest.helpers.anyvar(str, strict=True), args),
]) ])
@ -28,7 +33,11 @@ def test_package_remove_packages(database: SQLite, connection: Connection, packa
""" """
database._package_remove_packages(connection, package_ahriman.base, package_ahriman.packages.keys()) database._package_remove_packages(connection, package_ahriman.base, package_ahriman.packages.keys())
connection.execute.assert_called_once_with( connection.execute.assert_called_once_with(
pytest.helpers.anyvar(str, strict=True), {"package_base": package_ahriman.base}) pytest.helpers.anyvar(str, strict=True), {
"package_base": package_ahriman.base,
"repository": database.repository_id.name,
"architecture": database.repository_id.architecture,
})
connection.executemany.assert_called_once_with(pytest.helpers.anyvar(str, strict=True), []) connection.executemany.assert_called_once_with(pytest.helpers.anyvar(str, strict=True), [])

View File

@ -16,7 +16,8 @@ def test_repo_clone(configuration: Configuration, mocker: MockerFixture) -> None
""" """
fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch") fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch")
copy_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_copy") copy_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_copy")
runner = RemotePull(configuration, "x86_64", "gitremote") _, repository_id = configuration.check_loaded()
runner = RemotePull(repository_id, configuration, "gitremote")
runner.repo_clone() runner.repo_clone()
fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), runner.remote_source) fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), runner.remote_source)
@ -32,7 +33,8 @@ def test_package_copy(configuration: Configuration, package_ahriman: Package, mo
ignore_patterns_mock = mocker.patch("shutil.ignore_patterns", return_value=patterns) ignore_patterns_mock = mocker.patch("shutil.ignore_patterns", return_value=patterns)
copytree_mock = mocker.patch("shutil.copytree") copytree_mock = mocker.patch("shutil.copytree")
init_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.init") init_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.init")
runner = RemotePull(configuration, "x86_64", "gitremote") _, repository_id = configuration.check_loaded()
runner = RemotePull(repository_id, configuration, "gitremote")
local = Path("local") local = Path("local")
runner.package_copy(local / "PKGBUILD") runner.package_copy(local / "PKGBUILD")
@ -57,7 +59,8 @@ def test_repo_copy(configuration: Configuration, mocker: MockerFixture) -> None:
local / "package3" / ".SRCINFO", local / "package3" / ".SRCINFO",
]) ])
copy_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.package_copy") copy_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.package_copy")
runner = RemotePull(configuration, "x86_64", "gitremote") _, repository_id = configuration.check_loaded()
runner = RemotePull(repository_id, configuration, "gitremote")
runner.repo_copy(local) runner.repo_copy(local)
copy_mock.assert_has_calls([ copy_mock.assert_has_calls([
@ -71,7 +74,8 @@ def test_run(configuration: Configuration, mocker: MockerFixture) -> None:
must clone repo on run must clone repo on run
""" """
clone_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_clone") clone_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_clone")
runner = RemotePull(configuration, "x86_64", "gitremote") _, repository_id = configuration.check_loaded()
runner = RemotePull(repository_id, configuration, "gitremote")
runner.run() runner.run()
clone_mock.assert_called_once_with() clone_mock.assert_called_once_with()
@ -82,7 +86,8 @@ def test_run_failed(configuration: Configuration, mocker: MockerFixture) -> None
must reraise exception on error occurred must reraise exception on error occurred
""" """
mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_clone", side_effect=Exception()) mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_clone", side_effect=Exception())
runner = RemotePull(configuration, "x86_64", "gitremote") _, repository_id = configuration.check_loaded()
runner = RemotePull(repository_id, configuration, "gitremote")
with pytest.raises(GitRemoteError): with pytest.raises(GitRemoteError):
runner.run() runner.run()

View File

@ -20,7 +20,8 @@ def test_on_start(configuration: Configuration, mocker: MockerFixture) -> None:
must clone repo on start must clone repo on start
""" """
run_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.run") run_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.run")
trigger = RemotePullTrigger("x86_64", configuration) _, repository_id = configuration.check_loaded()
trigger = RemotePullTrigger(repository_id, configuration)
trigger.on_start() trigger.on_start()
run_mock.assert_called_once_with() run_mock.assert_called_once_with()

View File

@ -26,7 +26,8 @@ def test_on_result(configuration: Configuration, result: Result, package_ahriman
""" """
database_mock = mocker.patch("ahriman.core._Context.get", return_value=database) database_mock = mocker.patch("ahriman.core._Context.get", return_value=database)
run_mock = mocker.patch("ahriman.core.gitremote.remote_push.RemotePush.run") run_mock = mocker.patch("ahriman.core.gitremote.remote_push.RemotePush.run")
trigger = RemotePushTrigger("x86_64", configuration) _, repository_id = configuration.check_loaded()
trigger = RemotePushTrigger(repository_id, configuration)
trigger.on_result(result, [package_ahriman]) trigger.on_result(result, [package_ahriman])
database_mock.assert_called_once_with(ContextKey("database", SQLite)) database_mock.assert_called_once_with(ContextKey("database", SQLite))

View File

@ -22,7 +22,7 @@ def test_init_auth(configuration: Configuration) -> None:
configuration.set_option("web", "username", "username") configuration.set_option("web", "username", "username")
configuration.set_option("web", "password", "password") configuration.set_option("web", "password", "password")
assert SyncHttpClient("web", configuration).auth == ("username", "password") assert SyncHttpClient(configuration, "web").auth == ("username", "password")
assert SyncHttpClient(configuration=configuration).auth is None assert SyncHttpClient(configuration=configuration).auth is None

View File

@ -7,7 +7,7 @@ from pytest_mock import MockerFixture
from systemd.journal import JournalHandler from systemd.journal import JournalHandler
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.log.log_loader import LogLoader from ahriman.core.log import Log
from ahriman.models.log_handler import LogHandler from ahriman.models.log_handler import LogHandler
@ -15,14 +15,14 @@ def test_handler() -> None:
""" """
must extract journald handler if available must extract journald handler if available
""" """
assert LogLoader.handler(None) == LogHandler.Journald assert Log.handler(None) == LogHandler.Journald
def test_handler_selected() -> None: def test_handler_selected() -> None:
""" """
must return selected log handler must return selected log handler
""" """
assert LogLoader.handler(LogHandler.Console) == LogHandler.Console assert Log.handler(LogHandler.Console) == LogHandler.Console
def test_handler_syslog(mocker: MockerFixture) -> None: def test_handler_syslog(mocker: MockerFixture) -> None:
@ -31,7 +31,7 @@ def test_handler_syslog(mocker: MockerFixture) -> None:
""" """
mocker.patch("pathlib.Path.exists", return_value=True) mocker.patch("pathlib.Path.exists", return_value=True)
mocker.patch.dict(sys.modules, {"systemd.journal": None}) mocker.patch.dict(sys.modules, {"systemd.journal": None})
assert LogLoader.handler(None) == LogHandler.Syslog assert Log.handler(None) == LogHandler.Syslog
def test_handler_console(mocker: MockerFixture) -> None: def test_handler_console(mocker: MockerFixture) -> None:
@ -40,17 +40,17 @@ def test_handler_console(mocker: MockerFixture) -> None:
""" """
mocker.patch("pathlib.Path.exists", return_value=False) mocker.patch("pathlib.Path.exists", return_value=False)
mocker.patch.dict(sys.modules, {"systemd.journal": None}) mocker.patch.dict(sys.modules, {"systemd.journal": None})
assert LogLoader.handler(None) == LogHandler.Console assert Log.handler(None) == LogHandler.Console
def test_load(configuration: Configuration, mocker: MockerFixture) -> None: def test_load(configuration: Configuration, mocker: MockerFixture) -> None:
""" """
must load logging must load logging
""" """
logging_mock = mocker.patch("ahriman.core.log.log_loader.fileConfig", side_effect=fileConfig) logging_mock = mocker.patch("ahriman.core.log.log.fileConfig", side_effect=fileConfig)
http_log_mock = mocker.patch("ahriman.core.log.http_log_handler.HttpLogHandler.load") http_log_mock = mocker.patch("ahriman.core.log.http_log_handler.HttpLogHandler.load")
LogLoader.load(configuration, LogHandler.Journald, quiet=False, report=False) Log.load(configuration, LogHandler.Journald, quiet=False, report=False)
logging_mock.assert_called_once_with(pytest.helpers.anyvar(int), disable_existing_loggers=True) 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(configuration, report=False)
assert all(isinstance(handler, JournalHandler) for handler in logging.getLogger().handlers) assert all(isinstance(handler, JournalHandler) for handler in logging.getLogger().handlers)
@ -60,8 +60,8 @@ def test_load_fallback(configuration: Configuration, mocker: MockerFixture) -> N
""" """
must fall back to stderr without errors must fall back to stderr without errors
""" """
mocker.patch("ahriman.core.log.log_loader.fileConfig", side_effect=PermissionError()) mocker.patch("ahriman.core.log.log.fileConfig", side_effect=PermissionError())
LogLoader.load(configuration, LogHandler.Journald, quiet=False, report=False) Log.load(configuration, LogHandler.Journald, quiet=False, report=False)
def test_load_quiet(configuration: Configuration, mocker: MockerFixture) -> None: def test_load_quiet(configuration: Configuration, mocker: MockerFixture) -> None:
@ -69,5 +69,5 @@ def test_load_quiet(configuration: Configuration, mocker: MockerFixture) -> None
must disable logging in case if quiet flag set must disable logging in case if quiet flag set
""" """
disable_mock = mocker.patch("logging.disable") disable_mock = mocker.patch("logging.disable")
LogLoader.load(configuration, LogHandler.Journald, quiet=True, report=False) Log.load(configuration, LogHandler.Journald, quiet=True, report=False)
disable_mock.assert_called_once_with(logging.WARNING) disable_mock.assert_called_once_with(logging.WARNING)

View File

@ -1,7 +1,24 @@
import pytest import pytest
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.report.email import Email
from ahriman.core.report.remote_call import RemoteCall from ahriman.core.report.remote_call import RemoteCall
from ahriman.core.report.telegram import Telegram
@pytest.fixture
def email(configuration: Configuration) -> Email:
"""
fixture for email trigger
Args:
configuration(Configuration): configuration fixture
Returns:
RemoteCall: email trigger test instance
"""
_, repository_id = configuration.check_loaded()
return Email(repository_id, configuration, "email")
@pytest.fixture @pytest.fixture
@ -19,3 +36,18 @@ def remote_call(configuration: Configuration) -> RemoteCall:
configuration.set_option("web", "port", "8080") configuration.set_option("web", "port", "8080")
_, repository_id = configuration.check_loaded() _, repository_id = configuration.check_loaded()
return RemoteCall(repository_id, configuration, "remote-call") return RemoteCall(repository_id, configuration, "remote-call")
@pytest.fixture
def telegram(configuration: Configuration) -> Telegram:
"""
fixture for telegram trigger
Args:
configuration(Configuration): configuration fixture
Returns:
RemoteCall: telegram trigger test instance
"""
_, repository_id = configuration.check_loaded()
return Telegram(repository_id, configuration, "telegram")

View File

@ -14,7 +14,8 @@ def test_generate(configuration: Configuration, result: Result, package_python_s
""" """
print_mock = mocker.patch("ahriman.core.formatters.Printer.print") print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
result.add_failed(package_python_schedule) result.add_failed(package_python_schedule)
report = Console("x86_64", configuration, "console") _, repository_id = configuration.check_loaded()
report = Console(repository_id, configuration, "console")
report.generate([], result) report.generate([], result)
print_mock.assert_has_calls([MockCall(verbose=True), MockCall(verbose=True)]) print_mock.assert_has_calls([MockCall(verbose=True), MockCall(verbose=True)])

View File

@ -8,17 +8,16 @@ from ahriman.models.package import Package
from ahriman.models.result import Result from ahriman.models.result import Result
def test_send(configuration: Configuration, mocker: MockerFixture) -> None: def test_send(email: Email, mocker: MockerFixture) -> None:
""" """
must send an email with attachment must send an email with attachment
""" """
smtp_mock = mocker.patch("smtplib.SMTP") smtp_mock = mocker.patch("smtplib.SMTP")
report = Email("x86_64", configuration, "email") email._send("a text", {"attachment.html": "an attachment"})
report._send("a text", {"attachment.html": "an attachment"})
smtp_mock.return_value.starttls.assert_not_called() smtp_mock.return_value.starttls.assert_not_called()
smtp_mock.return_value.login.assert_not_called() smtp_mock.return_value.login.assert_not_called()
smtp_mock.return_value.sendmail.assert_called_once_with(report.sender, report.receivers, pytest.helpers.anyvar(int)) smtp_mock.return_value.sendmail.assert_called_once_with(email.sender, email.receivers, pytest.helpers.anyvar(int))
smtp_mock.return_value.quit.assert_called_once_with() smtp_mock.return_value.quit.assert_called_once_with()
@ -29,10 +28,11 @@ def test_send_auth(configuration: Configuration, mocker: MockerFixture) -> None:
configuration.set_option("email", "user", "username") configuration.set_option("email", "user", "username")
configuration.set_option("email", "password", "password") configuration.set_option("email", "password", "password")
smtp_mock = mocker.patch("smtplib.SMTP") smtp_mock = mocker.patch("smtplib.SMTP")
_, repository_id = configuration.check_loaded()
report = Email("x86_64", configuration, "email") email = Email(repository_id, configuration, "email")
report._send("a text", {"attachment.html": "an attachment"}) email._send("a text", {"attachment.html": "an attachment"})
smtp_mock.return_value.login.assert_called_once_with(report.user, report.password) smtp_mock.return_value.login.assert_called_once_with(email.user, email.password)
def test_send_auth_no_password(configuration: Configuration, mocker: MockerFixture) -> None: def test_send_auth_no_password(configuration: Configuration, mocker: MockerFixture) -> None:
@ -41,9 +41,10 @@ def test_send_auth_no_password(configuration: Configuration, mocker: MockerFixtu
""" """
configuration.set_option("email", "user", "username") configuration.set_option("email", "user", "username")
smtp_mock = mocker.patch("smtplib.SMTP") smtp_mock = mocker.patch("smtplib.SMTP")
_, repository_id = configuration.check_loaded()
report = Email("x86_64", configuration, "email") email = Email(repository_id, configuration, "email")
report._send("a text", {"attachment.html": "an attachment"}) email._send("a text", {"attachment.html": "an attachment"})
smtp_mock.return_value.login.assert_not_called() smtp_mock.return_value.login.assert_not_called()
@ -53,9 +54,10 @@ def test_send_auth_no_user(configuration: Configuration, mocker: MockerFixture)
""" """
configuration.set_option("email", "password", "password") configuration.set_option("email", "password", "password")
smtp_mock = mocker.patch("smtplib.SMTP") smtp_mock = mocker.patch("smtplib.SMTP")
_, repository_id = configuration.check_loaded()
report = Email("x86_64", configuration, "email") email = Email(repository_id, configuration, "email")
report._send("a text", {"attachment.html": "an attachment"}) email._send("a text", {"attachment.html": "an attachment"})
smtp_mock.return_value.login.assert_not_called() smtp_mock.return_value.login.assert_not_called()
@ -65,12 +67,13 @@ def test_send_ssl_tls(configuration: Configuration, mocker: MockerFixture) -> No
""" """
configuration.set_option("email", "ssl", "ssl") configuration.set_option("email", "ssl", "ssl")
smtp_mock = mocker.patch("smtplib.SMTP_SSL") smtp_mock = mocker.patch("smtplib.SMTP_SSL")
_, repository_id = configuration.check_loaded()
report = Email("x86_64", configuration, "email") email = Email(repository_id, configuration, "email")
report._send("a text", {"attachment.html": "an attachment"}) email._send("a text", {"attachment.html": "an attachment"})
smtp_mock.return_value.starttls.assert_not_called() smtp_mock.return_value.starttls.assert_not_called()
smtp_mock.return_value.login.assert_not_called() smtp_mock.return_value.login.assert_not_called()
smtp_mock.return_value.sendmail.assert_called_once_with(report.sender, report.receivers, pytest.helpers.anyvar(int)) smtp_mock.return_value.sendmail.assert_called_once_with(email.sender, email.receivers, pytest.helpers.anyvar(int))
smtp_mock.return_value.quit.assert_called_once_with() smtp_mock.return_value.quit.assert_called_once_with()
@ -80,48 +83,40 @@ def test_send_starttls(configuration: Configuration, mocker: MockerFixture) -> N
""" """
configuration.set_option("email", "ssl", "starttls") configuration.set_option("email", "ssl", "starttls")
smtp_mock = mocker.patch("smtplib.SMTP") smtp_mock = mocker.patch("smtplib.SMTP")
_, repository_id = configuration.check_loaded()
report = Email("x86_64", configuration, "email") email = Email(repository_id, configuration, "email")
report._send("a text", {"attachment.html": "an attachment"}) email._send("a text", {"attachment.html": "an attachment"})
smtp_mock.return_value.starttls.assert_called_once_with() smtp_mock.return_value.starttls.assert_called_once_with()
def test_generate(configuration: Configuration, package_ahriman: Package, mocker: MockerFixture) -> None: def test_generate(email: Email, package_ahriman: Package, mocker: MockerFixture) -> None:
""" """
must generate report must generate report
""" """
send_mock = mocker.patch("ahriman.core.report.email.Email._send") send_mock = mocker.patch("ahriman.core.report.email.Email._send")
email.generate([package_ahriman], Result())
report = Email("x86_64", configuration, "email")
report.generate([package_ahriman], Result())
send_mock.assert_called_once_with(pytest.helpers.anyvar(int), {}) send_mock.assert_called_once_with(pytest.helpers.anyvar(int), {})
def test_generate_with_built(configuration: Configuration, package_ahriman: Package, result: Result, def test_generate_with_built(email: Email, package_ahriman: Package, result: Result, mocker: MockerFixture) -> None:
mocker: MockerFixture) -> None:
""" """
must generate report with built packages must generate report with built packages
""" """
send_mock = mocker.patch("ahriman.core.report.email.Email._send") send_mock = mocker.patch("ahriman.core.report.email.Email._send")
email.generate([package_ahriman], result)
report = Email("x86_64", configuration, "email")
report.generate([package_ahriman], result)
send_mock.assert_called_once_with(pytest.helpers.anyvar(int), {}) send_mock.assert_called_once_with(pytest.helpers.anyvar(int), {})
def test_generate_with_built_and_full_path( def test_generate_with_built_and_full_path(email: Email, package_ahriman: Package, result: Result,
configuration: Configuration,
package_ahriman: Package,
result: Result,
mocker: MockerFixture) -> None: mocker: MockerFixture) -> None:
""" """
must generate report with built packages and full packages lists must generate report with built packages and full packages lists
""" """
send_mock = mocker.patch("ahriman.core.report.email.Email._send") send_mock = mocker.patch("ahriman.core.report.email.Email._send")
report = Email("x86_64", configuration, "email") email.full_template_path = email.template_path
report.full_template_path = report.template_path email.generate([package_ahriman], result)
report.generate([package_ahriman], result)
send_mock.assert_called_once_with(pytest.helpers.anyvar(int), pytest.helpers.anyvar(int)) send_mock.assert_called_once_with(pytest.helpers.anyvar(int), pytest.helpers.anyvar(int))
@ -131,9 +126,10 @@ def test_generate_no_empty(configuration: Configuration, package_ahriman: Packag
""" """
configuration.set_option("email", "no_empty_report", "yes") configuration.set_option("email", "no_empty_report", "yes")
send_mock = mocker.patch("ahriman.core.report.email.Email._send") send_mock = mocker.patch("ahriman.core.report.email.Email._send")
_, repository_id = configuration.check_loaded()
report = Email("x86_64", configuration, "email") email = Email(repository_id, configuration, "email")
report.generate([package_ahriman], Result()) email.generate([package_ahriman], Result())
send_mock.assert_not_called() send_mock.assert_not_called()
@ -144,7 +140,8 @@ def test_generate_no_empty_with_built(configuration: Configuration, package_ahri
""" """
configuration.set_option("email", "no_empty_report", "yes") configuration.set_option("email", "no_empty_report", "yes")
send_mock = mocker.patch("ahriman.core.report.email.Email._send") send_mock = mocker.patch("ahriman.core.report.email.Email._send")
_, repository_id = configuration.check_loaded()
report = Email("x86_64", configuration, "email") email = Email(repository_id, configuration, "email")
report.generate([package_ahriman], result) email.generate([package_ahriman], result)
send_mock.assert_called_once_with(pytest.helpers.anyvar(int), {}) send_mock.assert_called_once_with(pytest.helpers.anyvar(int), {})

View File

@ -13,7 +13,8 @@ def test_generate(configuration: Configuration, package_ahriman: Package, mocker
must generate report must generate report
""" """
write_mock = mocker.patch("pathlib.Path.write_text") write_mock = mocker.patch("pathlib.Path.write_text")
_, repository_id = configuration.check_loaded()
report = HTML("x86_64", configuration, "html") report = HTML(repository_id, configuration, "html")
report.generate([package_ahriman], Result()) report.generate([package_ahriman], Result())
write_mock.assert_called_once_with(pytest.helpers.anyvar(int), encoding="utf8") write_mock.assert_called_once_with(pytest.helpers.anyvar(int), encoding="utf8")

View File

@ -9,5 +9,6 @@ def test_generate(configuration: Configuration, package_ahriman: Package) -> Non
must generate html report must generate html report
""" """
path = configuration.getpath("html", "template_path") path = configuration.getpath("html", "template_path")
report = JinjaTemplate("html", configuration) _, repository_id = configuration.check_loaded()
report = JinjaTemplate(repository_id, configuration, "html")
assert report.make_html(Result(success=[package_ahriman]), path) assert report.make_html(Result(success=[package_ahriman]), path)

View File

@ -14,8 +14,10 @@ def test_report_failure(configuration: Configuration, mocker: MockerFixture) ->
must raise ReportFailed on errors must raise ReportFailed on errors
""" """
mocker.patch("ahriman.core.report.html.HTML.generate", side_effect=Exception()) mocker.patch("ahriman.core.report.html.HTML.generate", side_effect=Exception())
_, repository_id = configuration.check_loaded()
with pytest.raises(ReportError): with pytest.raises(ReportError):
Report.load("x86_64", configuration, "html").run(Result(), []) Report.load(repository_id, configuration, "html").run(Result(), [])
def test_report_dummy(configuration: Configuration, result: Result, mocker: MockerFixture) -> None: def test_report_dummy(configuration: Configuration, result: Result, mocker: MockerFixture) -> None:
@ -24,8 +26,9 @@ def test_report_dummy(configuration: Configuration, result: Result, mocker: Mock
""" """
mocker.patch("ahriman.models.report_settings.ReportSettings.from_option", return_value=ReportSettings.Disabled) mocker.patch("ahriman.models.report_settings.ReportSettings.from_option", return_value=ReportSettings.Disabled)
report_mock = mocker.patch("ahriman.core.report.report.Report.generate") report_mock = mocker.patch("ahriman.core.report.report.Report.generate")
_, repository_id = configuration.check_loaded()
Report.load("x86_64", configuration, "disabled").run(result, []) Report.load(repository_id, configuration, "disabled").run(result, [])
report_mock.assert_called_once_with([], result) report_mock.assert_called_once_with([], result)
@ -34,7 +37,9 @@ def test_report_console(configuration: Configuration, result: Result, mocker: Mo
must generate console report must generate console report
""" """
report_mock = mocker.patch("ahriman.core.report.console.Console.generate") report_mock = mocker.patch("ahriman.core.report.console.Console.generate")
Report.load("x86_64", configuration, "console").run(result, []) _, repository_id = configuration.check_loaded()
Report.load(repository_id, configuration, "console").run(result, [])
report_mock.assert_called_once_with([], result) report_mock.assert_called_once_with([], result)
@ -43,7 +48,9 @@ def test_report_email(configuration: Configuration, result: Result, mocker: Mock
must generate email report must generate email report
""" """
report_mock = mocker.patch("ahriman.core.report.email.Email.generate") report_mock = mocker.patch("ahriman.core.report.email.Email.generate")
Report.load("x86_64", configuration, "email").run(result, []) _, repository_id = configuration.check_loaded()
Report.load(repository_id, configuration, "email").run(result, [])
report_mock.assert_called_once_with([], result) report_mock.assert_called_once_with([], result)
@ -52,7 +59,9 @@ def test_report_html(configuration: Configuration, result: Result, mocker: Mocke
must generate html report must generate html report
""" """
report_mock = mocker.patch("ahriman.core.report.html.HTML.generate") report_mock = mocker.patch("ahriman.core.report.html.HTML.generate")
Report.load("x86_64", configuration, "html").run(result, []) _, repository_id = configuration.check_loaded()
Report.load(repository_id, configuration, "html").run(result, [])
report_mock.assert_called_once_with([], result) report_mock.assert_called_once_with([], result)
@ -63,8 +72,9 @@ def test_report_remote_call(configuration: Configuration, result: Result, mocker
configuration.set_option("web", "host", "localhost") configuration.set_option("web", "host", "localhost")
configuration.set_option("web", "port", "8080") configuration.set_option("web", "port", "8080")
report_mock = mocker.patch("ahriman.core.report.remote_call.RemoteCall.generate") report_mock = mocker.patch("ahriman.core.report.remote_call.RemoteCall.generate")
_, repository_id = configuration.check_loaded()
Report.load("x86_64", configuration, "remote-call").run(result, []) Report.load(repository_id, configuration, "remote-call").run(result, [])
report_mock.assert_called_once_with([], result) report_mock.assert_called_once_with([], result)
@ -73,5 +83,7 @@ def test_report_telegram(configuration: Configuration, result: Result, mocker: M
must generate telegram report must generate telegram report
""" """
report_mock = mocker.patch("ahriman.core.report.telegram.Telegram.generate") report_mock = mocker.patch("ahriman.core.report.telegram.Telegram.generate")
Report.load("x86_64", configuration, "telegram").run(result, []) _, repository_id = configuration.check_loaded()
Report.load(repository_id, configuration, "telegram").run(result, [])
report_mock.assert_called_once_with([], result) report_mock.assert_called_once_with([], result)

View File

@ -22,7 +22,8 @@ def test_on_result(configuration: Configuration, mocker: MockerFixture) -> None:
""" """
configuration.set_option("report", "target", "email") configuration.set_option("report", "target", "email")
run_mock = mocker.patch("ahriman.core.report.report.Report.run") run_mock = mocker.patch("ahriman.core.report.report.Report.run")
_, repository_id = configuration.check_loaded()
trigger = ReportTrigger("x86_64", configuration) trigger = ReportTrigger(repository_id, configuration)
trigger.on_result(Result(), []) trigger.on_result(Result(), [])
run_mock.assert_called_once_with(Result(), []) run_mock.assert_called_once_with(Result(), [])

View File

@ -10,67 +10,58 @@ from ahriman.models.package import Package
from ahriman.models.result import Result from ahriman.models.result import Result
def test_send(configuration: Configuration, mocker: MockerFixture) -> None: def test_send(telegram: Telegram, mocker: MockerFixture) -> None:
""" """
must send a message must send a message
""" """
request_mock = mocker.patch("ahriman.core.report.telegram.Telegram.make_request") request_mock = mocker.patch("ahriman.core.report.telegram.Telegram.make_request")
report = Telegram("x86_64", configuration, "telegram")
report._send("a text") telegram._send("a text")
request_mock.assert_called_once_with( request_mock.assert_called_once_with(
"POST", "POST",
pytest.helpers.anyvar(str, strict=True), pytest.helpers.anyvar(str, strict=True),
data={"chat_id": pytest.helpers.anyvar(str, strict=True), "text": "a text", "parse_mode": "HTML"}) data={"chat_id": pytest.helpers.anyvar(str, strict=True), "text": "a text", "parse_mode": "HTML"})
def test_send_failed(configuration: Configuration, mocker: MockerFixture) -> None: def test_send_failed(telegram: Telegram, mocker: MockerFixture) -> None:
""" """
must reraise generic exception must reraise generic exception
""" """
mocker.patch("requests.Session.request", side_effect=Exception()) mocker.patch("requests.Session.request", side_effect=Exception())
report = Telegram("x86_64", configuration, "telegram")
with pytest.raises(Exception): with pytest.raises(Exception):
report._send("a text") telegram._send("a text")
def test_send_failed_http_error(configuration: Configuration, mocker: MockerFixture) -> None: def test_send_failed_http_error(telegram: Telegram, mocker: MockerFixture) -> None:
""" """
must reraise http exception must reraise http exception
""" """
mocker.patch("requests.Session.request", side_effect=requests.HTTPError()) mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
report = Telegram("x86_64", configuration, "telegram")
with pytest.raises(requests.HTTPError): with pytest.raises(requests.HTTPError):
report._send("a text") telegram._send("a text")
def test_generate(configuration: Configuration, package_ahriman: Package, result: Result, def test_generate(telegram: Telegram, package_ahriman: Package, result: Result,
mocker: MockerFixture) -> None: mocker: MockerFixture) -> None:
""" """
must generate report must generate report
""" """
send_mock = mocker.patch("ahriman.core.report.telegram.Telegram._send") send_mock = mocker.patch("ahriman.core.report.telegram.Telegram._send")
telegram.generate([package_ahriman], result)
report = Telegram("x86_64", configuration, "telegram")
report.generate([package_ahriman], result)
send_mock.assert_called_once_with(pytest.helpers.anyvar(int)) send_mock.assert_called_once_with(pytest.helpers.anyvar(int))
def test_generate_big_text_without_spaces(configuration: Configuration, package_ahriman: Package, result: Result, def test_generate_big_text_without_spaces(telegram: Telegram, package_ahriman: Package, result: Result,
mocker: MockerFixture) -> None: mocker: MockerFixture) -> None:
""" """
must raise ValueError in case if there are no new lines in text must raise ValueError in case if there are no new lines in text
""" """
mocker.patch("ahriman.core.report.jinja_template.JinjaTemplate.make_html", return_value="ab" * 4096) mocker.patch("ahriman.core.report.jinja_template.JinjaTemplate.make_html", return_value="ab" * 4096)
report = Telegram("x86_64", configuration, "telegram")
with pytest.raises(ValueError): with pytest.raises(ValueError):
report.generate([package_ahriman], result) telegram.generate([package_ahriman], result)
def test_generate_big_text(configuration: Configuration, package_ahriman: Package, result: Result, def test_generate_big_text(telegram: Telegram, package_ahriman: Package, result: Result,
mocker: MockerFixture) -> None: mocker: MockerFixture) -> None:
""" """
must generate report with big text must generate report with big text
@ -78,14 +69,13 @@ def test_generate_big_text(configuration: Configuration, package_ahriman: Packag
mocker.patch("ahriman.core.report.jinja_template.JinjaTemplate.make_html", return_value="a\n" * 4096) mocker.patch("ahriman.core.report.jinja_template.JinjaTemplate.make_html", return_value="a\n" * 4096)
send_mock = mocker.patch("ahriman.core.report.telegram.Telegram._send") send_mock = mocker.patch("ahriman.core.report.telegram.Telegram._send")
report = Telegram("x86_64", configuration, "telegram") telegram.generate([package_ahriman], result)
report.generate([package_ahriman], result)
send_mock.assert_has_calls([ send_mock.assert_has_calls([
MockCall(pytest.helpers.anyvar(str, strict=True)), MockCall(pytest.helpers.anyvar(str, strict=True)) MockCall(pytest.helpers.anyvar(str, strict=True)), MockCall(pytest.helpers.anyvar(str, strict=True))
]) ])
def test_generate_very_big_text(configuration: Configuration, package_ahriman: Package, result: Result, def test_generate_very_big_text(telegram: Telegram, package_ahriman: Package, result: Result,
mocker: MockerFixture) -> None: mocker: MockerFixture) -> None:
""" """
must generate report with very big text must generate report with very big text
@ -93,8 +83,7 @@ def test_generate_very_big_text(configuration: Configuration, package_ahriman: P
mocker.patch("ahriman.core.report.jinja_template.JinjaTemplate.make_html", return_value="ab\n" * 4096) mocker.patch("ahriman.core.report.jinja_template.JinjaTemplate.make_html", return_value="ab\n" * 4096)
send_mock = mocker.patch("ahriman.core.report.telegram.Telegram._send") send_mock = mocker.patch("ahriman.core.report.telegram.Telegram._send")
report = Telegram("x86_64", configuration, "telegram") telegram.generate([package_ahriman], result)
report.generate([package_ahriman], result)
send_mock.assert_has_calls([ send_mock.assert_has_calls([
MockCall(pytest.helpers.anyvar(str, strict=True)), MockCall(pytest.helpers.anyvar(str, strict=True)),
MockCall(pytest.helpers.anyvar(str, strict=True)), MockCall(pytest.helpers.anyvar(str, strict=True)),
@ -102,12 +91,10 @@ def test_generate_very_big_text(configuration: Configuration, package_ahriman: P
]) ])
def test_generate_no_empty(configuration: Configuration, package_ahriman: Package, mocker: MockerFixture) -> None: def test_generate_no_empty(telegram: Telegram, package_ahriman: Package, mocker: MockerFixture) -> None:
""" """
must generate report must generate report
""" """
send_mock = mocker.patch("ahriman.core.report.telegram.Telegram._send") send_mock = mocker.patch("ahriman.core.report.telegram.Telegram._send")
telegram.generate([package_ahriman], Result())
report = Telegram("x86_64", configuration, "telegram")
report.generate([package_ahriman], Result())
send_mock.assert_not_called() send_mock.assert_not_called()

View File

@ -20,7 +20,9 @@ def test_load(configuration: Configuration, database: SQLite, mocker: MockerFixt
must correctly load instance must correctly load instance
""" """
context_mock = mocker.patch("ahriman.core.repository.Repository._set_context") context_mock = mocker.patch("ahriman.core.repository.Repository._set_context")
Repository.load("x86_64", configuration, database, report=False) _, repository_id = configuration.check_loaded()
Repository.load(repository_id, configuration, database, report=False)
context_mock.assert_called_once_with() context_mock.assert_called_once_with()
@ -29,8 +31,9 @@ def test_set_context(configuration: Configuration, database: SQLite, mocker: Moc
must set context variables must set context variables
""" """
set_mock = mocker.patch("ahriman.core._Context.set") set_mock = mocker.patch("ahriman.core._Context.set")
_, repository_id = configuration.check_loaded()
instance = Repository.load("x86_64", configuration, database, report=False) instance = Repository.load(repository_id, configuration, database, report=False)
set_mock.assert_has_calls([ set_mock.assert_has_calls([
MockCall(ContextKey("database", SQLite), instance.database), MockCall(ContextKey("database", SQLite), instance.database),
MockCall(ContextKey("configuration", Configuration), instance.configuration), MockCall(ContextKey("configuration", Configuration), instance.configuration),

View File

@ -6,6 +6,20 @@ from ahriman.models.user import User
from ahriman.models.user_access import UserAccess from ahriman.models.user_access import UserAccess
def test_architecture(repository: RepositoryProperties) -> None:
"""
must provide repository architecture for backward compatibility
"""
assert repository.architecture == repository.repository_id.architecture
def test_name(repository: RepositoryProperties) -> None:
"""
must provide repository name for backward compatibility
"""
assert repository.name == repository.repository_id.name
def test_packager(repository: RepositoryProperties, mocker: MockerFixture) -> None: def test_packager(repository: RepositoryProperties, mocker: MockerFixture) -> None:
""" """
must extract packager must extract packager

View File

@ -17,9 +17,10 @@ def test_force_no_report(configuration: Configuration, database: SQLite, mocker:
""" """
configuration.set_option("web", "port", "8080") configuration.set_option("web", "port", "8080")
load_mock = mocker.patch("ahriman.core.repository.Repository.load") load_mock = mocker.patch("ahriman.core.repository.Repository.load")
_, repository_id = configuration.check_loaded()
Watcher("x86_64", configuration, database) Watcher(repository_id, configuration, database)
load_mock.assert_called_once_with("x86_64", configuration, database, report=False) load_mock.assert_called_once_with(repository_id, configuration, database, report=False)
def test_load(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None: def test_load(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:

View File

@ -16,7 +16,8 @@ def mirrorlist_generator(configuration: Configuration) -> MirrorlistGenerator:
Returns: Returns:
MirrorlistGenerator: mirrorlist pkgbuild generator test instance MirrorlistGenerator: mirrorlist pkgbuild generator test instance
""" """
return MirrorlistGenerator(configuration, "mirrorlist") _, repository_id = configuration.check_loaded()
return MirrorlistGenerator(repository_id, configuration, "mirrorlist")
@pytest.fixture @pytest.fixture

View File

@ -20,7 +20,8 @@ def keyring_generator(database: SQLite, gpg: GPG, configuration: Configuration)
Returns: Returns:
KeyringGenerator: keyring generator test instance KeyringGenerator: keyring generator test instance
""" """
return KeyringGenerator(database, gpg, configuration, "keyring") _, repository_id = configuration.check_loaded()
return KeyringGenerator(database, gpg, repository_id, configuration, "keyring")
@pytest.fixture @pytest.fixture

View File

@ -18,74 +18,87 @@ def test_init_packagers(database: SQLite, gpg: GPG, configuration: Configuration
must extract packagers keys must extract packagers keys
""" """
mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[user]) mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[user])
_, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, configuration, "keyring").packagers == ["key"] assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").packagers == ["key"]
configuration.set_option("keyring", "packagers", "key1") configuration.set_option("keyring", "packagers", "key1")
assert KeyringGenerator(database, gpg, configuration, "keyring").packagers == ["key1"] assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").packagers == ["key1"]
def test_init_revoked(database: SQLite, gpg: GPG, configuration: Configuration) -> None: def test_init_revoked(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
""" """
must extract revoked keys must extract revoked keys
""" """
assert KeyringGenerator(database, gpg, configuration, "keyring").revoked == [] _, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").revoked == []
configuration.set_option("keyring", "revoked", "key1") configuration.set_option("keyring", "revoked", "key1")
assert KeyringGenerator(database, gpg, configuration, "keyring").revoked == ["key1"] assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").revoked == ["key1"]
def test_init_trusted(database: SQLite, gpg: GPG, configuration: Configuration) -> None: def test_init_trusted(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
""" """
must extract trusted keys must extract trusted keys
""" """
assert KeyringGenerator(database, gpg, configuration, "keyring").trusted == [] _, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").trusted == []
gpg.default_key = "key" gpg.default_key = "key"
assert KeyringGenerator(database, gpg, configuration, "keyring").trusted == ["key"] assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").trusted == ["key"]
configuration.set_option("keyring", "trusted", "key1") configuration.set_option("keyring", "trusted", "key1")
assert KeyringGenerator(database, gpg, configuration, "keyring").trusted == ["key1"] assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").trusted == ["key1"]
def test_license(database: SQLite, gpg: GPG, configuration: Configuration) -> None: def test_license(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
""" """
must generate correct licenses list must generate correct licenses list
""" """
assert KeyringGenerator(database, gpg, configuration, "keyring").license == ["Unlicense"] _, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").license == ["Unlicense"]
configuration.set_option("keyring", "license", "GPL MPL") configuration.set_option("keyring", "license", "GPL MPL")
assert KeyringGenerator(database, gpg, configuration, "keyring").license == ["GPL", "MPL"] assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").license == ["GPL", "MPL"]
def test_pkgdesc(database: SQLite, gpg: GPG, configuration: Configuration) -> None: def test_pkgdesc(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
""" """
must generate correct pkgdesc property must generate correct pkgdesc property
""" """
assert KeyringGenerator(database, gpg, configuration, "keyring").pkgdesc == "aur-clone PGP keyring" _, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").pkgdesc == "aur-clone PGP keyring"
configuration.set_option("keyring", "description", "description") configuration.set_option("keyring", "description", "description")
assert KeyringGenerator(database, gpg, configuration, "keyring").pkgdesc == "description" assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").pkgdesc == "description"
def test_pkgname(database: SQLite, gpg: GPG, configuration: Configuration) -> None: def test_pkgname(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
""" """
must generate correct pkgname property must generate correct pkgname property
""" """
assert KeyringGenerator(database, gpg, configuration, "keyring").pkgname == "aur-clone-keyring" _, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").pkgname == "aur-clone-keyring"
configuration.set_option("keyring", "package", "keyring") configuration.set_option("keyring", "package", "keyring")
assert KeyringGenerator(database, gpg, configuration, "keyring").pkgname == "keyring" assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").pkgname == "keyring"
def test_url(database: SQLite, gpg: GPG, configuration: Configuration) -> None: def test_url(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
""" """
must generate correct url property must generate correct url property
""" """
assert KeyringGenerator(database, gpg, configuration, "keyring").url == "" _, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").url == ""
configuration.set_option("keyring", "homepage", "homepage") configuration.set_option("keyring", "homepage", "homepage")
assert KeyringGenerator(database, gpg, configuration, "keyring").url == "homepage" assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").url == "homepage"
def test_generate_gpg(keyring_generator: KeyringGenerator, mocker: MockerFixture) -> None: def test_generate_gpg(keyring_generator: KeyringGenerator, mocker: MockerFixture) -> None:

View File

@ -9,50 +9,62 @@ def test_init_path(configuration: Configuration) -> None:
""" """
must set relative path to mirrorlist must set relative path to mirrorlist
""" """
assert MirrorlistGenerator(configuration, "mirrorlist").path == Path("etc") / "pacman.d" / "aur-clone-mirrorlist" _, repository_id = configuration.check_loaded()
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").path == \
Path("etc") / "pacman.d" / "aur-clone-mirrorlist"
configuration.set_option("mirrorlist", "path", "/etc") configuration.set_option("mirrorlist", "path", "/etc")
assert MirrorlistGenerator(configuration, "mirrorlist").path == Path("etc") assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").path == Path("etc")
def test_license(configuration: Configuration) -> None: def test_license(configuration: Configuration) -> None:
""" """
must generate correct licenses list must generate correct licenses list
""" """
assert MirrorlistGenerator(configuration, "mirrorlist").license == ["Unlicense"] _, repository_id = configuration.check_loaded()
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").license == ["Unlicense"]
configuration.set_option("mirrorlist", "license", "GPL MPL") configuration.set_option("mirrorlist", "license", "GPL MPL")
assert MirrorlistGenerator(configuration, "mirrorlist").license == ["GPL", "MPL"] assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").license == ["GPL", "MPL"]
def test_pkgdesc(configuration: Configuration) -> None: def test_pkgdesc(configuration: Configuration) -> None:
""" """
must generate correct pkgdesc property must generate correct pkgdesc property
""" """
assert MirrorlistGenerator(configuration, "mirrorlist").pkgdesc == "aur-clone mirror list for use by pacman" _, repository_id = configuration.check_loaded()
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").pkgdesc == \
"aur-clone mirror list for use by pacman"
configuration.set_option("mirrorlist", "description", "description") configuration.set_option("mirrorlist", "description", "description")
assert MirrorlistGenerator(configuration, "mirrorlist").pkgdesc == "description" assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").pkgdesc == "description"
def test_pkgname(configuration: Configuration) -> None: def test_pkgname(configuration: Configuration) -> None:
""" """
must generate correct pkgname property must generate correct pkgname property
""" """
assert MirrorlistGenerator(configuration, "mirrorlist").pkgname == "aur-clone-mirrorlist" _, repository_id = configuration.check_loaded()
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").pkgname == "aur-clone-mirrorlist"
configuration.set_option("mirrorlist", "package", "mirrorlist") configuration.set_option("mirrorlist", "package", "mirrorlist")
assert MirrorlistGenerator(configuration, "mirrorlist").pkgname == "mirrorlist" assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").pkgname == "mirrorlist"
def test_url(configuration: Configuration) -> None: def test_url(configuration: Configuration) -> None:
""" """
must generate correct url property must generate correct url property
""" """
assert MirrorlistGenerator(configuration, "mirrorlist").url == "" _, repository_id = configuration.check_loaded()
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").url == ""
configuration.set_option("mirrorlist", "homepage", "homepage") configuration.set_option("mirrorlist", "homepage", "homepage")
assert MirrorlistGenerator(configuration, "mirrorlist").url == "homepage" assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").url == "homepage"
def test_generate_mirrorlist(mirrorlist_generator: MirrorlistGenerator, mocker: MockerFixture) -> None: def test_generate_mirrorlist(mirrorlist_generator: MirrorlistGenerator, mocker: MockerFixture) -> None:

View File

@ -25,8 +25,9 @@ def test_on_start(configuration: Configuration, mocker: MockerFixture) -> None:
""" """
context_mock = mocker.patch("ahriman.core._Context.get") context_mock = mocker.patch("ahriman.core._Context.get")
run_mock = mocker.patch("ahriman.core.support.package_creator.PackageCreator.run") run_mock = mocker.patch("ahriman.core.support.package_creator.PackageCreator.run")
_, repository_id = configuration.check_loaded()
trigger = KeyringTrigger("x86_64", configuration) trigger = KeyringTrigger(repository_id, configuration)
trigger.on_start() trigger.on_start()
context_mock.assert_has_calls([MockCall(ContextKey("sign", GPG)), MockCall(ContextKey("database", SQLite))]) context_mock.assert_has_calls([MockCall(ContextKey("sign", GPG)), MockCall(ContextKey("database", SQLite))])
run_mock.assert_called_once_with() run_mock.assert_called_once_with()

View File

@ -20,7 +20,8 @@ def test_on_start(configuration: Configuration, mocker: MockerFixture) -> None:
must run report for specified targets must run report for specified targets
""" """
run_mock = mocker.patch("ahriman.core.support.package_creator.PackageCreator.run") run_mock = mocker.patch("ahriman.core.support.package_creator.PackageCreator.run")
_, repository_id = configuration.check_loaded()
trigger = MirrorlistTrigger("x86_64", configuration) trigger = MirrorlistTrigger(repository_id, configuration)
trigger.on_start() trigger.on_start()
run_mock.assert_called_once_with() run_mock.assert_called_once_with()

View File

@ -7,6 +7,8 @@ from ahriman.core.support.package_creator import PackageCreator
from ahriman.models.context_key import ContextKey from ahriman.models.context_key import ContextKey
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.package_description import PackageDescription from ahriman.models.package_description import PackageDescription
from ahriman.models.package_source import PackageSource
from ahriman.models.remote_source import RemoteSource
def test_run(package_creator: PackageCreator, database: SQLite, mocker: MockerFixture) -> None: def test_run(package_creator: PackageCreator, database: SQLite, mocker: MockerFixture) -> None:
@ -16,7 +18,7 @@ def test_run(package_creator: PackageCreator, database: SQLite, mocker: MockerFi
package = Package( package = Package(
base=package_creator.generator.pkgname, base=package_creator.generator.pkgname,
version=package_creator.generator.pkgver, version=package_creator.generator.pkgver,
remote=None, remote=RemoteSource(source=PackageSource.Local),
packages={package_creator.generator.pkgname: PackageDescription()}, packages={package_creator.generator.pkgname: PackageDescription()},
) )
local_path = package_creator.configuration.repository_paths.cache_for(package_creator.generator.pkgname) local_path = package_creator.configuration.repository_paths.cache_for(package_creator.generator.pkgname)

View File

@ -20,9 +20,9 @@ def test_process(spawner: Spawn) -> None:
callback = MagicMock() callback = MagicMock()
callback.return_value = True callback.return_value = True
spawner.process(callback, args, spawner.architecture, "id", spawner.queue) spawner.process(callback, args, spawner.repository_id, "id", spawner.queue)
callback.assert_called_once_with(args, spawner.architecture) callback.assert_called_once_with(args, spawner.repository_id)
(uuid, status, time) = spawner.queue.get() (uuid, status, time) = spawner.queue.get()
assert uuid == "id" assert uuid == "id"
assert status assert status
@ -37,7 +37,7 @@ def test_process_error(spawner: Spawn) -> None:
callback = MagicMock() callback = MagicMock()
callback.return_value = False callback.return_value = False
spawner.process(callback, MagicMock(), spawner.architecture, "id", spawner.queue) spawner.process(callback, MagicMock(), spawner.repository_id, "id", spawner.queue)
(uuid, status, time) = spawner.queue.get() (uuid, status, time) = spawner.queue.get()
assert uuid == "id" assert uuid == "id"

View File

@ -6,15 +6,23 @@ from ahriman.core.triggers import Trigger
from ahriman.models.result import Result from ahriman.models.result import Result
def test_architecture(trigger: Trigger) -> None:
"""
must return repository architecture for backward compatibility
"""
assert trigger.architecture == trigger.repository_id.architecture
def test_configuration_schema(configuration: Configuration) -> None: def test_configuration_schema(configuration: Configuration) -> None:
""" """
must return used configuration schema must return used configuration schema
""" """
section = "console" section = "console"
configuration.set_option("report", "target", section) configuration.set_option("report", "target", section)
_, repository_id = configuration.check_loaded()
expected = {section: ReportTrigger.CONFIGURATION_SCHEMA[section]} expected = {section: ReportTrigger.CONFIGURATION_SCHEMA[section]}
assert ReportTrigger.configuration_schema("x86_64", configuration) == expected assert ReportTrigger.configuration_schema(repository_id, configuration) == expected
def test_configuration_schema_no_section(configuration: Configuration) -> None: def test_configuration_schema_no_section(configuration: Configuration) -> None:
@ -23,7 +31,9 @@ def test_configuration_schema_no_section(configuration: Configuration) -> None:
""" """
section = "abracadabra" section = "abracadabra"
configuration.set_option("report", "target", section) configuration.set_option("report", "target", section)
assert ReportTrigger.configuration_schema("x86_64", configuration) == {} _, repository_id = configuration.check_loaded()
assert ReportTrigger.configuration_schema(repository_id, configuration) == {}
def test_configuration_schema_no_schema(configuration: Configuration) -> None: def test_configuration_schema_no_schema(configuration: Configuration) -> None:
@ -33,15 +43,17 @@ def test_configuration_schema_no_schema(configuration: Configuration) -> None:
section = "abracadabra" section = "abracadabra"
configuration.set_option("report", "target", section) configuration.set_option("report", "target", section)
configuration.set_option(section, "key", "value") configuration.set_option(section, "key", "value")
_, repository_id = configuration.check_loaded()
assert ReportTrigger.configuration_schema("x86_64", configuration) == {} assert ReportTrigger.configuration_schema(repository_id, configuration) == {}
def test_configuration_schema_empty() -> None: def test_configuration_schema_empty(configuration: Configuration) -> None:
""" """
must return default schema if no configuration set must return default schema if no configuration set
""" """
assert ReportTrigger.configuration_schema("x86_64", None) == ReportTrigger.CONFIGURATION_SCHEMA _, repository_id = configuration.check_loaded()
assert ReportTrigger.configuration_schema(repository_id, None) == ReportTrigger.CONFIGURATION_SCHEMA
def test_configuration_schema_variables(configuration: Configuration) -> None: def test_configuration_schema_variables(configuration: Configuration) -> None:

View File

@ -48,8 +48,10 @@ def test_load_trigger_package_error_on_creation(trigger_loader: TriggerLoader, c
must raise InvalidException on trigger initialization if any exception is thrown must raise InvalidException on trigger initialization if any exception is thrown
""" """
mocker.patch("ahriman.core.triggers.trigger.Trigger.__init__", side_effect=Exception()) mocker.patch("ahriman.core.triggers.trigger.Trigger.__init__", side_effect=Exception())
_, repository_id = configuration.check_loaded()
with pytest.raises(ExtensionError): with pytest.raises(ExtensionError):
trigger_loader.load_trigger("ahriman.core.report.ReportTrigger", "x86_64", configuration) trigger_loader.load_trigger("ahriman.core.report.ReportTrigger", repository_id, configuration)
def test_load_trigger_class_package(trigger_loader: TriggerLoader) -> None: def test_load_trigger_class_package(trigger_loader: TriggerLoader) -> None:
@ -155,8 +157,9 @@ def test_on_stop_with_on_start(configuration: Configuration, mocker: MockerFixtu
mocker.patch("ahriman.core.upload.UploadTrigger.on_start") mocker.patch("ahriman.core.upload.UploadTrigger.on_start")
mocker.patch("ahriman.core.report.ReportTrigger.on_start") mocker.patch("ahriman.core.report.ReportTrigger.on_start")
on_stop_mock = mocker.patch("ahriman.core.triggers.trigger_loader.TriggerLoader.on_stop") on_stop_mock = mocker.patch("ahriman.core.triggers.trigger_loader.TriggerLoader.on_stop")
_, repository_id = configuration.check_loaded()
trigger_loader = TriggerLoader.load("x86_64", configuration) trigger_loader = TriggerLoader.load(repository_id, configuration)
trigger_loader.on_start() trigger_loader.on_start()
del trigger_loader del trigger_loader
on_stop_mock.assert_called_once_with() on_stop_mock.assert_called_once_with()
@ -167,8 +170,9 @@ def test_on_stop_without_on_start(configuration: Configuration, mocker: MockerFi
must call not on_stop on exit if on_start wasn't called must call not on_stop on exit if on_start wasn't called
""" """
on_stop_mock = mocker.patch("ahriman.core.triggers.trigger_loader.TriggerLoader.on_stop") on_stop_mock = mocker.patch("ahriman.core.triggers.trigger_loader.TriggerLoader.on_stop")
_, repository_id = configuration.check_loaded()
trigger_loader = TriggerLoader.load("x86_64", configuration) trigger_loader = TriggerLoader.load(repository_id, configuration)
del trigger_loader del trigger_loader
on_stop_mock.assert_not_called() on_stop_mock.assert_not_called()

View File

@ -95,19 +95,20 @@ def s3(configuration: Configuration) -> S3:
@pytest.fixture @pytest.fixture
def s3_remote_objects() -> list[MagicMock]: def s3_remote_objects(configuration: Configuration) -> list[MagicMock]:
""" """
fixture for boto3 like S3 objects fixture for boto3 like S3 objects
Returns: Returns:
list[MagicMock]: boto3 like S3 objects test instance list[MagicMock]: boto3 like S3 objects test instance
""" """
_, repository_id = configuration.check_loaded()
delete_mock = MagicMock() delete_mock = MagicMock()
result = [] result = []
for item in ["a", "b", "c"]: for item in ["a", "b", "c"]:
s3_object = MagicMock() s3_object = MagicMock()
s3_object.key = f"x86_64/{item}" s3_object.key = f"{repository_id.name}/{repository_id.architecture}/{item}"
s3_object.e_tag = f"\"{item}\"" s3_object.e_tag = f"\"{item}\""
s3_object.delete = delete_mock s3_object.delete = delete_mock

View File

@ -6,14 +6,30 @@ from pytest_mock import MockerFixture
from typing import Any from typing import Any
from unittest.mock import call as MockCall from unittest.mock import call as MockCall
from ahriman.core.configuration import Configuration
from ahriman.core.upload.github import GitHub from ahriman.core.upload.github import GitHub
def test_github_release_tag(configuration: Configuration) -> None:
"""
must correctly define GitHub release tag
"""
_, repository_id = configuration.check_loaded()
instance = GitHub(repository_id, configuration, "github:x86_64")
assert instance.github_release_tag == instance.github_release_tag_name == repository_id.architecture
configuration.set_option("github:x86_64", "use_full_release_name", "yes")
instance = GitHub(repository_id, configuration, "github:x86_64")
assert instance.github_release_tag == f"{repository_id.name}-{repository_id.architecture}"
assert instance.github_release_tag_name == f"{repository_id.name} {repository_id.architecture}"
def test_asset_remove(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None: def test_asset_remove(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
""" """
must remove asset from the release must remove asset from the release
""" """
request_mock = mocker.patch("ahriman.core.upload.github.Github.make_request") request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
github.asset_remove(github_release, "asset_name") github.asset_remove(github_release, "asset_name")
request_mock.assert_called_once_with("DELETE", "asset_url") request_mock.assert_called_once_with("DELETE", "asset_url")
@ -22,7 +38,7 @@ def test_asset_remove_unknown(github: GitHub, github_release: dict[str, Any], mo
""" """
must not fail if no asset found must not fail if no asset found
""" """
request_mock = mocker.patch("ahriman.core.upload.github.Github.make_request") request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
github.asset_remove(github_release, "unknown_asset_name") github.asset_remove(github_release, "unknown_asset_name")
request_mock.assert_not_called() request_mock.assert_not_called()
@ -32,8 +48,8 @@ def test_asset_upload(github: GitHub, github_release: dict[str, Any], mocker: Mo
must upload asset to the repository must upload asset to the repository
""" """
mocker.patch("pathlib.Path.open") mocker.patch("pathlib.Path.open")
request_mock = mocker.patch("ahriman.core.upload.github.Github.make_request") request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
remove_mock = mocker.patch("ahriman.core.upload.github.Github.asset_remove") remove_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_remove")
github.asset_upload(github_release, Path("/root/new.tar.xz")) github.asset_upload(github_release, Path("/root/new.tar.xz"))
request_mock.assert_called_once_with("POST", "upload_url", params=[("name", "new.tar.xz")], request_mock.assert_called_once_with("POST", "upload_url", params=[("name", "new.tar.xz")],
@ -47,8 +63,8 @@ def test_asset_upload_with_removal(github: GitHub, github_release: dict[str, Any
must remove existing file before upload must remove existing file before upload
""" """
mocker.patch("pathlib.Path.open") mocker.patch("pathlib.Path.open")
mocker.patch("ahriman.core.upload.github.Github.make_request") mocker.patch("ahriman.core.upload.github.GitHub.make_request")
remove_mock = mocker.patch("ahriman.core.upload.github.Github.asset_remove") remove_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_remove")
github.asset_upload(github_release, Path("asset_name")) github.asset_upload(github_release, Path("asset_name"))
github.asset_upload(github_release, Path("/root/asset_name")) github.asset_upload(github_release, Path("/root/asset_name"))
@ -63,9 +79,9 @@ def test_asset_upload_empty_mimetype(github: GitHub, github_release: dict[str, A
must upload asset to the repository with empty mime type if the library cannot guess it must upload asset to the repository with empty mime type if the library cannot guess it
""" """
mocker.patch("pathlib.Path.open") mocker.patch("pathlib.Path.open")
mocker.patch("ahriman.core.upload.github.Github.asset_remove") mocker.patch("ahriman.core.upload.github.GitHub.asset_remove")
mocker.patch("mimetypes.guess_type", return_value=(None, None)) mocker.patch("mimetypes.guess_type", return_value=(None, None))
request_mock = mocker.patch("ahriman.core.upload.github.Github.make_request") request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
github.asset_upload(github_release, Path("/root/new.tar.xz")) github.asset_upload(github_release, Path("/root/new.tar.xz"))
request_mock.assert_called_once_with("POST", "upload_url", params=[("name", "new.tar.xz")], request_mock.assert_called_once_with("POST", "upload_url", params=[("name", "new.tar.xz")],
@ -86,7 +102,7 @@ def test_files_remove(github: GitHub, github_release: dict[str, Any], mocker: Mo
""" """
must remove files from the remote must remove files from the remote
""" """
remove_mock = mocker.patch("ahriman.core.upload.github.Github.asset_remove") remove_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_remove")
github.files_remove(github_release, {Path("a"): "a"}, {"a": "a", "b": "b"}) github.files_remove(github_release, {Path("a"): "a"}, {"a": "a", "b": "b"})
remove_mock.assert_called_once_with(github_release, "b") remove_mock.assert_called_once_with(github_release, "b")
@ -95,7 +111,7 @@ def test_files_remove_empty(github: GitHub, github_release: dict[str, Any], mock
""" """
must remove nothing if nothing changed must remove nothing if nothing changed
""" """
remove_mock = mocker.patch("ahriman.core.upload.github.Github.asset_remove") remove_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_remove")
github.files_remove(github_release, {Path("a"): "a"}, {"a": "a"}) github.files_remove(github_release, {Path("a"): "a"}, {"a": "a"})
remove_mock.assert_not_called() remove_mock.assert_not_called()
@ -104,7 +120,7 @@ def test_files_upload(github: GitHub, github_release: dict[str, Any], mocker: Mo
""" """
must upload files to the remote must upload files to the remote
""" """
upload_mock = mocker.patch("ahriman.core.upload.github.Github.asset_upload") upload_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_upload")
github.files_upload(github_release, {Path("a"): "a", Path("b"): "c", Path("c"): "c"}, {"a": "a", "b": "b"}) github.files_upload(github_release, {Path("a"): "a", Path("b"): "c", Path("c"): "c"}, {"a": "a", "b": "b"})
upload_mock.assert_has_calls([ upload_mock.assert_has_calls([
MockCall(github_release, Path("b")), MockCall(github_release, Path("b")),
@ -116,7 +132,7 @@ def test_files_upload_empty(github: GitHub, github_release: dict[str, Any], mock
""" """
must upload nothing if nothing changed must upload nothing if nothing changed
""" """
upload_mock = mocker.patch("ahriman.core.upload.github.Github.asset_upload") upload_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_upload")
github.files_upload(github_release, {Path("a"): "a"}, {"a": "a"}) github.files_upload(github_release, {Path("a"): "a"}, {"a": "a"})
upload_mock.assert_not_called() upload_mock.assert_not_called()
@ -125,17 +141,18 @@ def test_release_create(github: GitHub, mocker: MockerFixture) -> None:
""" """
must create release must create release
""" """
request_mock = mocker.patch("ahriman.core.upload.github.Github.make_request") request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
github.release_create() github.release_create()
request_mock.assert_called_once_with("POST", pytest.helpers.anyvar(str, True), request_mock.assert_called_once_with(
json={"tag_name": github.architecture, "name": github.architecture}) "POST", pytest.helpers.anyvar(str, True),
json={"tag_name": github.github_release_tag, "name": github.github_release_tag_name})
def test_release_get(github: GitHub, mocker: MockerFixture) -> None: def test_release_get(github: GitHub, mocker: MockerFixture) -> None:
""" """
must get release must get release
""" """
request_mock = mocker.patch("ahriman.core.upload.github.Github.make_request") request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
github.release_get() github.release_get()
request_mock.assert_called_once_with("GET", pytest.helpers.anyvar(str, True)) request_mock.assert_called_once_with("GET", pytest.helpers.anyvar(str, True))
@ -146,7 +163,7 @@ def test_release_get_empty(github: GitHub, mocker: MockerFixture) -> None:
""" """
response = requests.Response() response = requests.Response()
response.status_code = 404 response.status_code = 404
mocker.patch("ahriman.core.upload.github.Github.make_request", mocker.patch("ahriman.core.upload.github.GitHub.make_request",
side_effect=requests.HTTPError(response=response)) side_effect=requests.HTTPError(response=response))
assert github.release_get() is None assert github.release_get() is None
@ -155,7 +172,7 @@ def test_release_get_exception(github: GitHub, mocker: MockerFixture) -> None:
""" """
must re-raise non HTTPError exception must re-raise non HTTPError exception
""" """
mocker.patch("ahriman.core.upload.github.Github.make_request", side_effect=Exception()) mocker.patch("ahriman.core.upload.github.GitHub.make_request", side_effect=Exception())
with pytest.raises(Exception): with pytest.raises(Exception):
github.release_get() github.release_get()
@ -165,7 +182,7 @@ def test_release_get_exception_http_error(github: GitHub, mocker: MockerFixture)
must re-raise HTTPError exception with code differs from 404 must re-raise HTTPError exception with code differs from 404
""" """
exception = requests.HTTPError(response=requests.Response()) exception = requests.HTTPError(response=requests.Response())
mocker.patch("ahriman.core.upload.github.Github.make_request", side_effect=exception) mocker.patch("ahriman.core.upload.github.GitHub.make_request", side_effect=exception)
with pytest.raises(requests.HTTPError): with pytest.raises(requests.HTTPError):
github.release_get() github.release_get()
@ -174,7 +191,7 @@ def test_release_update(github: GitHub, github_release: dict[str, Any], mocker:
""" """
must update release must update release
""" """
request_mock = mocker.patch("ahriman.core.upload.github.Github.make_request") request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
github.release_update(github_release, "body") github.release_update(github_release, "body")
request_mock.assert_called_once_with("POST", "release_url", json={"body": "body"}) request_mock.assert_called_once_with("POST", "release_url", json={"body": "body"})
@ -183,12 +200,12 @@ def test_release_sync(github: GitHub, mocker: MockerFixture) -> None:
""" """
must run sync command must run sync command
""" """
release_get_mock = mocker.patch("ahriman.core.upload.github.Github.release_get", return_value={}) release_get_mock = mocker.patch("ahriman.core.upload.github.GitHub.release_get", return_value={})
get_hashes_mock = mocker.patch("ahriman.core.upload.github.Github.get_hashes", return_value={}) get_hashes_mock = mocker.patch("ahriman.core.upload.github.GitHub.get_hashes", return_value={})
get_local_files_mock = mocker.patch("ahriman.core.upload.github.Github.get_local_files", return_value={}) get_local_files_mock = mocker.patch("ahriman.core.upload.github.GitHub.get_local_files", return_value={})
files_upload_mock = mocker.patch("ahriman.core.upload.github.Github.files_upload") files_upload_mock = mocker.patch("ahriman.core.upload.github.GitHub.files_upload")
files_remove_mock = mocker.patch("ahriman.core.upload.github.Github.files_remove") files_remove_mock = mocker.patch("ahriman.core.upload.github.GitHub.files_remove")
release_update_mock = mocker.patch("ahriman.core.upload.github.Github.release_update") release_update_mock = mocker.patch("ahriman.core.upload.github.GitHub.release_update")
github.sync(Path("local"), []) github.sync(Path("local"), [])
release_get_mock.assert_called_once_with() release_get_mock.assert_called_once_with()
@ -203,13 +220,13 @@ def test_release_sync_create_release(github: GitHub, mocker: MockerFixture) -> N
""" """
must create release in case if it does not exist must create release in case if it does not exist
""" """
mocker.patch("ahriman.core.upload.github.Github.release_get", return_value=None) mocker.patch("ahriman.core.upload.github.GitHub.release_get", return_value=None)
mocker.patch("ahriman.core.upload.github.Github.get_hashes") mocker.patch("ahriman.core.upload.github.GitHub.get_hashes")
mocker.patch("ahriman.core.upload.github.Github.get_local_files") mocker.patch("ahriman.core.upload.github.GitHub.get_local_files")
mocker.patch("ahriman.core.upload.github.Github.files_upload") mocker.patch("ahriman.core.upload.github.GitHub.files_upload")
mocker.patch("ahriman.core.upload.github.Github.files_remove") mocker.patch("ahriman.core.upload.github.GitHub.files_remove")
mocker.patch("ahriman.core.upload.github.Github.release_update") mocker.patch("ahriman.core.upload.github.GitHub.release_update")
release_create_mock = mocker.patch("ahriman.core.upload.github.Github.release_create") release_create_mock = mocker.patch("ahriman.core.upload.github.GitHub.release_create")
github.sync(Path("local"), []) github.sync(Path("local"), [])
release_create_mock.assert_called_once_with() release_create_mock.assert_called_once_with()

View File

@ -38,12 +38,12 @@ def test_files_remove(s3_remote_objects: list[Any]) -> None:
must remove remote objects must remove remote objects
""" """
local_files = { local_files = {
Path(item.key): item.e_tag for item in s3_remote_objects if item.key != "x86_64/a" Path(item.key): item.e_tag for item in s3_remote_objects if item.key != "aur-clone/x86_64/a"
} }
remote_objects = {Path(item.key): item for item in s3_remote_objects} remote_objects = {Path(item.key): item for item in s3_remote_objects}
S3.files_remove(local_files, remote_objects) S3.files_remove(local_files, remote_objects)
remote_objects[Path("x86_64/a")].delete.assert_called_once_with() remote_objects[Path("aur-clone/x86_64/a")].delete.assert_called_once_with()
def test_files_upload(s3: S3, s3_remote_objects: list[Any], mocker: MockerFixture) -> None: def test_files_upload(s3: S3, s3_remote_objects: list[Any], mocker: MockerFixture) -> None:
@ -55,9 +55,10 @@ def test_files_upload(s3: S3, s3_remote_objects: list[Any], mocker: MockerFixtur
root = Path("path") root = Path("path")
local_files = { local_files = {
Path(item.key.replace("a", "d")): item.e_tag.replace("b", "d").replace("\"", "") Path(item.key[:-1] + item.key[-1].replace("a", "d")): item.e_tag.replace("b", "d").replace("\"", "")
for item in s3_remote_objects for item in s3_remote_objects
} }
print(local_files)
remote_objects = {Path(item.key): item for item in s3_remote_objects} remote_objects = {Path(item.key): item for item in s3_remote_objects}
mocker.patch("mimetypes.guess_type", side_effect=mimetype) mocker.patch("mimetypes.guess_type", side_effect=mimetype)
@ -67,12 +68,12 @@ def test_files_upload(s3: S3, s3_remote_objects: list[Any], mocker: MockerFixtur
upload_mock.upload_file.assert_has_calls( upload_mock.upload_file.assert_has_calls(
[ [
MockCall( MockCall(
Filename=str(root / s3.architecture / "b"), Filename=str(root / s3.remote_root / "b"),
Key=f"{s3.architecture}/{s3.architecture}/b", Key=f"{s3.remote_root}/b",
ExtraArgs={"ContentType": "text/html"}), ExtraArgs={"ContentType": "text/html"}),
MockCall( MockCall(
Filename=str(root / s3.architecture / "d"), Filename=str(root / s3.remote_root / "d"),
Key=f"{s3.architecture}/{s3.architecture}/d", Key=f"{s3.remote_root}/d",
ExtraArgs=None), ExtraArgs=None),
], ],
any_order=True) any_order=True)
@ -91,7 +92,7 @@ def test_get_remote_objects(s3: S3, s3_remote_objects: list[Any]) -> None:
""" """
must generate list of remote objects by calling boto3 function must generate list of remote objects by calling boto3 function
""" """
expected = {Path(item.key).relative_to(s3.architecture): item for item in s3_remote_objects} expected = {Path(item.key).relative_to(s3.remote_root): item for item in s3_remote_objects}
s3.bucket = MagicMock() s3.bucket = MagicMock()
s3.bucket.objects.filter.return_value = s3_remote_objects s3.bucket.objects.filter.return_value = s3_remote_objects

View File

@ -14,8 +14,10 @@ def test_upload_failure(configuration: Configuration, mocker: MockerFixture) ->
must raise SyncFailed on errors must raise SyncFailed on errors
""" """
mocker.patch("ahriman.core.upload.rsync.Rsync.sync", side_effect=Exception()) mocker.patch("ahriman.core.upload.rsync.Rsync.sync", side_effect=Exception())
_, repository_id = configuration.check_loaded()
with pytest.raises(SynchronizationError): with pytest.raises(SynchronizationError):
Upload.load("x86_64", configuration, "rsync").run(Path("path"), []) Upload.load(repository_id, configuration, "rsync").run(Path("path"), [])
def test_report_dummy(configuration: Configuration, mocker: MockerFixture) -> None: def test_report_dummy(configuration: Configuration, mocker: MockerFixture) -> None:
@ -24,7 +26,9 @@ def test_report_dummy(configuration: Configuration, mocker: MockerFixture) -> No
""" """
mocker.patch("ahriman.models.upload_settings.UploadSettings.from_option", return_value=UploadSettings.Disabled) mocker.patch("ahriman.models.upload_settings.UploadSettings.from_option", return_value=UploadSettings.Disabled)
upload_mock = mocker.patch("ahriman.core.upload.upload.Upload.sync") upload_mock = mocker.patch("ahriman.core.upload.upload.Upload.sync")
Upload.load("x86_64", configuration, "disabled").run(Path("path"), []) _, repository_id = configuration.check_loaded()
Upload.load(repository_id, configuration, "disabled").run(Path("path"), [])
upload_mock.assert_called_once_with(Path("path"), []) upload_mock.assert_called_once_with(Path("path"), [])
@ -33,7 +37,9 @@ def test_upload_rsync(configuration: Configuration, mocker: MockerFixture) -> No
must upload via rsync must upload via rsync
""" """
upload_mock = mocker.patch("ahriman.core.upload.rsync.Rsync.sync") upload_mock = mocker.patch("ahriman.core.upload.rsync.Rsync.sync")
Upload.load("x86_64", configuration, "rsync").run(Path("path"), []) _, repository_id = configuration.check_loaded()
Upload.load(repository_id, configuration, "rsync").run(Path("path"), [])
upload_mock.assert_called_once_with(Path("path"), []) upload_mock.assert_called_once_with(Path("path"), [])
@ -42,7 +48,9 @@ def test_upload_s3(configuration: Configuration, mocker: MockerFixture) -> None:
must upload via s3 must upload via s3
""" """
upload_mock = mocker.patch("ahriman.core.upload.s3.S3.sync") upload_mock = mocker.patch("ahriman.core.upload.s3.S3.sync")
Upload.load("x86_64", configuration, "customs3").run(Path("path"), []) _, repository_id = configuration.check_loaded()
Upload.load(repository_id, configuration, "customs3").run(Path("path"), [])
upload_mock.assert_called_once_with(Path("path"), []) upload_mock.assert_called_once_with(Path("path"), [])
@ -50,8 +58,10 @@ def test_upload_github(configuration: Configuration, mocker: MockerFixture) -> N
""" """
must upload via github must upload via github
""" """
upload_mock = mocker.patch("ahriman.core.upload.github.Github.sync") upload_mock = mocker.patch("ahriman.core.upload.github.GitHub.sync")
Upload.load("x86_64", configuration, "github").run(Path("path"), []) _, repository_id = configuration.check_loaded()
Upload.load(repository_id, configuration, "github").run(Path("path"), [])
upload_mock.assert_called_once_with(Path("path"), []) upload_mock.assert_called_once_with(Path("path"), [])
@ -62,6 +72,7 @@ def test_upload_ahriman(configuration: Configuration, mocker: MockerFixture) ->
upload_mock = mocker.patch("ahriman.core.upload.remote_service.RemoteService.sync") upload_mock = mocker.patch("ahriman.core.upload.remote_service.RemoteService.sync")
configuration.set_option("web", "host", "localhost") configuration.set_option("web", "host", "localhost")
configuration.set_option("web", "port", "8080") configuration.set_option("web", "port", "8080")
_, repository_id = configuration.check_loaded()
Upload.load("x86_64", configuration, "remote-service").run(Path("path"), []) Upload.load(repository_id, configuration, "remote-service").run(Path("path"), [])
upload_mock.assert_called_once_with(Path("path"), []) upload_mock.assert_called_once_with(Path("path"), [])

View File

@ -22,7 +22,8 @@ def test_on_result(configuration: Configuration, mocker: MockerFixture) -> None:
""" """
configuration.set_option("upload", "target", "rsync") configuration.set_option("upload", "target", "rsync")
run_mock = mocker.patch("ahriman.core.upload.upload.Upload.run") run_mock = mocker.patch("ahriman.core.upload.upload.Upload.run")
_, repository_id = configuration.check_loaded()
trigger = UploadTrigger("x86_64", configuration) trigger = UploadTrigger(repository_id, configuration)
trigger.on_result(Result(), []) trigger.on_result(Result(), [])
run_mock.assert_called_once_with(configuration.repository_paths.repository, []) run_mock.assert_called_once_with(configuration.repository_paths.repository, [])

View File

@ -0,0 +1,33 @@
import pytest
from ahriman.core.exceptions import InitializeError
from ahriman.models.repository_id import RepositoryId
def test_post_init() -> None:
"""
must raise InitializeError if name is empty
"""
RepositoryId("x86_64", "aur-clone")
with pytest.raises(InitializeError):
RepositoryId("x86_64", "")
def test_lt() -> None:
"""
must correctly compare instances
"""
assert RepositoryId("x86_64", "a") < RepositoryId("x86_64", "b")
assert RepositoryId("x86_64", "b") > RepositoryId("x86_64", "a")
assert RepositoryId("i686", "a") < RepositoryId("x86_64", "a")
assert RepositoryId("x86_64", "a") > RepositoryId("i686", "a")
def test_lt_invalid() -> None:
"""
must raise ValueError if other is not valid repository id
"""
with pytest.raises(ValueError):
RepositoryId("x86_64", "a") < 42

View File

@ -7,6 +7,7 @@ from unittest.mock import MagicMock, call as MockCall
from ahriman.core.exceptions import PathError from ahriman.core.exceptions import PathError
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.repository_id import RepositoryId
from ahriman.models.repository_paths import RepositoryPaths from ahriman.models.repository_paths import RepositoryPaths
@ -26,6 +27,18 @@ def _get_owner(root: Path, same: bool) -> Callable[[Path], tuple[int, int]]:
return lambda path: root_owner if path == root else non_root_owner return lambda path: root_owner if path == root else non_root_owner
def test_suffix(repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must correctly define suffix
"""
is_dir_mock = mocker.patch("pathlib.Path.is_dir", autospec=True, return_value=True)
assert RepositoryPaths(Path("root"), repository_id)._suffix == Path(repository_id.architecture)
is_dir_mock.assert_called_once_with(Path("root") / "repository" / repository_id.architecture)
mocker.patch("pathlib.Path.is_dir", return_value=False)
assert RepositoryPaths(Path("root"), repository_id)._suffix == Path(repository_id.name) / repository_id.architecture
def test_root_owner(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None: def test_root_owner(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
""" """
must correctly define root directory owner must correctly define root directory owner
@ -36,11 +49,63 @@ def test_root_owner(repository_paths: RepositoryPaths, mocker: MockerFixture) ->
def test_known_architectures(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None: def test_known_architectures(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
""" """
must list available directory paths must list available directory paths /repository/repo/arch
""" """
iterdir_mock = mocker.patch("pathlib.Path.iterdir") def iterdir(root: Path) -> list[Path]:
repository_paths.known_architectures(repository_paths.root) if root == repository_paths._repository_root:
iterdir_mock.assert_called_once_with() return [Path("repo1"), Path("repo2")]
if root == Path("repo1"):
return [Path("i686"), Path("x86_64")]
return [Path("x86_64")]
is_dir_mock = mocker.patch("pathlib.Path.is_dir", autospec=True, return_value=True)
iterdir_mock = mocker.patch("pathlib.Path.iterdir", autospec=True, side_effect=iterdir)
assert repository_paths.known_architectures(repository_paths.root, "") == {
RepositoryId("i686", "repo1"),
RepositoryId("x86_64", "repo1"),
RepositoryId("x86_64", "repo2"),
}
iterdir_mock.assert_has_calls([
MockCall(repository_paths._repository_root),
MockCall(Path("repo1")),
MockCall(Path("repo2")),
])
is_dir_mock.assert_has_calls([
MockCall(Path("repo1")),
MockCall(Path("i686")),
MockCall(Path("x86_64")),
MockCall(Path("repo2")),
MockCall(Path("x86_64")),
])
def test_known_architectures_legacy(repository_id: RepositoryId, repository_paths: RepositoryPaths,
mocker: MockerFixture) -> None:
"""
must correctly define legacy tree /repository/arch
"""
def iterdir(root: Path) -> list[Path]:
if root == repository_paths._repository_root:
return [Path("i686"), Path("x86_64")]
return []
is_dir_mock = mocker.patch("pathlib.Path.is_dir", autospec=True, return_value=True)
iterdir_mock = mocker.patch("pathlib.Path.iterdir", autospec=True, side_effect=iterdir)
assert repository_paths.known_architectures(repository_paths.root, repository_id.name) == {
RepositoryId("i686", repository_id.name),
RepositoryId("x86_64", repository_id.name),
}
iterdir_mock.assert_has_calls([
MockCall(repository_paths._repository_root),
MockCall(Path("i686")),
MockCall(Path("x86_64")),
])
is_dir_mock.assert_has_calls([
MockCall(Path("i686")),
MockCall(Path("x86_64")),
])
def test_owner(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None: def test_owner(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
@ -140,10 +205,10 @@ def test_tree_create(repository_paths: RepositoryPaths, mocker: MockerFixture) -
for prop in dir(repository_paths) for prop in dir(repository_paths)
if not prop.startswith("_") if not prop.startswith("_")
and not prop.endswith("_for") and not prop.endswith("_for")
and prop not in ("architecture", and prop not in ("chown",
"chown",
"known_architectures", "known_architectures",
"owner", "owner",
"repository_id",
"root", "root",
"root_owner", "root_owner",
"tree_clear", "tree_clear",

View File

@ -16,7 +16,6 @@ from ahriman.core.configuration import Configuration
from ahriman.core.database import SQLite from ahriman.core.database import SQLite
from ahriman.core.repository import Repository from ahriman.core.repository import Repository
from ahriman.core.spawn import Spawn from ahriman.core.spawn import Spawn
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user import User from ahriman.models.user import User
from ahriman.web.web import setup_service from ahriman.web.web import setup_service