Adding unittests for undercloud.py
[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         uc.configure(ns, 'playbook', '/tmp/dir')
125
126     @patch('apex.undercloud.undercloud.utils')
127     @patch.object(Undercloud, 'generate_config', return_value={})
128     @patch.object(Undercloud, '_get_vm', return_value=None)
129     @patch.object(Undercloud, 'create')
130     def test_configure_raises(self, mock_create, mock_get_vm,
131                               mock_generate_config, mock_utils):
132         uc = Undercloud('img_path', 'tplt_path', external_network=True)
133         ns = MagicMock()
134         subps_err = subprocess.CalledProcessError(1, 'cmd')
135         mock_utils.run_ansible.side_effect = subps_err
136         assert_raises(ApexUndercloudException,
137                       uc.configure, ns, 'playbook', '/tmp/dir')
138
139     @patch('apex.undercloud.undercloud.os.remove')
140     @patch('apex.undercloud.undercloud.os.path')
141     @patch('apex.undercloud.undercloud.shutil')
142     @patch.object(Undercloud, '_get_vm', return_value=None)
143     @patch.object(Undercloud, 'create')
144     def test_setup_vols(self, mock_get_vm, mock_create,
145                         mock_shutil, mock_os_path, mock_os_remove):
146         uc = Undercloud('img_path', 'tplt_path', external_network=True)
147         mock_os_path.isfile.return_value = True
148         mock_os_path.exists.return_value = True
149         uc.setup_volumes()
150         for img_file in ('overcloud-full.vmlinuz', 'overcloud-full.initrd',
151                          'undercloud.qcow2'):
152             src_img = os.path.join(uc.image_path, img_file)
153             dest_img = os.path.join(constants.LIBVIRT_VOLUME_PATH, img_file)
154             mock_shutil.copyfile.assert_called_with(src_img, dest_img)
155
156     @patch('apex.undercloud.undercloud.os.path')
157     @patch.object(Undercloud, '_get_vm', return_value=None)
158     @patch.object(Undercloud, 'create')
159     def test_setup_vols_raises(self, mock_get_vm, mock_create, mock_os_path):
160         uc = Undercloud('img_path', 'tplt_path', external_network=True)
161         mock_os_path.isfile.return_value = False
162         assert_raises(ApexUndercloudException, uc.setup_volumes)
163
164     @patch('apex.undercloud.undercloud.virt_utils')
165     @patch.object(Undercloud, '_get_vm', return_value=None)
166     @patch.object(Undercloud, 'create')
167     def test_inject_auth(self, mock_get_vm, mock_create, mock_vutils):
168         uc = Undercloud('img_path', 'tplt_path', external_network=True)
169         uc.root_pw = 'test'
170         uc.inject_auth()
171         test_ops = [{'--root-password': 'password:test'},
172                     {'--run-command': 'mkdir -p /root/.ssh'},
173                     {'--upload':
174                      '/root/.ssh/id_rsa.pub:/root/.ssh/authorized_keys'},
175                     {'--run-command': 'chmod 600 /root/.ssh/authorized_keys'},
176                     {'--run-command': 'restorecon /root/.ssh/authorized_keys'},
177                     {'--run-command':
178                      'cp /root/.ssh/authorized_keys /home/stack/.ssh/'},
179                     {'--run-command':
180                      'chown stack:stack /home/stack/.ssh/authorized_keys'},
181                     {'--run-command':
182                      'chmod 600 /home/stack/.ssh/authorized_keys'}]
183         mock_vutils.virt_customize.assert_called_with(test_ops, uc.volume)
184
185     @patch.object(Undercloud, '_get_vm', return_value=None)
186     @patch.object(Undercloud, 'create')
187     def test_generate_config(self, mock_get_vm, mock_create):
188         ns_net = MagicMock()
189         ns_net.__getitem__.side_effect = \
190             lambda i: '1234/24' if i is 'cidr' else MagicMock()
191         ns = {'apex': MagicMock(),
192               'dns-domain': 'dns',
193               'networks': {'admin': ns_net,
194                            'external': [ns_net]}}
195
196         Undercloud('img_path', 'tplt_path').generate_config(ns)