Misc methods to support vm migration tests
Misc methods to support vm migration tests.
This commit is contained in:
@@ -119,6 +119,18 @@ class TestJujuUtils(ut_utils.BaseTestCase):
|
||||
self.subordinate_application),
|
||||
[self.machine])
|
||||
|
||||
def test_get_unit_name_from_host_name(self):
|
||||
unit_mock1 = mock.MagicMock()
|
||||
unit_mock1.data = {'machine-id': 12}
|
||||
unit_mock1.entity_id = 'myapp/2'
|
||||
unit_mock2 = mock.MagicMock()
|
||||
unit_mock2.data = {'machine-id': 15}
|
||||
unit_mock2.entity_id = 'myapp/5'
|
||||
self.model.get_units.return_value = [unit_mock1, unit_mock2]
|
||||
self.assertEqual(
|
||||
juju_utils.get_unit_name_from_host_name('juju-model-12', 'myapp'),
|
||||
'myapp/2')
|
||||
|
||||
def test_get_machine_status(self):
|
||||
self.patch_object(juju_utils, "get_full_juju_status")
|
||||
self.get_full_juju_status.return_value = self.juju_status
|
||||
|
||||
@@ -811,3 +811,78 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
|
||||
ksclient, project_name, domain_name=domain_name), project_id)
|
||||
ksclient.domains.list.assert_called_once_with(name=domain_name)
|
||||
ksclient.projects.list.assert_called_once_with(domain=domain_id)
|
||||
|
||||
def test_wait_for_server_migration(self):
|
||||
openstack_utils.wait_for_server_migration.retry.stop = \
|
||||
tenacity.stop_after_attempt(1)
|
||||
novaclient = mock.MagicMock()
|
||||
servermock = mock.MagicMock()
|
||||
setattr(servermock, 'OS-EXT-SRV-ATTR:host', 'newhypervisor')
|
||||
servermock.status = 'ACTIVE'
|
||||
novaclient.servers.find.return_value = servermock
|
||||
# Implicit assertion that exception is not raised.
|
||||
openstack_utils.wait_for_server_migration(
|
||||
novaclient,
|
||||
'myvm',
|
||||
'org-hypervisor')
|
||||
|
||||
def test_wait_for_server_migration_fail_no_host_change(self):
|
||||
openstack_utils.wait_for_server_migration.retry.stop = \
|
||||
tenacity.stop_after_attempt(1)
|
||||
novaclient = mock.MagicMock()
|
||||
servermock = mock.MagicMock()
|
||||
setattr(servermock, 'OS-EXT-SRV-ATTR:host', 'org-hypervisor')
|
||||
servermock.status = 'ACTIVE'
|
||||
novaclient.servers.find.return_value = servermock
|
||||
with self.assertRaises(exceptions.NovaGuestMigrationFailed):
|
||||
openstack_utils.wait_for_server_migration(
|
||||
novaclient,
|
||||
'myvm',
|
||||
'org-hypervisor')
|
||||
|
||||
def test_wait_for_server_migration_fail_not_active(self):
|
||||
openstack_utils.wait_for_server_migration.retry.stop = \
|
||||
tenacity.stop_after_attempt(1)
|
||||
novaclient = mock.MagicMock()
|
||||
servermock = mock.MagicMock()
|
||||
setattr(servermock, 'OS-EXT-SRV-ATTR:host', 'newhypervisor')
|
||||
servermock.status = 'NOTACTIVE'
|
||||
novaclient.servers.find.return_value = servermock
|
||||
with self.assertRaises(exceptions.NovaGuestMigrationFailed):
|
||||
openstack_utils.wait_for_server_migration(
|
||||
novaclient,
|
||||
'myvm',
|
||||
'org-hypervisor')
|
||||
|
||||
def test_enable_all_nova_services(self):
|
||||
novaclient = mock.MagicMock()
|
||||
svc_mock1 = mock.MagicMock()
|
||||
svc_mock1.status = 'disabled'
|
||||
svc_mock1.binary = 'nova-compute'
|
||||
svc_mock1.host = 'juju-bb659c-zaza-ad7c662d7f1d-13'
|
||||
svc_mock2 = mock.MagicMock()
|
||||
svc_mock2.status = 'enabled'
|
||||
svc_mock2.binary = 'nova-compute'
|
||||
svc_mock2.host = 'juju-bb659c-zaza-ad7c662d7f1d-14'
|
||||
svc_mock3 = mock.MagicMock()
|
||||
svc_mock3.status = 'disabled'
|
||||
svc_mock3.binary = 'nova-compute'
|
||||
svc_mock3.host = 'juju-bb659c-zaza-ad7c662d7f1d-15'
|
||||
novaclient.services.list.return_value = [
|
||||
svc_mock1,
|
||||
svc_mock2,
|
||||
svc_mock3]
|
||||
openstack_utils.enable_all_nova_services(novaclient)
|
||||
expected_calls = [
|
||||
mock.call('juju-bb659c-zaza-ad7c662d7f1d-13', 'nova-compute'),
|
||||
mock.call('juju-bb659c-zaza-ad7c662d7f1d-15', 'nova-compute')]
|
||||
novaclient.services.enable.assert_has_calls(expected_calls)
|
||||
|
||||
def test_get_hypervisor_for_guest(self):
|
||||
novaclient = mock.MagicMock()
|
||||
servermock = mock.MagicMock()
|
||||
setattr(servermock, 'OS-EXT-SRV-ATTR:host', 'newhypervisor')
|
||||
novaclient.servers.find.return_value = servermock
|
||||
self.assertEqual(
|
||||
openstack_utils.get_hypervisor_for_guest(novaclient, 'vmname'),
|
||||
'newhypervisor')
|
||||
|
||||
@@ -160,3 +160,9 @@ class CephPoolNotFound(Exception):
|
||||
"""Ceph pool not found."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class NovaGuestMigrationFailed(Exception):
|
||||
"""Nova guest migration failed."""
|
||||
|
||||
pass
|
||||
|
||||
@@ -98,6 +98,23 @@ def get_machines_for_application(application):
|
||||
return machines
|
||||
|
||||
|
||||
def get_unit_name_from_host_name(host_name, application):
|
||||
"""Return the juju unit name corresponding to a hostname.
|
||||
|
||||
:param host_name: Host name to map to unit name.
|
||||
:type host_name: string
|
||||
:param application: Application name
|
||||
:type application: string
|
||||
"""
|
||||
# Assume that a juju managed hostname always ends in the machine number.
|
||||
machine_number = host_name.split('-')[-1]
|
||||
unit_names = [
|
||||
u.entity_id
|
||||
for u in model.get_units(application_name=application)
|
||||
if int(u.data['machine-id']) == int(machine_number)]
|
||||
return unit_names[0]
|
||||
|
||||
|
||||
def get_machine_status(machine, key=None):
|
||||
"""Return the juju status for a machine.
|
||||
|
||||
|
||||
@@ -1889,3 +1889,59 @@ def neutron_bgp_speaker_appears_on_agent(neutron_client, agent_id):
|
||||
'No BGP Speaker appeared on agent "{}"'
|
||||
''.format(agent_id))
|
||||
return result
|
||||
|
||||
|
||||
@tenacity.retry(wait=tenacity.wait_exponential(multiplier=1, max=60),
|
||||
reraise=True, stop=tenacity.stop_after_attempt(80))
|
||||
def wait_for_server_migration(nova_client, vm_name, original_hypervisor):
|
||||
"""Wait for guest to migrate to a different hypervisor.
|
||||
|
||||
:param nova_client: Authenticated nova client
|
||||
:type nova_client: novaclient.v2.client.Client
|
||||
:param vm_name: Name of guest to monitor
|
||||
:type vm_name: str
|
||||
:param original_hypervisor: Name of hypervisor that was hosting guest
|
||||
prior to migration.
|
||||
:type original_hypervisor: str
|
||||
:raises: exceptions.NovaGuestMigrationFailed
|
||||
"""
|
||||
server = nova_client.servers.find(name=vm_name)
|
||||
current_hypervisor = getattr(server, 'OS-EXT-SRV-ATTR:host')
|
||||
logging.info('{} is on {} in state {}'.format(
|
||||
vm_name,
|
||||
current_hypervisor,
|
||||
server.status))
|
||||
if original_hypervisor == current_hypervisor or server.status != 'ACTIVE':
|
||||
raise exceptions.NovaGuestMigrationFailed(
|
||||
'Migration of {} away from {} timed out of failed'.format(
|
||||
vm_name,
|
||||
original_hypervisor))
|
||||
else:
|
||||
logging.info('SUCCESS {} has migrated to {}'.format(
|
||||
vm_name,
|
||||
current_hypervisor))
|
||||
|
||||
|
||||
def enable_all_nova_services(nova_client):
|
||||
"""Enable all nova services.
|
||||
|
||||
:param nova_client: Authenticated nova client
|
||||
:type nova_client: novaclient.v2.client.Client
|
||||
"""
|
||||
for svc in nova_client.services.list():
|
||||
if svc.status == 'disabled':
|
||||
logging.info("Enabling {} on {}".format(svc.binary, svc.host))
|
||||
nova_client.services.enable(svc.host, svc.binary)
|
||||
|
||||
|
||||
def get_hypervisor_for_guest(nova_client, guest_name):
|
||||
"""Return the name of the hypervisor hosting a guest.
|
||||
|
||||
:param nova_client: Authenticated nova client
|
||||
:type nova_client: novaclient.v2.client.Client
|
||||
:param vm_name: Name of guest to loohup
|
||||
:type vm_name: str
|
||||
"""
|
||||
logging.info('Finding hosting hypervisor')
|
||||
server = nova_client.servers.find(name=guest_name)
|
||||
return getattr(server, 'OS-EXT-SRV-ATTR:host')
|
||||
|
||||
Reference in New Issue
Block a user