test_monitoring.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import asyncio
  2. import httpx
  3. import pytest
  4. from prometheus_client.parser import text_string_to_metric_families
  5. from test_after_sales import scenario # noqa: F401
  6. from zhifu.core.telemetry import heartbeat
  7. from zhifu.monitoring.api import app
  8. pytestmark = pytest.mark.integration
  9. def samples(payload):
  10. return [
  11. sample for family in text_string_to_metric_families(payload) for sample in family.samples
  12. ]
  13. async def test_http_metric_templates_exclude_identity(scenario): # noqa: F811
  14. for _ in range(3):
  15. response = await scenario["call"]("GET", f"/openapi/v1/orders?store_id={scenario['store']}")
  16. assert response.status_code == 200
  17. response = await scenario["client"].get("/metrics")
  18. assert response.status_code == 200
  19. counters = [
  20. sample
  21. for sample in samples(response.text)
  22. if sample.name == "http_requests_total"
  23. and sample.labels.get("handler") == "/openapi/v1/orders"
  24. ]
  25. assert len(counters) == 1 and counters[0].value == 3
  26. assert str(scenario["tenant"]) not in response.text
  27. assert str(scenario["store"]) not in response.text
  28. assert scenario["headers"]["customer"]["Authorization"] not in response.text
  29. @pytest.mark.parametrize("role", ["agent", "channel-delivery"])
  30. async def test_heartbeat_and_real_database_metrics(scenario, role): # noqa: F811
  31. async with app.router.lifespan_context(app):
  32. async with httpx.AsyncClient(
  33. transport=httpx.ASGITransport(app=app), base_url="http://monitor"
  34. ) as client:
  35. initial = await client.get("/metrics")
  36. assert initial.status_code == 200
  37. before = next(
  38. sample.value for sample in samples(initial.text)
  39. if sample.name == "zhifu_workers_alive" and sample.labels == {"role": role}
  40. )
  41. async with heartbeat(role):
  42. response = await client.get("/metrics")
  43. assert response.status_code == 200, response.text
  44. values = samples(response.text)
  45. live = [
  46. sample.value
  47. for sample in values
  48. if sample.name == "zhifu_workers_alive" and sample.labels == {"role": role}
  49. ]
  50. assert live == [before + 1]
  51. assert any(
  52. sample.name == "zhifu_pending_jobs"
  53. and sample.labels == {"kind": "outbox"}
  54. and sample.value > 0
  55. for sample in values
  56. )
  57. await asyncio.sleep(0)
  58. response = await client.get("/metrics")
  59. values = samples(response.text)
  60. assert any(
  61. sample.name == "zhifu_workers_alive"
  62. and sample.labels == {"role": role}
  63. and sample.value == before
  64. for sample in values
  65. )