File size: 5,549 Bytes
43478ec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""Sprint S8.2 โ€” Endpoint Prometheus ``/metrics``.

Vรฉrifie :

1. Dรฉsactivรฉ par dรฉfaut โ†’ 404.
2. Activรฉ via ``PICARONES_METRICS_ENABLED=1`` โ†’ 200 avec format
   Prometheus exposition.
3. Mรฉtriques attendues : ``picarones_app_info``,
   ``picarones_jobs_total{status="..."}``, alias gauges.
4. Tolรฉrance store inaccessible : retourne ``picarones_app_info``
   sans crasher.
"""

from __future__ import annotations

import pytest


def _make_app():
    from fastapi import FastAPI
    from picarones.interfaces.web.routers import system as sys_router

    app = FastAPI()
    app.include_router(sys_router.router)
    return app


# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# 1. Dรฉsactivรฉ par dรฉfaut
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€


class TestMetricsDisabledByDefault:
    def test_404_when_env_not_set(
        self, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        from fastapi.testclient import TestClient

        monkeypatch.delenv("PICARONES_METRICS_ENABLED", raising=False)
        app = _make_app()
        with TestClient(app) as client:
            r = client.get("/metrics")
            assert r.status_code == 404
            assert "PICARONES_METRICS_ENABLED" in r.text


# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# 2. Format Prometheus quand activรฉ
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€


class TestMetricsFormat:
    def test_200_with_prometheus_content_type(
        self, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        from fastapi.testclient import TestClient

        monkeypatch.setenv("PICARONES_METRICS_ENABLED", "1")
        app = _make_app()
        with TestClient(app) as client:
            r = client.get("/metrics")
            assert r.status_code == 200
            ct = r.headers.get("content-type", "")
            assert "text/plain" in ct
            assert "version=0.0.4" in ct

    def test_exposes_app_info(
        self, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        from fastapi.testclient import TestClient

        monkeypatch.setenv("PICARONES_METRICS_ENABLED", "1")
        app = _make_app()
        with TestClient(app) as client:
            r = client.get("/metrics")
            text = r.text
            assert "# TYPE picarones_app_info gauge" in text
            assert 'picarones_app_info{version=' in text
            assert text.rstrip().endswith("1") or "} 1" in text

    def test_exposes_jobs_total_per_status(
        self, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        from fastapi.testclient import TestClient

        monkeypatch.setenv("PICARONES_METRICS_ENABLED", "1")
        app = _make_app()
        with TestClient(app) as client:
            r = client.get("/metrics")
            text = r.text
            # Chaque statut connu apparaรฎt, mรชme ร  0
            for status in ("pending", "running", "complete", "error",
                           "cancelled", "interrupted"):
                assert f'status="{status}"' in text, (
                    f"Statut ``{status}`` absent du payload"
                )

    def test_exposes_alias_gauges(
        self, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        from fastapi.testclient import TestClient

        monkeypatch.setenv("PICARONES_METRICS_ENABLED", "1")
        app = _make_app()
        with TestClient(app) as client:
            r = client.get("/metrics")
            text = r.text
            assert "picarones_jobs_pending" in text
            assert "picarones_jobs_running" in text


# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# 3. Activation insensible casse / yes / true
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€


class TestEnvVarParsing:
    @pytest.mark.parametrize("value", ["1", "true", "yes"])
    def test_truthy_values_enable(
        self, monkeypatch: pytest.MonkeyPatch, value: str,
    ) -> None:
        from fastapi.testclient import TestClient

        monkeypatch.setenv("PICARONES_METRICS_ENABLED", value)
        app = _make_app()
        with TestClient(app) as client:
            r = client.get("/metrics")
            assert r.status_code == 200

    @pytest.mark.parametrize("value", ["0", "false", "no", "", "off"])
    def test_falsy_values_keep_disabled(
        self, monkeypatch: pytest.MonkeyPatch, value: str,
    ) -> None:
        from fastapi.testclient import TestClient

        monkeypatch.setenv("PICARONES_METRICS_ENABLED", value)
        app = _make_app()
        with TestClient(app) as client:
            r = client.get("/metrics")
            assert r.status_code == 404