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
39 changes: 35 additions & 4 deletions src/oxygen/base_handler.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import re

from inspect import signature, Parameter

from oxygen.errors import MismatchArgumentException
from .robot_interface import (RobotInterface, get_keywords_from,
set_special_keyword)

Expand Down Expand Up @@ -100,14 +103,42 @@ def _build_results(self, keyword, setup_keyword, teardown_keyword):
setup_keyword: The special oxygen setup wrapper
teardown_keyword: The special oxygen teardown wrapper
'''
test = keyword.parent
test_results = self.parse_results(self.run_time_data)
end_time, result_suite = self._interface.result.build_suite(100000,
test_results)
accepted_params = signature(self.parse_results).parameters
accepted_params_max = len(accepted_params)
accepted_params_min = len([
n for n, v in accepted_params.items()
if v.default == Parameter.empty])
is_multiple_inputs = isinstance(self.run_time_data, tuple)

# there are multiple inputs and in the range of accepted min and max
if is_multiple_inputs and (accepted_params_min <= len(
self.run_time_data) <= accepted_params_max):
test_results = self.parse_results(*self.run_time_data)

# there is single input and one required, also can be more non-required
elif not is_multiple_inputs and accepted_params_min == 1:
test_results = self.parse_results(self.run_time_data)

# else if there are multiple inputs and not in the range of accepted
elif is_multiple_inputs:
raise MismatchArgumentException(
f'parse_results expects at least {accepted_params_min} and'
f' at most {accepted_params_max} arguments '
f'but got {len(self.run_time_data)}')

# at this point there could be only multiple required and single input
else:
raise MismatchArgumentException(
f'parse_results expects at least {accepted_params_min} '
'arguments but got 1')

_, result_suite = self._interface.result.build_suite(
100000, test_results)

if not result_suite:
return

test = keyword.parent
self._set_suite_tags(result_suite, *(self._tags + list(test.tags)))

if setup_keyword:
Expand Down
4 changes: 4 additions & 0 deletions src/oxygen/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ class ResultFileNotFoundException(Exception):

class ResultFileIsNotAFileException(Exception):
pass


class MismatchArgumentException(Exception):
pass
51 changes: 51 additions & 0 deletions tests/resources/example_robot_output.xml
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,56 @@
</tags>
<status status="PASS" starttime="20200506 17:39:30.140" endtime="20200506 17:39:30.142" critical="yes"></status>
</test>
<test id="s1-s1-t7" name="My Fifth Test">
<kw name="Log" library="BuiltIn">
<doc>Logs the given message with the given level.</doc>
<arguments>
<arg>My Dummy Handler Setup Here 1</arg>
</arguments>
<msg timestamp="20200506 17:39:28.028" level="INFO">My Dummy Handler Setup Here 1</msg>
<status status="PASS" starttime="20200506 17:39:28.028" endtime="20200506 17:39:28.029"></status>
</kw>
<kw name="Log" library="BuiltIn">
<doc>Logs the given message with the given level.</doc>
<arguments>
<arg>My Dummy Handler Setup Here 2</arg>
</arguments>
<msg timestamp="20200506 17:39:28.029" level="INFO">My Dummy Handler Setup Here 2</msg>
<status status="PASS" starttime="20200506 17:39:28.029" endtime="20200506 17:39:28.029"></status>
</kw>
<kw name="Run My Dummy Handler" library="oxygen.OxygenLibrary">
<doc>Run My Dummy Handler tool specified with ``command``.</doc>
<arguments>
<arg>${RESOURCES}/my_dummy_handler.xml</arg>
<arg>echo</arg>
<arg>MY_DUMMY_HANDLER_TEST_STRING</arg>
</arguments>
<msg timestamp="20200506 17:39:28.041" level="INFO">MY_DUMMY_HANDLER_TEST_STRING
</msg>
<msg timestamp="20200506 17:39:28.041" level="INFO">Result file: /Users/tkairi/Coding/oxygen/tests/atest/../resources/my_dummy_handler.xml</msg>
<status status="PASS" starttime="20200506 17:39:28.029" endtime="20200506 17:39:28.041"></status>
</kw>
<kw name="Log" library="BuiltIn">
<doc>Logs the given message with the given level.</doc>
<arguments>
<arg>My Dummy Handler Teardown Here 1</arg>
</arguments>
<msg timestamp="20200506 17:39:28.042" level="INFO">My Dummy Handler Teardown Here 1</msg>
<status status="PASS" starttime="20200506 17:39:28.042" endtime="20200506 17:39:28.042"></status>
</kw>
<kw name="Log" library="BuiltIn">
<doc>Logs the given message with the given level.</doc>
<arguments>
<arg>My Dummy Handler Teardown Here 2</arg>
</arguments>
<msg timestamp="20200506 17:39:28.043" level="INFO">My Dummy Handler Teardown Here 2</msg>
<status status="PASS" starttime="20200506 17:39:28.043" endtime="20200506 17:39:28.043"></status>
</kw>
<tags>
<tag>MY_DUMMY_HANDLER_ROBOT_TAG</tag>
</tags>
<status status="PASS" starttime="20200506 17:39:28.028" endtime="20200506 17:39:28.043" critical="yes"></status>
</test>
<status status="PASS" starttime="20200506 17:39:27.974" endtime="20200506 17:39:30.143"></status>
</suite>
<status status="PASS" starttime="20200506 17:39:27.937" endtime="20200506 17:39:30.146"></status>
Expand All @@ -272,6 +322,7 @@
<stat pass="2" fail="0">JUNIT_ROBOT_TAG</stat>
<stat pass="1" fail="0">NO_OXYGEN_HERE</stat>
<stat pass="2" fail="0">ZAP_ROBOT_TAG</stat>
<stat pass="2" fail="0">MY_DUMMY_HANDLER_ROBOT_TAG</stat>
</tag>
<suite>
<stat pass="6" fail="0" id="s1" name="Atest">Atest</stat>
Expand Down
Empty file.
17 changes: 17 additions & 0 deletions tests/resources/my_dummy_handlers/dummy_handler_default_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from oxygen import BaseHandler


class MyDummyHandler(BaseHandler):
'''
A test handler that throws mismatch argument exception if single argument
is passed with multiple accepted
'''

def run_my_dummy_handler(self, result_file):
return result_file

def parse_results(self, result_file, foo='foo'):
return {
'name': result_file,
'foo': foo
}
17 changes: 17 additions & 0 deletions tests/resources/my_dummy_handlers/dummy_handler_multiple_args.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from oxygen import BaseHandler


class MyDummyHandler(BaseHandler):
'''
A test handler for unfolding parse_results arguments
if it has multiple parameters
'''

def run_my_dummy_handler(self, result_file):
return result_file, 'foo'

def parse_results(self, result_file, foo):
return {
'name': result_file,
'foo': foo
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from oxygen import BaseHandler


class MyDummyHandler(BaseHandler):
'''
A test handler that throws mismatch argument exception because
parse_results expects too many arguments
'''

def run_my_dummy_handler(self, result_file):
return result_file, 'foo'

def parse_results(self, result_file, foo, bar):
return {
'name': result_file,
'foo': foo,
'bar': bar
}
15 changes: 15 additions & 0 deletions tests/resources/my_dummy_handlers/dummy_handler_single_arg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from oxygen import BaseHandler


class MyDummyHandler(BaseHandler):
'''
A test handler for passing tuple if parse_results accepts one parameter
'''

def run_my_dummy_handler(self, result_file):
return result_file, 'foo'

def parse_results(self, result_file):
return {
'name': result_file
}
4 changes: 4 additions & 0 deletions tests/utest/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
tags: ZAP
accepted_risk_level: 2
required_confidence_level: 1
oxygen.my_dummy_handler:
handler: MyDummyHandler
keyword: run_my_dummy_handler
tags: MY_DUMMY_HANDLER
'''

RESOURCES_PATH = Path.cwd() / 'tests' / 'resources'
Expand Down
Empty file.
150 changes: 150 additions & 0 deletions tests/utest/my_dummy_handler/test_basic_functionality.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import sys
from unittest import TestCase
from oxygen.errors import MismatchArgumentException
from ..helpers import RESOURCES_PATH, get_config, example_robot_output

sys.path.append(str(RESOURCES_PATH / 'my_dummy_handlers'))

from dummy_handler_single_arg import (
MyDummyHandler as DummyHandlerSingleArg,
)
from dummy_handler_multiple_args import (
MyDummyHandler as DummyHandlerMultipleArgs,
)
from dummy_handler_multiple_args_too_few import (
MyDummyHandler as DummyHandlerMultipleArgsTooFew,
)
from dummy_handler_default_params import (
MyDummyHandler as DummyHandlerDefaultParams,
)


class DummyHandlerSingleArgTests(TestCase):
'''
A test for passing tuple if parse_results accepts one parameter
'''

def setUp(self):
self.handler = DummyHandlerSingleArg(
get_config()['oxygen.my_dummy_handler']
)

def test_run_my_dummy_handler(self):
return_value = self.handler.run_my_dummy_handler('/some/path/to.ext')
self.assertTupleEqual(return_value, ('/some/path/to.ext', 'foo'))

def test_parse_results(self):
fake_test = example_robot_output().suite.suites[0].tests[6]
expected_data = {'Atest.Test.My Fifth Test': '/some/path/to.ext'}

self.handler.check_for_keyword(fake_test, expected_data)

self.assertEqual(self.handler.run_time_data, '/some/path/to.ext')


class DummyHandlerMultipleArgsTests(TestCase):
'''
A test for unfolding parse_results arguments
if it has multiple parameters
'''

def setUp(self):
self.handler = DummyHandlerMultipleArgs(
get_config()['oxygen.my_dummy_handler']
)

def test_parse_results(self):
fake_test = example_robot_output().suite.suites[0].tests[6]
expected_data = {
'Atest.Test.My Fifth Test': ('/some/path/to.ext', 'foo')
}

self.handler.check_for_keyword(fake_test, expected_data)

self.assertEqual(
self.handler.run_time_data, ('/some/path/to.ext', 'foo')
)


class DummyHandlerMultipleArgsTooFewTests(TestCase):
'''
A test for testing if it throws mismatch argument exception because
parse_results expects too many arguments
'''

def setUp(self):
self.handler = DummyHandlerMultipleArgsTooFew(
get_config()['oxygen.my_dummy_handler']
)

def test_parse_results(self):
fake_test = example_robot_output().suite.suites[0].tests[6]
expected_data = {
'Atest.Test.My Fifth Test': ('/some/path/to.ext', 'foo')
}

self.assertRaises(
MismatchArgumentException,
self.handler.check_for_keyword,
fake_test,
expected_data,
)


class DummyHandlerMultipleArgsSingleTests(TestCase):
'''
A test for testing if it throws mismatch argument exception because
parse_results expects multiple arguments but we do not pass multiple
'''

def setUp(self):
self.handler = DummyHandlerMultipleArgsTooFew(
get_config()['oxygen.my_dummy_handler']
)

def test_parse_results(self):
fake_test = example_robot_output().suite.suites[0].tests[6]
expected_data = {'Atest.Test.My Fifth Test': 'some/path/to.ext'}

self.assertRaises(
MismatchArgumentException,
self.handler.check_for_keyword,
fake_test,
expected_data,
)


class DummyHandlerDefaultParamsTests(TestCase):
'''
A test for testing arguments with defaults
'''

def setUp(self):
self.handler = DummyHandlerDefaultParams(
get_config()['oxygen.my_dummy_handler']
)

def test_parse_results_with_one(self):
fake_test = example_robot_output().suite.suites[0].tests[6]
expected_data = {'Atest.Test.My Fifth Test': 'some/path/to.ext'}
self.handler.check_for_keyword(fake_test, expected_data)
self.assertEqual(self.handler.run_time_data, 'some/path/to.ext')

def test_parse_results_with_multiple(self):
fake_test = example_robot_output().suite.suites[0].tests[6]
expected_data = {
'Atest.Test.My Fifth Test': ('some/path/to.ext', 'foo')}
self.handler.check_for_keyword(fake_test, expected_data)
self.assertTupleEqual(
self.handler.run_time_data, ('some/path/to.ext', 'foo'))

def test_parse_results_with_too_many(self):
fake_test = example_robot_output().suite.suites[0].tests[6]
expected_data = {
'Atest.Test.My Fifth Test': ('some/path/to.ext', 'foo', 'bar')}
self.assertRaises(
MismatchArgumentException,
self.handler.check_for_keyword,
fake_test,
expected_data,
)