Merge "Use 8081 for apex's restconfport robot variable"
[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     res_dir = '/home/opnfv/functest/results/odl/'
58     logger = ft_logger.Logger("opendaylight").getLogger()
59
60     def __init__(self):
61         testcase_base.TestcaseBase.__init__(self)
62         self.case_name = "odl"
63
64     @classmethod
65     def set_robotframework_vars(cls, odlusername="admin", odlpassword="admin"):
66         odl_variables_files = os.path.join(cls.odl_test_repo,
67                                            'csit/variables/Variables.py')
68         try:
69             for line in fileinput.input(odl_variables_files,
70                                         inplace=True):
71                 print re.sub("AUTH = .*",
72                              ("AUTH = [u'" + odlusername + "', u'" +
73                               odlpassword + "']"),
74                              line.rstrip())
75             return True
76         except Exception as e:
77             cls.logger.error("Cannot set ODL creds: %s" % str(e))
78             return False
79
80     def parse_results(self):
81         xml_file = os.path.join(self.res_dir, 'output.xml')
82         result = robot.api.ExecutionResult(xml_file)
83         visitor = ODLResultVisitor()
84         result.visit(visitor)
85         self.criteria = result.suite.status
86         self.start_time = timestamp_to_secs(result.suite.starttime)
87         self.stop_time = timestamp_to_secs(result.suite.endtime)
88         self.details = {}
89         self.details['description'] = result.suite.name
90         self.details['tests'] = visitor.get_data()
91
92     def main(self, **kwargs):
93         dirs = [self.basic_suite_dir, self.neutron_suite_dir]
94         try:
95             odlusername = kwargs['odlusername']
96             odlpassword = kwargs['odlpassword']
97             variables = ['KEYSTONE:' + kwargs['keystoneip'],
98                          'NEUTRON:' + kwargs['neutronip'],
99                          'OSUSERNAME:"' + kwargs['osusername'] + '"',
100                          'OSTENANTNAME:"' + kwargs['ostenantname'] + '"',
101                          'OSPASSWORD:"' + kwargs['ospassword'] + '"',
102                          'ODL_SYSTEM_IP:' + kwargs['odlip'],
103                          'PORT:' + kwargs['odlwebport'],
104                          'RESTCONFPORT:' + kwargs['odlrestconfport']]
105         except KeyError as e:
106             self.logger.error("Cannot run ODL testcases. Please check "
107                               "%s" % str(e))
108             return self.EX_RUN_ERROR
109         if self.set_robotframework_vars(odlusername, odlpassword):
110             try:
111                 os.makedirs(self.res_dir)
112             except OSError as e:
113                 if e.errno != errno.EEXIST:
114                     self.logger.exception(
115                         "Cannot create {}".format(self.res_dir))
116                     return self.EX_RUN_ERROR
117             stdout_file = os.path.join(self.res_dir, 'stdout.txt')
118             output_dir = os.path.join(self.res_dir, 'output.xml')
119             with open(stdout_file, 'w+') as stdout:
120                 robot.run(*dirs, variable=variables,
121                           output=output_dir,
122                           log='NONE',
123                           report='NONE',
124                           stdout=stdout)
125                 stdout.seek(0, 0)
126                 self.logger.info("\n" + stdout.read())
127             self.logger.info("ODL results were successfully generated")
128             try:
129                 self.parse_results()
130                 self.logger.info("ODL results were successfully parsed")
131             except RobotError as e:
132                 self.logger.error("Run tests before publishing: %s" %
133                                   e.message)
134                 return self.EX_RUN_ERROR
135             try:
136                 os.remove(stdout_file)
137             except OSError:
138                 self.logger.warning("Cannot remove {}".format(stdout_file))
139             return self.EX_OK
140         else:
141             return self.EX_RUN_ERROR
142
143     def run(self):
144         try:
145             keystone_url = op_utils.get_endpoint(service_type='identity')
146             neutron_url = op_utils.get_endpoint(service_type='network')
147             kwargs = {'keystoneip': urlparse.urlparse(keystone_url).hostname}
148             kwargs['neutronip'] = urlparse.urlparse(neutron_url).hostname
149             kwargs['odlip'] = kwargs['neutronip']
150             kwargs['odlwebport'] = '8080'
151             kwargs['odlrestconfport'] = '8181'
152             kwargs['odlusername'] = 'admin'
153             kwargs['odlpassword'] = 'admin'
154             installer_type = None
155             if 'INSTALLER_TYPE' in os.environ:
156                 installer_type = os.environ['INSTALLER_TYPE']
157             kwargs['osusername'] = os.environ['OS_USERNAME']
158             kwargs['ostenantname'] = os.environ['OS_TENANT_NAME']
159             kwargs['ospassword'] = os.environ['OS_PASSWORD']
160             if installer_type == 'fuel':
161                 kwargs['odlwebport'] = '8282'
162             elif installer_type == 'apex':
163                 kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
164                 kwargs['odlwebport'] = '8081'
165                 kwargs['odlrestconfport'] = '8081'
166             elif installer_type == 'joid':
167                 kwargs['odlip'] = os.environ['SDN_CONTROLLER']
168             elif installer_type == 'compass':
169                 kwargs['odlwebport'] = '8181'
170             else:
171                 kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
172         except KeyError as e:
173             self.logger.error("Cannot run ODL testcases. "
174                               "Please check env var: "
175                               "%s" % str(e))
176             return self.EX_RUN_ERROR
177         except Exception:
178             self.logger.exception("Cannot run ODL testcases.")
179             return self.EX_RUN_ERROR
180
181         return self.main(**kwargs)
182
183
184 class ODLParser():
185
186     def __init__(self):
187         self.parser = argparse.ArgumentParser()
188         self.parser.add_argument(
189             '-k', '--keystoneip', help='Keystone IP',
190             default='127.0.0.1')
191         self.parser.add_argument(
192             '-n', '--neutronip', help='Neutron IP',
193             default='127.0.0.1')
194         self.parser.add_argument(
195             '-a', '--osusername', help='Username for OpenStack',
196             default='admin')
197         self.parser.add_argument(
198             '-b', '--ostenantname', help='Tenantname for OpenStack',
199             default='admin')
200         self.parser.add_argument(
201             '-c', '--ospassword', help='Password for OpenStack',
202             default='admin')
203         self.parser.add_argument(
204             '-o', '--odlip', help='OpenDaylight IP',
205             default='127.0.0.1')
206         self.parser.add_argument(
207             '-w', '--odlwebport', help='OpenDaylight Web Portal Port',
208             default='8080')
209         self.parser.add_argument(
210             '-r', '--odlrestconfport', help='OpenDaylight RESTConf Port',
211             default='8181')
212         self.parser.add_argument(
213             '-d', '--odlusername', help='Username for ODL',
214             default='admin')
215         self.parser.add_argument(
216             '-e', '--odlpassword', help='Password for ODL',
217             default='admin')
218         self.parser.add_argument(
219             '-p', '--pushtodb', help='Push results to DB',
220             action='store_true')
221
222     def parse_args(self, argv=[]):
223         return vars(self.parser.parse_args(argv))
224
225
226 if __name__ == '__main__':
227     odl = ODLTests()
228     parser = ODLParser()
229     args = parser.parse_args(sys.argv[1:])
230     try:
231         result = odl.main(**args)
232         if result != testcase_base.TestcaseBase.EX_OK:
233             sys.exit(result)
234         if args['pushtodb']:
235             sys.exit(odl.push_to_db())
236     except Exception:
237         sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)