3 # Copyright (c) 2016 Orange and others.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
19 from robot.errors import RobotError
21 from robot.utils.robottime import timestamp_to_secs
23 from functest.core import testcase
24 import functest.utils.functest_logger as ft_logger
25 import functest.utils.openstack_utils as op_utils
28 class ODLResultVisitor(robot.api.ResultVisitor):
33 def visit_test(self, test):
35 output['name'] = test.name
36 output['parent'] = test.parent.name
37 output['status'] = test.status
38 output['starttime'] = test.starttime
39 output['endtime'] = test.endtime
40 output['critical'] = test.critical
41 output['text'] = test.message
42 output['elapsedtime'] = test.elapsedtime
43 self._data.append(output)
49 class ODLTests(testcase.TestCase):
51 repos = "/home/opnfv/repos/"
52 odl_test_repo = os.path.join(repos, "odl_test")
53 neutron_suite_dir = os.path.join(odl_test_repo,
54 "csit/suites/openstack/neutron")
55 basic_suite_dir = os.path.join(odl_test_repo,
56 "csit/suites/integration/basic")
57 default_suites = [basic_suite_dir, neutron_suite_dir]
58 res_dir = '/home/opnfv/functest/results/odl/'
59 logger = ft_logger.Logger("opendaylight").getLogger()
62 testcase.TestCase.__init__(self)
63 self.case_name = "odl"
66 def set_robotframework_vars(cls, odlusername="admin", odlpassword="admin"):
67 odl_variables_files = os.path.join(cls.odl_test_repo,
68 'csit/variables/Variables.py')
70 for line in fileinput.input(odl_variables_files,
72 print re.sub("AUTH = .*",
73 ("AUTH = [u'" + odlusername + "', u'" +
77 except Exception as ex: # pylint: disable=broad-except
78 cls.logger.error("Cannot set ODL creds: %s", str(ex))
81 def parse_results(self):
82 xml_file = os.path.join(self.res_dir, 'output.xml')
83 result = robot.api.ExecutionResult(xml_file)
84 visitor = ODLResultVisitor()
86 self.criteria = result.suite.status
87 self.start_time = timestamp_to_secs(result.suite.starttime)
88 self.stop_time = timestamp_to_secs(result.suite.endtime)
90 self.details['description'] = result.suite.name
91 self.details['tests'] = visitor.get_data()
93 def main(self, suites=None, **kwargs):
96 suites = self.default_suites
97 odlusername = kwargs['odlusername']
98 odlpassword = kwargs['odlpassword']
99 osauthurl = kwargs['osauthurl']
100 keystoneip = urlparse.urlparse(osauthurl).hostname
101 variables = ['KEYSTONE:' + keystoneip,
102 'NEUTRON:' + kwargs['neutronip'],
103 'OS_AUTH_URL:"' + osauthurl + '"',
104 'OSUSERNAME:"' + kwargs['osusername'] + '"',
105 'OSTENANTNAME:"' + kwargs['ostenantname'] + '"',
106 'OSPASSWORD:"' + kwargs['ospassword'] + '"',
107 'ODL_SYSTEM_IP:' + kwargs['odlip'],
108 'PORT:' + kwargs['odlwebport'],
109 'RESTCONFPORT:' + kwargs['odlrestconfport']]
110 except KeyError as ex:
111 self.logger.error("Cannot run ODL testcases. Please check "
113 return self.EX_RUN_ERROR
114 if self.set_robotframework_vars(odlusername, odlpassword):
116 os.makedirs(self.res_dir)
117 except OSError as ex:
118 if ex.errno != errno.EEXIST:
119 self.logger.exception(
120 "Cannot create %s", self.res_dir)
121 return self.EX_RUN_ERROR
122 stdout_file = os.path.join(self.res_dir, 'stdout.txt')
123 output_dir = os.path.join(self.res_dir, 'output.xml')
124 with open(stdout_file, 'w+') as stdout:
125 robot.run(*suites, variable=variables,
131 self.logger.info("\n" + stdout.read())
132 self.logger.info("ODL results were successfully generated")
135 self.logger.info("ODL results were successfully parsed")
136 except RobotError as ex:
137 self.logger.error("Run tests before publishing: %s",
139 return self.EX_RUN_ERROR
141 os.remove(stdout_file)
143 self.logger.warning("Cannot remove %s", stdout_file)
146 return self.EX_RUN_ERROR
148 def run(self, **kwargs):
150 suites = self.default_suites
152 suites = kwargs["suites"]
155 neutron_url = op_utils.get_endpoint(service_type='network')
156 kwargs = {'neutronip': urlparse.urlparse(neutron_url).hostname}
157 kwargs['odlip'] = kwargs['neutronip']
158 kwargs['odlwebport'] = '8080'
159 kwargs['odlrestconfport'] = '8181'
160 kwargs['odlusername'] = 'admin'
161 kwargs['odlpassword'] = 'admin'
162 installer_type = None
163 if 'INSTALLER_TYPE' in os.environ:
164 installer_type = os.environ['INSTALLER_TYPE']
165 kwargs['osusername'] = os.environ['OS_USERNAME']
166 kwargs['ostenantname'] = os.environ['OS_TENANT_NAME']
167 kwargs['osauthurl'] = os.environ['OS_AUTH_URL']
168 kwargs['ospassword'] = os.environ['OS_PASSWORD']
169 if installer_type == 'fuel':
170 kwargs['odlwebport'] = '8282'
171 elif installer_type == 'apex' or installer_type == 'netvirt':
172 kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
173 kwargs['odlwebport'] = '8081'
174 kwargs['odlrestconfport'] = '8081'
175 elif installer_type == 'joid':
176 kwargs['odlip'] = os.environ['SDN_CONTROLLER']
177 elif installer_type == 'compass':
178 kwargs['odlwebport'] = '8181'
180 kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
181 except KeyError as ex:
182 self.logger.error("Cannot run ODL testcases. "
183 "Please check env var: "
185 return self.EX_RUN_ERROR
186 except Exception: # pylint: disable=broad-except
187 self.logger.exception("Cannot run ODL testcases.")
188 return self.EX_RUN_ERROR
190 return self.main(suites, **kwargs)
193 class ODLParser(object): # pylint: disable=too-few-public-methods
196 self.parser = argparse.ArgumentParser()
197 self.parser.add_argument(
198 '-n', '--neutronip', help='Neutron IP',
200 self.parser.add_argument(
201 '-k', '--osauthurl', help='OS_AUTH_URL as defined by OpenStack',
202 default='http://127.0.0.1:5000/v2.0')
203 self.parser.add_argument(
204 '-a', '--osusername', help='Username for OpenStack',
206 self.parser.add_argument(
207 '-b', '--ostenantname', help='Tenantname for OpenStack',
209 self.parser.add_argument(
210 '-c', '--ospassword', help='Password for OpenStack',
212 self.parser.add_argument(
213 '-o', '--odlip', help='OpenDaylight IP',
215 self.parser.add_argument(
216 '-w', '--odlwebport', help='OpenDaylight Web Portal Port',
218 self.parser.add_argument(
219 '-r', '--odlrestconfport', help='OpenDaylight RESTConf Port',
221 self.parser.add_argument(
222 '-d', '--odlusername', help='Username for ODL',
224 self.parser.add_argument(
225 '-e', '--odlpassword', help='Password for ODL',
227 self.parser.add_argument(
228 '-p', '--pushtodb', help='Push results to DB',
231 def parse_args(self, argv=None):
234 return vars(self.parser.parse_args(argv))
237 if __name__ == '__main__':
240 ARGS = PARSER.parse_args(sys.argv[1:])
242 RESULT = ODL.main(ODLTests.default_suites, **ARGS)
243 if RESULT != testcase.TestCase.EX_OK:
246 sys.exit(ODL.push_to_db())
247 except Exception: # pylint: disable=broad-except
248 sys.exit(testcase.TestCase.EX_RUN_ERROR)