Generalization of recursive function
[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_string(self):
78         ds = {'sdn_controller': 'opendaylight',
79               'sriov': 'xxx'}
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)
84
85     def test_build_sdn_env_list_with_default(self):
86         ds = {'sdn_controller': 'opendaylight',
87               'vpn': True}
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)
92
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,
98                                mock_prep_sriov):
99         mock_sdn_list.return_value = []
100         ds = {'deploy_options':
101               {'ha_enabled': True,
102                'congress': True,
103                'tacker': True,
104                'containers': False,
105                'barometer': True,
106                'ceph': False,
107                'sriov': False
108                },
109               'global_params': MagicMock()}
110
111         ns = {'ntp': ['ntp']}
112         inv = MagicMock()
113         inv.get_node_counts.return_value = (3, 2)
114         virt = True
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)
123
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,
128                                               mock_prep_sriov):
129         ds = {'deploy_options':
130               {'ha_enabled': True,
131                'congress': False,
132                'tacker': False,
133                'containers': True,
134                'barometer': False,
135                'ceph': True,
136                'sdn_controller': 'opendaylight',
137                'sriov': False
138                },
139               'global_params': MagicMock()}
140
141         ns = {'ntp': ['ntp']}
142         inv = MagicMock()
143         inv.get_node_counts.return_value = (3, 2)
144         virt = True
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)
161
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']}
174         inv = MagicMock()
175         inv.get_node_counts.return_value = (3, 2)
176         virt = False
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)
185
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,
190                                       mock_prep_sriov):
191         mock_sdn_list.return_value = []
192         ds = {'deploy_options': MagicMock(),
193               'global_params': MagicMock()}
194         ns = {}
195         inv = MagicMock()
196         inv.get_node_counts.return_value = (0, 0)
197         virt = False
198         assert_raises(ApexDeployException, create_deploy_cmd,
199                       ds, ns, inv, '/tmp', virt)
200
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',
209                    'sriov': False}
210         ds = {'deploy_options': MagicMock(),
211               'global_params': MagicMock()}
212         ds['deploy_options'].__getitem__.side_effect = \
213             lambda i: ds_opts.get(i, MagicMock())
214         ns = MagicMock()
215         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
216         mock_virt_utils.virt_customize.assert_called()
217
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,
223                                   mock_virt_utils):
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())
230         ns = MagicMock()
231         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
232         mock_virt_utils.virt_customize.assert_called()
233
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,
239                                 mock_virt_utils):
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()
250         ns = MagicMock()
251         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
252         mock_virt_utils.virt_customize.assert_called()
253
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()
273         ns = 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'])
282
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())
296         ns = MagicMock()
297         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
298         mock_virt_utils.virt_customize.assert_called()
299
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,
305                                 mock_virt_utils):
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())
312         ns = MagicMock()
313         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
314         mock_virt_utils.virt_customize.assert_called()
315
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')
321
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)
326
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',
340                'sriov': 'xxx',
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',
347               'networks':
348               {'tenant':
349                {'nic_mapping': {'controller':
350                                 {'members': ['tenant_nic']},
351                                 'compute':
352                                 {'members': ['tenant_nic']}}},
353                'external':
354                [{'nic_mapping': {'controller':
355                                  {'members': ['ext_nic']},
356                                  'compute':
357                                  {'members': ['ext_nic']}}}]}}
358         inv = None
359         try:
360             # Swap stdout
361             saved_stdout = sys.stdout
362             out = StringIO()
363             sys.stdout = out
364             # run test
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)
371         finally:
372             # put stdout back
373             sys.stdout = saved_stdout
374
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,
382                'dataplane': 'fdio',
383                'sriov': 'xxx',
384                'performance': {'Compute': {},
385                                'Controller': {}}}}
386         ns = {'domain_name': 'test.domain',
387               'networks':
388               {'tenant':
389                {'nic_mapping': {'controller':
390                                 {'members': ['tenant_nic']},
391                                 'compute':
392                                 {'members': ['tenant_nic']}}},
393                'external':
394                [{'nic_mapping': {'controller':
395                                  {'members': ['ext_nic']},
396                                  'compute':
397                                  {'members': ['ext_nic']}}}]}}
398         inv = None
399         try:
400             # Swap stdout
401             saved_stdout = sys.stdout
402             out = StringIO()
403             sys.stdout = out
404             # run test
405             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
406             output = out.getvalue().strip()
407             assert_in('NeutronVPPAgentPhysnets: \'datacentre:tenant_nic\'',
408                       output)
409             assert_in('NeutronVPPAgentPhysnets', output)
410         finally:
411             # put stdout back
412             sys.stdout = saved_stdout
413
414     @patch('apex.overcloud.deploy.fileinput')
415     @patch('apex.overcloud.deploy.shutil')
416     def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
417         mock_fileinput.input.return_value = \
418             ['OS::TripleO::Services::NeutronDhcpAgent',
419              'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
420         ds = {'deploy_options':
421               {'sdn_controller': 'opendaylight',
422                'dataplane': 'fdio',
423                'sriov': 'xxx',
424                'dvr': True}}
425         ns = {'domain_name': 'test.domain',
426               'networks':
427               {'tenant':
428                {'nic_mapping': {'controller':
429                                 {'members': ['tenant_nic']},
430                                 'compute':
431                                 {'members': ['tenant_nic']}}},
432                'external':
433                [{'nic_mapping': {'controller':
434                                  {'members': ['ext_nic']},
435                                  'compute':
436                                  {'members': ['ext_nic']}}}]}}
437         inv = MagicMock()
438         inv.get_node_counts.return_value = (3, 2)
439         try:
440             # Swap stdout
441             saved_stdout = sys.stdout
442             out = StringIO()
443             sys.stdout = out
444             # run test
445             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
446             output = out.getvalue().strip()
447             assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
448         finally:
449             # put stdout back
450             sys.stdout = saved_stdout
451
452     def test_generate_ceph_key(self):
453         assert_equal(len(generate_ceph_key()), 40)
454
455     @patch('apex.overcloud.deploy.generate_ceph_key')
456     @patch('apex.overcloud.deploy.fileinput')
457     @patch('apex.overcloud.deploy.os.path.isfile')
458     @patch('builtins.open', mock_open())
459     def test_prep_storage_env(self, mock_isfile, mock_fileinput,
460                               mock_ceph_key):
461         mock_fileinput.input.return_value = \
462             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
463         ds = {'deploy_options': {
464             'ceph_device': '/dev/sdx',
465             'containers': False
466         }}
467         ns = {}
468         prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
469
470     @patch('apex.overcloud.deploy.utils.edit_tht_env')
471     @patch('apex.overcloud.deploy.generate_ceph_key')
472     @patch('apex.overcloud.deploy.fileinput')
473     @patch('apex.overcloud.deploy.os.path.isfile')
474     @patch('builtins.open', mock_open())
475     def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
476                                          mock_ceph_key, mock_edit_tht):
477         mock_fileinput.input.return_value = \
478             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
479         ds = {'deploy_options': {
480               'ceph_device': '/dev/sdx',
481               'containers': True,
482               'os_version': 'master'
483               }, 'global_params': {'ha_enabled': False}}
484         ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
485                                                {'ip': '192.0.2.1'}}}
486               }
487         prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
488         ceph_params = {
489             'DockerCephDaemonImage':
490                 '192.0.2.1:8787/ceph/daemon:tag-build-master-luminous-centos'
491                 '-7',
492             'CephPoolDefaultSize': 1,
493             'CephAnsibleExtraConfig': {
494                 'centos_package_dependencies': [],
495                 'ceph_osd_docker_memory_limit': '1g',
496                 'ceph_mds_docker_memory_limit': '1g'
497             },
498             'CephPoolDefaultPgNum': 32,
499             'CephAnsibleDisksConfig': {
500                 'devices': ['/dev/sdx'],
501                 'journal_size': 512,
502                 'osd_scenario': 'collocated'
503             }
504         }
505         mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
506                                          'parameter_defaults',
507                                          ceph_params)
508
509     @patch('apex.overcloud.deploy.os.path.isfile')
510     @patch('builtins.open', mock_open())
511     def test_prep_storage_env_raises(self, mock_isfile):
512         mock_isfile.return_value = False
513         ds = {'deploy_options': MagicMock()}
514         ns = {}
515         assert_raises(ApexDeployException, prep_storage_env, ds,
516                       ns, virtual=False, tmp_dir='/tmp')
517
518     @patch('apex.overcloud.deploy.generate_ceph_key')
519     @patch('apex.overcloud.deploy.fileinput')
520     @patch('apex.overcloud.deploy.os.path.isfile')
521     @patch('builtins.open', mock_open())
522     def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
523         ds = {'deploy_options':
524               {'sdn_controller': 'opendaylight',
525                'sriov': 'xxx'}}
526         try:
527             # Swap stdout
528             saved_stdout = sys.stdout
529             out = StringIO()
530             sys.stdout = out
531             # Run tests
532             mock_fileinput.input.return_value = \
533                 ['#  NovaSchedulerDefaultFilters',
534                  '#  NovaSchedulerAvailableFilters',
535                  '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
536                  '#NeutronSriovNumVFs: \"ens20f2:5\"',
537                  '#NovaPCIPassthrough:',
538                  '#  - devname: \"ens20f2\"',
539                  '#    physical_network: \"datacentre\"']
540             prep_sriov_env(ds, '/tmp')
541             output = out.getvalue().strip()
542             assert_in('NovaSchedulerDefaultFilters', output)
543             assert_in('NovaSchedulerAvailableFilters', output)
544             assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
545             assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
546             assert_in('NovaPCIPassthrough:', output)
547             assert_in('- devname: \"xxx\"', output)
548             assert_in('physical_network: \"nfv_sriov\"', output)
549         finally:
550             # put stdout back
551             sys.stdout = saved_stdout
552
553     @patch('apex.overcloud.deploy.os.path.isfile')
554     @patch('builtins.open', mock_open())
555     def test_prep_sriov_env_raises(self, mock_isfile):
556         ds_opts = {'sriov': True}
557         ds = {'deploy_options': MagicMock()}
558         ds['deploy_options'].__getitem__.side_effect = \
559             lambda i: ds_opts.get(i, MagicMock())
560         mock_isfile.return_value = False
561         ds = {'deploy_options': MagicMock()}
562         assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
563
564     def test_external_network_cmds(self):
565         cidr = MagicMock()
566         cidr.version = 6
567         ns_dict = {'networks':
568                    {'external': [{'floating_ip_range': (0, 1),
569                                   'nic_mapping':
570                                   {'compute': {'vlan': 'native'}},
571                                   'gateway': 'gw',
572                                   'cidr': cidr}]}}
573         ns = MagicMock()
574         ns.enabled_network_list = ['external']
575         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
576         cmds = ' '.join(external_network_cmds(ns))
577         assert_in('--external', cmds)
578         assert_in('--allocation-pool start=0,end=1', cmds)
579         assert_in('--gateway gw', cmds)
580         assert_in('--network external', cmds)
581
582     def test_external_network_cmds_no_ext(self):
583         cidr = MagicMock()
584         cidr.version = 6
585         ns_dict = {'apex':
586                    {'networks':
587                     {'admin':
588                      {'introspection_range': (0, 1),
589                       'nic_mapping':
590                       {'compute': {'vlan': '123'}},
591                       'gateway': 'gw',
592                       'cidr': cidr}}}}
593         ns = MagicMock()
594         ns.enabled_network_list = ['admin']
595         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
596         external_network_cmds(ns)
597         cmds = ' '.join(external_network_cmds(ns))
598         assert_in('--external', cmds)
599         assert_in('--allocation-pool start=0,end=1', cmds)
600         assert_in('--network external', cmds)
601         assert_in('--provider-network-type vlan', cmds)
602
603     @patch('apex.overcloud.deploy.parsers')
604     def test_create_congress_cmds(self, mock_parsers):
605         assert_greater(len(create_congress_cmds('overcloud_file')), 0)
606
607     @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
608     def test_create_congress_cmds_raises(self, mock_parsers):
609         mock_parsers.return_value.__getitem__.side_effect = KeyError()
610         assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
611
612     def test_get_docker_sdn_file(self):
613         ds_opts = {'ha_enabled': True,
614                    'congress': True,
615                    'tacker': True,
616                    'containers': False,
617                    'barometer': True,
618                    'ceph': False,
619                    'sdn_controller': 'opendaylight'
620                    }
621         output = get_docker_sdn_file(ds_opts)
622         self.assertEqual(output,
623                          ('/usr/share/openstack-tripleo-heat-templates'
624                           '/environments/services-docker/neutron-opendaylight'
625                           '.yaml')
626                          )