Use dev-setup.sh to create a local development environment. This sets up a .dev_venv virtual environment in the root of the repo and installs healthagent in editable mode with dev and test dependencies.
./dev-setup.sh
This will:
.dev_venv/pip install -e ".[dev]")build, pytest, pytest-asyncioActivate the environment:
source .dev_venv/bin/activate
To recreate the virtual environment from scratch:
./dev-setup.sh --recreate
You can also override the Python binary:
PYTHON=/usr/bin/python3.12 ./dev-setup.sh
package.sh builds the healthagent source distribution and places it in the blobs/ directory. It supports two modes.
./package.sh
.dev_venv/ virtual environment (creates one if it doesn’t exist)./package.sh --prod
.prod_venv/ virtual environment every time (deletes any existing one). Does not touch .dev_venv.Only use production mode for releases.
Both modes:
project.inipython -m build.tar.gz artifact into blobs/project.ini are presentBuild logs are written to .build.log. If the build fails, check this file for details.
Requires the dev environment to be active:
source .dev_venv/bin/activate
Unit tests live in tests/ and can run on any development machine without GPUs or root access.
# Run all unit tests
pytest tests/
# Run a specific test file
pytest tests/test_config.py
# Run with verbose output
pytest tests/ -v
# Run a specific test by name
pytest tests/test_healthmodule.py -k "test_execute"
Available test modules:
| Test File | Covers |
|———–|——–|
| test_config.py | Config loading, deep merge, Pydantic validation |
| test_healthmodule.py | Healthcheck decorator, check registry, execute logic |
| test_reporter.py | HealthReport, HealthStatus, CLI exclude behavior |
| test_async_systemd.py | Systemd monitor state transitions, D-Bus callbacks |
| test_network.py | Network interface checks, threshold evaluation |
| test_scheduler.py | Task scheduling, periodic tasks, locks |
| test_util.py | Evaluate functions, TimeSeries, read_kernel_attrs |
Integration tests live in integration/ and require a running healthagent instance, root access, and (for GPU tests) NVIDIA GPUs with DCGM.
Systemd monitor integration test:
Tests config-driven service registration by creating a dummy systemd service and verifying healthagent detects its failure and recovery.
# Full automated run (requires root)
sudo python3 integration/test_systemd_monitor.py
# Or step-by-step:
sudo python3 integration/test_systemd_monitor.py --initialize
sudo systemctl restart healthagent
sudo python3 integration/test_systemd_monitor.py --run
sudo python3 integration/test_systemd_monitor.py --teardown
DCGM field injection test:
Injects DCGM field values to simulate GPU errors. Requires nvidia-dcgm.service running and healthagent started with DCGM_TEST_MODE=true. DCGM Test Mode is defined in detail below.
# Run all injection tests on GPU 0, keep injecting for 2 minutes
python3 integration/test_inject.py --test all --duration 120
# Inject high temperature on GPU 1 for 60 seconds
python3 integration/test_inject.py --gpu 1 --test temp --duration 60
# Clear injected values (inject healthy values)
python3 integration/test_inject.py --test clear
Healthagent relies on DCGM bindings for GPU checks. The VS Code workspace settings file adds import paths for these bindings. To get IntelliSense working:
${workspaceFolder}/.bindings/dcgm-4.5.0/DCGM supports two modes of operation — Standalone mode and Embedded mode.
Healthagent by default loads DCGM in embedded mode, loading the DCGM library directly as a shared library. This avoids reliance on the nvidia-dcgm service (nv-hostengine) in production, since a service crash would disable GPU tests.
However, DCGM’s error injection framework only works in standalone mode because injected values are stored in nv-hostengine’s cache. To test healthagent behavior by simulating DCGM errors, use DCGM_TEST_MODE.
Set the environment variable in the healthagent systemd unit file (/etc/systemd/system/healthagent.service):
[Service]
Environment="DCGM_TEST_MODE=True"
Then reload and restart:
systemctl daemon-reload
systemctl restart healthagent
With DCGM_TEST_MODE enabled and nvidia-dcgm.service running, inject values from another terminal using dcgmi test --inject.
For example, injecting a XID 63 error on GPU 0:
dcgmi test --inject --gpuid 0 -f 230 -v 63
# Successfully injected field info.
Injected values expire from the DCGM cache quickly. Use the integration/test_inject.py script with --duration to re-inject continuously:
# Inject high temperature on GPU 0 for 2 minutes
python3 integration/test_inject.py --gpu 0 --test temp --duration 120
# Clear all injected values (restore healthy state)
python3 integration/test_inject.py --test clear
References: