Skip to content

Commit 1d14a5b

Browse files
committed
feat(config): add specific-to-handler config options to override config entries
1 parent 8c3def1 commit 1d14a5b

File tree

7 files changed

+138
-28
lines changed

7 files changed

+138
-28
lines changed

example/my_parser.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ class MyParser(BaseHandler):
1212
{'name': 'My Test 2', 'passed': False, 'msg': 'Error text D:'}]
1313
}
1414

15-
def run_my_tests(self, resultfile):
16-
with open(resultfile, 'w') as f:
15+
def run_my_tests(self, result_file):
16+
with open(result_file, 'w') as f:
1717
json.dump(self.RESULTS, f)
18-
return resultfile
18+
return result_file
1919

20-
def parse_results(self, resultfile):
21-
with open(resultfile, 'r') as f:
20+
def parse_results(self, result_file):
21+
with open(result_file, 'r') as f:
2222
results = json.load(f)
2323
return {
24-
'name': resultfile,
24+
'name': result_file,
2525
'tags': [],
2626
'setup': None,
2727
'teardown': None,

src/oxygen/base_handler.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from .robot_interface import RobotInterface
44

55
class BaseHandler(object):
6-
DEFAULT_CLI = {tuple(['resultfile']): {}}
6+
DEFAULT_CLI = {tuple(['result_file']): {}}
77

88
def __init__(self, config):
99
'''

src/oxygen/oxygen.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,10 @@ def parse_args(self, parser):
213213
for flags, params in tool_handler.cli().items():
214214
subcommand_parser.add_argument(*flags, **params)
215215
subcommand_parser.set_defaults(func=tool_handler.parse_results)
216-
return parser.parse_args()
216+
return vars(parser.parse_args()) # returns a dictionary
217217

218-
def get_output_filename(self, resultfile):
219-
filename = Path(resultfile)
218+
def get_output_filename(self, result_file):
219+
filename = Path(result_file)
220220
filename = filename.with_suffix('.xml')
221221
robot_name = filename.stem + '_robot_output' + filename.suffix
222222
filename = filename.with_name(robot_name)
@@ -228,10 +228,11 @@ def run(self):
228228
action='version',
229229
version=f'%(prog)s {self.__version__}')
230230
args = self.parse_args(parser)
231-
if not vars(args):
231+
if not args:
232232
parser.error('No arguments given')
233-
output_filename = self.get_output_filename(args.resultfile)
234-
parsed_results = args.func(args.resultfile)
233+
output_filename = self.get_output_filename(args['result_file'])
234+
parsed_results = args['func'](
235+
**{k: v for (k, v) in args.items() if not callable(v)})
235236
robot_suite = RobotInterface().running.build_suite(parsed_results)
236237
robot_suite.run(output=output_filename,
237238
log=None,

src/oxygen/zap.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,25 @@ def run_zap(self, result_file, command, check_return_code=False, **env):
2525
logger.info('Result file: {}'.format(result_file))
2626
return result_file
2727

28-
29-
def parse_results(self, result_file):
28+
def cli(self):
29+
cli_interface = self.DEFAULT_CLI.copy()
30+
cli_interface[('--accepted-risk-level',)] = {
31+
'help': 'Set accepted risk level',
32+
'type': int
33+
}
34+
cli_interface[('--required-confidence-level',)] = {
35+
'help': 'Set required confidence level',
36+
'type': int
37+
}
38+
return cli_interface
39+
40+
def parse_results(self, result_file, accepted_risk_level=None,
41+
required_confidence_level=None):
42+
if accepted_risk_level is not None:
43+
self._config['accepted_risk_level'] = accepted_risk_level
44+
if required_confidence_level is not None:
45+
self._config['required_confidence_level'] = \
46+
required_confidence_level
3047
zap_dict = self._read_results(validate_path(result_file).resolve())
3148
return self._parse_zap_dict(zap_dict)
3249

tests/utest/oxygen/test_oxygen_cli.py

+15-8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from ..helpers import RESOURCES_PATH
1212

13+
1314
class TestOxygenCLIEntryPoints(TestCase):
1415
'''Coverage does not measure coverage correctly for these tests.
1516
@@ -20,6 +21,7 @@ class TestOxygenCLIEntryPoints(TestCase):
2021
Setting up Coverage to see subprocesses as well seems a lot of work and
2122
quite a hack: https://coverage.readthedocs.io/en/latest/subprocess.html
2223
'''
24+
2325
def test_main_level_entrypoint(self):
2426
self.verify_cli_help_text('python -m oxygen --help')
2527
self.verify_cli_help_text('python -m oxygen -h')
@@ -43,16 +45,20 @@ def verify_cli_help_text(self, cmd):
4345

4446
def test_junit_works_on_cli(self):
4547
target = RESOURCES_PATH / 'green-junit-example.xml'
46-
expected = target.with_name('green-junit-expected-robot-output.xml')
48+
example = target.with_name('green-junit-expected-robot-output.xml')
4749
actual = target.with_name('green-junit-example_robot_output.xml')
4850
if actual.exists():
49-
actual.unlink() # delete file if exists
51+
actual.unlink() # delete file if exists
52+
53+
check_output(f'python -m oxygen oxygen.junit {target}',
54+
text=True,
55+
shell=True)
5056

51-
out = check_output(f'python -m oxygen oxygen.junit {target}',
52-
text=True,
53-
shell=True)
57+
for expected in ('<stat pass="69" fail="3">Critical Tests</stat>',
58+
'<stat pass="69" fail="3">All Tests</stat>'):
59+
self.assertIn(expected, example.read_text())
60+
self.assertIn(expected, actual.read_text())
5461

55-
self.assertEqual(expected.read_text(), expected.read_text())
5662

5763
class TestOxygenCLI(TestCase):
5864

@@ -62,8 +68,9 @@ def setUp(self):
6268
@patch('oxygen.oxygen.RobotInterface')
6369
@patch('oxygen.oxygen.OxygenCLI.parse_args')
6470
def test_run(self, mock_parse_args, mock_robot_iface):
65-
mock_parse_args.return_value = Mock(resultfile='path/to/file.xml',
66-
func=lambda _: {'some': 'results'})
71+
mock_parse_args.return_value = {
72+
'result_file': 'path/to/file.xml',
73+
'func': lambda *_, **__: {'some': 'results'}}
6774
expected_suite = create_autospec(TestSuite)
6875
mock = Mock()
6976
mock.running.build_suite = Mock(return_value=expected_suite)

tests/utest/zap/test_basic_functionality.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
from pathlib import Path
2-
from unittest import skip, TestCase
2+
from unittest import TestCase
33
from unittest.mock import ANY, create_autospec, Mock, mock_open, patch
44

55
from testfixtures import compare
66

7-
from oxygen.base_handler import BaseHandler
87
from oxygen.zap import ZAProxyHandler
98
from oxygen.errors import ZAProxyHandlerException
109
from ..helpers import (example_robot_output,
@@ -299,9 +298,6 @@ def test_parsing_json(self):
299298
def assertNotNoneOrEmpty(self, str_):
300299
return str_ is not None and str_ != ''
301300

302-
def test_cli(self):
303-
self.assertEqual(self.handler.cli(), BaseHandler.DEFAULT_CLI)
304-
305301
@patch('oxygen.zap.ZAProxyHandler._report_oxygen_run')
306302
def test_check_for_keyword(self, mock_report):
307303
fake_test = example_robot_output().suite.suites[0].tests[4]

tests/utest/zap/test_zap_cli.py

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import sys
2+
from unittest import TestCase
3+
from unittest.mock import ANY, Mock, create_autospec, patch
4+
from robot.running.model import TestSuite
5+
from oxygen.oxygen import OxygenCLI
6+
from ..helpers import RESOURCES_PATH
7+
8+
9+
class TestOxygenZapCLI(TestCase):
10+
ZAP_XML = str(RESOURCES_PATH / "zap" / "zap.xml")
11+
12+
def setUp(self):
13+
self.cli = OxygenCLI()
14+
self.handler = self.cli._handlers["oxygen.zap"]
15+
self.expected_suite = create_autospec(TestSuite)
16+
self.mock = Mock()
17+
self.mock.running.build_suite = Mock(return_value=self.expected_suite)
18+
19+
def test_cli(self):
20+
self.assertEqual(
21+
self.handler.cli(),
22+
{
23+
("--accepted-risk-level",): {
24+
"help": "Set accepted risk level",
25+
"type": int,
26+
},
27+
("--required-confidence-level",): {
28+
"help": "Set required confidence level",
29+
"type": int,
30+
},
31+
("result_file",): {},
32+
},
33+
)
34+
35+
@patch("oxygen.oxygen.RobotInterface")
36+
def test_cli_run(self, mock_robot_iface):
37+
mock_robot_iface.return_value = self.mock
38+
39+
cmd_args = f"oxygen oxygen.zap {self.ZAP_XML}"
40+
with patch.object(sys, "argv", cmd_args.split()):
41+
self.cli.run()
42+
43+
self.assertEqual(self.handler._config["accepted_risk_level"], 2)
44+
self.assertEqual(self.handler._config["required_confidence_level"], 1)
45+
46+
self.mock.running.build_suite.assert_called_once()
47+
48+
self.expected_suite.run.assert_called_once_with(
49+
output=str(RESOURCES_PATH / "zap" / "zap_robot_output.xml"),
50+
log=None,
51+
report=None,
52+
stdout=ANY,
53+
)
54+
55+
@patch("oxygen.oxygen.RobotInterface")
56+
def test_cli_run_with_levels(self, mock_robot_iface):
57+
mock_robot_iface.return_value = self.mock
58+
59+
cmd_args = (
60+
f"oxygen oxygen.zap {self.ZAP_XML} --accepted-risk-level 3"
61+
" --required-confidence-level 3"
62+
)
63+
with patch.object(sys, "argv", cmd_args.split()):
64+
self.cli.run()
65+
66+
self.assertEqual(self.handler._config["accepted_risk_level"], 3)
67+
self.assertEqual(self.handler._config["required_confidence_level"], 3)
68+
69+
@patch("oxygen.oxygen.RobotInterface")
70+
def test_cli_run_with_accepted_risk_level(self, mock_robot_iface):
71+
mock_robot_iface.return_value = self.mock
72+
73+
cmd_args = f"oxygen oxygen.zap {self.ZAP_XML} --accepted-risk-level 3"
74+
with patch.object(sys, "argv", cmd_args.split()):
75+
self.cli.run()
76+
77+
self.assertEqual(self.handler._config["accepted_risk_level"], 3)
78+
self.assertEqual(self.handler._config["required_confidence_level"], 1)
79+
80+
@patch("oxygen.oxygen.RobotInterface")
81+
def test_cli_run_with_required_confidence_level(self, mock_robot_iface):
82+
mock_robot_iface.return_value = self.mock
83+
84+
cmd_args = f"oxygen oxygen.zap {self.ZAP_XML} " "--required-confidence-level 3"
85+
with patch.object(sys, "argv", cmd_args.split()):
86+
self.cli.run()
87+
88+
self.assertEqual(self.handler._config["accepted_risk_level"], 2)
89+
self.assertEqual(self.handler._config["required_confidence_level"], 3)

0 commit comments

Comments
 (0)