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."""
18 from robot.errors import RobotError
20 from six.moves import urllib
21 from xtesting.core import testcase
23 from functest.opnfv_tests.sdn.odl import odl
25 __author__ = "Cedric Ollivier <cedric.ollivier@orange.com>"
28 class ODLTesting(unittest.TestCase):
30 """The super class which testing classes could inherit."""
31 # pylint: disable=missing-docstring
33 logging.disable(logging.CRITICAL)
35 _keystone_ip = "127.0.0.1"
36 _neutron_url = "https://127.0.0.1:9696"
38 _sdn_controller_ip = "127.0.0.3"
39 _os_auth_url = f"http://{_keystone_ip}:5000/v3"
40 _os_projectname = "admin"
41 _os_username = "admin"
42 _os_password = "admin"
44 _odl_restconfport = "8181"
45 _odl_username = "admin"
46 _odl_password = "admin"
47 _os_userdomainname = 'Default'
48 _os_projectdomainname = 'Default'
49 _os_interface = "public"
52 for var in ("SDN_CONTROLLER", "SDN_CONTROLLER_IP"):
55 os.environ["OS_AUTH_URL"] = self._os_auth_url
56 os.environ["OS_USERNAME"] = self._os_username
57 os.environ["OS_USER_DOMAIN_NAME"] = self._os_userdomainname
58 os.environ["OS_PASSWORD"] = self._os_password
59 os.environ["OS_PROJECT_NAME"] = self._os_projectname
60 os.environ["OS_PROJECT_DOMAIN_NAME"] = self._os_projectdomainname
61 os.environ["OS_PASSWORD"] = self._os_password
62 os.environ["OS_INTERFACE"] = self._os_interface
63 self.test = odl.ODLTests(case_name='odl', project_name='functest')
64 self.defaultargs = {'odlusername': self._odl_username,
65 'odlpassword': self._odl_password,
66 'neutronurl': f"http://{self._keystone_ip}:9696",
67 'osauthurl': self._os_auth_url,
68 'osusername': self._os_username,
69 'osuserdomainname': self._os_userdomainname,
70 'osprojectname': self._os_projectname,
71 'osprojectdomainname': self._os_projectdomainname,
72 'ospassword': self._os_password,
73 'odlip': self._keystone_ip,
74 'odlwebport': self._odl_webport,
75 'odlrestconfport': self._odl_restconfport,
79 class ODLRobotTesting(ODLTesting):
81 """The class testing ODLTests.set_robotframework_vars()."""
82 # pylint: disable=missing-docstring
84 @mock.patch('fileinput.input', side_effect=Exception())
85 def test_set_vars_ko(self, mock_method):
86 self.assertFalse(self.test.set_robotframework_vars())
87 mock_method.assert_called_once_with(
88 os.path.join(odl.ODLTests.odl_test_repo,
89 'csit/variables/Variables.robot'), inplace=True)
91 @mock.patch('fileinput.input', return_value=[])
92 def test_set_vars_empty(self, mock_method):
93 self.assertTrue(self.test.set_robotframework_vars())
94 mock_method.assert_called_once_with(
95 os.path.join(odl.ODLTests.odl_test_repo,
96 'csit/variables/Variables.robot'), inplace=True)
98 @mock.patch('sys.stdout', new_callable=six.StringIO)
99 def _test_set_vars(self, msg1, msg2, *args):
100 line = mock.MagicMock()
101 line.__iter__.return_value = [msg1]
102 with mock.patch('fileinput.input', return_value=line) as mock_method:
103 self.assertTrue(self.test.set_robotframework_vars())
104 mock_method.assert_called_once_with(
105 os.path.join(odl.ODLTests.odl_test_repo,
106 'csit/variables/Variables.robot'), inplace=True)
107 self.assertEqual(args[0].getvalue(), f"{msg2}\n")
109 def test_set_vars_auth_default(self):
112 "@{AUTH} admin admin")
114 def test_set_vars_auth1(self):
119 @mock.patch('sys.stdout', new_callable=six.StringIO)
120 def test_set_vars_auth_foo(self, *args):
121 line = mock.MagicMock()
122 line.__iter__.return_value = ["@{AUTH} "]
123 with mock.patch('fileinput.input', return_value=line) as mock_method:
124 self.assertTrue(self.test.set_robotframework_vars('foo', 'bar'))
125 mock_method.assert_called_once_with(
126 os.path.join(odl.ODLTests.odl_test_repo,
127 'csit/variables/Variables.robot'), inplace=True)
133 class ODLMainTesting(ODLTesting):
135 """The class testing ODLTests.run_suites()."""
136 # pylint: disable=missing-docstring
138 def _get_run_suites_kwargs(self, key=None):
139 kwargs = {'odlusername': self._odl_username,
140 'odlpassword': self._odl_password,
141 'neutronurl': self._neutron_url,
142 'osauthurl': self._os_auth_url,
143 'osusername': self._os_username,
144 'osuserdomainname': self._os_userdomainname,
145 'osprojectname': self._os_projectname,
146 'osprojectdomainname': self._os_projectdomainname,
147 'ospassword': self._os_password,
148 'odlip': self._sdn_controller_ip,
149 'odlwebport': self._odl_webport,
150 'odlrestconfport': self._odl_restconfport}
155 def _test_run_suites(self, status, *args):
156 kwargs = self._get_run_suites_kwargs()
157 self.assertEqual(self.test.run_suites(**kwargs), status)
159 args[0].assert_called_once_with(self.test.odl_variables_file)
163 f'{urllib.parse.urlparse(self._os_auth_url).scheme}://'
164 f'{urllib.parse.urlparse(self._os_auth_url).netloc}'),
165 f'NEUTRONURL:{self._neutron_url}',
166 f'OS_AUTH_URL:"{self._os_auth_url}"',
167 f'OSUSERNAME:"{self._os_username}"',
168 f'OSUSERDOMAINNAME:"{self._os_userdomainname}"',
169 f'OSTENANTNAME:"{self._os_projectname}"',
170 f'OSPROJECTDOMAINNAME:"{self._os_projectdomainname}"',
171 f'OSPASSWORD:"{self._os_password}"',
172 f'ODL_SYSTEM_IP:{self._sdn_controller_ip}',
173 f'PORT:{self._odl_webport}',
174 f'RESTCONFPORT:{self._odl_restconfport}']
175 args[1].assert_called_once_with(
176 odl.ODLTests.basic_suite_dir, odl.ODLTests.neutron_suite_dir,
179 output=os.path.join(self.test.res_dir, 'output.xml'),
180 report='NONE', stdout=mock.ANY, variable=variable,
183 def _test_no_keyword(self, key):
184 kwargs = self._get_run_suites_kwargs(key)
185 self.assertEqual(self.test.run_suites(**kwargs),
186 testcase.TestCase.EX_RUN_ERROR)
188 def test_no_odlusername(self):
189 self._test_no_keyword('odlusername')
191 def test_no_odlpassword(self):
192 self._test_no_keyword('odlpassword')
194 def test_no_neutronurl(self):
195 self._test_no_keyword('neutronurl')
197 def test_no_osauthurl(self):
198 self._test_no_keyword('osauthurl')
200 def test_no_osusername(self):
201 self._test_no_keyword('osusername')
203 def test_no_osprojectname(self):
204 self._test_no_keyword('osprojectname')
206 def test_no_ospassword(self):
207 self._test_no_keyword('ospassword')
209 def test_no_odlip(self):
210 self._test_no_keyword('odlip')
212 def test_no_odlwebport(self):
213 self._test_no_keyword('odlwebport')
215 def test_no_odlrestconfport(self):
216 self._test_no_keyword('odlrestconfport')
218 @mock.patch('os.path.isfile', return_value=True)
219 def test_set_vars_ko(self, *args):
220 with mock.patch.object(self.test, 'set_robotframework_vars',
221 return_value=False) as mock_object:
222 self._test_run_suites(testcase.TestCase.EX_RUN_ERROR)
223 mock_object.assert_called_once_with(
224 self._odl_username, self._odl_password)
225 args[0].assert_called_once_with(self.test.odl_variables_file)
227 @mock.patch('os.makedirs')
228 @mock.patch('robot.run', side_effect=RobotError)
229 @mock.patch('os.path.isfile', return_value=True)
230 def test_run_ko(self, *args):
231 with mock.patch.object(self.test, 'set_robotframework_vars',
232 return_value=True), \
233 self.assertRaises(RobotError):
234 self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, *args)
236 @mock.patch('os.makedirs')
237 @mock.patch('robot.run')
238 @mock.patch('os.path.isfile', return_value=True)
239 def test_parse_results_ko(self, *args):
240 with mock.patch.object(self.test, 'set_robotframework_vars',
241 return_value=True), \
242 mock.patch.object(self.test, 'parse_results',
243 side_effect=RobotError):
244 self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, *args)
246 @mock.patch('os.makedirs')
247 @mock.patch('robot.run')
248 @mock.patch('os.path.isfile', return_value=True)
249 def test_generate_report_ko(self, *args):
250 with mock.patch.object(self.test, 'set_robotframework_vars',
251 return_value=True), \
252 mock.patch.object(self.test, 'parse_results'), \
253 mock.patch.object(self.test, 'generate_report',
255 self._test_run_suites(testcase.TestCase.EX_OK, *args)
257 @mock.patch('os.makedirs')
258 @mock.patch('robot.run')
259 @mock.patch('os.path.isfile', return_value=True)
260 def test_generate_report_exc(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 mock.patch.object(self.test, 'generate_report',
265 side_effect=Exception):
266 self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, *args)
268 @mock.patch('os.makedirs')
269 @mock.patch('robot.run')
270 @mock.patch('os.path.isfile', return_value=True)
271 def test_ok(self, *args):
272 with mock.patch.object(self.test, 'set_robotframework_vars',
273 return_value=True), \
274 mock.patch.object(self.test, 'parse_results'), \
275 mock.patch.object(self.test, 'generate_report',
277 self._test_run_suites(testcase.TestCase.EX_OK, *args)
279 @mock.patch('os.makedirs')
280 @mock.patch('robot.run')
281 @mock.patch('os.path.isfile', return_value=False)
282 def test_ok_no_creds(self, *args):
283 with mock.patch.object(self.test, 'set_robotframework_vars',
284 return_value=True) as mock_method, \
285 mock.patch.object(self.test, 'parse_results'), \
286 mock.patch.object(self.test, 'generate_report',
288 self._test_run_suites(testcase.TestCase.EX_OK, *args)
289 mock_method.assert_not_called()
291 @mock.patch('os.makedirs')
292 @mock.patch('robot.run', return_value=1)
293 @mock.patch('os.path.isfile', return_value=True)
294 def test_testcases_in_failure(self, *args):
295 with mock.patch.object(self.test, 'set_robotframework_vars',
296 return_value=True), \
297 mock.patch.object(self.test, 'parse_results'), \
298 mock.patch.object(self.test, 'generate_report',
300 self._test_run_suites(testcase.TestCase.EX_OK, *args)
303 class ODLRunTesting(ODLTesting):
304 """The class testing ODLTests.run()."""
305 # pylint: disable=too-many-public-methods,missing-docstring
307 @mock.patch('os_client_config.make_shade', side_effect=Exception)
308 def test_no_cloud(self, *args):
309 self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
310 args[0].assert_called_once_with()
312 @mock.patch('os_client_config.make_shade')
313 def test_no_service1(self, *args):
314 args[0].return_value.search_services.return_value = None
315 self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
316 args[0].return_value.search_services.assert_called_once_with('neutron')
317 args[0].return_value.search_endpoints.assert_not_called()
319 @mock.patch('os_client_config.make_shade')
320 def test_no_service2(self, *args):
321 args[0].return_value.search_services.return_value = []
322 self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
323 args[0].return_value.search_services.assert_called_once_with('neutron')
324 args[0].return_value.search_endpoints.assert_not_called()
326 @mock.patch('os_client_config.make_shade')
327 def test_no_service3(self, *args):
328 args[0].return_value.search_services.return_value = [
330 self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
331 args[0].return_value.search_services.assert_called_once_with('neutron')
332 args[0].return_value.search_endpoints.assert_not_called()
334 @mock.patch('os_client_config.make_shade')
335 def test_no_endpoint1(self, *args):
336 args[0].return_value.search_services.return_value = [
337 munch.Munch(id=self._neutron_id)]
338 args[0].return_value.search_endpoints.return_value = None
339 self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
340 args[0].return_value.search_services.assert_called_once_with('neutron')
341 args[0].return_value.search_endpoints.assert_called_once_with(
342 filters={'interface': self._os_interface,
343 'service_id': self._neutron_id})
345 @mock.patch('os_client_config.make_shade')
346 def test_no_endpoint2(self, *args):
347 args[0].return_value.search_services.return_value = [
348 munch.Munch(id=self._neutron_id)]
349 args[0].return_value.search_endpoints.return_value = []
350 self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
351 args[0].return_value.search_services.assert_called_once_with('neutron')
352 args[0].return_value.search_endpoints.assert_called_once_with(
353 filters={'interface': self._os_interface,
354 'service_id': self._neutron_id})
356 @mock.patch('os_client_config.make_shade')
357 def test_no_endpoint3(self, *args):
358 args[0].return_value.search_services.return_value = [
359 munch.Munch(id=self._neutron_id)]
360 args[0].return_value.search_endpoints.return_value = [munch.Munch()]
361 self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
362 args[0].return_value.search_services.assert_called_once_with('neutron')
363 args[0].return_value.search_endpoints.assert_called_once_with(
364 filters={'interface': self._os_interface,
365 'service_id': self._neutron_id})
367 @mock.patch('os_client_config.make_shade')
368 def test_endpoint_interface(self, *args):
369 args[0].return_value.search_services.return_value = [
370 munch.Munch(id=self._neutron_id)]
371 args[0].return_value.search_endpoints.return_value = [munch.Munch()]
372 self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
373 args[0].return_value.search_services.assert_called_once_with('neutron')
374 args[0].return_value.search_endpoints.assert_called_once_with(
375 filters={'interface': self._os_interface,
376 'service_id': self._neutron_id})
378 @mock.patch('os_client_config.make_shade')
379 def _test_no_env_var(self, var, *args):
381 self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
382 args[0].assert_called_once_with()
384 @mock.patch('os_client_config.make_shade')
385 def _test_missing_value(self, *args):
386 self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR)
387 args[0].assert_called_once_with()
389 @mock.patch('os_client_config.make_shade')
390 def _test_run(self, status=testcase.TestCase.EX_OK,
391 exception=None, *args, **kwargs):
392 # pylint: disable=keyword-arg-before-vararg
393 args[0].return_value.search_services.return_value = [
394 munch.Munch(id=self._neutron_id)]
395 args[0].return_value.search_endpoints.return_value = [
396 munch.Munch(url=self._neutron_url)]
397 odlip = kwargs['odlip'] if 'odlip' in kwargs else '127.0.0.3'
398 odlwebport = kwargs['odlwebport'] if 'odlwebport' in kwargs else '8080'
399 odlrestconfport = (kwargs['odlrestconfport']
400 if 'odlrestconfport' in kwargs else '8181')
402 self.test.run_suites = mock.Mock(side_effect=exception)
404 self.test.run_suites = mock.Mock(return_value=status)
405 self.assertEqual(self.test.run(), status)
406 self.test.run_suites.assert_called_once_with(
407 odl.ODLTests.default_suites, neutronurl=self._neutron_url,
408 odlip=odlip, odlpassword=self._odl_password,
409 odlrestconfport=odlrestconfport, odlusername=self._odl_username,
410 odlwebport=odlwebport, osauthurl=self._os_auth_url,
411 ospassword=self._os_password, osprojectname=self._os_projectname,
412 osusername=self._os_username,
413 osprojectdomainname=self._os_projectdomainname,
414 osuserdomainname=self._os_userdomainname)
415 args[0].assert_called_once_with()
416 args[0].return_value.search_services.assert_called_once_with('neutron')
417 args[0].return_value.search_endpoints.assert_called_once_with(
419 'interface': os.environ.get(
420 "OS_INTERFACE", "public").replace('URL', ''),
421 'service_id': self._neutron_id})
423 @mock.patch('os_client_config.make_shade')
424 def _test_multiple_suites(self, suites,
425 status=testcase.TestCase.EX_OK, *args, **kwargs):
426 # pylint: disable=keyword-arg-before-vararg
427 args[0].return_value.search_endpoints.return_value = [
428 munch.Munch(url=self._neutron_url)]
429 args[0].return_value.search_services.return_value = [
430 munch.Munch(id=self._neutron_id)]
431 odlip = kwargs['odlip'] if 'odlip' in kwargs else '127.0.0.3'
432 odlwebport = kwargs['odlwebport'] if 'odlwebport' in kwargs else '8080'
433 odlrestconfport = (kwargs['odlrestconfport']
434 if 'odlrestconfport' in kwargs else '8181')
435 self.test.run_suites = mock.Mock(return_value=status)
436 self.assertEqual(self.test.run(suites=suites), status)
437 self.test.run_suites.assert_called_once_with(
438 suites, neutronurl=self._neutron_url, odlip=odlip,
439 odlpassword=self._odl_password, odlrestconfport=odlrestconfport,
440 odlusername=self._odl_username, odlwebport=odlwebport,
441 osauthurl=self._os_auth_url, ospassword=self._os_password,
442 osprojectname=self._os_projectname, osusername=self._os_username,
443 osprojectdomainname=self._os_projectdomainname,
444 osuserdomainname=self._os_userdomainname)
445 args[0].assert_called_once_with()
446 args[0].return_value.search_services.assert_called_once_with('neutron')
447 args[0].return_value.search_endpoints.assert_called_once_with(
448 filters={'interface': os.environ.get("OS_INTERFACE", "public"),
449 'service_id': self._neutron_id})
452 with mock.patch('os_client_config.make_shade',
453 side_effect=Exception()):
454 self.assertEqual(self.test.run(),
455 testcase.TestCase.EX_RUN_ERROR)
457 def test_no_os_auth_url(self):
458 self._test_no_env_var("OS_AUTH_URL")
460 def test_no_os_username(self):
461 self._test_no_env_var("OS_USERNAME")
463 def test_no_os_password(self):
464 self._test_no_env_var("OS_PASSWORD")
466 def test_no_os__name(self):
467 self._test_no_env_var("OS_PROJECT_NAME")
469 def test_run_suites_false(self):
470 os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
471 self._test_run(testcase.TestCase.EX_RUN_ERROR, None,
472 odlip=self._sdn_controller_ip,
473 odlwebport=self._odl_webport)
475 def test_run_suites_exc(self):
476 with self.assertRaises(Exception):
477 os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
478 self._test_run(testcase.TestCase.EX_RUN_ERROR,
480 odlip=self._sdn_controller_ip,
481 odlwebport=self._odl_webport)
483 def test_no_sdn_controller_ip(self):
484 self._test_missing_value()
486 def test_without_installer_type(self):
487 os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
488 self._test_run(testcase.TestCase.EX_OK, None,
489 odlip=self._sdn_controller_ip,
490 odlwebport=self._odl_webport)
492 def test_without_os_interface(self):
493 del os.environ["OS_INTERFACE"]
494 os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
495 self._test_run(testcase.TestCase.EX_OK, None,
496 odlip=self._sdn_controller_ip,
497 odlwebport=self._odl_webport)
499 def test_os_interface_public(self):
500 os.environ["OS_INTERFACE"] = "public"
501 os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
502 self._test_run(testcase.TestCase.EX_OK, None,
503 odlip=self._sdn_controller_ip,
504 odlwebport=self._odl_webport)
506 def test_os_interface_publicurl(self):
507 os.environ["OS_INTERFACE"] = "publicURL"
508 os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
509 self._test_run(testcase.TestCase.EX_OK, None,
510 odlip=self._sdn_controller_ip,
511 odlwebport=self._odl_webport)
513 def test_os_interface_internal(self):
514 os.environ["OS_INTERFACE"] = "internal"
515 os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
516 self._test_run(testcase.TestCase.EX_OK, None,
517 odlip=self._sdn_controller_ip,
518 odlwebport=self._odl_webport)
520 def test_os_interface_admin(self):
521 os.environ["OS_INTERFACE"] = "admin"
522 os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
523 self._test_run(testcase.TestCase.EX_OK, None,
524 odlip=self._sdn_controller_ip,
525 odlwebport=self._odl_webport)
527 def test_suites(self):
528 os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip
529 self._test_multiple_suites(
530 [odl.ODLTests.basic_suite_dir],
531 testcase.TestCase.EX_OK,
532 odlip=self._sdn_controller_ip,
533 odlwebport=self._odl_webport)
536 class ODLArgParserTesting(ODLTesting):
538 """The class testing ODLParser."""
539 # pylint: disable=missing-docstring
542 self.parser = odl.ODLParser()
545 def test_default(self):
546 self.assertEqual(self.parser.parse_args(), self.defaultargs)
548 def test_basic(self):
549 self.defaultargs['neutronurl'] = self._neutron_url
550 self.defaultargs['odlip'] = self._sdn_controller_ip
552 self.parser.parse_args(
553 [f"--neutronurl={self._neutron_url}",
554 f"--odlip={self._sdn_controller_ip}"]),
557 @mock.patch('sys.stderr', new_callable=six.StringIO)
558 def test_fail(self, mock_method):
559 self.defaultargs['foo'] = 'bar'
560 with self.assertRaises(SystemExit):
561 self.parser.parse_args(["--foo=bar"])
562 self.assertTrue(mock_method.getvalue().startswith("usage:"))
564 def _test_arg(self, arg, value):
565 self.defaultargs[arg] = value
567 self.parser.parse_args([f"--{arg}={value}"]),
570 def test_odlusername(self):
571 self._test_arg('odlusername', 'foo')
573 def test_odlpassword(self):
574 self._test_arg('odlpassword', 'foo')
576 def test_osauthurl(self):
577 self._test_arg('osauthurl', 'http://127.0.0.4:5000/v2')
579 def test_neutronurl(self):
580 self._test_arg('neutronurl', 'http://127.0.0.4:9696')
582 def test_osusername(self):
583 self._test_arg('osusername', 'foo')
585 def test_osuserdomainname(self):
586 self._test_arg('osuserdomainname', 'domain')
588 def test_osprojectname(self):
589 self._test_arg('osprojectname', 'foo')
591 def test_osprojectdomainname(self):
592 self._test_arg('osprojectdomainname', 'domain')
594 def test_ospassword(self):
595 self._test_arg('ospassword', 'foo')
597 def test_odlip(self):
598 self._test_arg('odlip', '127.0.0.4')
600 def test_odlwebport(self):
601 self._test_arg('odlwebport', '80')
603 def test_odlrestconfport(self):
604 self._test_arg('odlrestconfport', '80')
606 def test_pushtodb(self):
607 self.defaultargs['pushtodb'] = True
608 self.assertEqual(self.parser.parse_args(["--pushtodb"]),
611 def test_multiple_args(self):
612 self.defaultargs['neutronurl'] = self._neutron_url
613 self.defaultargs['odlip'] = self._sdn_controller_ip
615 self.parser.parse_args(
616 [f"--neutronurl={self._neutron_url}",
617 f"--odlip={self._sdn_controller_ip}"]),
621 if __name__ == "__main__":
622 logging.disable(logging.CRITICAL)
623 unittest.main(verbosity=2)