937e37120ccfb7a5c71cb58ccc2a1e48a63db4a0
[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 from xtesting.core import testcase
21
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_missing_value(self, *args):
286         self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
287         args[0].assert_called_once_with()
288         args[1].assert_called_once_with(mock.ANY, 'network')
289
290     @mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
291                 return_value=ODLTesting._neutron_url)
292     @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
293                 'get_credentials')
294     def _test_run(self, status=testcase.TestCase.EX_OK,
295                   exception=None, *args, **kwargs):
296         odlip = kwargs['odlip'] if 'odlip' in kwargs else '127.0.0.3'
297         odlwebport = kwargs['odlwebport'] if 'odlwebport' in kwargs else '8080'
298         odlrestconfport = (kwargs['odlrestconfport']
299                            if 'odlrestconfport' in kwargs else '8181')
300         if exception:
301             self.test.run_suites = mock.Mock(side_effect=exception)
302         else:
303             self.test.run_suites = mock.Mock(return_value=status)
304         self.assertEqual(self.test.run(), status)
305         self.test.run_suites.assert_called_once_with(
306             odl.ODLTests.default_suites, neutronurl=self._neutron_url,
307             odlip=odlip, odlpassword=self._odl_password,
308             odlrestconfport=odlrestconfport, odlusername=self._odl_username,
309             odlwebport=odlwebport, osauthurl=self._os_auth_url,
310             ospassword=self._os_password, osprojectname=self._os_projectname,
311             osusername=self._os_username,
312             osprojectdomainname=self._os_projectdomainname,
313             osuserdomainname=self._os_userdomainname)
314         args[0].assert_called_once_with()
315         args[1].assert_called_once_with(mock.ANY, 'network')
316
317     @mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
318                 return_value=ODLTesting._neutron_url)
319     @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
320                 'get_credentials')
321     def _test_multiple_suites(self, suites,
322                               status=testcase.TestCase.EX_OK, *args, **kwargs):
323         odlip = kwargs['odlip'] if 'odlip' in kwargs else '127.0.0.3'
324         odlwebport = kwargs['odlwebport'] if 'odlwebport' in kwargs else '8080'
325         odlrestconfport = (kwargs['odlrestconfport']
326                            if 'odlrestconfport' in kwargs else '8181')
327         self.test.run_suites = mock.Mock(return_value=status)
328         self.assertEqual(self.test.run(suites=suites), status)
329         self.test.run_suites.assert_called_once_with(
330             suites, neutronurl=self._neutron_url, odlip=odlip,
331             odlpassword=self._odl_password, odlrestconfport=odlrestconfport,
332             odlusername=self._odl_username, odlwebport=odlwebport,
333             osauthurl=self._os_auth_url, ospassword=self._os_password,
334             osprojectname=self._os_projectname, osusername=self._os_username,
335             osprojectdomainname=self._os_projectdomainname,
336             osuserdomainname=self._os_userdomainname)
337         args[0].assert_called_once_with()
338         args[1].assert_called_once_with(mock.ANY, 'network')
339
340     def test_exc(self):
341         with mock.patch('snaps.openstack.utils.keystone_utils.get_endpoint',
342                         side_effect=Exception()):
343             self.assertEqual(self.test.run(),
344                              testcase.TestCase.EX_RUN_ERROR)
345
346     def test_no_os_auth_url(self):
347         self._test_no_env_var("OS_AUTH_URL")
348
349     def test_no_os_username(self):
350         self._test_no_env_var("OS_USERNAME")
351
352     def test_no_os_password(self):
353         self._test_no_env_var("OS_PASSWORD")
354
355     def test_no_os__name(self):
356         self._test_no_env_var("OS_PROJECT_NAME")
357
358     def test_run_suites_false(self):
359         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
360         self._test_run(testcase.TestCase.EX_RUN_ERROR, None,
361                        odlip=self._sdn_controller_ip,
362                        odlwebport=self._odl_webport)
363
364     def test_run_suites_exc(self):
365         with self.assertRaises(Exception):
366             os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
367             self._test_run(testcase.TestCase.EX_RUN_ERROR,
368                            Exception(),
369                            odlip=self._sdn_controller_ip,
370                            odlwebport=self._odl_webport)
371
372     def test_no_sdn_controller_ip(self):
373         self._test_missing_value()
374
375     def test_without_installer_type(self):
376         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
377         self._test_run(testcase.TestCase.EX_OK, None,
378                        odlip=self._sdn_controller_ip,
379                        odlwebport=self._odl_webport)
380
381     def test_suites(self):
382         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
383         self._test_multiple_suites(
384             [odl.ODLTests.basic_suite_dir],
385             testcase.TestCase.EX_OK,
386             odlip=self._sdn_controller_ip,
387             odlwebport=self._odl_webport)
388
389     def test_fuel(self):
390         os.environ["INSTALLER_TYPE"] = "fuel"
391         self._test_run(testcase.TestCase.EX_OK, None,
392                        odlip=urllib.parse.urlparse(self._neutron_url).hostname,
393                        odlwebport='8181',
394                        odlrestconfport='8282')
395
396     def test_apex_no_controller_ip(self):
397         os.environ["INSTALLER_TYPE"] = "apex"
398         self._test_missing_value()
399
400     def test_apex(self):
401         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
402         os.environ["INSTALLER_TYPE"] = "apex"
403         self._test_run(testcase.TestCase.EX_OK, None,
404                        odlip=self._sdn_controller_ip, odlwebport='8081',
405                        odlrestconfport='8081')
406
407     def test_netvirt_no_controller_ip(self):
408         os.environ["INSTALLER_TYPE"] = "netvirt"
409         self._test_missing_value()
410
411     def test_netvirt(self):
412         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
413         os.environ["INSTALLER_TYPE"] = "netvirt"
414         self._test_run(testcase.TestCase.EX_OK, None,
415                        odlip=self._sdn_controller_ip, odlwebport='8081',
416                        odlrestconfport='8081')
417
418     def test_compass(self):
419         os.environ["INSTALLER_TYPE"] = "compass"
420         self._test_run(testcase.TestCase.EX_OK, None,
421                        odlip=urllib.parse.urlparse(self._neutron_url).hostname,
422                        odlrestconfport='8080')
423
424     def test_daisy_no_controller_ip(self):
425         os.environ["INSTALLER_TYPE"] = "daisy"
426         self._test_missing_value()
427
428     def test_daisy(self):
429         os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
430         os.environ["INSTALLER_TYPE"] = "daisy"
431         self._test_run(testcase.TestCase.EX_OK, None,
432                        odlip=self._sdn_controller_ip, odlwebport='8181',
433                        odlrestconfport='8087')
434
435
436 class ODLArgParserTesting(ODLTesting):
437
438     """The class testing ODLParser."""
439     # pylint: disable=missing-docstring
440
441     def setUp(self):
442         self.parser = odl.ODLParser()
443         super(ODLArgParserTesting, self).setUp()
444
445     def test_default(self):
446         self.assertEqual(self.parser.parse_args(), self.defaultargs)
447
448     def test_basic(self):
449         self.defaultargs['neutronurl'] = self._neutron_url
450         self.defaultargs['odlip'] = self._sdn_controller_ip
451         self.assertEqual(
452             self.parser.parse_args(
453                 ["--neutronurl={}".format(self._neutron_url),
454                  "--odlip={}".format(self._sdn_controller_ip)]),
455             self.defaultargs)
456
457     @mock.patch('sys.stderr', new_callable=six.StringIO)
458     def test_fail(self, mock_method):
459         self.defaultargs['foo'] = 'bar'
460         with self.assertRaises(SystemExit):
461             self.parser.parse_args(["--foo=bar"])
462         self.assertTrue(mock_method.getvalue().startswith("usage:"))
463
464     def _test_arg(self, arg, value):
465         self.defaultargs[arg] = value
466         self.assertEqual(
467             self.parser.parse_args(["--{}={}".format(arg, value)]),
468             self.defaultargs)
469
470     def test_odlusername(self):
471         self._test_arg('odlusername', 'foo')
472
473     def test_odlpassword(self):
474         self._test_arg('odlpassword', 'foo')
475
476     def test_osauthurl(self):
477         self._test_arg('osauthurl', 'http://127.0.0.4:5000/v2')
478
479     def test_neutronurl(self):
480         self._test_arg('neutronurl', 'http://127.0.0.4:9696')
481
482     def test_osusername(self):
483         self._test_arg('osusername', 'foo')
484
485     def test_osuserdomainname(self):
486         self._test_arg('osuserdomainname', 'domain')
487
488     def test_osprojectname(self):
489         self._test_arg('osprojectname', 'foo')
490
491     def test_osprojectdomainname(self):
492         self._test_arg('osprojectdomainname', 'domain')
493
494     def test_ospassword(self):
495         self._test_arg('ospassword', 'foo')
496
497     def test_odlip(self):
498         self._test_arg('odlip', '127.0.0.4')
499
500     def test_odlwebport(self):
501         self._test_arg('odlwebport', '80')
502
503     def test_odlrestconfport(self):
504         self._test_arg('odlrestconfport', '80')
505
506     def test_pushtodb(self):
507         self.defaultargs['pushtodb'] = True
508         self.assertEqual(self.parser.parse_args(["--{}".format('pushtodb')]),
509                          self.defaultargs)
510
511     def test_multiple_args(self):
512         self.defaultargs['neutronurl'] = self._neutron_url
513         self.defaultargs['odlip'] = self._sdn_controller_ip
514         self.assertEqual(
515             self.parser.parse_args(
516                 ["--neutronurl={}".format(self._neutron_url),
517                  "--odlip={}".format(self._sdn_controller_ip)]),
518             self.defaultargs)
519
520
521 if __name__ == "__main__":
522     logging.disable(logging.CRITICAL)
523     unittest.main(verbosity=2)