Testing Guide#
This guide covers how to run tests for Metrics Manager.
Prerequisites#
Service is running:
docker compose up -dOr local setup with uvicorn and Telegraf running
curlor similar HTTP client
Running Tests via Docker#
Build Test Image#
docker compose build
Run All Tests#
docker compose --profile test run --rm metrics-manager-test
Expected output: 179 passed in ~2s
Run with Coverage Report#
docker compose --profile test run --rm metrics-manager-test \
python -m pytest tests/ -v --cov=app --cov-report=term-missing
Running Tests Locally#
Prerequisites#
Python 3.10+ (
python3 --version)uv (fast package manager):
pip install uvTelegraf installed and running on the system
Setup#
Create a virtual environment:
uv venv source .venv/bin/activate # On Windows: .venv\Scripts\activate
Install test dependencies:
uv sync --group test
Configure the environment:
cp .env.example .env
Edit
.envto point to your local Telegraf:TELEGRAF_PORT=9273 TELEGRAF_HTTP_ENDPOINT=http://localhost:8186/write PROMETHEUS_TELEGRAF_ENDPOINT=http://localhost:9273
Start Telegraf on host:
telegraf --config telegraf.conf
Run Tests#
# All tests
pytest
# Verbose output
pytest -v
# With coverage report
pytest --cov=app --cov-report=html
# Run specific test file
pytest tests/test_models.py -v
Test Categories#
Test File |
Description |
|---|---|
|
Pydantic models: Metric, SimpleMetric, MetricsBatch, InfluxDB/OTLP parsing |
|
MetricsStore CRUD, persistence, cleanup, eviction, statistics |
|
REST API endpoints: health, ingestion, queries, Prometheus |
|
Pydantic Settings loading, environment variables overrides, validation |
|
Structured logging setup (JSON and text formats) |
|
FastAPI middleware, lifespan, correlation ID handling |
|
Internal service metrics counters and uptime |
|
IP-based rate limiting middleware |
|
SSE endpoint |
|
NPU bit slicing, register maps, value decoding |
|
|
|
Telegraf configuration mounting and custom-metrics (integration) |
Smoke Tests (Manual Testing)#
After starting the service with docker compose up, verify all endpoints:
Test 1: Simple JSON Metric#
curl -X POST http://localhost:9090/api/v1/metrics/simple \
-H "Content-Type: application/json" \
-d '{"name": "test_metric", "value": 123.45}'
# Verify
curl -s http://localhost:9090/api/v1/metrics/latest | grep -i "test_metric"
curl -s http://localhost:9090/metrics | grep "test_metric"
Test 3: InfluxDB Line Protocol#
curl -X POST http://localhost:9090/api/v1/metrics/influx \
-H "Content-Type: text/plain" \
-d 'influx_test,host=myhost,env=test value=99.9'
# Verify
curl -s http://localhost:9090/api/v1/metrics/latest | grep -i "influx_test"
Test 4: Direct to Telegraf HTTP Listener#
curl -X POST http://localhost:8186/write \
-H "Content-Type: text/plain" \
-d 'telegraf_direct,source=curl temperature=25.5'
# Verify
curl -s http://localhost:9273/metrics | grep "telegraf_direct"
Test 5: OpenTelemetry (OTLP)#
curl -X POST http://localhost:9090/api/v1/metrics/otlp \
-H "Content-Type: application/json" \
-d '{
"resourceMetrics": [{
"resource": {"attributes": [{"key": "service.name", "value": {"stringValue": "test-service"}}]},
"scopeMetrics": [{
"metrics": [{
"name": "otlp_test_metric",
"gauge": {"dataPoints": [{"asDouble": 77.7, "attributes": []}]}
}]
}]
}]
}'
# Verify
curl -s http://localhost:9090/api/v1/metrics/latest | grep -i "otlp_test"
Test 6: SSE Real-time Streaming#
# Terminal 1: Connect to SSE stream
curl -N -H "Accept: text/event-stream" http://localhost:9090/metrics/stream
# Terminal 2: Push a metric
curl -X POST http://localhost:9090/api/v1/metrics/simple \
-H "Content-Type: application/json" \
-d '{"name": "realtime_test", "value": 42}'
# Terminal 1 should show the metric in the next SSE event (~500ms)
# Or open http://localhost:9090/metrics/stream in a browser
Test 7: Full Health Check#
echo "=== Health ===" && curl -s http://localhost:9090/health | jq .
echo "=== Detailed ===" && curl -s http://localhost:9090/api/health | jq .
echo "=== Stats ===" && curl -s http://localhost:9090/api/v1/stats | jq .
echo "=== Telegraf ===" && curl -s http://localhost:9273/metrics | head -20
Expected Test Output#
========================= test session starts ==========================
tests/test_settings.py::... PASSED
tests/test_logging_config.py::... PASSED
tests/test_main.py::... PASSED
tests/test_models.py::... PASSED
tests/test_store.py::... PASSED
tests/test_routes.py::... PASSED
tests/test_metrics.py::... PASSED
tests/test_rate_limit.py::... PASSED
tests/test_sse.py::... PASSED
tests/test_npu_monitor_tool.py::... PASSED
tests/test_npu_reader.py::... PASSED
tests/test_telegraf_integration.py::... SKIPPED (requires Docker)
========================= 179 passed, 1 skipped in 1.70s ==============
Development Setup#
For local development with hot-reload:
# Install dev dependencies
uv sync --group test --group dev
# Run with auto-reload
uvicorn app.main:app --reload --port 9090
# Run linting and formatting
black app/
ruff check app/
Troubleshooting Tests#
Issue |
Solution |
|---|---|
|
Ensure you are in |
|
Telegraf not running. Start it: |
|
Clear cache: |
|
Expected if not in Docker. Other tests still pass |
Supporting Resources#
License#
Copyright (C) 2025-2026 Intel Corporation
SPDX-License-Identifier: Apache-2.0