simplify watcher class

This commit is contained in:
Evgenii Alekseev 2024-05-17 15:54:43 +03:00
parent 702bd03b22
commit 13c063c99d
12 changed files with 111 additions and 333 deletions

View File

@ -218,21 +218,6 @@ class PackageOperations(Operations):
) )
} }
def package_base_update(self, package: Package, repository_id: RepositoryId | None = None) -> None:
"""
update package base only
Args:
package(Package): package properties
repository_id(RepositoryId, optional): repository unique identifier override (Default value = None)
"""
repository_id = repository_id or self._repository_id
def run(connection: Connection) -> None:
self._package_update_insert_base(connection, package, repository_id)
return self.with_connection(run, commit=True)
def package_remove(self, package_base: str, repository_id: RepositoryId | None = None) -> None: def package_remove(self, package_base: str, repository_id: RepositoryId | None = None) -> None:
""" """
remove package from database remove package from database
@ -287,26 +272,6 @@ class PackageOperations(Operations):
return self.with_connection(lambda connection: list(run(connection))) return self.with_connection(lambda connection: list(run(connection)))
def remotes_get(self, repository_id: RepositoryId | None = None) -> dict[str, RemoteSource]:
"""
get packages remotes based on current settings
Args:
repository_id(RepositoryId, optional): repository unique identifier override (Default value = None)
Returns:
dict[str, RemoteSource]: map of package base to its remote sources
"""
repository_id = repository_id or self._repository_id
def run(connection: Connection) -> dict[str, Package]:
return self._packages_get_select_package_bases(connection, repository_id)
return {
package_base: package.remote
for package_base, package in self.with_connection(run).items()
}
def status_update(self, package_base: str, status: BuildStatus, repository_id: RepositoryId | None = None) -> None: def status_update(self, package_base: str, status: BuildStatus, repository_id: RepositoryId | None = None) -> None:
""" """
insert base package status into table insert base package status into table

View File

@ -17,7 +17,9 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# 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 collections.abc import Callable
from threading import Lock from threading import Lock
from typing import Any, Self
from ahriman.core.exceptions import UnknownPackageError from ahriman.core.exceptions import UnknownPackageError
from ahriman.core.log import LazyLogging from ahriman.core.log import LazyLogging
@ -88,53 +90,13 @@ class Watcher(LazyLogging):
self._known[package.base] = (package, BuildStatus(status)) self._known[package.base] = (package, BuildStatus(status))
self.client.package_add(package, status) self.client.package_add(package, status)
def package_changes_get(self, package_base: str) -> Changes: package_changes_get: Callable[[str], Changes]
"""
retrieve package changes
Args: package_changes_update: Callable[[str, Changes], None]
package_base(str): package base
Returns: package_dependencies_get: Callable[[str], Dependencies]
Changes: package changes if available
"""
_ = self.package_get(package_base)
return self.client.package_changes_get(package_base)
def package_changes_update(self, package_base: str, changes: Changes) -> None: package_dependencies_update: Callable[[str, Dependencies], None]
"""
update package changes
Args:
package_base(str): package base
changes(Changes): package changes
"""
_ = self.package_get(package_base)
self.client.package_changes_update(package_base, changes)
def package_dependencies_get(self, package_base: str) -> Dependencies:
"""
retrieve package dependencies
Args:
package_base(str): package base
Returns:
Dependencies: package dependencies if available
"""
_ = self.package_get(package_base)
return self.client.package_dependencies_get(package_base)
def package_dependencies_update(self, package_base: str, dependencies: Dependencies) -> None:
"""
update package dependencies
Args:
package_base(str): package base
dependencies(Dependencies): package dependencies
"""
_ = self.package_get(package_base)
self.client.package_dependencies_update(package_base, dependencies)
def package_get(self, package_base: str) -> tuple[Package, BuildStatus]: def package_get(self, package_base: str) -> tuple[Package, BuildStatus]:
""" """
@ -155,32 +117,7 @@ class Watcher(LazyLogging):
except KeyError: except KeyError:
raise UnknownPackageError(package_base) from None raise UnknownPackageError(package_base) from None
def package_logs_get(self, package_base: str, limit: int = -1, offset: int = 0) -> list[tuple[float, str]]: def package_logs_add(self, log_record_id: LogRecordId, created: float, message: str) -> None:
"""
extract logs for the package base
Args:
package_base(str): package base
limit(int, optional): limit records to the specified count, -1 means unlimited (Default value = -1)
offset(int, optional): records offset (Default value = 0)
Returns:
list[tuple[float, str]]: package logs
"""
_ = self.package_get(package_base)
return self.client.package_logs_get(package_base, limit, offset)
def package_logs_remove(self, package_base: str, version: str | None) -> None:
"""
remove package related logs
Args:
package_base(str): package base
version(str): package version
"""
self.client.package_logs_remove(package_base, version)
def package_logs_update(self, log_record_id: LogRecordId, created: float, message: str) -> None:
""" """
make new log record into database make new log record into database
@ -195,40 +132,15 @@ class Watcher(LazyLogging):
self._last_log_record_id = log_record_id self._last_log_record_id = log_record_id
self.client.package_logs_add(log_record_id, created, message) self.client.package_logs_add(log_record_id, created, message)
def package_patches_get(self, package_base: str, variable: str | None) -> list[PkgbuildPatch]: package_logs_get: Callable[[str, int, int], list[tuple[float, str]]]
"""
get patches for the package
Args: package_logs_remove: Callable[[str, str | None], None]
package_base(str): package base
variable(str | None): patch variable name if any
Returns: package_patches_get: Callable[[str, str | None], list[PkgbuildPatch]]
list[PkgbuildPatch]: list of patches which are stored for the package
"""
# patches are package base based, we don't know (and don't differentiate) to which package does them belong
# so here we skip checking if package exists or not
return self.client.package_patches_get(package_base, variable)
def package_patches_remove(self, package_base: str, variable: str) -> None: package_patches_remove: Callable[[str, str], None]
"""
remove package patch
Args: package_patches_update: Callable[[str, PkgbuildPatch], None]
package_base(str): package base
variable(str): patch variable name
"""
self.client.package_patches_remove(package_base, variable)
def package_patches_update(self, package_base: str, patch: PkgbuildPatch) -> None:
"""
update package patch
Args:
package_base(str): package base
patch(PkgbuildPatch): package patch
"""
self.client.package_patches_update(package_base, patch)
def package_remove(self, package_base: str) -> None: def package_remove(self, package_base: str) -> None:
""" """
@ -263,3 +175,34 @@ class Watcher(LazyLogging):
status(BuildStatusEnum): new service status status(BuildStatusEnum): new service status
""" """
self.status = BuildStatus(status) self.status = BuildStatus(status)
def __call__(self, package_base: str | None) -> Self:
"""
extract client for future calls
Args:
package_base(str | None): package base to validate that package exists if applicable
Returns:
Self: instance of self to pass calls to the client
"""
if package_base is not None:
_ = self.package_get(package_base)
return self
def __getattr__(self, item: str) -> Any:
"""
proxy methods for reporter client
Args:
item(str): property name:
Returns:
Any: attribute by its name
Raises:
AttributeError: in case if no such attribute found
"""
if (method := getattr(self.client, item, None)) is not None:
return method
raise AttributeError(f"'{self.__class__.__qualname__}' object has no attribute '{item}'")

View File

@ -218,12 +218,13 @@ class BaseView(View, CorsViewMixin):
return RepositoryId(architecture, name) return RepositoryId(architecture, name)
return next(iter(sorted(self.services.keys()))) return next(iter(sorted(self.services.keys())))
def service(self, repository_id: RepositoryId | None = None) -> Watcher: def service(self, repository_id: RepositoryId | None = None, package_base: str | None = None) -> Watcher:
""" """
get status watcher instance get status watcher instance
Args: Args:
repository_id(RepositoryId | None, optional): repository unique identifier (Default value = None) repository_id(RepositoryId | None, optional): repository unique identifier (Default value = None)
package_base(str | None, optional): package base to validate if exists (Default value = None)
Returns: Returns:
Watcher: build status watcher instance. If no repository provided, it will return the first one Watcher: build status watcher instance. If no repository provided, it will return the first one
@ -234,7 +235,7 @@ class BaseView(View, CorsViewMixin):
if repository_id is None: if repository_id is None:
repository_id = self.repository_id() repository_id = self.repository_id()
try: try:
return self.services[repository_id] return self.services[repository_id](package_base)
except KeyError: except KeyError:
raise HTTPNotFound(reason=f"Repository {repository_id.id} is unknown") raise HTTPNotFound(reason=f"Repository {repository_id.id} is unknown")

View File

@ -71,7 +71,7 @@ class ChangesView(StatusViewGuard, BaseView):
package_base = self.request.match_info["package"] package_base = self.request.match_info["package"]
try: try:
changes = self.service().package_changes_get(package_base) changes = self.service(package_base=package_base).package_changes_get(package_base)
except UnknownPackageError: except UnknownPackageError:
raise HTTPNotFound(reason=f"Package {package_base} is unknown") raise HTTPNotFound(reason=f"Package {package_base} is unknown")
@ -86,7 +86,7 @@ class ChangesView(StatusViewGuard, BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema}, 400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema}, 401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema}, 403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Package base and/or repository are unknown", "schema": ErrorSchema}, 404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema}, 500: {"description": "Internal server error", "schema": ErrorSchema},
}, },
security=[{"token": [POST_PERMISSION]}], security=[{"token": [POST_PERMISSION]}],
@ -113,9 +113,6 @@ class ChangesView(StatusViewGuard, BaseView):
raise HTTPBadRequest(reason=str(ex)) raise HTTPBadRequest(reason=str(ex))
changes = Changes(last_commit_sha, change) changes = Changes(last_commit_sha, change)
try: self.service().package_changes_update(package_base, changes)
self.service().package_changes_update(package_base, changes)
except UnknownPackageError:
raise HTTPNotFound(reason=f"Package {package_base} is unknown")
raise HTTPNoContent raise HTTPNoContent

View File

@ -71,7 +71,7 @@ class DependenciesView(StatusViewGuard, BaseView):
package_base = self.request.match_info["package"] package_base = self.request.match_info["package"]
try: try:
dependencies = self.service().package_dependencies_get(package_base) dependencies = self.service(package_base=package_base).package_dependencies_get(package_base)
except UnknownPackageError: except UnknownPackageError:
raise HTTPNotFound(reason=f"Package {package_base} is unknown") raise HTTPNotFound(reason=f"Package {package_base} is unknown")
@ -113,7 +113,7 @@ class DependenciesView(StatusViewGuard, BaseView):
raise HTTPBadRequest(reason=str(ex)) raise HTTPBadRequest(reason=str(ex))
try: try:
self.service().package_dependencies_update(package_base, dependencies) self.service(package_base=package_base).package_dependencies_update(package_base, dependencies)
except UnknownPackageError: except UnknownPackageError:
raise HTTPNotFound(reason=f"Package {package_base} is unknown") raise HTTPNotFound(reason=f"Package {package_base} is unknown")

View File

@ -104,7 +104,7 @@ class LogsView(StatusViewGuard, BaseView):
try: try:
_, status = self.service().package_get(package_base) _, status = self.service().package_get(package_base)
logs = self.service().package_logs_get(package_base) logs = self.service(package_base=package_base).package_logs_get(package_base, -1, 0)
except UnknownPackageError: except UnknownPackageError:
raise HTTPNotFound(reason=f"Package {package_base} is unknown") raise HTTPNotFound(reason=f"Package {package_base} is unknown")
@ -150,6 +150,6 @@ class LogsView(StatusViewGuard, BaseView):
except Exception as ex: except Exception as ex:
raise HTTPBadRequest(reason=str(ex)) raise HTTPBadRequest(reason=str(ex))
self.service().package_logs_update(LogRecordId(package_base, version), created, record) self.service().package_logs_add(LogRecordId(package_base, version), created, record)
raise HTTPNoContent raise HTTPNoContent

View File

@ -69,7 +69,7 @@ class LogsView(StatusViewGuard, BaseView):
package_base = self.request.match_info["package"] package_base = self.request.match_info["package"]
limit, offset = self.page() limit, offset = self.page()
try: try:
logs = self.service().package_logs_get(package_base, limit, offset) logs = self.service(package_base=package_base).package_logs_get(package_base, limit, offset)
except UnknownPackageError: except UnknownPackageError:
raise HTTPNotFound(reason=f"Package {package_base} is unknown") raise HTTPNotFound(reason=f"Package {package_base} is unknown")

View File

@ -7,8 +7,6 @@ from unittest.mock import call as MockCall
from ahriman.core.database import SQLite from ahriman.core.database import SQLite
from ahriman.models.build_status import BuildStatus from ahriman.models.build_status import BuildStatus
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.package_source import PackageSource
from ahriman.models.remote_source import RemoteSource
def test_package_remove_package_base(database: SQLite, connection: Connection) -> None: def test_package_remove_package_base(database: SQLite, connection: Connection) -> None:
@ -185,26 +183,6 @@ def test_package_update_update(database: SQLite, package_ahriman: Package) -> No
if db_package.base == package_ahriman.base) == package_ahriman.version if db_package.base == package_ahriman.base) == package_ahriman.version
def test_remote_update_get(database: SQLite, package_ahriman: Package) -> None:
"""
must insert and retrieve package remote
"""
database.package_base_update(package_ahriman)
assert database.remotes_get()[package_ahriman.base] == package_ahriman.remote
def test_remote_update_update(database: SQLite, package_ahriman: Package) -> None:
"""
must perform package remote update for existing package
"""
database.package_base_update(package_ahriman)
remote_source = RemoteSource(source=PackageSource.Repository)
package_ahriman.remote = remote_source
database.package_base_update(package_ahriman)
assert database.remotes_get()[package_ahriman.base] == remote_source
def test_status_update(database: SQLite, package_ahriman: Package) -> None: def test_status_update(database: SQLite, package_ahriman: Package) -> None:
""" """
must insert single package status must insert single package status

View File

@ -1,16 +1,12 @@
import pytest import pytest
from pytest_mock import MockerFixture from pytest_mock import MockerFixture
from unittest.mock import call as MockCall
from ahriman.core.exceptions import UnknownPackageError from ahriman.core.exceptions import UnknownPackageError
from ahriman.core.status.watcher import Watcher from ahriman.core.status.watcher import Watcher
from ahriman.models.build_status import BuildStatus, BuildStatusEnum from ahriman.models.build_status import BuildStatus, BuildStatusEnum
from ahriman.models.changes import Changes
from ahriman.models.dependencies import Dependencies
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.pkgbuild_patch import PkgbuildPatch
def test_packages(watcher: Watcher, package_ahriman: Package) -> None: def test_packages(watcher: Watcher, package_ahriman: Package) -> None:
@ -61,82 +57,6 @@ def test_package_add(watcher: Watcher, package_ahriman: Package, mocker: MockerF
cache_mock.assert_called_once_with(package_ahriman, pytest.helpers.anyvar(int)) cache_mock.assert_called_once_with(package_ahriman, pytest.helpers.anyvar(int))
def test_package_changes_get(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must retrieve package changes
"""
cache_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get")
watcher._known = {package_ahriman.base: (package_ahriman, BuildStatus())}
watcher.package_changes_get(package_ahriman.base)
cache_mock.assert_called_once_with(package_ahriman.base)
def test_package_changes_get_failed(watcher: Watcher, package_ahriman: Package) -> None:
"""
must fail if package is unknown during fetching changes
"""
with pytest.raises(UnknownPackageError):
watcher.package_changes_get(package_ahriman.base)
def test_package_changes_update(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must update package changes
"""
cache_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_update")
watcher._known = {package_ahriman.base: (package_ahriman, BuildStatus())}
watcher.package_changes_update(package_ahriman.base, Changes())
cache_mock.assert_called_once_with(package_ahriman.base, Changes())
def test_package_changes_update_failed(watcher: Watcher, package_ahriman: Package) -> None:
"""
must fail if package is unknown during updating changes
"""
with pytest.raises(UnknownPackageError):
watcher.package_changes_update(package_ahriman.base, Changes())
def test_package_dependencies_get(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must retrieve package dependencies
"""
cache_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_dependencies_get")
watcher._known = {package_ahriman.base: (package_ahriman, BuildStatus())}
watcher.package_dependencies_get(package_ahriman.base)
cache_mock.assert_called_once_with(package_ahriman.base)
def test_package_dependencies_get_failed(watcher: Watcher, package_ahriman: Package) -> None:
"""
must fail if package is unknown during fetching dependencies
"""
with pytest.raises(UnknownPackageError):
watcher.package_dependencies_get(package_ahriman.base)
def test_package_dependencies_update(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must update package dependencies
"""
cache_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_dependencies_update")
watcher._known = {package_ahriman.base: (package_ahriman, BuildStatus())}
watcher.package_dependencies_update(package_ahriman.base, Dependencies())
cache_mock.assert_called_once_with(package_ahriman.base, Dependencies())
def test_package_dependencies_update_failed(watcher: Watcher, package_ahriman: Package) -> None:
"""
must fail if package is unknown during updating dependencies
"""
with pytest.raises(UnknownPackageError):
watcher.package_dependencies_update(package_ahriman.base, Dependencies())
def test_package_get(watcher: Watcher, package_ahriman: Package) -> None: def test_package_get(watcher: Watcher, package_ahriman: Package) -> None:
""" """
must return package status must return package status
@ -155,107 +75,44 @@ def test_package_get_failed(watcher: Watcher, package_ahriman: Package) -> None:
watcher.package_get(package_ahriman.base) watcher.package_get(package_ahriman.base)
def test_package_logs_get(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None: def test_package_logs_add_new(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must return package logs
"""
watcher._known = {package_ahriman.base: (package_ahriman, BuildStatus())}
logs_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_logs_get")
watcher.package_logs_get(package_ahriman.base, 1, 2)
logs_mock.assert_called_once_with(package_ahriman.base, 1, 2)
def test_package_logs_get_failed(watcher: Watcher, package_ahriman: Package) -> None:
"""
must raise UnknownPackageError on logs in case of unknown package
"""
with pytest.raises(UnknownPackageError):
watcher.package_logs_get(package_ahriman.base)
def test_package_logs_remove(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must remove package logs
"""
logs_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_logs_remove")
watcher.package_logs_remove(package_ahriman.base, "42")
logs_mock.assert_called_once_with(package_ahriman.base, "42")
def test_package_logs_update_new(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
""" """
must create package logs record for new package must create package logs record for new package
""" """
delete_mock = mocker.patch("ahriman.core.status.watcher.Watcher.package_logs_remove") delete_mock = mocker.patch("ahriman.core.status.watcher.Watcher.package_logs_remove", create=True)
insert_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_logs_add") insert_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_logs_add")
log_record_id = LogRecordId(package_ahriman.base, watcher._last_log_record_id.version) log_record_id = LogRecordId(package_ahriman.base, watcher._last_log_record_id.version)
assert watcher._last_log_record_id != log_record_id assert watcher._last_log_record_id != log_record_id
watcher.package_logs_update(log_record_id, 42.01, "log record") watcher.package_logs_add(log_record_id, 42.01, "log record")
delete_mock.assert_called_once_with(package_ahriman.base, log_record_id.version) delete_mock.assert_called_once_with(package_ahriman.base, log_record_id.version)
insert_mock.assert_called_once_with(log_record_id, 42.01, "log record") insert_mock.assert_called_once_with(log_record_id, 42.01, "log record")
assert watcher._last_log_record_id == log_record_id assert watcher._last_log_record_id == log_record_id
def test_package_logs_update_update(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None: def test_package_logs_add_update(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
""" """
must create package logs record for current package must create package logs record for current package
""" """
delete_mock = mocker.patch("ahriman.core.status.watcher.Watcher.package_logs_remove") delete_mock = mocker.patch("ahriman.core.status.watcher.Watcher.package_logs_remove", create=True)
insert_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_logs_add") insert_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_logs_add")
log_record_id = LogRecordId(package_ahriman.base, watcher._last_log_record_id.version) log_record_id = LogRecordId(package_ahriman.base, watcher._last_log_record_id.version)
watcher._last_log_record_id = log_record_id watcher._last_log_record_id = log_record_id
watcher.package_logs_update(log_record_id, 42.01, "log record") watcher.package_logs_add(log_record_id, 42.01, "log record")
delete_mock.assert_not_called() delete_mock.assert_not_called()
insert_mock.assert_called_once_with(log_record_id, 42.01, "log record") insert_mock.assert_called_once_with(log_record_id, 42.01, "log record")
def test_package_patches_get(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must return patches for the package
"""
watcher._known = {package_ahriman.base: (package_ahriman, BuildStatus())}
patches_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_patches_get")
watcher.package_patches_get(package_ahriman.base, None)
watcher.package_patches_get(package_ahriman.base, "var")
patches_mock.assert_has_calls([
MockCall(package_ahriman.base, None),
MockCall(package_ahriman.base, "var"),
])
def test_package_patches_remove(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must remove patches for the package
"""
patches_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_patches_remove")
watcher.package_patches_remove(package_ahriman.base, "var")
patches_mock.assert_called_once_with(package_ahriman.base, "var")
def test_package_patches_update(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must update patches for the package
"""
patch = PkgbuildPatch("key", "value")
patches_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_patches_update")
watcher.package_patches_update(package_ahriman.base, patch)
patches_mock.assert_called_once_with(package_ahriman.base, patch)
def test_package_remove(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None: def test_package_remove(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
""" """
must remove package base must remove package base
""" """
cache_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_remove") cache_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_remove")
logs_mock = mocker.patch("ahriman.core.status.watcher.Watcher.package_logs_remove") logs_mock = mocker.patch("ahriman.core.status.watcher.Watcher.package_logs_remove", create=True)
watcher._known = {package_ahriman.base: (package_ahriman, BuildStatus())} watcher._known = {package_ahriman.base: (package_ahriman, BuildStatus())}
watcher.package_remove(package_ahriman.base) watcher.package_remove(package_ahriman.base)
@ -301,3 +158,41 @@ def test_status_update(watcher: Watcher) -> None:
""" """
watcher.status_update(BuildStatusEnum.Success) watcher.status_update(BuildStatusEnum.Success)
assert watcher.status.status == BuildStatusEnum.Success assert watcher.status.status == BuildStatusEnum.Success
def test_call(watcher: Watcher, package_ahriman: Package) -> None:
"""
must return self instance if package exists
"""
watcher._known = {package_ahriman.base: (package_ahriman, BuildStatus())}
assert watcher(package_ahriman.base)
def test_call_skip(watcher: Watcher) -> None:
"""
must return self instance if no package base set
"""
assert watcher(None)
def test_call_failed(watcher: Watcher, package_ahriman: Package) -> None:
"""
must raise UnknownPackage
"""
with pytest.raises(UnknownPackageError):
assert watcher(package_ahriman.base)
def test_getattr(watcher: Watcher) -> None:
"""
must return client method call
"""
assert watcher.package_logs_remove
def test_getattr_unknown_method(watcher: Watcher) -> None:
"""
must raise AttributeError in case if no reporter attribute found
"""
with pytest.raises(AttributeError):
assert watcher.random_method

View File

@ -7,6 +7,7 @@ from pytest_mock import MockerFixture
from unittest.mock import AsyncMock from unittest.mock import AsyncMock
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import UnknownPackageError
from ahriman.models.repository_id import RepositoryId from ahriman.models.repository_id import RepositoryId
from ahriman.models.user_access import UserAccess from ahriman.models.user_access import UserAccess
from ahriman.web.keys import WatcherKey from ahriman.web.keys import WatcherKey
@ -204,6 +205,15 @@ def test_service_not_found(base: BaseView) -> None:
base.service(RepositoryId("", "")) base.service(RepositoryId("", ""))
def test_service_package(base: BaseView, repository_id: RepositoryId, mocker: MockerFixture) -> None:
"""
must validate that package exists
"""
mocker.patch("ahriman.web.views.base.BaseView.repository_id", return_value=repository_id)
with pytest.raises(UnknownPackageError):
base.service(package_base="base")
async def test_username(base: BaseView, mocker: MockerFixture) -> None: async def test_username(base: BaseView, mocker: MockerFixture) -> None:
""" """
must return identity of logged-in user must return identity of logged-in user

View File

@ -82,14 +82,3 @@ async def test_post_exception(client: TestClient, package_ahriman: Package) -> N
response = await client.post(f"/api/v1/packages/{package_ahriman.base}/changes", json=[]) response = await client.post(f"/api/v1/packages/{package_ahriman.base}/changes", json=[])
assert response.status == 400 assert response.status == 400
assert not response_schema.validate(await response.json()) assert not response_schema.validate(await response.json())
async def test_post_not_found(client: TestClient, package_ahriman: Package) -> None:
"""
must raise exception on unknown package
"""
response_schema = pytest.helpers.schema_response(ChangesView.post, code=404)
response = await client.post(f"/api/v1/packages/{package_ahriman.base}/changes", json={})
assert response.status == 404
assert not response_schema.validate(await response.json())

View File

@ -37,9 +37,9 @@ async def test_delete(client: TestClient, package_ahriman: Package, package_pyth
json={"status": BuildStatusEnum.Success.value, "package": package_python_schedule.view()}) json={"status": BuildStatusEnum.Success.value, "package": package_python_schedule.view()})
await client.post(f"/api/v1/packages/{package_ahriman.base}/logs", await client.post(f"/api/v1/packages/{package_ahriman.base}/logs",
json={"created": 42.0, "message": "message", "version": "42"}) json={"created": 42.0, "message": "message 1", "version": "42"})
await client.post(f"/api/v1/packages/{package_python_schedule.base}/logs", await client.post(f"/api/v1/packages/{package_python_schedule.base}/logs",
json={"created": 42.0, "message": "message", "version": "42"}) json={"created": 42.0, "message": "message 2", "version": "42"})
request_schema = pytest.helpers.schema_request(LogsView.delete, location="querystring") request_schema = pytest.helpers.schema_request(LogsView.delete, location="querystring")
payload = {} payload = {}