c821ade51dadb12d13b9e31f19e82d0083946adc
[apex.git] / apex / tests / test_apex_undercloud.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 libvirt
11 import os
12 import subprocess
13 import unittest
14
15 from mock import patch
16 from mock import MagicMock
17
18 from apex.common import constants
19 from apex.undercloud.undercloud import Undercloud
20 from apex.undercloud.undercloud import ApexUndercloudException
21
22 from nose.tools import (
23     assert_regexp_matches,
24     assert_raises,
25     assert_true,
26     assert_equal)
27
28
29 class TestUndercloud(unittest.TestCase):
30     @classmethod
31     def setup_class(cls):
32         """This method is run once for each class before any tests are run"""
33
34     @classmethod
35     def teardown_class(cls):
36         """This method is run once for each class _after_ all tests are run"""
37
38     def setup(self):
39         """This method is run once before _each_ test method is executed"""
40
41     def teardown(self):
42         """This method is run once after _each_ test method is executed"""
43
44     @patch.object(Undercloud, '_get_vm', return_value=None)
45     @patch.object(Undercloud, 'create')
46     def test_init(self, mock_get_vm, mock_create):
47         Undercloud('img_path', 'tplt_path')
48         mock_create.assert_called()
49
50     @patch.object(Undercloud, '_get_vm', return_value=object())
51     @patch.object(Undercloud, 'create')
52     def test_init_uc_exists(self, mock_get_vm, mock_create):
53         assert_raises(ApexUndercloudException,
54                       Undercloud, 'img_path', 'tplt_path')
55
56     @patch('apex.undercloud.undercloud.libvirt.open')
57     @patch.object(Undercloud, 'create')
58     def test_get_vm_exists(self, mock_create, mock_libvirt):
59         assert_raises(ApexUndercloudException,
60                       Undercloud, 'img_path', 'tplt_path')
61
62     @patch('apex.undercloud.undercloud.libvirt.open')
63     @patch.object(Undercloud, 'create')
64     def test_get_vm_not_exists(self, mock_create, mock_libvirt):
65         conn = mock_libvirt.return_value
66         conn.lookupByName.side_effect = libvirt.libvirtError('defmsg')
67         Undercloud('img_path', 'tplt_path')
68
69     @patch('apex.undercloud.undercloud.vm_lib')
70     @patch.object(Undercloud, 'inject_auth', return_value=None)
71     @patch.object(Undercloud, 'setup_volumes', return_value=None)
72     @patch.object(Undercloud, '_get_vm', return_value=None)
73     def test_create(self, mock_get_vm, mock_setup_vols,
74                     mock_inject_auth, mock_vm_lib):
75         Undercloud('img_path', 'tplt_path', external_network=True)
76         mock_inject_auth.assert_called()
77         mock_setup_vols.assert_called()
78         mock_inject_auth.assert_called()
79
80     @patch.object(Undercloud, '_get_vm', return_value=None)
81     @patch.object(Undercloud, 'create')
82     def test_set_ip(self, mock_get_vm, mock_create):
83         uc = Undercloud('img_path', 'tplt_path', external_network=True)
84         uc.vm = MagicMock()
85         if_addrs = {'item1': {'addrs': [{'type': libvirt.VIR_IP_ADDR_TYPE_IPV4,
86                                          'addr': 'ipaddress'}]},
87                     'item2': {'addrs': [{'type': libvirt.VIR_IP_ADDR_TYPE_IPV4,
88                                          'addr': 'ipaddress'}]}}
89         uc.vm.interfaceAddresses.return_value = if_addrs
90         assert_true(uc._set_ip())
91
92     @patch('apex.undercloud.undercloud.time.sleep')
93     @patch.object(Undercloud, '_set_ip', return_value=False)
94     @patch.object(Undercloud, '_get_vm', return_value=None)
95     @patch.object(Undercloud, 'create')
96     def test_start(self, mock_create, mock_get_vm,
97                    mock_set_ip, mock_time):
98         uc = Undercloud('img_path', 'tplt_path', external_network=True)
99         uc.vm = MagicMock()
100         uc.vm.isActive.return_value = False
101         mock_set_ip.return_value = True
102         uc.start()
103
104     @patch('apex.undercloud.undercloud.time.sleep')
105     @patch.object(Undercloud, '_set_ip', return_value=False)
106     @patch.object(Undercloud, '_get_vm', return_value=None)
107     @patch.object(Undercloud, 'create')
108     def test_start_no_ip(self, mock_create, mock_get_vm,
109                          mock_set_ip, mock_time):
110         uc = Undercloud('img_path', 'tplt_path', external_network=True)
111         uc.vm = MagicMock()
112         uc.vm.isActive.return_value = True
113         mock_set_ip.return_value = False
114         assert_raises(ApexUndercloudException, uc.start)
115
116     @patch('apex.undercloud.undercloud.utils')
117     @patch.object(Undercloud, 'generate_config', return_value={})
118     @patch.object(Undercloud, '_get_vm', return_value=None)
119     @patch.object(Undercloud, 'create')
120     def test_configure(self, mock_create, mock_get_vm,
121                        mock_generate_config, mock_utils):
122         uc = Undercloud('img_path', 'tplt_path', external_network=True)
123         ns = MagicMock()
124         ds = MagicMock()
125         uc.configure(ns, ds, 'playbook', '/tmp/dir')
126
127     @patch('apex.undercloud.undercloud.utils')
128     @patch.object(Undercloud, 'generate_config', return_value={})
129     @patch.object(Undercloud, '_get_vm', return_value=None)
130     @patch.object(Undercloud, 'create')
131     def test_configure_raises(self, mock_create, mock_get_vm,
132                               mock_generate_config, mock_utils):
133         uc = Undercloud('img_path', 'tplt_path', external_network=True)
134         ns = MagicMock()
135         ds = MagicMock()
136         subps_err = subprocess.CalledProcessError(1, 'cmd')
137         mock_utils.run_ansible.side_effect = subps_err
138         assert_raises(ApexUndercloudException,
139                       uc.configure, ns, ds, 'playbook', '/tmp/dir')
140
141     @patch('apex.undercloud.undercloud.os.remove')
142     @patch('apex.undercloud.undercloud.os.path')
143     @patch('apex.undercloud.undercloud.shutil')
144     @patch.object(Undercloud, '_get_vm', return_value=None)
145     @patch.object(Undercloud, 'create')
146     def test_setup_vols(self, mock_get_vm, mock_create,
147                         mock_shutil, mock_os_path, mock_os_remove):
148         uc = Undercloud('img_path', 'tplt_path', external_network=True)
149         mock_os_path.isfile.return_value = True
150         mock_os_path.exists.return_value = True
151         uc.setup_volumes()
152         for img_file in ('overcloud-full.vmlinuz', 'overcloud-full.initrd',
153                          'undercloud.qcow2'):
154             src_img = os.path.join(uc.image_path, img_file)
155             dest_img = os.path.join(constants.LIBVIRT_VOLUME_PATH, img_file)
156             mock_shutil.copyfile.assert_called_with(src_img, dest_img)
157
158     @patch('apex.undercloud.undercloud.os.path')
159     @patch.object(Undercloud, '_get_vm', return_value=None)
160     @patch.object(Undercloud, 'create')
161     def test_setup_vols_raises(self, mock_get_vm, mock_create, mock_os_path):
162         uc = Undercloud('img_path', 'tplt_path', external_network=True)
163         mock_os_path.isfile.return_value = False
164         assert_raises(ApexUndercloudException, uc.setup_volumes)
165
166     @patch('apex.undercloud.undercloud.virt_utils')
167     @patch.object(Undercloud, '_get_vm', return_value=None)
168     @patch.object(Undercloud, 'create')
169     def test_inject_auth(self, mock_get_vm, mock_create, mock_vutils):
170         uc = Undercloud('img_path', 'tplt_path', external_network=True)
171         uc.root_pw = 'test'
172         uc.inject_auth()
173         test_ops = [{'--root-password': 'password:test'},
174                     {'--run-command': 'mkdir -p /root/.ssh'},
175                     {'--upload':
176                      '/root/.ssh/id_rsa.pub:/root/.ssh/authorized_keys'},
177                     {'--run-command': 'chmod 600 /root/.ssh/authorized_keys'},
178                     {'--run-command': 'restorecon /root/.ssh/authorized_keys'},
179                     {'--run-command':
180                      'cp /root/.ssh/authorized_keys /home/stack/.ssh/'},
181                     {'--run-command':
182                      'chown stack:stack /home/stack/.ssh/authorized_keys'},
183                     {'--run-command':
184                      'chmod 600 /home/stack/.ssh/authorized_keys'}]
185         mock_vutils.virt_customize.assert_called_with(test_ops, uc.volume)
186
187     @patch.object(Undercloud, '_get_vm', return_value=None)
188     @patch.object(Undercloud, 'create')
189     def test_generate_config(self, mock_get_vm, mock_create):
190         ns_net = MagicMock()
191         ns_net.__getitem__.side_effect = \
192             lambda i: '1234/24' if i is 'cidr' else MagicMock()
193         ns = {'apex': MagicMock(),
194               'dns-domain': 'dns',
195               'networks': {'admin': ns_net,
196                            'external': [ns_net]}}
197         ds = {'global_params': {}}
198
199         Undercloud('img_path', 'tplt_path').generate_config(ns, ds)