bc9f1bb7fb8fbf08cb4cbd41b280b87e152bcea5
[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 from robot.api import ExecutionResult, ResultVisitor
19 from robot.errors import RobotError
20 import robot.run
21 from robot.utils.robottime import timestamp_to_secs
22
23 import functest.core.testcase_base as testcase_base
24 import functest.utils.functest_logger as ft_logger
25 import functest.utils.openstack_utils as op_utils
26 import functest.utils.functest_constants as ft_constants
27
28
29 class ODLResultVisitor(ResultVisitor):
30
31     def __init__(self):
32         self._data = []
33
34     def visit_test(self, test):
35         output = {}
36         output['name'] = test.name
37         output['parent'] = test.parent.name
38         output['status'] = test.status
39         output['startime'] = test.starttime
40         output['endtime'] = test.endtime
41         output['critical'] = test.critical
42         output['text'] = test.message
43         output['elapsedtime'] = test.elapsedtime
44         self._data.append(output)
45
46     def get_data(self):
47         return self._data
48
49
50 class ODLTests(testcase_base.TestcaseBase):
51
52     repos = ft_constants.REPOS_DIR
53     odl_test_repo = os.path.join(repos, "odl_test")
54     neutron_suite_dir = os.path.join(odl_test_repo,
55                                      "csit/suites/openstack/neutron")
56     basic_suite_dir = os.path.join(odl_test_repo,
57                                    "csit/suites/integration/basic")
58     res_dir = os.path.join(ft_constants.FUNCTEST_RESULTS_DIR, "odl")
59
60     logger = ft_logger.Logger("opendaylight").getLogger()
61
62     def __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         output_dir = os.path.join(self.res_dir, 'output.xml')
83         result = ExecutionResult(output_dir)
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         return self.criteria
93
94     def main(self, **kwargs):
95         dirs = [self.basic_suite_dir, self.neutron_suite_dir]
96         try:
97             odlusername = kwargs['odlusername']
98             odlpassword = kwargs['odlpassword']
99             variables = ['KEYSTONE:' + kwargs['keystoneip'],
100                          'NEUTRON:' + kwargs['neutronip'],
101                          'OSUSERNAME:"' + kwargs['osusername'] + '"',
102                          'OSTENANTNAME:"' + kwargs['ostenantname'] + '"',
103                          'OSPASSWORD:"' + kwargs['ospassword'] + '"',
104                          'ODL_SYSTEM_IP:' + kwargs['odlip'],
105                          'PORT:' + kwargs['odlwebport'],
106                          'RESTCONFPORT:' + kwargs['odlrestconfport']]
107         except KeyError as e:
108             self.logger.error("Cannot run ODL testcases. Please check "
109                               "%s" % str(e))
110             return self.EX_RUN_ERROR
111         if self.set_robotframework_vars(odlusername, odlpassword):
112             try:
113                 os.makedirs(self.res_dir)
114             except OSError as e:
115                 if e.errno != errno.EEXIST:
116                     self.logger.exception(
117                         "Cannot create {}".format(self.res_dir))
118                     return self.EX_RUN_ERROR
119             stdout_file = os.path.join(self.res_dir, 'stdout.txt')
120             output_dir = os.path.join(self.res_dir, 'output.xml')
121             with open(stdout_file, 'w+') as stdout:
122                 robot.run(*dirs, variable=variables,
123                           output=output_dir,
124                           log='NONE',
125                           report='NONE',
126                           stdout=stdout)
127                 stdout.seek(0, 0)
128                 self.logger.info("\n" + stdout.read())
129             self.logger.info("ODL results were successfully generated")
130             try:
131                 test_res = self.parse_results()
132                 self.logger.info("ODL results were successfully parsed")
133                 if test_res is not "PASS":
134                     return self.EX_RUN_ERROR
135             except RobotError as e:
136                 self.logger.error("Run tests before publishing: %s" %
137                                   e.message)
138                 return self.EX_RUN_ERROR
139             try:
140                 os.remove(stdout_file)
141             except OSError:
142                 self.logger.warning("Cannot remove {}".format(stdout_file))
143             return self.EX_OK
144         else:
145             return self.EX_RUN_ERROR
146
147     def run(self):
148         try:
149             keystone_url = op_utils.get_endpoint(service_type='identity')
150             neutron_url = op_utils.get_endpoint(service_type='network')
151             kwargs = {'keystoneip': urlparse.urlparse(keystone_url).hostname}
152             kwargs['neutronip'] = urlparse.urlparse(neutron_url).hostname
153             kwargs['odlip'] = kwargs['neutronip']
154             kwargs['odlwebport'] = '8080'
155             kwargs['odlrestconfport'] = '8181'
156             kwargs['odlusername'] = 'admin'
157             kwargs['odlpassword'] = 'admin'
158
159             installer_type = ft_constants.CI_INSTALLER_TYPE
160             kwargs['osusername'] = ft_constants.OS_USERNAME
161             kwargs['ostenantname'] = ft_constants.OS_TENANT_NAME
162             kwargs['ospassword'] = ft_constants.OS_PASSWORD
163
164             if installer_type == 'fuel':
165                 kwargs['odlwebport'] = '8282'
166             elif installer_type == 'apex':
167                 if ft_constants.SDN_CONTROLLER_IP is None:
168                     return self.EX_RUN_ERROR
169                 kwargs['odlip'] = ft_constants.SDN_CONTROLLER_IP
170                 kwargs['odlwebport'] = '8181'
171             elif installer_type == 'joid':
172                 if ft_constants.SDN_CONTROLLER is None:
173                     return self.EX_RUN_ERROR
174                 kwargs['odlip'] = ft_constants.SDN_CONTROLLER
175             elif installer_type == 'compass':
176                 kwargs['odlwebport'] = '8181'
177             else:
178                 if ft_constants.SDN_CONTROLLER_IP is None:
179                     return self.EX_RUN_ERROR
180                 kwargs['odlip'] = ft_constants.SDN_CONTROLLER_IP
181         except KeyError as e:
182             self.logger.error("Cannot run ODL testcases. "
183                               "Please check env var: "
184                               "%s" % str(e))
185             return self.EX_RUN_ERROR
186         except Exception:
187             self.logger.exception("Cannot run ODL testcases.")
188             return self.EX_RUN_ERROR
189
190         return self.main(**kwargs)
191
192
193 if __name__ == '__main__':
194     parser = argparse.ArgumentParser()
195     parser.add_argument('-k', '--keystoneip',
196                         help='Keystone IP',
197                         default='127.0.0.1')
198     parser.add_argument('-n', '--neutronip',
199                         help='Neutron IP',
200                         default='127.0.0.1')
201     parser.add_argument('-a', '--osusername',
202                         help='Username for OpenStack',
203                         default='admin')
204     parser.add_argument('-b', '--ostenantname',
205                         help='Tenantname for OpenStack',
206                         default='admin')
207     parser.add_argument('-c', '--ospassword',
208                         help='Password for OpenStack',
209                         default='admin')
210     parser.add_argument('-o', '--odlip',
211                         help='OpenDaylight IP',
212                         default='127.0.0.1')
213     parser.add_argument('-w', '--odlwebport',
214                         help='OpenDaylight Web Portal Port',
215                         default='8080')
216     parser.add_argument('-r', '--odlrestconfport',
217                         help='OpenDaylight RESTConf Port',
218                         default='8181')
219     parser.add_argument('-d', '--odlusername',
220                         help='Username for ODL',
221                         default='admin')
222     parser.add_argument('-e', '--odlpassword',
223                         help='Password for ODL',
224                         default='admin')
225     parser.add_argument('-p', '--pushtodb',
226                         help='Push results to DB',
227                         action='store_true')
228
229     args = vars(parser.parse_args())
230     odl = ODLTests()
231     try:
232         result = odl.main(**args)
233         if result != testcase_base.TestcaseBase.EX_OK:
234             sys.exit(result)
235         if args['pushtodb']:
236             sys.exit(odl.push_to_db())
237     except Exception:
238         sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)