368 lines
12 KiB
Python
368 lines
12 KiB
Python
# Copyright 2016 Mirantis, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import mock
|
|
|
|
import exec_helpers
|
|
|
|
from devops.client import environment
|
|
from devops.client import nailgun
|
|
from devops import error
|
|
from devops.helpers import helpers
|
|
from devops.helpers import ntp
|
|
from devops.tests.driver import driverless
|
|
|
|
|
|
class TestDevopsEnvironment(driverless.DriverlessTestCase):
|
|
|
|
def patch(self, *args, **kwargs):
|
|
patcher = mock.patch(*args, **kwargs)
|
|
m = patcher.start()
|
|
self.addCleanup(patcher.stop)
|
|
return m
|
|
|
|
def setUp(self):
|
|
super(TestDevopsEnvironment, self).setUp()
|
|
self.paramiko_mock = self.patch('devops.client.environment.paramiko')
|
|
self.l2dev_start_mock = self.patch(
|
|
'devops.models.network.L2NetworkDevice.start')
|
|
self.vol_define_mock = self.patch(
|
|
'devops.models.volume.Volume.define')
|
|
self.wait_tcp_mock = self.patch(
|
|
'devops.helpers.helpers.wait_tcp', spec=helpers.wait_tcp)
|
|
self.ssh_mock = self.patch(
|
|
'exec_helpers.SSHClient', spec=exec_helpers.SSHClient)
|
|
self.nc_mock = self.patch(
|
|
'devops.client.nailgun.NailgunClient', spec=nailgun.NailgunClient)
|
|
self.nc_mock_inst = self.nc_mock.return_value
|
|
self.mac_to_ip = {
|
|
'64:52:dc:96:12:cc': '10.109.0.100',
|
|
}
|
|
self.nc_mock_inst.get_slave_ip_by_mac.side_effect = self.mac_to_ip.get
|
|
|
|
self.ntpgroup_mock = self.patch(
|
|
'devops.helpers.ntp.GroupNtpSync', spec=ntp.GroupNtpSync)
|
|
self.ntpgroup_inst = self.ntpgroup_mock.return_value
|
|
|
|
self.slave_conf = {
|
|
'name': 'slave-01',
|
|
'role': 'fuel_slave',
|
|
'params': {},
|
|
'volumes': [
|
|
{
|
|
'name': 'system',
|
|
},
|
|
]
|
|
}
|
|
|
|
self.cr_sl_conf_mock = self.patch(
|
|
'devops.helpers.templates.create_slave_config')
|
|
self.cr_sl_conf_mock.return_value = self.slave_conf
|
|
|
|
self.ext_mock = self.patch(
|
|
'devops.models.node.Node.ext')
|
|
|
|
self.env.add_group(group_name='default',
|
|
driver_name='devops.driver.empty')
|
|
|
|
self.denv = environment.DevopsEnvironment(self.env)
|
|
|
|
def test_add_slaves(self):
|
|
nodes = self.denv.add_slaves(
|
|
nodes_count=1)
|
|
|
|
self.cr_sl_conf_mock.assert_called_once_with(
|
|
slave_name='slave-01',
|
|
slave_role='fuel_slave',
|
|
slave_vcpu=1,
|
|
slave_memory=1024,
|
|
slave_volume_capacity=50,
|
|
second_volume_capacity=50,
|
|
third_volume_capacity=50,
|
|
interfaceorder=[
|
|
'admin', 'public', 'management', 'private', 'storage'],
|
|
numa_nodes=0,
|
|
use_all_disks=True,
|
|
networks_multiplenetworks=False,
|
|
networks_nodegroups=(),
|
|
networks_bonding=False,
|
|
networks_bondinginterfaces={
|
|
'admin': ['eth0', 'eth1'],
|
|
'public': ['eth2', 'eth3', 'eth4', 'eth5']},
|
|
)
|
|
|
|
assert len(nodes) == 1
|
|
assert nodes[0].name == 'slave-01'
|
|
|
|
self.vol_define_mock.assert_called_once_with()
|
|
|
|
def test_admin_setup(self):
|
|
self.group.add_node(
|
|
name='admin',
|
|
role='fule_master')
|
|
|
|
admin = self.denv.admin_setup()
|
|
|
|
assert admin is not None
|
|
self.ext_mock.get_kernel_cmd.assert_called_once_with(
|
|
boot_from='cdrom',
|
|
wait_for_external_config='no',
|
|
iface='enp0s3')
|
|
self.ext_mock.bootstrap_and_wait()
|
|
self.ext_mock.deploy_wait()
|
|
|
|
def test_get_active_nodes(self):
|
|
assert self.denv.get_active_nodes() == []
|
|
|
|
self.group.add_node(
|
|
name='admin',
|
|
role='fule_master')
|
|
self.patch('devops.models.node.Node.is_active', return_value=True)
|
|
nodes = self.denv.get_active_nodes()
|
|
assert len(nodes) == 1
|
|
assert nodes[0].name == 'admin'
|
|
|
|
def test_get_admin(self):
|
|
with self.assertRaises(error.DevopsError):
|
|
self.denv.get_admin()
|
|
|
|
self.group.add_node(
|
|
name='admin',
|
|
role='fule_master')
|
|
|
|
node = self.denv.get_admin()
|
|
assert node is not None
|
|
assert node.name == 'admin'
|
|
|
|
def test_get_admin_ip(self):
|
|
self.group.add_node(
|
|
name='admin',
|
|
role='fule_master',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
|
|
ip = self.denv.get_admin_ip()
|
|
assert ip == '10.109.0.2'
|
|
|
|
def test_get_admin_remote(self):
|
|
ssh = self.ssh_mock.return_value
|
|
self.group.add_node(
|
|
name='admin',
|
|
role='fule_master',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
|
|
remote = self.denv.get_admin_remote()
|
|
assert remote is ssh
|
|
self.ssh_mock.assert_called_once_with(
|
|
'10.109.0.2',
|
|
auth=exec_helpers.SSHAuth(username='root', password='r00tme'))
|
|
|
|
self.wait_tcp_mock.assert_called_once_with(
|
|
host='10.109.0.2', port=22, timeout=180,
|
|
timeout_msg='Admin node 10.109.0.2 is not accessible by SSH.')
|
|
|
|
def test_get_node_ip(self):
|
|
self.group.add_node(
|
|
name='admin',
|
|
role='fule_master',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
|
|
slave = self.group.add_node(
|
|
name='slave-01',
|
|
role='fule_slave',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
|
|
eth0 = slave.get_interface_by_network_name('admin')
|
|
eth0.mac_address = '64:52:dc:96:12:cc'
|
|
eth0.save()
|
|
|
|
ip = self.denv.get_node_ip('slave-01')
|
|
assert ip == '10.109.0.100'
|
|
|
|
def test_get_private_keys(self):
|
|
ssh = self.ssh_mock.return_value.__enter__.return_value
|
|
ssh.open = mock.mock_open()
|
|
key = self.paramiko_mock.RSAKey.from_private_key.return_value
|
|
|
|
self.group.add_node(
|
|
name='admin',
|
|
role='fule_master',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
|
|
keys = self.denv.get_private_keys()
|
|
assert len(keys) == 2
|
|
assert keys == [key, key]
|
|
|
|
self.ssh_mock.assert_called_once_with(
|
|
'10.109.0.2',
|
|
auth=exec_helpers.SSHAuth(username='root', password='r00tme'))
|
|
assert ssh.isfile.call_count == 2
|
|
ssh.isfile.assert_any_call('/root/.ssh/id_rsa')
|
|
ssh.isfile.assert_any_call('/root/.ssh/bootstrap.rsa')
|
|
assert ssh.open.call_count == 2
|
|
ssh.open.assert_any_call('/root/.ssh/id_rsa')
|
|
ssh.open.assert_any_call('/root/.ssh/bootstrap.rsa')
|
|
|
|
assert self.paramiko_mock.RSAKey.from_private_key.call_count == 2
|
|
self.paramiko_mock.RSAKey.from_private_key.assert_called_with(
|
|
ssh.open.return_value)
|
|
|
|
def test_get_node_remote(self):
|
|
ssh = self.ssh_mock.return_value
|
|
ssh.open = mock.mock_open()
|
|
|
|
self.group.add_node(
|
|
name='admin',
|
|
role='fule_master',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
|
|
slave = self.group.add_node(
|
|
name='slave-01',
|
|
role='fule_slave',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
|
|
eth0 = slave.get_interface_by_network_name('admin')
|
|
eth0.mac_address = '64:52:dc:96:12:cc'
|
|
eth0.save()
|
|
|
|
key = self.paramiko_mock.RSAKey.from_private_key.return_value
|
|
keys = [key, key]
|
|
remote = self.denv.get_node_remote('slave-01')
|
|
assert remote is ssh
|
|
self.ssh_mock.assert_called_with(
|
|
'10.109.0.100',
|
|
auth=exec_helpers.SSHAuth(
|
|
username='root',
|
|
password='r00tme',
|
|
keys=keys))
|
|
|
|
self.wait_tcp_mock.assert_called_with(
|
|
host='10.109.0.2', port=22, timeout=180,
|
|
timeout_msg='Admin node 10.109.0.2 is not accessible by SSH.')
|
|
|
|
def test_sync_time(self):
|
|
ssh = self.ssh_mock.return_value
|
|
self.patch('devops.models.node.Node.is_active', return_value=True)
|
|
|
|
self.group.add_node(
|
|
name='admin',
|
|
role='fule_master',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
slave = self.group.add_node(
|
|
name='slave-01',
|
|
role='fule_slave',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
|
|
eth0 = slave.get_interface_by_network_name('admin')
|
|
eth0.mac_address = '64:52:dc:96:12:cc'
|
|
eth0.save()
|
|
|
|
t = self.denv.sync_time()
|
|
assert t is self.ntpgroup_inst.get_curr_time.return_value
|
|
|
|
self.ntpgroup_mock.assert_called_once_with()
|
|
self.ntpgroup_inst.add_node.assert_has_calls((
|
|
mock.call(ssh, 'admin'),
|
|
mock.call(ssh, 'slave-01'),
|
|
))
|
|
|
|
assert self.ntpgroup_inst.sync_time.call_count == 3
|
|
self.ntpgroup_inst.sync_time.assert_any_call('admin')
|
|
self.ntpgroup_inst.sync_time.assert_any_call('pacemaker')
|
|
self.ntpgroup_inst.sync_time.assert_any_call('other')
|
|
self.ntpgroup_inst.get_curr_time.assert_called_once_with()
|
|
self.ntpgroup_inst.__enter__.assert_called_once_with()
|
|
self.ntpgroup_inst.__exit__.assert_called_once_with(None, None, None)
|
|
|
|
def test_get_curr_time(self):
|
|
ssh = self.ssh_mock.return_value
|
|
self.patch('devops.models.node.Node.is_active', return_value=True)
|
|
|
|
self.group.add_node(
|
|
name='admin',
|
|
role='fule_master',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
slave = self.group.add_node(
|
|
name='slave-01',
|
|
role='fule_slave',
|
|
interfaces=[dict(
|
|
label='eth0',
|
|
l2_network_device='admin',
|
|
interface_model='e1000',
|
|
)])
|
|
|
|
eth0 = slave.get_interface_by_network_name('admin')
|
|
eth0.mac_address = '64:52:dc:96:12:cc'
|
|
eth0.save()
|
|
|
|
t = self.denv.get_curr_time(node_names=['admin', 'slave-01'])
|
|
assert t is self.ntpgroup_inst.get_curr_time.return_value
|
|
|
|
self.ntpgroup_mock.assert_called_once_with()
|
|
self.ntpgroup_inst.add_node.assert_has_calls((
|
|
mock.call(ssh, 'admin'),
|
|
mock.call(ssh, 'slave-01'),
|
|
))
|
|
|
|
assert self.ntpgroup_inst.sync_time.call_count == 0
|
|
self.ntpgroup_inst.get_curr_time.assert_called_once_with()
|
|
self.ntpgroup_inst.__enter__.assert_called_once_with()
|
|
self.ntpgroup_inst.__exit__.assert_called_once_with(None, None, None)
|
|
|
|
def test_get_default_gw(self):
|
|
assert self.denv.get_default_gw() == '10.109.0.1'
|
|
assert self.denv.get_default_gw('public') == '10.109.1.1'
|
|
|
|
def test_get_admin_login(self):
|
|
assert self.denv.get_admin_login() == 'root'
|