3 # Copyright (c) 2016 Orange and others.
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
10 """Define the classes required to fully cover odl."""
17 from robot.errors import RobotError
19 from six.moves import urllib
21 from functest.core import testcase
22 from functest.opnfv_tests.sdn.odl import odl
24 __author__ = "Cedric Ollivier <cedric.ollivier@orange.com>"
27 class ODLTesting(unittest.TestCase):
29 """The super class which testing classes could inherit."""
30 # pylint: disable=missing-docstring
32 logging.disable(logging.CRITICAL)
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"
42 _odl_restconfport = "8181"
43 _odl_username = "admin"
44 _odl_password = "admin"
45 _os_userdomainname = 'Default'
46 _os_projectdomainname = 'Default'
49 for var in ("INSTALLER_TYPE", "SDN_CONTROLLER", "SDN_CONTROLLER_IP"):
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(
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,
76 class ODLRobotTesting(ODLTesting):
78 """The class testing ODLTests.set_robotframework_vars()."""
79 # pylint: disable=missing-docstring
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)
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)
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))
106 def test_set_vars_auth_default(self):
109 "@{AUTH} admin admin")
111 def test_set_vars_auth1(self):
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)
130 class ODLMainTesting(ODLTesting):
132 """The class testing ODLTests.run_suites()."""
133 # pylint: disable=missing-docstring
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}
152 def _test_run_suites(self, status, *args):
153 kwargs = self._get_run_suites_kwargs()
154 self.assertEqual(self.test.run_suites(**kwargs), status)
156 args[0].assert_called_once_with(self.test.odl_variables_file)
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,
175 output=os.path.join(self.test.res_dir, 'output.xml'),
176 report='NONE', stdout=mock.ANY, variable=variable,
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)
184 def test_no_odlusername(self):
185 self._test_no_keyword('odlusername')
187 def test_no_odlpassword(self):
188 self._test_no_keyword('odlpassword')
190 def test_no_neutronurl(self):
191 self._test_no_keyword('neutronurl')
193 def test_no_osauthurl(self):
194 self._test_no_keyword('osauthurl')
196 def test_no_osusername(self):
197 self._test_no_keyword('osusername')
199 def test_no_osprojectname(self):
200 self._test_no_keyword('osprojectname')
202 def test_no_ospassword(self):
203 self._test_no_keyword('ospassword')
205 def test_no_odlip(self):
206 self._test_no_keyword('odlip')
208 def test_no_odlwebport(self):
209 self._test_no_keyword('odlwebport')
211 def test_no_odlrestconfport(self):
212 self._test_no_keyword('odlrestconfport')
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)
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)
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)
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)
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()
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)
266 class ODLRunTesting(ODLTesting):
268 """The class testing ODLTests.run()."""
269 # pylint: disable=missing-docstring
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.'
275 def _test_no_env_var(self, var, *args):
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')
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.'
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')
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.'
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')
301 self.test.run_suites = mock.Mock(side_effect=exception)
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')
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.'
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')
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)
346 def test_no_os_auth_url(self):
347 self._test_no_env_var("OS_AUTH_URL")
349 def test_no_os_username(self):
350 self._test_no_env_var("OS_USERNAME")
352 def test_no_os_password(self):
353 self._test_no_env_var("OS_PASSWORD")
355 def test_no_os__name(self):
356 self._test_no_env_var("OS_PROJECT_NAME")
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)
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,
369 odlip=self._sdn_controller_ip,
370 odlwebport=self._odl_webport)
372 def test_no_sdn_controller_ip(self):
373 self._test_missing_value()
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)
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)
390 os.environ["INSTALLER_TYPE"] = "fuel"
391 self._test_run(testcase.TestCase.EX_OK, None,
392 odlip=urllib.parse.urlparse(self._neutron_url).hostname,
394 odlrestconfport='8282')
396 def test_apex_no_controller_ip(self):
397 os.environ["INSTALLER_TYPE"] = "apex"
398 self._test_missing_value()
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')
407 def test_netvirt_no_controller_ip(self):
408 os.environ["INSTALLER_TYPE"] = "netvirt"
409 self._test_missing_value()
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')
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')
424 def test_daisy_no_controller_ip(self):
425 os.environ["INSTALLER_TYPE"] = "daisy"
426 self._test_missing_value()
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')
436 class ODLArgParserTesting(ODLTesting):
438 """The class testing ODLParser."""
439 # pylint: disable=missing-docstring
442 self.parser = odl.ODLParser()
443 super(ODLArgParserTesting, self).setUp()
445 def test_default(self):
446 self.assertEqual(self.parser.parse_args(), self.defaultargs)
448 def test_basic(self):
449 self.defaultargs['neutronurl'] = self._neutron_url
450 self.defaultargs['odlip'] = self._sdn_controller_ip
452 self.parser.parse_args(
453 ["--neutronurl={}".format(self._neutron_url),
454 "--odlip={}".format(self._sdn_controller_ip)]),
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:"))
464 def _test_arg(self, arg, value):
465 self.defaultargs[arg] = value
467 self.parser.parse_args(["--{}={}".format(arg, value)]),
470 def test_odlusername(self):
471 self._test_arg('odlusername', 'foo')
473 def test_odlpassword(self):
474 self._test_arg('odlpassword', 'foo')
476 def test_osauthurl(self):
477 self._test_arg('osauthurl', 'http://127.0.0.4:5000/v2')
479 def test_neutronurl(self):
480 self._test_arg('neutronurl', 'http://127.0.0.4:9696')
482 def test_osusername(self):
483 self._test_arg('osusername', 'foo')
485 def test_osuserdomainname(self):
486 self._test_arg('osuserdomainname', 'domain')
488 def test_osprojectname(self):
489 self._test_arg('osprojectname', 'foo')
491 def test_osprojectdomainname(self):
492 self._test_arg('osprojectdomainname', 'domain')
494 def test_ospassword(self):
495 self._test_arg('ospassword', 'foo')
497 def test_odlip(self):
498 self._test_arg('odlip', '127.0.0.4')
500 def test_odlwebport(self):
501 self._test_arg('odlwebport', '80')
503 def test_odlrestconfport(self):
504 self._test_arg('odlrestconfport', '80')
506 def test_pushtodb(self):
507 self.defaultargs['pushtodb'] = True
508 self.assertEqual(self.parser.parse_args(["--{}".format('pushtodb')]),
511 def test_multiple_args(self):
512 self.defaultargs['neutronurl'] = self._neutron_url
513 self.defaultargs['odlip'] = self._sdn_controller_ip
515 self.parser.parse_args(
516 ["--neutronurl={}".format(self._neutron_url),
517 "--odlip={}".format(self._sdn_controller_ip)]),
521 if __name__ == "__main__":
522 logging.disable(logging.CRITICAL)
523 unittest.main(verbosity=2)