Merge "Stop reading NODE_NAME in tempest and refstack"
[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 """Define classes required to run ODL suites.
11
12 It has been designed for any context. But helpers are given for
13 running test suites in OPNFV environment.
14
15 Example:
16         $ python odl.py
17 """
18
19 from __future__ import division
20
21 import argparse
22 import fileinput
23 import logging
24 import os
25 import re
26 import sys
27
28 from six.moves import urllib
29 from snaps.openstack.utils import keystone_utils
30
31 from functest.core import robotframework
32 from functest.opnfv_tests.openstack.snaps import snaps_utils
33 from functest.utils import constants
34
35 __author__ = "Cedric Ollivier <cedric.ollivier@orange.com>"
36
37
38 class ODLTests(robotframework.RobotFramework):
39     """ODL test runner."""
40
41     odl_test_repo = getattr(constants.CONST, 'dir_repo_odl_test')
42     neutron_suite_dir = os.path.join(
43         odl_test_repo, "csit/suites/openstack/neutron")
44     basic_suite_dir = os.path.join(
45         odl_test_repo, "csit/suites/integration/basic")
46     default_suites = [basic_suite_dir, neutron_suite_dir]
47     odl_variables_file = os.path.join(
48         odl_test_repo, 'csit/variables/Variables.robot')
49     __logger = logging.getLogger(__name__)
50
51     def __init__(self, **kwargs):
52         super(ODLTests, self).__init__(**kwargs)
53         self.res_dir = os.path.join(
54             getattr(constants.CONST, 'dir_results'), 'odl')
55         self.xml_file = os.path.join(self.res_dir, 'output.xml')
56
57     @classmethod
58     def set_robotframework_vars(cls, odlusername="admin", odlpassword="admin"):
59         """Set credentials in csit/variables/Variables.robot.
60
61         Returns:
62             True if credentials are set.
63             False otherwise.
64         """
65
66         try:
67             for line in fileinput.input(cls.odl_variables_file,
68                                         inplace=True):
69                 print(re.sub("@{AUTH}.*",
70                              "@{{AUTH}}           {}    {}".format(
71                                  odlusername, odlpassword),
72                              line.rstrip()))
73             return True
74         except Exception:  # pylint: disable=broad-except
75             cls.__logger.exception("Cannot set ODL creds:")
76             return False
77
78     def run_suites(self, suites=None, **kwargs):
79         """Run the test suites
80
81         It has been designed to be called in any context.
82         It requires the following keyword arguments:
83
84            * odlusername,
85            * odlpassword,
86            * osauthurl,
87            * neutronurl,
88            * osusername,
89            * osprojectname,
90            * ospassword,
91            * odlip,
92            * odlwebport,
93            * odlrestconfport.
94
95         Here are the steps:
96            * set all RobotFramework_variables,
97            * create the output directories if required,
98            * get the results in output.xml,
99            * delete temporary files.
100
101         Args:
102             kwargs: Arbitrary keyword arguments.
103
104         Returns:
105             EX_OK if all suites ran well.
106             EX_RUN_ERROR otherwise.
107         """
108         try:
109             if not suites:
110                 suites = self.default_suites
111             odlusername = kwargs['odlusername']
112             odlpassword = kwargs['odlpassword']
113             osauthurl = kwargs['osauthurl']
114             keystoneurl = "{}://{}".format(
115                 urllib.parse.urlparse(osauthurl).scheme,
116                 urllib.parse.urlparse(osauthurl).netloc)
117             variable = ['KEYSTONEURL:' + keystoneurl,
118                         'NEUTRONURL:' + kwargs['neutronurl'],
119                         'OS_AUTH_URL:"' + osauthurl + '"',
120                         'OSUSERNAME:"' + kwargs['osusername'] + '"',
121                         ('OSUSERDOMAINNAME:"' +
122                          kwargs['osuserdomainname'] + '"'),
123                         'OSTENANTNAME:"' + kwargs['osprojectname'] + '"',
124                         ('OSPROJECTDOMAINNAME:"' +
125                          kwargs['osprojectdomainname'] + '"'),
126                         'OSPASSWORD:"' + kwargs['ospassword'] + '"',
127                         'ODL_SYSTEM_IP:' + kwargs['odlip'],
128                         'PORT:' + kwargs['odlwebport'],
129                         'RESTCONFPORT:' + kwargs['odlrestconfport']]
130         except KeyError:
131             self.__logger.exception("Cannot run ODL testcases. Please check")
132             return self.EX_RUN_ERROR
133         if not os.path.isfile(self.odl_variables_file):
134             self.__logger.info("Skip writting ODL creds")
135         else:
136             if not self.set_robotframework_vars(odlusername, odlpassword):
137                 return self.EX_RUN_ERROR
138         return super(ODLTests, self).run(variable=variable, suites=suites)
139
140     def run(self, **kwargs):
141         """Run suites in OPNFV environment
142
143         It basically checks env vars to call main() with the keywords
144         required.
145
146         Args:
147             kwargs: Arbitrary keyword arguments.
148
149         Returns:
150             EX_OK if all suites ran well.
151             EX_RUN_ERROR otherwise.
152         """
153         try:
154             suites = self.default_suites
155             try:
156                 suites = kwargs["suites"]
157             except KeyError:
158                 pass
159             snaps_creds = snaps_utils.get_credentials()
160             kwargs = {'neutronurl': keystone_utils.get_endpoint(
161                 snaps_creds, 'network')}
162             kwargs['odlip'] = urllib.parse.urlparse(
163                 kwargs['neutronurl']).hostname
164             kwargs['odlwebport'] = '8080'
165             kwargs['odlrestconfport'] = '8181'
166             kwargs['odlusername'] = 'admin'
167             kwargs['odlpassword'] = 'admin'
168             installer_type = None
169             if 'INSTALLER_TYPE' in os.environ:
170                 installer_type = os.environ['INSTALLER_TYPE']
171             kwargs['osusername'] = os.environ['OS_USERNAME']
172             kwargs['osuserdomainname'] = os.environ.get(
173                 'OS_USER_DOMAIN_NAME', 'Default')
174             kwargs['osprojectname'] = os.environ['OS_PROJECT_NAME']
175             kwargs['osprojectdomainname'] = os.environ.get(
176                 'OS_PROJECT_DOMAIN_NAME', 'Default')
177             kwargs['osauthurl'] = os.environ['OS_AUTH_URL']
178             kwargs['ospassword'] = os.environ['OS_PASSWORD']
179             if installer_type == 'fuel':
180                 kwargs['odlwebport'] = '8181'
181                 kwargs['odlrestconfport'] = '8282'
182             elif installer_type == 'apex' or installer_type == 'netvirt':
183                 kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
184                 kwargs['odlwebport'] = '8081'
185                 kwargs['odlrestconfport'] = '8081'
186             elif installer_type == 'joid':
187                 kwargs['odlip'] = os.environ['SDN_CONTROLLER']
188             elif installer_type == 'compass':
189                 kwargs['odlrestconfport'] = '8080'
190             elif installer_type == 'daisy':
191                 kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
192                 kwargs['odlwebport'] = '8181'
193                 kwargs['odlrestconfport'] = '8087'
194             else:
195                 kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
196         except KeyError as ex:
197             self.__logger.error("Cannot run ODL testcases. "
198                                 "Please check env var: "
199                                 "%s", str(ex))
200             return self.EX_RUN_ERROR
201         except Exception:  # pylint: disable=broad-except
202             self.__logger.exception("Cannot run ODL testcases.")
203             return self.EX_RUN_ERROR
204
205         return self.run_suites(suites, **kwargs)
206
207
208 class ODLParser(object):  # pylint: disable=too-few-public-methods
209     """Parser to run ODL test suites."""
210
211     def __init__(self):
212         self.parser = argparse.ArgumentParser()
213         self.parser.add_argument(
214             '-n', '--neutronurl', help='Neutron Endpoint',
215             default='http://127.0.0.1:9696')
216         self.parser.add_argument(
217             '-k', '--osauthurl', help='OS_AUTH_URL as defined by OpenStack',
218             default='http://127.0.0.1:5000/v3')
219         self.parser.add_argument(
220             '-a', '--osusername', help='Username for OpenStack',
221             default='admin')
222         self.parser.add_argument(
223             '-f', '--osuserdomainname', help='User domain name for OpenStack',
224             default='Default')
225         self.parser.add_argument(
226             '-b', '--osprojectname', help='Projet name for OpenStack',
227             default='admin')
228         self.parser.add_argument(
229             '-g', '--osprojectdomainname',
230             help='Project domain name for OpenStack',
231             default='Default')
232         self.parser.add_argument(
233             '-c', '--ospassword', help='Password for OpenStack',
234             default='admin')
235         self.parser.add_argument(
236             '-o', '--odlip', help='OpenDaylight IP',
237             default='127.0.0.1')
238         self.parser.add_argument(
239             '-w', '--odlwebport', help='OpenDaylight Web Portal Port',
240             default='8080')
241         self.parser.add_argument(
242             '-r', '--odlrestconfport', help='OpenDaylight RESTConf Port',
243             default='8181')
244         self.parser.add_argument(
245             '-d', '--odlusername', help='Username for ODL',
246             default='admin')
247         self.parser.add_argument(
248             '-e', '--odlpassword', help='Password for ODL',
249             default='admin')
250         self.parser.add_argument(
251             '-p', '--pushtodb', help='Push results to DB',
252             action='store_true')
253
254     def parse_args(self, argv=None):
255         """Parse arguments.
256
257         It can call sys.exit if arguments are incorrect.
258
259         Returns:
260             the arguments from cmdline
261         """
262         if not argv:
263             argv = []
264         return vars(self.parser.parse_args(argv))
265
266
267 def main():
268     """Entry point"""
269     logging.basicConfig()
270     odl = ODLTests()
271     parser = ODLParser()
272     args = parser.parse_args(sys.argv[1:])
273     try:
274         result = odl.run_suites(ODLTests.default_suites, **args)
275         if result != robotframework.RobotFramework.EX_OK:
276             return result
277         if args['pushtodb']:
278             return odl.push_to_db()
279         return result
280     except Exception:  # pylint: disable=broad-except
281         return robotframework.RobotFramework.EX_RUN_ERROR