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