Merge "Fix pylint warnings in odl"
[functest.git] / functest / opnfv_tests / sdn / odl / odl.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2016 Orange and others.
4 #
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
9
10 import argparse
11 import errno
12 import fileinput
13 import os
14 import re
15 import sys
16 import urlparse
17
18 import robot.api
19 from robot.errors import RobotError
20 import robot.run
21 from robot.utils.robottime import timestamp_to_secs
22
23 from functest.core import testcase
24 import functest.utils.functest_logger as ft_logger
25 import functest.utils.openstack_utils as op_utils
26
27
28 class ODLResultVisitor(robot.api.ResultVisitor):
29
30     def __init__(self):
31         self._data = []
32
33     def visit_test(self, test):
34         output = {}
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)
44
45     def get_data(self):
46         return self._data
47
48
49 class ODLTests(testcase.TestCase):
50
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()
60
61     def __init__(self):
62         testcase.TestCase.__init__(self)
63         self.case_name = "odl"
64
65     @classmethod
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')
69         try:
70             for line in fileinput.input(odl_variables_files,
71                                         inplace=True):
72                 print re.sub("AUTH = .*",
73                              ("AUTH = [u'" + odlusername + "', u'" +
74                               odlpassword + "']"),
75                              line.rstrip())
76             return True
77         except Exception as ex:  # pylint: disable=broad-except
78             cls.logger.error("Cannot set ODL creds: %s", str(ex))
79             return False
80
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()
85         result.visit(visitor)
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)
89         self.details = {}
90         self.details['description'] = result.suite.name
91         self.details['tests'] = visitor.get_data()
92
93     def main(self, suites=None, **kwargs):
94         try:
95             if not suites:
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 "
112                               "%s", str(ex))
113             return self.EX_RUN_ERROR
114         if self.set_robotframework_vars(odlusername, odlpassword):
115             try:
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,
126                           output=output_dir,
127                           log='NONE',
128                           report='NONE',
129                           stdout=stdout)
130                 stdout.seek(0, 0)
131                 self.logger.info("\n" + stdout.read())
132             self.logger.info("ODL results were successfully generated")
133             try:
134                 self.parse_results()
135                 self.logger.info("ODL results were successfully parsed")
136             except RobotError as ex:
137                 self.logger.error("Run tests before publishing: %s",
138                                   ex.message)
139                 return self.EX_RUN_ERROR
140             try:
141                 os.remove(stdout_file)
142             except OSError:
143                 self.logger.warning("Cannot remove %s", stdout_file)
144             return self.EX_OK
145         else:
146             return self.EX_RUN_ERROR
147
148     def run(self, **kwargs):
149         try:
150             suites = self.default_suites
151             try:
152                 suites = kwargs["suites"]
153             except KeyError:
154                 pass
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'
179             else:
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: "
184                               "%s", str(ex))
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
189
190         return self.main(suites, **kwargs)
191
192
193 class ODLParser(object):  # pylint: disable=too-few-public-methods
194
195     def __init__(self):
196         self.parser = argparse.ArgumentParser()
197         self.parser.add_argument(
198             '-n', '--neutronip', help='Neutron IP',
199             default='127.0.0.1')
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',
205             default='admin')
206         self.parser.add_argument(
207             '-b', '--ostenantname', help='Tenantname for OpenStack',
208             default='admin')
209         self.parser.add_argument(
210             '-c', '--ospassword', help='Password for OpenStack',
211             default='admin')
212         self.parser.add_argument(
213             '-o', '--odlip', help='OpenDaylight IP',
214             default='127.0.0.1')
215         self.parser.add_argument(
216             '-w', '--odlwebport', help='OpenDaylight Web Portal Port',
217             default='8080')
218         self.parser.add_argument(
219             '-r', '--odlrestconfport', help='OpenDaylight RESTConf Port',
220             default='8181')
221         self.parser.add_argument(
222             '-d', '--odlusername', help='Username for ODL',
223             default='admin')
224         self.parser.add_argument(
225             '-e', '--odlpassword', help='Password for ODL',
226             default='admin')
227         self.parser.add_argument(
228             '-p', '--pushtodb', help='Push results to DB',
229             action='store_true')
230
231     def parse_args(self, argv=None):
232         if not argv:
233             argv = []
234         return vars(self.parser.parse_args(argv))
235
236
237 if __name__ == '__main__':
238     ODL = ODLTests()
239     PARSER = ODLParser()
240     ARGS = PARSER.parse_args(sys.argv[1:])
241     try:
242         RESULT = ODL.main(ODLTests.default_suites, **ARGS)
243         if RESULT != testcase.TestCase.EX_OK:
244             sys.exit(RESULT)
245         if ARGS['pushtodb']:
246             sys.exit(ODL.push_to_db())
247     except Exception:  # pylint: disable=broad-except
248         sys.exit(testcase.TestCase.EX_RUN_ERROR)