mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 15:27:17 +00:00
restore behavior of the httploghandler
This commit is contained in:
parent
c83936d4d9
commit
7d7fd691b4
@ -20,6 +20,14 @@ ahriman.core.configuration.schema module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.configuration.shell\_interpolator module
|
||||
-----------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.configuration.shell_interpolator
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.configuration.validator module
|
||||
-------------------------------------------
|
||||
|
||||
|
@ -84,6 +84,14 @@ ahriman.core.database.migrations.m009\_local\_source module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.database.migrations.m010\_version\_based\_logs\_removal module
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.database.migrations.m010_version_based_logs_removal
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
|
@ -58,11 +58,11 @@ _shtab_ahriman_config_validate_option_strings=('-h' '--help' '-e' '--exit-code')
|
||||
_shtab_ahriman_repo_config_validate_option_strings=('-h' '--help' '-e' '--exit-code')
|
||||
_shtab_ahriman_service_key_import_option_strings=('-h' '--help' '--key-server')
|
||||
_shtab_ahriman_key_import_option_strings=('-h' '--help' '--key-server')
|
||||
_shtab_ahriman_service_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_init_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_repo_init_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_repo_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_service_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--server' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_init_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--server' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_repo_init_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--server' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_repo_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--server' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--generate-salt' '--no-generate-salt' '--makeflags-jobs' '--no-makeflags-jobs' '--mirror' '--multilib' '--no-multilib' '--packager' '--repository' '--server' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
|
||||
_shtab_ahriman_service_shell_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_shell_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_user_add_option_strings=('-h' '--help' '--key' '--packager' '-p' '--password' '-r' '--role')
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH AHRIMAN "1" "2023\-08\-13" "ahriman" "Generated Python Manual"
|
||||
.TH AHRIMAN "1" "2023\-08\-19" "ahriman" "Generated Python Manual"
|
||||
.SH NAME
|
||||
ahriman
|
||||
.SH SYNOPSIS
|
||||
@ -689,7 +689,7 @@ key server for key import
|
||||
usage: ahriman service\-setup [\-h] [\-\-build\-as\-user BUILD_AS_USER] [\-\-build\-command BUILD_COMMAND]
|
||||
[\-\-from\-configuration FROM_CONFIGURATION] [\-\-generate\-salt | \-\-no\-generate\-salt]
|
||||
[\-\-makeflags\-jobs | \-\-no\-makeflags\-jobs] [\-\-mirror MIRROR] [\-\-multilib | \-\-no\-multilib]
|
||||
\-\-packager PACKAGER \-\-repository REPOSITORY [\-\-sign\-key SIGN_KEY]
|
||||
\-\-packager PACKAGER \-\-repository REPOSITORY [\-\-server SERVER] [\-\-sign\-key SIGN_KEY]
|
||||
[\-\-sign\-target {disabled,packages,repository}] [\-\-web\-port WEB_PORT]
|
||||
[\-\-web\-unix\-socket WEB_UNIX_SOCKET]
|
||||
|
||||
@ -732,6 +732,10 @@ packager name and email
|
||||
\fB\-\-repository\fR \fI\,REPOSITORY\/\fR
|
||||
repository name
|
||||
|
||||
.TP
|
||||
\fB\-\-server\fR \fI\,SERVER\/\fR
|
||||
server to be used for devtools. If none set, local files will be used
|
||||
|
||||
.TP
|
||||
\fB\-\-sign\-key\fR \fI\,SIGN_KEY\/\fR
|
||||
sign key id
|
||||
|
@ -177,6 +177,7 @@ _shtab_ahriman_init_options=(
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--server[server to be used for devtools. If none set, local files will be used (default\: None)]:server:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
@ -347,6 +348,7 @@ _shtab_ahriman_repo_init_options=(
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--server[server to be used for devtools. If none set, local files will be used (default\: None)]:server:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
@ -390,6 +392,7 @@ _shtab_ahriman_repo_setup_options=(
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--server[server to be used for devtools. If none set, local files will be used (default\: None)]:server:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
@ -482,6 +485,7 @@ _shtab_ahriman_service_setup_options=(
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--server[server to be used for devtools. If none set, local files will be used (default\: None)]:server:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
@ -504,6 +508,7 @@ _shtab_ahriman_setup_options=(
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--server[server to be used for devtools. If none set, local files will be used (default\: None)]:server:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
|
@ -66,9 +66,9 @@ class LogsOperations(Operations):
|
||||
connection.execute(
|
||||
"""
|
||||
insert into logs
|
||||
(package_base, created, version, record)
|
||||
(package_base, version, created, record)
|
||||
values
|
||||
(:package_base, :created, :version, :record)
|
||||
(:package_base, :version, :created, :record)
|
||||
""",
|
||||
{
|
||||
"package_base": log_record_id.package_base,
|
||||
|
@ -31,15 +31,17 @@ class HttpLogHandler(logging.Handler):
|
||||
|
||||
Attributes:
|
||||
reporter(Client): build status reporter instance
|
||||
suppress_errors(bool): suppress logging errors (e.g. if no web server available)
|
||||
"""
|
||||
|
||||
def __init__(self, configuration: Configuration, *, report: bool) -> None:
|
||||
def __init__(self, configuration: Configuration, *, report: bool, suppress_errors: bool) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
report(bool): force enable or disable reporting
|
||||
suppress_errors(bool): suppress logging errors (e.g. if no web server available)
|
||||
"""
|
||||
# we don't really care about those parameters because they will be handled by the reporter
|
||||
logging.Handler.__init__(self)
|
||||
@ -47,6 +49,7 @@ class HttpLogHandler(logging.Handler):
|
||||
# client has to be imported here because of circular imports
|
||||
from ahriman.core.status.client import Client
|
||||
self.reporter = Client.load(configuration, report=report)
|
||||
self.suppress_errors = suppress_errors
|
||||
|
||||
@classmethod
|
||||
def load(cls, configuration: Configuration, *, report: bool) -> Self:
|
||||
@ -65,7 +68,8 @@ class HttpLogHandler(logging.Handler):
|
||||
if (handler := next((handler for handler in root.handlers if isinstance(handler, cls)), None)) is not None:
|
||||
return handler # there is already registered instance
|
||||
|
||||
handler = cls(configuration, report=report)
|
||||
suppress_errors = configuration.getboolean("settings", "suppress_http_log_errors", fallback=False)
|
||||
handler = cls(configuration, report=report, suppress_errors=suppress_errors)
|
||||
root.addHandler(handler)
|
||||
|
||||
return handler
|
||||
@ -81,4 +85,9 @@ class HttpLogHandler(logging.Handler):
|
||||
if log_record_id is None:
|
||||
return # in case if no package base supplied we need just skip log message
|
||||
|
||||
try:
|
||||
self.reporter.package_logs(log_record_id, record)
|
||||
except Exception:
|
||||
if self.suppress_errors:
|
||||
return
|
||||
self.handleError(record)
|
||||
|
@ -17,6 +17,8 @@
|
||||
# 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 requests
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.report.report import Report
|
||||
from ahriman.core.status.web_client import WebClient
|
||||
@ -77,43 +79,41 @@ class RemoteCall(Report):
|
||||
Returns:
|
||||
bool: True in case if remote process is alive and False otherwise
|
||||
"""
|
||||
try:
|
||||
response = self.client.make_request("GET", f"/api/v1/service/process/{process_id}")
|
||||
if response is None:
|
||||
except requests.RequestException as e:
|
||||
if e.response is not None and e.response.status_code == 404:
|
||||
return False
|
||||
raise
|
||||
|
||||
response_json = response.json()
|
||||
is_alive: bool = response_json["is_alive"]
|
||||
|
||||
return is_alive
|
||||
|
||||
def remote_update(self) -> str | None:
|
||||
def remote_update(self) -> str:
|
||||
"""
|
||||
call remote server for update
|
||||
|
||||
Returns:
|
||||
str | None: remote process id on success and ``None`` otherwise
|
||||
str: remote process id
|
||||
"""
|
||||
response = self.client.make_request("POST", "/api/v1/service/update", json={
|
||||
"aur": self.update_aur,
|
||||
"local": self.update_local,
|
||||
"manual": self.update_manual,
|
||||
})
|
||||
if response is None:
|
||||
return None # request terminated with error
|
||||
|
||||
response_json = response.json()
|
||||
|
||||
process_id: str = response_json["process_id"]
|
||||
return process_id
|
||||
|
||||
def remote_wait(self, process_id: str | None) -> None:
|
||||
def remote_wait(self, process_id: str) -> None:
|
||||
"""
|
||||
wait for remote process termination
|
||||
|
||||
Args:
|
||||
process_id(str | None): remote process id
|
||||
process_id(str): remote process id
|
||||
"""
|
||||
if process_id is None:
|
||||
return # nothing to track
|
||||
|
||||
waiter = Waiter(self.wait_timeout)
|
||||
waiter.wait(self.is_process_alive, process_id)
|
||||
|
@ -21,7 +21,6 @@ import contextlib
|
||||
import logging
|
||||
import requests
|
||||
|
||||
from collections.abc import Generator
|
||||
from functools import cached_property
|
||||
from typing import Any, IO, Literal
|
||||
from urllib.parse import quote_plus as urlencode
|
||||
@ -129,32 +128,6 @@ class WebClient(Client, LazyLogging):
|
||||
address = f"http://{host}:{port}"
|
||||
return address, False
|
||||
|
||||
@contextlib.contextmanager
|
||||
def __get_session(self, session: requests.Session | None = None) -> Generator[requests.Session, None, None]:
|
||||
"""
|
||||
execute request and handle exceptions
|
||||
|
||||
Args:
|
||||
session(requests.Session | None, optional): session to be used or stored instance property otherwise
|
||||
(Default value = None)
|
||||
|
||||
Yields:
|
||||
requests.Session: session for requests
|
||||
"""
|
||||
try:
|
||||
if session is not None:
|
||||
yield session # use session from arguments
|
||||
else:
|
||||
yield self.session # use instance generated session
|
||||
except requests.RequestException as e:
|
||||
if self.suppress_errors:
|
||||
return
|
||||
self.logger.exception("could not perform http request: %s", exception_response_text(e))
|
||||
except Exception:
|
||||
if self.suppress_errors:
|
||||
return
|
||||
self.logger.exception("could not perform http request")
|
||||
|
||||
def _create_session(self, *, use_unix_socket: bool) -> requests.Session:
|
||||
"""
|
||||
generate new request session
|
||||
@ -191,13 +164,15 @@ class WebClient(Client, LazyLogging):
|
||||
"username": self.user.username,
|
||||
"password": self.user.password
|
||||
}
|
||||
with contextlib.suppress(Exception):
|
||||
self.make_request("POST", self._login_url, json=payload, session=session)
|
||||
|
||||
def make_request(self, method: Literal["DELETE", "GET", "POST"], url: str, *,
|
||||
params: list[tuple[str, str]] | None = None,
|
||||
json: dict[str, Any] | None = None,
|
||||
files: dict[str, MultipartType] | None = None,
|
||||
session: requests.Session | None = None) -> requests.Response | None:
|
||||
session: requests.Session | None = None,
|
||||
suppress_errors: bool | None = None) -> requests.Response:
|
||||
"""
|
||||
perform request with specified parameters
|
||||
|
||||
@ -208,17 +183,30 @@ class WebClient(Client, LazyLogging):
|
||||
json(dict[str, Any] | None, optional): request json parameters (Default value = None)
|
||||
files(dict[str, MultipartType] | None, optional): multipart upload (Default value = None)
|
||||
session(requests.Session | None, optional): session object if any (Default value = None)
|
||||
suppress_errors(bool | None, optional): suppress logging errors (e.g. if no web server available). If none
|
||||
set, the instance-wide value will be used (Default value = None)
|
||||
|
||||
Returns:
|
||||
requests.Response | None: response object or None in case of errors
|
||||
requests.Response: response object
|
||||
"""
|
||||
with self.__get_session(session) as _session:
|
||||
response = _session.request(method, f"{self.address}{url}", params=params, json=json, files=files)
|
||||
# defaults
|
||||
if suppress_errors is None:
|
||||
suppress_errors = self.suppress_errors
|
||||
if session is None:
|
||||
session = self.session
|
||||
|
||||
try:
|
||||
response = session.request(method, f"{self.address}{url}", params=params, json=json, files=files)
|
||||
response.raise_for_status()
|
||||
return response
|
||||
|
||||
# noinspection PyUnreachableCode
|
||||
return None
|
||||
except requests.RequestException as e:
|
||||
if not suppress_errors:
|
||||
self.logger.exception("could not perform http request: %s", exception_response_text(e))
|
||||
raise
|
||||
except Exception:
|
||||
if not suppress_errors:
|
||||
self.logger.exception("could not perform http request")
|
||||
raise
|
||||
|
||||
def package_add(self, package: Package, status: BuildStatusEnum) -> None:
|
||||
"""
|
||||
@ -232,6 +220,7 @@ class WebClient(Client, LazyLogging):
|
||||
"status": status.value,
|
||||
"package": package.view()
|
||||
}
|
||||
with contextlib.suppress(Exception):
|
||||
self.make_request("POST", self._package_url(package.base), json=payload)
|
||||
|
||||
def package_get(self, package_base: str | None) -> list[tuple[Package, BuildStatus]]:
|
||||
@ -244,16 +233,17 @@ class WebClient(Client, LazyLogging):
|
||||
Returns:
|
||||
list[tuple[Package, BuildStatus]]: list of current package description and status if it has been found
|
||||
"""
|
||||
with contextlib.suppress(Exception):
|
||||
response = self.make_request("GET", self._package_url(package_base or ""))
|
||||
if response is None:
|
||||
return []
|
||||
|
||||
response_json = response.json()
|
||||
|
||||
return [
|
||||
(Package.from_json(package["package"]), BuildStatus.from_json(package["status"]))
|
||||
for package in response_json
|
||||
]
|
||||
|
||||
return []
|
||||
|
||||
def package_logs(self, log_record_id: LogRecordId, record: logging.LogRecord) -> None:
|
||||
"""
|
||||
post log record
|
||||
@ -267,7 +257,11 @@ class WebClient(Client, LazyLogging):
|
||||
"message": record.getMessage(),
|
||||
"version": log_record_id.version,
|
||||
}
|
||||
self.make_request("POST", self._logs_url(log_record_id.package_base), json=payload)
|
||||
|
||||
# this is special case, because we would like to do not suppress exception here
|
||||
# in case of exception raised it will be handled by upstream HttpLogHandler
|
||||
# In the other hand, we force to suppress all http logs here to avoid cyclic reporting
|
||||
self.make_request("POST", self._logs_url(log_record_id.package_base), json=payload, suppress_errors=True)
|
||||
|
||||
def package_remove(self, package_base: str) -> None:
|
||||
"""
|
||||
@ -276,6 +270,7 @@ class WebClient(Client, LazyLogging):
|
||||
Args:
|
||||
package_base(str): basename to remove
|
||||
"""
|
||||
with contextlib.suppress(Exception):
|
||||
self.make_request("DELETE", self._package_url(package_base))
|
||||
|
||||
def package_update(self, package_base: str, status: BuildStatusEnum) -> None:
|
||||
@ -287,6 +282,7 @@ class WebClient(Client, LazyLogging):
|
||||
status(BuildStatusEnum): current package build status
|
||||
"""
|
||||
payload = {"status": status.value}
|
||||
with contextlib.suppress(Exception):
|
||||
self.make_request("POST", self._package_url(package_base), json=payload)
|
||||
|
||||
def status_get(self) -> InternalStatus:
|
||||
@ -296,13 +292,14 @@ class WebClient(Client, LazyLogging):
|
||||
Returns:
|
||||
InternalStatus: current internal (web) service status
|
||||
"""
|
||||
with contextlib.suppress(Exception):
|
||||
response = self.make_request("GET", self._status_url)
|
||||
if response is None:
|
||||
return InternalStatus(status=BuildStatus())
|
||||
|
||||
response_json = response.json()
|
||||
|
||||
return InternalStatus.from_json(response_json)
|
||||
|
||||
return InternalStatus(status=BuildStatus())
|
||||
|
||||
def status_update(self, status: BuildStatusEnum) -> None:
|
||||
"""
|
||||
update ahriman status itself
|
||||
@ -311,4 +308,5 @@ class WebClient(Client, LazyLogging):
|
||||
status(BuildStatusEnum): current ahriman status
|
||||
"""
|
||||
payload = {"status": status.value}
|
||||
with contextlib.suppress(Exception):
|
||||
self.make_request("POST", self._status_url, json=payload)
|
||||
|
@ -43,18 +43,46 @@ def test_emit(configuration: Configuration, log_record: logging.LogRecord, packa
|
||||
log_record_id = log_record.package_id = LogRecordId(package_ahriman.base, package_ahriman.version)
|
||||
log_mock = mocker.patch("ahriman.core.status.client.Client.package_logs")
|
||||
|
||||
handler = HttpLogHandler(configuration, report=False)
|
||||
handler = HttpLogHandler(configuration, report=False, suppress_errors=False)
|
||||
|
||||
handler.emit(log_record)
|
||||
log_mock.assert_called_once_with(log_record_id, log_record)
|
||||
|
||||
|
||||
def test_emit_failed(configuration: Configuration, log_record: logging.LogRecord, package_ahriman: Package,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must call handle error on exception
|
||||
"""
|
||||
log_record.package_id = LogRecordId(package_ahriman.base, package_ahriman.version)
|
||||
mocker.patch("ahriman.core.status.client.Client.package_logs", side_effect=Exception())
|
||||
handle_error_mock = mocker.patch("logging.Handler.handleError")
|
||||
handler = HttpLogHandler(configuration, report=False, suppress_errors=False)
|
||||
|
||||
handler.emit(log_record)
|
||||
handle_error_mock.assert_called_once_with(log_record)
|
||||
|
||||
|
||||
def test_emit_suppress_failed(configuration: Configuration, log_record: logging.LogRecord, package_ahriman: Package,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must not call handle error on exception if suppress flag is set
|
||||
"""
|
||||
log_record.package_id = LogRecordId(package_ahriman.base, package_ahriman.version)
|
||||
mocker.patch("ahriman.core.status.client.Client.package_logs", side_effect=Exception())
|
||||
handle_error_mock = mocker.patch("logging.Handler.handleError")
|
||||
handler = HttpLogHandler(configuration, report=False, suppress_errors=True)
|
||||
|
||||
handler.emit(log_record)
|
||||
handle_error_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_emit_skip(configuration: Configuration, log_record: logging.LogRecord, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must skip log record posting if no package base set
|
||||
"""
|
||||
log_mock = mocker.patch("ahriman.core.status.client.Client.package_logs")
|
||||
handler = HttpLogHandler(configuration, report=False)
|
||||
handler = HttpLogHandler(configuration, report=False, suppress_errors=False)
|
||||
|
||||
handler.emit(log_record)
|
||||
log_mock.assert_not_called()
|
||||
|
@ -37,10 +37,37 @@ def test_is_process_alive_unknown(remote_call: RemoteCall, mocker: MockerFixture
|
||||
"""
|
||||
must correctly define if process is unknown
|
||||
"""
|
||||
mocker.patch("ahriman.core.status.web_client.WebClient.make_request", return_value=None)
|
||||
response = requests.Response()
|
||||
response.status_code = 404
|
||||
mocker.patch("ahriman.core.status.web_client.WebClient.make_request",
|
||||
side_effect=requests.RequestException(response=response))
|
||||
|
||||
assert not remote_call.is_process_alive("id")
|
||||
|
||||
|
||||
def test_is_process_alive_error(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must reraise exception on process request
|
||||
"""
|
||||
mocker.patch("ahriman.core.status.web_client.WebClient.make_request", side_effect=Exception)
|
||||
|
||||
with pytest.raises(Exception):
|
||||
remote_call.is_process_alive("id")
|
||||
|
||||
|
||||
def test_is_process_alive_http_error(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must reraise http exception on process request
|
||||
"""
|
||||
response = requests.Response()
|
||||
response.status_code = 500
|
||||
mocker.patch("ahriman.core.status.web_client.WebClient.make_request",
|
||||
side_effect=requests.RequestException(response=response))
|
||||
|
||||
with pytest.raises(requests.RequestException):
|
||||
remote_call.is_process_alive("id")
|
||||
|
||||
|
||||
def test_remote_update(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must call remote server for update process
|
||||
@ -59,14 +86,6 @@ def test_remote_update(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
||||
})
|
||||
|
||||
|
||||
def test_remote_update_failed(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return empty process id in case of errors
|
||||
"""
|
||||
mocker.patch("ahriman.core.status.web_client.WebClient.make_request", return_value=None)
|
||||
assert remote_call.generate([], Result()) is None
|
||||
|
||||
|
||||
def test_remote_wait(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must wait for remote process to success
|
||||
@ -74,12 +93,3 @@ def test_remote_wait(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
||||
wait_mock = mocker.patch("ahriman.models.waiter.Waiter.wait")
|
||||
remote_call.remote_wait("id")
|
||||
wait_mock.assert_called_once_with(pytest.helpers.anyvar(int), "id")
|
||||
|
||||
|
||||
def test_remote_wait_skip(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must skip wait if process id is unknown
|
||||
"""
|
||||
wait_mock = mocker.patch("ahriman.models.waiter.Waiter.wait")
|
||||
remote_call.remote_wait(None)
|
||||
wait_mock.assert_not_called()
|
||||
|
@ -163,7 +163,8 @@ def test_make_request_failed(web_client: WebClient, mocker: MockerFixture) -> No
|
||||
must make HTTP request
|
||||
"""
|
||||
mocker.patch("requests.Session.request", side_effect=Exception())
|
||||
assert web_client.make_request("GET", "url") is None
|
||||
with pytest.raises(Exception):
|
||||
web_client.make_request("GET", "url")
|
||||
|
||||
|
||||
def test_package_add(web_client: WebClient, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
@ -296,6 +297,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
|
||||
with pytest.raises(Exception):
|
||||
web_client.package_logs(LogRecordId(package_ahriman.base, package_ahriman.version), log_record)
|
||||
|
||||
|
||||
@ -306,6 +308,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
|
||||
with pytest.raises(Exception):
|
||||
web_client.package_logs(LogRecordId(package_ahriman.base, package_ahriman.version), log_record)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user