Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions pytest_splunk_addon/fields_tests/test_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,17 +250,19 @@ def generate_requirements_tests(self):
}

cim_fields = event.requirement_test_data.get("cim_fields", {})
other_fields = event.requirement_test_data.get("other_fields", {})
requirement_fields = {**cim_fields, **other_fields}

if cim_fields:
cim_fields = {
if requirement_fields:
requirement_fields = {
field: value
for field, value in cim_fields.items()
for field, value in requirement_fields.items()
if field not in exceptions
}
yield pytest.param(
{
"escaped_event": escaped_event,
"fields": cim_fields,
"fields": requirement_fields,
"modinput_params": modinput_params,
},
id=f"sample_name::{event.sample_name}::host::{event.metadata.get('host')}",
Expand Down
10 changes: 10 additions & 0 deletions pytest_splunk_addon/sample_generation/sample_stanza.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,16 @@ def populate_requirement_test_data(event):
"""
requirement_test_data = {}
cim = event.get("cim")
other_mappings = event.get("other_mappings")
if other_mappings:
other_fields = {}
fields = other_mappings["field"]
if type(fields) == list:
for field in fields:
other_fields[field["@name"]] = field["@value"]
elif type(fields) == dict:
other_fields[fields["@name"]] = fields["@value"]
requirement_test_data["other_fields"] = other_fields
if cim:
requirement_test_data["cim_version"] = cim.get("@version", "latest")
requirement_test_data["datamodels"] = cim.get("models") or {}
Expand Down
28 changes: 28 additions & 0 deletions tests/e2e/addons/TA_req_broken/samples/sample_modinput.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,32 @@
</missing_recommended_fields>
</cim>
</event>
<event code="" name="WrongFieldValueOtherMappings" format="">
<transport type="modinput" sourcetype="test:data:1" source="test_data.1" host="so1"/>
<source>
<jira id=""/>
<comment>lab</comment>
</source>
<raw>
<![CDATA[2021-12-31 15:15:30,340+0000 action=success app=psa user=admin status=success dest=10.0.0.1 src=10.0.0.2]]></raw>
<cim>
<models>
<model>Authentication</model>
</models>
<cim_fields>
<field name="action" value="success"/>
<field name="status" value="success"/>
<field name="app" value="psa"/>
<field name="src" value="10.0.0.2"/>
<field name="user" value="admin"/>
<field name="dest" value="10.0.0.1"/>
</cim_fields>
<missing_recommended_fields>
<field>src_user</field>
</missing_recommended_fields>
</cim>
<other_mappings>
<field name="vendor_product" value="PSA"/>
</other_mappings>
</event>
</device>
3 changes: 2 additions & 1 deletion tests/e2e/addons/TA_transition_from_req/default/props.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ FIELDALIAS-action = result AS action
EVAL-app = "psa"
FIELDALIAS-user = tester AS user
FIELDALIAS-src = ip AS src
EVAL-status = case(action=="success", "PASS", action=="failure", "FAIL", 0==0, "OTHER")
EVAL-status = case(action=="success", "PASS", action=="failure", "FAIL", 0==0, "OTHER")
EVAL-vendor_product = "Pytest Splunk Addon"
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@
<field>src_user</field>
</missing_recommended_fields>
</cim>
<other_mappings>
<field name="vendor_product" value="Pytest Splunk Addon"/>
</other_mappings>
</event>
</device>
6 changes: 6 additions & 0 deletions tests/e2e/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,7 @@
"*test_splunk_app_req.py::Test_App::test_props_fields[test:data:1::field::status* PASSED*",
"*test_splunk_app_req.py::Test_App::test_props_fields[test:data:1::field::tester* PASSED*",
"*test_splunk_app_req.py::Test_App::test_props_fields[test:data:1::field::user* PASSED*",
"*test_splunk_app_req.py::Test_App::test_props_fields[test:data:1::field::vendor_product* PASSED*",
"*test_splunk_app_req.py::Test_App::test_requirements_fields[sample_name::sample_modinput.xml::host::so1-4* PASSED*",
"*test_splunk_app_req.py::Test_App::test_requirements_fields[sample_name::sample_modinput.xml::host::so1-5* PASSED*",
"*test_splunk_app_req.py::Test_App::test_requirements_fields[sample_name::sample_modinput.xml::host::so1-6* PASSED*",
Expand All @@ -811,6 +812,7 @@
"*test_splunk_app_req.py::Test_App::test_props_fields_no_dash_not_empty[test:data:1::field::status* PASSED*",
"*test_splunk_app_req.py::Test_App::test_props_fields_no_dash_not_empty[test:data:1::field::tester* PASSED*",
"*test_splunk_app_req.py::Test_App::test_props_fields_no_dash_not_empty[test:data:1::field::user* PASSED*",
"*test_splunk_app_req.py::Test_App::test_props_fields_no_dash_not_empty[test:data:1::field::vendor_product* PASSED*",
"*test_splunk_app_req.py::Test_App::test_datamodels[Authentication::sample_name::sample_modinput.xml::host::so1-4* PASSED*",
"*test_splunk_app_req.py::Test_App::test_datamodels[Authentication::sample_name::sample_modinput.xml::host::so1-5* PASSED*",
"*test_splunk_app_req.py::Test_App::test_datamodels[Authentication::sample_name::sample_modinput.xml::host::so1-6* PASSED*",
Expand All @@ -836,6 +838,7 @@
"*test_splunk_app_req_broken.py::Test_App::test_indextime_time[req:test:broken::so11* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_indextime_time[req:test:broken::so12* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_indextime_time[req:test:broken::so13* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_indextime_time[req:test:broken::so14* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_indextime_line_breaker[juniper:junos:firewall::syslog.xml* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_indextime_line_breaker[req:test:broken::sample_modinput.xml* PASSED*",
'*test_splunk_app_req_broken.py::Test_App::test_cim_required_fields[eventtype="net"::All_Traffic* PASSED*',
Expand Down Expand Up @@ -882,6 +885,7 @@
"*test_splunk_app_req_broken.py::Test_App::test_cim_fields_recommended[Authentication-::sample_name::sample_modinput.xml::host::so10* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_cim_fields_recommended[Authentication-::sample_name::sample_modinput.xml::host::so12* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_cim_fields_recommended[Authentication-::sample_name::sample_modinput.xml::host::so13* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_cim_fields_recommended[Authentication-::sample_name::sample_modinput.xml::host::so14* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_cim_fields_recommended[Network_Traffic-::sample_name::syslog.xml::host::10.0.0.30* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_cim_fields_recommended[Network_Traffic-::sample_name::syslog.xml::host::10.0.0.31* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_splunk_internal_errors PASSED*",
Expand All @@ -897,6 +901,7 @@
"*test_splunk_app_req_broken.py::Test_App::test_datamodels[Authentication::sample_name::sample_modinput.xml::host::so11* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_datamodels[Authentication::sample_name::sample_modinput.xml::host::so12* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_datamodels[Authentication::sample_name::sample_modinput.xml::host::so13* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_datamodels[Authentication::sample_name::sample_modinput.xml::host::so14* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_datamodels[Network_Traffic::sample_name::syslog.xml::host::10.0.0.30* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_eventtype[eventtype::net* PASSED*",
"*test_splunk_app_req_broken.py::Test_App::test_eventtype[eventtype::test_auth* PASSED*",
Expand All @@ -913,6 +918,7 @@
'*test_splunk_app_req_broken.py::Test_App::test_cim_required_fields[eventtype="net"::All_Traffic::src_zone* FAILED*',
'*test_splunk_app_req_broken.py::Test_App::test_cim_required_fields[eventtype="net"::Blocked_Traffic* FAILED*',
"*test_splunk_app_req_broken.py::Test_App::test_requirements_fields[sample_name::sample_modinput.xml::host::so13* FAILED*",
"*test_splunk_app_req_broken.py::Test_App::test_requirements_fields[sample_name::sample_modinput.xml::host::so14* FAILED*",
"*test_splunk_app_req_broken.py::Test_App::test_cim_fields_recommended[Authentication-::sample_name::sample_modinput.xml::host::so11* FAILED*",
"*test_splunk_app_req_broken.py::Test_App::test_datamodels[Network_Traffic::sample_name::syslog.xml::host::10.0.0.31* FAILED*",
]
Expand Down
205 changes: 205 additions & 0 deletions tests/unit/tests_standard_lib/test_fields_tests/test_test_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from pytest_splunk_addon.fields_tests.test_generator import (
FieldTestGenerator,
)
from pytest_splunk_addon.sample_generation.sample_event import SampleEvent
from pytest_splunk_addon.utilities import xml_event_parser


def field_1():
Expand Down Expand Up @@ -71,6 +73,14 @@ def test_field_test_generator_instantiation(addon_parser_mock):
"splunk_searchtime_fields_savedsearches",
"GENERATE_SAVEDSEARCHES_TESTS_RETURN_VALUE",
),
(
"splunk_searchtime_fields_requirements",
"GENERATE_REQUIREMENT_TESTS_RETURN_VALUE",
),
(
"splunk_searchtime_fields_datamodels",
"GENERATE_REQUIREMENT_DATAMODEL_TESTS_RETURN_VALUE",
),
],
)
def test_generate_tests(addon_parser_mock, fixture_name, expected_ouptput):
Expand All @@ -90,6 +100,14 @@ def test_generate_tests(addon_parser_mock, fixture_name, expected_ouptput):
FieldTestGenerator,
"generate_savedsearches_tests",
return_value=(["GENERATE_SAVEDSEARCHES_TESTS_RETURN_VALUE"]),
), patch.object(
FieldTestGenerator,
"generate_requirements_tests",
return_value=(["GENERATE_REQUIREMENT_TESTS_RETURN_VALUE"]),
), patch.object(
FieldTestGenerator,
"generate_requirements_datamodels_tests",
return_value=(["GENERATE_REQUIREMENT_DATAMODEL_TESTS_RETURN_VALUE"]),
):
assert list(
FieldTestGenerator(
Expand Down Expand Up @@ -391,3 +409,190 @@ def test_generate_field_tests(
)
assert out == expected_output
assert param_mock.call_count == len(expected_output)


@pytest.mark.parametrize(
"tokenised_events, expected_output",
[
(
[
SampleEvent(
event_string="escaped_event",
metadata={
"input_type": "modinput",
"sourcetype_to_search": "dummy_sourcetype",
"host": "dummy_host",
},
sample_name="file1.xml",
requirement_test_data={
"cim_fields": {
"dest": "192.168.0.1",
"severity": "low",
"signature_id": "405001",
"src": "192.168.0.1",
"type": "event",
},
"exceptions": {"mane_1": "value_1", "dest": "192.168.0.1"},
"other_fields": {
"vendor_product": "Pytest Splunk Addon",
"target_users": "[email protected]",
},
},
),
SampleEvent(
event_string="escaped_event",
metadata={
"input_type": "syslog_tcp",
"sourcetype_to_search": "dummy_sourcetype",
"host": "dummy_host_syslog",
},
sample_name="file1.xml",
requirement_test_data={},
),
SampleEvent(
event_string="escaped_event",
metadata={
"input_type": "syslog_tcp",
"sourcetype_to_search": "dummy_sourcetype",
"host": "dummy_host_syslog",
},
sample_name="file1.xml",
requirement_test_data={
"cim_fields": {
"src": "192.168.0.1",
"type": "event",
},
"exceptions": {},
"other_fields": {
"vendor_product": "Pytest Splunk Addon",
"target_users": "[email protected]",
},
},
),
],
[
(
{
"escaped_event": "escaped_event",
"fields": {
"severity": "low",
"signature_id": "405001",
"src": "192.168.0.1",
"type": "event",
"vendor_product": "Pytest Splunk Addon",
"target_users": "[email protected]",
},
"modinput_params": {"sourcetype": "dummy_sourcetype"},
},
"sample_name::file1.xml::host::dummy_host",
),
(
{
"escaped_event": "escaped_event",
"fields": {
"src": "192.168.0.1",
"type": "event",
"vendor_product": "Pytest Splunk Addon",
"target_users": "[email protected]",
},
"modinput_params": {"sourcetype": "dummy_sourcetype"},
},
"sample_name::file1.xml::host::dummy_host_syslog",
),
],
),
],
)
def test_generate_requirement_tests(tokenised_events, expected_output):
with patch.object(
xml_event_parser, "strip_syslog_header", return_value="escaped_event"
), patch.object(
xml_event_parser, "escape_char_event", return_value="escaped_event"
), patch.object(
pytest, "param", side_effect=lambda x, id: (x, id)
) as param_mock:
out = list(
FieldTestGenerator(
"app_path",
tokenised_events,
"field_bank",
).generate_requirements_tests()
)
assert out == expected_output
assert param_mock.call_count == len(expected_output)


@pytest.mark.parametrize(
"tokenised_events, expected_output",
[
(
[
SampleEvent(
event_string="escaped_event",
metadata={
"input_type": "modinput",
"sourcetype_to_search": "dummy_sourcetype",
"host": "dummy_host",
},
sample_name="file1.xml",
requirement_test_data={"datamodels": {"model": "Alerts"}},
),
SampleEvent(
event_string="escaped_event",
metadata={
"input_type": "syslog_tcp",
"sourcetype_to_search": "dummy_sourcetype",
"host": "dummy_host_syslog",
},
sample_name="file1.xml",
requirement_test_data={},
),
SampleEvent(
event_string="escaped_event",
metadata={
"input_type": "syslog_tcp",
"sourcetype_to_search": "dummy_sourcetype",
"host": "dummy_host_syslog",
},
sample_name="file1.xml",
requirement_test_data={
"datamodels": {"model": ["Change", "Account Management"]}
},
),
],
[
(
{
"datamodels": ["Alerts"],
"stanza": "escaped_event",
},
"Alerts::sample_name::file1.xml::host::dummy_host",
),
(
{
"datamodels": ["Change", "Account_Management"],
"stanza": "escaped_event",
},
"Change-Account_Management::sample_name::file1.xml::host::dummy_host_syslog",
),
],
),
],
)
def test_generate_requirement_datamodel_tests(tokenised_events, expected_output):
with patch.object(
xml_event_parser, "strip_syslog_header", return_value="escaped_event"
), patch.object(
xml_event_parser, "escape_char_event", return_value="escaped_event"
), patch.object(
pytest, "param", side_effect=lambda x, id: (x, id)
) as param_mock:
out = list(
FieldTestGenerator(
"app_path",
tokenised_events,
"field_bank",
).generate_requirements_datamodels_tests()
)
assert out == expected_output
assert param_mock.call_count == len(expected_output)
Loading