Fix nosdn fdio scenario
[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: '
408                       '\'datacentre:tenant_nic,external:tap0\'',
409                       output)
410             assert_in('NeutronVPPAgentPhysnets', output)
411         finally:
412             # put stdout back
413             sys.stdout = saved_stdout
414
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',
423                'dataplane': 'fdio',
424                'sriov': 'xxx',
425                'dvr': True}}
426         ns = {'domain_name': 'test.domain',
427               'networks':
428               {'tenant':
429                {'nic_mapping': {'controller':
430                                 {'members': ['tenant_nic']},
431                                 'compute':
432                                 {'members': ['tenant_nic']}}},
433                'external':
434                [{'nic_mapping': {'controller':
435                                  {'members': ['ext_nic']},
436                                  'compute':
437                                  {'members': ['ext_nic']}}}]}}
438         inv = MagicMock()
439         inv.get_node_counts.return_value = (3, 2)
440         try:
441             # Swap stdout
442             saved_stdout = sys.stdout
443             out = StringIO()
444             sys.stdout = out
445             # run test
446             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
447             output = out.getvalue().strip()
448             assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
449         finally:
450             # put stdout back
451             sys.stdout = saved_stdout
452
453     def test_generate_ceph_key(self):
454         assert_equal(len(generate_ceph_key()), 40)
455
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,
461                               mock_ceph_key):
462         mock_fileinput.input.return_value = \
463             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
464         ds = {'deploy_options': {
465             'ceph_device': '/dev/sdx',
466             'containers': False
467         }}
468         ns = {}
469         prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
470
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',
482               'containers': True,
483               'os_version': 'master'
484               }, 'global_params': {'ha_enabled': False}}
485         ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
486                                                {'ip': '192.0.2.1'}}}
487               }
488         prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
489         ceph_params = {
490             'DockerCephDaemonImage':
491                 '192.0.2.1:8787/ceph/daemon:tag-build-master-luminous-centos'
492                 '-7',
493             'CephPoolDefaultSize': 1,
494             'CephAnsibleExtraConfig': {
495                 'centos_package_dependencies': [],
496                 'ceph_osd_docker_memory_limit': '1g',
497                 'ceph_mds_docker_memory_limit': '1g'
498             },
499             'CephPoolDefaultPgNum': 32,
500             'CephAnsibleDisksConfig': {
501                 'devices': ['/dev/sdx'],
502                 'journal_size': 512,
503                 'osd_scenario': 'collocated'
504             }
505         }
506         mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
507                                          'parameter_defaults',
508                                          ceph_params)
509
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()}
515         ns = {}
516         assert_raises(ApexDeployException, prep_storage_env, ds,
517                       ns, virtual=False, tmp_dir='/tmp')
518
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',
526                'sriov': 'xxx'}}
527         try:
528             # Swap stdout
529             saved_stdout = sys.stdout
530             out = StringIO()
531             sys.stdout = out
532             # Run tests
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)
550         finally:
551             # put stdout back
552             sys.stdout = saved_stdout
553
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')
564
565     def test_external_network_cmds(self):
566         ds = {'deploy_options':
567               {'sdn_controller': 'opendaylight',
568                'dataplane': 'ovs'}}
569
570         cidr = MagicMock()
571         cidr.version = 6
572         ns_dict = {'networks':
573                    {'external': [{'floating_ip_range': (0, 1),
574                                   'nic_mapping':
575                                   {'compute': {'vlan': 'native'}},
576                                   'gateway': 'gw',
577                                   'cidr': cidr}]}}
578         ns = MagicMock()
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)
587
588     def test_external_network_cmds_nosdn_fdio(self):
589         ds = {'deploy_options':
590               {'sdn_controller': False,
591                'dataplane': 'fdio'}}
592
593         cidr = MagicMock()
594         cidr.version = 6
595         ns_dict = {'networks':
596                    {'external': [{'floating_ip_range': (0, 1),
597                                   'nic_mapping':
598                                   {'compute': {'vlan': 'native'}},
599                                   'gateway': 'gw',
600                                   'cidr': cidr}]}}
601         ns = MagicMock()
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)
610
611     def test_external_network_cmds_no_ext(self):
612         ds = {'deploy_options':
613               {'sdn_controller': 'opendaylight',
614                'dataplane': 'ovs'}}
615
616         cidr = MagicMock()
617         cidr.version = 6
618         ns_dict = {'apex':
619                    {'networks':
620                     {'admin':
621                      {'introspection_range': (0, 1),
622                       'nic_mapping':
623                       {'compute': {'vlan': '123'}},
624                       'gateway': 'gw',
625                       'cidr': cidr}}}}
626         ns = MagicMock()
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)
634
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)
638
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')
643
644     def test_get_docker_sdn_file(self):
645         ds_opts = {'ha_enabled': True,
646                    'congress': True,
647                    'tacker': True,
648                    'containers': False,
649                    'barometer': True,
650                    'ceph': False,
651                    'sdn_controller': 'opendaylight'
652                    }
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'
657                           '.yaml')
658                          )