1 ##############################################################################
2 # Copyright (c) 2016 Dan Radez (dradez@redhat.com) (Red Hat)
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 ##############################################################################
17 from mock import patch
18 from mock import MagicMock
20 from apex.common import constants
21 from apex.undercloud.undercloud import Undercloud
22 from apex.undercloud.undercloud import ApexUndercloudException
24 from nose.tools import (
25 assert_regexp_matches,
32 class TestUndercloud(unittest.TestCase):
35 """This method is run once for each class before any tests are run"""
38 def teardown_class(cls):
39 """This method is run once for each class _after_ all tests are run"""
42 """This method is run once before _each_ test method is executed"""
45 """This method is run once after _each_ test method is executed"""
47 @patch.object(Undercloud, '_get_vm', return_value=None)
48 @patch.object(Undercloud, 'create')
49 def test_init(self, mock_get_vm, mock_create):
50 Undercloud('img_path', 'tplt_path')
51 mock_create.assert_called()
53 @patch.object(Undercloud, '_get_vm', return_value=object())
54 @patch.object(Undercloud, 'create')
55 def test_init_uc_exists(self, mock_get_vm, mock_create):
56 assert_raises(ApexUndercloudException,
57 Undercloud, 'img_path', 'tplt_path')
59 @patch('apex.undercloud.undercloud.libvirt.open')
60 @patch.object(Undercloud, 'create')
61 def test_get_vm_exists(self, mock_create, mock_libvirt):
62 assert_raises(ApexUndercloudException,
63 Undercloud, 'img_path', 'tplt_path')
65 @patch('apex.undercloud.undercloud.libvirt.open')
66 @patch.object(Undercloud, 'create')
67 def test_get_vm_not_exists(self, mock_create, mock_libvirt):
68 conn = mock_libvirt.return_value
69 conn.lookupByName.side_effect = libvirt.libvirtError('defmsg')
70 Undercloud('img_path', 'tplt_path')
72 @patch('apex.undercloud.undercloud.vm_lib')
73 @patch.object(Undercloud, 'inject_auth', return_value=None)
74 @patch.object(Undercloud, 'setup_volumes', return_value=None)
75 @patch.object(Undercloud, '_get_vm', return_value=None)
76 def test_create(self, mock_get_vm, mock_setup_vols,
77 mock_inject_auth, mock_vm_lib):
78 Undercloud('img_path', 'tplt_path', external_network=True)
79 mock_inject_auth.assert_called()
80 mock_setup_vols.assert_called()
81 mock_inject_auth.assert_called()
83 @patch.object(Undercloud, '_get_vm', return_value=None)
84 @patch.object(Undercloud, 'create')
85 def test_set_ip(self, mock_get_vm, mock_create):
86 uc = Undercloud('img_path', 'tplt_path', external_network=True)
88 if_addrs = {'item1': {'addrs': [{'type': libvirt.VIR_IP_ADDR_TYPE_IPV4,
89 'addr': 'ipaddress'}]},
90 'item2': {'addrs': [{'type': libvirt.VIR_IP_ADDR_TYPE_IPV4,
91 'addr': 'ipaddress'}]}}
92 uc.vm.interfaceAddresses.return_value = if_addrs
93 assert_true(uc._set_ip())
95 @patch('apex.undercloud.undercloud.time.sleep')
96 @patch.object(Undercloud, '_set_ip', return_value=False)
97 @patch.object(Undercloud, '_get_vm', return_value=None)
98 @patch.object(Undercloud, 'create')
99 def test_start(self, mock_create, mock_get_vm,
100 mock_set_ip, mock_time):
101 uc = Undercloud('img_path', 'tplt_path', external_network=True)
103 uc.vm.isActive.return_value = False
104 mock_set_ip.return_value = True
107 @patch('apex.undercloud.undercloud.time.sleep')
108 @patch.object(Undercloud, '_set_ip', return_value=False)
109 @patch.object(Undercloud, '_get_vm', return_value=None)
110 @patch.object(Undercloud, 'create')
111 def test_start_no_ip(self, mock_create, mock_get_vm,
112 mock_set_ip, mock_time):
113 uc = Undercloud('img_path', 'tplt_path', external_network=True)
115 uc.vm.isActive.return_value = True
116 mock_set_ip.return_value = False
117 assert_raises(ApexUndercloudException, uc.start)
119 @patch('apex.undercloud.undercloud.utils')
120 @patch.object(Undercloud, 'generate_config', return_value={})
121 @patch.object(Undercloud, '_get_vm', return_value=None)
122 @patch.object(Undercloud, 'create')
123 def test_detect_nat_with_external(self, mock_create, mock_get_vm,
124 mock_generate_config, mock_utils):
126 ns.enabled_network_list = ['admin', 'external']
130 'networks': {'admin':
131 {'cidr': ipaddress.ip_network('192.0.2.0/24'),
132 'installer_vm': {'ip': '192.0.2.1',
134 'dhcp_range': ['192.0.2.15', '192.0.2.30'],
135 'gateway': '192.1.1.1',
139 'cidr': ipaddress.ip_network('192.168.0.0/24'),
140 'installer_vm': {'ip': '192.168.0.1',
142 'gateway': '192.168.0.1'
146 ns.__getitem__.side_effect = ns_dict.__getitem__
147 ns.__contains__.side_effect = ns_dict.__contains__
149 uc = Undercloud('img_path', 'tplt_path', external_network=True)
150 assert_true(uc.detect_nat(ns))
152 @patch('apex.undercloud.undercloud.utils')
153 @patch.object(Undercloud, 'generate_config', return_value={})
154 @patch.object(Undercloud, '_get_vm', return_value=None)
155 @patch.object(Undercloud, 'create')
156 def test_detect_nat_no_external(self, mock_create, mock_get_vm,
157 mock_generate_config, mock_utils):
159 ns.enabled_network_list = ['admin', 'external']
163 'networks': {'admin':
164 {'cidr': ipaddress.ip_network('192.0.2.0/24'),
165 'installer_vm': {'ip': '192.0.2.1',
167 'dhcp_range': ['192.0.2.15', '192.0.2.30'],
168 'gateway': '192.0.2.1',
172 'cidr': ipaddress.ip_network('192.168.0.0/24'),
173 'installer_vm': {'ip': '192.168.0.1',
175 'gateway': '192.168.1.1'
179 ns.__getitem__.side_effect = ns_dict.__getitem__
180 ns.__contains__.side_effect = ns_dict.__contains__
182 uc = Undercloud('img_path', 'tplt_path', external_network=False)
183 assert_true(uc.detect_nat(ns))
185 @patch('apex.undercloud.undercloud.utils')
186 @patch.object(Undercloud, 'generate_config', return_value={})
187 @patch.object(Undercloud, '_get_vm', return_value=None)
188 @patch.object(Undercloud, 'create')
189 def test_detect_no_nat_no_external(self, mock_create, mock_get_vm,
190 mock_generate_config, mock_utils):
192 ns.enabled_network_list = ['admin', 'external']
196 'networks': {'admin':
197 {'cidr': ipaddress.ip_network('192.0.2.0/24'),
198 'installer_vm': {'ip': '192.0.2.1',
200 'dhcp_range': ['192.0.2.15', '192.0.2.30'],
201 'gateway': '192.0.2.3',
205 'cidr': ipaddress.ip_network('192.168.0.0/24'),
206 'installer_vm': {'ip': '192.168.0.1',
208 'gateway': '192.168.1.1'
212 ns.__getitem__.side_effect = ns_dict.__getitem__
213 ns.__contains__.side_effect = ns_dict.__contains__
215 uc = Undercloud('img_path', 'tplt_path', external_network=False)
216 assert_false(uc.detect_nat(ns))
218 @patch('apex.undercloud.undercloud.utils')
219 @patch.object(Undercloud, 'generate_config', return_value={})
220 @patch.object(Undercloud, '_get_vm', return_value=None)
221 @patch.object(Undercloud, 'create')
222 def test_configure(self, mock_create, mock_get_vm,
223 mock_generate_config, mock_utils):
224 uc = Undercloud('img_path', 'tplt_path', external_network=True)
227 uc.configure(ns, ds, 'playbook', '/tmp/dir')
229 @patch('apex.undercloud.undercloud.utils')
230 @patch.object(Undercloud, 'generate_config', return_value={})
231 @patch.object(Undercloud, '_get_vm', return_value=None)
232 @patch.object(Undercloud, 'create')
233 def test_configure_raises(self, mock_create, mock_get_vm,
234 mock_generate_config, mock_utils):
235 uc = Undercloud('img_path', 'tplt_path', external_network=True)
238 subps_err = subprocess.CalledProcessError(1, 'cmd')
239 mock_utils.run_ansible.side_effect = subps_err
240 assert_raises(ApexUndercloudException,
241 uc.configure, ns, ds, 'playbook', '/tmp/dir')
243 @patch('apex.undercloud.undercloud.virt_utils')
244 @patch('apex.undercloud.undercloud.uc_builder')
245 @patch('apex.undercloud.undercloud.os.remove')
246 @patch('apex.undercloud.undercloud.os.path')
247 @patch('apex.undercloud.undercloud.shutil')
248 @patch.object(Undercloud, '_get_vm', return_value=None)
249 @patch.object(Undercloud, 'create')
250 def test_setup_vols(self, mock_get_vm, mock_create,
251 mock_shutil, mock_os_path, mock_os_remove,
252 mock_uc_builder, mock_virt_utils):
253 uc = Undercloud('img_path', 'tplt_path', external_network=True)
254 mock_os_path.isfile.return_value = True
255 mock_os_path.exists.return_value = True
257 for img_file in ('overcloud-full.vmlinuz', 'overcloud-full.initrd',
259 src_img = os.path.join(uc.image_path, img_file)
260 dest_img = os.path.join(constants.LIBVIRT_VOLUME_PATH, img_file)
261 mock_shutil.copyfile.assert_called_with(src_img, dest_img)
262 if platform.machine() != 'aarch64':
263 mock_uc_builder.expand_disk.assert_called()
264 mock_virt_utils.virt_customize.assert_called()
266 @patch('apex.undercloud.undercloud.os.path')
267 @patch.object(Undercloud, '_get_vm', return_value=None)
268 @patch.object(Undercloud, 'create')
269 def test_setup_vols_raises(self, mock_get_vm, mock_create, mock_os_path):
270 uc = Undercloud('img_path', 'tplt_path', external_network=True)
271 mock_os_path.isfile.return_value = False
272 assert_raises(ApexUndercloudException, uc.setup_volumes)
274 @patch('apex.undercloud.undercloud.virt_utils')
275 @patch.object(Undercloud, '_get_vm', return_value=None)
276 @patch.object(Undercloud, 'create')
277 def test_inject_auth(self, mock_get_vm, mock_create, mock_vutils):
278 uc = Undercloud('img_path', 'tplt_path', external_network=True)
281 test_ops = [{'--root-password': 'password:test'},
282 {'--run-command': 'mkdir -p /root/.ssh'},
284 '/root/.ssh/id_rsa.pub:/root/.ssh/authorized_keys'},
285 {'--run-command': 'chmod 600 /root/.ssh/authorized_keys'},
286 {'--run-command': 'restorecon '
288 {'--run-command': 'id -u stack || useradd -m stack'},
289 {'--run-command': 'mkdir -p /home/stack/.ssh'},
290 {'--run-command': 'chown stack:stack /home/stack/.ssh'},
292 'cp /root/.ssh/authorized_keys /home/stack/.ssh/'},
294 'chown stack:stack /home/stack/.ssh/authorized_keys'},
296 'chmod 600 /home/stack/.ssh/authorized_keys'},
298 'echo "stack ALL = (ALL) NOPASSWD: ALL" >> '
300 {'--run-command': 'touch /etc/cloud/cloud-init.disabled'}]
301 mock_vutils.virt_customize.assert_called_with(test_ops, uc.volume)
303 @patch.object(Undercloud, '_get_vm', return_value=None)
304 @patch.object(Undercloud, 'create')
305 def test_generate_config(self, mock_get_vm, mock_create):
307 ns.enabled_network_list = ['admin', 'external']
311 'ntp': 'pool.ntp.org',
312 'networks': {'admin':
313 {'cidr': ipaddress.ip_network('192.0.2.0/24'),
314 'installer_vm': {'ip': '192.0.2.1',
316 'dhcp_range': ['192.0.2.15', '192.0.2.30']
320 'cidr': ipaddress.ip_network('192.168.0.0/24'),
321 'installer_vm': {'ip': '192.168.0.1',
326 ns.__getitem__.side_effect = ns_dict.__getitem__
327 ns.__contains__.side_effect = ns_dict.__contains__
328 ds = {'global_params': {},
329 'deploy_options': {}}
331 Undercloud('img_path', 'tplt_path').generate_config(ns, ds)
333 @patch.object(Undercloud, '_get_vm', return_value=None)
334 @patch.object(Undercloud, 'create')
335 @patch('apex.undercloud.undercloud.virt_utils')
336 def test_update_delorean(self, mock_vutils, mock_uc_create, mock_get_vm):
337 uc = Undercloud('img_path', 'tmplt_path', external_network=True)
338 uc._update_delorean_repo()
341 "/etc/yum.repos.d/deloran.repo "
342 "https://trunk.rdoproject.org/centos7-{}"
343 "/current-tripleo/delorean.repo".format(
344 constants.DEFAULT_OS_VERSION))
345 test_ops = [{'--run-command': download_cmd}]
346 mock_vutils.virt_customize.assert_called_with(test_ops, uc.volume)