Skip to content

Commit be94ccb

Browse files
committed
fix: handle sigma errors and default to offline tests
1 parent afa9730 commit be94ccb

5 files changed

Lines changed: 58 additions & 10 deletions

File tree

.github/workflows/integration-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
2727
- name: Run live integration smoke tests
2828
run: |
29-
python -m pytest -v \
29+
python -m pytest -m integration -v \
3030
tests/test_basic.py::test_status \
3131
tests/test_basic.py::test_demo_rules_json \
3232
tests/test_cli_and_sigma.py::test_sigma_zip_updates_retrieved_rule_count_live_demo

Makefile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: help prepare-dev test lint release release-test
1+
.PHONY: help prepare-dev test test-integration lint release release-test
22

33
VENV_NAME?=venv
44
VENV_ACTIVATE=. $(VENV_NAME)/bin/activate
@@ -8,7 +8,9 @@ help:
88
@echo "make prepare-dev"
99
@echo " prepare development environment, use only once"
1010
@echo "make test"
11-
@echo " run tests"
11+
@echo " run offline tests"
12+
@echo "make test-integration"
13+
@echo " run live integration tests"
1214
@echo "make lint"
1315
@echo " run pylint and mypy"
1416

@@ -28,6 +30,9 @@ $(VENV_NAME)/bin/activate: setup.py
2830
test: venv
2931
${PYTHON} -m pytest -v
3032

33+
test-integration: venv
34+
${PYTHON} -m pytest -m integration -v
35+
3136
release:
3237
rm -rf ./dist/*
3338
${PYTHON} -m pip install --upgrade setuptools wheel
@@ -50,4 +55,3 @@ lint: venv
5055

5156

5257

53-

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[pytest]
2+
addopts = -m "not integration"
23
markers =
34
integration: tests that call the live Valhalla service

tests/test_cli_and_sigma.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import valhallaAPI.valhalla as valhalla_module
99
import valhallaAPI.valhalla_cli as valhalla_cli
10-
from valhallaAPI.valhalla import ValhallaAPI
10+
from valhallaAPI.valhalla import ValhallaAPI, ApiError
1111
from valhallaAPI.version import __version__
1212

1313
DEMO_KEY = ValhallaAPI.DEMO_KEY
@@ -75,6 +75,44 @@ def fake_post(url, data=None, proxies=None, headers=None):
7575
]
7676

7777

78+
def test_sigma_json_error_response_does_not_keyerror(monkeypatch):
79+
def fake_post(url, data=None, proxies=None, headers=None):
80+
assert url.endswith("/getsigma")
81+
return MockResponse(
82+
{
83+
"status": "error",
84+
"message": "demo failure",
85+
}
86+
)
87+
88+
monkeypatch.setattr(valhalla_module.requests, "post", fake_post)
89+
v = ValhallaAPI(api_key=DEMO_KEY)
90+
91+
response = v.get_sigma_rules_json(search="suspicious", private_only=True)
92+
93+
assert response["status"] == "error"
94+
assert v.last_retrieved_rules_count == 0
95+
96+
97+
def test_sigma_zip_raises_api_error_on_error_response(monkeypatch):
98+
def fake_post(url, data=None, proxies=None, headers=None):
99+
assert url.endswith("/getsigma")
100+
return MockResponse(
101+
{
102+
"status": "error",
103+
"message": "demo failure",
104+
}
105+
)
106+
107+
monkeypatch.setattr(valhalla_module.requests, "post", fake_post)
108+
v = ValhallaAPI(api_key=DEMO_KEY)
109+
110+
with pytest.raises(ApiError) as exc:
111+
v.get_sigma_rules_zip(search="suspicious", private_only=True)
112+
113+
assert exc.value.message == "demo failure"
114+
115+
78116
@pytest.mark.integration
79117
def test_sigma_zip_updates_retrieved_rule_count_live_demo():
80118
v = ValhallaAPI(api_key=DEMO_KEY)

valhallaAPI/valhalla.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,11 @@ def get_sigma_rules_json(self, search="", private_only=False):
313313
# Load JSON
314314
rules_response = json.loads(r.text)
315315

316-
if search:
317-
rules_response['rules'] = filter_search(rules_response['rules'], query=search)
318-
if private_only:
319-
rules_response['rules'] = filter_privateonly(rules_response['rules'])
320-
321316
if 'rules' in rules_response:
317+
if search:
318+
rules_response['rules'] = filter_search(rules_response['rules'], query=search)
319+
if private_only:
320+
rules_response['rules'] = filter_privateonly(rules_response['rules'])
322321
self.last_retrieved_rules_count = len(rules_response['rules'])
323322
else:
324323
self.last_retrieved_rules_count = 0
@@ -332,6 +331,12 @@ def get_sigma_rules_zip(self, search="", private_only=False):
332331
:return:
333332
"""
334333
rules_response = self.get_sigma_rules_json(search, private_only)
334+
335+
if 'status' in rules_response:
336+
if rules_response['status'] == "error":
337+
raise ApiError(rules_response['message'])
338+
if 'rules' not in rules_response:
339+
raise ApiError("Unexpected response from Valhalla API")
335340

336341
zip_buffer = io.BytesIO()
337342
with zipfile.ZipFile(file=zip_buffer, mode='w') as zip_file:

0 commit comments

Comments
 (0)