Skip to content

Commit

Permalink
feat(config): add specific-to-handler config options to override conf…
Browse files Browse the repository at this point in the history
…ig entries
  • Loading branch information
matejc committed Aug 26, 2021
1 parent 8c3def1 commit 1d14a5b
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 28 deletions.
12 changes: 6 additions & 6 deletions example/my_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ class MyParser(BaseHandler):
{'name': 'My Test 2', 'passed': False, 'msg': 'Error text D:'}]
}

def run_my_tests(self, resultfile):
with open(resultfile, 'w') as f:
def run_my_tests(self, result_file):
with open(result_file, 'w') as f:
json.dump(self.RESULTS, f)
return resultfile
return result_file

def parse_results(self, resultfile):
with open(resultfile, 'r') as f:
def parse_results(self, result_file):
with open(result_file, 'r') as f:
results = json.load(f)
return {
'name': resultfile,
'name': result_file,
'tags': [],
'setup': None,
'teardown': None,
Expand Down
2 changes: 1 addition & 1 deletion src/oxygen/base_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .robot_interface import RobotInterface

class BaseHandler(object):
DEFAULT_CLI = {tuple(['resultfile']): {}}
DEFAULT_CLI = {tuple(['result_file']): {}}

def __init__(self, config):
'''
Expand Down
13 changes: 7 additions & 6 deletions src/oxygen/oxygen.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,10 @@ def parse_args(self, parser):
for flags, params in tool_handler.cli().items():
subcommand_parser.add_argument(*flags, **params)
subcommand_parser.set_defaults(func=tool_handler.parse_results)
return parser.parse_args()
return vars(parser.parse_args()) # returns a dictionary

def get_output_filename(self, resultfile):
filename = Path(resultfile)
def get_output_filename(self, result_file):
filename = Path(result_file)
filename = filename.with_suffix('.xml')
robot_name = filename.stem + '_robot_output' + filename.suffix
filename = filename.with_name(robot_name)
Expand All @@ -228,10 +228,11 @@ def run(self):
action='version',
version=f'%(prog)s {self.__version__}')
args = self.parse_args(parser)
if not vars(args):
if not args:
parser.error('No arguments given')
output_filename = self.get_output_filename(args.resultfile)
parsed_results = args.func(args.resultfile)
output_filename = self.get_output_filename(args['result_file'])
parsed_results = args['func'](
**{k: v for (k, v) in args.items() if not callable(v)})
robot_suite = RobotInterface().running.build_suite(parsed_results)
robot_suite.run(output=output_filename,
log=None,
Expand Down
21 changes: 19 additions & 2 deletions src/oxygen/zap.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,25 @@ def run_zap(self, result_file, command, check_return_code=False, **env):
logger.info('Result file: {}'.format(result_file))
return result_file


def parse_results(self, result_file):
def cli(self):
cli_interface = self.DEFAULT_CLI.copy()
cli_interface[('--accepted-risk-level',)] = {
'help': 'Set accepted risk level',
'type': int
}
cli_interface[('--required-confidence-level',)] = {
'help': 'Set required confidence level',
'type': int
}
return cli_interface

def parse_results(self, result_file, accepted_risk_level=None,
required_confidence_level=None):
if accepted_risk_level is not None:
self._config['accepted_risk_level'] = accepted_risk_level
if required_confidence_level is not None:
self._config['required_confidence_level'] = \
required_confidence_level
zap_dict = self._read_results(validate_path(result_file).resolve())
return self._parse_zap_dict(zap_dict)

Expand Down
23 changes: 15 additions & 8 deletions tests/utest/oxygen/test_oxygen_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from ..helpers import RESOURCES_PATH


class TestOxygenCLIEntryPoints(TestCase):
'''Coverage does not measure coverage correctly for these tests.
Expand All @@ -20,6 +21,7 @@ class TestOxygenCLIEntryPoints(TestCase):
Setting up Coverage to see subprocesses as well seems a lot of work and
quite a hack: https://coverage.readthedocs.io/en/latest/subprocess.html
'''

def test_main_level_entrypoint(self):
self.verify_cli_help_text('python -m oxygen --help')
self.verify_cli_help_text('python -m oxygen -h')
Expand All @@ -43,16 +45,20 @@ def verify_cli_help_text(self, cmd):

def test_junit_works_on_cli(self):
target = RESOURCES_PATH / 'green-junit-example.xml'
expected = target.with_name('green-junit-expected-robot-output.xml')
example = target.with_name('green-junit-expected-robot-output.xml')
actual = target.with_name('green-junit-example_robot_output.xml')
if actual.exists():
actual.unlink() # delete file if exists
actual.unlink() # delete file if exists

check_output(f'python -m oxygen oxygen.junit {target}',
text=True,
shell=True)

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

self.assertEqual(expected.read_text(), expected.read_text())

class TestOxygenCLI(TestCase):

Expand All @@ -62,8 +68,9 @@ def setUp(self):
@patch('oxygen.oxygen.RobotInterface')
@patch('oxygen.oxygen.OxygenCLI.parse_args')
def test_run(self, mock_parse_args, mock_robot_iface):
mock_parse_args.return_value = Mock(resultfile='path/to/file.xml',
func=lambda _: {'some': 'results'})
mock_parse_args.return_value = {
'result_file': 'path/to/file.xml',
'func': lambda *_, **__: {'some': 'results'}}
expected_suite = create_autospec(TestSuite)
mock = Mock()
mock.running.build_suite = Mock(return_value=expected_suite)
Expand Down
6 changes: 1 addition & 5 deletions tests/utest/zap/test_basic_functionality.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from pathlib import Path
from unittest import skip, TestCase
from unittest import TestCase
from unittest.mock import ANY, create_autospec, Mock, mock_open, patch

from testfixtures import compare

from oxygen.base_handler import BaseHandler
from oxygen.zap import ZAProxyHandler
from oxygen.errors import ZAProxyHandlerException
from ..helpers import (example_robot_output,
Expand Down Expand Up @@ -299,9 +298,6 @@ def test_parsing_json(self):
def assertNotNoneOrEmpty(self, str_):
return str_ is not None and str_ != ''

def test_cli(self):
self.assertEqual(self.handler.cli(), BaseHandler.DEFAULT_CLI)

@patch('oxygen.zap.ZAProxyHandler._report_oxygen_run')
def test_check_for_keyword(self, mock_report):
fake_test = example_robot_output().suite.suites[0].tests[4]
Expand Down
89 changes: 89 additions & 0 deletions tests/utest/zap/test_zap_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import sys
from unittest import TestCase
from unittest.mock import ANY, Mock, create_autospec, patch
from robot.running.model import TestSuite
from oxygen.oxygen import OxygenCLI
from ..helpers import RESOURCES_PATH


class TestOxygenZapCLI(TestCase):
ZAP_XML = str(RESOURCES_PATH / "zap" / "zap.xml")

def setUp(self):
self.cli = OxygenCLI()
self.handler = self.cli._handlers["oxygen.zap"]
self.expected_suite = create_autospec(TestSuite)
self.mock = Mock()
self.mock.running.build_suite = Mock(return_value=self.expected_suite)

def test_cli(self):
self.assertEqual(
self.handler.cli(),
{
("--accepted-risk-level",): {
"help": "Set accepted risk level",
"type": int,
},
("--required-confidence-level",): {
"help": "Set required confidence level",
"type": int,
},
("result_file",): {},
},
)

@patch("oxygen.oxygen.RobotInterface")
def test_cli_run(self, mock_robot_iface):
mock_robot_iface.return_value = self.mock

cmd_args = f"oxygen oxygen.zap {self.ZAP_XML}"
with patch.object(sys, "argv", cmd_args.split()):
self.cli.run()

self.assertEqual(self.handler._config["accepted_risk_level"], 2)
self.assertEqual(self.handler._config["required_confidence_level"], 1)

self.mock.running.build_suite.assert_called_once()

self.expected_suite.run.assert_called_once_with(
output=str(RESOURCES_PATH / "zap" / "zap_robot_output.xml"),
log=None,
report=None,
stdout=ANY,
)

@patch("oxygen.oxygen.RobotInterface")
def test_cli_run_with_levels(self, mock_robot_iface):
mock_robot_iface.return_value = self.mock

cmd_args = (
f"oxygen oxygen.zap {self.ZAP_XML} --accepted-risk-level 3"
" --required-confidence-level 3"
)
with patch.object(sys, "argv", cmd_args.split()):
self.cli.run()

self.assertEqual(self.handler._config["accepted_risk_level"], 3)
self.assertEqual(self.handler._config["required_confidence_level"], 3)

@patch("oxygen.oxygen.RobotInterface")
def test_cli_run_with_accepted_risk_level(self, mock_robot_iface):
mock_robot_iface.return_value = self.mock

cmd_args = f"oxygen oxygen.zap {self.ZAP_XML} --accepted-risk-level 3"
with patch.object(sys, "argv", cmd_args.split()):
self.cli.run()

self.assertEqual(self.handler._config["accepted_risk_level"], 3)
self.assertEqual(self.handler._config["required_confidence_level"], 1)

@patch("oxygen.oxygen.RobotInterface")
def test_cli_run_with_required_confidence_level(self, mock_robot_iface):
mock_robot_iface.return_value = self.mock

cmd_args = f"oxygen oxygen.zap {self.ZAP_XML} " "--required-confidence-level 3"
with patch.object(sys, "argv", cmd_args.split()):
self.cli.run()

self.assertEqual(self.handler._config["accepted_risk_level"], 2)
self.assertEqual(self.handler._config["required_confidence_level"], 3)

0 comments on commit 1d14a5b

Please sign in to comment.