mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 15:27:17 +00:00
erase logs based on current package version
Old implementation has used process id instead, but it leads to log removal in case of remote process trigger
This commit is contained in:
parent
50775c3f0a
commit
479f0db572
@ -0,0 +1,36 @@
|
||||
#
|
||||
# Copyright (c) 2021-2023 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
__all__ = ["steps"]
|
||||
|
||||
|
||||
steps = [
|
||||
"""
|
||||
drop index logs_package_base_process_id
|
||||
""",
|
||||
"""
|
||||
alter table logs drop column process_id
|
||||
""",
|
||||
"""
|
||||
alter table logs add column version text not null default ''
|
||||
""",
|
||||
"""
|
||||
create index logs_package_base_version on logs (package_base, version)
|
||||
""",
|
||||
]
|
@ -66,13 +66,13 @@ class LogsOperations(Operations):
|
||||
connection.execute(
|
||||
"""
|
||||
insert into logs
|
||||
(package_base, process_id, created, record)
|
||||
(package_base, created, version, record)
|
||||
values
|
||||
(:package_base, :process_id, :created, :record)
|
||||
(:package_base, :created, :version, :record)
|
||||
""",
|
||||
{
|
||||
"package_base": log_record_id.package_base,
|
||||
"process_id": log_record_id.process_id,
|
||||
"version": log_record_id.version,
|
||||
"created": created,
|
||||
"record": record,
|
||||
}
|
||||
@ -80,22 +80,22 @@ class LogsOperations(Operations):
|
||||
|
||||
return self.with_connection(run, commit=True)
|
||||
|
||||
def logs_remove(self, package_base: str, current_process_id: int | None) -> None:
|
||||
def logs_remove(self, package_base: str, version: str | None) -> None:
|
||||
"""
|
||||
remove log records for the specified package
|
||||
|
||||
Args:
|
||||
package_base(str): package base to remove logs
|
||||
current_process_id(int | None): current process id. If set it will remove only logs belonging to another
|
||||
process
|
||||
version(str): package version. If set it will remove only logs belonging to another
|
||||
version
|
||||
"""
|
||||
def run(connection: Connection) -> None:
|
||||
connection.execute(
|
||||
"""
|
||||
delete from logs
|
||||
where package_base = :package_base and (:process_id is null or process_id <> :process_id)
|
||||
where package_base = :package_base and (:version is null or version <> :version)
|
||||
""",
|
||||
{"package_base": package_base, "process_id": current_process_id}
|
||||
{"package_base": package_base, "version": version}
|
||||
)
|
||||
|
||||
return self.with_connection(run, commit=True)
|
||||
|
@ -77,8 +77,8 @@ class HttpLogHandler(logging.Handler):
|
||||
Args:
|
||||
record(logging.LogRecord): log record to log
|
||||
"""
|
||||
package_base = getattr(record, "package_base", None)
|
||||
if package_base is None:
|
||||
log_record_id = getattr(record, "package_id", None)
|
||||
if log_record_id is None:
|
||||
return # in case if no package base supplied we need just skip log message
|
||||
|
||||
self.reporter.package_logs(package_base, record)
|
||||
self.reporter.package_logs(log_record_id, record)
|
||||
|
@ -24,6 +24,8 @@ from collections.abc import Generator
|
||||
from functools import cached_property
|
||||
from typing import Any
|
||||
|
||||
from ahriman.models.log_record_id import LogRecordId
|
||||
|
||||
|
||||
class LazyLogging:
|
||||
"""
|
||||
@ -60,38 +62,40 @@ class LazyLogging:
|
||||
logging.setLogRecordFactory(logging.LogRecord)
|
||||
|
||||
@staticmethod
|
||||
def _package_logger_set(package_base: str) -> None:
|
||||
def _package_logger_set(package_base: str, version: str | None) -> None:
|
||||
"""
|
||||
set package base as extra info to the logger
|
||||
|
||||
Args:
|
||||
package_base(str): package base
|
||||
version(str | None): package version if available
|
||||
"""
|
||||
current_factory = logging.getLogRecordFactory()
|
||||
|
||||
def package_record_factory(*args: Any, **kwargs: Any) -> logging.LogRecord:
|
||||
record = current_factory(*args, **kwargs)
|
||||
record.package_base = package_base
|
||||
record.package_id = LogRecordId(package_base, version or "")
|
||||
return record
|
||||
|
||||
logging.setLogRecordFactory(package_record_factory)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_package_context(self, package_base: str) -> Generator[None, None, None]:
|
||||
def in_package_context(self, package_base: str, version: str | None) -> Generator[None, None, None]:
|
||||
"""
|
||||
execute function while setting package context
|
||||
|
||||
Args:
|
||||
package_base(str): package base to set context in
|
||||
version(str | None): package version if available
|
||||
|
||||
Examples:
|
||||
This function is designed to be called as context manager with ``package_base`` argument, e.g.:
|
||||
|
||||
>>> with self.in_package_context(package.base):
|
||||
>>> with self.in_package_context(package.base, package.version):
|
||||
>>> build_package(package)
|
||||
"""
|
||||
try:
|
||||
self._package_logger_set(package_base)
|
||||
self._package_logger_set(package_base, version)
|
||||
yield
|
||||
finally:
|
||||
self._package_logger_reset()
|
||||
|
@ -93,7 +93,8 @@ class Executor(Cleaner):
|
||||
|
||||
result = Result()
|
||||
for single in updates:
|
||||
with self.in_package_context(single.base), TemporaryDirectory(ignore_cleanup_errors=True) as dir_name:
|
||||
with self.in_package_context(single.base, local_versions.get(single.base)), \
|
||||
TemporaryDirectory(ignore_cleanup_errors=True) as dir_name:
|
||||
try:
|
||||
packager = self.packager(packagers, single.base)
|
||||
build_single(single, Path(dir_name), packager.packager_id)
|
||||
@ -201,14 +202,16 @@ class Executor(Cleaner):
|
||||
package_path = self.paths.repository / safe_filename(name)
|
||||
self.repo.add(package_path)
|
||||
|
||||
current_packages = self.packages()
|
||||
current_packages = {package.base: package for package in self.packages()}
|
||||
local_versions = {package_base: package.version for package_base, package in current_packages.items()}
|
||||
|
||||
removed_packages: list[str] = [] # list of packages which have been removed from the base
|
||||
updates = self.load_archives(packages)
|
||||
packagers = packagers or Packagers()
|
||||
|
||||
result = Result()
|
||||
for local in updates:
|
||||
with self.in_package_context(local.base):
|
||||
with self.in_package_context(local.base, local_versions.get(local.base)):
|
||||
try:
|
||||
packager = self.packager(packagers, local.base)
|
||||
|
||||
@ -218,12 +221,9 @@ class Executor(Cleaner):
|
||||
self.reporter.set_success(local)
|
||||
result.add_success(local)
|
||||
|
||||
current_package_archives = {
|
||||
package
|
||||
for current in current_packages
|
||||
if current.base == local.base
|
||||
for package in current.packages
|
||||
}
|
||||
current_package_archives: set[str] = set()
|
||||
if local.base in current_packages:
|
||||
current_package_archives = set(current_packages[local.base].packages.keys())
|
||||
removed_packages.extend(current_package_archives.difference(local.packages))
|
||||
except Exception:
|
||||
self.reporter.set_failed(local.base)
|
||||
|
@ -66,10 +66,11 @@ class UpdateHandler(Cleaner):
|
||||
continue
|
||||
raise UnknownPackageError(package.base)
|
||||
|
||||
result: list[Package] = []
|
||||
local_versions = {package.base: package.version for package in self.packages()}
|
||||
|
||||
result: list[Package] = []
|
||||
for local in self.packages():
|
||||
with self.in_package_context(local.base):
|
||||
with self.in_package_context(local.base, local_versions.get(local.base)):
|
||||
if not local.remote.is_remote:
|
||||
continue # avoid checking local packages
|
||||
if local.base in self.ignore_list:
|
||||
@ -102,11 +103,12 @@ class UpdateHandler(Cleaner):
|
||||
Returns:
|
||||
list[Package]: list of local packages which are out-of-dated
|
||||
"""
|
||||
result: list[Package] = []
|
||||
packages = {local.base: local for local in self.packages()}
|
||||
local_versions = {package_base: package.version for package_base, package in packages.items()}
|
||||
|
||||
result: list[Package] = []
|
||||
for cache_dir in self.paths.cache.iterdir():
|
||||
with self.in_package_context(cache_dir.name):
|
||||
with self.in_package_context(cache_dir.name, local_versions.get(cache_dir.name)):
|
||||
try:
|
||||
source = RemoteSource(
|
||||
source=PackageSource.Local,
|
||||
|
@ -24,6 +24,7 @@ import logging
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
|
||||
from ahriman.models.internal_status import InternalStatus
|
||||
from ahriman.models.log_record_id import LogRecordId
|
||||
from ahriman.models.package import Package
|
||||
|
||||
|
||||
@ -82,12 +83,12 @@ class Client:
|
||||
del package_base
|
||||
return []
|
||||
|
||||
def package_logs(self, package_base: str, record: logging.LogRecord) -> None:
|
||||
def package_logs(self, log_record_id: LogRecordId, record: logging.LogRecord) -> None:
|
||||
"""
|
||||
post log record
|
||||
|
||||
Args:
|
||||
package_base(str) package base
|
||||
log_record_id(LogRecordId): log record id
|
||||
record(logging.LogRecord): log record to post to api
|
||||
"""
|
||||
|
||||
|
@ -17,8 +17,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import os
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.database import SQLite
|
||||
from ahriman.core.exceptions import UnknownPackageError
|
||||
@ -59,7 +57,7 @@ class Watcher(LazyLogging):
|
||||
self.status = BuildStatus()
|
||||
|
||||
# special variables for updating logs
|
||||
self._last_log_record_id = LogRecordId("", os.getpid())
|
||||
self._last_log_record_id = LogRecordId("", "")
|
||||
|
||||
@property
|
||||
def packages(self) -> list[tuple[Package, BuildStatus]]:
|
||||
@ -99,15 +97,15 @@ class Watcher(LazyLogging):
|
||||
"""
|
||||
return self.database.logs_get(package_base)
|
||||
|
||||
def logs_remove(self, package_base: str, current_process_id: int | None) -> None:
|
||||
def logs_remove(self, package_base: str, version: str | None) -> None:
|
||||
"""
|
||||
remove package related logs
|
||||
|
||||
Args:
|
||||
package_base(str): package base
|
||||
current_process_id(int | None): current process id
|
||||
version(str): package versio
|
||||
"""
|
||||
self.database.logs_remove(package_base, current_process_id)
|
||||
self.database.logs_remove(package_base, version)
|
||||
|
||||
def logs_update(self, log_record_id: LogRecordId, created: float, record: str) -> None:
|
||||
"""
|
||||
@ -120,7 +118,7 @@ class Watcher(LazyLogging):
|
||||
"""
|
||||
if self._last_log_record_id != log_record_id:
|
||||
# there is new log record, so we remove old ones
|
||||
self.logs_remove(log_record_id.package_base, log_record_id.process_id)
|
||||
self.logs_remove(log_record_id.package_base, log_record_id.version)
|
||||
self._last_log_record_id = log_record_id
|
||||
self.database.logs_insert(log_record_id, created, record)
|
||||
|
||||
|
@ -33,6 +33,7 @@ from ahriman.core.status.client import Client
|
||||
from ahriman.core.util import exception_response_text
|
||||
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
|
||||
from ahriman.models.internal_status import InternalStatus
|
||||
from ahriman.models.log_record_id import LogRecordId
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.user import User
|
||||
|
||||
@ -253,20 +254,20 @@ class WebClient(Client, LazyLogging):
|
||||
for package in response_json
|
||||
]
|
||||
|
||||
def package_logs(self, package_base: str, record: logging.LogRecord) -> None:
|
||||
def package_logs(self, log_record_id: LogRecordId, record: logging.LogRecord) -> None:
|
||||
"""
|
||||
post log record
|
||||
|
||||
Args:
|
||||
package_base(str) package base
|
||||
log_record_id(LogRecordId): log record id
|
||||
record(logging.LogRecord): log record to post to api
|
||||
"""
|
||||
payload = {
|
||||
"created": record.created,
|
||||
"message": record.getMessage(),
|
||||
"process_id": record.process,
|
||||
"version": log_record_id.version,
|
||||
}
|
||||
self.make_request("POST", self._logs_url(package_base), json=payload)
|
||||
self.make_request("POST", self._logs_url(log_record_id.package_base), json=payload)
|
||||
|
||||
def package_remove(self, package_base: str) -> None:
|
||||
"""
|
||||
|
@ -27,8 +27,8 @@ class LogRecordId:
|
||||
|
||||
Attributes:
|
||||
package_base(str): package base for which log record belongs
|
||||
process_id(int): process id from which log record was emitted
|
||||
version(str): package version for which log record belongs
|
||||
"""
|
||||
|
||||
package_base: str
|
||||
process_id: int
|
||||
version: str
|
||||
|
@ -19,6 +19,8 @@
|
||||
#
|
||||
from marshmallow import Schema, fields
|
||||
|
||||
from ahriman import __version__
|
||||
|
||||
|
||||
class LogSchema(Schema):
|
||||
"""
|
||||
@ -29,9 +31,9 @@ class LogSchema(Schema):
|
||||
"description": "Log record timestamp",
|
||||
"example": 1680537091.233495,
|
||||
})
|
||||
process_id = fields.Integer(required=True, metadata={
|
||||
"description": "Current process id",
|
||||
"example": 42,
|
||||
version = fields.Integer(required=True, metadata={
|
||||
"description": "Package version to tag",
|
||||
"example": __version__,
|
||||
})
|
||||
message = fields.String(required=True, metadata={
|
||||
"description": "Log message",
|
||||
|
@ -19,11 +19,11 @@
|
||||
#
|
||||
import aiohttp_apispec # type: ignore[import]
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from aiohttp import BodyPartReader
|
||||
from aiohttp.web import HTTPBadRequest, HTTPCreated, HTTPNotFound
|
||||
from pathlib import Path
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
from ahriman.models.user_access import UserAccess
|
||||
from ahriman.web.schemas import AuthSchema, ErrorSchema, FileSchema
|
||||
@ -68,7 +68,7 @@ class UploadView(BaseView):
|
||||
|
||||
# in order to handle errors automatically we create temporary file for long operation (transfer)
|
||||
# and then copy it to valid location
|
||||
with tempfile.NamedTemporaryFile() as cache:
|
||||
with NamedTemporaryFile() as cache:
|
||||
while True:
|
||||
chunk = await part.read_chunk()
|
||||
if not chunk:
|
||||
|
@ -137,10 +137,10 @@ class LogsView(BaseView):
|
||||
try:
|
||||
created = data["created"]
|
||||
record = data["message"]
|
||||
process_id = data["process_id"]
|
||||
version = data["version"]
|
||||
except Exception as e:
|
||||
raise HTTPBadRequest(reason=str(e))
|
||||
|
||||
self.service.logs_update(LogRecordId(package_base, process_id), created, record)
|
||||
self.service.logs_update(LogRecordId(package_base, version), created, record)
|
||||
|
||||
raise HTTPNoContent()
|
||||
|
@ -1,7 +1,7 @@
|
||||
from ahriman.core.database.migrations.m009_local_source import steps
|
||||
|
||||
|
||||
def test_migration_packagers() -> None:
|
||||
def test_migration_local_source() -> None:
|
||||
"""
|
||||
migration must not be empty
|
||||
"""
|
||||
|
@ -0,0 +1,8 @@
|
||||
from ahriman.core.database.migrations.m010_version_based_logs_removal import steps
|
||||
|
||||
|
||||
def test_migration_version_based_logs_removal() -> None:
|
||||
"""
|
||||
migration must not be empty
|
||||
"""
|
||||
assert steps
|
@ -8,11 +8,11 @@ def test_logs_insert_remove_process(database: SQLite, package_ahriman: Package,
|
||||
"""
|
||||
must clear process specific package logs
|
||||
"""
|
||||
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_python_schedule.base, 1), 42.0, "message 3")
|
||||
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_python_schedule.base, "1"), 42.0, "message 3")
|
||||
|
||||
database.logs_remove(package_ahriman.base, 1)
|
||||
database.logs_remove(package_ahriman.base, "1")
|
||||
assert database.logs_get(package_ahriman.base) == "[1970-01-01 00:00:42] message 1"
|
||||
assert database.logs_get(package_python_schedule.base) == "[1970-01-01 00:00:42] message 3"
|
||||
|
||||
@ -21,9 +21,9 @@ def test_logs_insert_remove_full(database: SQLite, package_ahriman: Package, pac
|
||||
"""
|
||||
must clear full package logs
|
||||
"""
|
||||
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_python_schedule.base, 1), 42.0, "message 3")
|
||||
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_python_schedule.base, "1"), 42.0, "message 3")
|
||||
|
||||
database.logs_remove(package_ahriman.base, None)
|
||||
assert not database.logs_get(package_ahriman.base)
|
||||
@ -34,6 +34,6 @@ def test_logs_insert_get(database: SQLite, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must insert and get package logs
|
||||
"""
|
||||
database.logs_insert(LogRecordId(package_ahriman.base, 1), 43.0, "message 2")
|
||||
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"), 42.0, "message 1")
|
||||
assert database.logs_get(package_ahriman.base) == "[1970-01-01 00:00:42] message 1\n[1970-01-01 00:00:43] message 2"
|
||||
|
@ -4,6 +4,7 @@ from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.log.http_log_handler import HttpLogHandler
|
||||
from ahriman.models.log_record_id import LogRecordId
|
||||
from ahriman.models.package import Package
|
||||
|
||||
|
||||
@ -39,13 +40,13 @@ def test_emit(configuration: Configuration, log_record: logging.LogRecord, packa
|
||||
"""
|
||||
must emit log record to reporter
|
||||
"""
|
||||
log_record.package_base = package_ahriman.base
|
||||
log_record_id = log_record.package_id = LogRecordId(package_ahriman.base, package_ahriman.version)
|
||||
log_mock = mocker.patch("ahriman.core.status.client.Client.package_logs")
|
||||
|
||||
handler = HttpLogHandler(configuration, report=False)
|
||||
|
||||
handler.emit(log_record)
|
||||
log_mock.assert_called_once_with(package_ahriman.base, log_record)
|
||||
log_mock.assert_called_once_with(log_record_id, log_record)
|
||||
|
||||
|
||||
def test_emit_skip(configuration: Configuration, log_record: logging.LogRecord, mocker: MockerFixture) -> None:
|
||||
|
@ -5,6 +5,7 @@ from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.core.alpm.repo import Repo
|
||||
from ahriman.core.database import SQLite
|
||||
from ahriman.models.log_record_id import LogRecordId
|
||||
from ahriman.models.package import Package
|
||||
|
||||
|
||||
@ -20,16 +21,16 @@ def test_package_logger_set_reset(database: SQLite) -> None:
|
||||
"""
|
||||
must set and reset package base attribute
|
||||
"""
|
||||
package_base = "package base"
|
||||
log_record_id = LogRecordId("base", "version")
|
||||
|
||||
database._package_logger_set(package_base)
|
||||
database._package_logger_set(log_record_id.package_base, log_record_id.version)
|
||||
record = logging.makeLogRecord({})
|
||||
assert record.package_base == package_base
|
||||
assert record.package_id == log_record_id
|
||||
|
||||
database._package_logger_reset()
|
||||
record = logging.makeLogRecord({})
|
||||
with pytest.raises(AttributeError):
|
||||
record.package_base
|
||||
record.package_id
|
||||
|
||||
|
||||
def test_in_package_context(database: SQLite, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
@ -39,10 +40,24 @@ def test_in_package_context(database: SQLite, package_ahriman: Package, mocker:
|
||||
set_mock = mocker.patch("ahriman.core.log.LazyLogging._package_logger_set")
|
||||
reset_mock = mocker.patch("ahriman.core.log.LazyLogging._package_logger_reset")
|
||||
|
||||
with database.in_package_context(package_ahriman.base):
|
||||
with database.in_package_context(package_ahriman.base, package_ahriman.version):
|
||||
pass
|
||||
|
||||
set_mock.assert_called_once_with(package_ahriman.base)
|
||||
set_mock.assert_called_once_with(package_ahriman.base, package_ahriman.version)
|
||||
reset_mock.assert_called_once_with()
|
||||
|
||||
|
||||
def test_in_package_context_empty_version(database: SQLite, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must set package log context
|
||||
"""
|
||||
set_mock = mocker.patch("ahriman.core.log.LazyLogging._package_logger_set")
|
||||
reset_mock = mocker.patch("ahriman.core.log.LazyLogging._package_logger_reset")
|
||||
|
||||
with database.in_package_context(package_ahriman.base, None):
|
||||
pass
|
||||
|
||||
set_mock.assert_called_once_with(package_ahriman.base, None)
|
||||
reset_mock.assert_called_once_with()
|
||||
|
||||
|
||||
@ -54,7 +69,7 @@ def test_in_package_context_failed(database: SQLite, package_ahriman: Package, m
|
||||
reset_mock = mocker.patch("ahriman.core.log.LazyLogging._package_logger_reset")
|
||||
|
||||
with pytest.raises(Exception):
|
||||
with database.in_package_context(package_ahriman.base):
|
||||
with database.in_package_context(package_ahriman.base, ""):
|
||||
raise Exception()
|
||||
|
||||
reset_mock.assert_called_once_with()
|
||||
|
@ -7,6 +7,7 @@ from ahriman.core.status.client import Client
|
||||
from ahriman.core.status.web_client import WebClient
|
||||
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
|
||||
from ahriman.models.internal_status import InternalStatus
|
||||
from ahriman.models.log_record_id import LogRecordId
|
||||
from ahriman.models.package import Package
|
||||
|
||||
|
||||
@ -66,11 +67,11 @@ def test_package_get(client: Client, package_ahriman: Package) -> None:
|
||||
assert client.package_get(None) == []
|
||||
|
||||
|
||||
def test_package_log(client: Client, package_ahriman: Package, log_record: logging.LogRecord) -> None:
|
||||
def test_package_logs(client: Client, package_ahriman: Package, log_record: logging.LogRecord) -> None:
|
||||
"""
|
||||
must process log record without errors
|
||||
"""
|
||||
client.package_logs(package_ahriman.base, log_record)
|
||||
client.package_logs(LogRecordId(package_ahriman.base, package_ahriman.version), log_record)
|
||||
|
||||
|
||||
def test_package_remove(client: Client, package_ahriman: Package) -> None:
|
||||
|
@ -64,8 +64,8 @@ def test_logs_remove(watcher: Watcher, package_ahriman: Package, mocker: MockerF
|
||||
must remove package logs
|
||||
"""
|
||||
logs_mock = mocker.patch("ahriman.core.database.SQLite.logs_remove")
|
||||
watcher.logs_remove(package_ahriman.base, 42)
|
||||
logs_mock.assert_called_once_with(package_ahriman.base, 42)
|
||||
watcher.logs_remove(package_ahriman.base, "42")
|
||||
logs_mock.assert_called_once_with(package_ahriman.base, "42")
|
||||
|
||||
|
||||
def test_logs_update_new(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
@ -75,11 +75,11 @@ def test_logs_update_new(watcher: Watcher, package_ahriman: Package, mocker: Moc
|
||||
delete_mock = mocker.patch("ahriman.core.status.watcher.Watcher.logs_remove")
|
||||
insert_mock = mocker.patch("ahriman.core.database.SQLite.logs_insert")
|
||||
|
||||
log_record_id = LogRecordId(package_ahriman.base, watcher._last_log_record_id.process_id)
|
||||
log_record_id = LogRecordId(package_ahriman.base, watcher._last_log_record_id.version)
|
||||
assert watcher._last_log_record_id != log_record_id
|
||||
|
||||
watcher.logs_update(log_record_id, 42.01, "log record")
|
||||
delete_mock.assert_called_once_with(package_ahriman.base, log_record_id.process_id)
|
||||
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")
|
||||
|
||||
assert watcher._last_log_record_id == log_record_id
|
||||
@ -92,7 +92,7 @@ def test_logs_update_update(watcher: Watcher, package_ahriman: Package, mocker:
|
||||
delete_mock = mocker.patch("ahriman.core.status.watcher.Watcher.logs_remove")
|
||||
insert_mock = mocker.patch("ahriman.core.database.SQLite.logs_insert")
|
||||
|
||||
log_record_id = LogRecordId(package_ahriman.base, watcher._last_log_record_id.process_id)
|
||||
log_record_id = LogRecordId(package_ahriman.base, watcher._last_log_record_id.version)
|
||||
watcher._last_log_record_id = log_record_id
|
||||
|
||||
watcher.logs_update(log_record_id, 42.01, "log record")
|
||||
|
@ -11,6 +11,7 @@ from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.status.web_client import WebClient
|
||||
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
|
||||
from ahriman.models.internal_status import InternalStatus
|
||||
from ahriman.models.log_record_id import LogRecordId
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.user import User
|
||||
|
||||
@ -280,10 +281,10 @@ def test_package_logs(web_client: WebClient, log_record: logging.LogRecord, pack
|
||||
payload = {
|
||||
"created": log_record.created,
|
||||
"message": log_record.getMessage(),
|
||||
"process_id": log_record.process,
|
||||
"version": package_ahriman.version,
|
||||
}
|
||||
|
||||
web_client.package_logs(package_ahriman.base, log_record)
|
||||
web_client.package_logs(LogRecordId(package_ahriman.base, package_ahriman.version), log_record)
|
||||
requests_mock.assert_called_once_with("POST", pytest.helpers.anyvar(str, True),
|
||||
params=None, json=payload, files=None)
|
||||
|
||||
@ -295,7 +296,7 @@ def test_package_logs_failed(web_client: WebClient, log_record: logging.LogRecor
|
||||
"""
|
||||
mocker.patch("requests.Session.request", side_effect=Exception())
|
||||
log_record.package_base = package_ahriman.base
|
||||
web_client.package_logs(package_ahriman.base, log_record)
|
||||
web_client.package_logs(LogRecordId(package_ahriman.base, package_ahriman.version), log_record)
|
||||
|
||||
|
||||
def test_package_logs_failed_http_error(web_client: WebClient, log_record: logging.LogRecord, package_ahriman: Package,
|
||||
@ -305,7 +306,7 @@ def test_package_logs_failed_http_error(web_client: WebClient, log_record: loggi
|
||||
"""
|
||||
mocker.patch("requests.Session.request", side_effect=requests.exceptions.HTTPError())
|
||||
log_record.package_base = package_ahriman.base
|
||||
web_client.package_logs(package_ahriman.base, log_record)
|
||||
web_client.package_logs(LogRecordId(package_ahriman.base, package_ahriman.version), log_record)
|
||||
|
||||
|
||||
def test_package_remove(web_client: WebClient, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
|
@ -30,7 +30,7 @@ async def test_save_file(mocker: MockerFixture) -> None:
|
||||
part_mock.filename = "filename"
|
||||
part_mock.read_chunk = AsyncMock(side_effect=[b"content", None])
|
||||
|
||||
tempfile_mock = mocker.patch("tempfile.NamedTemporaryFile")
|
||||
tempfile_mock = mocker.patch("ahriman.web.views.service.upload.NamedTemporaryFile")
|
||||
file_mock = MagicMock()
|
||||
tempfile_mock.return_value.__enter__.return_value = file_mock
|
||||
|
||||
|
@ -30,9 +30,9 @@ async def test_delete(client: TestClient, package_ahriman: Package, package_pyth
|
||||
json={"status": BuildStatusEnum.Success.value, "package": package_python_schedule.view()})
|
||||
|
||||
await client.post(f"/api/v1/packages/{package_ahriman.base}/logs",
|
||||
json={"created": 42.0, "message": "message", "process_id": 42})
|
||||
json={"created": 42.0, "message": "message", "version": "42"})
|
||||
await client.post(f"/api/v1/packages/{package_python_schedule.base}/logs",
|
||||
json={"created": 42.0, "message": "message", "process_id": 42})
|
||||
json={"created": 42.0, "message": "message", "version": "42"})
|
||||
|
||||
response = await client.delete(f"/api/v1/packages/{package_ahriman.base}/logs")
|
||||
assert response.status == 204
|
||||
@ -53,7 +53,7 @@ async def test_get(client: TestClient, package_ahriman: Package) -> None:
|
||||
await client.post(f"/api/v1/packages/{package_ahriman.base}",
|
||||
json={"status": BuildStatusEnum.Success.value, "package": package_ahriman.view()})
|
||||
await client.post(f"/api/v1/packages/{package_ahriman.base}/logs",
|
||||
json={"created": 42.0, "message": "message", "process_id": 42})
|
||||
json={"created": 42.0, "message": "message", "version": "42"})
|
||||
response_schema = pytest.helpers.schema_response(LogsView.get)
|
||||
|
||||
response = await client.get(f"/api/v1/packages/{package_ahriman.base}/logs")
|
||||
@ -83,7 +83,7 @@ async def test_post(client: TestClient, package_ahriman: Package) -> None:
|
||||
json={"status": BuildStatusEnum.Success.value, "package": package_ahriman.view()})
|
||||
request_schema = pytest.helpers.schema_request(LogsView.post)
|
||||
|
||||
payload = {"created": 42.0, "message": "message", "process_id": 42}
|
||||
payload = {"created": 42.0, "message": "message", "version": "42"}
|
||||
assert not request_schema.validate(payload)
|
||||
response = await client.post(f"/api/v1/packages/{package_ahriman.base}/logs", json=payload)
|
||||
assert response.status == 204
|
||||
|
Loading…
Reference in New Issue
Block a user