write test results to a local file
[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             elif installer_type == 'joid':
166                 kwargs['odlip'] = os.environ['SDN_CONTROLLER']
167             elif installer_type == 'compass':
168                 kwargs['odlwebport'] = '8181'
169             else:
170                 kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
171         except KeyError as e:
172             self.logger.error("Cannot run ODL testcases. "
173                               "Please check env var: "
174                               "%s" % str(e))
175             return self.EX_RUN_ERROR
176         except Exception:
177             self.logger.exception("Cannot run ODL testcases.")
178             return self.EX_RUN_ERROR
179
180         return self.main(**kwargs)
181
182
183 class ODLParser():
184
185     def __init__(self):
186         self.parser = argparse.ArgumentParser()
187         self.parser.add_argument(
188             '-k', '--keystoneip', help='Keystone IP',
189             default='127.0.0.1')
190         self.parser.add_argument(
191             '-n', '--neutronip', help='Neutron IP',
192             default='127.0.0.1')
193         self.parser.add_argument(
194             '-a', '--osusername', help='Username for OpenStack',
195             default='admin')
196         self.parser.add_argument(
197             '-b', '--ostenantname', help='Tenantname for OpenStack',
198             default='admin')
199         self.parser.add_argument(
200             '-c', '--ospassword', help='Password for OpenStack',
201             default='admin')
202         self.parser.add_argument(
203             '-o', '--odlip', help='OpenDaylight IP',
204             default='127.0.0.1')
205         self.parser.add_argument(
206             '-w', '--odlwebport', help='OpenDaylight Web Portal Port',
207             default='8080')
208         self.parser.add_argument(
209             '-r', '--odlrestconfport', help='OpenDaylight RESTConf Port',
210             default='8181')
211         self.parser.add_argument(
212             '-d', '--odlusername', help='Username for ODL',
213             default='admin')
214         self.parser.add_argument(
215             '-e', '--odlpassword', help='Password for ODL',
216             default='admin')
217         self.parser.add_argument(
218             '-p', '--pushtodb', help='Push results to DB',
219             action='store_true')
220
221     def parse_args(self, argv=[]):
222         return vars(self.parser.parse_args(argv))
223
224
225 if __name__ == '__main__':
226     odl = ODLTests()
227     parser = ODLParser()
228     args = parser.parse_args(sys.argv[1:])
229     try:
230         result = odl.main(**args)
231         if result != testcase_base.TestcaseBase.EX_OK:
232             sys.exit(result)
233         if args['pushtodb']:
234             sys.exit(odl.publish_report())
235     except Exception:
236         sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)