1 ##############################################################################
2 # Copyright (c) 2016 Dan Radez (dradez@redhat.com) (Red Hat)
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
14 from mock import patch
15 from mock import MagicMock
16 from mock import mock_open
17 from io import StringIO
19 from apex.common import constants as con
20 from apex.common.exceptions import ApexDeployException
21 from apex.overcloud.deploy import build_sdn_env_list
22 from apex.overcloud.deploy import create_deploy_cmd
23 from apex.overcloud.deploy import prep_image
24 from apex.overcloud.deploy import make_ssh_key
25 from apex.overcloud.deploy import prep_env
26 from apex.overcloud.deploy import generate_ceph_key
27 from apex.overcloud.deploy import prep_storage_env
28 from apex.overcloud.deploy import prep_sriov_env
29 from apex.overcloud.deploy import external_network_cmds
30 from apex.overcloud.deploy import create_congress_cmds
31 from apex.overcloud.deploy import SDN_FILE_MAP
32 from apex.overcloud.deploy import get_docker_sdn_file
34 from nose.tools import (
35 assert_regexp_matches,
43 class TestOvercloudDeploy(unittest.TestCase):
46 """This method is run once for each class before any tests are run"""
49 def teardown_class(cls):
50 """This method is run once for each class _after_ all tests are run"""
53 """This method is run once before _each_ test method is executed"""
56 """This method is run once after _each_ test method is executed"""
58 def test_build_sdn_env_list(self):
59 ds = {'sdn_controller': 'opendaylight'}
60 sdn_map = {'opendaylight': 'test'}
61 res = '/usr/share/openstack-tripleo-heat-templates/environments/test'
62 assert_equal(build_sdn_env_list(ds, sdn_map), [res])
64 def test_build_sdn_env_list_dict(self):
65 ds = {'opendaylight': True,
66 'sdn_controller': None}
67 sdn_map = {'opendaylight': {}}
68 assert_equal(build_sdn_env_list(ds, sdn_map), [])
70 def test_build_sdn_env_list_tuple(self):
71 ds = {'opendaylight': 'test',
72 'sdn_controller': None}
73 sdn_map = {'opendaylight': ('test', 'test')}
74 res = '/usr/share/openstack-tripleo-heat-templates/environments/test'
75 assert_equal(build_sdn_env_list(ds, sdn_map), [res])
77 def test_build_sdn_env_list_with_string(self):
78 ds = {'sdn_controller': 'opendaylight',
80 prefix = '/usr/share/openstack-tripleo-heat-templates/environments'
81 res = [os.path.join(prefix, 'neutron-opendaylight.yaml'),
82 os.path.join(prefix, 'neutron-opendaylight-sriov.yaml')]
83 assert_equal(build_sdn_env_list(ds, SDN_FILE_MAP), res)
85 def test_build_sdn_env_list_with_default(self):
86 ds = {'sdn_controller': 'opendaylight',
88 prefix = '/usr/share/openstack-tripleo-heat-templates/environments'
89 res = [os.path.join(prefix, 'neutron-opendaylight.yaml'),
90 os.path.join(prefix, 'neutron-bgpvpn-opendaylight.yaml')]
91 assert_equal(build_sdn_env_list(ds, SDN_FILE_MAP), res)
93 @patch('apex.overcloud.deploy.prep_sriov_env')
94 @patch('apex.overcloud.deploy.prep_storage_env')
95 @patch('apex.overcloud.deploy.build_sdn_env_list')
96 @patch('builtins.open', mock_open())
97 def test_create_deploy_cmd(self, mock_sdn_list, mock_prep_storage,
99 mock_sdn_list.return_value = []
100 ds = {'deploy_options':
109 'global_params': MagicMock()}
111 ns = {'ntp': ['ntp']}
113 inv.get_node_counts.return_value = (3, 2)
115 result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
116 assert_in('--ntp-server ntp', result_cmd)
117 assert_in('enable_tacker.yaml', result_cmd)
118 assert_in('enable_congress.yaml', result_cmd)
119 assert_in('enable_barometer.yaml', result_cmd)
120 assert_in('virtual-environment.yaml', result_cmd)
121 assert_in('--control-scale 3', result_cmd)
122 assert_in('--compute-scale 2', result_cmd)
124 @patch('apex.overcloud.deploy.prep_sriov_env')
125 @patch('apex.overcloud.deploy.prep_storage_env')
126 @patch('builtins.open', mock_open())
127 def test_create_deploy_cmd_containers_sdn(self, mock_prep_storage,
129 ds = {'deploy_options':
136 'sdn_controller': 'opendaylight',
139 'global_params': MagicMock()}
141 ns = {'ntp': ['ntp']}
143 inv.get_node_counts.return_value = (3, 2)
145 result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
146 assert_in('--ntp-server ntp', result_cmd)
147 assert_not_in('enable_tacker.yaml', result_cmd)
148 assert_not_in('enable_congress.yaml', result_cmd)
149 assert_not_in('enable_barometer.yaml', result_cmd)
150 assert_in('virtual-environment.yaml', result_cmd)
151 assert_in('--control-scale 3', result_cmd)
152 assert_in('--compute-scale 2', result_cmd)
153 assert_in('docker-images.yaml', result_cmd)
154 assert_in('sdn-images.yaml', result_cmd)
155 assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
156 '/docker.yaml', result_cmd)
157 assert_in('/usr/share/openstack-tripleo-heat-templates/environments/'
158 'storage-environment.yaml', result_cmd)
159 assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
160 '/services-docker/neutron-opendaylight.yaml', result_cmd)
162 @patch('apex.overcloud.deploy.prep_sriov_env')
163 @patch('apex.overcloud.deploy.prep_storage_env')
164 @patch('apex.overcloud.deploy.build_sdn_env_list')
165 @patch('builtins.open', mock_open())
166 def test_create_deploy_cmd_no_ha_bm(self, mock_sdn_list,
167 mock_prep_storage, mock_prep_sriov):
168 mock_sdn_list.return_value = []
169 ds = {'deploy_options': MagicMock(),
170 'global_params': MagicMock()}
171 ds['global_params'].__getitem__.side_effect = \
172 lambda i: False if i == 'ha_enabled' else MagicMock()
173 ns = {'ntp': ['ntp']}
175 inv.get_node_counts.return_value = (3, 2)
177 result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
178 assert_in('--ntp-server ntp', result_cmd)
179 assert_in('--control-scale 1', result_cmd)
180 assert_in('--compute-scale 2', result_cmd)
181 assert_in('baremetal-environment.yaml', result_cmd)
182 assert_not_in('enable_tacker.yaml', result_cmd)
183 assert_not_in('enable_congress.yaml', result_cmd)
184 assert_not_in('enable_barometer.yaml', result_cmd)
186 @patch('apex.overcloud.deploy.prep_sriov_env')
187 @patch('apex.overcloud.deploy.prep_storage_env')
188 @patch('apex.overcloud.deploy.build_sdn_env_list')
189 def test_create_deploy_cmd_raises(self, mock_sdn_list, mock_prep_storage,
191 mock_sdn_list.return_value = []
192 ds = {'deploy_options': MagicMock(),
193 'global_params': MagicMock()}
196 inv.get_node_counts.return_value = (0, 0)
198 assert_raises(ApexDeployException, create_deploy_cmd,
199 ds, ns, inv, '/tmp', virt)
201 @patch('apex.overcloud.deploy.virt_utils')
202 @patch('apex.overcloud.deploy.shutil')
203 @patch('apex.overcloud.deploy.os.path')
204 @patch('builtins.open', mock_open())
205 def test_prep_image(self, mock_os_path, mock_shutil, mock_virt_utils):
206 ds_opts = {'dataplane': 'fdio',
207 'sdn_controller': 'opendaylight',
208 'odl_version': 'master',
210 ds = {'deploy_options': MagicMock(),
211 'global_params': MagicMock()}
212 ds['deploy_options'].__getitem__.side_effect = \
213 lambda i: ds_opts.get(i, MagicMock())
215 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
216 mock_virt_utils.virt_customize.assert_called()
218 @patch('apex.overcloud.deploy.virt_utils')
219 @patch('apex.overcloud.deploy.shutil')
220 @patch('apex.overcloud.deploy.os.path')
221 @patch('builtins.open', mock_open())
222 def test_prep_image_sdn_false(self, mock_os_path, mock_shutil,
224 ds_opts = {'dataplane': 'fdio',
225 'sdn_controller': False}
226 ds = {'deploy_options': MagicMock(),
227 'global_params': MagicMock()}
228 ds['deploy_options'].__getitem__.side_effect = \
229 lambda i: ds_opts.get(i, MagicMock())
231 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
232 mock_virt_utils.virt_customize.assert_called()
234 @patch('apex.overcloud.deploy.virt_utils')
235 @patch('apex.overcloud.deploy.shutil')
236 @patch('apex.overcloud.deploy.os.path')
237 @patch('builtins.open', mock_open())
238 def test_prep_image_sdn_odl(self, mock_os_path, mock_shutil,
240 ds_opts = {'dataplane': 'ovs',
241 'sdn_controller': 'opendaylight',
242 'odl_version': con.DEFAULT_ODL_VERSION,
243 'odl_vpp_netvirt': True}
244 ds = {'deploy_options': MagicMock(),
245 'global_params': MagicMock()}
246 ds['deploy_options'].__getitem__.side_effect = \
247 lambda i: ds_opts.get(i, MagicMock())
248 ds['deploy_options'].__contains__.side_effect = \
249 lambda i: True if i in ds_opts else MagicMock()
251 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
252 mock_virt_utils.virt_customize.assert_called()
254 @patch('apex.overcloud.deploy.c_builder')
255 @patch('apex.overcloud.deploy.oc_builder')
256 @patch('apex.overcloud.deploy.virt_utils')
257 @patch('apex.overcloud.deploy.shutil')
258 @patch('apex.overcloud.deploy.os.path')
259 @patch('builtins.open', mock_open())
260 def test_prep_image_sdn_odl_upstream_containers_patches(
261 self, mock_os_path, mock_shutil, mock_virt_utils,
262 mock_oc_builder, mock_c_builder):
263 ds_opts = {'dataplane': 'ovs',
264 'sdn_controller': 'opendaylight',
265 'odl_version': con.DEFAULT_ODL_VERSION,
266 'odl_vpp_netvirt': True}
267 ds = {'deploy_options': MagicMock(),
268 'global_params': MagicMock()}
269 ds['deploy_options'].__getitem__.side_effect = \
270 lambda i: ds_opts.get(i, MagicMock())
271 ds['deploy_options'].__contains__.side_effect = \
272 lambda i: True if i in ds_opts else MagicMock()
274 mock_c_builder.add_upstream_patches.return_value = ['nova-api']
275 patches = ['dummy_nova_patch']
276 rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
277 docker_tag='latest', patches=patches, upstream=True)
278 mock_oc_builder.inject_opendaylight.assert_called
279 mock_virt_utils.virt_customize.assert_called()
280 mock_c_builder.add_upstream_patches.assert_called
281 self.assertListEqual(sorted(rv), ['nova-api', 'opendaylight'])
283 @patch('apex.overcloud.deploy.virt_utils')
284 @patch('apex.overcloud.deploy.shutil')
285 @patch('apex.overcloud.deploy.os.path')
286 @patch('builtins.open', mock_open())
287 def test_prep_image_sdn_odl_not_def(self, mock_os_path,
288 mock_shutil, mock_virt_utils):
289 ds_opts = {'dataplane': 'ovs',
290 'sdn_controller': 'opendaylight',
291 'odl_version': 'uncommon'}
292 ds = {'deploy_options': MagicMock(),
293 'global_params': MagicMock()}
294 ds['deploy_options'].__getitem__.side_effect = \
295 lambda i: ds_opts.get(i, MagicMock())
297 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
298 mock_virt_utils.virt_customize.assert_called()
300 @patch('apex.overcloud.deploy.virt_utils')
301 @patch('apex.overcloud.deploy.shutil')
302 @patch('apex.overcloud.deploy.os.path')
303 @patch('builtins.open', mock_open())
304 def test_prep_image_sdn_ovn(self, mock_os_path, mock_shutil,
306 ds_opts = {'dataplane': 'ovs',
307 'sdn_controller': 'ovn'}
308 ds = {'deploy_options': MagicMock(),
309 'global_params': MagicMock()}
310 ds['deploy_options'].__getitem__.side_effect = \
311 lambda i: ds_opts.get(i, MagicMock())
313 prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
314 mock_virt_utils.virt_customize.assert_called()
316 @patch('apex.overcloud.deploy.os.path.isfile')
317 def test_prep_image_no_image(self, mock_isfile):
318 mock_isfile.return_value = False
319 assert_raises(ApexDeployException, prep_image,
320 {}, {}, 'undercloud.qcow2', '/tmp')
322 def test_make_ssh_key(self):
323 priv, pub = make_ssh_key()
324 assert_in('-----BEGIN PRIVATE KEY-----', priv)
325 assert_in('ssh-rsa', pub)
327 @patch('apex.overcloud.deploy.fileinput')
328 @patch('apex.overcloud.deploy.shutil')
329 def test_prep_env(self, mock_shutil, mock_fileinput):
330 mock_fileinput.input.return_value = \
331 ['CloudDomain', 'replace_private_key', 'replace_public_key',
332 'opendaylight::vpp_routing_node', 'ControllerExtraConfig',
333 'NovaComputeExtraConfig', 'ComputeKernelArgs', 'HostCpusList',
334 'ComputeExtraConfigPre', 'resource_registry',
335 'NovaSchedulerDefaultFilters']
336 ds = {'deploy_options':
337 {'sdn_controller': 'opendaylight',
338 'odl_vpp_routing_node': 'test',
339 'dataplane': 'ovs_dpdk',
341 'performance': {'Compute': {'vpp': {'main-core': 'test',
342 'corelist-workers': 'test'},
343 'ovs': {'dpdk_cores': 'test'},
344 'kernel': {'test': 'test'}},
345 'Controller': {'vpp': 'test'}}}}
346 ns = {'domain_name': 'test.domain',
349 {'nic_mapping': {'controller':
350 {'members': ['tenant_nic']},
352 {'members': ['tenant_nic']}}},
354 [{'nic_mapping': {'controller':
355 {'members': ['ext_nic']},
357 {'members': ['ext_nic']}}}]}}
361 saved_stdout = sys.stdout
365 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
366 output = out.getvalue().strip()
367 assert_in('CloudDomain: test.domain', output)
368 assert_in('ssh-rsa', output)
369 assert_in('ComputeKernelArgs: \'test=test \'', output)
370 assert_in('fdio::vpp_cpu_main_core: \'test\'', output)
373 sys.stdout = saved_stdout
375 @patch('apex.overcloud.deploy.fileinput')
376 @patch('apex.overcloud.deploy.shutil')
377 def test_prep_env_round_two(self, mock_shutil, mock_fileinput):
378 mock_fileinput.input.return_value = \
379 ['NeutronVPPAgentPhysnets']
380 ds = {'deploy_options':
381 {'sdn_controller': False,
384 'performance': {'Compute': {},
386 ns = {'domain_name': 'test.domain',
389 {'nic_mapping': {'controller':
390 {'members': ['tenant_nic']},
392 {'members': ['tenant_nic']}}},
394 [{'nic_mapping': {'controller':
395 {'members': ['ext_nic']},
397 {'members': ['ext_nic']}}}]}}
401 saved_stdout = sys.stdout
405 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
406 output = out.getvalue().strip()
407 assert_in('NeutronVPPAgentPhysnets: '
408 '\'datacentre:tenant_nic\'',
410 assert_in('NeutronVPPAgentPhysnets', output)
413 sys.stdout = saved_stdout
415 @patch('apex.overcloud.deploy.fileinput')
416 @patch('apex.overcloud.deploy.shutil')
417 def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
418 mock_fileinput.input.return_value = \
419 ['OS::TripleO::Services::NeutronDhcpAgent',
420 'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
421 ds = {'deploy_options':
422 {'sdn_controller': 'opendaylight',
426 ns = {'domain_name': 'test.domain',
429 {'nic_mapping': {'controller':
430 {'members': ['tenant_nic']},
432 {'members': ['tenant_nic']}}},
434 [{'nic_mapping': {'controller':
435 {'members': ['ext_nic']},
437 {'members': ['ext_nic']}}}]}}
439 inv.get_node_counts.return_value = (3, 2)
442 saved_stdout = sys.stdout
446 prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
447 output = out.getvalue().strip()
448 assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
451 sys.stdout = saved_stdout
453 def test_generate_ceph_key(self):
454 assert_equal(len(generate_ceph_key()), 40)
456 @patch('apex.overcloud.deploy.generate_ceph_key')
457 @patch('apex.overcloud.deploy.fileinput')
458 @patch('apex.overcloud.deploy.os.path.isfile')
459 @patch('builtins.open', mock_open())
460 def test_prep_storage_env(self, mock_isfile, mock_fileinput,
462 mock_fileinput.input.return_value = \
463 ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
464 ds = {'deploy_options': {
465 'ceph_device': '/dev/sdx',
469 prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
471 @patch('apex.overcloud.deploy.utils.edit_tht_env')
472 @patch('apex.overcloud.deploy.generate_ceph_key')
473 @patch('apex.overcloud.deploy.fileinput')
474 @patch('apex.overcloud.deploy.os.path.isfile')
475 @patch('builtins.open', mock_open())
476 def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
477 mock_ceph_key, mock_edit_tht):
478 mock_fileinput.input.return_value = \
479 ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
480 ds = {'deploy_options': {
481 'ceph_device': '/dev/sdx',
483 'os_version': 'master'
484 }, 'global_params': {'ha_enabled': False}}
485 ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
486 {'ip': '192.0.2.1'}}}
488 prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
490 'DockerCephDaemonImage':
491 '192.0.2.1:8787/ceph/daemon:tag-build-master-luminous-centos'
493 'CephPoolDefaultSize': 1,
494 'CephAnsibleExtraConfig': {
495 'centos_package_dependencies': [],
496 'ceph_osd_docker_memory_limit': '1g',
497 'ceph_mds_docker_memory_limit': '1g'
499 'CephPoolDefaultPgNum': 32,
500 'CephAnsibleDisksConfig': {
501 'devices': ['/dev/sdx'],
503 'osd_scenario': 'collocated'
506 mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
507 'parameter_defaults',
510 @patch('apex.overcloud.deploy.os.path.isfile')
511 @patch('builtins.open', mock_open())
512 def test_prep_storage_env_raises(self, mock_isfile):
513 mock_isfile.return_value = False
514 ds = {'deploy_options': MagicMock()}
516 assert_raises(ApexDeployException, prep_storage_env, ds,
517 ns, virtual=False, tmp_dir='/tmp')
519 @patch('apex.overcloud.deploy.generate_ceph_key')
520 @patch('apex.overcloud.deploy.fileinput')
521 @patch('apex.overcloud.deploy.os.path.isfile')
522 @patch('builtins.open', mock_open())
523 def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
524 ds = {'deploy_options':
525 {'sdn_controller': 'opendaylight',
529 saved_stdout = sys.stdout
533 mock_fileinput.input.return_value = \
534 ['# NovaSchedulerDefaultFilters',
535 '# NovaSchedulerAvailableFilters',
536 '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
537 '#NeutronSriovNumVFs: \"ens20f2:5\"',
538 '#NovaPCIPassthrough:',
539 '# - devname: \"ens20f2\"',
540 '# physical_network: \"datacentre\"']
541 prep_sriov_env(ds, '/tmp')
542 output = out.getvalue().strip()
543 assert_in('NovaSchedulerDefaultFilters', output)
544 assert_in('NovaSchedulerAvailableFilters', output)
545 assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
546 assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
547 assert_in('NovaPCIPassthrough:', output)
548 assert_in('- devname: \"xxx\"', output)
549 assert_in('physical_network: \"nfv_sriov\"', output)
552 sys.stdout = saved_stdout
554 @patch('apex.overcloud.deploy.os.path.isfile')
555 @patch('builtins.open', mock_open())
556 def test_prep_sriov_env_raises(self, mock_isfile):
557 ds_opts = {'sriov': True}
558 ds = {'deploy_options': MagicMock()}
559 ds['deploy_options'].__getitem__.side_effect = \
560 lambda i: ds_opts.get(i, MagicMock())
561 mock_isfile.return_value = False
562 ds = {'deploy_options': MagicMock()}
563 assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
565 def test_external_network_cmds(self):
566 ds = {'deploy_options':
567 {'sdn_controller': 'opendaylight',
572 ns_dict = {'networks':
573 {'external': [{'floating_ip_range': (0, 1),
575 {'compute': {'vlan': 'native'}},
579 ns.enabled_network_list = ['external']
580 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
581 cmds = ' '.join(external_network_cmds(ns, ds))
582 assert_in('--external', cmds)
583 assert_in('--allocation-pool start=0,end=1', cmds)
584 assert_in('--gateway gw', cmds)
585 assert_in('--network external', cmds)
586 assert_in('--provider-physical-network datacentre', cmds)
588 def test_external_network_cmds_nosdn_fdio(self):
589 ds = {'deploy_options':
590 {'sdn_controller': False,
591 'dataplane': 'fdio'}}
595 ns_dict = {'networks':
596 {'external': [{'floating_ip_range': (0, 1),
598 {'compute': {'vlan': 'native'}},
602 ns.enabled_network_list = ['external']
603 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
604 cmds = ' '.join(external_network_cmds(ns, ds))
605 assert_in('--external', cmds)
606 assert_in('--allocation-pool start=0,end=1', cmds)
607 assert_in('--gateway gw', cmds)
608 assert_in('--network external', cmds)
609 assert_in('--provider-physical-network external', cmds)
611 def test_external_network_cmds_no_ext(self):
612 ds = {'deploy_options':
613 {'sdn_controller': 'opendaylight',
621 {'introspection_range': (0, 1),
623 {'compute': {'vlan': '123'}},
627 ns.enabled_network_list = ['admin']
628 ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
629 cmds = ' '.join(external_network_cmds(ns, ds))
630 assert_in('--external', cmds)
631 assert_in('--allocation-pool start=0,end=1', cmds)
632 assert_in('--network external', cmds)
633 assert_in('--provider-network-type vlan', cmds)
635 @patch('apex.overcloud.deploy.parsers')
636 def test_create_congress_cmds(self, mock_parsers):
637 assert_greater(len(create_congress_cmds('overcloud_file')), 0)
639 @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
640 def test_create_congress_cmds_raises(self, mock_parsers):
641 mock_parsers.return_value.__getitem__.side_effect = KeyError()
642 assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
644 def test_get_docker_sdn_file(self):
645 ds_opts = {'ha_enabled': True,
651 'sdn_controller': 'opendaylight'
653 output = get_docker_sdn_file(ds_opts)
654 self.assertEqual(output,
655 ('/usr/share/openstack-tripleo-heat-templates'
656 '/environments/services-docker/neutron-opendaylight'