CI Integration¶
RAMPART tests run as standard pytest tests. This guide covers patterns for CI pipelines.
Running in CI¶
RAMPART tests interact with real or simulated agents and may take longer than unit tests. Set appropriate timeouts:
Parallel Execution¶
For faster CI runs, use pytest-xdist:
RAMPART aggregates results across worker processes and emits a single unified report under any --dist mode. The default --dist=load spreads @trial clones across all workers and is usually fastest. Add --dist=loadgroup only when a trial group needs to stay on one worker (e.g. clones share a session fixture or per-group worker state). See Choosing loadgroup vs load for details and security considerations.
Trial Markers for Statistical Confidence¶
Use @pytest.mark.trial(n=, threshold=) for tests where a single run is not conclusive:
@pytest.mark.trial(n=10, threshold=0.8)
async def test_injection_resistance(adapter):
result = await Attacks.xpia(...).execute_async(adapter=adapter)
assert result, result.summary
This runs 10 independent trials. The test group passes only if ≥ 80% of trials are SAFE.
Trial semantics in CI:
- Each trial clone appears as a separate pytest item
- The aggregate verdict appears in the RAMPART terminal summary
- Any
UNSAFEtrial → the group fails ERRORtrials count against the pass rate
Structured Reports¶
Register the pytest_rampart_sinks hook to write JSON reports for downstream processing:
# conftest.py
from pathlib import Path
from rampart.reporting import JsonFileReportSink
def pytest_rampart_sinks(config):
return [JsonFileReportSink(output_dir=Path(".report"))]
The JSON file contains aggregate statistics and per-result data that CI dashboards can consume. The hook is resolved on the controller, so it behaves identically in single-process and pytest-xdist CI runs. See Registering Sinks.
Deprecated
The older rampart_sinks fixture still works but is deprecated and will be removed in 0.3.0. Prefer the pytest_rampart_sinks hook above.
Pytest Options¶
RAMPART is configured via pytest options and Python (sinks, adapters, payloads).
--rampart-xdist-max-bytes¶
Maximum size in bytes of a worker's serialized result payload when running under pytest-xdist. Defaults to 67108864 (64 MB). Workers that exceed the cap log a warning and the controller marks the run as incomplete. Also configurable via the rampart_xdist_max_bytes ini option.
Environment Variables¶
Your adapter and test configuration typically read environment variables. Setting them locally for ad-hoc runs:
Then consume them in your adapter and configuration:
import os
from rampart.core.llm import LLMConfig
@pytest.fixture
def adapter():
return MyAdapter(
api_key=os.environ["AGENT_API_KEY"],
endpoint=os.environ["AGENT_ENDPOINT"],
)
# For LLM-driven attacks
llm = LLMConfig(
model="gpt-4o",
endpoint=os.environ["OPENAI_ENDPOINT"],
api_key=os.environ.get("OPENAI_API_KEY"), # None → azure-identity
deployment=os.environ.get("OPENAI_DEPLOYMENT"),
)
Exit Codes¶
RAMPART does not alter pytest's exit codes:
| Exit Code | Meaning |
|---|---|
0 |
All tests passed |
1 |
Some tests failed |
2 |
Test execution interrupted |
5 |
No tests collected |