From 6cc6cc701b183563a05393b212f150bca6584abf Mon Sep 17 00:00:00 2001 From: Cédric Ollivier Date: Mon, 27 Nov 2017 11:43:42 +0100 Subject: Create RobotFramework class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It moves the capability to run any robot script from ODL TestCase into a new class: RobotFramework. It updates ODL TestCase and the related unit tests to inherit from the new parent class. Change-Id: I73e59ee9652fb63d9d89d7c75c58cce9cf62b0d7 Signed-off-by: Cédric Ollivier --- functest/tests/unit/core/test_robotframework.py | 191 ++++++++++++++++++++++++ functest/tests/unit/odl/test_odl.py | 117 +-------------- 2 files changed, 195 insertions(+), 113 deletions(-) create mode 100644 functest/tests/unit/core/test_robotframework.py (limited to 'functest/tests') diff --git a/functest/tests/unit/core/test_robotframework.py b/functest/tests/unit/core/test_robotframework.py new file mode 100644 index 000000000..38e9039b2 --- /dev/null +++ b/functest/tests/unit/core/test_robotframework.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python + +# Copyright (c) 2017 Orange and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 + +"""Define the classes required to fully cover robot.""" + +import errno +import logging +import os +import unittest + +import mock +from robot.errors import DataError, RobotError +from robot.result import model +from robot.utils.robottime import timestamp_to_secs + +from functest.core import robotframework + +__author__ = "Cedric Ollivier " + + +class ResultVisitorTesting(unittest.TestCase): + + """The class testing ResultVisitor.""" + # pylint: disable=missing-docstring + + def setUp(self): + self.visitor = robotframework.ResultVisitor() + + def test_empty(self): + self.assertFalse(self.visitor.get_data()) + + def test_ok(self): + data = {'name': 'foo', + 'parent': 'bar', + 'status': 'PASS', + 'starttime': "20161216 16:00:00.000", + 'endtime': "20161216 16:00:01.000", + 'elapsedtime': 1000, + 'text': 'Hello, World!', + 'critical': True} + test = model.TestCase( + name=data['name'], status=data['status'], message=data['text'], + starttime=data['starttime'], endtime=data['endtime']) + test.parent = mock.Mock() + config = {'name': data['parent'], + 'criticality.test_is_critical.return_value': data[ + 'critical']} + test.parent.configure_mock(**config) + self.visitor.visit_test(test) + self.assertEqual(self.visitor.get_data(), [data]) + + +class ParseResultTesting(unittest.TestCase): + + """The class testing RobotFramework.parse_results().""" + # pylint: disable=missing-docstring + + _config = {'name': 'dummy', 'starttime': '20161216 16:00:00.000', + 'endtime': '20161216 16:00:01.000'} + + def setUp(self): + self.test = robotframework.RobotFramework( + case_name='robot', project_name='functest') + + @mock.patch('robot.api.ExecutionResult', side_effect=DataError) + def test_raises_exc(self, mock_method): + with self.assertRaises(DataError): + self.test.parse_results() + mock_method.assert_called_once_with( + os.path.join(self.test.res_dir, 'output.xml')) + + def _test_result(self, config, result): + suite = mock.Mock() + suite.configure_mock(**config) + with mock.patch('robot.api.ExecutionResult', + return_value=mock.Mock(suite=suite)): + self.test.parse_results() + self.assertEqual(self.test.result, result) + self.assertEqual(self.test.start_time, + timestamp_to_secs(config['starttime'])) + self.assertEqual(self.test.stop_time, + timestamp_to_secs(config['endtime'])) + self.assertEqual(self.test.details, + {'description': config['name'], 'tests': []}) + + def test_null_passed(self): + self._config.update({'statistics.critical.passed': 0, + 'statistics.critical.total': 20}) + self._test_result(self._config, 0) + + def test_no_test(self): + self._config.update({'statistics.critical.passed': 20, + 'statistics.critical.total': 0}) + self._test_result(self._config, 0) + + def test_half_success(self): + self._config.update({'statistics.critical.passed': 10, + 'statistics.critical.total': 20}) + self._test_result(self._config, 50) + + def test_success(self): + self._config.update({'statistics.critical.passed': 20, + 'statistics.critical.total': 20}) + self._test_result(self._config, 100) + + +class RunTesting(unittest.TestCase): + + """The class testing RobotFramework.run().""" + # pylint: disable=missing-docstring + + suites = ["foo"] + variable = [] + + def setUp(self): + self.test = robotframework.RobotFramework( + case_name='robot', project_name='functest') + + def test_exc_key_error(self): + self.assertEqual(self.test.run(), self.test.EX_RUN_ERROR) + + @mock.patch('robot.run') + def _test_makedirs_exc(self, *args): + with mock.patch.object(self.test, 'parse_results') as mock_method: + self.assertEqual( + self.test.run(suites=self.suites, variable=self.variable), + self.test.EX_RUN_ERROR) + args[0].assert_not_called() + mock_method.asser_not_called() + + @mock.patch('os.makedirs', side_effect=Exception) + def test_makedirs_exc(self, *args): + self._test_makedirs_exc() + args[0].assert_called_once_with(self.test.res_dir) + + @mock.patch('os.makedirs', side_effect=OSError) + def test_makedirs_oserror(self, *args): + self._test_makedirs_exc() + args[0].assert_called_once_with(self.test.res_dir) + + @mock.patch('robot.run') + def _test_makedirs(self, *args): + with mock.patch.object(self.test, 'parse_results') as mock_method: + self.assertEqual( + self.test.run(suites=self.suites, variable=self.variable), + self.test.EX_OK) + args[0].assert_called_once_with( + *self.suites, log='NONE', output=self.test.xml_file, + report='NONE', stdout=mock.ANY, variable=self.variable) + mock_method.assert_called_once_with() + + @mock.patch('os.makedirs', side_effect=OSError(errno.EEXIST, '')) + def test_makedirs_oserror17(self, *args): + self._test_makedirs() + args[0].assert_called_once_with(self.test.res_dir) + + @mock.patch('os.makedirs') + def test_makedirs(self, *args): + self._test_makedirs() + args[0].assert_called_once_with(self.test.res_dir) + + @mock.patch('robot.run') + def _test_parse_results(self, status, *args): + self.assertEqual( + self.test.run(suites=self.suites, variable=self.variable), status) + args[0].assert_called_once_with( + *self.suites, log='NONE', output=self.test.xml_file, + report='NONE', stdout=mock.ANY, variable=self.variable) + + def test_parse_results_exc(self): + with mock.patch.object(self.test, 'parse_results', + side_effect=Exception) as mock_method: + self._test_parse_results(self.test.EX_RUN_ERROR) + mock_method.assert_called_once_with() + + def test_parse_results_robot_error(self): + with mock.patch.object(self.test, 'parse_results', + side_effect=RobotError('foo')) as mock_method: + self._test_parse_results(self.test.EX_RUN_ERROR) + mock_method.assert_called_once_with() + + +if __name__ == "__main__": + logging.disable(logging.CRITICAL) + unittest.main(verbosity=2) diff --git a/functest/tests/unit/odl/test_odl.py b/functest/tests/unit/odl/test_odl.py index 7258cd5e1..a331a6f36 100644 --- a/functest/tests/unit/odl/test_odl.py +++ b/functest/tests/unit/odl/test_odl.py @@ -9,16 +9,13 @@ """Define the classes required to fully cover odl.""" -import errno import logging import os import unittest from keystoneauth1.exceptions import auth_plugins import mock -from robot.errors import DataError, RobotError -from robot.result import model -from robot.utils.robottime import timestamp_to_secs +from robot.errors import RobotError import six from six.moves import urllib @@ -28,38 +25,6 @@ from functest.opnfv_tests.sdn.odl import odl __author__ = "Cedric Ollivier " -class ODLVisitorTesting(unittest.TestCase): - - """The class testing ODLResultVisitor.""" - # pylint: disable=missing-docstring - - def setUp(self): - self.visitor = odl.ODLResultVisitor() - - def test_empty(self): - self.assertFalse(self.visitor.get_data()) - - def test_ok(self): - data = {'name': 'foo', - 'parent': 'bar', - 'status': 'PASS', - 'starttime': "20161216 16:00:00.000", - 'endtime': "20161216 16:00:01.000", - 'elapsedtime': 1000, - 'text': 'Hello, World!', - 'critical': True} - test = model.TestCase( - name=data['name'], status=data['status'], message=data['text'], - starttime=data['starttime'], endtime=data['endtime']) - test.parent = mock.Mock() - config = {'name': data['parent'], - 'criticality.test_is_critical.return_value': data[ - 'critical']} - test.parent.configure_mock(**config) - self.visitor.visit_test(test) - self.assertEqual(self.visitor.get_data(), [data]) - - class ODLTesting(unittest.TestCase): """The super class which testing classes could inherit.""" @@ -109,56 +74,6 @@ class ODLTesting(unittest.TestCase): 'pushtodb': False} -class ODLParseResultTesting(ODLTesting): - - """The class testing ODLTests.parse_results().""" - # pylint: disable=missing-docstring - - _config = {'name': 'dummy', 'starttime': '20161216 16:00:00.000', - 'endtime': '20161216 16:00:01.000'} - - @mock.patch('robot.api.ExecutionResult', side_effect=DataError) - def test_raises_exc(self, mock_method): - with self.assertRaises(DataError): - self.test.parse_results() - mock_method.assert_called_once_with( - os.path.join(odl.ODLTests.res_dir, 'output.xml')) - - def _test_result(self, config, result): - suite = mock.Mock() - suite.configure_mock(**config) - with mock.patch('robot.api.ExecutionResult', - return_value=mock.Mock(suite=suite)): - self.test.parse_results() - self.assertEqual(self.test.result, result) - self.assertEqual(self.test.start_time, - timestamp_to_secs(config['starttime'])) - self.assertEqual(self.test.stop_time, - timestamp_to_secs(config['endtime'])) - self.assertEqual(self.test.details, - {'description': config['name'], 'tests': []}) - - def test_null_passed(self): - self._config.update({'statistics.critical.passed': 0, - 'statistics.critical.total': 20}) - self._test_result(self._config, 0) - - def test_no_test(self): - self._config.update({'statistics.critical.passed': 20, - 'statistics.critical.total': 0}) - self._test_result(self._config, 0) - - def test_half_success(self): - self._config.update({'statistics.critical.passed': 10, - 'statistics.critical.total': 20}) - self._test_result(self._config, 50) - - def test_success(self): - self._config.update({'statistics.critical.passed': 20, - 'statistics.critical.total': 20}) - self._test_result(self._config, 100) - - class ODLRobotTesting(ODLTesting): """The class testing ODLTests.set_robotframework_vars().""" @@ -239,8 +154,7 @@ class ODLMainTesting(ODLTesting): kwargs = self._get_run_suites_kwargs() self.assertEqual(self.test.run_suites(**kwargs), status) if len(args) > 0: - args[0].assert_called_once_with( - odl.ODLTests.res_dir) + args[0].assert_called_once_with(self.test.res_dir) if len(args) > 1: variable = [ 'KEYSTONEURL:{}://{}'.format( @@ -260,13 +174,13 @@ class ODLMainTesting(ODLTesting): odl.ODLTests.basic_suite_dir, odl.ODLTests.neutron_suite_dir, log='NONE', - output=os.path.join(odl.ODLTests.res_dir, 'output.xml'), + output=os.path.join(self.test.res_dir, 'output.xml'), report='NONE', stdout=mock.ANY, variable=variable) if len(args) > 2: args[2].assert_called_with( - os.path.join(odl.ODLTests.res_dir, 'stdout.txt')) + os.path.join(self.test.res_dir, 'stdout.txt')) def _test_no_keyword(self, key): kwargs = self._get_run_suites_kwargs(key) @@ -310,21 +224,6 @@ class ODLMainTesting(ODLTesting): mock_object.assert_called_once_with( self._odl_username, self._odl_password) - @mock.patch('os.makedirs', side_effect=Exception) - def test_makedirs_exc(self, mock_method): - with mock.patch.object(self.test, 'set_robotframework_vars', - return_value=True), \ - self.assertRaises(Exception): - self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, - mock_method) - - @mock.patch('os.makedirs', side_effect=OSError) - def test_makedirs_oserror(self, mock_method): - with mock.patch.object(self.test, 'set_robotframework_vars', - return_value=True): - self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, - mock_method) - @mock.patch('robot.run', side_effect=RobotError) @mock.patch('os.makedirs') def test_run_ko(self, *args): @@ -350,14 +249,6 @@ class ODLMainTesting(ODLTesting): mock.patch.object(self.test, 'parse_results'): self._test_run_suites(testcase.TestCase.EX_OK, *args) - @mock.patch('robot.run') - @mock.patch('os.makedirs', side_effect=OSError(errno.EEXIST, '')) - def test_makedirs_oserror17(self, *args): - with mock.patch.object(self.test, 'set_robotframework_vars', - return_value=True), \ - mock.patch.object(self.test, 'parse_results'): - self._test_run_suites(testcase.TestCase.EX_OK, *args) - @mock.patch('robot.run', return_value=1) @mock.patch('os.makedirs') def test_testcases_in_failure(self, *args): -- cgit 1.2.3-korg