54f95bb7419d098463b5d5710a2dd91d193d53b7
[apex.git] / apex / tests / test_apex_overcloud_deploy.py
1 ##############################################################################
2 # Copyright (c) 2016 Dan Radez (dradez@redhat.com) (Red Hat)
3 #
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 ##############################################################################
9
10 import os
11 import sys
12 import unittest
13
14 from mock import patch
15 from mock import MagicMock
16 from mock import mock_open
17 from io import StringIO
18
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
33
34 from nose.tools import (
35     assert_regexp_matches,
36     assert_raises,
37     assert_in,
38     assert_not_in,
39     assert_greater,
40     assert_equal)
41
42
43 class TestOvercloudDeploy(unittest.TestCase):
44     @classmethod
45     def setup_class(cls):
46         """This method is run once for each class before any tests are run"""
47
48     @classmethod
49     def teardown_class(cls):
50         """This method is run once for each class _after_ all tests are run"""
51
52     def setup(self):
53         """This method is run once before _each_ test method is executed"""
54
55     def teardown(self):
56         """This method is run once after _each_ test method is executed"""
57
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])
63
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), [])
69
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])
76
77     def test_build_sdn_env_list_with_default(self):
78         ds = {'sdn_controller': 'opendaylight',
79               'vpn': True}
80         prefix = '/usr/share/openstack-tripleo-heat-templates/environments'
81         res = [os.path.join(prefix, 'neutron-opendaylight.yaml'),
82                os.path.join(prefix, 'neutron-bgpvpn-opendaylight.yaml')]
83         assert_equal(build_sdn_env_list(ds, SDN_FILE_MAP), res)
84
85     @patch('apex.overcloud.deploy.prep_sriov_env')
86     @patch('apex.overcloud.deploy.prep_storage_env')
87     @patch('apex.overcloud.deploy.build_sdn_env_list')
88     @patch('builtins.open', mock_open())
89     def test_create_deploy_cmd(self, mock_sdn_list, mock_prep_storage,
90                                mock_prep_sriov):
91         mock_sdn_list.return_value = []
92         ds = {'deploy_options':
93               {'ha_enabled': True,
94                'congress': True,
95                'tacker': True,
96                'containers': False,
97                'barometer': True,
98                'ceph': False,
99                'sriov': False
100                },
101               'global_params': MagicMock()}
102
103         ns = {'ntp': ['ntp']}
104         inv = MagicMock()
105         inv.get_node_counts.return_value = (3, 2)
106         virt = True
107         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
108         assert_in('--ntp-server ntp', result_cmd)
109         assert_in('enable_tacker.yaml', result_cmd)
110         assert_in('enable_congress.yaml', result_cmd)
111         assert_in('enable_barometer.yaml', result_cmd)
112         assert_in('virtual-environment.yaml', result_cmd)
113         assert_in('--control-scale 3', result_cmd)
114         assert_in('--compute-scale 2', result_cmd)
115
116     @patch('apex.overcloud.deploy.prep_sriov_env')
117     @patch('apex.overcloud.deploy.prep_storage_env')
118     @patch('builtins.open', mock_open())
119     def test_create_deploy_cmd_containers_sdn(self, mock_prep_storage,
120                                               mock_prep_sriov):
121         ds = {'deploy_options':
122               {'ha_enabled': True,
123                'congress': False,
124                'tacker': False,
125                'containers': True,
126                'barometer': False,
127                'ceph': True,
128                'sdn_controller': 'opendaylight',
129                'sriov': False
130                },
131               'global_params': MagicMock()}
132
133         ns = {'ntp': ['ntp']}
134         inv = MagicMock()
135         inv.get_node_counts.return_value = (3, 2)
136         virt = True
137         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
138         assert_in('--ntp-server ntp', result_cmd)
139         assert_not_in('enable_tacker.yaml', result_cmd)
140         assert_not_in('enable_congress.yaml', result_cmd)
141         assert_not_in('enable_barometer.yaml', result_cmd)
142         assert_in('virtual-environment.yaml', result_cmd)
143         assert_in('--control-scale 3', result_cmd)
144         assert_in('--compute-scale 2', result_cmd)
145         assert_in('docker-images.yaml', result_cmd)
146         assert_in('sdn-images.yaml', result_cmd)
147         assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
148                   '/docker.yaml', result_cmd)
149         assert_in('/usr/share/openstack-tripleo-heat-templates/environments/'
150                   'storage-environment.yaml', result_cmd)
151         assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
152                   '/services-docker/neutron-opendaylight.yaml', result_cmd)
153
154     @patch('apex.overcloud.deploy.prep_sriov_env')
155     @patch('apex.overcloud.deploy.prep_storage_env')
156     @patch('apex.overcloud.deploy.build_sdn_env_list')
157     @patch('builtins.open', mock_open())
158     def test_create_deploy_cmd_no_ha_bm(self, mock_sdn_list,
159                                         mock_prep_storage, mock_prep_sriov):
160         mock_sdn_list.return_value = []
161         ds = {'deploy_options': MagicMock(),
162               'global_params': MagicMock()}
163         ds['global_params'].__getitem__.side_effect = \
164             lambda i: False if i == 'ha_enabled' else MagicMock()
165         ns = {'ntp': ['ntp']}
166         inv = MagicMock()
167         inv.get_node_counts.return_value = (3, 2)
168         virt = False
169         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
170         assert_in('--ntp-server ntp', result_cmd)
171         assert_in('--control-scale 1', result_cmd)
172         assert_in('--compute-scale 2', result_cmd)
173         assert_in('baremetal-environment.yaml', result_cmd)
174         assert_not_in('enable_tacker.yaml', result_cmd)
175         assert_not_in('enable_congress.yaml', result_cmd)
176         assert_not_in('enable_barometer.yaml', result_cmd)
177
178     @patch('apex.overcloud.deploy.prep_sriov_env')
179     @patch('apex.overcloud.deploy.prep_storage_env')
180     @patch('apex.overcloud.deploy.build_sdn_env_list')
181     def test_create_deploy_cmd_raises(self, mock_sdn_list, mock_prep_storage,
182                                       mock_prep_sriov):
183         mock_sdn_list.return_value = []
184         ds = {'deploy_options': MagicMock(),
185               'global_params': MagicMock()}
186         ns = {}
187         inv = MagicMock()
188         inv.get_node_counts.return_value = (0, 0)
189         virt = False
190         assert_raises(ApexDeployException, create_deploy_cmd,
191                       ds, ns, inv, '/tmp', virt)
192
193     @patch('apex.overcloud.deploy.virt_utils')
194     @patch('apex.overcloud.deploy.shutil')
195     @patch('apex.overcloud.deploy.os.path')
196     @patch('builtins.open', mock_open())
197     def test_prep_image(self, mock_os_path, mock_shutil, mock_virt_utils):
198         ds_opts = {'dataplane': 'fdio',
199                    'sdn_controller': 'opendaylight',
200                    'odl_version': 'master',
201                    'sriov': False}
202         ds = {'deploy_options': MagicMock(),
203               'global_params': MagicMock()}
204         ds['deploy_options'].__getitem__.side_effect = \
205             lambda i: ds_opts.get(i, MagicMock())
206         ns = MagicMock()
207         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
208         mock_virt_utils.virt_customize.assert_called()
209
210     @patch('apex.overcloud.deploy.virt_utils')
211     @patch('apex.overcloud.deploy.shutil')
212     @patch('apex.overcloud.deploy.os.path')
213     @patch('builtins.open', mock_open())
214     def test_prep_image_sdn_false(self, mock_os_path, mock_shutil,
215                                   mock_virt_utils):
216         ds_opts = {'dataplane': 'fdio',
217                    'sdn_controller': False}
218         ds = {'deploy_options': MagicMock(),
219               'global_params': MagicMock()}
220         ds['deploy_options'].__getitem__.side_effect = \
221             lambda i: ds_opts.get(i, MagicMock())
222         ns = MagicMock()
223         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
224         mock_virt_utils.virt_customize.assert_called()
225
226     @patch('apex.overcloud.deploy.virt_utils')
227     @patch('apex.overcloud.deploy.shutil')
228     @patch('apex.overcloud.deploy.os.path')
229     @patch('builtins.open', mock_open())
230     def test_prep_image_sdn_odl(self, mock_os_path, mock_shutil,
231                                 mock_virt_utils):
232         ds_opts = {'dataplane': 'ovs',
233                    'sdn_controller': 'opendaylight',
234                    'odl_version': con.DEFAULT_ODL_VERSION,
235                    'odl_vpp_netvirt': True}
236         ds = {'deploy_options': MagicMock(),
237               'global_params': MagicMock()}
238         ds['deploy_options'].__getitem__.side_effect = \
239             lambda i: ds_opts.get(i, MagicMock())
240         ds['deploy_options'].__contains__.side_effect = \
241             lambda i: True if i in ds_opts else MagicMock()
242         ns = MagicMock()
243         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
244         mock_virt_utils.virt_customize.assert_called()
245
246     @patch('apex.overcloud.deploy.c_builder')
247     @patch('apex.overcloud.deploy.oc_builder')
248     @patch('apex.overcloud.deploy.virt_utils')
249     @patch('apex.overcloud.deploy.shutil')
250     @patch('apex.overcloud.deploy.os.path')
251     @patch('builtins.open', mock_open())
252     def test_prep_image_sdn_odl_upstream_containers_patches(
253             self, mock_os_path, mock_shutil, mock_virt_utils,
254             mock_oc_builder, mock_c_builder):
255         ds_opts = {'dataplane': 'ovs',
256                    'sdn_controller': 'opendaylight',
257                    'odl_version': con.DEFAULT_ODL_VERSION,
258                    'odl_vpp_netvirt': True}
259         ds = {'deploy_options': MagicMock(),
260               'global_params': MagicMock()}
261         ds['deploy_options'].__getitem__.side_effect = \
262             lambda i: ds_opts.get(i, MagicMock())
263         ds['deploy_options'].__contains__.side_effect = \
264             lambda i: True if i in ds_opts else MagicMock()
265         ns = MagicMock()
266         mock_c_builder.add_upstream_patches.return_value = ['nova-api']
267         patches = ['dummy_nova_patch']
268         rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
269                         docker_tag='latest', patches=patches, upstream=True)
270         mock_oc_builder.inject_opendaylight.assert_called
271         mock_virt_utils.virt_customize.assert_called()
272         mock_c_builder.add_upstream_patches.assert_called
273         self.assertListEqual(sorted(rv), ['nova-api', 'opendaylight'])
274
275     @patch('apex.overcloud.deploy.virt_utils')
276     @patch('apex.overcloud.deploy.shutil')
277     @patch('apex.overcloud.deploy.os.path')
278     @patch('builtins.open', mock_open())
279     def test_prep_image_sdn_odl_not_def(self, mock_os_path,
280                                         mock_shutil, mock_virt_utils):
281         ds_opts = {'dataplane': 'ovs',
282                    'sdn_controller': 'opendaylight',
283                    'odl_version': 'uncommon'}
284         ds = {'deploy_options': MagicMock(),
285               'global_params': MagicMock()}
286         ds['deploy_options'].__getitem__.side_effect = \
287             lambda i: ds_opts.get(i, MagicMock())
288         ns = MagicMock()
289         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
290         mock_virt_utils.virt_customize.assert_called()
291
292     @patch('apex.overcloud.deploy.virt_utils')
293     @patch('apex.overcloud.deploy.shutil')
294     @patch('apex.overcloud.deploy.os.path')
295     @patch('builtins.open', mock_open())
296     def test_prep_image_sdn_ovn(self, mock_os_path, mock_shutil,
297                                 mock_virt_utils):
298         ds_opts = {'dataplane': 'ovs',
299                    'sdn_controller': 'ovn'}
300         ds = {'deploy_options': MagicMock(),
301               'global_params': MagicMock()}
302         ds['deploy_options'].__getitem__.side_effect = \
303             lambda i: ds_opts.get(i, MagicMock())
304         ns = MagicMock()
305         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
306         mock_virt_utils.virt_customize.assert_called()
307
308     @patch('apex.overcloud.deploy.os.path.isfile')
309     def test_prep_image_no_image(self, mock_isfile):
310         mock_isfile.return_value = False
311         assert_raises(ApexDeployException, prep_image,
312                       {}, {}, 'undercloud.qcow2', '/tmp')
313
314     def test_make_ssh_key(self):
315         priv, pub = make_ssh_key()
316         assert_in('-----BEGIN PRIVATE KEY-----', priv)
317         assert_in('ssh-rsa', pub)
318
319     @patch('apex.overcloud.deploy.fileinput')
320     @patch('apex.overcloud.deploy.shutil')
321     def test_prep_env(self, mock_shutil, mock_fileinput):
322         mock_fileinput.input.return_value = \
323             ['CloudDomain', 'replace_private_key', 'replace_public_key',
324              'opendaylight::vpp_routing_node', 'ControllerExtraConfig',
325              'NovaComputeExtraConfig', 'ComputeKernelArgs', 'HostCpusList',
326              'ComputeExtraConfigPre', 'resource_registry',
327              'NovaSchedulerDefaultFilters']
328         ds = {'deploy_options':
329               {'sdn_controller': 'opendaylight',
330                'odl_vpp_routing_node': 'test',
331                'dataplane': 'ovs_dpdk',
332                'sriov': 'xxx',
333                'performance': {'Compute': {'vpp': {'main-core': 'test',
334                                                    'corelist-workers': 'test'},
335                                            'ovs': {'dpdk_cores': 'test'},
336                                            'kernel': {'test': 'test'}},
337                                'Controller': {'vpp': 'test'}}}}
338         ns = {'domain_name': 'test.domain',
339               'networks':
340               {'tenant':
341                {'nic_mapping': {'controller':
342                                 {'members': ['tenant_nic']},
343                                 'compute':
344                                 {'members': ['tenant_nic']}}},
345                'external':
346                [{'nic_mapping': {'controller':
347                                  {'members': ['ext_nic']},
348                                  'compute':
349                                  {'members': ['ext_nic']}}}]}}
350         inv = None
351         try:
352             # Swap stdout
353             saved_stdout = sys.stdout
354             out = StringIO()
355             sys.stdout = out
356             # run test
357             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
358             output = out.getvalue().strip()
359             assert_in('CloudDomain: test.domain', output)
360             assert_in('ssh-rsa', output)
361             assert_in('ComputeKernelArgs: \'test=test \'', output)
362             assert_in('fdio::vpp_cpu_main_core: \'test\'', output)
363         finally:
364             # put stdout back
365             sys.stdout = saved_stdout
366
367     @patch('apex.overcloud.deploy.fileinput')
368     @patch('apex.overcloud.deploy.shutil')
369     def test_prep_env_round_two(self, mock_shutil, mock_fileinput):
370         mock_fileinput.input.return_value = \
371             ['NeutronVPPAgentPhysnets']
372         ds = {'deploy_options':
373               {'sdn_controller': False,
374                'dataplane': 'fdio',
375                'sriov': 'xxx',
376                'performance': {'Compute': {},
377                                'Controller': {}}}}
378         ns = {'domain_name': 'test.domain',
379               'networks':
380               {'tenant':
381                {'nic_mapping': {'controller':
382                                 {'members': ['tenant_nic']},
383                                 'compute':
384                                 {'members': ['tenant_nic']}}},
385                'external':
386                [{'nic_mapping': {'controller':
387                                  {'members': ['ext_nic']},
388                                  'compute':
389                                  {'members': ['ext_nic']}}}]}}
390         inv = None
391         try:
392             # Swap stdout
393             saved_stdout = sys.stdout
394             out = StringIO()
395             sys.stdout = out
396             # run test
397             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
398             output = out.getvalue().strip()
399             assert_in('NeutronVPPAgentPhysnets: \'datacentre:tenant_nic\'',
400                       output)
401             assert_in('NeutronVPPAgentPhysnets', output)
402         finally:
403             # put stdout back
404             sys.stdout = saved_stdout
405
406     @patch('apex.overcloud.deploy.fileinput')
407     @patch('apex.overcloud.deploy.shutil')
408     def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
409         mock_fileinput.input.return_value = \
410             ['OS::TripleO::Services::NeutronDhcpAgent',
411              'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
412         ds = {'deploy_options':
413               {'sdn_controller': 'opendaylight',
414                'dataplane': 'fdio',
415                'sriov': 'xxx',
416                'dvr': True}}
417         ns = {'domain_name': 'test.domain',
418               'networks':
419               {'tenant':
420                {'nic_mapping': {'controller':
421                                 {'members': ['tenant_nic']},
422                                 'compute':
423                                 {'members': ['tenant_nic']}}},
424                'external':
425                [{'nic_mapping': {'controller':
426                                  {'members': ['ext_nic']},
427                                  'compute':
428                                  {'members': ['ext_nic']}}}]}}
429         inv = MagicMock()
430         inv.get_node_counts.return_value = (3, 2)
431         try:
432             # Swap stdout
433             saved_stdout = sys.stdout
434             out = StringIO()
435             sys.stdout = out
436             # run test
437             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
438             output = out.getvalue().strip()
439             assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
440         finally:
441             # put stdout back
442             sys.stdout = saved_stdout
443
444     def test_generate_ceph_key(self):
445         assert_equal(len(generate_ceph_key()), 40)
446
447     @patch('apex.overcloud.deploy.generate_ceph_key')
448     @patch('apex.overcloud.deploy.fileinput')
449     @patch('apex.overcloud.deploy.os.path.isfile')
450     @patch('builtins.open', mock_open())
451     def test_prep_storage_env(self, mock_isfile, mock_fileinput,
452                               mock_ceph_key):
453         mock_fileinput.input.return_value = \
454             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
455         ds = {'deploy_options': {
456             'ceph_device': '/dev/sdx',
457             'containers': False
458         }}
459         ns = {}
460         prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
461
462     @patch('apex.overcloud.deploy.utils.edit_tht_env')
463     @patch('apex.overcloud.deploy.generate_ceph_key')
464     @patch('apex.overcloud.deploy.fileinput')
465     @patch('apex.overcloud.deploy.os.path.isfile')
466     @patch('builtins.open', mock_open())
467     def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
468                                          mock_ceph_key, mock_edit_tht):
469         mock_fileinput.input.return_value = \
470             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
471         ds = {'deploy_options': {
472               'ceph_device': '/dev/sdx',
473               'containers': True,
474               'os_version': 'master'
475               }, 'global_params': {'ha_enabled': False}}
476         ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
477                                                {'ip': '192.0.2.1'}}}
478               }
479         prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
480         ceph_params = {
481             'DockerCephDaemonImage':
482                 '192.0.2.1:8787/ceph/daemon:tag-build-master-luminous-centos'
483                 '-7',
484             'CephPoolDefaultSize': 1,
485             'CephAnsibleExtraConfig': {
486                 'centos_package_dependencies': [],
487                 'ceph_osd_docker_memory_limit': '1g',
488                 'ceph_mds_docker_memory_limit': '1g'
489             },
490             'CephPoolDefaultPgNum': 32,
491             'CephAnsibleDisksConfig': {
492                 'devices': ['/dev/sdx'],
493                 'journal_size': 512,
494                 'osd_scenario': 'collocated'
495             }
496         }
497         mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
498                                          'parameter_defaults',
499                                          ceph_params)
500
501     @patch('apex.overcloud.deploy.os.path.isfile')
502     @patch('builtins.open', mock_open())
503     def test_prep_storage_env_raises(self, mock_isfile):
504         mock_isfile.return_value = False
505         ds = {'deploy_options': MagicMock()}
506         ns = {}
507         assert_raises(ApexDeployException, prep_storage_env, ds,
508                       ns, virtual=False, tmp_dir='/tmp')
509
510     @patch('apex.overcloud.deploy.generate_ceph_key')
511     @patch('apex.overcloud.deploy.fileinput')
512     @patch('apex.overcloud.deploy.os.path.isfile')
513     @patch('builtins.open', mock_open())
514     def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
515         ds = {'deploy_options':
516               {'sdn_controller': 'opendaylight',
517                'sriov': 'xxx'}}
518         try:
519             # Swap stdout
520             saved_stdout = sys.stdout
521             out = StringIO()
522             sys.stdout = out
523             # Run tests
524             mock_fileinput.input.return_value = \
525                 ['#  NovaSchedulerDefaultFilters',
526                  '#  NovaSchedulerAvailableFilters',
527                  '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
528                  '#NeutronSriovNumVFs: \"ens20f2:5\"',
529                  '#NovaPCIPassthrough:',
530                  '#  - devname: \"ens20f2\"',
531                  '#    physical_network: \"datacentre\"']
532             prep_sriov_env(ds, '/tmp')
533             output = out.getvalue().strip()
534             assert_in('NovaSchedulerDefaultFilters', output)
535             assert_in('NovaSchedulerAvailableFilters', output)
536             assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
537             assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
538             assert_in('NovaPCIPassthrough:', output)
539             assert_in('- devname: \"xxx\"', output)
540             assert_in('physical_network: \"nfv_sriov\"', output)
541         finally:
542             # put stdout back
543             sys.stdout = saved_stdout
544
545     @patch('apex.overcloud.deploy.os.path.isfile')
546     @patch('builtins.open', mock_open())
547     def test_prep_sriov_env_raises(self, mock_isfile):
548         ds_opts = {'sriov': True}
549         ds = {'deploy_options': MagicMock()}
550         ds['deploy_options'].__getitem__.side_effect = \
551             lambda i: ds_opts.get(i, MagicMock())
552         mock_isfile.return_value = False
553         ds = {'deploy_options': MagicMock()}
554         assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
555
556     def test_external_network_cmds(self):
557         cidr = MagicMock()
558         cidr.version = 6
559         ns_dict = {'networks':
560                    {'external': [{'floating_ip_range': (0, 1),
561                                   'nic_mapping':
562                                   {'compute': {'vlan': 'native'}},
563                                   'gateway': 'gw',
564                                   'cidr': cidr}]}}
565         ns = MagicMock()
566         ns.enabled_network_list = ['external']
567         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
568         cmds = ' '.join(external_network_cmds(ns))
569         assert_in('--external', cmds)
570         assert_in('--allocation-pool start=0,end=1', cmds)
571         assert_in('--gateway gw', cmds)
572         assert_in('--network external', cmds)
573
574     def test_external_network_cmds_no_ext(self):
575         cidr = MagicMock()
576         cidr.version = 6
577         ns_dict = {'apex':
578                    {'networks':
579                     {'admin':
580                      {'introspection_range': (0, 1),
581                       'nic_mapping':
582                       {'compute': {'vlan': '123'}},
583                       'gateway': 'gw',
584                       'cidr': cidr}}}}
585         ns = MagicMock()
586         ns.enabled_network_list = ['admin']
587         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
588         external_network_cmds(ns)
589         cmds = ' '.join(external_network_cmds(ns))
590         assert_in('--external', cmds)
591         assert_in('--allocation-pool start=0,end=1', cmds)
592         assert_in('--network external', cmds)
593         assert_in('--provider-network-type vlan', cmds)
594
595     @patch('apex.overcloud.deploy.parsers')
596     def test_create_congress_cmds(self, mock_parsers):
597         assert_greater(len(create_congress_cmds('overcloud_file')), 0)
598
599     @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
600     def test_create_congress_cmds_raises(self, mock_parsers):
601         mock_parsers.return_value.__getitem__.side_effect = KeyError()
602         assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
603
604     def test_get_docker_sdn_file(self):
605         ds_opts = {'ha_enabled': True,
606                    'congress': True,
607                    'tacker': True,
608                    'containers': False,
609                    'barometer': True,
610                    'ceph': False,
611                    'sdn_controller': 'opendaylight'
612                    }
613         output = get_docker_sdn_file(ds_opts)
614         self.assertEqual(output,
615                          ('/usr/share/openstack-tripleo-heat-templates'
616                           '/environments/services-docker/neutron-opendaylight'
617                           '.yaml')
618                          )