Revert "Updates scenario files for hunter branch"
[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('/usr/share/openstack-tripleo-heat-templates/environments'
160                   '/docker.yaml', result_cmd)
161         assert_in('/usr/share/openstack-tripleo-heat-templates/environments/'
162                   'storage-environment.yaml', result_cmd)
163         assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
164                   '/services/neutron-opendaylight.yaml', result_cmd)
165         ds['deploy_options']['os_version'] = 'master'
166         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
167         assert_in('/usr/share/openstack-tripleo-heat-templates/environments'
168                   '/services/neutron-opendaylight.yaml', result_cmd)
169
170     @patch('apex.overcloud.deploy.prep_sriov_env')
171     @patch('apex.overcloud.deploy.prep_storage_env')
172     @patch('apex.overcloud.deploy.build_sdn_env_list')
173     @patch('builtins.open', mock_open())
174     def test_create_deploy_cmd_no_ha_bm(self, mock_sdn_list,
175                                         mock_prep_storage, mock_prep_sriov):
176         mock_sdn_list.return_value = []
177         ds = {'deploy_options': MagicMock(),
178               'global_params': MagicMock()}
179         ds['global_params'].__getitem__.side_effect = \
180             lambda i: False if i == 'ha_enabled' else MagicMock()
181         ds['deploy_options'].__getitem__.side_effect = \
182             lambda i: 'master' if i == 'os_version' else MagicMock()
183         ns = {'ntp': ['ntp']}
184         inv = MagicMock()
185         inv.get_node_counts.return_value = (3, 2)
186         virt = False
187         result_cmd = create_deploy_cmd(ds, ns, inv, '/tmp', virt)
188         assert_in('--ntp-server ntp', result_cmd)
189         assert_in('--control-scale 1', result_cmd)
190         assert_in('--compute-scale 2', result_cmd)
191         assert_in('baremetal-environment.yaml', result_cmd)
192         assert_not_in('enable_tacker.yaml', result_cmd)
193         assert_not_in('enable_congress.yaml', result_cmd)
194         assert_not_in('enable_barometer.yaml', result_cmd)
195
196     @patch('apex.builders.overcloud_builder.inject_opendaylight')
197     @patch('apex.overcloud.deploy.virt_utils')
198     @patch('apex.overcloud.deploy.shutil')
199     @patch('apex.overcloud.deploy.os.path.isfile')
200     @patch('builtins.open', mock_open())
201     def test_prep_image(self, mock_is_file, mock_shutil, mock_virt_utils,
202                         mock_inject_odl):
203         mock_is_file.return_value = True
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.isfile')
221     @patch('builtins.open', mock_open())
222     def test_prep_image_sdn_false(self, mock_is_file, mock_shutil,
223                                   mock_virt_utils):
224         mock_is_file.return_value = True
225         ds_opts = {'dataplane': 'fdio',
226                    'vpn': False,
227                    'sdn_controller': False}
228         ds = {'deploy_options': MagicMock(),
229               'global_params': MagicMock()}
230         ds['deploy_options'].__getitem__.side_effect = \
231             lambda i: ds_opts.get(i, MagicMock())
232         ns = MagicMock()
233         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
234         mock_virt_utils.virt_customize.assert_called()
235
236     @patch('apex.builders.overcloud_builder.inject_ovs_nsh')
237     @patch('apex.overcloud.deploy.utils.fetch_upstream_and_unpack')
238     @patch('apex.builders.overcloud_builder.inject_opendaylight')
239     @patch('apex.overcloud.deploy.virt_utils')
240     @patch('apex.overcloud.deploy.shutil')
241     @patch('apex.overcloud.deploy.os.path.isfile')
242     @patch('builtins.open', mock_open())
243     def test_prep_image_sdn_odl(self, mock_is_file, mock_shutil,
244                                 mock_virt_utils, mock_inject_odl,
245                                 mock_fetch, mock_ovs_nsh):
246         mock_is_file.return_value = True
247         ds_opts = {'dataplane': 'ovs',
248                    'sdn_controller': 'opendaylight',
249                    'vpn': False,
250                    'sfc': False,
251                    'odl_version': con.DEFAULT_ODL_VERSION,
252                    'odl_vpp_netvirt': True}
253         ds = {'deploy_options': MagicMock(),
254               'global_params': MagicMock()}
255         ds['deploy_options'].__getitem__.side_effect = \
256             lambda i: ds_opts.get(i, MagicMock())
257         ds['deploy_options'].__contains__.side_effect = \
258             lambda i: True if i in ds_opts else MagicMock()
259         ns = MagicMock()
260         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
261         mock_virt_utils.virt_customize.assert_called()
262         mock_inject_odl.assert_called()
263         # mock_ovs_nsh.assert_called()
264
265     @patch('apex.overcloud.deploy.c_builder')
266     @patch('apex.overcloud.deploy.oc_builder')
267     @patch('apex.overcloud.deploy.virt_utils')
268     @patch('apex.overcloud.deploy.shutil')
269     @patch('apex.overcloud.deploy.os.path.isfile')
270     @patch('builtins.open', mock_open())
271     def test_prep_image_sdn_odl_upstream_containers_patches(
272             self, mock_is_file, mock_shutil, mock_virt_utils,
273             mock_oc_builder, mock_c_builder):
274         mock_is_file.return_value = True
275         ds_opts = {'dataplane': 'ovs',
276                    'sdn_controller': 'opendaylight',
277                    'odl_version': con.DEFAULT_ODL_VERSION,
278                    'odl_vpp_netvirt': True}
279         ds = {'deploy_options': MagicMock(),
280               'global_params': MagicMock()}
281         ds['deploy_options'].__getitem__.side_effect = \
282             lambda i: ds_opts.get(i, MagicMock())
283         ds['deploy_options'].__contains__.side_effect = \
284             lambda i: True if i in ds_opts else MagicMock()
285         ns = MagicMock()
286         mock_c_builder.add_upstream_patches.return_value = ['nova-api']
287         patches = ['dummy_nova_patch']
288         rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
289                         docker_tag='latest', patches=patches)
290         mock_oc_builder.inject_opendaylight.assert_called()
291         mock_virt_utils.virt_customize.assert_called()
292         mock_c_builder.add_upstream_patches.assert_called()
293         self.assertListEqual(sorted(rv), ['nova-api', 'opendaylight'])
294
295     @patch('apex.overcloud.deploy.c_builder')
296     @patch('apex.overcloud.deploy.oc_builder')
297     @patch('apex.overcloud.deploy.virt_utils')
298     @patch('apex.overcloud.deploy.shutil')
299     @patch('apex.overcloud.deploy.os.path.isfile')
300     @patch('builtins.open', mock_open())
301     def test_prep_image_nosdn_upstream_containers_patches(
302             self, mock_is_file, mock_shutil, mock_virt_utils,
303             mock_oc_builder, mock_c_builder):
304         mock_is_file.return_value = True
305         ds_opts = {'dataplane': 'ovs',
306                    'sdn_controller': False,
307                    'odl_version': con.DEFAULT_ODL_VERSION,
308                    'odl_vpp_netvirt': False}
309         ds = {'deploy_options': MagicMock(),
310               'global_params': MagicMock()}
311         ds['deploy_options'].__getitem__.side_effect = \
312             lambda i: ds_opts.get(i, MagicMock())
313         ds['deploy_options'].__contains__.side_effect = \
314             lambda i: True if i in ds_opts else MagicMock()
315         ns = MagicMock()
316         mock_c_builder.add_upstream_patches.return_value = ['nova-api']
317         patches = ['dummy_nova_patch']
318         rv = prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test',
319                         docker_tag='latest', patches=patches)
320         mock_virt_utils.virt_customize.assert_called()
321         mock_c_builder.add_upstream_patches.assert_called()
322         self.assertListEqual(sorted(rv), ['nova-api'])
323
324     @patch('apex.overcloud.deploy.oc_builder')
325     @patch('apex.overcloud.deploy.virt_utils')
326     @patch('apex.overcloud.deploy.shutil')
327     @patch('apex.overcloud.deploy.os.path.isfile')
328     @patch('builtins.open', mock_open())
329     def test_prep_image_sdn_odl_not_def(self, mock_is_file,
330                                         mock_shutil, mock_virt_utils,
331                                         mock_oc_builder):
332         mock_is_file.return_value = True
333         ds_opts = {'dataplane': 'ovs',
334                    'sdn_controller': 'opendaylight',
335                    'odl_version': 'uncommon'}
336         ds = {'deploy_options': MagicMock(),
337               'global_params': MagicMock()}
338         ds['deploy_options'].__getitem__.side_effect = \
339             lambda i: ds_opts.get(i, MagicMock())
340         ns = MagicMock()
341         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
342         mock_virt_utils.virt_customize.assert_called()
343         mock_oc_builder.inject_opendaylight.assert_called()
344
345     @patch('apex.builders.overcloud_builder.inject_ovs_nsh')
346     @patch('apex.overcloud.deploy.virt_utils')
347     @patch('apex.overcloud.deploy.shutil')
348     @patch('apex.overcloud.deploy.os.path.isfile')
349     @patch('builtins.open', mock_open())
350     def test_prep_image_sdn_ovn(self, mock_is_file, mock_shutil,
351                                 mock_virt_utils, mock_ovs_nsh):
352         mock_is_file.return_value = True
353         ds_opts = {'dataplane': 'ovs',
354                    'vpn': False,
355                    'sfc': False,
356                    'sdn_controller': 'ovn'}
357         ds = {'deploy_options': MagicMock(),
358               'global_params': MagicMock()}
359         ds['deploy_options'].__getitem__.side_effect = \
360             lambda i: ds_opts.get(i, MagicMock())
361         ns = MagicMock()
362         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
363         mock_virt_utils.virt_customize.assert_called()
364         # mock_ovs_nsh.assert_called()
365
366     @patch('apex.builders.overcloud_builder.inject_ovs_nsh')
367     @patch('apex.overcloud.deploy.utils.fetch_upstream_and_unpack')
368     @patch('apex.builders.overcloud_builder.inject_quagga')
369     @patch('apex.builders.overcloud_builder.inject_opendaylight')
370     @patch('apex.overcloud.deploy.virt_utils')
371     @patch('apex.overcloud.deploy.shutil')
372     @patch('apex.overcloud.deploy.os.path.isfile')
373     @patch('builtins.open', mock_open())
374     def test_prep_image_sdn_odl_vpn(self, mock_is_file, mock_shutil,
375                                     mock_virt_utils, mock_inject_odl,
376                                     mock_inject_quagga, mock_fetch,
377                                     mock_ovs_nsh):
378         mock_is_file.return_value = True
379         ds_opts = {'dataplane': 'ovs',
380                    'sdn_controller': 'opendaylight',
381                    'vpn': True,
382                    'sfc': False,
383                    'odl_version': con.DEFAULT_ODL_VERSION,
384                    'odl_vpp_netvirt': True}
385         ds = {'deploy_options': MagicMock(),
386               'global_params': MagicMock()}
387         ds['deploy_options'].__getitem__.side_effect = \
388             lambda i: ds_opts.get(i, MagicMock())
389         ds['deploy_options'].__contains__.side_effect = \
390             lambda i: True if i in ds_opts else MagicMock()
391         ns = MagicMock()
392         prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
393         mock_virt_utils.virt_customize.assert_called()
394         mock_inject_odl.assert_called()
395         mock_inject_quagga.assert_called()
396         # mock_ovs_nsh.assert_called()
397
398         @patch('apex.builders.overcloud_builder.inject_ovs_nsh')
399         @patch('apex.builders.overcloud_builder.inject_opendaylight')
400         @patch('apex.overcloud.deploy.virt_utils')
401         @patch('apex.overcloud.deploy.shutil')
402         @patch('apex.overcloud.deploy.os.path.isfile')
403         @patch('builtins.open', mock_open())
404         def test_prep_image_sdn_odl_sfc(self, mock_is_file, mock_shutil,
405                                         mock_virt_utils, mock_inject_odl,
406                                         mock_inject_ovs_nsh):
407             mock_is_file.return_value = True
408             ds_opts = {'dataplane': 'ovs',
409                        'sdn_controller': 'opendaylight',
410                        'vpn': False,
411                        'sfc': True,
412                        'odl_version': con.DEFAULT_ODL_VERSION,
413                        'odl_vpp_netvirt': True}
414             ds = {'deploy_options': MagicMock(),
415                   'global_params': MagicMock()}
416             ds['deploy_options'].__getitem__.side_effect = \
417                 lambda i: ds_opts.get(i, MagicMock())
418             ds['deploy_options'].__contains__.side_effect = \
419                 lambda i: True if i in ds_opts else MagicMock()
420             ns = MagicMock()
421             prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test')
422             mock_virt_utils.virt_customize.assert_called()
423             mock_inject_odl.assert_called()
424             # mock_inject_ovs_nsh.assert_called()
425
426     @patch('apex.overcloud.deploy.os.path.isfile')
427     def test_prep_image_no_image(self, mock_isfile):
428         mock_isfile.return_value = False
429         assert_raises(ApexDeployException, prep_image,
430                       {}, {}, 'undercloud.qcow2', '/tmp')
431
432     def test_make_ssh_key(self):
433         priv, pub = make_ssh_key()
434         assert_in('-----BEGIN PRIVATE KEY-----', priv)
435         assert_in('ssh-rsa', pub)
436
437     @patch('apex.overcloud.deploy.yaml')
438     @patch('apex.overcloud.deploy.fileinput')
439     @patch('apex.overcloud.deploy.shutil')
440     @patch('builtins.open', mock_open())
441     def test_prep_env(self, mock_shutil, mock_fileinput, mock_yaml):
442         mock_fileinput.input.return_value = \
443             ['CloudDomain', 'replace_private_key', 'replace_public_key',
444              'opendaylight::vpp_routing_node', 'ControllerExtraConfig',
445              'NovaComputeExtraConfig', 'ComputeKernelArgs', 'HostCpusList',
446              'ComputeExtraConfigPre', 'resource_registry',
447              'NovaSchedulerDefaultFilters']
448         mock_yaml.safe_load.return_value = {
449             'parameter_defaults': {
450                 'ControllerServices': [1, 2, 3],
451                 'ComputeServices': [3, 4, 5]
452             }}
453         ds = {'global_params': {'ha_enabled': False},
454               'deploy_options':
455               {'sdn_controller': 'opendaylight',
456                'odl_vpp_routing_node': 'test',
457                'dataplane': 'ovs_dpdk',
458                'sriov': 'xxx',
459                'performance': {'Compute': {'vpp': {'main-core': 'test',
460                                                    'corelist-workers': 'test'},
461                                            'ovs': {'dpdk_cores': 'test'},
462                                            'kernel': {'test': 'test'}},
463                                'Controller': {'vpp': 'test'}}}}
464         ns_dict = {'domain_name': 'test.domain',
465                    'networks':
466                    {'tenant':
467                     {'nic_mapping': {'controller':
468                                      {'members': ['tenant_nic']},
469                                      'compute':
470                                      {'members': ['tenant_nic']}}},
471                     'external':
472                     [{'nic_mapping': {'controller':
473                                       {'members': ['ext_nic']},
474                                       'compute':
475                                       {'members': ['ext_nic']}}}]}}
476         inv = MagicMock()
477         inv.get_node_counts.return_value = (1, 0)
478         try:
479             # Swap stdout
480             saved_stdout = sys.stdout
481             out = StringIO()
482             sys.stdout = out
483             ns = MagicMock()
484             ns.enabled_network_list = ['external', 'tenant']
485             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
486             # run test
487             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
488             output = out.getvalue().strip()
489             assert_in('CloudDomain: test.domain', output)
490             assert_in('ssh-rsa', output)
491             assert_in('ComputeKernelArgs: \'test=test \'', output)
492             assert_in('fdio::vpp_cpu_main_core: \'test\'', output)
493             mock_yaml.safe_dump.assert_called_with(
494                 {'parameter_defaults': {
495                     'ControllerServices': [1, 2, 3, 4, 5],
496                 }},
497                 mock.ANY, default_flow_style=False
498             )
499         finally:
500             # put stdout back
501             sys.stdout = saved_stdout
502
503     @patch('apex.overcloud.deploy.fileinput')
504     @patch('apex.overcloud.deploy.shutil')
505     @patch('builtins.open', mock_open())
506     def test_prep_env_round_two(self, mock_shutil, mock_fileinput):
507         mock_fileinput.input.return_value = \
508             ['NeutronVPPAgentPhysnets']
509         ds = {'global_params': {'ha_enabled': False},
510               'deploy_options':
511               {'sdn_controller': False,
512                'dataplane': 'fdio',
513                'sriov': 'xxx',
514                'performance': {'Compute': {},
515                                'Controller': {}}}}
516         ns_dict = {'domain_name': 'test.domain',
517                    'networks':
518                    {'tenant':
519                     {'nic_mapping': {'controller':
520                                      {'members': ['tenant_nic']},
521                                      'compute':
522                                      {'members': ['tenant_nic']}}},
523                     'external':
524                     [{'nic_mapping': {'controller':
525                                       {'members': ['ext_nic']},
526                                       'compute':
527                                       {'members': ['ext_nic']}}}]}}
528         inv = MagicMock()
529         inv.get_node_counts.return_value = (3, 2)
530         try:
531             # Swap stdout
532             saved_stdout = sys.stdout
533             out = StringIO()
534             sys.stdout = out
535             ns = MagicMock()
536             ns.enabled_network_list = ['external', 'tenant']
537             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
538             # run test
539             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
540             output = out.getvalue().strip()
541             assert_in('NeutronVPPAgentPhysnets: '
542                       '\'datacentre:tenant_nic,external:tap0\'',
543                       output)
544             assert_in('NeutronVPPAgentPhysnets', output)
545         finally:
546             # put stdout back
547             sys.stdout = saved_stdout
548
549     @patch('apex.overcloud.deploy.fileinput')
550     @patch('apex.overcloud.deploy.shutil')
551     @patch('builtins.open', mock_open())
552     def test_prep_env_round_three(self, mock_shutil, mock_fileinput):
553         mock_fileinput.input.return_value = \
554             ['OS::TripleO::Services::NeutronDhcpAgent',
555              'NeutronDhcpAgentsPerNetwork', 'ComputeServices']
556         ds = {'global_params': {'ha_enabled': False},
557               'deploy_options':
558               {'sdn_controller': 'opendaylight',
559                'dataplane': 'fdio',
560                'sriov': 'xxx',
561                'dvr': True}}
562         ns_dict = {'domain_name': 'test.domain',
563                    'networks':
564                    {'tenant':
565                     {'nic_mapping': {'controller':
566                                      {'members': ['tenant_nic']},
567                                      'compute':
568                                      {'members': ['tenant_nic']}}},
569                     'external':
570                     [{'nic_mapping': {'controller':
571                                       {'members': ['ext_nic']},
572                                       'compute':
573                                       {'members': ['ext_nic']}}}]}}
574         inv = MagicMock()
575         inv.get_node_counts.return_value = (3, 2)
576         try:
577             # Swap stdout
578             saved_stdout = sys.stdout
579             out = StringIO()
580             sys.stdout = out
581             ns = MagicMock()
582             ns.enabled_network_list = ['external', 'tenant']
583             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
584             # run test
585             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
586             output = out.getvalue().strip()
587             assert_in('NeutronDhcpAgentsPerNetwork: 2', output)
588         finally:
589             # put stdout back
590             sys.stdout = saved_stdout
591
592     @patch('apex.overcloud.deploy.fileinput')
593     @patch('apex.overcloud.deploy.shutil')
594     @patch('builtins.open', mock_open())
595     def test_prep_env_tenant_vlan(self, mock_shutil, mock_fileinput):
596         mock_fileinput.input.return_value = \
597             ['NeutronNetworkVLANRanges',
598              'NeutronNetworkType', 'NeutronBridgeMappings']
599         ds = {'global_params': {'ha_enabled': False},
600               'deploy_options':
601               {'sdn_controller': False,
602                'dataplane': 'ovs',
603                'sriov': 'xxx',
604                'dvr': True}}
605         ns_dict = {'domain_name': 'test.domain',
606                    'networks':
607                    {'tenant':
608                     {'nic_mapping': {'controller':
609                                      {'members': ['tenant_nic']},
610                                      'compute':
611                                      {'members': ['tenant_nic']}},
612                      'segmentation_type': 'vlan',
613                      'overlay_id_range': 'vlan:500:600'
614                      },
615                     'external':
616                     [{'nic_mapping': {'controller':
617                                       {'members': ['ext_nic']},
618                                       'compute':
619                                       {'members': ['ext_nic']}}}]}}
620         inv = MagicMock()
621         inv.get_node_counts.return_value = (3, 2)
622         try:
623             # Swap stdout
624             saved_stdout = sys.stdout
625             out = StringIO()
626             sys.stdout = out
627             ns = MagicMock()
628             ns.enabled_network_list = ['external', 'tenant']
629             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
630             # run test
631             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
632             output = out.getvalue().strip()
633             assert_in('NeutronNetworkVLANRanges: '
634                       'vlan:500:600,datacentre:1:1000', output)
635             assert_in('NeutronNetworkType: vlan', output)
636             assert_in('NeutronBridgeMappings: '
637                       'vlan:br-vlan,datacentre:br-ex', output)
638             assert_not_in('OpenDaylightProviderMappings', output)
639         finally:
640             # put stdout back
641             sys.stdout = saved_stdout
642
643     @patch('apex.overcloud.deploy.fileinput')
644     @patch('apex.overcloud.deploy.shutil')
645     @patch('builtins.open', mock_open())
646     def test_prep_env_tenant_vlan_odl(self, mock_shutil, mock_fileinput):
647         mock_fileinput.input.return_value = \
648             ['NeutronNetworkVLANRanges',
649              'NeutronNetworkType',
650              'NeutronBridgeMappings',
651              'OpenDaylightProviderMappings']
652         ds = {'global_params': {'ha_enabled': False},
653               'deploy_options':
654               {'sdn_controller': 'opendaylight',
655                'dataplane': 'ovs',
656                'sriov': 'xxx',
657                'dvr': True}}
658         ns_dict = {'domain_name': 'test.domain',
659                    'networks':
660                    {'tenant':
661                     {'nic_mapping': {'controller':
662                                      {'members': ['tenant_nic']},
663                                      'compute':
664                                      {'members': ['tenant_nic']}},
665                      'segmentation_type': 'vlan',
666                      'overlay_id_range': 'vlan:500:600'
667                      },
668                     'external':
669                     [{'nic_mapping': {'controller':
670                                       {'members': ['ext_nic']},
671                                       'compute':
672                                       {'members': ['ext_nic']}}}]}}
673         inv = MagicMock()
674         inv.get_node_counts.return_value = (3, 2)
675         try:
676             # Swap stdout
677             saved_stdout = sys.stdout
678             out = StringIO()
679             sys.stdout = out
680             ns = MagicMock()
681             ns.enabled_network_list = ['external', 'tenant']
682             ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
683             # run test
684             prep_env(ds, ns, inv, 'opnfv-env.yml', '/net-env.yml', '/tmp')
685             output = out.getvalue().strip()
686             assert_in('NeutronNetworkVLANRanges: '
687                       'vlan:500:600,datacentre:1:1000', output)
688             assert_in('NeutronNetworkType: vlan', output)
689             assert_in('NeutronBridgeMappings: '
690                       'vlan:br-vlan,datacentre:br-ex', output)
691             assert_in('OpenDaylightProviderMappings: '
692                       'vlan:br-vlan,datacentre:br-ex', output)
693         finally:
694             # put stdout back
695             sys.stdout = saved_stdout
696
697     def test_generate_ceph_key(self):
698         assert_equal(len(generate_ceph_key()), 40)
699
700     @patch('apex.overcloud.deploy.generate_ceph_key')
701     @patch('apex.overcloud.deploy.fileinput')
702     @patch('apex.overcloud.deploy.os.path.isfile')
703     @patch('builtins.open', mock_open())
704     def test_prep_storage_env(self, mock_isfile, mock_fileinput,
705                               mock_ceph_key):
706         mock_fileinput.input.return_value = \
707             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
708         ds = {'deploy_options': {
709             'ceph_device': '/dev/sdx',
710             'containers': False
711         }}
712         ns = {}
713         prep_storage_env(ds, ns, virtual=False, tmp_dir='/tmp')
714
715     @patch('apex.overcloud.deploy.utils.edit_tht_env')
716     @patch('apex.overcloud.deploy.generate_ceph_key')
717     @patch('apex.overcloud.deploy.fileinput')
718     @patch('apex.overcloud.deploy.os.path.isfile')
719     @patch('builtins.open', mock_open())
720     def test_prep_storage_env_containers(self, mock_isfile, mock_fileinput,
721                                          mock_ceph_key, mock_edit_tht):
722         mock_fileinput.input.return_value = \
723             ['CephClusterFSID', 'CephMonKey', 'CephAdminKey', 'random_key']
724         ds = {'deploy_options': {
725               'ceph_device': '/dev/sdx',
726               'containers': True,
727               'os_version': 'master'
728               }, 'global_params': {'ha_enabled': False}}
729         ns = {'networks': {con.ADMIN_NETWORK: {'installer_vm':
730                                                {'ip': '192.0.2.1'}}}
731               }
732         prep_storage_env(ds, ns, virtual=True, tmp_dir='/tmp')
733         ceph_params = {
734             'CephPoolDefaultSize': 2,
735             'CephAnsibleExtraConfig': {
736                 'centos_package_dependencies': [],
737                 'ceph_osd_docker_memory_limit': '1g',
738                 'ceph_mds_docker_memory_limit': '1g'
739             },
740             'CephPoolDefaultPgNum': 32,
741             'CephAnsibleDisksConfig': {
742                 'devices': ['/dev/sdx'],
743                 'journal_size': 512,
744                 'osd_scenario': 'collocated'
745             }
746         }
747         mock_edit_tht.assert_called_with('/tmp/storage-environment.yaml',
748                                          'parameter_defaults',
749                                          ceph_params)
750
751     @patch('apex.overcloud.deploy.os.path.isfile')
752     @patch('builtins.open', mock_open())
753     def test_prep_storage_env_raises(self, mock_isfile):
754         mock_isfile.return_value = False
755         ds = {'deploy_options': MagicMock()}
756         ns = {}
757         assert_raises(ApexDeployException, prep_storage_env, ds,
758                       ns, virtual=False, tmp_dir='/tmp')
759
760     @patch('apex.overcloud.deploy.generate_ceph_key')
761     @patch('apex.overcloud.deploy.fileinput')
762     @patch('apex.overcloud.deploy.os.path.isfile')
763     @patch('builtins.open', mock_open())
764     def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
765         ds = {'deploy_options':
766               {'sdn_controller': 'opendaylight',
767                'sriov': 'xxx'}}
768         try:
769             # Swap stdout
770             saved_stdout = sys.stdout
771             out = StringIO()
772             sys.stdout = out
773             # Run tests
774             mock_fileinput.input.return_value = \
775                 ['#  NovaSchedulerDefaultFilters',
776                  '#  NovaSchedulerAvailableFilters',
777                  '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
778                  '#NeutronSriovNumVFs: \"ens20f2:5\"',
779                  '#NovaPCIPassthrough:',
780                  '#  - devname: \"ens20f2\"',
781                  '#    physical_network: \"datacentre\"']
782             prep_sriov_env(ds, '/tmp')
783             output = out.getvalue().strip()
784             assert_in('NovaSchedulerDefaultFilters', output)
785             assert_in('NovaSchedulerAvailableFilters', output)
786             assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
787             assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
788             assert_in('NovaPCIPassthrough:', output)
789             assert_in('- devname: \"xxx\"', output)
790             assert_in('physical_network: \"nfv_sriov\"', output)
791         finally:
792             # put stdout back
793             sys.stdout = saved_stdout
794
795     @patch('apex.overcloud.deploy.os.path.isfile')
796     @patch('builtins.open', mock_open())
797     def test_prep_sriov_env_raises(self, mock_isfile):
798         ds_opts = {'sriov': True}
799         ds = {'deploy_options': MagicMock()}
800         ds['deploy_options'].__getitem__.side_effect = \
801             lambda i: ds_opts.get(i, MagicMock())
802         mock_isfile.return_value = False
803         ds = {'deploy_options': MagicMock()}
804         assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
805
806     def test_external_network_cmds(self):
807         ds = {'deploy_options':
808               {'sdn_controller': 'opendaylight',
809                'dataplane': 'ovs'}}
810
811         cidr = MagicMock()
812         cidr.version = 6
813         ns_dict = {'networks':
814                    {'external': [{'floating_ip_range': (0, 1),
815                                   'nic_mapping':
816                                   {'compute': {'vlan': 'native'}},
817                                   'gateway': 'gw',
818                                   'cidr': cidr}]}}
819         ns = MagicMock()
820         ns.enabled_network_list = ['external']
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('--gateway gw', cmds)
826         assert_in('--network external', cmds)
827         assert_in('--provider-physical-network datacentre', cmds)
828
829     def test_external_network_cmds_nosdn_fdio(self):
830         ds = {'deploy_options':
831               {'sdn_controller': False,
832                'dataplane': 'fdio'}}
833
834         cidr = MagicMock()
835         cidr.version = 6
836         ns_dict = {'networks':
837                    {'external': [{'floating_ip_range': (0, 1),
838                                   'nic_mapping':
839                                   {'compute': {'vlan': 'native'}},
840                                   'gateway': 'gw',
841                                   'cidr': cidr}]}}
842         ns = MagicMock()
843         ns.enabled_network_list = ['external']
844         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
845         cmds = ' '.join(external_network_cmds(ns, ds))
846         assert_in('--external', cmds)
847         assert_in('--allocation-pool start=0,end=1', cmds)
848         assert_in('--gateway gw', cmds)
849         assert_in('--network external', cmds)
850         assert_in('--provider-physical-network external', cmds)
851
852     def test_external_network_cmds_no_ext(self):
853         ds = {'deploy_options':
854               {'sdn_controller': 'opendaylight',
855                'dataplane': 'ovs'}}
856
857         cidr = MagicMock()
858         cidr.version = 6
859         ns_dict = {'apex':
860                    {'networks':
861                     {'admin':
862                      {'introspection_range': (0, 1),
863                       'nic_mapping':
864                       {'compute': {'vlan': '123'}},
865                       'gateway': 'gw',
866                       'cidr': cidr}}}}
867         ns = MagicMock()
868         ns.enabled_network_list = ['admin']
869         ns.__getitem__.side_effect = lambda i: ns_dict.get(i, MagicMock())
870         cmds = ' '.join(external_network_cmds(ns, ds))
871         assert_in('--external', cmds)
872         assert_in('--allocation-pool start=0,end=1', cmds)
873         assert_in('--network external', cmds)
874         assert_in('--provider-network-type vlan', cmds)
875
876     @patch('apex.overcloud.deploy.parsers')
877     def test_create_congress_cmds(self, mock_parsers):
878         assert_greater(len(create_congress_cmds('overcloud_file')), 0)
879
880     @patch('apex.overcloud.deploy.parsers.parse_overcloudrc')
881     def test_create_congress_cmds_raises(self, mock_parsers):
882         mock_parsers.return_value.__getitem__.side_effect = KeyError()
883         assert_raises(KeyError, create_congress_cmds, 'overcloud_file')
884
885     def test_get_docker_sdn_files(self):
886         ds_opts = {'ha_enabled': True,
887                    'congress': True,
888                    'tacker': True,
889                    'containers': False,
890                    'barometer': True,
891                    'ceph': False,
892                    'vpn': True,
893                    'sdn_controller': 'opendaylight',
894                    'os_version': 'queens'
895                    }
896         output = get_docker_sdn_files(ds_opts)
897         compare = ['/usr/share/openstack-tripleo-heat-templates/'
898                    'environments/services/neutron-opendaylight.yaml',
899                    '/usr/share/openstack-tripleo-heat-templates/environments'
900                    '/services/neutron-bgpvpn-opendaylight.yaml']
901         self.assertEqual(output, compare)