Skip to content

Commit 5e851e0

Browse files
Feature/unit tests/tags parser (#257)
* eventtype_parser unit tests * eventtype_parser no config file update * review remarks #1 * conftest parametrization * wrapped pytest arguments * test_tags_parser * build_parsed_output * fixture scope * typo change * review remarks #1 * review remarks #2
1 parent 17607a1 commit 5e851e0

File tree

3 files changed

+173
-38
lines changed

3 files changed

+173
-38
lines changed

tests/unit/conftest.py

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,47 @@
11
import pytest
22
from unittest.mock import Mock
3-
from pytest_splunk_addon.standard_lib.addon_parser.eventtype_parser import (
4-
EventTypeParser,
5-
)
63

74

8-
@pytest.fixture()
5+
@pytest.fixture(scope="session")
96
def parser():
10-
class FakeConfigurationFile:
11-
def __init__(self):
12-
self.headers = []
13-
self.sects = {
14-
"fake_splunkd": {
15-
"name": "fake_splunkd",
16-
"options": "index=_internal sourcetype=splunkd",
17-
},
18-
"fake_for_tags_positive": {
19-
"name": "fake_for_tags_positive",
20-
"options": "sourcetype=splunkd",
21-
},
22-
}
23-
self.errors = []
7+
def create_parser(parser_class, func_to_be_mocked, parsed_output):
8+
class FakeConfigurationFile:
9+
def __init__(self, sects):
10+
self.headers = []
11+
self.sects = sects
12+
self.errors = []
2413

25-
FakeApp = Mock()
26-
FakeApp.eventtypes = FakeConfigurationFile()
27-
FakeApp.eventtypes_conf.return_value = FakeConfigurationFile()
14+
FakeApp = Mock()
15+
attrs = {
16+
"{}.return_value".format(func_to_be_mocked): FakeConfigurationFile(
17+
parsed_output
18+
)
19+
}
20+
FakeApp.configure_mock(**attrs)
21+
return parser_class("fake_path", FakeApp)
2822

29-
return EventTypeParser("fake_path", FakeApp)
23+
return create_parser
24+
25+
26+
@pytest.fixture(scope="session")
27+
def build_parsed_output():
28+
def parsed_output(output_elements):
29+
"""
30+
builds expected parser output from provided dict
31+
:param output_elements: dictionary with {stanza: {option: value, ...}, ...}
32+
:return: parsed_output
33+
"""
34+
parsed_output = {}
35+
for stanza, stanza_value in output_elements.items():
36+
fake_section = Mock()
37+
fake_section.options = {}
38+
fake_section.name = stanza
39+
parsed_output.update({stanza: fake_section})
40+
for option, value in stanza_value.items():
41+
fake_setting = Mock()
42+
fake_setting.name = option
43+
fake_setting.value = value
44+
parsed_output[stanza].options.update({option: fake_setting})
45+
return parsed_output
46+
47+
return parsed_output
Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,61 @@
1-
def test_eventtypes_can_be_parsed_and_extracted(parser):
2-
assert hasattr(
3-
parser.eventtypes, "sects"
4-
), "eventypes can not be called or does have sects attribute"
1+
import pytest
2+
from unittest.mock import patch, PropertyMock
3+
from pytest_splunk_addon.standard_lib.addon_parser.eventtype_parser import (
4+
EventTypeParser,
5+
)
56

67

7-
def test_eventtypes_can_be_parsed_and_returned(parser):
8-
expected_outputs = [
9-
{"stanza": x} for x in ["fake_splunkd", "fake_for_tags_positive"]
10-
]
11-
for i, event in enumerate(parser.get_eventtypes()):
8+
output_to_build = {
9+
"fiction_is_splunkd": {"search": "index=_internal sourcetype=splunkd"},
10+
"fiction_for_tags_positive": {"search": "sourcetype=splunkd"},
11+
"fiction_is_splunkd-%host%": {"search": "index=_internal sourcetype=splunkd"},
12+
}
13+
14+
15+
def test_eventtypes_can_be_parsed_and_extracted(parser_instance):
16+
assert list(parser_instance.eventtypes.sects.keys()) == [
17+
"fiction_is_splunkd",
18+
"fiction_for_tags_positive",
19+
"fiction_is_splunkd-%host%",
20+
], "eventypes can not be called or does not have sects attribute"
21+
22+
23+
def test_eventtypes_can_be_parsed_and_returned(parsed_output, parser_instance):
24+
expected_outputs = [{"stanza": x} for x in parsed_output.keys()]
25+
for i, event in enumerate(parser_instance.get_eventtypes()):
1226
assert event == expected_outputs[i], "expeceted event {} not found".format(
1327
expected_outputs[i]
1428
)
1529

1630

17-
def test_get_eventtypes_calls_app_get_config(parser):
18-
for _ in parser.get_eventtypes():
31+
def test_get_eventtypes_calls_app_get_config(parser_instance):
32+
for _ in parser_instance.get_eventtypes():
1933
pass
20-
parser.app.eventtypes_conf.assert_called_once()
34+
parser_instance.app.eventtypes_conf.assert_called_once()
35+
36+
37+
def test_no_eventtype_config_file(parser_instance):
38+
parser_instance.app.eventtypes_conf.side_effect = OSError
39+
assert (
40+
parser_instance.eventtypes is None
41+
), "eventtypes created when no config file exists"
42+
43+
44+
def test_nothing_returned_when_no_tags_config_file(parser):
45+
with patch.object(
46+
EventTypeParser, "eventtypes", new_callable=PropertyMock
47+
) as eventtypes_mock:
48+
eventtypes_mock.return_value = None
49+
parser_instance = parser(EventTypeParser, "eventtypes_conf", {})
50+
output = [tag for tag in parser_instance.get_eventtypes() if tag]
51+
assert output == [], "eventtypes returned when no config file exists"
52+
53+
54+
@pytest.fixture(scope="module")
55+
def parsed_output(build_parsed_output):
56+
return build_parsed_output(output_to_build)
2157

2258

23-
def test_no_eventtype_config_file(parser):
24-
parser.app.eventtypes_conf.side_effect = OSError
25-
output = [eventtype for eventtype in parser.get_eventtypes() if eventtype]
26-
assert output == [], "eventtypes created when no config file exists"
59+
@pytest.fixture()
60+
def parser_instance(parsed_output, parser):
61+
return parser(EventTypeParser, "eventtypes_conf", parsed_output)

tests/unit/test_tags_parser.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import pytest
2+
from unittest.mock import patch, PropertyMock
3+
from pytest_splunk_addon.standard_lib.addon_parser.tags_parser import (
4+
TagsParser,
5+
)
6+
7+
8+
output_to_build = {
9+
"eventtype=fiction_for_tags_positive": {
10+
"tags_positive_event": "enabled",
11+
"tags_disabled_event": "disabled",
12+
},
13+
"source=%2Fopt%2Fsplunk%2Fvar%2Flog%2Fsplunk%2Fsplunkd.log": {
14+
"tags_positive_event": "enabled",
15+
"tags_disabled_event": "disabled",
16+
},
17+
}
18+
19+
20+
def test_tags_can_be_parsed_and_extracted(parser_instance):
21+
assert list(parser_instance.tags.sects.keys()) == [
22+
"eventtype=fiction_for_tags_positive",
23+
"source=%2Fopt%2Fsplunk%2Fvar%2Flog%2Fsplunk%2Fsplunkd.log",
24+
], "tags can not be called or does not have sects attribute"
25+
26+
27+
def test_tags_can_be_parsed_and_returned(parser_instance):
28+
expected_outputs = [
29+
{
30+
"stanza": 'eventtype="fiction_for_tags_positive"',
31+
"tag": "tags_positive_event",
32+
"enabled": True,
33+
},
34+
{
35+
"stanza": 'eventtype="fiction_for_tags_positive"',
36+
"tag": "tags_disabled_event",
37+
"enabled": False,
38+
},
39+
{
40+
"stanza": 'source="/opt/splunk/var/log/splunk/splunkd.log"',
41+
"tag": "tags_positive_event",
42+
"enabled": True,
43+
},
44+
{
45+
"stanza": 'source="/opt/splunk/var/log/splunk/splunkd.log"',
46+
"tag": "tags_disabled_event",
47+
"enabled": False,
48+
},
49+
]
50+
for i, event in enumerate(parser_instance.get_tags()):
51+
assert event == expected_outputs[i], "expeceted event {} not found".format(
52+
expected_outputs[i]
53+
)
54+
55+
56+
def test_get_tags_calls_app_get_config(parser_instance):
57+
for _ in parser_instance.get_tags():
58+
pass
59+
parser_instance.app.get_config.assert_called_once()
60+
61+
62+
def test_no_tags_config_file(parser_instance):
63+
parser_instance.app.get_config.side_effect = OSError
64+
assert parser_instance.tags is None, "tags created when no config file exists"
65+
66+
67+
def test_nothing_returned_when_no_tags_config_file(parser):
68+
with patch.object(TagsParser, "tags", new_callable=PropertyMock) as tags_mock:
69+
tags_mock.return_value = None
70+
parser_instance = parser(TagsParser, "get_config", {})
71+
output = [tag for tag in parser_instance.get_tags() if tag]
72+
assert output == [], "tags returned when no config file exists"
73+
74+
75+
@pytest.fixture(scope="module")
76+
def parsed_output(build_parsed_output):
77+
return build_parsed_output(output_to_build)
78+
79+
80+
@pytest.fixture()
81+
def parser_instance(parsed_output, parser):
82+
return parser(TagsParser, "get_config", parsed_output)

0 commit comments

Comments
 (0)