mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-06-28 14:51:43 +00:00
feat: add support of openmetrics (#144)
* feat: add openmetrics support & endpoint * add support of named resources * update docstrings * generate docs * add another test for http api
This commit is contained in:
59
tests/ahriman/web/middlewares/test_metrics_handler.py
Normal file
59
tests/ahriman/web/middlewares/test_metrics_handler.py
Normal file
@ -0,0 +1,59 @@
|
||||
import importlib
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
from aiohttp.web import HTTPNotFound
|
||||
from pytest_mock import MockerFixture
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import ahriman.web.middlewares.metrics_handler as metrics_handler
|
||||
|
||||
|
||||
async def test_metrics(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return metrics methods if library is available
|
||||
"""
|
||||
metrics_mock = AsyncMock()
|
||||
mocker.patch.object(metrics_handler, "aiohttp_openmetrics", metrics_mock)
|
||||
|
||||
await metrics_handler.metrics(42)
|
||||
metrics_mock.metrics.assert_called_once_with(42)
|
||||
|
||||
|
||||
async def test_metrics_dummy(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must raise HTTPNotFound if no module found
|
||||
"""
|
||||
mocker.patch.object(metrics_handler, "aiohttp_openmetrics", None)
|
||||
with pytest.raises(HTTPNotFound):
|
||||
await metrics_handler.metrics(None)
|
||||
|
||||
|
||||
async def test_metrics_handler() -> None:
|
||||
"""
|
||||
must return metrics handler if library is available
|
||||
"""
|
||||
assert metrics_handler.metrics_handler() == metrics_handler.aiohttp_openmetrics.metrics_middleware
|
||||
|
||||
|
||||
async def test_metrics_handler_dummy(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return dummy handler if no module found
|
||||
"""
|
||||
mocker.patch.object(metrics_handler, "aiohttp_openmetrics", None)
|
||||
handler = metrics_handler.metrics_handler()
|
||||
|
||||
async def handle(result: int) -> int:
|
||||
return result
|
||||
|
||||
assert await handler(42, handle) == 42
|
||||
|
||||
|
||||
def test_import_openmetrics_missing(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must correctly process missing module
|
||||
"""
|
||||
mocker.patch.dict(sys.modules, {"aiohttp_openmetrics": None})
|
||||
importlib.reload(metrics_handler)
|
||||
|
||||
assert metrics_handler.aiohttp_openmetrics is None
|
1
tests/ahriman/web/schemas/test_any_schema.py
Normal file
1
tests/ahriman/web/schemas/test_any_schema.py
Normal file
@ -0,0 +1 @@
|
||||
# schema testing goes in view class tests
|
@ -3,7 +3,7 @@ from pathlib import Path
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.utils import walk
|
||||
from ahriman.web.routes import _dynamic_routes, setup_routes
|
||||
from ahriman.web.routes import _dynamic_routes, _identifier, setup_routes
|
||||
|
||||
|
||||
def test_dynamic_routes(resource_path_root: Path, configuration: Configuration) -> None:
|
||||
@ -22,9 +22,19 @@ def test_dynamic_routes(resource_path_root: Path, configuration: Configuration)
|
||||
assert len(set(routes.values())) == len(expected_views)
|
||||
|
||||
|
||||
def test_identifier() -> None:
|
||||
"""
|
||||
must correctly extract route identifiers
|
||||
"""
|
||||
assert _identifier("/") == "_"
|
||||
assert _identifier("/api/v1/status") == "_api_v1_status"
|
||||
assert _identifier("/api/v1/packages/{package}") == "_api_v1_packages_:package"
|
||||
|
||||
|
||||
def test_setup_routes(application: Application, configuration: Configuration) -> None:
|
||||
"""
|
||||
must generate non-empty list of routes
|
||||
"""
|
||||
application.router._named_resources = {}
|
||||
setup_routes(application, configuration)
|
||||
assert application.router.routes()
|
||||
|
@ -0,0 +1,50 @@
|
||||
import pytest
|
||||
|
||||
from aiohttp.test_utils import TestClient
|
||||
from aiohttp.web import Response
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
import ahriman.web.middlewares.metrics_handler as metrics_handler
|
||||
|
||||
from ahriman.models.user_access import UserAccess
|
||||
from ahriman.web.views.v1.status.metrics import MetricsView
|
||||
|
||||
|
||||
async def test_get_permission() -> None:
|
||||
"""
|
||||
must return correct permission for the request
|
||||
"""
|
||||
for method in ("GET",):
|
||||
request = pytest.helpers.request("", "", method)
|
||||
assert await MetricsView.get_permission(request) == UserAccess.Unauthorized
|
||||
|
||||
|
||||
def test_routes() -> None:
|
||||
"""
|
||||
must return correct routes
|
||||
"""
|
||||
assert MetricsView.ROUTES == ["/api/v1/metrics"]
|
||||
|
||||
|
||||
async def test_get(client: TestClient, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return service metrics
|
||||
"""
|
||||
metrics_mock = mocker.patch("ahriman.web.views.v1.status.metrics.metrics", return_value=Response())
|
||||
|
||||
response = await client.get("/api/v1/metrics")
|
||||
assert response.ok
|
||||
# there is no response validation here, because it is free text, so we check call instead
|
||||
metrics_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
async def test_get_not_found(client: TestClient, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return 404 error if no module found
|
||||
"""
|
||||
mocker.patch.object(metrics_handler, "aiohttp_openmetrics", None)
|
||||
response_schema = pytest.helpers.schema_response(MetricsView.get, code=404)
|
||||
|
||||
response = await client.get("/api/v1/metrics")
|
||||
assert response.status == 404
|
||||
assert not response_schema.validate(await response.json())
|
Reference in New Issue
Block a user