aa31703b86267a37aa04197a2a91a31f0c7efd3c
[functest.git] / functest / tests / unit / odl / test_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 the classes required to fully cover odl."""
11
12 import logging
13 import os
14 import unittest
15
16 import mock
17 from robot.errors import RobotError
18 import six
19 from six.moves import urllib
20
21 from functest.core import testcase
22 from functest.opnfv_tests.sdn.odl import odl
23
24 __author__ = "Cedric Ollivier <cedric.ollivier@orange.com>"
25
26
27 class ODLTesting(unittest.TestCase):
28
29     """The super class which testing classes could inherit."""
30     # pylint: disable=missing-docstring
31
32     logging.disable(logging.CRITICAL)
33
34     _keystone_ip = "127.0.0.1"
35     _neutron_url = u"https://127.0.0.1:9696"
36     _sdn_controller_ip = "127.0.0.3"
37     _os_auth_url = "http://{}:5000/v3".format(_keystone_ip)
38     _os_projectname = "admin"
39     _os_username = "admin"
40     _os_password = "admin"
41     _odl_webport = "8080"
42     _odl_restconfport = "8181"
43     _odl_username = "admin"
44     _odl_password = "admin"
45     _os_userdomainname = 'Default'
46     _os_projectdomainname = 'Default'
47
48     def setUp(self):
49         for var in ("INSTALLER_TYPE", "SDN_CONTROLLER", "SDN_CONTROLLER_IP"):
50             if var in os.environ:
51                 del os.environ[var]
52         os.environ["OS_AUTH_URL"] = self._os_auth_url
53         os.environ["OS_USERNAME"] = self._os_username
54         os.environ["OS_USER_DOMAIN_NAME"] = self._os_userdomainname
55         os.environ["OS_PASSWORD"] = self._os_password
56         os.environ["OS_PROJECT_NAME"] = self._os_projectname
57         os.environ["OS_PROJECT_DOMAIN_NAME"] = self._os_projectdomainname
58         os.environ["OS_PASSWORD"] = self._os_password
59         self.test = odl.ODLTests(case_name='odl', project_name='functest')
60         self.defaultargs = {'odlusername': self._odl_username,
61                             'odlpassword': self._odl_password,
62                             'neutronurl': "http://{}:9696".format(
63                                 self._keystone_ip),
64                             'osauthurl': self._os_auth_url,
65                             'osusername': self._os_username,
66                             'osuserdomainname': self._os_userdomainname,
67                             'osprojectname': self._os_projectname,
68                             'osprojectdomainname': self._os_projectdomainname,
69                             'ospassword': self._os_password,
70                             'odlip': self._keystone_ip,
71                             'odlwebport': self._odl_webport,
72                             'odlrestconfport': self._odl_restconfport,
73                             'pushtodb': False}
74
75
76 class ODLRobotTesting(ODLTesting):
77
78     """The class testing ODLTests.set_robotframework_vars()."""
79     # pylint: disable=missing-docstring
80
81     @mock.patch('fileinput.input', side_effect=Exception())
82     def test_set_vars_ko(self, mock_method):
83         self.assertFalse(self.test.set_robotframework_vars())
84         mock_method.assert_called_once_with(
85             os.path.join(odl.ODLTests.odl_test_repo,
86                          'csit/variables/Variables.robot'), inplace=True)
87
88     @mock.patch('fileinput.input', return_value=[])
89     def test_set_vars_empty(self, mock_method):
90         self.assertTrue(self.test.set_robotframework_vars())
91         mock_method.assert_called_once_with(
92             os.path.join(odl.ODLTests.odl_test_repo,
93                          'csit/variables/Variables.robot'), inplace=True)
94
95     @mock.patch('sys.stdout', new_callable=six.StringIO)
96     def _test_set_vars(self, msg1, msg2, *args):
97         line = mock.MagicMock()
98         line.__iter__.return_value = [msg1]
99         with mock.patch('fileinput.input', return_value=line) as mock_method:
100             self.assertTrue(self.test.set_robotframework_vars())
101             mock_method.assert_called_once_with(
102                 os.path.join(odl.ODLTests.odl_test_repo,
103                              'csit/variables/Variables.robot'), inplace=True)
104             self.assertEqual(args[0].getvalue(), "{}\n".format(msg2))
105
106     def test_set_vars_auth_default(self):
107         self._test_set_vars(
108             "@{AUTH} ",
109             "@{AUTH}           admin    admin")
110
111     def test_set_vars_auth1(self):
112         self._test_set_vars(
113             "@{AUTH1}           foo    bar",
114             "@{AUTH1}           foo    bar")
115
116     @mock.patch('sys.stdout', new_callable=six.StringIO)
117     def test_set_vars_auth_foo(self, *args):
118         line = mock.MagicMock()
119         line.__iter__.return_value = ["@{AUTH} "]
120         with mock.patch('fileinput.input', return_value=line) as mock_method:
121             self.assertTrue(self.test.set_robotframework_vars('foo', 'bar'))
122             mock_method.assert_called_once_with(
123                 os.path.join(odl.ODLTests.odl_test_repo,
124                              'csit/variables/Variables.robot'), inplace=True)
125             self.assertEqual(
126                 args[0].getvalue(),
127                 "@{AUTH}           foo    bar\n")
128
129
130 class ODLMainTesting(ODLTesting):
131
132     """The class testing ODLTests.run_suites()."""
133     # pylint: disable=missing-docstring
134
135     def _get_run_suites_kwargs(self, key=None):
136         kwargs = {'odlusername': self._odl_username,
137                   'odlpassword': self._odl_password,
138                   'neutronurl': self._neutron_url,
139                   'osauthurl': self._os_auth_url,
140                   'osusername': self._os_username,
141                   'osuserdomainname': self._os_userdomainname,
142                   'osprojectname': self._os_projectname,
143                   'osprojectdomainname': self._os_projectdomainname,
144                   'ospassword': self._os_password,
145                   'odlip': self._sdn_controller_ip,
146                   'odlwebport': self._odl_webport,
147                   'odlrestconfport': self._odl_restconfport}
148         if key:
149             del kwargs[key]
150         return kwargs
151
152     def _test_run_suites(self, status, *args):
153         kwargs = self._get_run_suites_kwargs()
154         self.assertEqual(self.test.run_suites(**kwargs), status)
155         if args:
156             args[0].assert_called_once_with(self.test.odl_variables_file)
157         if len(args) > 1:
158             variable = [
159                 'KEYSTONEURL:{}://{}'.format(
160                     urllib.parse.urlparse(self._os_auth_url).scheme,
161                     urllib.parse.urlparse(self._os_auth_url).netloc),
162                 'NEUTRONURL:{}'.format(self._neutron_url),
163                 'OS_AUTH_URL:"{}"'.format(self._os_auth_url),
164                 'OSUSERNAME:"{}"'.format(self._os_username),
165                 'OSUSERDOMAINNAME:"{}"'.format(self._os_userdomainname),
166                 'OSTENANTNAME:"{}"'.format(self._os_projectname),
167                 'OSPROJECTDOMAINNAME:"{}"'.format(self._os_projectdomainname),
168                 'OSPASSWORD:"{}"'.format(self._os_password),
169                 'ODL_SYSTEM_IP:{}'.format(self._sdn_controller_ip),
170                 'PORT:{}'.format(self._odl_webport),
171                 'RESTCONFPORT:{}'.format(self._odl_restconfport)]
172             args[1].assert_called_once_with(
173                 odl.ODLTests.basic_suite_dir, odl.ODLTests.neutron_suite_dir,
174                 log='NONE',
175                 output=os.path.join(self.test.res_dir, 'output.xml'),
176                 report='NONE', stdout=mock.ANY, variable=variable,
177                 variablefile=[])
178
179     def _test_no_keyword(self, key):
180         kwargs = self._get_run_suites_kwargs(key)
181         self.assertEqual(self.test.run_suites(**kwargs),
182                          testcase.TestCase.EX_RUN_ERROR)
183
184     def test_no_odlusername(self):
185         self._test_no_keyword('odlusername')
186
187     def test_no_odlpassword(self):
188         self._test_no_keyword('odlpassword')
189
190     def test_no_neutronurl(self):
191         self._test_no_keyword('neutronurl')
192
193     def test_no_osauthurl(self):
194         self._test_no_keyword('osauthurl')
195
196     def test_no_osusername(self):
197         self._test_no_keyword('osusername')
198
199     def test_no_osprojectname(self):
200         self._test_no_keyword('osprojectname')
201
202     def test_no_ospassword(self):
203         self._test_no_keyword('ospassword')
204
205     def test_no_odlip(self):
206         self._test_no_keyword('odlip')
207
208     def test_no_odlwebport(self):
209         self._test_no_keyword('odlwebport')
210
211     def test_no_odlrestconfport(self):
212         self._test_no_keyword('odlrestconfport')
213
214     @mock.patch('os.path.isfile', return_value=True)
215     def test_set_vars_ko(self, *args):
216         with mock.patch.object(self.test, 'set_robotframework_vars',
217                                return_value=False) as mock_object:
218             self._test_run_suites(testcase.TestCase.EX_RUN_ERROR)
219             mock_object.assert_called_once_with(
220                 self._odl_username, self._odl_password)
221         args[0].assert_called_once_with(self.test.odl_variables_file)
222
223     @mock.patch('robot.run', side_effect=RobotError)
224     @mock.patch('os.path.isfile', return_value=True)
225     def test_run_ko(self, *args):
226         with mock.patch.object(self.test, 'set_robotframework_vars',
227                                return_value=True), \
228                 self.assertRaises(RobotError):
229             self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, *args)
230
231     @mock.patch('robot.run')
232     @mock.patch('os.path.isfile', return_value=True)
233     def test_parse_results_ko(self, *args):
234         with mock.patch.object(self.test, 'set_robotframework_vars',
235                                return_value=True), \
236                 mock.patch.object(self.test, 'parse_results',
237                                   side_effect=RobotError):
238             self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, *args)
239
240     @mock.patch('robot.run')
241     @mock.patch('os.path.isfile', return_value=True)
242     def test_ok(self, *args):
243         with mock.patch.object(self.test, 'set_robotframework_vars',
244                                return_value=True), \
245                 mock.patch.object(self.test, 'parse_results'):
246             self._test_run_suites(testcase.TestCase.EX_OK, *args)
247
248     @mock.patch('robot.run')
249     @mock.patch('os.path.isfile', return_value=False)
250     def test_ok_no_creds(self, *args):
251         with mock.patch.object(self.test, 'set_robotframework_vars',
252                                return_value=True) as mock_method, \
253                 mock.patch.object(self.test, 'parse_results'):
254             self._test_run_suites(testcase.TestCase.EX_OK, *args)
255             mock_method.assert_not_called()
256
257     @mock.patch('robot.run', return_value=1)
258     @mock.patch('os.path.isfile', return_value=True)
259     def test_testcases_in_failure(self, *args):
260         with mock.patch.object(self.test, 'set_robotframework_vars',
261                                return_value=True), \
262                 mock.patch.object(self.test, 'parse_results'):
263             self._test_run_suites(testcase.TestCase.EX_OK, *args)
264
265
266 class ODLRunTesting(ODLTesting):
267
268     """The class testing ODLTests.run()."""
269     # pylint: disable=missing-docstring
270
271     @mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
272                 return_value=ODLTesting._neutron_url)
273     @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
274                 'get_credentials')
275     def _test_no_env_var(self, var, *args):
276         del os.environ[var]
277         self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
278         args[0].assert_called_once_with()
279         args[1].assert_called_once_with(mock.ANY, 'network')
280
281     @mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
282                 return_value=ODLTesting._neutron_url)
283     @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
284                 'get_credentials')
285     def _test_run(self, status=testcase.TestCase.EX_OK,
286                   exception=None, *args, **kwargs):
287         odlip = kwargs['odlip'] if 'odlip' in kwargs else '127.0.0.3'
288         odlwebport = kwargs['odlwebport'] if 'odlwebport' in kwargs else '8080'
289         odlrestconfport = (kwargs['odlrestconfport']
290                            if 'odlrestconfport' in kwargs else '8181')
291         if exception:
292             self.test.run_suites = mock.Mock(side_effect=exception)
293         else:
294             self.test.run_suites = mock.Mock(return_value=status)
295         self.assertEqual(self.test.run(), status)
296         self.test.run_suites.assert_called_once_with(
297             odl.ODLTests.default_suites, neutronurl=self._neutron_url,
298             odlip=odlip, odlpassword=self._odl_password,
299             odlrestconfport=odlrestconfport, odlusername=self._odl_username,
300             odlwebport=odlwebport, osauthurl=self._os_auth_url,
301             ospassword=self._os_password, osprojectname=self._os_projectname,
302             osusername=self._os_username,
303             osprojectdomainname=self._os_projectdomainname,
304             osuserdomainname=self._os_userdomainname)
305         args[0].assert_called_once_with()
306         args[1].assert_called_once_with(mock.ANY, 'network')
307
308     @mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
309                 return_value=ODLTesting._neutron_url)
310     @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
311                 'get_credentials')
312     def _test_multiple_suites(self, suites,
313                               status=testcase.TestCase.EX_OK, *args, **kwargs):
314         odlip = kwargs['odlip'] if 'odlip' in kwargs else '127.0.0.3'
315         odlwebport = kwargs['odlwebport'] if 'odlwebport' in kwargs else '8080'
316         odlrestconfport = (kwargs['odlrestconfport']
317                            if 'odlrestconfport' in kwargs else '8181')
318         self.test.run_suites = mock.Mock(return_value=status)
319         self.assertEqual(self.test.run(suites=suites), status)
320         self.test.run_suites.assert_called_once_with(
321             suites, neutronurl=self._neutron_url, odlip=odlip,
322             odlpassword=self._odl_password, odlrestconfport=odlrestconfport,
323             odlusername=self._odl_username, odlwebport=odlwebport,
324             osauthurl=self._os_auth_url, ospassword=self._os_password,
325             osprojectname=self._os_projectname, osusername=self._os_username,
326             osprojectdomainname=self._os_projectdomainname,
327             osuserdomainname=self._os_userdomainname)
328         args[0].assert_called_once_with()
329         args[1].assert_called_once_with(mock.ANY, 'network')
330
331     def test_exc(self):
332         with mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
333                         side_effect=Exception()):
334             self.assertEqual(self.test.run(),
335                              testcase.TestCase.EX_RUN_ERROR)
336
337     def test_no_os_auth_url(self):
338         self._test_no_env_var("OS_AUTH_URL")
339
340     def test_no_os_username(self):
341         self._test_no_env_var("OS_USERNAME")
342
343     def test_no_os_password(self):
344         self._test_no_env_var("OS_PASSWORD")
345
346     def test_no_os__name(self):
347         self._test_no_env_var("OS_PROJECT_NAME")
348
349     def test_run_suites_false(self):
350         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
351         self._test_run(testcase.TestCase.EX_RUN_ERROR, None,
352                        odlip=self._sdn_controller_ip,
353                        odlwebport=self._odl_webport)
354
355     def test_run_suites_exc(self):
356         with self.assertRaises(Exception):
357             os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
358             self._test_run(testcase.TestCase.EX_RUN_ERROR,
359                            Exception(),
360                            odlip=self._sdn_controller_ip,
361                            odlwebport=self._odl_webport)
362
363     def test_no_sdn_controller_ip(self):
364         self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
365
366     def test_without_installer_type(self):
367         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
368         self._test_run(testcase.TestCase.EX_OK, None,
369                        odlip=self._sdn_controller_ip,
370                        odlwebport=self._odl_webport)
371
372     def test_suites(self):
373         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
374         self._test_multiple_suites(
375             [odl.ODLTests.basic_suite_dir],
376             testcase.TestCase.EX_OK,
377             odlip=self._sdn_controller_ip,
378             odlwebport=self._odl_webport)
379
380     def test_fuel(self):
381         os.environ["INSTALLER_TYPE"] = "fuel"
382         self._test_run(testcase.TestCase.EX_OK, None,
383                        odlip=urllib.parse.urlparse(self._neutron_url).hostname,
384                        odlwebport='8181',
385                        odlrestconfport='8282')
386
387     def test_apex_no_controller_ip(self):
388         os.environ["INSTALLER_TYPE"] = "apex"
389         self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
390
391     def test_apex(self):
392         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
393         os.environ["INSTALLER_TYPE"] = "apex"
394         self._test_run(testcase.TestCase.EX_OK, None,
395                        odlip=self._sdn_controller_ip, odlwebport='8081',
396                        odlrestconfport='8081')
397
398     def test_netvirt_no_controller_ip(self):
399         os.environ["INSTALLER_TYPE"] = "netvirt"
400         self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
401
402     def test_netvirt(self):
403         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
404         os.environ["INSTALLER_TYPE"] = "netvirt"
405         self._test_run(testcase.TestCase.EX_OK, None,
406                        odlip=self._sdn_controller_ip, odlwebport='8081',
407                        odlrestconfport='8081')
408
409     def test_compass(self):
410         os.environ["INSTALLER_TYPE"] = "compass"
411         self._test_run(testcase.TestCase.EX_OK, None,
412                        odlip=urllib.parse.urlparse(self._neutron_url).hostname,
413                        odlrestconfport='8080')
414
415     def test_daisy_no_controller_ip(self):
416         os.environ["INSTALLER_TYPE"] = "daisy"
417         self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
418
419     def test_daisy(self):
420         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
421         os.environ["INSTALLER_TYPE"] = "daisy"
422         self._test_run(testcase.TestCase.EX_OK, None,
423                        odlip=self._sdn_controller_ip, odlwebport='8181',
424                        odlrestconfport='8087')
425
426
427 class ODLArgParserTesting(ODLTesting):
428
429     """The class testing ODLParser."""
430     # pylint: disable=missing-docstring
431
432     def setUp(self):
433         self.parser = odl.ODLParser()
434         super(ODLArgParserTesting, self).setUp()
435
436     def test_default(self):
437         self.assertEqual(self.parser.parse_args(), self.defaultargs)
438
439     def test_basic(self):
440         self.defaultargs['neutronurl'] = self._neutron_url
441         self.defaultargs['odlip'] = self._sdn_controller_ip
442         self.assertEqual(
443             self.parser.parse_args(
444                 ["--neutronurl={}".format(self._neutron_url),
445                  "--odlip={}".format(self._sdn_controller_ip)]),
446             self.defaultargs)
447
448     @mock.patch('sys.stderr', new_callable=six.StringIO)
449     def test_fail(self, mock_method):
450         self.defaultargs['foo'] = 'bar'
451         with self.assertRaises(SystemExit):
452             self.parser.parse_args(["--foo=bar"])
453         self.assertTrue(mock_method.getvalue().startswith("usage:"))
454
455     def _test_arg(self, arg, value):
456         self.defaultargs[arg] = value
457         self.assertEqual(
458             self.parser.parse_args(["--{}={}".format(arg, value)]),
459             self.defaultargs)
460
461     def test_odlusername(self):
462         self._test_arg('odlusername', 'foo')
463
464     def test_odlpassword(self):
465         self._test_arg('odlpassword', 'foo')
466
467     def test_osauthurl(self):
468         self._test_arg('osauthurl', 'http://127.0.0.4:5000/v2')
469
470     def test_neutronurl(self):
471         self._test_arg('neutronurl', 'http://127.0.0.4:9696')
472
473     def test_osusername(self):
474         self._test_arg('osusername', 'foo')
475
476     def test_osuserdomainname(self):
477         self._test_arg('osuserdomainname', 'domain')
478
479     def test_osprojectname(self):
480         self._test_arg('osprojectname', 'foo')
481
482     def test_osprojectdomainname(self):
483         self._test_arg('osprojectdomainname', 'domain')
484
485     def test_ospassword(self):
486         self._test_arg('ospassword', 'foo')
487
488     def test_odlip(self):
489         self._test_arg('odlip', '127.0.0.4')
490
491     def test_odlwebport(self):
492         self._test_arg('odlwebport', '80')
493
494     def test_odlrestconfport(self):
495         self._test_arg('odlrestconfport', '80')
496
497     def test_pushtodb(self):
498         self.defaultargs['pushtodb'] = True
499         self.assertEqual(self.parser.parse_args(["--{}".format('pushtodb')]),
500                          self.defaultargs)
501
502     def test_multiple_args(self):
503         self.defaultargs['neutronurl'] = self._neutron_url
504         self.defaultargs['odlip'] = self._sdn_controller_ip
505         self.assertEqual(
506             self.parser.parse_args(
507                 ["--neutronurl={}".format(self._neutron_url),
508                  "--odlip={}".format(self._sdn_controller_ip)]),
509             self.defaultargs)
510
511
512 if __name__ == "__main__":
513     logging.disable(logging.CRITICAL)
514     unittest.main(verbosity=2)