Skip to content

Commit 90fe9c8

Browse files
committed
add fuzz testing and workflows update
1 parent 53f08fc commit 90fe9c8

File tree

4 files changed

+381
-1
lines changed

4 files changed

+381
-1
lines changed

.github/workflows/test.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,54 @@ jobs:
3737
flags: unittests
3838
name: codecov-umbrella
3939
fail_ci_if_error: false
40+
41+
schema-fuzz:
42+
runs-on: ubuntu-latest
43+
if: github.event_name == 'pull_request'
44+
steps:
45+
- uses: actions/checkout@v4
46+
with:
47+
fetch-depth: 0
48+
49+
- name: Check for schema changes
50+
id: schema
51+
run: |
52+
CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- \
53+
'src/inference_endpoint/config/schema.py' \
54+
'src/inference_endpoint/endpoint_client/config.py' \
55+
'src/inference_endpoint/commands/benchmark/cli.py')
56+
echo "changed=$([[ -n "$CHANGED" ]] && echo true || echo false)" >> "$GITHUB_OUTPUT"
57+
58+
- name: Set up Python 3.12
59+
if: steps.schema.outputs.changed == 'true'
60+
uses: actions/setup-python@v4
61+
with:
62+
python-version: "3.12"
63+
64+
- name: Install dependencies
65+
if: steps.schema.outputs.changed == 'true'
66+
run: |
67+
python -m pip install --upgrade pip
68+
pip install -e .[test]
69+
70+
- name: Run schema fuzz tests
71+
if: steps.schema.outputs.changed == 'true'
72+
run: |
73+
pytest -xv -m schema_fuzz
74+
75+
- name: Validate YAML templates against schema
76+
if: steps.schema.outputs.changed == 'true'
77+
run: |
78+
python -c "
79+
from pathlib import Path
80+
from inference_endpoint.config.schema import BenchmarkConfig
81+
templates = sorted(Path('src/inference_endpoint/config/templates').glob('*.yaml'))
82+
for t in templates:
83+
try:
84+
BenchmarkConfig.from_yaml_file(t)
85+
print(f' OK: {t.name}')
86+
except Exception as e:
87+
print(f' FAIL: {t.name}: {e}')
88+
raise SystemExit(1)
89+
print(f'All {len(templates)} templates valid.')
90+
"

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ test = [
9595
"aiohttp==3.13.3",
9696
# Plotting for benchmark sweep mode
9797
"matplotlib>=3.8.0",
98+
# Property-based testing (CLI fuzz)
99+
"hypothesis==6.151.10",
98100
]
99101
performance = [
100102
"pytest-benchmark>=4.0.0",
@@ -182,6 +184,7 @@ markers = [
182184
"integration: marks tests as integration tests",
183185
"unit: marks tests as unit tests",
184186
"run_explicitly: mark test to only run explicitly",
187+
"schema_fuzz: hypothesis CLI fuzz tests (run in CI on schema changes)",
185188
]
186189
filterwarnings = [
187190
"ignore:Session timeout reached:RuntimeWarning",

tests/integration/commands/test_benchmark_command.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def test_offline_benchmark(
8787

8888
@pytest.mark.integration
8989
@pytest.mark.parametrize("streaming", [StreamingMode.OFF, StreamingMode.ON])
90-
def test_online_benchmark(
90+
def test_poisson_benchmark(
9191
self, mock_http_echo_server, ds_pickle_dataset_path, caplog, streaming
9292
):
9393
config = _config(
@@ -105,6 +105,32 @@ def test_online_benchmark(
105105
assert "PoissonDistributionScheduler" in caplog.text
106106
assert "50" in caplog.text
107107

108+
@pytest.mark.integration
109+
@pytest.mark.parametrize("streaming", [StreamingMode.OFF, StreamingMode.ON])
110+
def test_concurrency_benchmark(
111+
self, mock_http_echo_server, ds_pickle_dataset_path, caplog, streaming
112+
):
113+
config = _config(
114+
mock_http_echo_server.url,
115+
ds_pickle_dataset_path,
116+
type=TestType.ONLINE,
117+
model_params=ModelParams(name="echo-server", streaming=streaming),
118+
settings=Settings(
119+
runtime=RuntimeConfig(min_duration_ms=2000),
120+
load_pattern=LoadPattern(
121+
type=LoadPatternType.CONCURRENCY, target_concurrency=4
122+
),
123+
client=HTTPClientConfig(
124+
num_workers=1, warmup_connections=0, max_connections=10
125+
),
126+
),
127+
)
128+
with caplog.at_level("INFO"):
129+
run_benchmark(config, TestMode.PERF)
130+
131+
assert "Completed in" in caplog.text
132+
assert "successful" in caplog.text
133+
108134
@pytest.mark.integration
109135
def test_results_json_output(
110136
self, mock_http_echo_server, ds_pickle_dataset_path, tmp_path

0 commit comments

Comments
 (0)