Merge "Update tempest to the latest 15.0.0"
[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_base
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_base.TestcaseBase):
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_base.TestcaseBase.__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 e:
78             cls.logger.error("Cannot set ODL creds: %s" % str(e))
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=default_suites, **kwargs):
94         try:
95             odlusername = kwargs['odlusername']
96             odlpassword = kwargs['odlpassword']
97             osauthurl = kwargs['osauthurl']
98             keystoneip = urlparse.urlparse(osauthurl).hostname
99             variables = ['KEYSTONE:' + keystoneip,
100                          'NEUTRON:' + kwargs['neutronip'],
101                          'OS_AUTH_URL:"' + osauthurl + '"',
102                          'OSUSERNAME:"' + kwargs['osusername'] + '"',
103                          'OSTENANTNAME:"' + kwargs['ostenantname'] + '"',
104                          'OSPASSWORD:"' + kwargs['ospassword'] + '"',
105                          'ODL_SYSTEM_IP:' + kwargs['odlip'],
106                          'PORT:' + kwargs['odlwebport'],
107                          'RESTCONFPORT:' + kwargs['odlrestconfport']]
108         except KeyError as e:
109             self.logger.error("Cannot run ODL testcases. Please check "
110                               "%s" % str(e))
111             return self.EX_RUN_ERROR
112         if self.set_robotframework_vars(odlusername, odlpassword):
113             try:
114                 os.makedirs(self.res_dir)
115             except OSError as e:
116                 if e.errno != errno.EEXIST:
117                     self.logger.exception(
118                         "Cannot create {}".format(self.res_dir))
119                     return self.EX_RUN_ERROR
120             stdout_file = os.path.join(self.res_dir, 'stdout.txt')
121             output_dir = os.path.join(self.res_dir, 'output.xml')
122             with open(stdout_file, 'w+') as stdout:
123                 robot.run(*suites, variable=variables,
124                           output=output_dir,
125                           log='NONE',
126                           report='NONE',
127                           stdout=stdout)
128                 stdout.seek(0, 0)
129                 self.logger.info("\n" + stdout.read())
130             self.logger.info("ODL results were successfully generated")
131             try:
132                 self.parse_results()
133                 self.logger.info("ODL results were successfully parsed")
134             except RobotError as e:
135                 self.logger.error("Run tests before publishing: %s" %
136                                   e.message)
137                 return self.EX_RUN_ERROR
138             try:
139                 os.remove(stdout_file)
140             except OSError:
141                 self.logger.warning("Cannot remove {}".format(stdout_file))
142             return self.EX_OK
143         else:
144             return self.EX_RUN_ERROR
145
146     def run(self, **kwargs):
147         try:
148             suites = self.default_suites
149             try:
150                 suites = kwargs["suites"]
151             except KeyError:
152                 pass
153             neutron_url = op_utils.get_endpoint(service_type='network')
154             kwargs = {'neutronip': urlparse.urlparse(neutron_url).hostname}
155             kwargs['odlip'] = kwargs['neutronip']
156             kwargs['odlwebport'] = '8080'
157             kwargs['odlrestconfport'] = '8181'
158             kwargs['odlusername'] = 'admin'
159             kwargs['odlpassword'] = 'admin'
160             installer_type = None
161             if 'INSTALLER_TYPE' in os.environ:
162                 installer_type = os.environ['INSTALLER_TYPE']
163             kwargs['osusername'] = os.environ['OS_USERNAME']
164             kwargs['ostenantname'] = os.environ['OS_TENANT_NAME']
165             kwargs['osauthurl'] = os.environ['OS_AUTH_URL']
166             kwargs['ospassword'] = os.environ['OS_PASSWORD']
167             if installer_type == 'fuel':
168                 kwargs['odlwebport'] = '8282'
169             elif installer_type == 'apex' or installer_type == 'netvirt':
170                 kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
171                 kwargs['odlwebport'] = '8081'
172                 kwargs['odlrestconfport'] = '8081'
173             elif installer_type == 'joid':
174                 kwargs['odlip'] = os.environ['SDN_CONTROLLER']
175             elif installer_type == 'compass':
176                 kwargs['odlwebport'] = '8181'
177             else:
178                 kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
179         except KeyError as e:
180             self.logger.error("Cannot run ODL testcases. "
181                               "Please check env var: "
182                               "%s" % str(e))
183             return self.EX_RUN_ERROR
184         except Exception:
185             self.logger.exception("Cannot run ODL testcases.")
186             return self.EX_RUN_ERROR
187
188         return self.main(suites, **kwargs)
189
190
191 class ODLParser(object):
192
193     def __init__(self):
194         self.parser = argparse.ArgumentParser()
195         self.parser.add_argument(
196             '-n', '--neutronip', help='Neutron IP',
197             default='127.0.0.1')
198         self.parser.add_argument(
199             '-k', '--osauthurl', help='OS_AUTH_URL as defined by OpenStack',
200             default='http://127.0.0.1:5000/v2.0')
201         self.parser.add_argument(
202             '-a', '--osusername', help='Username for OpenStack',
203             default='admin')
204         self.parser.add_argument(
205             '-b', '--ostenantname', help='Tenantname for OpenStack',
206             default='admin')
207         self.parser.add_argument(
208             '-c', '--ospassword', help='Password for OpenStack',
209             default='admin')
210         self.parser.add_argument(
211             '-o', '--odlip', help='OpenDaylight IP',
212             default='127.0.0.1')
213         self.parser.add_argument(
214             '-w', '--odlwebport', help='OpenDaylight Web Portal Port',
215             default='8080')
216         self.parser.add_argument(
217             '-r', '--odlrestconfport', help='OpenDaylight RESTConf Port',
218             default='8181')
219         self.parser.add_argument(
220             '-d', '--odlusername', help='Username for ODL',
221             default='admin')
222         self.parser.add_argument(
223             '-e', '--odlpassword', help='Password for ODL',
224             default='admin')
225         self.parser.add_argument(
226             '-p', '--pushtodb', help='Push results to DB',
227             action='store_true')
228
229     def parse_args(self, argv=[]):
230         return vars(self.parser.parse_args(argv))
231
232
233 if __name__ == '__main__':
234     odl = ODLTests()
235     parser = ODLParser()
236     args = parser.parse_args(sys.argv[1:])
237     try:
238         result = odl.main(ODLTests.default_suites, **args)
239         if result != testcase_base.TestcaseBase.EX_OK:
240             sys.exit(result)
241         if args['pushtodb']:
242             sys.exit(odl.push_to_db())
243     except Exception:
244         sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)