17911d592d2d63a05abe940793f1be84417d89c2
[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                'vim': 'openstack'
109                },
110               'global_params': MagicMock()}
111
112         ns = {'ntp': ['ntp']}
113         inv = MagicMock()
114         inv.get_node_counts.return_value = (3, 2)
115         virt = True
116         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
117         assert_in('--ntp-server ntp', result_cmd)
118         assert_in('enable_tacker.yaml', result_cmd)
119         assert_in('enable_congress.yaml', result_cmd)
120         assert_in('enable_barometer.yaml', result_cmd)
121         assert_in('virtual-environment.yaml', result_cmd)
122         assert_in('--control-scale 3', result_cmd)
123         assert_in('--compute-scale 2', result_cmd)
124
125     @patch('apex.overcloud.deploy.prep_sriov_env')
126     @patch('apex.overcloud.deploy.prep_storage_env')
127     @patch('builtins.open', mock_open())
128     def test_create_deploy_cmd_containers_sdn(self, mock_prep_storage,
129                                               mock_prep_sriov):
130         ds = {'deploy_options':
131               {'ha_enabled': True,
132                'congress': False,
133                'tacker': False,
134                'containers': True,
135                'barometer': False,
136                'ceph': True,
137                'sdn_controller': 'opendaylight',
138                'sriov': False,
139                'os_version': 'queens',
140                'vim': 'openstack'
141                },
142               'global_params': MagicMock()}
143
144         ns = {'ntp': ['ntp']}
145         inv = MagicMock()
146         inv.get_node_counts.return_value = (3, 2)
147         virt = True
148         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
149         assert_in('--ntp-server ntp', result_cmd)
150         assert_not_in('enable_tacker.yaml', result_cmd)
151         assert_not_in('enable_congress.yaml', result_cmd)
152         assert_not_in('enable_barometer.yaml', result_cmd)
153         assert_in('virtual-environment.yaml', result_cmd)
154         assert_in('--control-scale 3', result_cmd)
155         assert_in('--compute-scale 2', result_cmd)
156         assert_in('docker-images.yaml', result_cmd)
157         assert_in('sdn-images.yaml', result_cmd)
158         assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
159                   '/docker.yaml', result_cmd)
160         assert_in('/usr/share/openstack-tripleo-heat-templates/environments/'
161                   'storage-environment.yaml', result_cmd)
162         assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
163                   '/services/neutron-opendaylight.yaml', result_cmd)
164         ds['deploy_options']['os_version'] = 'master'
165         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
166         assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
167                   '/services/neutron-opendaylight.yaml', result_cmd)
168
169     @patch('apex.overcloud.deploy.prep_sriov_env')
170     @patch('apex.overcloud.deploy.prep_storage_env')
171     @patch('apex.overcloud.deploy.build_sdn_env_list')
172     @patch('builtins.open', mock_open())
173     def test_create_deploy_cmd_no_ha_bm(self, mock_sdn_list,
174                                         mock_prep_storage, mock_prep_sriov):
175         mock_sdn_list.return_value = []
176         ds = {'deploy_options': MagicMock(),
177               'global_params': MagicMock()}
178         ds['global_params'].__getitem__.side_effect = \
179             lambda i: False if i == 'ha_enabled' else MagicMock()
180         ds['deploy_options'].__getitem__.side_effect = \
181             lambda i: 'master' if i == 'os_version' else MagicMock()
182         ns = {'ntp': ['ntp']}
183         inv = MagicMock()
184         inv.get_node_counts.return_value = (3, 2)
185         virt = False
186         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
187         assert_in('--ntp-server ntp', result_cmd)
188         assert_in('--control-scale 1', result_cmd)
189         assert_in('--compute-scale 2', result_cmd)
190         assert_in('baremetal-environment.yaml', result_cmd)
191         assert_not_in('enable_tacker.yaml', result_cmd)
192         assert_not_in('enable_congress.yaml', result_cmd)
193         assert_not_in('enable_barometer.yaml', result_cmd)
194
195     @patch('apex.overcloud.deploy.prep_sriov_env')
196     @patch('apex.overcloud.deploy.prep_storage_env')
197     @patch('apex.overcloud.deploy.build_sdn_env_list')
198     def test_create_deploy_cmd_raises(self, mock_sdn_list, mock_prep_storage,
199                                       mock_prep_sriov):
200         mock_sdn_list.return_value = []
201         ds = {'deploy_options': MagicMock(),
202               'global_params': MagicMock()}
203         ds['deploy_options'].__getitem__.side_effect = \
204             lambda i: 'master' if i == 'os_version' else MagicMock()
205         ns = {}
206         inv = MagicMock()
207         inv.get_node_counts.return_value = (0, 0)
208         virt = False
209         assert_raises(ApexDeployException, create_deploy_cmd,
210                       ds, ns, inv, '/tmp', virt)
211
212     @patch('apex.builders.overcloud_builder.inject_opendaylight')
213     @patch('apex.overcloud.deploy.virt_utils')
214     @patch('apex.overcloud.deploy.shutil')
215     @patch('apex.overcloud.deploy.os.path')
216     @patch('builtins.open', mock_open())
217     def test_prep_image(self, mock_os_path, mock_shutil, mock_virt_utils,
218                         mock_inject_odl):
219         ds_opts = {'dataplane': 'fdio',
220                    'sdn_controller': 'opendaylight',
221                    'odl_version': 'master',
222                    'sriov': False}
223         ds = {'deploy_options': MagicMock(),
224               'global_params': MagicMock()}
225         ds['deploy_options'].__getitem__.side_effect = \
226             lambda i: ds_opts.get(i, MagicMock())
227         ns = MagicMock()
228         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
229         mock_virt_utils.virt_customize.assert_called()
230         mock_inject_odl.assert_called()
231
232     @patch('apex.overcloud.deploy.virt_utils')
233     @patch('apex.overcloud.deploy.shutil')
234     @patch('apex.overcloud.deploy.os.path')
235     @patch('builtins.open', mock_open())
236     def test_prep_image_sdn_false(self, mock_os_path, mock_shutil,
237                                   mock_virt_utils):
238         ds_opts = {'dataplane': 'fdio',
239                    'sdn_controller': False}
240         ds = {'deploy_options': MagicMock(),
241               'global_params': MagicMock()}
242         ds['deploy_options'].__getitem__.side_effect = \
243             lambda i: ds_opts.get(i, MagicMock())
244         ns = MagicMock()
245         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
246         mock_virt_utils.virt_customize.assert_called()
247
248     @patch('apex.builders.overcloud_builder.inject_opendaylight')
249     @patch('apex.overcloud.deploy.virt_utils')
250     @patch('apex.overcloud.deploy.shutil')
251     @patch('apex.overcloud.deploy.os.path')
252     @patch('builtins.open', mock_open())
253     def test_prep_image_sdn_odl(self, mock_os_path, mock_shutil,
254                                 mock_virt_utils, mock_inject_odl):
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         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
267         mock_virt_utils.virt_customize.assert_called()
268         mock_inject_odl.assert_called()
269
270     @patch('apex.overcloud.deploy.c_builder')
271     @patch('apex.overcloud.deploy.oc_builder')
272     @patch('apex.overcloud.deploy.virt_utils')
273     @patch('apex.overcloud.deploy.shutil')
274     @patch('apex.overcloud.deploy.os.path')
275     @patch('builtins.open', mock_open())
276     def test_prep_image_sdn_odl_upstream_containers_patches(
277             self, mock_os_path, mock_shutil, mock_virt_utils,
278             mock_oc_builder, mock_c_builder):
279         ds_opts = {'dataplane': 'ovs',
280                    'sdn_controller': 'opendaylight',
281                    'odl_version': con.DEFAULT_ODL_VERSION,
282                    'odl_vpp_netvirt': True}
283         ds = {'deploy_options': MagicMock(),
284               'global_params': MagicMock()}
285         ds['deploy_options'].__getitem__.side_effect = \
286             lambda i: ds_opts.get(i, MagicMock())
287         ds['deploy_options'].__contains__.side_effect = \
288             lambda i: True if i in ds_opts else MagicMock()
289         ns = MagicMock()
290         mock_c_builder.add_upstream_patches.return_value = ['nova-api']
291         patches = ['dummy_nova_patch']
292         rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
293                         docker_tag='latest', patches=patches)
294         mock_oc_builder.inject_opendaylight.assert_called()
295         mock_virt_utils.virt_customize.assert_called()
296         mock_c_builder.add_upstream_patches.assert_called()
297         self.assertListEqual(sorted(rv), ['nova-api', 'opendaylight'])
298
299     @patch('apex.overcloud.deploy.oc_builder')
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_odl_not_def(self, mock_os_path,
305                                         mock_shutil, mock_virt_utils,
306                                         mock_oc_builder):
307         ds_opts = {'dataplane': 'ovs',
308                    'sdn_controller': 'opendaylight',
309                    'odl_version': 'uncommon'}
310         ds = {'deploy_options': MagicMock(),
311               'global_params': MagicMock()}
312         ds['deploy_options'].__getitem__.side_effect = \
313             lambda i: ds_opts.get(i, MagicMock())
314         ns = MagicMock()
315         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
316         mock_virt_utils.virt_customize.assert_called()
317         mock_oc_builder.inject_opendaylight.assert_called()
318
319     @patch('apex.overcloud.deploy.virt_utils')
320     @patch('apex.overcloud.deploy.shutil')
321     @patch('apex.overcloud.deploy.os.path')
322     @patch('builtins.open', mock_open())
323     def test_prep_image_sdn_ovn(self, mock_os_path, mock_shutil,
324                                 mock_virt_utils):
325         ds_opts = {'dataplane': 'ovs',
326                    'sdn_controller': 'ovn'}
327         ds = {'deploy_options': MagicMock(),
328               'global_params': MagicMock()}
329         ds['deploy_options'].__getitem__.side_effect = \
330             lambda i: ds_opts.get(i, MagicMock())
331         ns = MagicMock()
332         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
333         mock_virt_utils.virt_customize.assert_called()
334
335     @patch('apex.overcloud.deploy.os.path.isfile')
336     def test_prep_image_no_image(self, mock_isfile):
337         mock_isfile.return_value = False
338         assert_raises(ApexDeployException, prep_image,
339                       {}, {}, 'undercloud.qcow2', '/tmp')
340
341     def test_make_ssh_key(self):
342         priv, pub = make_ssh_key()
343         assert_in('-----BEGIN PRIVATE KEY-----', priv)
344         assert_in('ssh-rsa', pub)
345
346     @patch('apex.overcloud.deploy.fileinput')
347     @patch('apex.overcloud.deploy.shutil')
348     def test_prep_env(self, mock_shutil, mock_fileinput):
349         mock_fileinput.input.return_value = \
350             ['CloudDomain', 'replace_private_key', 'replace_public_key',
351              'opendaylight::vpp_routing_node', 'ControllerExtraConfig',
352              'NovaComputeExtraConfig', 'ComputeKernelArgs', 'HostCpusList',
353              'ComputeExtraConfigPre', 'resource_registry',
354              'NovaSchedulerDefaultFilters']
355         ds = {'deploy_options':
356               {'sdn_controller': 'opendaylight',
357                'odl_vpp_routing_node': 'test',
358                'dataplane': 'ovs_dpdk',
359                'sriov': 'xxx',
360                'performance': {'Compute': {'vpp': {'main-core': 'test',
361                                                    'corelist-workers': 'test'},
362                                            'ovs': {'dpdk_cores': 'test'},
363                                            'kernel': {'test': 'test'}},
364                                'Controller': {'vpp': 'test'}}}}
365         ns_dict = {'domain_name': 'test.domain',
366                    'networks':
367                    {'tenant':
368                     {'nic_mapping': {'controller':
369                                      {'members': ['tenant_nic']},
370                                      'compute':
371                                      {'members': ['tenant_nic']}}},
372                     'external':
373                     [{'nic_mapping': {'controller':
374                                       {'members': ['ext_nic']},
375                                       'compute':
376                                       {'members': ['ext_nic']}}}]}}
377         inv = None
378         try:
379             # Swap stdout
380             saved_stdout = sys.stdout
381             out = StringIO()
382             sys.stdout = out
383             ns = MagicMock()
384             ns.enabled_network_list = ['external', 'tenant']
385             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
386             # run test
387             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
388             output = out.getvalue().strip()
389             assert_in('CloudDomain: test.domain', output)
390             assert_in('ssh-rsa', output)
391             assert_in('ComputeKernelArgs: \'test=test \'', output)
392             assert_in('fdio::vpp_cpu_main_core: \'test\'', output)
393         finally:
394             # put stdout back
395             sys.stdout = saved_stdout
396
397     @patch('apex.overcloud.deploy.fileinput')
398     @patch('apex.overcloud.deploy.shutil')
399     def test_prep_env_round_two(self, mock_shutil, mock_fileinput):
400         mock_fileinput.input.return_value = \
401             ['NeutronVPPAgentPhysnets']
402         ds = {'deploy_options':
403               {'sdn_controller': False,
404                'dataplane': 'fdio',
405                'sriov': 'xxx',
406                'performance': {'Compute': {},
407                                'Controller': {}}}}
408         ns_dict = {'domain_name': 'test.domain',
409                    'networks':
410                    {'tenant':
411                     {'nic_mapping': {'controller':
412                                      {'members': ['tenant_nic']},
413                                      'compute':
414                                      {'members': ['tenant_nic']}}},
415                     'external':
416                     [{'nic_mapping': {'controller':
417                                       {'members': ['ext_nic']},
418                                       'compute':
419                                       {'members': ['ext_nic']}}}]}}
420         inv = None
421         try:
422             # Swap stdout
423             saved_stdout = sys.stdout
424             out = StringIO()
425             sys.stdout = out
426             ns = MagicMock()
427             ns.enabled_network_list = ['external', 'tenant']
428             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
429             # run test
430             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
431             output = out.getvalue().strip()
432             assert_in('NeutronVPPAgentPhysnets: '
433                       '\'datacentre:tenant_nic,external:tap0\'',
434                       output)
435             assert_in('NeutronVPPAgentPhysnets', output)
436         finally:
437             # put stdout back
438             sys.stdout = saved_stdout
439
440     @patch('apex.overcloud.deploy.fileinput')
441     @patch('apex.overcloud.deploy.shutil')
442     def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
443         mock_fileinput.input.return_value = \
444             ['OS::TripleO::Services::NeutronDhcpAgent',
445              'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
446         ds = {'deploy_options':
447               {'sdn_controller': 'opendaylight',
448                'dataplane': 'fdio',
449                'sriov': 'xxx',
450                'dvr': True}}
451         ns_dict = {'domain_name': 'test.domain',
452                    'networks':
453                    {'tenant':
454                     {'nic_mapping': {'controller':
455                                      {'members': ['tenant_nic']},
456                                      'compute':
457                                      {'members': ['tenant_nic']}}},
458                     'external':
459                     [{'nic_mapping': {'controller':
460                                       {'members': ['ext_nic']},
461                                       'compute':
462                                       {'members': ['ext_nic']}}}]}}
463         inv = MagicMock()
464         inv.get_node_counts.return_value = (3, 2)
465         try:
466             # Swap stdout
467             saved_stdout = sys.stdout
468             out = StringIO()
469             sys.stdout = out
470             ns = MagicMock()
471             ns.enabled_network_list = ['external', 'tenant']
472             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
473             # run test
474             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
475             output = out.getvalue().strip()
476             assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
477         finally:
478             # put stdout back
479             sys.stdout = saved_stdout
480
481     @patch('apex.overcloud.deploy.fileinput')
482     @patch('apex.overcloud.deploy.shutil')
483     def test_prep_env_tenant_vlan(self, mock_shutil, mock_fileinput):
484         mock_fileinput.input.return_value = \
485             ['NeutronNetworkVLANRanges',
486              'NeutronNetworkType', 'NeutronBridgeMappings']
487         ds = {'deploy_options':
488               {'sdn_controller': False,
489                'dataplane': 'ovs',
490                'sriov': 'xxx',
491                'dvr': True}}
492         ns_dict = {'domain_name': 'test.domain',
493                    'networks':
494                    {'tenant':
495                     {'nic_mapping': {'controller':
496                                      {'members': ['tenant_nic']},
497                                      'compute':
498                                      {'members': ['tenant_nic']}},
499                      'segmentation_type': 'vlan',
500                      'overlay_id_range': 'vlan:500:600'
501                      },
502                     'external':
503                     [{'nic_mapping': {'controller':
504                                       {'members': ['ext_nic']},
505                                       'compute':
506                                       {'members': ['ext_nic']}}}]}}
507         inv = MagicMock()
508         inv.get_node_counts.return_value = (3, 2)
509         try:
510             # Swap stdout
511             saved_stdout = sys.stdout
512             out = StringIO()
513             sys.stdout = out
514             ns = MagicMock()
515             ns.enabled_network_list = ['external', 'tenant']
516             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
517             # run test
518             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
519             output = out.getvalue().strip()
520             assert_in('NeutronNetworkVLANRanges: '
521                       'vlan:500:600,datacentre:1:1000', output)
522             assert_in('NeutronNetworkType: vlan', output)
523             assert_in('NeutronBridgeMappings: '
524                       'vlan:br-vlan,datacentre:br-ex', output)
525             assert_not_in('OpenDaylightProviderMappings', output)
526         finally:
527             # put stdout back
528             sys.stdout = saved_stdout
529
530     @patch('apex.overcloud.deploy.fileinput')
531     @patch('apex.overcloud.deploy.shutil')
532     def test_prep_env_tenant_vlan_odl(self, mock_shutil, mock_fileinput):
533         mock_fileinput.input.return_value = \
534             ['NeutronNetworkVLANRanges',
535              'NeutronNetworkType',
536              'NeutronBridgeMappings',
537              'OpenDaylightProviderMappings']
538         ds = {'deploy_options':
539               {'sdn_controller': 'opendaylight',
540                'dataplane': 'ovs',
541                'sriov': 'xxx',
542                'dvr': True}}
543         ns_dict = {'domain_name': 'test.domain',
544                    'networks':
545                    {'tenant':
546                     {'nic_mapping': {'controller':
547                                      {'members': ['tenant_nic']},
548                                      'compute':
549                                      {'members': ['tenant_nic']}},
550                      'segmentation_type': 'vlan',
551                      'overlay_id_range': 'vlan:500:600'
552                      },
553                     'external':
554                     [{'nic_mapping': {'controller':
555                                       {'members': ['ext_nic']},
556                                       'compute':
557                                       {'members': ['ext_nic']}}}]}}
558         inv = MagicMock()
559         inv.get_node_counts.return_value = (3, 2)
560         try:
561             # Swap stdout
562             saved_stdout = sys.stdout
563             out = StringIO()
564             sys.stdout = out
565             ns = MagicMock()
566             ns.enabled_network_list = ['external', 'tenant']
567             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
568             # run test
569             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
570             output = out.getvalue().strip()
571             assert_in('NeutronNetworkVLANRanges: '
572                       'vlan:500:600,datacentre:1:1000', output)
573             assert_in('NeutronNetworkType: vlan', output)
574             assert_in('NeutronBridgeMappings: '
575                       'vlan:br-vlan,datacentre:br-ex', output)
576             assert_in('OpenDaylightProviderMappings: '
577                       'vlan:br-vlan,datacentre:br-ex', output)
578         finally:
579             # put stdout back
580             sys.stdout = saved_stdout
581
582     def test_generate_ceph_key(self):
583         assert_equal(len(generate_ceph_key()), 40)
584
585     @patch('apex.overcloud.deploy.generate_ceph_key')
586     @patch('apex.overcloud.deploy.fileinput')
587     @patch('apex.overcloud.deploy.os.path.isfile')
588     @patch('builtins.open', mock_open())
589     def test_prep_storage_env(self, mock_isfile, mock_fileinput,
590                               mock_ceph_key):
591         mock_fileinput.input.return_value = \
592             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
593         ds = {'deploy_options': {
594             'ceph_device': '/dev/sdx',
595             'containers': False
596         }}
597         ns = {}
598         prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
599
600     @patch('apex.overcloud.deploy.utils.edit_tht_env')
601     @patch('apex.overcloud.deploy.generate_ceph_key')
602     @patch('apex.overcloud.deploy.fileinput')
603     @patch('apex.overcloud.deploy.os.path.isfile')
604     @patch('builtins.open', mock_open())
605     def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
606                                          mock_ceph_key, mock_edit_tht):
607         mock_fileinput.input.return_value = \
608             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
609         ds = {'deploy_options': {
610               'ceph_device': '/dev/sdx',
611               'containers': True,
612               'os_version': 'master'
613               }, 'global_params': {'ha_enabled': False}}
614         ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
615                                                {'ip': '192.0.2.1'}}}
616               }
617         prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
618         ceph_params = {
619             'CephPoolDefaultSize': 2,
620             'CephAnsibleExtraConfig': {
621                 'centos_package_dependencies': [],
622                 'ceph_osd_docker_memory_limit': '1g',
623                 'ceph_mds_docker_memory_limit': '1g'
624             },
625             'CephPoolDefaultPgNum': 32,
626             'CephAnsibleDisksConfig': {
627                 'devices': ['/dev/sdx'],
628                 'journal_size': 512,
629                 'osd_scenario': 'collocated'
630             }
631         }
632         mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
633                                          'parameter_defaults',
634                                          ceph_params)
635
636     @patch('apex.overcloud.deploy.os.path.isfile')
637     @patch('builtins.open', mock_open())
638     def test_prep_storage_env_raises(self, mock_isfile):
639         mock_isfile.return_value = False
640         ds = {'deploy_options': MagicMock()}
641         ns = {}
642         assert_raises(ApexDeployException, prep_storage_env, ds,
643                       ns, virtual=False, tmp_dir='/tmp')
644
645     @patch('apex.overcloud.deploy.generate_ceph_key')
646     @patch('apex.overcloud.deploy.fileinput')
647     @patch('apex.overcloud.deploy.os.path.isfile')
648     @patch('builtins.open', mock_open())
649     def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
650         ds = {'deploy_options':
651               {'sdn_controller': 'opendaylight',
652                'sriov': 'xxx'}}
653         try:
654             # Swap stdout
655             saved_stdout = sys.stdout
656             out = StringIO()
657             sys.stdout = out
658             # Run tests
659             mock_fileinput.input.return_value = \
660                 ['#  NovaSchedulerDefaultFilters',
661                  '#  NovaSchedulerAvailableFilters',
662                  '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
663                  '#NeutronSriovNumVFs: \"ens20f2:5\"',
664                  '#NovaPCIPassthrough:',
665                  '#  - devname: \"ens20f2\"',
666                  '#    physical_network: \"datacentre\"']
667             prep_sriov_env(ds, '/tmp')
668             output = out.getvalue().strip()
669             assert_in('NovaSchedulerDefaultFilters', output)
670             assert_in('NovaSchedulerAvailableFilters', output)
671             assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
672             assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
673             assert_in('NovaPCIPassthrough:', output)
674             assert_in('- devname: \"xxx\"', output)
675             assert_in('physical_network: \"nfv_sriov\"', output)
676         finally:
677             # put stdout back
678             sys.stdout = saved_stdout
679
680     @patch('apex.overcloud.deploy.os.path.isfile')
681     @patch('builtins.open', mock_open())
682     def test_prep_sriov_env_raises(self, mock_isfile):
683         ds_opts = {'sriov': True}
684         ds = {'deploy_options': MagicMock()}
685         ds['deploy_options'].__getitem__.side_effect = \
686             lambda i: ds_opts.get(i, MagicMock())
687         mock_isfile.return_value = False
688         ds = {'deploy_options': MagicMock()}
689         assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
690
691     def test_external_network_cmds(self):
692         ds = {'deploy_options':
693               {'sdn_controller': 'opendaylight',
694                'dataplane': 'ovs'}}
695
696         cidr = MagicMock()
697         cidr.version = 6
698         ns_dict = {'networks':
699                    {'external': [{'floating_ip_range': (0, 1),
700                                   'nic_mapping':
701                                   {'compute': {'vlan': 'native'}},
702                                   'gateway': 'gw',
703                                   'cidr': cidr}]}}
704         ns = MagicMock()
705         ns.enabled_network_list = ['external']
706         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
707         cmds = ' '.join(external_network_cmds(ns, ds))
708         assert_in('--external', cmds)
709         assert_in('--allocation-pool start=0,end=1', cmds)
710         assert_in('--gateway gw', cmds)
711         assert_in('--network external', cmds)
712         assert_in('--provider-physical-network datacentre', cmds)
713
714     def test_external_network_cmds_nosdn_fdio(self):
715         ds = {'deploy_options':
716               {'sdn_controller': False,
717                'dataplane': 'fdio'}}
718
719         cidr = MagicMock()
720         cidr.version = 6
721         ns_dict = {'networks':
722                    {'external': [{'floating_ip_range': (0, 1),
723                                   'nic_mapping':
724                                   {'compute': {'vlan': 'native'}},
725                                   'gateway': 'gw',
726                                   'cidr': cidr}]}}
727         ns = MagicMock()
728         ns.enabled_network_list = ['external']
729         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
730         cmds = ' '.join(external_network_cmds(ns, ds))
731         assert_in('--external', cmds)
732         assert_in('--allocation-pool start=0,end=1', cmds)
733         assert_in('--gateway gw', cmds)
734         assert_in('--network external', cmds)
735         assert_in('--provider-physical-network external', cmds)
736
737     def test_external_network_cmds_no_ext(self):
738         ds = {'deploy_options':
739               {'sdn_controller': 'opendaylight',
740                'dataplane': 'ovs'}}
741
742         cidr = MagicMock()
743         cidr.version = 6
744         ns_dict = {'apex':
745                    {'networks':
746                     {'admin':
747                      {'introspection_range': (0, 1),
748                       'nic_mapping':
749                       {'compute': {'vlan': '123'}},
750                       'gateway': 'gw',
751                       'cidr': cidr}}}}
752         ns = MagicMock()
753         ns.enabled_network_list = ['admin']
754         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
755         cmds = ' '.join(external_network_cmds(ns, ds))
756         assert_in('--external', cmds)
757         assert_in('--allocation-pool start=0,end=1', cmds)
758         assert_in('--network external', cmds)
759         assert_in('--provider-network-type vlan', cmds)
760
761     @patch('apex.overcloud.deploy.parsers')
762     def test_create_congress_cmds(self, mock_parsers):
763         assert_greater(len(create_congress_cmds('overcloud_file')), 0)
764
765     @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
766     def test_create_congress_cmds_raises(self, mock_parsers):
767         mock_parsers.return_value.__getitem__.side_effect = KeyError()
768         assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
769
770     def test_get_docker_sdn_file(self):
771         ds_opts = {'ha_enabled': True,
772                    'congress': True,
773                    'tacker': True,
774                    'containers': False,
775                    'barometer': True,
776                    'ceph': False,
777                    'sdn_controller': 'opendaylight',
778                    'os_version': 'queens'
779                    }
780         output = get_docker_sdn_file(ds_opts)
781         self.assertEqual(output,
782                          ('/usr/share/openstack-tripleo-heat-templates'
783                           '/environments/services/neutron-opendaylight'
784                           '.yaml')
785                          )