Fixes unit test failures
[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 mock
11 import os
12 import sys
13 import unittest
14
15 from mock import patch
16 from mock import MagicMock
17 from mock import mock_open
18 from io import StringIO
19
20 from apex.common import constants as con
21 from apex.common.exceptions import ApexDeployException
22 from apex.overcloud.deploy import build_sdn_env_list
23 from apex.overcloud.deploy import create_deploy_cmd
24 from apex.overcloud.deploy import prep_image
25 from apex.overcloud.deploy import make_ssh_key
26 from apex.overcloud.deploy import prep_env
27 from apex.overcloud.deploy import generate_ceph_key
28 from apex.overcloud.deploy import prep_storage_env
29 from apex.overcloud.deploy import prep_sriov_env
30 from apex.overcloud.deploy import external_network_cmds
31 from apex.overcloud.deploy import create_congress_cmds
32 from apex.overcloud.deploy import SDN_FILE_MAP
33 from apex.overcloud.deploy import get_docker_sdn_files
34
35 from nose.tools import (
36     assert_regexp_matches,
37     assert_raises,
38     assert_in,
39     assert_not_in,
40     assert_greater,
41     assert_equal)
42
43
44 class TestOvercloudDeploy(unittest.TestCase):
45     @classmethod
46     def setup_class(cls):
47         """This method is run once for each class before any tests are run"""
48
49     @classmethod
50     def teardown_class(cls):
51         """This method is run once for each class _after_ all tests are run"""
52
53     def setup(self):
54         """This method is run once before _each_ test method is executed"""
55
56     def teardown(self):
57         """This method is run once after _each_ test method is executed"""
58
59     def test_build_sdn_env_list(self):
60         ds = {'sdn_controller': 'opendaylight'}
61         sdn_map = {'opendaylight': 'test'}
62         res = '/usr/share/openstack-tripleo-heat-templates/environments/test'
63         assert_equal(build_sdn_env_list(ds, sdn_map), [res])
64
65     def test_build_sdn_env_list_dict(self):
66         ds = {'opendaylight': True,
67               'sdn_controller': None}
68         sdn_map = {'opendaylight': {}}
69         assert_equal(build_sdn_env_list(ds, sdn_map), [])
70
71     def test_build_sdn_env_list_tuple(self):
72         ds = {'opendaylight': 'test',
73               'sdn_controller': None}
74         sdn_map = {'opendaylight': ('test', 'test')}
75         res = '/usr/share/openstack-tripleo-heat-templates/environments/test'
76         assert_equal(build_sdn_env_list(ds, sdn_map), [res])
77
78     def test_build_sdn_env_list_with_string(self):
79         ds = {'sdn_controller': 'opendaylight',
80               'sriov': 'xxx'}
81         prefix = '/usr/share/openstack-tripleo-heat-templates/environments'
82         res = [os.path.join(prefix, 'neutron-opendaylight.yaml'),
83                os.path.join(prefix, 'neutron-opendaylight-sriov.yaml')]
84         assert_equal(build_sdn_env_list(ds, SDN_FILE_MAP), res)
85
86     def test_build_sdn_env_list_with_default(self):
87         ds = {'sdn_controller': 'opendaylight',
88               'vpn': True}
89         prefix = '/usr/share/openstack-tripleo-heat-templates/environments'
90         res = [os.path.join(prefix, 'neutron-opendaylight.yaml'),
91                os.path.join(prefix, 'neutron-bgpvpn-opendaylight.yaml')]
92         assert_equal(build_sdn_env_list(ds, SDN_FILE_MAP), res)
93
94     @patch('apex.overcloud.deploy.prep_sriov_env')
95     @patch('apex.overcloud.deploy.prep_storage_env')
96     @patch('apex.overcloud.deploy.build_sdn_env_list')
97     @patch('builtins.open', mock_open())
98     def test_create_deploy_cmd(self, mock_sdn_list, mock_prep_storage,
99                                mock_prep_sriov):
100         mock_sdn_list.return_value = []
101         ds = {'deploy_options':
102               {'ha_enabled': True,
103                'congress': True,
104                'tacker': True,
105                'containers': False,
106                'barometer': True,
107                'ceph': False,
108                'sriov': False,
109                'vim': 'openstack'
110                },
111               'global_params': MagicMock()}
112
113         ns = {'ntp': ['ntp']}
114         inv = MagicMock()
115         inv.get_node_counts.return_value = (3, 2)
116         virt = True
117         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
118         assert_in('--ntp-server ntp', result_cmd)
119         assert_in('enable_tacker.yaml', result_cmd)
120         assert_in('enable_congress.yaml', result_cmd)
121         assert_in('enable_barometer.yaml', result_cmd)
122         assert_in('virtual-environment.yaml', result_cmd)
123         assert_in('--control-scale 3', result_cmd)
124         assert_in('--compute-scale 2', result_cmd)
125
126     @patch('apex.overcloud.deploy.prep_sriov_env')
127     @patch('apex.overcloud.deploy.prep_storage_env')
128     @patch('builtins.open', mock_open())
129     def test_create_deploy_cmd_containers_sdn(self, mock_prep_storage,
130                                               mock_prep_sriov):
131         ds = {'deploy_options':
132               {'ha_enabled': True,
133                'congress': False,
134                'tacker': False,
135                'containers': True,
136                'barometer': False,
137                'vpn': False,
138                'ceph': True,
139                'sdn_controller': 'opendaylight',
140                'sriov': False,
141                'os_version': 'queens',
142                'vim': 'openstack'
143                },
144               'global_params': MagicMock()}
145
146         ns = {'ntp': ['ntp']}
147         inv = MagicMock()
148         inv.get_node_counts.return_value = (3, 2)
149         virt = True
150         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
151         assert_in('--ntp-server ntp', result_cmd)
152         assert_not_in('enable_tacker.yaml', result_cmd)
153         assert_not_in('enable_congress.yaml', result_cmd)
154         assert_not_in('enable_barometer.yaml', result_cmd)
155         assert_in('virtual-environment.yaml', result_cmd)
156         assert_in('--control-scale 3', result_cmd)
157         assert_in('--compute-scale 2', result_cmd)
158         assert_in('docker-images.yaml', result_cmd)
159         assert_in('sdn-images.yaml', result_cmd)
160         assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
161                   '/docker.yaml', result_cmd)
162         assert_in('/usr/share/openstack-tripleo-heat-templates/environments/'
163                   'storage-environment.yaml', result_cmd)
164         assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
165                   '/services/neutron-opendaylight.yaml', result_cmd)
166         ds['deploy_options']['os_version'] = 'master'
167         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
168         assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
169                   '/services/neutron-opendaylight.yaml', result_cmd)
170
171     @patch('apex.overcloud.deploy.prep_sriov_env')
172     @patch('apex.overcloud.deploy.prep_storage_env')
173     @patch('apex.overcloud.deploy.build_sdn_env_list')
174     @patch('builtins.open', mock_open())
175     def test_create_deploy_cmd_no_ha_bm(self, mock_sdn_list,
176                                         mock_prep_storage, mock_prep_sriov):
177         mock_sdn_list.return_value = []
178         ds = {'deploy_options': MagicMock(),
179               'global_params': MagicMock()}
180         ds['global_params'].__getitem__.side_effect = \
181             lambda i: False if i == 'ha_enabled' else MagicMock()
182         ds['deploy_options'].__getitem__.side_effect = \
183             lambda i: 'master' if i == 'os_version' else MagicMock()
184         ns = {'ntp': ['ntp']}
185         inv = MagicMock()
186         inv.get_node_counts.return_value = (3, 2)
187         virt = False
188         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
189         assert_in('--ntp-server ntp', result_cmd)
190         assert_in('--control-scale 1', result_cmd)
191         assert_in('--compute-scale 2', result_cmd)
192         assert_in('baremetal-environment.yaml', result_cmd)
193         assert_not_in('enable_tacker.yaml', result_cmd)
194         assert_not_in('enable_congress.yaml', result_cmd)
195         assert_not_in('enable_barometer.yaml', result_cmd)
196
197     @patch('apex.builders.overcloud_builder.inject_opendaylight')
198     @patch('apex.overcloud.deploy.virt_utils')
199     @patch('apex.overcloud.deploy.shutil')
200     @patch('apex.overcloud.deploy.os.path')
201     @patch('builtins.open', mock_open())
202     def test_prep_image(self, mock_os_path, mock_shutil, mock_virt_utils,
203                         mock_inject_odl):
204         ds_opts = {'dataplane': 'fdio',
205                    'sdn_controller': 'opendaylight',
206                    'odl_version': 'master',
207                    'vpn': False,
208                    'sriov': False}
209         ds = {'deploy_options': MagicMock(),
210               'global_params': MagicMock()}
211         ds['deploy_options'].__getitem__.side_effect = \
212             lambda i: ds_opts.get(i, MagicMock())
213         ns = MagicMock()
214         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
215         mock_virt_utils.virt_customize.assert_called()
216         mock_inject_odl.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                    'vpn': False,
226                    'sdn_controller': False}
227         ds = {'deploy_options': MagicMock(),
228               'global_params': MagicMock()}
229         ds['deploy_options'].__getitem__.side_effect = \
230             lambda i: ds_opts.get(i, MagicMock())
231         ns = MagicMock()
232         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
233         mock_virt_utils.virt_customize.assert_called()
234
235     @patch('apex.builders.overcloud_builder.inject_opendaylight')
236     @patch('apex.overcloud.deploy.virt_utils')
237     @patch('apex.overcloud.deploy.shutil')
238     @patch('apex.overcloud.deploy.os.path')
239     @patch('builtins.open', mock_open())
240     def test_prep_image_sdn_odl(self, mock_os_path, mock_shutil,
241                                 mock_virt_utils, mock_inject_odl):
242         ds_opts = {'dataplane': 'ovs',
243                    'sdn_controller': 'opendaylight',
244                    'vpn': False,
245                    'odl_version': con.DEFAULT_ODL_VERSION,
246                    'odl_vpp_netvirt': True}
247         ds = {'deploy_options': MagicMock(),
248               'global_params': MagicMock()}
249         ds['deploy_options'].__getitem__.side_effect = \
250             lambda i: ds_opts.get(i, MagicMock())
251         ds['deploy_options'].__contains__.side_effect = \
252             lambda i: True if i in ds_opts else MagicMock()
253         ns = MagicMock()
254         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
255         mock_virt_utils.virt_customize.assert_called()
256         mock_inject_odl.assert_called()
257
258     @patch('apex.overcloud.deploy.c_builder')
259     @patch('apex.overcloud.deploy.oc_builder')
260     @patch('apex.overcloud.deploy.virt_utils')
261     @patch('apex.overcloud.deploy.shutil')
262     @patch('apex.overcloud.deploy.os.path')
263     @patch('builtins.open', mock_open())
264     def test_prep_image_sdn_odl_upstream_containers_patches(
265             self, mock_os_path, mock_shutil, mock_virt_utils,
266             mock_oc_builder, mock_c_builder):
267         ds_opts = {'dataplane': 'ovs',
268                    'sdn_controller': 'opendaylight',
269                    'odl_version': con.DEFAULT_ODL_VERSION,
270                    'odl_vpp_netvirt': True}
271         ds = {'deploy_options': MagicMock(),
272               'global_params': MagicMock()}
273         ds['deploy_options'].__getitem__.side_effect = \
274             lambda i: ds_opts.get(i, MagicMock())
275         ds['deploy_options'].__contains__.side_effect = \
276             lambda i: True if i in ds_opts else MagicMock()
277         ns = MagicMock()
278         mock_c_builder.add_upstream_patches.return_value = ['nova-api']
279         patches = ['dummy_nova_patch']
280         rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
281                         docker_tag='latest', patches=patches)
282         mock_oc_builder.inject_opendaylight.assert_called()
283         mock_virt_utils.virt_customize.assert_called()
284         mock_c_builder.add_upstream_patches.assert_called()
285         self.assertListEqual(sorted(rv), ['nova-api', 'opendaylight'])
286
287     @patch('apex.overcloud.deploy.c_builder')
288     @patch('apex.overcloud.deploy.oc_builder')
289     @patch('apex.overcloud.deploy.virt_utils')
290     @patch('apex.overcloud.deploy.shutil')
291     @patch('apex.overcloud.deploy.os.path')
292     @patch('builtins.open', mock_open())
293     def test_prep_image_nosdn_upstream_containers_patches(
294             self, mock_os_path, mock_shutil, mock_virt_utils,
295             mock_oc_builder, mock_c_builder):
296         ds_opts = {'dataplane': 'ovs',
297                    'sdn_controller': False,
298                    'odl_version': con.DEFAULT_ODL_VERSION,
299                    'odl_vpp_netvirt': False}
300         ds = {'deploy_options': MagicMock(),
301               'global_params': MagicMock()}
302         ds['deploy_options'].__getitem__.side_effect = \
303             lambda i: ds_opts.get(i, MagicMock())
304         ds['deploy_options'].__contains__.side_effect = \
305             lambda i: True if i in ds_opts else MagicMock()
306         ns = MagicMock()
307         mock_c_builder.add_upstream_patches.return_value = ['nova-api']
308         patches = ['dummy_nova_patch']
309         rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
310                         docker_tag='latest', patches=patches)
311         mock_virt_utils.virt_customize.assert_called()
312         mock_c_builder.add_upstream_patches.assert_called()
313         self.assertListEqual(sorted(rv), ['nova-api'])
314
315     @patch('apex.overcloud.deploy.oc_builder')
316     @patch('apex.overcloud.deploy.virt_utils')
317     @patch('apex.overcloud.deploy.shutil')
318     @patch('apex.overcloud.deploy.os.path')
319     @patch('builtins.open', mock_open())
320     def test_prep_image_sdn_odl_not_def(self, mock_os_path,
321                                         mock_shutil, mock_virt_utils,
322                                         mock_oc_builder):
323         ds_opts = {'dataplane': 'ovs',
324                    'sdn_controller': 'opendaylight',
325                    'odl_version': 'uncommon'}
326         ds = {'deploy_options': MagicMock(),
327               'global_params': MagicMock()}
328         ds['deploy_options'].__getitem__.side_effect = \
329             lambda i: ds_opts.get(i, MagicMock())
330         ns = MagicMock()
331         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
332         mock_virt_utils.virt_customize.assert_called()
333         mock_oc_builder.inject_opendaylight.assert_called()
334
335     @patch('apex.overcloud.deploy.virt_utils')
336     @patch('apex.overcloud.deploy.shutil')
337     @patch('apex.overcloud.deploy.os.path')
338     @patch('builtins.open', mock_open())
339     def test_prep_image_sdn_ovn(self, mock_os_path, mock_shutil,
340                                 mock_virt_utils):
341         ds_opts = {'dataplane': 'ovs',
342                    'vpn': False,
343                    'sdn_controller': 'ovn'}
344         ds = {'deploy_options': MagicMock(),
345               'global_params': MagicMock()}
346         ds['deploy_options'].__getitem__.side_effect = \
347             lambda i: ds_opts.get(i, MagicMock())
348         ns = MagicMock()
349         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
350         mock_virt_utils.virt_customize.assert_called()
351
352     @patch('apex.builders.overcloud_builder.inject_quagga')
353     @patch('apex.builders.overcloud_builder.inject_opendaylight')
354     @patch('apex.overcloud.deploy.virt_utils')
355     @patch('apex.overcloud.deploy.shutil')
356     @patch('apex.overcloud.deploy.os.path')
357     @patch('builtins.open', mock_open())
358     def test_prep_image_sdn_odl_vpn(self, mock_os_path, mock_shutil,
359                                     mock_virt_utils, mock_inject_odl,
360                                     mock_inject_quagga):
361         ds_opts = {'dataplane': 'ovs',
362                    'sdn_controller': 'opendaylight',
363                    'vpn': True,
364                    'odl_version': con.DEFAULT_ODL_VERSION,
365                    'odl_vpp_netvirt': True}
366         ds = {'deploy_options': MagicMock(),
367               'global_params': MagicMock()}
368         ds['deploy_options'].__getitem__.side_effect = \
369             lambda i: ds_opts.get(i, MagicMock())
370         ds['deploy_options'].__contains__.side_effect = \
371             lambda i: True if i in ds_opts else MagicMock()
372         ns = MagicMock()
373         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
374         mock_virt_utils.virt_customize.assert_called()
375         mock_inject_odl.assert_called()
376         mock_inject_quagga.assert_called()
377
378     @patch('apex.overcloud.deploy.os.path.isfile')
379     def test_prep_image_no_image(self, mock_isfile):
380         mock_isfile.return_value = False
381         assert_raises(ApexDeployException, prep_image,
382                       {}, {}, 'undercloud.qcow2', '/tmp')
383
384     def test_make_ssh_key(self):
385         priv, pub = make_ssh_key()
386         assert_in('-----BEGIN PRIVATE KEY-----', priv)
387         assert_in('ssh-rsa', pub)
388
389     @patch('apex.overcloud.deploy.yaml')
390     @patch('apex.overcloud.deploy.fileinput')
391     @patch('apex.overcloud.deploy.shutil')
392     @patch('builtins.open', mock_open())
393     def test_prep_env(self, mock_shutil, mock_fileinput, mock_yaml):
394         mock_fileinput.input.return_value = \
395             ['CloudDomain', 'replace_private_key', 'replace_public_key',
396              'opendaylight::vpp_routing_node', 'ControllerExtraConfig',
397              'NovaComputeExtraConfig', 'ComputeKernelArgs', 'HostCpusList',
398              'ComputeExtraConfigPre', 'resource_registry',
399              'NovaSchedulerDefaultFilters']
400         mock_yaml.safe_load.return_value = {
401             'parameter_defaults': {
402                 'ControllerServices': [1, 2, 3],
403                 'ComputeServices': [3, 4, 5]
404             }}
405         ds = {'global_params': {'ha_enabled': False},
406               'deploy_options':
407               {'sdn_controller': 'opendaylight',
408                'odl_vpp_routing_node': 'test',
409                'dataplane': 'ovs_dpdk',
410                'sriov': 'xxx',
411                'performance': {'Compute': {'vpp': {'main-core': 'test',
412                                                    'corelist-workers': 'test'},
413                                            'ovs': {'dpdk_cores': 'test'},
414                                            'kernel': {'test': 'test'}},
415                                'Controller': {'vpp': 'test'}}}}
416         ns_dict = {'domain_name': 'test.domain',
417                    'networks':
418                    {'tenant':
419                     {'nic_mapping': {'controller':
420                                      {'members': ['tenant_nic']},
421                                      'compute':
422                                      {'members': ['tenant_nic']}}},
423                     'external':
424                     [{'nic_mapping': {'controller':
425                                       {'members': ['ext_nic']},
426                                       'compute':
427                                       {'members': ['ext_nic']}}}]}}
428         inv = MagicMock()
429         inv.get_node_counts.return_value = (1, 0)
430         try:
431             # Swap stdout
432             saved_stdout = sys.stdout
433             out = StringIO()
434             sys.stdout = out
435             ns = MagicMock()
436             ns.enabled_network_list = ['external', 'tenant']
437             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
438             # run test
439             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
440             output = out.getvalue().strip()
441             assert_in('CloudDomain: test.domain', output)
442             assert_in('ssh-rsa', output)
443             assert_in('ComputeKernelArgs: \'test=test \'', output)
444             assert_in('fdio::vpp_cpu_main_core: \'test\'', output)
445             mock_yaml.safe_dump.assert_called_with(
446                 {'parameter_defaults': {
447                     'ControllerServices': [1, 2, 3, 4, 5],
448                 }},
449                 mock.ANY, default_flow_style=False
450             )
451         finally:
452             # put stdout back
453             sys.stdout = saved_stdout
454
455     @patch('apex.overcloud.deploy.fileinput')
456     @patch('apex.overcloud.deploy.shutil')
457     @patch('builtins.open', mock_open())
458     def test_prep_env_round_two(self, mock_shutil, mock_fileinput):
459         mock_fileinput.input.return_value = \
460             ['NeutronVPPAgentPhysnets']
461         ds = {'global_params': {'ha_enabled': False},
462               'deploy_options':
463               {'sdn_controller': False,
464                'dataplane': 'fdio',
465                'sriov': 'xxx',
466                'performance': {'Compute': {},
467                                'Controller': {}}}}
468         ns_dict = {'domain_name': 'test.domain',
469                    'networks':
470                    {'tenant':
471                     {'nic_mapping': {'controller':
472                                      {'members': ['tenant_nic']},
473                                      'compute':
474                                      {'members': ['tenant_nic']}}},
475                     'external':
476                     [{'nic_mapping': {'controller':
477                                       {'members': ['ext_nic']},
478                                       'compute':
479                                       {'members': ['ext_nic']}}}]}}
480         inv = MagicMock()
481         inv.get_node_counts.return_value = (3, 2)
482         try:
483             # Swap stdout
484             saved_stdout = sys.stdout
485             out = StringIO()
486             sys.stdout = out
487             ns = MagicMock()
488             ns.enabled_network_list = ['external', 'tenant']
489             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
490             # run test
491             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
492             output = out.getvalue().strip()
493             assert_in('NeutronVPPAgentPhysnets: '
494                       '\'datacentre:tenant_nic,external:tap0\'',
495                       output)
496             assert_in('NeutronVPPAgentPhysnets', output)
497         finally:
498             # put stdout back
499             sys.stdout = saved_stdout
500
501     @patch('apex.overcloud.deploy.fileinput')
502     @patch('apex.overcloud.deploy.shutil')
503     @patch('builtins.open', mock_open())
504     def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
505         mock_fileinput.input.return_value = \
506             ['OS::TripleO::Services::NeutronDhcpAgent',
507              'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
508         ds = {'global_params': {'ha_enabled': False},
509               'deploy_options':
510               {'sdn_controller': 'opendaylight',
511                'dataplane': 'fdio',
512                'sriov': 'xxx',
513                'dvr': True}}
514         ns_dict = {'domain_name': 'test.domain',
515                    'networks':
516                    {'tenant':
517                     {'nic_mapping': {'controller':
518                                      {'members': ['tenant_nic']},
519                                      'compute':
520                                      {'members': ['tenant_nic']}}},
521                     'external':
522                     [{'nic_mapping': {'controller':
523                                       {'members': ['ext_nic']},
524                                       'compute':
525                                       {'members': ['ext_nic']}}}]}}
526         inv = MagicMock()
527         inv.get_node_counts.return_value = (3, 2)
528         try:
529             # Swap stdout
530             saved_stdout = sys.stdout
531             out = StringIO()
532             sys.stdout = out
533             ns = MagicMock()
534             ns.enabled_network_list = ['external', 'tenant']
535             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
536             # run test
537             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
538             output = out.getvalue().strip()
539             assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
540         finally:
541             # put stdout back
542             sys.stdout = saved_stdout
543
544     @patch('apex.overcloud.deploy.fileinput')
545     @patch('apex.overcloud.deploy.shutil')
546     @patch('builtins.open', mock_open())
547     def test_prep_env_tenant_vlan(self, mock_shutil, mock_fileinput):
548         mock_fileinput.input.return_value = \
549             ['NeutronNetworkVLANRanges',
550              'NeutronNetworkType', 'NeutronBridgeMappings']
551         ds = {'global_params': {'ha_enabled': False},
552               'deploy_options':
553               {'sdn_controller': False,
554                'dataplane': 'ovs',
555                'sriov': 'xxx',
556                'dvr': True}}
557         ns_dict = {'domain_name': 'test.domain',
558                    'networks':
559                    {'tenant':
560                     {'nic_mapping': {'controller':
561                                      {'members': ['tenant_nic']},
562                                      'compute':
563                                      {'members': ['tenant_nic']}},
564                      'segmentation_type': 'vlan',
565                      'overlay_id_range': 'vlan:500:600'
566                      },
567                     'external':
568                     [{'nic_mapping': {'controller':
569                                       {'members': ['ext_nic']},
570                                       'compute':
571                                       {'members': ['ext_nic']}}}]}}
572         inv = MagicMock()
573         inv.get_node_counts.return_value = (3, 2)
574         try:
575             # Swap stdout
576             saved_stdout = sys.stdout
577             out = StringIO()
578             sys.stdout = out
579             ns = MagicMock()
580             ns.enabled_network_list = ['external', 'tenant']
581             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
582             # run test
583             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
584             output = out.getvalue().strip()
585             assert_in('NeutronNetworkVLANRanges: '
586                       'vlan:500:600,datacentre:1:1000', output)
587             assert_in('NeutronNetworkType: vlan', output)
588             assert_in('NeutronBridgeMappings: '
589                       'vlan:br-vlan,datacentre:br-ex', output)
590             assert_not_in('OpenDaylightProviderMappings', output)
591         finally:
592             # put stdout back
593             sys.stdout = saved_stdout
594
595     @patch('apex.overcloud.deploy.fileinput')
596     @patch('apex.overcloud.deploy.shutil')
597     @patch('builtins.open', mock_open())
598     def test_prep_env_tenant_vlan_odl(self, mock_shutil, mock_fileinput):
599         mock_fileinput.input.return_value = \
600             ['NeutronNetworkVLANRanges',
601              'NeutronNetworkType',
602              'NeutronBridgeMappings',
603              'OpenDaylightProviderMappings']
604         ds = {'global_params': {'ha_enabled': False},
605               'deploy_options':
606               {'sdn_controller': 'opendaylight',
607                'dataplane': 'ovs',
608                'sriov': 'xxx',
609                'dvr': True}}
610         ns_dict = {'domain_name': 'test.domain',
611                    'networks':
612                    {'tenant':
613                     {'nic_mapping': {'controller':
614                                      {'members': ['tenant_nic']},
615                                      'compute':
616                                      {'members': ['tenant_nic']}},
617                      'segmentation_type': 'vlan',
618                      'overlay_id_range': 'vlan:500:600'
619                      },
620                     'external':
621                     [{'nic_mapping': {'controller':
622                                       {'members': ['ext_nic']},
623                                       'compute':
624                                       {'members': ['ext_nic']}}}]}}
625         inv = MagicMock()
626         inv.get_node_counts.return_value = (3, 2)
627         try:
628             # Swap stdout
629             saved_stdout = sys.stdout
630             out = StringIO()
631             sys.stdout = out
632             ns = MagicMock()
633             ns.enabled_network_list = ['external', 'tenant']
634             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
635             # run test
636             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
637             output = out.getvalue().strip()
638             assert_in('NeutronNetworkVLANRanges: '
639                       'vlan:500:600,datacentre:1:1000', output)
640             assert_in('NeutronNetworkType: vlan', output)
641             assert_in('NeutronBridgeMappings: '
642                       'vlan:br-vlan,datacentre:br-ex', output)
643             assert_in('OpenDaylightProviderMappings: '
644                       'vlan:br-vlan,datacentre:br-ex', output)
645         finally:
646             # put stdout back
647             sys.stdout = saved_stdout
648
649     def test_generate_ceph_key(self):
650         assert_equal(len(generate_ceph_key()), 40)
651
652     @patch('apex.overcloud.deploy.generate_ceph_key')
653     @patch('apex.overcloud.deploy.fileinput')
654     @patch('apex.overcloud.deploy.os.path.isfile')
655     @patch('builtins.open', mock_open())
656     def test_prep_storage_env(self, mock_isfile, mock_fileinput,
657                               mock_ceph_key):
658         mock_fileinput.input.return_value = \
659             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
660         ds = {'deploy_options': {
661             'ceph_device': '/dev/sdx',
662             'containers': False
663         }}
664         ns = {}
665         prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
666
667     @patch('apex.overcloud.deploy.utils.edit_tht_env')
668     @patch('apex.overcloud.deploy.generate_ceph_key')
669     @patch('apex.overcloud.deploy.fileinput')
670     @patch('apex.overcloud.deploy.os.path.isfile')
671     @patch('builtins.open', mock_open())
672     def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
673                                          mock_ceph_key, mock_edit_tht):
674         mock_fileinput.input.return_value = \
675             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
676         ds = {'deploy_options': {
677               'ceph_device': '/dev/sdx',
678               'containers': True,
679               'os_version': 'master'
680               }, 'global_params': {'ha_enabled': False}}
681         ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
682                                                {'ip': '192.0.2.1'}}}
683               }
684         prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
685         ceph_params = {
686             'CephPoolDefaultSize': 2,
687             'CephAnsibleExtraConfig': {
688                 'centos_package_dependencies': [],
689                 'ceph_osd_docker_memory_limit': '1g',
690                 'ceph_mds_docker_memory_limit': '1g'
691             },
692             'CephPoolDefaultPgNum': 32,
693             'CephAnsibleDisksConfig': {
694                 'devices': ['/dev/sdx'],
695                 'journal_size': 512,
696                 'osd_scenario': 'collocated'
697             }
698         }
699         mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
700                                          'parameter_defaults',
701                                          ceph_params)
702
703     @patch('apex.overcloud.deploy.os.path.isfile')
704     @patch('builtins.open', mock_open())
705     def test_prep_storage_env_raises(self, mock_isfile):
706         mock_isfile.return_value = False
707         ds = {'deploy_options': MagicMock()}
708         ns = {}
709         assert_raises(ApexDeployException, prep_storage_env, ds,
710                       ns, virtual=False, tmp_dir='/tmp')
711
712     @patch('apex.overcloud.deploy.generate_ceph_key')
713     @patch('apex.overcloud.deploy.fileinput')
714     @patch('apex.overcloud.deploy.os.path.isfile')
715     @patch('builtins.open', mock_open())
716     def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
717         ds = {'deploy_options':
718               {'sdn_controller': 'opendaylight',
719                'sriov': 'xxx'}}
720         try:
721             # Swap stdout
722             saved_stdout = sys.stdout
723             out = StringIO()
724             sys.stdout = out
725             # Run tests
726             mock_fileinput.input.return_value = \
727                 ['#  NovaSchedulerDefaultFilters',
728                  '#  NovaSchedulerAvailableFilters',
729                  '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
730                  '#NeutronSriovNumVFs: \"ens20f2:5\"',
731                  '#NovaPCIPassthrough:',
732                  '#  - devname: \"ens20f2\"',
733                  '#    physical_network: \"datacentre\"']
734             prep_sriov_env(ds, '/tmp')
735             output = out.getvalue().strip()
736             assert_in('NovaSchedulerDefaultFilters', output)
737             assert_in('NovaSchedulerAvailableFilters', output)
738             assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
739             assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
740             assert_in('NovaPCIPassthrough:', output)
741             assert_in('- devname: \"xxx\"', output)
742             assert_in('physical_network: \"nfv_sriov\"', output)
743         finally:
744             # put stdout back
745             sys.stdout = saved_stdout
746
747     @patch('apex.overcloud.deploy.os.path.isfile')
748     @patch('builtins.open', mock_open())
749     def test_prep_sriov_env_raises(self, mock_isfile):
750         ds_opts = {'sriov': True}
751         ds = {'deploy_options': MagicMock()}
752         ds['deploy_options'].__getitem__.side_effect = \
753             lambda i: ds_opts.get(i, MagicMock())
754         mock_isfile.return_value = False
755         ds = {'deploy_options': MagicMock()}
756         assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
757
758     def test_external_network_cmds(self):
759         ds = {'deploy_options':
760               {'sdn_controller': 'opendaylight',
761                'dataplane': 'ovs'}}
762
763         cidr = MagicMock()
764         cidr.version = 6
765         ns_dict = {'networks':
766                    {'external': [{'floating_ip_range': (0, 1),
767                                   'nic_mapping':
768                                   {'compute': {'vlan': 'native'}},
769                                   'gateway': 'gw',
770                                   'cidr': cidr}]}}
771         ns = MagicMock()
772         ns.enabled_network_list = ['external']
773         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
774         cmds = ' '.join(external_network_cmds(ns, ds))
775         assert_in('--external', cmds)
776         assert_in('--allocation-pool start=0,end=1', cmds)
777         assert_in('--gateway gw', cmds)
778         assert_in('--network external', cmds)
779         assert_in('--provider-physical-network datacentre', cmds)
780
781     def test_external_network_cmds_nosdn_fdio(self):
782         ds = {'deploy_options':
783               {'sdn_controller': False,
784                'dataplane': 'fdio'}}
785
786         cidr = MagicMock()
787         cidr.version = 6
788         ns_dict = {'networks':
789                    {'external': [{'floating_ip_range': (0, 1),
790                                   'nic_mapping':
791                                   {'compute': {'vlan': 'native'}},
792                                   'gateway': 'gw',
793                                   'cidr': cidr}]}}
794         ns = MagicMock()
795         ns.enabled_network_list = ['external']
796         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
797         cmds = ' '.join(external_network_cmds(ns, ds))
798         assert_in('--external', cmds)
799         assert_in('--allocation-pool start=0,end=1', cmds)
800         assert_in('--gateway gw', cmds)
801         assert_in('--network external', cmds)
802         assert_in('--provider-physical-network external', cmds)
803
804     def test_external_network_cmds_no_ext(self):
805         ds = {'deploy_options':
806               {'sdn_controller': 'opendaylight',
807                'dataplane': 'ovs'}}
808
809         cidr = MagicMock()
810         cidr.version = 6
811         ns_dict = {'apex':
812                    {'networks':
813                     {'admin':
814                      {'introspection_range': (0, 1),
815                       'nic_mapping':
816                       {'compute': {'vlan': '123'}},
817                       'gateway': 'gw',
818                       'cidr': cidr}}}}
819         ns = MagicMock()
820         ns.enabled_network_list = ['admin']
821         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
822         cmds = ' '.join(external_network_cmds(ns, ds))
823         assert_in('--external', cmds)
824         assert_in('--allocation-pool start=0,end=1', cmds)
825         assert_in('--network external', cmds)
826         assert_in('--provider-network-type vlan', cmds)
827
828     @patch('apex.overcloud.deploy.parsers')
829     def test_create_congress_cmds(self, mock_parsers):
830         assert_greater(len(create_congress_cmds('overcloud_file')), 0)
831
832     @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
833     def test_create_congress_cmds_raises(self, mock_parsers):
834         mock_parsers.return_value.__getitem__.side_effect = KeyError()
835         assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
836
837     def test_get_docker_sdn_files(self):
838         ds_opts = {'ha_enabled': True,
839                    'congress': True,
840                    'tacker': True,
841                    'containers': False,
842                    'barometer': True,
843                    'ceph': False,
844                    'vpn': True,
845                    'sdn_controller': 'opendaylight',
846                    'os_version': 'queens'
847                    }
848         output = get_docker_sdn_files(ds_opts)
849         compare = ['/usr/share/openstack-tripleo-heat-templates/'
850                    'environments/services/neutron-opendaylight.yaml',
851                    '/usr/share/openstack-tripleo-heat-templates/environments'
852                    '/services/neutron-bgpvpn-opendaylight.yaml']
853         self.assertEqual(output, compare)